Completed
Branch ADMIN-REFRESH (ff800a)
by
unknown
03:18 queued 26s
created
admin_pages/registrations/EE_Registrations_List_Table.class.php 2 patches
Indentation   +1056 added lines, -1056 removed lines patch added patch discarded remove patch
@@ -15,1093 +15,1093 @@
 block discarded – undo
15 15
 {
16 16
 
17 17
 
18
-    /**
19
-     * @var Registrations_Admin_Page
20
-     */
21
-    protected $_admin_page;
22
-
23
-    /**
24
-     * @var array
25
-     */
26
-    private $_status;
27
-
28
-    /**
29
-     * An array of transaction details for the related transaction to the registration being processed.
30
-     * This is set via the _set_related_details method.
31
-     *
32
-     * @var array
33
-     */
34
-    protected $_transaction_details = [];
35
-
36
-    /**
37
-     * An array of event details for the related event to the registration being processed.
38
-     * This is set via the _set_related_details method.
39
-     *
40
-     * @var array
41
-     */
42
-    protected $_event_details = [];
43
-
44
-
45
-    /**
46
-     * @param Registrations_Admin_Page $admin_page
47
-     */
48
-    public function __construct(Registrations_Admin_Page $admin_page)
49
-    {
50
-        $req_data = $admin_page->get_request_data();
51
-        if (! empty($req_data['event_id'])) {
52
-            $extra_query_args = [];
53
-            foreach ($admin_page->get_views() as $view_details) {
54
-                $extra_query_args[ $view_details['slug'] ] = ['event_id' => $req_data['event_id']];
55
-            }
56
-            $this->_views = $admin_page->get_list_table_view_RLs($extra_query_args);
57
-        }
58
-        parent::__construct($admin_page);
59
-        $this->_status = $this->_admin_page->get_registration_status_array();
60
-    }
61
-
62
-
63
-    /**
64
-     * @return void
65
-     * @throws EE_Error
66
-     */
67
-    protected function _setup_data()
68
-    {
69
-        $this->_data           = $this->_admin_page->get_registrations($this->_per_page);
70
-        $this->_all_data_count = $this->_admin_page->get_registrations($this->_per_page, true);
71
-    }
72
-
73
-
74
-    /**
75
-     * @return void
76
-     */
77
-    protected function _set_properties()
78
-    {
79
-        $return_url          = $this->getReturnUrl();
80
-        $this->_wp_list_args = [
81
-            'singular' => esc_html__('registration', 'event_espresso'),
82
-            'plural'   => esc_html__('registrations', 'event_espresso'),
83
-            'ajax'     => true,
84
-            'screen'   => $this->_admin_page->get_current_screen()->id,
85
-        ];
86
-        $req_data            = $this->_admin_page->get_request_data();
87
-        if (isset($req_data['event_id'])) {
88
-            $this->_columns        = [
89
-                'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
90
-                'status'           => '',
91
-                '_REG_ID'          => esc_html__('ID', 'event_espresso'),
92
-                'ATT_fname'        => esc_html__('Name', 'event_espresso'),
93
-                'ATT_email'        => esc_html__('Email', 'event_espresso'),
94
-                '_REG_date'        => esc_html__('Reg Date', 'event_espresso'),
95
-                'PRC_amount'       => esc_html__('TKT Price', 'event_espresso'),
96
-                '_REG_final_price' => esc_html__('Final Price', 'event_espresso'),
97
-                'TXN_total'        => esc_html__('Total Txn', 'event_espresso'),
98
-                'TXN_paid'         => esc_html__('Paid', 'event_espresso'),
99
-                'actions'          => esc_html__('Actions', 'event_espresso'),
100
-            ];
101
-            $this->_bottom_buttons = [
102
-                'report' => [
103
-                    'route'         => 'registrations_report',
104
-                    'extra_request' => [
105
-                        'EVT_ID'     => $this->_req_data['event_id'] ?? null,
106
-                        'return_url' => $return_url,
107
-                    ],
108
-                ],
109
-            ];
110
-        } else {
111
-            $this->_columns        = [
112
-                'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
113
-                'status'           => '',
114
-                '_REG_ID'          => esc_html__('ID', 'event_espresso'),
115
-                'ATT_fname'        => esc_html__('Name', 'event_espresso'),
116
-                '_REG_date'        => esc_html__('TXN Date', 'event_espresso'),
117
-                'event_name'       => esc_html__('Event', 'event_espresso'),
118
-                'DTT_EVT_start'    => esc_html__('Event Date', 'event_espresso'),
119
-                '_REG_final_price' => esc_html__('Price', 'event_espresso'),
120
-                '_REG_paid'        => esc_html__('Paid', 'event_espresso'),
121
-                'actions'          => esc_html__('Actions', 'event_espresso'),
122
-            ];
123
-            $this->_bottom_buttons = [
124
-                'report_all' => [
125
-                    'route'         => 'registrations_report',
126
-                    'extra_request' => [
127
-                        'return_url' => $return_url,
128
-                    ],
129
-                ],
130
-            ];
131
-        }
132
-        $this->_bottom_buttons['report_filtered'] = [
133
-            'route'         => 'registrations_report',
134
-            'extra_request' => [
135
-                'use_filters' => true,
136
-                'return_url'  => $return_url,
137
-            ],
138
-        ];
139
-        $filters                                  = array_diff_key(
140
-            $this->_req_data,
141
-            array_flip(
142
-                [
143
-                    'page',
144
-                    'action',
145
-                    'default_nonce',
146
-                ]
147
-            )
148
-        );
149
-        if (! empty($filters)) {
150
-            $this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters;
151
-        }
152
-        $this->_primary_column   = '_REG_ID';
153
-        $this->_sortable_columns = [
154
-            '_REG_date'     => ['_REG_date' => true],   // true means its already sorted
155
-            /**
156
-             * Allows users to change the default sort if they wish.
157
-             * Returning a falsey on this filter will result in the default sort to be by firstname rather than last
158
-             * name.
159
-             */
160
-            'ATT_fname'     => [
161
-                'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
162
-                true,
163
-                $this,
164
-            ]
165
-                ? ['ATT_lname' => false]
166
-                : ['ATT_fname' => false],
167
-            'event_name'    => ['event_name' => false],
168
-            'DTT_EVT_start' => ['DTT_EVT_start' => false],
169
-            '_REG_ID'       => ['_REG_ID' => false],
170
-        ];
171
-        $this->_hidden_columns   = [];
172
-    }
173
-
174
-
175
-    /**
176
-     * This simply sets up the row class for the table rows.
177
-     * Allows for easier overriding of child methods for setting up sorting.
178
-     *
179
-     * @param EE_Registration $item the current item
180
-     * @return string
181
-     */
182
-    protected function _get_row_class($item)
183
-    {
184
-        $class = parent::_get_row_class($item);
185
-        if ($this->_has_checkbox_column) {
186
-            $class .= ' has-checkbox-column';
187
-        }
188
-        return $class;
189
-    }
190
-
191
-
192
-    /**
193
-     * Set the $_transaction_details property if not set yet.
194
-     *
195
-     * @param EE_Registration $registration
196
-     * @throws EE_Error
197
-     * @throws InvalidArgumentException
198
-     * @throws ReflectionException
199
-     * @throws InvalidDataTypeException
200
-     * @throws InvalidInterfaceException
201
-     */
202
-    protected function _set_related_details(EE_Registration $registration)
203
-    {
204
-        $transaction                = $registration->get_first_related('Transaction');
205
-        $status                     = $transaction instanceof EE_Transaction
206
-            ? $transaction->status_ID()
207
-            : EEM_Transaction::failed_status_code;
208
-        $this->_transaction_details = [
209
-            'transaction' => $transaction,
210
-            'status'      => $status,
211
-            'id'          => $transaction instanceof EE_Transaction
212
-                ? $transaction->ID()
213
-                : 0,
214
-            'title_attr'  => sprintf(
215
-                esc_html__('View Transaction Details (%s)', 'event_espresso'),
216
-                EEH_Template::pretty_status($status, false, 'sentence')
217
-            ),
218
-        ];
219
-        try {
220
-            $event = $registration->event();
221
-        } catch (EntityNotFoundException $e) {
222
-            $event = null;
223
-        }
224
-        $status               = $event instanceof EE_Event
225
-            ? $event->get_active_status()
226
-            : EE_Datetime::inactive;
227
-        $this->_event_details = [
228
-            'event'      => $event,
229
-            'status'     => $status,
230
-            'id'         => $event instanceof EE_Event
231
-                ? $event->ID()
232
-                : 0,
233
-            'title_attr' => sprintf(
234
-                esc_html__('Edit Event (%s)', 'event_espresso'),
235
-                EEH_Template::pretty_status($status, false, 'sentence')
236
-            ),
237
-        ];
238
-    }
239
-
240
-
241
-    /**
242
-     *    _get_table_filters
243
-     *
244
-     * @return array
245
-     */
246
-    protected function _get_table_filters()
247
-    {
248
-        $filters = [];
249
-        // todo we're currently using old functions here. We need to move things into the Events_Admin_Page() class as
250
-        // methods.
251
-        $cur_date     = isset($this->_req_data['month_range'])
252
-            ? $this->_req_data['month_range']
253
-            : '';
254
-        $cur_category = isset($this->_req_data['EVT_CAT'])
255
-            ? $this->_req_data['EVT_CAT']
256
-            : -1;
257
-        $reg_status   = isset($this->_req_data['_reg_status'])
258
-            ? $this->_req_data['_reg_status']
259
-            : '';
260
-        $filters[]    = EEH_Form_Fields::generate_registration_months_dropdown($cur_date, $reg_status, $cur_category);
261
-        $filters[]    = EEH_Form_Fields::generate_event_category_dropdown($cur_category);
262
-        $status       = [];
263
-        $status[]     = ['id' => 0, 'text' => esc_html__('Select Status', 'event_espresso')];
264
-        foreach ($this->_status as $key => $value) {
265
-            $status[] = ['id' => $key, 'text' => $value];
266
-        }
267
-        if ($this->_view !== 'incomplete') {
268
-            $filters[] = EEH_Form_Fields::select_input(
269
-                '_reg_status',
270
-                $status,
271
-                isset($this->_req_data['_reg_status'])
272
-                    ? strtoupper(sanitize_key($this->_req_data['_reg_status']))
273
-                    : ''
274
-            );
275
-        }
276
-        if (isset($this->_req_data['event_id'])) {
277
-            $filters[] = EEH_Form_Fields::hidden_input('event_id', $this->_req_data['event_id'], 'reg_event_id');
278
-        }
279
-        return $filters;
280
-    }
281
-
282
-
283
-    /**
284
-     * @return void
285
-     * @throws EE_Error
286
-     * @throws InvalidArgumentException
287
-     * @throws InvalidDataTypeException
288
-     * @throws InvalidInterfaceException
289
-     */
290
-    protected function _add_view_counts()
291
-    {
292
-        $this->_views['all']['count']   = $this->_total_registrations();
293
-        $this->_views['month']['count'] = $this->_total_registrations_this_month();
294
-        $this->_views['today']['count'] = $this->_total_registrations_today();
295
-        if (
296
-            EE_Registry::instance()->CAP->current_user_can(
297
-                'ee_delete_registrations',
298
-                'espresso_registrations_trash_registrations'
299
-            )
300
-        ) {
301
-            $this->_views['incomplete']['count'] = $this->_total_registrations('incomplete');
302
-            $this->_views['trash']['count']      = $this->_total_registrations('trash');
303
-        }
304
-    }
305
-
306
-
307
-    /**
308
-     * @param string $view
309
-     * @return int
310
-     * @throws EE_Error
311
-     * @throws InvalidArgumentException
312
-     * @throws InvalidDataTypeException
313
-     * @throws InvalidInterfaceException
314
-     */
315
-    protected function _total_registrations($view = '')
316
-    {
317
-        $_where = [];
318
-        $EVT_ID = isset($this->_req_data['event_id'])
319
-            ? absint($this->_req_data['event_id'])
320
-            : false;
321
-        if ($EVT_ID) {
322
-            $_where['EVT_ID'] = $EVT_ID;
323
-        }
324
-        switch ($view) {
325
-            case 'trash':
326
-                return EEM_Registration::instance()->count_deleted([$_where]);
327
-            case 'incomplete':
328
-                $_where['STS_ID'] = EEM_Registration::status_id_incomplete;
329
-                break;
330
-            default:
331
-                $_where['STS_ID'] = ['!=', EEM_Registration::status_id_incomplete];
332
-        }
333
-        return EEM_Registration::instance()->count([$_where]);
334
-    }
335
-
336
-
337
-    /**
338
-     * @return int
339
-     * @throws EE_Error
340
-     * @throws InvalidArgumentException
341
-     * @throws InvalidDataTypeException
342
-     * @throws InvalidInterfaceException
343
-     */
344
-    protected function _total_registrations_this_month()
345
-    {
346
-        $EVT_ID          = isset($this->_req_data['event_id'])
347
-            ? absint($this->_req_data['event_id'])
348
-            : false;
349
-        $_where          = $EVT_ID
350
-            ? ['EVT_ID' => $EVT_ID]
351
-            : [];
352
-        $this_year_r     = date('Y', current_time('timestamp'));
353
-        $time_start      = ' 00:00:00';
354
-        $time_end        = ' 23:59:59';
355
-        $this_month_r    = date('m', current_time('timestamp'));
356
-        $days_this_month = date('t', current_time('timestamp'));
357
-        // setup date query.
358
-        $beginning_string   = EEM_Registration::instance()->convert_datetime_for_query(
359
-            'REG_date',
360
-            $this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start,
361
-            'Y-m-d H:i:s'
362
-        );
363
-        $end_string         = EEM_Registration::instance()->convert_datetime_for_query(
364
-            'REG_date',
365
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end,
366
-            'Y-m-d H:i:s'
367
-        );
368
-        $_where['REG_date'] = [
369
-            'BETWEEN',
370
-            [
371
-                $beginning_string,
372
-                $end_string,
373
-            ],
374
-        ];
375
-        $_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
376
-        return EEM_Registration::instance()->count([$_where]);
377
-    }
378
-
379
-
380
-    /**
381
-     * @return int
382
-     * @throws EE_Error
383
-     * @throws InvalidArgumentException
384
-     * @throws InvalidDataTypeException
385
-     * @throws InvalidInterfaceException
386
-     */
387
-    protected function _total_registrations_today()
388
-    {
389
-        $EVT_ID             = isset($this->_req_data['event_id'])
390
-            ? absint($this->_req_data['event_id'])
391
-            : false;
392
-        $_where             = $EVT_ID
393
-            ? ['EVT_ID' => $EVT_ID]
394
-            : [];
395
-        $current_date       = date('Y-m-d', current_time('timestamp'));
396
-        $time_start         = ' 00:00:00';
397
-        $time_end           = ' 23:59:59';
398
-        $_where['REG_date'] = [
399
-            'BETWEEN',
400
-            [
401
-                EEM_Registration::instance()->convert_datetime_for_query(
402
-                    'REG_date',
403
-                    $current_date . $time_start,
404
-                    'Y-m-d H:i:s'
405
-                ),
406
-                EEM_Registration::instance()->convert_datetime_for_query(
407
-                    'REG_date',
408
-                    $current_date . $time_end,
409
-                    'Y-m-d H:i:s'
410
-                ),
411
-            ],
412
-        ];
413
-        $_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
414
-        return EEM_Registration::instance()->count([$_where]);
415
-    }
416
-
417
-
418
-    /**
419
-     * @param EE_Registration $item
420
-     * @return string
421
-     * @throws EE_Error
422
-     * @throws InvalidArgumentException
423
-     * @throws InvalidDataTypeException
424
-     * @throws InvalidInterfaceException
425
-     * @throws ReflectionException
426
-     */
427
-    public function column_cb($item)
428
-    {
429
-        /** checkbox/lock **/
430
-        $transaction   = $item->get_first_related('Transaction');
431
-        $payment_count = $transaction instanceof EE_Transaction
432
-            ? $transaction->count_related('Payment')
433
-            : 0;
434
-        $content = $payment_count > 0 || ! EE_Registry::instance()->CAP->current_user_can(
435
-            'ee_edit_registration',
436
-            'registration_list_table_checkbox_input',
437
-            $item->ID()
438
-        )
439
-            ? sprintf('<input disabled type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID())
440
-              . '<span class="dashicons dashicons-lock"></span>'
441
-            : sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID());
442
-
443
-        return $this->columnContent('cb', $content, 'center');
444
-    }
445
-
446
-
447
-    /**
448
-     *    column status
449
-     *
450
-     * @param EE_Registration $registration
451
-     * @return string
452
-     * @throws EE_Error
453
-     */
454
-    public function column_status(EE_Registration $registration)
455
-    {
456
-        return '
18
+	/**
19
+	 * @var Registrations_Admin_Page
20
+	 */
21
+	protected $_admin_page;
22
+
23
+	/**
24
+	 * @var array
25
+	 */
26
+	private $_status;
27
+
28
+	/**
29
+	 * An array of transaction details for the related transaction to the registration being processed.
30
+	 * This is set via the _set_related_details method.
31
+	 *
32
+	 * @var array
33
+	 */
34
+	protected $_transaction_details = [];
35
+
36
+	/**
37
+	 * An array of event details for the related event to the registration being processed.
38
+	 * This is set via the _set_related_details method.
39
+	 *
40
+	 * @var array
41
+	 */
42
+	protected $_event_details = [];
43
+
44
+
45
+	/**
46
+	 * @param Registrations_Admin_Page $admin_page
47
+	 */
48
+	public function __construct(Registrations_Admin_Page $admin_page)
49
+	{
50
+		$req_data = $admin_page->get_request_data();
51
+		if (! empty($req_data['event_id'])) {
52
+			$extra_query_args = [];
53
+			foreach ($admin_page->get_views() as $view_details) {
54
+				$extra_query_args[ $view_details['slug'] ] = ['event_id' => $req_data['event_id']];
55
+			}
56
+			$this->_views = $admin_page->get_list_table_view_RLs($extra_query_args);
57
+		}
58
+		parent::__construct($admin_page);
59
+		$this->_status = $this->_admin_page->get_registration_status_array();
60
+	}
61
+
62
+
63
+	/**
64
+	 * @return void
65
+	 * @throws EE_Error
66
+	 */
67
+	protected function _setup_data()
68
+	{
69
+		$this->_data           = $this->_admin_page->get_registrations($this->_per_page);
70
+		$this->_all_data_count = $this->_admin_page->get_registrations($this->_per_page, true);
71
+	}
72
+
73
+
74
+	/**
75
+	 * @return void
76
+	 */
77
+	protected function _set_properties()
78
+	{
79
+		$return_url          = $this->getReturnUrl();
80
+		$this->_wp_list_args = [
81
+			'singular' => esc_html__('registration', 'event_espresso'),
82
+			'plural'   => esc_html__('registrations', 'event_espresso'),
83
+			'ajax'     => true,
84
+			'screen'   => $this->_admin_page->get_current_screen()->id,
85
+		];
86
+		$req_data            = $this->_admin_page->get_request_data();
87
+		if (isset($req_data['event_id'])) {
88
+			$this->_columns        = [
89
+				'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
90
+				'status'           => '',
91
+				'_REG_ID'          => esc_html__('ID', 'event_espresso'),
92
+				'ATT_fname'        => esc_html__('Name', 'event_espresso'),
93
+				'ATT_email'        => esc_html__('Email', 'event_espresso'),
94
+				'_REG_date'        => esc_html__('Reg Date', 'event_espresso'),
95
+				'PRC_amount'       => esc_html__('TKT Price', 'event_espresso'),
96
+				'_REG_final_price' => esc_html__('Final Price', 'event_espresso'),
97
+				'TXN_total'        => esc_html__('Total Txn', 'event_espresso'),
98
+				'TXN_paid'         => esc_html__('Paid', 'event_espresso'),
99
+				'actions'          => esc_html__('Actions', 'event_espresso'),
100
+			];
101
+			$this->_bottom_buttons = [
102
+				'report' => [
103
+					'route'         => 'registrations_report',
104
+					'extra_request' => [
105
+						'EVT_ID'     => $this->_req_data['event_id'] ?? null,
106
+						'return_url' => $return_url,
107
+					],
108
+				],
109
+			];
110
+		} else {
111
+			$this->_columns        = [
112
+				'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
113
+				'status'           => '',
114
+				'_REG_ID'          => esc_html__('ID', 'event_espresso'),
115
+				'ATT_fname'        => esc_html__('Name', 'event_espresso'),
116
+				'_REG_date'        => esc_html__('TXN Date', 'event_espresso'),
117
+				'event_name'       => esc_html__('Event', 'event_espresso'),
118
+				'DTT_EVT_start'    => esc_html__('Event Date', 'event_espresso'),
119
+				'_REG_final_price' => esc_html__('Price', 'event_espresso'),
120
+				'_REG_paid'        => esc_html__('Paid', 'event_espresso'),
121
+				'actions'          => esc_html__('Actions', 'event_espresso'),
122
+			];
123
+			$this->_bottom_buttons = [
124
+				'report_all' => [
125
+					'route'         => 'registrations_report',
126
+					'extra_request' => [
127
+						'return_url' => $return_url,
128
+					],
129
+				],
130
+			];
131
+		}
132
+		$this->_bottom_buttons['report_filtered'] = [
133
+			'route'         => 'registrations_report',
134
+			'extra_request' => [
135
+				'use_filters' => true,
136
+				'return_url'  => $return_url,
137
+			],
138
+		];
139
+		$filters                                  = array_diff_key(
140
+			$this->_req_data,
141
+			array_flip(
142
+				[
143
+					'page',
144
+					'action',
145
+					'default_nonce',
146
+				]
147
+			)
148
+		);
149
+		if (! empty($filters)) {
150
+			$this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters;
151
+		}
152
+		$this->_primary_column   = '_REG_ID';
153
+		$this->_sortable_columns = [
154
+			'_REG_date'     => ['_REG_date' => true],   // true means its already sorted
155
+			/**
156
+			 * Allows users to change the default sort if they wish.
157
+			 * Returning a falsey on this filter will result in the default sort to be by firstname rather than last
158
+			 * name.
159
+			 */
160
+			'ATT_fname'     => [
161
+				'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
162
+				true,
163
+				$this,
164
+			]
165
+				? ['ATT_lname' => false]
166
+				: ['ATT_fname' => false],
167
+			'event_name'    => ['event_name' => false],
168
+			'DTT_EVT_start' => ['DTT_EVT_start' => false],
169
+			'_REG_ID'       => ['_REG_ID' => false],
170
+		];
171
+		$this->_hidden_columns   = [];
172
+	}
173
+
174
+
175
+	/**
176
+	 * This simply sets up the row class for the table rows.
177
+	 * Allows for easier overriding of child methods for setting up sorting.
178
+	 *
179
+	 * @param EE_Registration $item the current item
180
+	 * @return string
181
+	 */
182
+	protected function _get_row_class($item)
183
+	{
184
+		$class = parent::_get_row_class($item);
185
+		if ($this->_has_checkbox_column) {
186
+			$class .= ' has-checkbox-column';
187
+		}
188
+		return $class;
189
+	}
190
+
191
+
192
+	/**
193
+	 * Set the $_transaction_details property if not set yet.
194
+	 *
195
+	 * @param EE_Registration $registration
196
+	 * @throws EE_Error
197
+	 * @throws InvalidArgumentException
198
+	 * @throws ReflectionException
199
+	 * @throws InvalidDataTypeException
200
+	 * @throws InvalidInterfaceException
201
+	 */
202
+	protected function _set_related_details(EE_Registration $registration)
203
+	{
204
+		$transaction                = $registration->get_first_related('Transaction');
205
+		$status                     = $transaction instanceof EE_Transaction
206
+			? $transaction->status_ID()
207
+			: EEM_Transaction::failed_status_code;
208
+		$this->_transaction_details = [
209
+			'transaction' => $transaction,
210
+			'status'      => $status,
211
+			'id'          => $transaction instanceof EE_Transaction
212
+				? $transaction->ID()
213
+				: 0,
214
+			'title_attr'  => sprintf(
215
+				esc_html__('View Transaction Details (%s)', 'event_espresso'),
216
+				EEH_Template::pretty_status($status, false, 'sentence')
217
+			),
218
+		];
219
+		try {
220
+			$event = $registration->event();
221
+		} catch (EntityNotFoundException $e) {
222
+			$event = null;
223
+		}
224
+		$status               = $event instanceof EE_Event
225
+			? $event->get_active_status()
226
+			: EE_Datetime::inactive;
227
+		$this->_event_details = [
228
+			'event'      => $event,
229
+			'status'     => $status,
230
+			'id'         => $event instanceof EE_Event
231
+				? $event->ID()
232
+				: 0,
233
+			'title_attr' => sprintf(
234
+				esc_html__('Edit Event (%s)', 'event_espresso'),
235
+				EEH_Template::pretty_status($status, false, 'sentence')
236
+			),
237
+		];
238
+	}
239
+
240
+
241
+	/**
242
+	 *    _get_table_filters
243
+	 *
244
+	 * @return array
245
+	 */
246
+	protected function _get_table_filters()
247
+	{
248
+		$filters = [];
249
+		// todo we're currently using old functions here. We need to move things into the Events_Admin_Page() class as
250
+		// methods.
251
+		$cur_date     = isset($this->_req_data['month_range'])
252
+			? $this->_req_data['month_range']
253
+			: '';
254
+		$cur_category = isset($this->_req_data['EVT_CAT'])
255
+			? $this->_req_data['EVT_CAT']
256
+			: -1;
257
+		$reg_status   = isset($this->_req_data['_reg_status'])
258
+			? $this->_req_data['_reg_status']
259
+			: '';
260
+		$filters[]    = EEH_Form_Fields::generate_registration_months_dropdown($cur_date, $reg_status, $cur_category);
261
+		$filters[]    = EEH_Form_Fields::generate_event_category_dropdown($cur_category);
262
+		$status       = [];
263
+		$status[]     = ['id' => 0, 'text' => esc_html__('Select Status', 'event_espresso')];
264
+		foreach ($this->_status as $key => $value) {
265
+			$status[] = ['id' => $key, 'text' => $value];
266
+		}
267
+		if ($this->_view !== 'incomplete') {
268
+			$filters[] = EEH_Form_Fields::select_input(
269
+				'_reg_status',
270
+				$status,
271
+				isset($this->_req_data['_reg_status'])
272
+					? strtoupper(sanitize_key($this->_req_data['_reg_status']))
273
+					: ''
274
+			);
275
+		}
276
+		if (isset($this->_req_data['event_id'])) {
277
+			$filters[] = EEH_Form_Fields::hidden_input('event_id', $this->_req_data['event_id'], 'reg_event_id');
278
+		}
279
+		return $filters;
280
+	}
281
+
282
+
283
+	/**
284
+	 * @return void
285
+	 * @throws EE_Error
286
+	 * @throws InvalidArgumentException
287
+	 * @throws InvalidDataTypeException
288
+	 * @throws InvalidInterfaceException
289
+	 */
290
+	protected function _add_view_counts()
291
+	{
292
+		$this->_views['all']['count']   = $this->_total_registrations();
293
+		$this->_views['month']['count'] = $this->_total_registrations_this_month();
294
+		$this->_views['today']['count'] = $this->_total_registrations_today();
295
+		if (
296
+			EE_Registry::instance()->CAP->current_user_can(
297
+				'ee_delete_registrations',
298
+				'espresso_registrations_trash_registrations'
299
+			)
300
+		) {
301
+			$this->_views['incomplete']['count'] = $this->_total_registrations('incomplete');
302
+			$this->_views['trash']['count']      = $this->_total_registrations('trash');
303
+		}
304
+	}
305
+
306
+
307
+	/**
308
+	 * @param string $view
309
+	 * @return int
310
+	 * @throws EE_Error
311
+	 * @throws InvalidArgumentException
312
+	 * @throws InvalidDataTypeException
313
+	 * @throws InvalidInterfaceException
314
+	 */
315
+	protected function _total_registrations($view = '')
316
+	{
317
+		$_where = [];
318
+		$EVT_ID = isset($this->_req_data['event_id'])
319
+			? absint($this->_req_data['event_id'])
320
+			: false;
321
+		if ($EVT_ID) {
322
+			$_where['EVT_ID'] = $EVT_ID;
323
+		}
324
+		switch ($view) {
325
+			case 'trash':
326
+				return EEM_Registration::instance()->count_deleted([$_where]);
327
+			case 'incomplete':
328
+				$_where['STS_ID'] = EEM_Registration::status_id_incomplete;
329
+				break;
330
+			default:
331
+				$_where['STS_ID'] = ['!=', EEM_Registration::status_id_incomplete];
332
+		}
333
+		return EEM_Registration::instance()->count([$_where]);
334
+	}
335
+
336
+
337
+	/**
338
+	 * @return int
339
+	 * @throws EE_Error
340
+	 * @throws InvalidArgumentException
341
+	 * @throws InvalidDataTypeException
342
+	 * @throws InvalidInterfaceException
343
+	 */
344
+	protected function _total_registrations_this_month()
345
+	{
346
+		$EVT_ID          = isset($this->_req_data['event_id'])
347
+			? absint($this->_req_data['event_id'])
348
+			: false;
349
+		$_where          = $EVT_ID
350
+			? ['EVT_ID' => $EVT_ID]
351
+			: [];
352
+		$this_year_r     = date('Y', current_time('timestamp'));
353
+		$time_start      = ' 00:00:00';
354
+		$time_end        = ' 23:59:59';
355
+		$this_month_r    = date('m', current_time('timestamp'));
356
+		$days_this_month = date('t', current_time('timestamp'));
357
+		// setup date query.
358
+		$beginning_string   = EEM_Registration::instance()->convert_datetime_for_query(
359
+			'REG_date',
360
+			$this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start,
361
+			'Y-m-d H:i:s'
362
+		);
363
+		$end_string         = EEM_Registration::instance()->convert_datetime_for_query(
364
+			'REG_date',
365
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end,
366
+			'Y-m-d H:i:s'
367
+		);
368
+		$_where['REG_date'] = [
369
+			'BETWEEN',
370
+			[
371
+				$beginning_string,
372
+				$end_string,
373
+			],
374
+		];
375
+		$_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
376
+		return EEM_Registration::instance()->count([$_where]);
377
+	}
378
+
379
+
380
+	/**
381
+	 * @return int
382
+	 * @throws EE_Error
383
+	 * @throws InvalidArgumentException
384
+	 * @throws InvalidDataTypeException
385
+	 * @throws InvalidInterfaceException
386
+	 */
387
+	protected function _total_registrations_today()
388
+	{
389
+		$EVT_ID             = isset($this->_req_data['event_id'])
390
+			? absint($this->_req_data['event_id'])
391
+			: false;
392
+		$_where             = $EVT_ID
393
+			? ['EVT_ID' => $EVT_ID]
394
+			: [];
395
+		$current_date       = date('Y-m-d', current_time('timestamp'));
396
+		$time_start         = ' 00:00:00';
397
+		$time_end           = ' 23:59:59';
398
+		$_where['REG_date'] = [
399
+			'BETWEEN',
400
+			[
401
+				EEM_Registration::instance()->convert_datetime_for_query(
402
+					'REG_date',
403
+					$current_date . $time_start,
404
+					'Y-m-d H:i:s'
405
+				),
406
+				EEM_Registration::instance()->convert_datetime_for_query(
407
+					'REG_date',
408
+					$current_date . $time_end,
409
+					'Y-m-d H:i:s'
410
+				),
411
+			],
412
+		];
413
+		$_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
414
+		return EEM_Registration::instance()->count([$_where]);
415
+	}
416
+
417
+
418
+	/**
419
+	 * @param EE_Registration $item
420
+	 * @return string
421
+	 * @throws EE_Error
422
+	 * @throws InvalidArgumentException
423
+	 * @throws InvalidDataTypeException
424
+	 * @throws InvalidInterfaceException
425
+	 * @throws ReflectionException
426
+	 */
427
+	public function column_cb($item)
428
+	{
429
+		/** checkbox/lock **/
430
+		$transaction   = $item->get_first_related('Transaction');
431
+		$payment_count = $transaction instanceof EE_Transaction
432
+			? $transaction->count_related('Payment')
433
+			: 0;
434
+		$content = $payment_count > 0 || ! EE_Registry::instance()->CAP->current_user_can(
435
+			'ee_edit_registration',
436
+			'registration_list_table_checkbox_input',
437
+			$item->ID()
438
+		)
439
+			? sprintf('<input disabled type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID())
440
+			  . '<span class="dashicons dashicons-lock"></span>'
441
+			: sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID());
442
+
443
+		return $this->columnContent('cb', $content, 'center');
444
+	}
445
+
446
+
447
+	/**
448
+	 *    column status
449
+	 *
450
+	 * @param EE_Registration $registration
451
+	 * @return string
452
+	 * @throws EE_Error
453
+	 */
454
+	public function column_status(EE_Registration $registration)
455
+	{
456
+		return '
457 457
         <span class="ee-status-dot ee-status-dot--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip" 
458 458
         aria-label="' .  EEH_Template::pretty_status( $registration->status_ID(), false, "sentence" ) . '">        
459 459
         </span>';
460
-    }
461
-
462
-
463
-    /**
464
-     * @param EE_Registration $item
465
-     * @return string
466
-     * @throws EE_Error
467
-     * @throws InvalidArgumentException
468
-     * @throws InvalidDataTypeException
469
-     * @throws InvalidInterfaceException
470
-     * @throws ReflectionException
471
-     */
472
-    public function column__REG_ID(EE_Registration $item)
473
-    {
474
-        $content  = $item->ID();
475
-        $attendee = $item->attendee();
476
-
477
-        $content  .= '<br>';
478
-        $content .= '<span class="show-on-mobile-view-only">';
479
-        // $content .= esc_html__('Registrant Name', 'event_espresso');
480
-        // $content  .= '<div class="show-on-mobile-view-only">';
481
-        // $content  .= '&nbsp;';
482
-        $content  .= $attendee instanceof EE_Attendee
483
-            ? $attendee->full_name()
484
-            : '';
485
-        // $content .= '</span> ';
486
-        // $content  .= '&nbsp;';
487
-        // $content  .= sprintf(
488
-        //     esc_html__('(%1$s / %2$s)', 'event_espresso'),
489
-        //     $item->count(),
490
-        //     $item->group_size()
491
-        // );
492
-        // $content  .= '<br>';
493
-        // $content  .= sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
494
-        // $content  .= '</div>';
495
-
496
-        return $this->columnContent('_REG_ID', $content, 'end');
497
-    }
498
-
499
-
500
-    /**
501
-     * @param EE_Registration $item
502
-     * @return string
503
-     * @throws EE_Error
504
-     * @throws InvalidArgumentException
505
-     * @throws InvalidDataTypeException
506
-     * @throws InvalidInterfaceException
507
-     * @throws ReflectionException
508
-     */
509
-    public function column__REG_date(EE_Registration $item)
510
-    {
511
-        $this->_set_related_details($item);
512
-        // Build row actions
513
-        $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
514
-            [
515
-                'action' => 'view_transaction',
516
-                'TXN_ID' => $this->_transaction_details['id'],
517
-            ],
518
-            TXN_ADMIN_URL
519
-        );
520
-        $view_link    = EE_Registry::instance()->CAP->current_user_can(
521
-            'ee_read_transaction',
522
-            'espresso_transactions_view_transaction'
523
-        )
524
-            ? '<a class="ee-aria-tooltip ee-status-color-' . $this->_transaction_details['status'] . '" href="'
525
-              . $view_lnk_url
526
-              . '" aria-label="'
527
-              . esc_attr($this->_transaction_details['title_attr'])
528
-              . '">'
529
-              . $item->get_i18n_datetime('REG_date', 'M jS Y g:i a')
530
-              . '</a>'
531
-            : $item->get_i18n_datetime('REG_date');
532
-        $view_link    .= ' <span class="ee-status-text-small">'
533
-                         . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence')
534
-                         . '</span>';
535
-
536
-        return $this->columnContent('_REG_date', $view_link);
537
-    }
538
-
539
-
540
-    /**
541
-     * @param EE_Registration $item
542
-     * @return string
543
-     * @throws EE_Error
544
-     * @throws InvalidArgumentException
545
-     * @throws InvalidDataTypeException
546
-     * @throws InvalidInterfaceException
547
-     * @throws ReflectionException
548
-     */
549
-    public function column_event_name(EE_Registration $item)
550
-    {
551
-        $this->_set_related_details($item);
552
-        // page=espresso_events&action=edit_event&EVT_ID=2&edit_event_nonce=cf3a7e5b62
553
-        $EVT_ID     = $item->event_ID();
554
-        $event_name = $item->event_name();
555
-        $event_name =
556
-            $event_name
557
-                ?: esc_html__("No Associated Event", 'event_espresso');
558
-        $event_name = wp_trim_words($event_name, 30, '...');
559
-        if ($EVT_ID) {
560
-            $edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(
561
-                ['action' => 'edit', 'post' => $EVT_ID],
562
-                EVENTS_ADMIN_URL
563
-            );
564
-            $edit_event              =
565
-                EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID)
566
-                    ? '<a class="ee-aria-tooltip ee-status-color-'
567
-                      . $this->_event_details['status']
568
-                      . '" href="'
569
-                      . $edit_event_url
570
-                      . '" aria-label="'
571
-                      . esc_attr($this->_event_details['title_attr'])
572
-                      . '">'
573
-                      . $event_name
574
-                      . '</a>'
575
-                    : $event_name;
576
-            $edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(['event_id' => $EVT_ID], REG_ADMIN_URL);
577
-            $actions['event_filter'] = '<a class="ee-aria-tooltip" href="' . $edit_event_url . '" aria-label="';
578
-            $actions['event_filter'] .= sprintf(
579
-                esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'),
580
-                $event_name
581
-            );
582
-            $actions['event_filter'] .= '">' . esc_html__('View Registrations', 'event_espresso') . '</a>';
583
-        } else {
584
-            $edit_event              = $event_name;
585
-            $actions['event_filter'] = '';
586
-        }
587
-        $content = sprintf('%1$s %2$s', $edit_event, $this->row_actions($actions));
588
-
589
-        return $this->columnContent('event_name', $content);
590
-    }
591
-
592
-
593
-    /**
594
-     * @param EE_Registration $item
595
-     * @return string
596
-     * @throws EE_Error
597
-     * @throws InvalidArgumentException
598
-     * @throws InvalidDataTypeException
599
-     * @throws InvalidInterfaceException
600
-     * @throws ReflectionException
601
-     */
602
-    public function column_DTT_EVT_start(EE_Registration $item)
603
-    {
604
-        $datetime_strings = [];
605
-        $ticket           = $item->ticket();
606
-        if ($ticket instanceof EE_Ticket) {
607
-            $remove_defaults = ['default_where_conditions' => 'none'];
608
-            $datetimes       = $ticket->datetimes($remove_defaults);
609
-            foreach ($datetimes as $datetime) {
610
-                $datetime_strings[] = $datetime->get_i18n_datetime('DTT_EVT_start', 'M jS Y g:i a');
611
-            }
612
-            $content = $this->generateDisplayForDatetimes($datetime_strings);
613
-        } else {
614
-            $content = esc_html__('There is no ticket on this registration', 'event_espresso');
615
-        }
616
-        return $this->columnContent('DTT_EVT_start', $content);
617
-    }
618
-
619
-
620
-    /**
621
-     * Receives an array of datetime strings to display and converts them to the html container for the column.
622
-     *
623
-     * @param array $datetime_strings
624
-     * @return string
625
-     */
626
-    public function generateDisplayForDateTimes(array $datetime_strings)
627
-    {
628
-        $content       = '<div class="ee-registration-event-datetimes-container">';
629
-        $expand_toggle = count($datetime_strings) > 1
630
-            ? ' <span aria-label="' . esc_attr__('Click to view all dates', 'event_espresso')
631
-              . '" class="ee-aria-tooltip ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>'
632
-            : '';
633
-        // get first item for initial visibility
634
-        $content .= '<div class="left">' . array_shift($datetime_strings) . '</div>';
635
-        $content .= $expand_toggle;
636
-        if ($datetime_strings) {
637
-            $content .= '<div style="clear:both"></div>';
638
-            $content .= '<div class="ee-registration-event-datetimes-container more-items hidden">';
639
-            $content .= implode("<br />", $datetime_strings);
640
-            $content .= '</div>';
641
-        }
642
-        $content .= '</div>';
643
-        return $content;
644
-    }
645
-
646
-
647
-    /**
648
-     * @param EE_Registration $item
649
-     * @return string
650
-     * @throws EE_Error
651
-     * @throws InvalidArgumentException
652
-     * @throws InvalidDataTypeException
653
-     * @throws InvalidInterfaceException
654
-     * @throws ReflectionException
655
-     */
656
-    public function column_ATT_fname(EE_Registration $item)
657
-    {
658
-        $attendee      = $item->attendee();
659
-        $edit_lnk_url  = EE_Admin_Page::add_query_args_and_nonce(
660
-            [
661
-                'action'  => 'view_registration',
662
-                '_REG_ID' => $item->ID(),
663
-            ],
664
-            REG_ADMIN_URL
665
-        );
666
-        $attendee_name = $attendee instanceof EE_Attendee
667
-            ? $attendee->full_name()
668
-            : '';
669
-        $link          = '<span>';
670
-        $link          .= EE_Registry::instance()->CAP->current_user_can(
671
-            'ee_read_registration',
672
-            'espresso_registrations_view_registration',
673
-            $item->ID()
674
-        )
675
-            ? '<a class="ee-aria-tooltip" href="'
676
-              . $edit_lnk_url
677
-              . '" aria-label="'
678
-              . esc_attr__('View Registration Details', 'event_espresso')
679
-              . '">'
680
-              . $attendee_name
681
-              . '</a>'
682
-            : $attendee_name;
683
-        $link          .= $item->count() === 1
684
-            ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon ee-icon-size-8"></div></sup>'
685
-            : '';
686
-        $t             = $item->get_first_related('Transaction');
687
-        $payment_count = $t instanceof EE_Transaction
688
-            ? $t->count_related('Payment')
689
-            : 0;
690
-        // append group count to name
691
-        $link .= '&nbsp;' . sprintf(esc_html__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
692
-        $link .= '</span>';
693
-        // append reg_code
694
-        $link .=  sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
695
-        // reg status text for accessibility
696
-        $link   .= '<span class="ee-status-text-small">'
697
-                   . EEH_Template::pretty_status($item->status_ID(), false, 'sentence')
698
-                   . '</span>';
699
-        $action = ['_REG_ID' => $item->ID()];
700
-        if (isset($this->_req_data['event_id'])) {
701
-            $action['event_id'] = $item->event_ID();
702
-        }
703
-        // trash/restore/delete actions
704
-        $actions = [];
705
-        if (
706
-            $this->_view !== 'trash'
707
-            && $payment_count === 0
708
-            && EE_Registry::instance()->CAP->current_user_can(
709
-                'ee_delete_registration',
710
-                'espresso_registrations_trash_registrations',
711
-                $item->ID()
712
-            )
713
-        ) {
714
-            $action['action'] = 'trash_registrations';
715
-            $trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
716
-                $action,
717
-                REG_ADMIN_URL
718
-            );
719
-            $actions['trash'] = '<a class="ee-aria-tooltip" href="'
720
-                                . $trash_lnk_url
721
-                                . '" aria-label="'
722
-                                . esc_attr__('Trash Registration', 'event_espresso')
723
-                                . '">' . esc_html__('Trash', 'event_espresso') . '</a>';
724
-        } elseif ($this->_view === 'trash') {
725
-            // restore registration link
726
-            if (
727
-                EE_Registry::instance()->CAP->current_user_can(
728
-                    'ee_delete_registration',
729
-                    'espresso_registrations_restore_registrations',
730
-                    $item->ID()
731
-                )
732
-            ) {
733
-                $action['action']   = 'restore_registrations';
734
-                $restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
735
-                    $action,
736
-                    REG_ADMIN_URL
737
-                );
738
-                $actions['restore'] = '<a class="ee-aria-tooltip" href="'
739
-                                      . $restore_lnk_url
740
-                                      . '" aria-label="'
741
-                                      . esc_attr__('Restore Registration', 'event_espresso') . '">'
742
-                                      . esc_html__('Restore', 'event_espresso') . '</a>';
743
-            }
744
-            if (
745
-                EE_Registry::instance()->CAP->current_user_can(
746
-                    'ee_delete_registration',
747
-                    'espresso_registrations_ee_delete_registrations',
748
-                    $item->ID()
749
-                )
750
-            ) {
751
-                $action['action']  = 'delete_registrations';
752
-                $delete_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
753
-                    $action,
754
-                    REG_ADMIN_URL
755
-                );
756
-                $actions['delete'] = '<a class="ee-aria-tooltip" href="'
757
-                                     . $delete_lnk_url
758
-                                     . '" aria-label="'
759
-                                     . esc_attr__('Delete Registration Permanently', 'event_espresso')
760
-                                     . '">'
761
-                                     . esc_html__('Delete', 'event_espresso')
762
-                                     . '</a>';
763
-            }
764
-        }
765
-        $content = sprintf('%1$s %2$s', $link, $this->row_actions($actions));
766
-        return $this->columnContent('ATT_fname', $content);
767
-    }
768
-
769
-
770
-    /**
771
-     * @param EE_Registration $item
772
-     * @return string
773
-     * @throws EE_Error
774
-     * @throws InvalidArgumentException
775
-     * @throws InvalidDataTypeException
776
-     * @throws InvalidInterfaceException
777
-     * @throws ReflectionException
778
-     */
779
-    public function column_ATT_email(EE_Registration $item)
780
-    {
781
-        $attendee = $item->get_first_related('Attendee');
782
-        $content = ! $attendee instanceof EE_Attendee
783
-            ? esc_html__('No attached contact record.', 'event_espresso')
784
-            : $attendee->email();
785
-        return $this->columnContent('ATT_email', $content);
786
-    }
787
-
788
-
789
-    /**
790
-     * @param EE_Registration $item
791
-     * @return string
792
-     */
793
-    public function column__REG_count(EE_Registration $item)
794
-    {
795
-        $content = sprintf(esc_html__('%1$s / %2$s', 'event_espresso'), $item->count(), $item->group_size());
796
-        return $this->columnContent('_REG_count', $content);
797
-    }
798
-
799
-
800
-    /**
801
-     * @param EE_Registration $item
802
-     * @return string
803
-     * @throws EE_Error
804
-     * @throws ReflectionException
805
-     */
806
-    public function column_PRC_amount(EE_Registration $item)
807
-    {
808
-        $ticket   = $item->ticket();
809
-        $req_data = $this->_admin_page->get_request_data();
810
-        $content  = isset($req_data['event_id']) && $ticket instanceof EE_Ticket
811
-            ? '<span class="TKT_name">' . $ticket->name() . '</span><br />'
812
-            : '';
813
-        if ($item->final_price() > 0) {
814
-            $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
815
-        } else {
816
-            // free event
817
-            $content .= '<span class="reg-overview-free-event-spn reg-pad-rght">'
818
-                        . esc_html__('free', 'event_espresso')
819
-                        . '</span>';
820
-        }
821
-
822
-        return $this->columnContent('PRC_amount', $content, 'end');
823
-    }
824
-
825
-
826
-    /**
827
-     * @param EE_Registration $item
828
-     * @return string
829
-     * @throws EE_Error
830
-     * @throws ReflectionException
831
-     */
832
-    public function column__REG_final_price(EE_Registration $item)
833
-    {
834
-        $ticket   = $item->ticket();
835
-        $req_data = $this->_admin_page->get_request_data();
836
-        $content  = isset($req_data['event_id']) || ! $ticket instanceof EE_Ticket
837
-            ? ''
838
-            : '<span class="TKT_name">' . $ticket->name() . '</span> ';
839
-        $content  .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
840
-        return $this->columnContent('_REG_final_price', $content, 'end');
841
-    }
842
-
843
-
844
-    /**
845
-     * @param EE_Registration $item
846
-     * @return string
847
-     * @throws EE_Error
848
-     */
849
-    public function column__REG_paid(EE_Registration $item)
850
-    {
851
-        $payment_method      = $item->payment_method();
852
-        $payment_method_name = $payment_method instanceof EE_Payment_Method
853
-            ? $payment_method->admin_name()
854
-            : esc_html__('Unknown', 'event_espresso');
855
-        $content             = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span> ';
856
-        if ($item->paid() > 0) {
857
-            $content .= '<span class="ee-status-text-small">'
858
-                        . sprintf(
859
-                            esc_html__('...via %s', 'event_espresso'),
860
-                            $payment_method_name
861
-                        )
862
-                        . '</span>';
863
-        }
864
-        return $this->columnContent('_REG_paid', $content, 'end');
865
-    }
866
-
867
-
868
-    /**
869
-     * @param EE_Registration $item
870
-     * @return string
871
-     * @throws EE_Error
872
-     * @throws EntityNotFoundException
873
-     * @throws InvalidArgumentException
874
-     * @throws InvalidDataTypeException
875
-     * @throws InvalidInterfaceException
876
-     * @throws ReflectionException
877
-     */
878
-    public function column_TXN_total(EE_Registration $item)
879
-    {
880
-        if ($item->transaction()) {
881
-            $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
882
-                [
883
-                    'action' => 'view_transaction',
884
-                    'TXN_ID' => $item->transaction_ID(),
885
-                ],
886
-                TXN_ADMIN_URL
887
-            );
888
-            $content = EE_Registry::instance()->CAP->current_user_can(
889
-                'ee_read_transaction',
890
-                'espresso_transactions_view_transaction',
891
-                $item->transaction_ID()
892
-            )
893
-                ? '<span class="reg-pad-rght"><a class="ee-aria-tooltip status-'
894
-                  . $item->transaction()->status_ID()
895
-                  . '" href="'
896
-                  . $view_txn_lnk_url
897
-                  . '"  aria-label="'
898
-                  . esc_attr__('View Transaction', 'event_espresso')
899
-                  . '">'
900
-                  . $item->transaction()->pretty_total()
901
-                  . '</a></span>'
902
-                : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>';
903
-        } else {
904
-            $content = esc_html__("None", "event_espresso");
905
-        }
906
-        return $this->columnContent('TXN_total', $content, 'end');
907
-    }
908
-
909
-
910
-    /**
911
-     * @param EE_Registration $item
912
-     * @return string
913
-     * @throws EE_Error
914
-     * @throws EntityNotFoundException
915
-     * @throws InvalidArgumentException
916
-     * @throws InvalidDataTypeException
917
-     * @throws InvalidInterfaceException
918
-     * @throws ReflectionException
919
-     */
920
-    public function column_TXN_paid(EE_Registration $item)
921
-    {
922
-        $content = '&nbsp;';
923
-        if ($item->count() === 1) {
924
-            $transaction = $item->transaction()
925
-                ? $item->transaction()
926
-                : EE_Transaction::new_instance();
927
-            if ($transaction->paid() >= $transaction->total()) {
928
-                $content = '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>';
929
-            } else {
930
-                $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
931
-                    [
932
-                        'action' => 'view_transaction',
933
-                        'TXN_ID' => $item->transaction_ID(),
934
-                    ],
935
-                    TXN_ADMIN_URL
936
-                );
937
-                $content = EE_Registry::instance()->CAP->current_user_can(
938
-                    'ee_read_transaction',
939
-                    'espresso_transactions_view_transaction',
940
-                    $item->transaction_ID()
941
-                )
942
-                    ? '<span class="reg-pad-rght"><a class="ee-aria-tooltip status-'
943
-                      . $transaction->status_ID()
944
-                      . '" href="'
945
-                      . $view_txn_lnk_url
946
-                      . '"  aria-label="'
947
-                      . esc_attr__('View Transaction', 'event_espresso')
948
-                      . '">'
949
-                      . $item->transaction()->pretty_paid()
950
-                      . '</a><span>'
951
-                    : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
952
-            }
953
-        }
954
-        return $this->columnContent('TXN_paid', $content, 'end');
955
-    }
956
-
957
-
958
-    /**
959
-     * column_actions
960
-     *
961
-     * @param EE_Registration $item
962
-     * @return string
963
-     * @throws EE_Error
964
-     * @throws InvalidArgumentException
965
-     * @throws InvalidDataTypeException
966
-     * @throws InvalidInterfaceException
967
-     * @throws ReflectionException
968
-     */
969
-    public function column_actions(EE_Registration $item)
970
-    {
971
-        $actions  = [];
972
-        $attendee = $item->attendee();
973
-        $this->_set_related_details($item);
974
-
975
-        // Build row actions
976
-        if (
977
-            EE_Registry::instance()->CAP->current_user_can(
978
-                'ee_read_registration',
979
-                'espresso_registrations_view_registration',
980
-                $item->ID()
981
-            )
982
-        ) {
983
-            $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
984
-                [
985
-                    'action'  => 'view_registration',
986
-                    '_REG_ID' => $item->ID(),
987
-                ],
988
-                REG_ADMIN_URL
989
-            );
990
-            $actions['view_lnk'] = '
460
+	}
461
+
462
+
463
+	/**
464
+	 * @param EE_Registration $item
465
+	 * @return string
466
+	 * @throws EE_Error
467
+	 * @throws InvalidArgumentException
468
+	 * @throws InvalidDataTypeException
469
+	 * @throws InvalidInterfaceException
470
+	 * @throws ReflectionException
471
+	 */
472
+	public function column__REG_ID(EE_Registration $item)
473
+	{
474
+		$content  = $item->ID();
475
+		$attendee = $item->attendee();
476
+
477
+		$content  .= '<br>';
478
+		$content .= '<span class="show-on-mobile-view-only">';
479
+		// $content .= esc_html__('Registrant Name', 'event_espresso');
480
+		// $content  .= '<div class="show-on-mobile-view-only">';
481
+		// $content  .= '&nbsp;';
482
+		$content  .= $attendee instanceof EE_Attendee
483
+			? $attendee->full_name()
484
+			: '';
485
+		// $content .= '</span> ';
486
+		// $content  .= '&nbsp;';
487
+		// $content  .= sprintf(
488
+		//     esc_html__('(%1$s / %2$s)', 'event_espresso'),
489
+		//     $item->count(),
490
+		//     $item->group_size()
491
+		// );
492
+		// $content  .= '<br>';
493
+		// $content  .= sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
494
+		// $content  .= '</div>';
495
+
496
+		return $this->columnContent('_REG_ID', $content, 'end');
497
+	}
498
+
499
+
500
+	/**
501
+	 * @param EE_Registration $item
502
+	 * @return string
503
+	 * @throws EE_Error
504
+	 * @throws InvalidArgumentException
505
+	 * @throws InvalidDataTypeException
506
+	 * @throws InvalidInterfaceException
507
+	 * @throws ReflectionException
508
+	 */
509
+	public function column__REG_date(EE_Registration $item)
510
+	{
511
+		$this->_set_related_details($item);
512
+		// Build row actions
513
+		$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
514
+			[
515
+				'action' => 'view_transaction',
516
+				'TXN_ID' => $this->_transaction_details['id'],
517
+			],
518
+			TXN_ADMIN_URL
519
+		);
520
+		$view_link    = EE_Registry::instance()->CAP->current_user_can(
521
+			'ee_read_transaction',
522
+			'espresso_transactions_view_transaction'
523
+		)
524
+			? '<a class="ee-aria-tooltip ee-status-color-' . $this->_transaction_details['status'] . '" href="'
525
+			  . $view_lnk_url
526
+			  . '" aria-label="'
527
+			  . esc_attr($this->_transaction_details['title_attr'])
528
+			  . '">'
529
+			  . $item->get_i18n_datetime('REG_date', 'M jS Y g:i a')
530
+			  . '</a>'
531
+			: $item->get_i18n_datetime('REG_date');
532
+		$view_link    .= ' <span class="ee-status-text-small">'
533
+						 . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence')
534
+						 . '</span>';
535
+
536
+		return $this->columnContent('_REG_date', $view_link);
537
+	}
538
+
539
+
540
+	/**
541
+	 * @param EE_Registration $item
542
+	 * @return string
543
+	 * @throws EE_Error
544
+	 * @throws InvalidArgumentException
545
+	 * @throws InvalidDataTypeException
546
+	 * @throws InvalidInterfaceException
547
+	 * @throws ReflectionException
548
+	 */
549
+	public function column_event_name(EE_Registration $item)
550
+	{
551
+		$this->_set_related_details($item);
552
+		// page=espresso_events&action=edit_event&EVT_ID=2&edit_event_nonce=cf3a7e5b62
553
+		$EVT_ID     = $item->event_ID();
554
+		$event_name = $item->event_name();
555
+		$event_name =
556
+			$event_name
557
+				?: esc_html__("No Associated Event", 'event_espresso');
558
+		$event_name = wp_trim_words($event_name, 30, '...');
559
+		if ($EVT_ID) {
560
+			$edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(
561
+				['action' => 'edit', 'post' => $EVT_ID],
562
+				EVENTS_ADMIN_URL
563
+			);
564
+			$edit_event              =
565
+				EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID)
566
+					? '<a class="ee-aria-tooltip ee-status-color-'
567
+					  . $this->_event_details['status']
568
+					  . '" href="'
569
+					  . $edit_event_url
570
+					  . '" aria-label="'
571
+					  . esc_attr($this->_event_details['title_attr'])
572
+					  . '">'
573
+					  . $event_name
574
+					  . '</a>'
575
+					: $event_name;
576
+			$edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(['event_id' => $EVT_ID], REG_ADMIN_URL);
577
+			$actions['event_filter'] = '<a class="ee-aria-tooltip" href="' . $edit_event_url . '" aria-label="';
578
+			$actions['event_filter'] .= sprintf(
579
+				esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'),
580
+				$event_name
581
+			);
582
+			$actions['event_filter'] .= '">' . esc_html__('View Registrations', 'event_espresso') . '</a>';
583
+		} else {
584
+			$edit_event              = $event_name;
585
+			$actions['event_filter'] = '';
586
+		}
587
+		$content = sprintf('%1$s %2$s', $edit_event, $this->row_actions($actions));
588
+
589
+		return $this->columnContent('event_name', $content);
590
+	}
591
+
592
+
593
+	/**
594
+	 * @param EE_Registration $item
595
+	 * @return string
596
+	 * @throws EE_Error
597
+	 * @throws InvalidArgumentException
598
+	 * @throws InvalidDataTypeException
599
+	 * @throws InvalidInterfaceException
600
+	 * @throws ReflectionException
601
+	 */
602
+	public function column_DTT_EVT_start(EE_Registration $item)
603
+	{
604
+		$datetime_strings = [];
605
+		$ticket           = $item->ticket();
606
+		if ($ticket instanceof EE_Ticket) {
607
+			$remove_defaults = ['default_where_conditions' => 'none'];
608
+			$datetimes       = $ticket->datetimes($remove_defaults);
609
+			foreach ($datetimes as $datetime) {
610
+				$datetime_strings[] = $datetime->get_i18n_datetime('DTT_EVT_start', 'M jS Y g:i a');
611
+			}
612
+			$content = $this->generateDisplayForDatetimes($datetime_strings);
613
+		} else {
614
+			$content = esc_html__('There is no ticket on this registration', 'event_espresso');
615
+		}
616
+		return $this->columnContent('DTT_EVT_start', $content);
617
+	}
618
+
619
+
620
+	/**
621
+	 * Receives an array of datetime strings to display and converts them to the html container for the column.
622
+	 *
623
+	 * @param array $datetime_strings
624
+	 * @return string
625
+	 */
626
+	public function generateDisplayForDateTimes(array $datetime_strings)
627
+	{
628
+		$content       = '<div class="ee-registration-event-datetimes-container">';
629
+		$expand_toggle = count($datetime_strings) > 1
630
+			? ' <span aria-label="' . esc_attr__('Click to view all dates', 'event_espresso')
631
+			  . '" class="ee-aria-tooltip ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>'
632
+			: '';
633
+		// get first item for initial visibility
634
+		$content .= '<div class="left">' . array_shift($datetime_strings) . '</div>';
635
+		$content .= $expand_toggle;
636
+		if ($datetime_strings) {
637
+			$content .= '<div style="clear:both"></div>';
638
+			$content .= '<div class="ee-registration-event-datetimes-container more-items hidden">';
639
+			$content .= implode("<br />", $datetime_strings);
640
+			$content .= '</div>';
641
+		}
642
+		$content .= '</div>';
643
+		return $content;
644
+	}
645
+
646
+
647
+	/**
648
+	 * @param EE_Registration $item
649
+	 * @return string
650
+	 * @throws EE_Error
651
+	 * @throws InvalidArgumentException
652
+	 * @throws InvalidDataTypeException
653
+	 * @throws InvalidInterfaceException
654
+	 * @throws ReflectionException
655
+	 */
656
+	public function column_ATT_fname(EE_Registration $item)
657
+	{
658
+		$attendee      = $item->attendee();
659
+		$edit_lnk_url  = EE_Admin_Page::add_query_args_and_nonce(
660
+			[
661
+				'action'  => 'view_registration',
662
+				'_REG_ID' => $item->ID(),
663
+			],
664
+			REG_ADMIN_URL
665
+		);
666
+		$attendee_name = $attendee instanceof EE_Attendee
667
+			? $attendee->full_name()
668
+			: '';
669
+		$link          = '<span>';
670
+		$link          .= EE_Registry::instance()->CAP->current_user_can(
671
+			'ee_read_registration',
672
+			'espresso_registrations_view_registration',
673
+			$item->ID()
674
+		)
675
+			? '<a class="ee-aria-tooltip" href="'
676
+			  . $edit_lnk_url
677
+			  . '" aria-label="'
678
+			  . esc_attr__('View Registration Details', 'event_espresso')
679
+			  . '">'
680
+			  . $attendee_name
681
+			  . '</a>'
682
+			: $attendee_name;
683
+		$link          .= $item->count() === 1
684
+			? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon ee-icon-size-8"></div></sup>'
685
+			: '';
686
+		$t             = $item->get_first_related('Transaction');
687
+		$payment_count = $t instanceof EE_Transaction
688
+			? $t->count_related('Payment')
689
+			: 0;
690
+		// append group count to name
691
+		$link .= '&nbsp;' . sprintf(esc_html__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
692
+		$link .= '</span>';
693
+		// append reg_code
694
+		$link .=  sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
695
+		// reg status text for accessibility
696
+		$link   .= '<span class="ee-status-text-small">'
697
+				   . EEH_Template::pretty_status($item->status_ID(), false, 'sentence')
698
+				   . '</span>';
699
+		$action = ['_REG_ID' => $item->ID()];
700
+		if (isset($this->_req_data['event_id'])) {
701
+			$action['event_id'] = $item->event_ID();
702
+		}
703
+		// trash/restore/delete actions
704
+		$actions = [];
705
+		if (
706
+			$this->_view !== 'trash'
707
+			&& $payment_count === 0
708
+			&& EE_Registry::instance()->CAP->current_user_can(
709
+				'ee_delete_registration',
710
+				'espresso_registrations_trash_registrations',
711
+				$item->ID()
712
+			)
713
+		) {
714
+			$action['action'] = 'trash_registrations';
715
+			$trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
716
+				$action,
717
+				REG_ADMIN_URL
718
+			);
719
+			$actions['trash'] = '<a class="ee-aria-tooltip" href="'
720
+								. $trash_lnk_url
721
+								. '" aria-label="'
722
+								. esc_attr__('Trash Registration', 'event_espresso')
723
+								. '">' . esc_html__('Trash', 'event_espresso') . '</a>';
724
+		} elseif ($this->_view === 'trash') {
725
+			// restore registration link
726
+			if (
727
+				EE_Registry::instance()->CAP->current_user_can(
728
+					'ee_delete_registration',
729
+					'espresso_registrations_restore_registrations',
730
+					$item->ID()
731
+				)
732
+			) {
733
+				$action['action']   = 'restore_registrations';
734
+				$restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
735
+					$action,
736
+					REG_ADMIN_URL
737
+				);
738
+				$actions['restore'] = '<a class="ee-aria-tooltip" href="'
739
+									  . $restore_lnk_url
740
+									  . '" aria-label="'
741
+									  . esc_attr__('Restore Registration', 'event_espresso') . '">'
742
+									  . esc_html__('Restore', 'event_espresso') . '</a>';
743
+			}
744
+			if (
745
+				EE_Registry::instance()->CAP->current_user_can(
746
+					'ee_delete_registration',
747
+					'espresso_registrations_ee_delete_registrations',
748
+					$item->ID()
749
+				)
750
+			) {
751
+				$action['action']  = 'delete_registrations';
752
+				$delete_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
753
+					$action,
754
+					REG_ADMIN_URL
755
+				);
756
+				$actions['delete'] = '<a class="ee-aria-tooltip" href="'
757
+									 . $delete_lnk_url
758
+									 . '" aria-label="'
759
+									 . esc_attr__('Delete Registration Permanently', 'event_espresso')
760
+									 . '">'
761
+									 . esc_html__('Delete', 'event_espresso')
762
+									 . '</a>';
763
+			}
764
+		}
765
+		$content = sprintf('%1$s %2$s', $link, $this->row_actions($actions));
766
+		return $this->columnContent('ATT_fname', $content);
767
+	}
768
+
769
+
770
+	/**
771
+	 * @param EE_Registration $item
772
+	 * @return string
773
+	 * @throws EE_Error
774
+	 * @throws InvalidArgumentException
775
+	 * @throws InvalidDataTypeException
776
+	 * @throws InvalidInterfaceException
777
+	 * @throws ReflectionException
778
+	 */
779
+	public function column_ATT_email(EE_Registration $item)
780
+	{
781
+		$attendee = $item->get_first_related('Attendee');
782
+		$content = ! $attendee instanceof EE_Attendee
783
+			? esc_html__('No attached contact record.', 'event_espresso')
784
+			: $attendee->email();
785
+		return $this->columnContent('ATT_email', $content);
786
+	}
787
+
788
+
789
+	/**
790
+	 * @param EE_Registration $item
791
+	 * @return string
792
+	 */
793
+	public function column__REG_count(EE_Registration $item)
794
+	{
795
+		$content = sprintf(esc_html__('%1$s / %2$s', 'event_espresso'), $item->count(), $item->group_size());
796
+		return $this->columnContent('_REG_count', $content);
797
+	}
798
+
799
+
800
+	/**
801
+	 * @param EE_Registration $item
802
+	 * @return string
803
+	 * @throws EE_Error
804
+	 * @throws ReflectionException
805
+	 */
806
+	public function column_PRC_amount(EE_Registration $item)
807
+	{
808
+		$ticket   = $item->ticket();
809
+		$req_data = $this->_admin_page->get_request_data();
810
+		$content  = isset($req_data['event_id']) && $ticket instanceof EE_Ticket
811
+			? '<span class="TKT_name">' . $ticket->name() . '</span><br />'
812
+			: '';
813
+		if ($item->final_price() > 0) {
814
+			$content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
815
+		} else {
816
+			// free event
817
+			$content .= '<span class="reg-overview-free-event-spn reg-pad-rght">'
818
+						. esc_html__('free', 'event_espresso')
819
+						. '</span>';
820
+		}
821
+
822
+		return $this->columnContent('PRC_amount', $content, 'end');
823
+	}
824
+
825
+
826
+	/**
827
+	 * @param EE_Registration $item
828
+	 * @return string
829
+	 * @throws EE_Error
830
+	 * @throws ReflectionException
831
+	 */
832
+	public function column__REG_final_price(EE_Registration $item)
833
+	{
834
+		$ticket   = $item->ticket();
835
+		$req_data = $this->_admin_page->get_request_data();
836
+		$content  = isset($req_data['event_id']) || ! $ticket instanceof EE_Ticket
837
+			? ''
838
+			: '<span class="TKT_name">' . $ticket->name() . '</span> ';
839
+		$content  .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
840
+		return $this->columnContent('_REG_final_price', $content, 'end');
841
+	}
842
+
843
+
844
+	/**
845
+	 * @param EE_Registration $item
846
+	 * @return string
847
+	 * @throws EE_Error
848
+	 */
849
+	public function column__REG_paid(EE_Registration $item)
850
+	{
851
+		$payment_method      = $item->payment_method();
852
+		$payment_method_name = $payment_method instanceof EE_Payment_Method
853
+			? $payment_method->admin_name()
854
+			: esc_html__('Unknown', 'event_espresso');
855
+		$content             = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span> ';
856
+		if ($item->paid() > 0) {
857
+			$content .= '<span class="ee-status-text-small">'
858
+						. sprintf(
859
+							esc_html__('...via %s', 'event_espresso'),
860
+							$payment_method_name
861
+						)
862
+						. '</span>';
863
+		}
864
+		return $this->columnContent('_REG_paid', $content, 'end');
865
+	}
866
+
867
+
868
+	/**
869
+	 * @param EE_Registration $item
870
+	 * @return string
871
+	 * @throws EE_Error
872
+	 * @throws EntityNotFoundException
873
+	 * @throws InvalidArgumentException
874
+	 * @throws InvalidDataTypeException
875
+	 * @throws InvalidInterfaceException
876
+	 * @throws ReflectionException
877
+	 */
878
+	public function column_TXN_total(EE_Registration $item)
879
+	{
880
+		if ($item->transaction()) {
881
+			$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
882
+				[
883
+					'action' => 'view_transaction',
884
+					'TXN_ID' => $item->transaction_ID(),
885
+				],
886
+				TXN_ADMIN_URL
887
+			);
888
+			$content = EE_Registry::instance()->CAP->current_user_can(
889
+				'ee_read_transaction',
890
+				'espresso_transactions_view_transaction',
891
+				$item->transaction_ID()
892
+			)
893
+				? '<span class="reg-pad-rght"><a class="ee-aria-tooltip status-'
894
+				  . $item->transaction()->status_ID()
895
+				  . '" href="'
896
+				  . $view_txn_lnk_url
897
+				  . '"  aria-label="'
898
+				  . esc_attr__('View Transaction', 'event_espresso')
899
+				  . '">'
900
+				  . $item->transaction()->pretty_total()
901
+				  . '</a></span>'
902
+				: '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>';
903
+		} else {
904
+			$content = esc_html__("None", "event_espresso");
905
+		}
906
+		return $this->columnContent('TXN_total', $content, 'end');
907
+	}
908
+
909
+
910
+	/**
911
+	 * @param EE_Registration $item
912
+	 * @return string
913
+	 * @throws EE_Error
914
+	 * @throws EntityNotFoundException
915
+	 * @throws InvalidArgumentException
916
+	 * @throws InvalidDataTypeException
917
+	 * @throws InvalidInterfaceException
918
+	 * @throws ReflectionException
919
+	 */
920
+	public function column_TXN_paid(EE_Registration $item)
921
+	{
922
+		$content = '&nbsp;';
923
+		if ($item->count() === 1) {
924
+			$transaction = $item->transaction()
925
+				? $item->transaction()
926
+				: EE_Transaction::new_instance();
927
+			if ($transaction->paid() >= $transaction->total()) {
928
+				$content = '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>';
929
+			} else {
930
+				$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
931
+					[
932
+						'action' => 'view_transaction',
933
+						'TXN_ID' => $item->transaction_ID(),
934
+					],
935
+					TXN_ADMIN_URL
936
+				);
937
+				$content = EE_Registry::instance()->CAP->current_user_can(
938
+					'ee_read_transaction',
939
+					'espresso_transactions_view_transaction',
940
+					$item->transaction_ID()
941
+				)
942
+					? '<span class="reg-pad-rght"><a class="ee-aria-tooltip status-'
943
+					  . $transaction->status_ID()
944
+					  . '" href="'
945
+					  . $view_txn_lnk_url
946
+					  . '"  aria-label="'
947
+					  . esc_attr__('View Transaction', 'event_espresso')
948
+					  . '">'
949
+					  . $item->transaction()->pretty_paid()
950
+					  . '</a><span>'
951
+					: '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
952
+			}
953
+		}
954
+		return $this->columnContent('TXN_paid', $content, 'end');
955
+	}
956
+
957
+
958
+	/**
959
+	 * column_actions
960
+	 *
961
+	 * @param EE_Registration $item
962
+	 * @return string
963
+	 * @throws EE_Error
964
+	 * @throws InvalidArgumentException
965
+	 * @throws InvalidDataTypeException
966
+	 * @throws InvalidInterfaceException
967
+	 * @throws ReflectionException
968
+	 */
969
+	public function column_actions(EE_Registration $item)
970
+	{
971
+		$actions  = [];
972
+		$attendee = $item->attendee();
973
+		$this->_set_related_details($item);
974
+
975
+		// Build row actions
976
+		if (
977
+			EE_Registry::instance()->CAP->current_user_can(
978
+				'ee_read_registration',
979
+				'espresso_registrations_view_registration',
980
+				$item->ID()
981
+			)
982
+		) {
983
+			$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
984
+				[
985
+					'action'  => 'view_registration',
986
+					'_REG_ID' => $item->ID(),
987
+				],
988
+				REG_ADMIN_URL
989
+			);
990
+			$actions['view_lnk'] = '
991 991
             <li>
992 992
                 <a href="' . $view_lnk_url . '" aria-label="'
993
-                . esc_attr__('View Registration Details', 'event_espresso')
994
-                . '" class="ee-aria-tooltip tiny-text">
993
+				. esc_attr__('View Registration Details', 'event_espresso')
994
+				. '" class="ee-aria-tooltip tiny-text">
995 995
 				    <div class="dashicons dashicons-clipboard"></div>
996 996
 			    </a>
997 997
 			</li>';
998
-        }
999
-
1000
-        if (
1001
-            $attendee instanceof EE_Attendee
1002
-            && EE_Registry::instance()->CAP->current_user_can(
1003
-                'ee_edit_contacts',
1004
-                'espresso_registrations_edit_attendee'
1005
-            )
1006
-        ) {
1007
-            $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
1008
-                [
1009
-                    'action' => 'edit_attendee',
1010
-                    'post'   => $item->attendee_ID(),
1011
-                ],
1012
-                REG_ADMIN_URL
1013
-            );
1014
-            $actions['edit_lnk'] = '
998
+		}
999
+
1000
+		if (
1001
+			$attendee instanceof EE_Attendee
1002
+			&& EE_Registry::instance()->CAP->current_user_can(
1003
+				'ee_edit_contacts',
1004
+				'espresso_registrations_edit_attendee'
1005
+			)
1006
+		) {
1007
+			$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
1008
+				[
1009
+					'action' => 'edit_attendee',
1010
+					'post'   => $item->attendee_ID(),
1011
+				],
1012
+				REG_ADMIN_URL
1013
+			);
1014
+			$actions['edit_lnk'] = '
1015 1015
 			<li>
1016 1016
                 <a href="' . $edit_lnk_url . '" aria-label="'
1017
-                . esc_attr__('Edit Contact Details', 'event_espresso')
1018
-                . '" class="ee-aria-tooltip tiny-text">
1017
+				. esc_attr__('Edit Contact Details', 'event_espresso')
1018
+				. '" class="ee-aria-tooltip tiny-text">
1019 1019
                     <div class="dashicons dashicons-groups ee-icon-size-16"></div>
1020 1020
                 </a>
1021 1021
 			</li>';
1022
-        }
1023
-
1024
-        if (
1025
-            $attendee instanceof EE_Attendee
1026
-            && EE_Registry::instance()->CAP->current_user_can(
1027
-                'ee_send_message',
1028
-                'espresso_registrations_resend_registration',
1029
-                $item->ID()
1030
-            )
1031
-        ) {
1032
-            $resend_reg_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
1033
-                [
1034
-                    'action'  => 'resend_registration',
1035
-                    '_REG_ID' => $item->ID(),
1036
-                ],
1037
-                REG_ADMIN_URL,
1038
-                true
1039
-            );
1040
-            $actions['resend_reg_lnk'] = '
1022
+		}
1023
+
1024
+		if (
1025
+			$attendee instanceof EE_Attendee
1026
+			&& EE_Registry::instance()->CAP->current_user_can(
1027
+				'ee_send_message',
1028
+				'espresso_registrations_resend_registration',
1029
+				$item->ID()
1030
+			)
1031
+		) {
1032
+			$resend_reg_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
1033
+				[
1034
+					'action'  => 'resend_registration',
1035
+					'_REG_ID' => $item->ID(),
1036
+				],
1037
+				REG_ADMIN_URL,
1038
+				true
1039
+			);
1040
+			$actions['resend_reg_lnk'] = '
1041 1041
 			<li>
1042 1042
 			    <a href="' . $resend_reg_lnk_url . '" aria-label="'
1043
-                . esc_attr__('Resend Registration Details', 'event_espresso')
1044
-                . '" class="ee-aria-tooltip tiny-text">
1043
+				. esc_attr__('Resend Registration Details', 'event_espresso')
1044
+				. '" class="ee-aria-tooltip tiny-text">
1045 1045
 			        <div class="dashicons dashicons-email-alt"></div>
1046 1046
 			    </a>
1047 1047
             </li>';
1048
-        }
1049
-
1050
-        if (
1051
-            EE_Registry::instance()->CAP->current_user_can(
1052
-                'ee_read_transaction',
1053
-                'espresso_transactions_view_transaction',
1054
-                $this->_transaction_details['id']
1055
-            )
1056
-        ) {
1057
-            $view_txn_lnk_url        = EE_Admin_Page::add_query_args_and_nonce(
1058
-                [
1059
-                    'action' => 'view_transaction',
1060
-                    'TXN_ID' => $this->_transaction_details['id'],
1061
-                ],
1062
-                TXN_ADMIN_URL
1063
-            );
1064
-            $actions['view_txn_lnk'] = '
1048
+		}
1049
+
1050
+		if (
1051
+			EE_Registry::instance()->CAP->current_user_can(
1052
+				'ee_read_transaction',
1053
+				'espresso_transactions_view_transaction',
1054
+				$this->_transaction_details['id']
1055
+			)
1056
+		) {
1057
+			$view_txn_lnk_url        = EE_Admin_Page::add_query_args_and_nonce(
1058
+				[
1059
+					'action' => 'view_transaction',
1060
+					'TXN_ID' => $this->_transaction_details['id'],
1061
+				],
1062
+				TXN_ADMIN_URL
1063
+			);
1064
+			$actions['view_txn_lnk'] = '
1065 1065
 			<li>
1066 1066
                 <a class="ee-aria-tooltip ee-status-color-' . $this->_transaction_details['status']
1067
-                . ' tiny-text" href="' . $view_txn_lnk_url
1068
-                . '"  aria-label="' . $this->_transaction_details['title_attr'] . '">
1067
+				. ' tiny-text" href="' . $view_txn_lnk_url
1068
+				. '"  aria-label="' . $this->_transaction_details['title_attr'] . '">
1069 1069
                     <div class="dashicons dashicons-cart"></div>
1070 1070
                 </a>
1071 1071
 			</li>';
1072
-        }
1073
-
1074
-        // only show invoice link if message type is active.
1075
-        if (
1076
-            $attendee instanceof EE_Attendee
1077
-            && $item->is_primary_registrant()
1078
-            && EEH_MSG_Template::is_mt_active('invoice')
1079
-        ) {
1080
-            $actions['dl_invoice_lnk'] = '
1072
+		}
1073
+
1074
+		// only show invoice link if message type is active.
1075
+		if (
1076
+			$attendee instanceof EE_Attendee
1077
+			&& $item->is_primary_registrant()
1078
+			&& EEH_MSG_Template::is_mt_active('invoice')
1079
+		) {
1080
+			$actions['dl_invoice_lnk'] = '
1081 1081
             <li>
1082 1082
                 <a aria-label="' . esc_attr__('View Transaction Invoice', 'event_espresso')
1083
-                . '" target="_blank" href="' . $item->invoice_url() . '" class="ee-aria-tooltip tiny-text">
1083
+				. '" target="_blank" href="' . $item->invoice_url() . '" class="ee-aria-tooltip tiny-text">
1084 1084
                     <span class="dashicons dashicons-media-spreadsheet ee-icon-size-18"></span>
1085 1085
                 </a>
1086 1086
             </li>';
1087
-        }
1087
+		}
1088 1088
 
1089
-        // message list table link (filtered by REG_ID
1090
-        if (
1091
-            EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')
1092
-        ) {
1093
-            $actions['filtered_messages_link'] = '
1089
+		// message list table link (filtered by REG_ID
1090
+		if (
1091
+			EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')
1092
+		) {
1093
+			$actions['filtered_messages_link'] = '
1094 1094
             <li>
1095 1095
                 ' . EEH_MSG_Template::get_message_action_link(
1096
-                'see_notifications_for',
1097
-                null,
1098
-                ['_REG_ID' => $item->ID()]
1099
-            ) . '
1096
+				'see_notifications_for',
1097
+				null,
1098
+				['_REG_ID' => $item->ID()]
1099
+			) . '
1100 1100
             </li>';
1101
-        }
1101
+		}
1102 1102
 
1103
-        $actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this);
1104
-        $content = $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul');
1105
-        return $this->columnContent('actions', $content);
1106
-    }
1103
+		$actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this);
1104
+		$content = $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul');
1105
+		return $this->columnContent('actions', $content);
1106
+	}
1107 1107
 }
Please login to merge, or discard this patch.
Spacing   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -48,10 +48,10 @@  discard block
 block discarded – undo
48 48
     public function __construct(Registrations_Admin_Page $admin_page)
49 49
     {
50 50
         $req_data = $admin_page->get_request_data();
51
-        if (! empty($req_data['event_id'])) {
51
+        if ( ! empty($req_data['event_id'])) {
52 52
             $extra_query_args = [];
53 53
             foreach ($admin_page->get_views() as $view_details) {
54
-                $extra_query_args[ $view_details['slug'] ] = ['event_id' => $req_data['event_id']];
54
+                $extra_query_args[$view_details['slug']] = ['event_id' => $req_data['event_id']];
55 55
             }
56 56
             $this->_views = $admin_page->get_list_table_view_RLs($extra_query_args);
57 57
         }
@@ -83,9 +83,9 @@  discard block
 block discarded – undo
83 83
             'ajax'     => true,
84 84
             'screen'   => $this->_admin_page->get_current_screen()->id,
85 85
         ];
86
-        $req_data            = $this->_admin_page->get_request_data();
86
+        $req_data = $this->_admin_page->get_request_data();
87 87
         if (isset($req_data['event_id'])) {
88
-            $this->_columns        = [
88
+            $this->_columns = [
89 89
                 'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
90 90
                 'status'           => '',
91 91
                 '_REG_ID'          => esc_html__('ID', 'event_espresso'),
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
                 ],
109 109
             ];
110 110
         } else {
111
-            $this->_columns        = [
111
+            $this->_columns = [
112 112
                 'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
113 113
                 'status'           => '',
114 114
                 '_REG_ID'          => esc_html__('ID', 'event_espresso'),
@@ -136,7 +136,7 @@  discard block
 block discarded – undo
136 136
                 'return_url'  => $return_url,
137 137
             ],
138 138
         ];
139
-        $filters                                  = array_diff_key(
139
+        $filters = array_diff_key(
140 140
             $this->_req_data,
141 141
             array_flip(
142 142
                 [
@@ -146,12 +146,12 @@  discard block
 block discarded – undo
146 146
                 ]
147 147
             )
148 148
         );
149
-        if (! empty($filters)) {
149
+        if ( ! empty($filters)) {
150 150
             $this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters;
151 151
         }
152 152
         $this->_primary_column   = '_REG_ID';
153 153
         $this->_sortable_columns = [
154
-            '_REG_date'     => ['_REG_date' => true],   // true means its already sorted
154
+            '_REG_date'     => ['_REG_date' => true], // true means its already sorted
155 155
             /**
156 156
              * Allows users to change the default sort if they wish.
157 157
              * Returning a falsey on this filter will result in the default sort to be by firstname rather than last
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
             'DTT_EVT_start' => ['DTT_EVT_start' => false],
169 169
             '_REG_ID'       => ['_REG_ID' => false],
170 170
         ];
171
-        $this->_hidden_columns   = [];
171
+        $this->_hidden_columns = [];
172 172
     }
173 173
 
174 174
 
@@ -355,14 +355,14 @@  discard block
 block discarded – undo
355 355
         $this_month_r    = date('m', current_time('timestamp'));
356 356
         $days_this_month = date('t', current_time('timestamp'));
357 357
         // setup date query.
358
-        $beginning_string   = EEM_Registration::instance()->convert_datetime_for_query(
358
+        $beginning_string = EEM_Registration::instance()->convert_datetime_for_query(
359 359
             'REG_date',
360
-            $this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start,
360
+            $this_year_r.'-'.$this_month_r.'-01'.' '.$time_start,
361 361
             'Y-m-d H:i:s'
362 362
         );
363
-        $end_string         = EEM_Registration::instance()->convert_datetime_for_query(
363
+        $end_string = EEM_Registration::instance()->convert_datetime_for_query(
364 364
             'REG_date',
365
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end,
365
+            $this_year_r.'-'.$this_month_r.'-'.$days_this_month.' '.$time_end,
366 366
             'Y-m-d H:i:s'
367 367
         );
368 368
         $_where['REG_date'] = [
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
                 $end_string,
373 373
             ],
374 374
         ];
375
-        $_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
375
+        $_where['STS_ID'] = ['!=', EEM_Registration::status_id_incomplete];
376 376
         return EEM_Registration::instance()->count([$_where]);
377 377
     }
378 378
 
@@ -400,17 +400,17 @@  discard block
 block discarded – undo
400 400
             [
401 401
                 EEM_Registration::instance()->convert_datetime_for_query(
402 402
                     'REG_date',
403
-                    $current_date . $time_start,
403
+                    $current_date.$time_start,
404 404
                     'Y-m-d H:i:s'
405 405
                 ),
406 406
                 EEM_Registration::instance()->convert_datetime_for_query(
407 407
                     'REG_date',
408
-                    $current_date . $time_end,
408
+                    $current_date.$time_end,
409 409
                     'Y-m-d H:i:s'
410 410
                 ),
411 411
             ],
412 412
         ];
413
-        $_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
413
+        $_where['STS_ID'] = ['!=', EEM_Registration::status_id_incomplete];
414 414
         return EEM_Registration::instance()->count([$_where]);
415 415
     }
416 416
 
@@ -454,8 +454,8 @@  discard block
 block discarded – undo
454 454
     public function column_status(EE_Registration $registration)
455 455
     {
456 456
         return '
457
-        <span class="ee-status-dot ee-status-dot--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip" 
458
-        aria-label="' .  EEH_Template::pretty_status( $registration->status_ID(), false, "sentence" ) . '">        
457
+        <span class="ee-status-dot ee-status-dot--' . esc_attr($registration->status_ID()).' ee-aria-tooltip" 
458
+        aria-label="' .  EEH_Template::pretty_status($registration->status_ID(), false, "sentence").'">        
459 459
         </span>';
460 460
     }
461 461
 
@@ -474,12 +474,12 @@  discard block
 block discarded – undo
474 474
         $content  = $item->ID();
475 475
         $attendee = $item->attendee();
476 476
 
477
-        $content  .= '<br>';
477
+        $content .= '<br>';
478 478
         $content .= '<span class="show-on-mobile-view-only">';
479 479
         // $content .= esc_html__('Registrant Name', 'event_espresso');
480 480
         // $content  .= '<div class="show-on-mobile-view-only">';
481 481
         // $content  .= '&nbsp;';
482
-        $content  .= $attendee instanceof EE_Attendee
482
+        $content .= $attendee instanceof EE_Attendee
483 483
             ? $attendee->full_name()
484 484
             : '';
485 485
         // $content .= '</span> ';
@@ -517,11 +517,11 @@  discard block
 block discarded – undo
517 517
             ],
518 518
             TXN_ADMIN_URL
519 519
         );
520
-        $view_link    = EE_Registry::instance()->CAP->current_user_can(
520
+        $view_link = EE_Registry::instance()->CAP->current_user_can(
521 521
             'ee_read_transaction',
522 522
             'espresso_transactions_view_transaction'
523 523
         )
524
-            ? '<a class="ee-aria-tooltip ee-status-color-' . $this->_transaction_details['status'] . '" href="'
524
+            ? '<a class="ee-aria-tooltip ee-status-color-'.$this->_transaction_details['status'].'" href="'
525 525
               . $view_lnk_url
526 526
               . '" aria-label="'
527 527
               . esc_attr($this->_transaction_details['title_attr'])
@@ -529,7 +529,7 @@  discard block
 block discarded – undo
529 529
               . $item->get_i18n_datetime('REG_date', 'M jS Y g:i a')
530 530
               . '</a>'
531 531
             : $item->get_i18n_datetime('REG_date');
532
-        $view_link    .= ' <span class="ee-status-text-small">'
532
+        $view_link .= ' <span class="ee-status-text-small">'
533 533
                          . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence')
534 534
                          . '</span>';
535 535
 
@@ -557,11 +557,11 @@  discard block
 block discarded – undo
557 557
                 ?: esc_html__("No Associated Event", 'event_espresso');
558 558
         $event_name = wp_trim_words($event_name, 30, '...');
559 559
         if ($EVT_ID) {
560
-            $edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(
560
+            $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(
561 561
                 ['action' => 'edit', 'post' => $EVT_ID],
562 562
                 EVENTS_ADMIN_URL
563 563
             );
564
-            $edit_event              =
564
+            $edit_event =
565 565
                 EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID)
566 566
                     ? '<a class="ee-aria-tooltip ee-status-color-'
567 567
                       . $this->_event_details['status']
@@ -574,12 +574,12 @@  discard block
 block discarded – undo
574 574
                       . '</a>'
575 575
                     : $event_name;
576 576
             $edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(['event_id' => $EVT_ID], REG_ADMIN_URL);
577
-            $actions['event_filter'] = '<a class="ee-aria-tooltip" href="' . $edit_event_url . '" aria-label="';
577
+            $actions['event_filter'] = '<a class="ee-aria-tooltip" href="'.$edit_event_url.'" aria-label="';
578 578
             $actions['event_filter'] .= sprintf(
579 579
                 esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'),
580 580
                 $event_name
581 581
             );
582
-            $actions['event_filter'] .= '">' . esc_html__('View Registrations', 'event_espresso') . '</a>';
582
+            $actions['event_filter'] .= '">'.esc_html__('View Registrations', 'event_espresso').'</a>';
583 583
         } else {
584 584
             $edit_event              = $event_name;
585 585
             $actions['event_filter'] = '';
@@ -627,11 +627,11 @@  discard block
 block discarded – undo
627 627
     {
628 628
         $content       = '<div class="ee-registration-event-datetimes-container">';
629 629
         $expand_toggle = count($datetime_strings) > 1
630
-            ? ' <span aria-label="' . esc_attr__('Click to view all dates', 'event_espresso')
630
+            ? ' <span aria-label="'.esc_attr__('Click to view all dates', 'event_espresso')
631 631
               . '" class="ee-aria-tooltip ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>'
632 632
             : '';
633 633
         // get first item for initial visibility
634
-        $content .= '<div class="left">' . array_shift($datetime_strings) . '</div>';
634
+        $content .= '<div class="left">'.array_shift($datetime_strings).'</div>';
635 635
         $content .= $expand_toggle;
636 636
         if ($datetime_strings) {
637 637
             $content .= '<div style="clear:both"></div>';
@@ -667,7 +667,7 @@  discard block
 block discarded – undo
667 667
             ? $attendee->full_name()
668 668
             : '';
669 669
         $link          = '<span>';
670
-        $link          .= EE_Registry::instance()->CAP->current_user_can(
670
+        $link .= EE_Registry::instance()->CAP->current_user_can(
671 671
             'ee_read_registration',
672 672
             'espresso_registrations_view_registration',
673 673
             $item->ID()
@@ -680,7 +680,7 @@  discard block
 block discarded – undo
680 680
               . $attendee_name
681 681
               . '</a>'
682 682
             : $attendee_name;
683
-        $link          .= $item->count() === 1
683
+        $link .= $item->count() === 1
684 684
             ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon ee-icon-size-8"></div></sup>'
685 685
             : '';
686 686
         $t             = $item->get_first_related('Transaction');
@@ -688,12 +688,12 @@  discard block
 block discarded – undo
688 688
             ? $t->count_related('Payment')
689 689
             : 0;
690 690
         // append group count to name
691
-        $link .= '&nbsp;' . sprintf(esc_html__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
691
+        $link .= '&nbsp;'.sprintf(esc_html__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
692 692
         $link .= '</span>';
693 693
         // append reg_code
694
-        $link .=  sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
694
+        $link .= sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
695 695
         // reg status text for accessibility
696
-        $link   .= '<span class="ee-status-text-small">'
696
+        $link .= '<span class="ee-status-text-small">'
697 697
                    . EEH_Template::pretty_status($item->status_ID(), false, 'sentence')
698 698
                    . '</span>';
699 699
         $action = ['_REG_ID' => $item->ID()];
@@ -720,7 +720,7 @@  discard block
 block discarded – undo
720 720
                                 . $trash_lnk_url
721 721
                                 . '" aria-label="'
722 722
                                 . esc_attr__('Trash Registration', 'event_espresso')
723
-                                . '">' . esc_html__('Trash', 'event_espresso') . '</a>';
723
+                                . '">'.esc_html__('Trash', 'event_espresso').'</a>';
724 724
         } elseif ($this->_view === 'trash') {
725 725
             // restore registration link
726 726
             if (
@@ -738,8 +738,8 @@  discard block
 block discarded – undo
738 738
                 $actions['restore'] = '<a class="ee-aria-tooltip" href="'
739 739
                                       . $restore_lnk_url
740 740
                                       . '" aria-label="'
741
-                                      . esc_attr__('Restore Registration', 'event_espresso') . '">'
742
-                                      . esc_html__('Restore', 'event_espresso') . '</a>';
741
+                                      . esc_attr__('Restore Registration', 'event_espresso').'">'
742
+                                      . esc_html__('Restore', 'event_espresso').'</a>';
743 743
             }
744 744
             if (
745 745
                 EE_Registry::instance()->CAP->current_user_can(
@@ -808,10 +808,10 @@  discard block
 block discarded – undo
808 808
         $ticket   = $item->ticket();
809 809
         $req_data = $this->_admin_page->get_request_data();
810 810
         $content  = isset($req_data['event_id']) && $ticket instanceof EE_Ticket
811
-            ? '<span class="TKT_name">' . $ticket->name() . '</span><br />'
811
+            ? '<span class="TKT_name">'.$ticket->name().'</span><br />'
812 812
             : '';
813 813
         if ($item->final_price() > 0) {
814
-            $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
814
+            $content .= '<span class="reg-pad-rght">'.$item->pretty_final_price().'</span>';
815 815
         } else {
816 816
             // free event
817 817
             $content .= '<span class="reg-overview-free-event-spn reg-pad-rght">'
@@ -835,8 +835,8 @@  discard block
 block discarded – undo
835 835
         $req_data = $this->_admin_page->get_request_data();
836 836
         $content  = isset($req_data['event_id']) || ! $ticket instanceof EE_Ticket
837 837
             ? ''
838
-            : '<span class="TKT_name">' . $ticket->name() . '</span> ';
839
-        $content  .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
838
+            : '<span class="TKT_name">'.$ticket->name().'</span> ';
839
+        $content .= '<span class="reg-pad-rght">'.$item->pretty_final_price().'</span>';
840 840
         return $this->columnContent('_REG_final_price', $content, 'end');
841 841
     }
842 842
 
@@ -852,7 +852,7 @@  discard block
 block discarded – undo
852 852
         $payment_method_name = $payment_method instanceof EE_Payment_Method
853 853
             ? $payment_method->admin_name()
854 854
             : esc_html__('Unknown', 'event_espresso');
855
-        $content             = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span> ';
855
+        $content             = '<span class="reg-pad-rght">'.$item->pretty_paid().'</span> ';
856 856
         if ($item->paid() > 0) {
857 857
             $content .= '<span class="ee-status-text-small">'
858 858
                         . sprintf(
@@ -899,7 +899,7 @@  discard block
 block discarded – undo
899 899
                   . '">'
900 900
                   . $item->transaction()->pretty_total()
901 901
                   . '</a></span>'
902
-                : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>';
902
+                : '<span class="reg-pad-rght">'.$item->transaction()->pretty_total().'</span>';
903 903
         } else {
904 904
             $content = esc_html__("None", "event_espresso");
905 905
         }
@@ -948,7 +948,7 @@  discard block
 block discarded – undo
948 948
                       . '">'
949 949
                       . $item->transaction()->pretty_paid()
950 950
                       . '</a><span>'
951
-                    : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
951
+                    : '<span class="reg-pad-rght">'.$item->transaction()->pretty_paid().'</span>';
952 952
             }
953 953
         }
954 954
         return $this->columnContent('TXN_paid', $content, 'end');
@@ -989,7 +989,7 @@  discard block
 block discarded – undo
989 989
             );
990 990
             $actions['view_lnk'] = '
991 991
             <li>
992
-                <a href="' . $view_lnk_url . '" aria-label="'
992
+                <a href="' . $view_lnk_url.'" aria-label="'
993 993
                 . esc_attr__('View Registration Details', 'event_espresso')
994 994
                 . '" class="ee-aria-tooltip tiny-text">
995 995
 				    <div class="dashicons dashicons-clipboard"></div>
@@ -1013,7 +1013,7 @@  discard block
 block discarded – undo
1013 1013
             );
1014 1014
             $actions['edit_lnk'] = '
1015 1015
 			<li>
1016
-                <a href="' . $edit_lnk_url . '" aria-label="'
1016
+                <a href="' . $edit_lnk_url.'" aria-label="'
1017 1017
                 . esc_attr__('Edit Contact Details', 'event_espresso')
1018 1018
                 . '" class="ee-aria-tooltip tiny-text">
1019 1019
                     <div class="dashicons dashicons-groups ee-icon-size-16"></div>
@@ -1039,7 +1039,7 @@  discard block
 block discarded – undo
1039 1039
             );
1040 1040
             $actions['resend_reg_lnk'] = '
1041 1041
 			<li>
1042
-			    <a href="' . $resend_reg_lnk_url . '" aria-label="'
1042
+			    <a href="' . $resend_reg_lnk_url.'" aria-label="'
1043 1043
                 . esc_attr__('Resend Registration Details', 'event_espresso')
1044 1044
                 . '" class="ee-aria-tooltip tiny-text">
1045 1045
 			        <div class="dashicons dashicons-email-alt"></div>
@@ -1054,7 +1054,7 @@  discard block
 block discarded – undo
1054 1054
                 $this->_transaction_details['id']
1055 1055
             )
1056 1056
         ) {
1057
-            $view_txn_lnk_url        = EE_Admin_Page::add_query_args_and_nonce(
1057
+            $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
1058 1058
                 [
1059 1059
                     'action' => 'view_transaction',
1060 1060
                     'TXN_ID' => $this->_transaction_details['id'],
@@ -1064,8 +1064,8 @@  discard block
 block discarded – undo
1064 1064
             $actions['view_txn_lnk'] = '
1065 1065
 			<li>
1066 1066
                 <a class="ee-aria-tooltip ee-status-color-' . $this->_transaction_details['status']
1067
-                . ' tiny-text" href="' . $view_txn_lnk_url
1068
-                . '"  aria-label="' . $this->_transaction_details['title_attr'] . '">
1067
+                . ' tiny-text" href="'.$view_txn_lnk_url
1068
+                . '"  aria-label="'.$this->_transaction_details['title_attr'].'">
1069 1069
                     <div class="dashicons dashicons-cart"></div>
1070 1070
                 </a>
1071 1071
 			</li>';
@@ -1080,7 +1080,7 @@  discard block
 block discarded – undo
1080 1080
             $actions['dl_invoice_lnk'] = '
1081 1081
             <li>
1082 1082
                 <a aria-label="' . esc_attr__('View Transaction Invoice', 'event_espresso')
1083
-                . '" target="_blank" href="' . $item->invoice_url() . '" class="ee-aria-tooltip tiny-text">
1083
+                . '" target="_blank" href="'.$item->invoice_url().'" class="ee-aria-tooltip tiny-text">
1084 1084
                     <span class="dashicons dashicons-media-spreadsheet ee-icon-size-18"></span>
1085 1085
                 </a>
1086 1086
             </li>';
@@ -1096,7 +1096,7 @@  discard block
 block discarded – undo
1096 1096
                 'see_notifications_for',
1097 1097
                 null,
1098 1098
                 ['_REG_ID' => $item->ID()]
1099
-            ) . '
1099
+            ).'
1100 1100
             </li>';
1101 1101
         }
1102 1102
 
Please login to merge, or discard this patch.
admin_pages/registrations/Registrations_Admin_Page.core.php 2 patches
Indentation   +3672 added lines, -3672 removed lines patch added patch discarded remove patch
@@ -19,2228 +19,2228 @@  discard block
 block discarded – undo
19 19
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
20 20
 {
21 21
 
22
-    /**
23
-     * @var EE_Registration
24
-     */
25
-    private $_registration;
26
-
27
-    /**
28
-     * @var EE_Event
29
-     */
30
-    private $_reg_event;
31
-
32
-    /**
33
-     * @var EE_Session
34
-     */
35
-    private $_session;
36
-
37
-    /**
38
-     * @var array
39
-     */
40
-    private static $_reg_status;
41
-
42
-    /**
43
-     * Form for displaying the custom questions for this registration.
44
-     * This gets used a few times throughout the request so its best to cache it
45
-     *
46
-     * @var EE_Registration_Custom_Questions_Form
47
-     */
48
-    protected $_reg_custom_questions_form;
49
-
50
-    /**
51
-     * @var EEM_Registration $registration_model
52
-     */
53
-    private $registration_model;
54
-
55
-    /**
56
-     * @var EEM_Attendee $attendee_model
57
-     */
58
-    private $attendee_model;
59
-
60
-    /**
61
-     * @var EEM_Event $event_model
62
-     */
63
-    private $event_model;
64
-
65
-    /**
66
-     * @var EEM_Status $status_model
67
-     */
68
-    private $status_model;
69
-
70
-
71
-    /**
72
-     * @param bool $routing
73
-     * @throws EE_Error
74
-     * @throws InvalidArgumentException
75
-     * @throws InvalidDataTypeException
76
-     * @throws InvalidInterfaceException
77
-     * @throws ReflectionException
78
-     */
79
-    public function __construct($routing = true)
80
-    {
81
-        parent::__construct($routing);
82
-        add_action('wp_loaded', [$this, 'wp_loaded']);
83
-    }
84
-
85
-
86
-    /**
87
-     * @return EEM_Registration
88
-     * @throws InvalidArgumentException
89
-     * @throws InvalidDataTypeException
90
-     * @throws InvalidInterfaceException
91
-     * @since 4.10.2.p
92
-     */
93
-    protected function getRegistrationModel()
94
-    {
95
-        if (! $this->registration_model instanceof EEM_Registration) {
96
-            $this->registration_model = $this->loader->getShared('EEM_Registration');
97
-        }
98
-        return $this->registration_model;
99
-    }
100
-
101
-
102
-    /**
103
-     * @return EEM_Attendee
104
-     * @throws InvalidArgumentException
105
-     * @throws InvalidDataTypeException
106
-     * @throws InvalidInterfaceException
107
-     * @since 4.10.2.p
108
-     */
109
-    protected function getAttendeeModel()
110
-    {
111
-        if (! $this->attendee_model instanceof EEM_Attendee) {
112
-            $this->attendee_model = $this->loader->getShared('EEM_Attendee');
113
-        }
114
-        return $this->attendee_model;
115
-    }
116
-
117
-
118
-    /**
119
-     * @return EEM_Event
120
-     * @throws InvalidArgumentException
121
-     * @throws InvalidDataTypeException
122
-     * @throws InvalidInterfaceException
123
-     * @since 4.10.2.p
124
-     */
125
-    protected function getEventModel()
126
-    {
127
-        if (! $this->event_model instanceof EEM_Event) {
128
-            $this->event_model = $this->loader->getShared('EEM_Event');
129
-        }
130
-        return $this->event_model;
131
-    }
132
-
133
-
134
-    /**
135
-     * @return EEM_Status
136
-     * @throws InvalidArgumentException
137
-     * @throws InvalidDataTypeException
138
-     * @throws InvalidInterfaceException
139
-     * @since 4.10.2.p
140
-     */
141
-    protected function getStatusModel()
142
-    {
143
-        if (! $this->status_model instanceof EEM_Status) {
144
-            $this->status_model = $this->loader->getShared('EEM_Status');
145
-        }
146
-        return $this->status_model;
147
-    }
148
-
149
-
150
-    public function wp_loaded()
151
-    {
152
-        // when adding a new registration...
153
-        $action = $this->request->getRequestParam('action');
154
-        if ($action === 'new_registration') {
155
-            EE_System::do_not_cache();
156
-            if ($this->request->getRequestParam('processing_registration', 0, 'int') !== 1) {
157
-                // and it's NOT the attendee information reg step
158
-                // force cookie expiration by setting time to last week
159
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
160
-                // and update the global
161
-                $_COOKIE['ee_registration_added'] = 0;
162
-            }
163
-        }
164
-    }
165
-
166
-
167
-    protected function _init_page_props()
168
-    {
169
-        $this->page_slug        = REG_PG_SLUG;
170
-        $this->_admin_base_url  = REG_ADMIN_URL;
171
-        $this->_admin_base_path = REG_ADMIN;
172
-        $this->page_label       = esc_html__('Registrations', 'event_espresso');
173
-        $this->_cpt_routes      = [
174
-            'add_new_attendee' => 'espresso_attendees',
175
-            'edit_attendee'    => 'espresso_attendees',
176
-            'insert_attendee'  => 'espresso_attendees',
177
-            'update_attendee'  => 'espresso_attendees',
178
-        ];
179
-        $this->_cpt_model_names = [
180
-            'add_new_attendee' => 'EEM_Attendee',
181
-            'edit_attendee'    => 'EEM_Attendee',
182
-        ];
183
-        $this->_cpt_edit_routes = [
184
-            'espresso_attendees' => 'edit_attendee',
185
-        ];
186
-        $this->_pagenow_map     = [
187
-            'add_new_attendee' => 'post-new.php',
188
-            'edit_attendee'    => 'post.php',
189
-            'trash'            => 'post.php',
190
-        ];
191
-        add_action('edit_form_after_title', [$this, 'after_title_form_fields'], 10);
192
-        // add filters so that the comment urls don't take users to a confusing 404 page
193
-        add_filter('get_comment_link', [$this, 'clear_comment_link'], 10, 2);
194
-    }
195
-
196
-
197
-    /**
198
-     * @param string     $link    The comment permalink with '#comment-$id' appended.
199
-     * @param WP_Comment $comment The current comment object.
200
-     * @return string
201
-     */
202
-    public function clear_comment_link($link, WP_Comment $comment)
203
-    {
204
-        // gotta make sure this only happens on this route
205
-        $post_type = get_post_type($comment->comment_post_ID);
206
-        if ($post_type === 'espresso_attendees') {
207
-            return '#commentsdiv';
208
-        }
209
-        return $link;
210
-    }
211
-
212
-
213
-    protected function _ajax_hooks()
214
-    {
215
-        // todo: all hooks for registrations ajax goes in here
216
-        add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
217
-    }
218
-
219
-
220
-    protected function _define_page_props()
221
-    {
222
-        $this->_admin_page_title = $this->page_label;
223
-        $this->_labels           = [
224
-            'buttons'                      => [
225
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
226
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
227
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
228
-                'report'              => esc_html__('Event Registrations CSV Report', 'event_espresso'),
229
-                'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
230
-                'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
231
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
232
-                'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
233
-            ],
234
-            'publishbox'                   => [
235
-                'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
236
-                'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
237
-            ],
238
-            'hide_add_button_on_cpt_route' => [
239
-                'edit_attendee' => true,
240
-            ],
241
-        ];
242
-    }
243
-
244
-
245
-    /**
246
-     * grab url requests and route them
247
-     *
248
-     * @return void
249
-     * @throws EE_Error
250
-     */
251
-    public function _set_page_routes()
252
-    {
253
-        $this->_get_registration_status_array();
254
-        $REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
255
-        $REG_ID             = $this->request->getRequestParam('reg_status_change_form[REG_ID]', $REG_ID, 'int');
256
-        $ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
257
-        $ATT_ID             = $this->request->getRequestParam('post', $ATT_ID, 'int');
258
-        $this->_page_routes = [
259
-            'default'                             => [
260
-                'func'       => '_registrations_overview_list_table',
261
-                'capability' => 'ee_read_registrations',
262
-            ],
263
-            'view_registration'                   => [
264
-                'func'       => '_registration_details',
265
-                'capability' => 'ee_read_registration',
266
-                'obj_id'     => $REG_ID,
267
-            ],
268
-            'edit_registration'                   => [
269
-                'func'               => '_update_attendee_registration_form',
270
-                'noheader'           => true,
271
-                'headers_sent_route' => 'view_registration',
272
-                'capability'         => 'ee_edit_registration',
273
-                'obj_id'             => $REG_ID,
274
-                '_REG_ID'            => $REG_ID,
275
-            ],
276
-            'trash_registrations'                 => [
277
-                'func'       => '_trash_or_restore_registrations',
278
-                'args'       => ['trash' => true],
279
-                'noheader'   => true,
280
-                'capability' => 'ee_delete_registrations',
281
-            ],
282
-            'restore_registrations'               => [
283
-                'func'       => '_trash_or_restore_registrations',
284
-                'args'       => ['trash' => false],
285
-                'noheader'   => true,
286
-                'capability' => 'ee_delete_registrations',
287
-            ],
288
-            'delete_registrations'                => [
289
-                'func'       => '_delete_registrations',
290
-                'noheader'   => true,
291
-                'capability' => 'ee_delete_registrations',
292
-            ],
293
-            'new_registration'                    => [
294
-                'func'       => 'new_registration',
295
-                'capability' => 'ee_edit_registrations',
296
-            ],
297
-            'process_reg_step'                    => [
298
-                'func'       => 'process_reg_step',
299
-                'noheader'   => true,
300
-                'capability' => 'ee_edit_registrations',
301
-            ],
302
-            'redirect_to_txn'                     => [
303
-                'func'       => 'redirect_to_txn',
304
-                'noheader'   => true,
305
-                'capability' => 'ee_edit_registrations',
306
-            ],
307
-            'change_reg_status'                   => [
308
-                'func'       => '_change_reg_status',
309
-                'noheader'   => true,
310
-                'capability' => 'ee_edit_registration',
311
-                'obj_id'     => $REG_ID,
312
-            ],
313
-            'approve_registration'                => [
314
-                'func'       => 'approve_registration',
315
-                'noheader'   => true,
316
-                'capability' => 'ee_edit_registration',
317
-                'obj_id'     => $REG_ID,
318
-            ],
319
-            'approve_and_notify_registration'     => [
320
-                'func'       => 'approve_registration',
321
-                'noheader'   => true,
322
-                'args'       => [true],
323
-                'capability' => 'ee_edit_registration',
324
-                'obj_id'     => $REG_ID,
325
-            ],
326
-            'approve_registrations'               => [
327
-                'func'       => 'bulk_action_on_registrations',
328
-                'noheader'   => true,
329
-                'capability' => 'ee_edit_registrations',
330
-                'args'       => ['approve'],
331
-            ],
332
-            'approve_and_notify_registrations'    => [
333
-                'func'       => 'bulk_action_on_registrations',
334
-                'noheader'   => true,
335
-                'capability' => 'ee_edit_registrations',
336
-                'args'       => ['approve', true],
337
-            ],
338
-            'decline_registration'                => [
339
-                'func'       => 'decline_registration',
340
-                'noheader'   => true,
341
-                'capability' => 'ee_edit_registration',
342
-                'obj_id'     => $REG_ID,
343
-            ],
344
-            'decline_and_notify_registration'     => [
345
-                'func'       => 'decline_registration',
346
-                'noheader'   => true,
347
-                'args'       => [true],
348
-                'capability' => 'ee_edit_registration',
349
-                'obj_id'     => $REG_ID,
350
-            ],
351
-            'decline_registrations'               => [
352
-                'func'       => 'bulk_action_on_registrations',
353
-                'noheader'   => true,
354
-                'capability' => 'ee_edit_registrations',
355
-                'args'       => ['decline'],
356
-            ],
357
-            'decline_and_notify_registrations'    => [
358
-                'func'       => 'bulk_action_on_registrations',
359
-                'noheader'   => true,
360
-                'capability' => 'ee_edit_registrations',
361
-                'args'       => ['decline', true],
362
-            ],
363
-            'pending_registration'                => [
364
-                'func'       => 'pending_registration',
365
-                'noheader'   => true,
366
-                'capability' => 'ee_edit_registration',
367
-                'obj_id'     => $REG_ID,
368
-            ],
369
-            'pending_and_notify_registration'     => [
370
-                'func'       => 'pending_registration',
371
-                'noheader'   => true,
372
-                'args'       => [true],
373
-                'capability' => 'ee_edit_registration',
374
-                'obj_id'     => $REG_ID,
375
-            ],
376
-            'pending_registrations'               => [
377
-                'func'       => 'bulk_action_on_registrations',
378
-                'noheader'   => true,
379
-                'capability' => 'ee_edit_registrations',
380
-                'args'       => ['pending'],
381
-            ],
382
-            'pending_and_notify_registrations'    => [
383
-                'func'       => 'bulk_action_on_registrations',
384
-                'noheader'   => true,
385
-                'capability' => 'ee_edit_registrations',
386
-                'args'       => ['pending', true],
387
-            ],
388
-            'no_approve_registration'             => [
389
-                'func'       => 'not_approve_registration',
390
-                'noheader'   => true,
391
-                'capability' => 'ee_edit_registration',
392
-                'obj_id'     => $REG_ID,
393
-            ],
394
-            'no_approve_and_notify_registration'  => [
395
-                'func'       => 'not_approve_registration',
396
-                'noheader'   => true,
397
-                'args'       => [true],
398
-                'capability' => 'ee_edit_registration',
399
-                'obj_id'     => $REG_ID,
400
-            ],
401
-            'no_approve_registrations'            => [
402
-                'func'       => 'bulk_action_on_registrations',
403
-                'noheader'   => true,
404
-                'capability' => 'ee_edit_registrations',
405
-                'args'       => ['not_approve'],
406
-            ],
407
-            'no_approve_and_notify_registrations' => [
408
-                'func'       => 'bulk_action_on_registrations',
409
-                'noheader'   => true,
410
-                'capability' => 'ee_edit_registrations',
411
-                'args'       => ['not_approve', true],
412
-            ],
413
-            'cancel_registration'                 => [
414
-                'func'       => 'cancel_registration',
415
-                'noheader'   => true,
416
-                'capability' => 'ee_edit_registration',
417
-                'obj_id'     => $REG_ID,
418
-            ],
419
-            'cancel_and_notify_registration'      => [
420
-                'func'       => 'cancel_registration',
421
-                'noheader'   => true,
422
-                'args'       => [true],
423
-                'capability' => 'ee_edit_registration',
424
-                'obj_id'     => $REG_ID,
425
-            ],
426
-            'cancel_registrations'                => [
427
-                'func'       => 'bulk_action_on_registrations',
428
-                'noheader'   => true,
429
-                'capability' => 'ee_edit_registrations',
430
-                'args'       => ['cancel'],
431
-            ],
432
-            'cancel_and_notify_registrations'     => [
433
-                'func'       => 'bulk_action_on_registrations',
434
-                'noheader'   => true,
435
-                'capability' => 'ee_edit_registrations',
436
-                'args'       => ['cancel', true],
437
-            ],
438
-            'wait_list_registration'              => [
439
-                'func'       => 'wait_list_registration',
440
-                'noheader'   => true,
441
-                'capability' => 'ee_edit_registration',
442
-                'obj_id'     => $REG_ID,
443
-            ],
444
-            'wait_list_and_notify_registration'   => [
445
-                'func'       => 'wait_list_registration',
446
-                'noheader'   => true,
447
-                'args'       => [true],
448
-                'capability' => 'ee_edit_registration',
449
-                'obj_id'     => $REG_ID,
450
-            ],
451
-            'contact_list'                        => [
452
-                'func'       => '_attendee_contact_list_table',
453
-                'capability' => 'ee_read_contacts',
454
-            ],
455
-            'add_new_attendee'                    => [
456
-                'func' => '_create_new_cpt_item',
457
-                'args' => [
458
-                    'new_attendee' => true,
459
-                    'capability'   => 'ee_edit_contacts',
460
-                ],
461
-            ],
462
-            'edit_attendee'                       => [
463
-                'func'       => '_edit_cpt_item',
464
-                'capability' => 'ee_edit_contacts',
465
-                'obj_id'     => $ATT_ID,
466
-            ],
467
-            'duplicate_attendee'                  => [
468
-                'func'       => '_duplicate_attendee',
469
-                'noheader'   => true,
470
-                'capability' => 'ee_edit_contacts',
471
-                'obj_id'     => $ATT_ID,
472
-            ],
473
-            'insert_attendee'                     => [
474
-                'func'       => '_insert_or_update_attendee',
475
-                'args'       => [
476
-                    'new_attendee' => true,
477
-                ],
478
-                'noheader'   => true,
479
-                'capability' => 'ee_edit_contacts',
480
-            ],
481
-            'update_attendee'                     => [
482
-                'func'       => '_insert_or_update_attendee',
483
-                'args'       => [
484
-                    'new_attendee' => false,
485
-                ],
486
-                'noheader'   => true,
487
-                'capability' => 'ee_edit_contacts',
488
-                'obj_id'     => $ATT_ID,
489
-            ],
490
-            'trash_attendees'                     => [
491
-                'func'       => '_trash_or_restore_attendees',
492
-                'args'       => [
493
-                    'trash' => 'true',
494
-                ],
495
-                'noheader'   => true,
496
-                'capability' => 'ee_delete_contacts',
497
-            ],
498
-            'trash_attendee'                      => [
499
-                'func'       => '_trash_or_restore_attendees',
500
-                'args'       => [
501
-                    'trash' => true,
502
-                ],
503
-                'noheader'   => true,
504
-                'capability' => 'ee_delete_contacts',
505
-                'obj_id'     => $ATT_ID,
506
-            ],
507
-            'restore_attendees'                   => [
508
-                'func'       => '_trash_or_restore_attendees',
509
-                'args'       => [
510
-                    'trash' => false,
511
-                ],
512
-                'noheader'   => true,
513
-                'capability' => 'ee_delete_contacts',
514
-                'obj_id'     => $ATT_ID,
515
-            ],
516
-            'resend_registration'                 => [
517
-                'func'       => '_resend_registration',
518
-                'noheader'   => true,
519
-                'capability' => 'ee_send_message',
520
-            ],
521
-            'registrations_report'                => [
522
-                'func'       => '_registrations_report',
523
-                'noheader'   => true,
524
-                'capability' => 'ee_read_registrations',
525
-            ],
526
-            'contact_list_export'                 => [
527
-                'func'       => '_contact_list_export',
528
-                'noheader'   => true,
529
-                'capability' => 'export',
530
-            ],
531
-            'contact_list_report'                 => [
532
-                'func'       => '_contact_list_report',
533
-                'noheader'   => true,
534
-                'capability' => 'ee_read_contacts',
535
-            ],
536
-        ];
537
-    }
538
-
539
-
540
-    protected function _set_page_config()
541
-    {
542
-        $REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
543
-        $ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
544
-        $this->_page_config = [
545
-            'default'           => [
546
-                'nav'           => [
547
-                    'label' => esc_html__('Overview', 'event_espresso'),
548
-                    'order' => 5,
549
-                ],
550
-                'help_tabs'     => [
551
-                    'registrations_overview_help_tab'                       => [
552
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
553
-                        'filename' => 'registrations_overview',
554
-                    ],
555
-                    'registrations_overview_table_column_headings_help_tab' => [
556
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
557
-                        'filename' => 'registrations_overview_table_column_headings',
558
-                    ],
559
-                    'registrations_overview_filters_help_tab'               => [
560
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
561
-                        'filename' => 'registrations_overview_filters',
562
-                    ],
563
-                    'registrations_overview_views_help_tab'                 => [
564
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
565
-                        'filename' => 'registrations_overview_views',
566
-                    ],
567
-                    'registrations_regoverview_other_help_tab'              => [
568
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
569
-                        'filename' => 'registrations_overview_other',
570
-                    ],
571
-                ],
572
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
573
-                // 'help_tour'     => array('Registration_Overview_Help_Tour'),
574
-                'qtips'         => ['Registration_List_Table_Tips'],
575
-                'list_table'    => 'EE_Registrations_List_Table',
576
-                'require_nonce' => false,
577
-            ],
578
-            'view_registration' => [
579
-                'nav'           => [
580
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
581
-                    'order'      => 15,
582
-                    'url'        => $REG_ID
583
-                        ? add_query_arg(['_REG_ID' => $REG_ID], $this->_current_page_view_url)
584
-                        : $this->_admin_base_url,
585
-                    'persistent' => false,
586
-                ],
587
-                'help_tabs'     => [
588
-                    'registrations_details_help_tab'                    => [
589
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
590
-                        'filename' => 'registrations_details',
591
-                    ],
592
-                    'registrations_details_table_help_tab'              => [
593
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
594
-                        'filename' => 'registrations_details_table',
595
-                    ],
596
-                    'registrations_details_form_answers_help_tab'       => [
597
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
598
-                        'filename' => 'registrations_details_form_answers',
599
-                    ],
600
-                    'registrations_details_registrant_details_help_tab' => [
601
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
602
-                        'filename' => 'registrations_details_registrant_details',
603
-                    ],
604
-                ],
605
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
606
-                // 'help_tour'     => array('Registration_Details_Help_Tour'),
607
-                'metaboxes'     => array_merge(
608
-                    $this->_default_espresso_metaboxes,
609
-                    ['_registration_details_metaboxes']
610
-                ),
611
-                'require_nonce' => false,
612
-            ],
613
-            'new_registration'  => [
614
-                'nav'           => [
615
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
616
-                    'url'        => '#',
617
-                    'order'      => 15,
618
-                    'persistent' => false,
619
-                ],
620
-                'metaboxes'     => $this->_default_espresso_metaboxes,
621
-                'labels'        => [
622
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
623
-                ],
624
-                'require_nonce' => false,
625
-            ],
626
-            'add_new_attendee'  => [
627
-                'nav'           => [
628
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
629
-                    'order'      => 15,
630
-                    'persistent' => false,
631
-                ],
632
-                'metaboxes'     => array_merge(
633
-                    $this->_default_espresso_metaboxes,
634
-                    ['_publish_post_box', 'attendee_editor_metaboxes']
635
-                ),
636
-                'require_nonce' => false,
637
-            ],
638
-            'edit_attendee'     => [
639
-                'nav'           => [
640
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
641
-                    'order'      => 15,
642
-                    'persistent' => false,
643
-                    'url'        => $ATT_ID
644
-                        ? add_query_arg(['ATT_ID' => $ATT_ID], $this->_current_page_view_url)
645
-                        : $this->_admin_base_url,
646
-                ],
647
-                'metaboxes'     => ['attendee_editor_metaboxes'],
648
-                'require_nonce' => false,
649
-            ],
650
-            'contact_list'      => [
651
-                'nav'           => [
652
-                    'label' => esc_html__('Contact List', 'event_espresso'),
653
-                    'order' => 20,
654
-                ],
655
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
656
-                'help_tabs'     => [
657
-                    'registrations_contact_list_help_tab'                       => [
658
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
659
-                        'filename' => 'registrations_contact_list',
660
-                    ],
661
-                    'registrations_contact-list_table_column_headings_help_tab' => [
662
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
663
-                        'filename' => 'registrations_contact_list_table_column_headings',
664
-                    ],
665
-                    'registrations_contact_list_views_help_tab'                 => [
666
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
667
-                        'filename' => 'registrations_contact_list_views',
668
-                    ],
669
-                    'registrations_contact_list_other_help_tab'                 => [
670
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
671
-                        'filename' => 'registrations_contact_list_other',
672
-                    ],
673
-                ],
674
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
675
-                // 'help_tour'     => array('Contact_List_Help_Tour'),
676
-                'metaboxes'     => [],
677
-                'require_nonce' => false,
678
-            ],
679
-            // override default cpt routes
680
-            'create_new'        => '',
681
-            'edit'              => '',
682
-        ];
683
-    }
684
-
685
-
686
-    /**
687
-     * The below methods aren't used by this class currently
688
-     */
689
-    protected function _add_screen_options()
690
-    {
691
-    }
692
-
693
-
694
-    protected function _add_feature_pointers()
695
-    {
696
-    }
697
-
698
-
699
-    public function admin_init()
700
-    {
701
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
702
-            'click "Update Registration Questions" to save your changes',
703
-            'event_espresso'
704
-        );
705
-    }
706
-
707
-
708
-    public function admin_notices()
709
-    {
710
-    }
711
-
712
-
713
-    public function admin_footer_scripts()
714
-    {
715
-    }
716
-
717
-
718
-    /**
719
-     * get list of registration statuses
720
-     *
721
-     * @return void
722
-     * @throws EE_Error
723
-     */
724
-    private function _get_registration_status_array()
725
-    {
726
-        self::$_reg_status = EEM_Registration::reg_status_array([], true);
727
-    }
728
-
729
-
730
-    /**
731
-     * @throws InvalidArgumentException
732
-     * @throws InvalidDataTypeException
733
-     * @throws InvalidInterfaceException
734
-     * @since 4.10.2.p
735
-     */
736
-    protected function _add_screen_options_default()
737
-    {
738
-        $this->_per_page_screen_option();
739
-    }
740
-
741
-
742
-    /**
743
-     * @throws InvalidArgumentException
744
-     * @throws InvalidDataTypeException
745
-     * @throws InvalidInterfaceException
746
-     * @since 4.10.2.p
747
-     */
748
-    protected function _add_screen_options_contact_list()
749
-    {
750
-        $page_title              = $this->_admin_page_title;
751
-        $this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
752
-        $this->_per_page_screen_option();
753
-        $this->_admin_page_title = $page_title;
754
-    }
755
-
756
-
757
-    public function load_scripts_styles()
758
-    {
759
-        // style
760
-        wp_register_style(
761
-            'espresso_reg',
762
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
763
-            ['ee-admin-css'],
764
-            EVENT_ESPRESSO_VERSION
765
-        );
766
-        wp_enqueue_style('espresso_reg');
767
-        // script
768
-        wp_register_script(
769
-            'espresso_reg',
770
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
771
-            ['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
772
-            EVENT_ESPRESSO_VERSION,
773
-            true
774
-        );
775
-        wp_enqueue_script('espresso_reg');
776
-    }
777
-
778
-
779
-    /**
780
-     * @throws EE_Error
781
-     * @throws InvalidArgumentException
782
-     * @throws InvalidDataTypeException
783
-     * @throws InvalidInterfaceException
784
-     * @throws ReflectionException
785
-     * @since 4.10.2.p
786
-     */
787
-    public function load_scripts_styles_edit_attendee()
788
-    {
789
-        // stuff to only show up on our attendee edit details page.
790
-        $attendee_details_translations = [
791
-            'att_publish_text' => sprintf(
792
-            /* translators: The date and time */
793
-                wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
794
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
795
-            ),
796
-        ];
797
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
798
-        wp_enqueue_script('jquery-validate');
799
-    }
800
-
801
-
802
-    /**
803
-     * @throws EE_Error
804
-     * @throws InvalidArgumentException
805
-     * @throws InvalidDataTypeException
806
-     * @throws InvalidInterfaceException
807
-     * @throws ReflectionException
808
-     * @since 4.10.2.p
809
-     */
810
-    public function load_scripts_styles_view_registration()
811
-    {
812
-        // styles
813
-        wp_enqueue_style('espresso-ui-theme');
814
-        // scripts
815
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
816
-        $this->_reg_custom_questions_form->wp_enqueue_scripts();
817
-    }
818
-
819
-
820
-    public function load_scripts_styles_contact_list()
821
-    {
822
-        wp_dequeue_style('espresso_reg');
823
-        wp_register_style(
824
-            'espresso_att',
825
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
826
-            ['ee-admin-css'],
827
-            EVENT_ESPRESSO_VERSION
828
-        );
829
-        wp_enqueue_style('espresso_att');
830
-    }
831
-
832
-
833
-    public function load_scripts_styles_new_registration()
834
-    {
835
-        wp_register_script(
836
-            'ee-spco-for-admin',
837
-            REG_ASSETS_URL . 'spco_for_admin.js',
838
-            ['underscore', 'jquery'],
839
-            EVENT_ESPRESSO_VERSION,
840
-            true
841
-        );
842
-        wp_enqueue_script('ee-spco-for-admin');
843
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
844
-        EE_Form_Section_Proper::wp_enqueue_scripts();
845
-        EED_Ticket_Selector::load_tckt_slctr_assets();
846
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
847
-    }
848
-
849
-
850
-    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
851
-    {
852
-        add_filter('FHEE_load_EE_messages', '__return_true');
853
-    }
854
-
855
-
856
-    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
857
-    {
858
-        add_filter('FHEE_load_EE_messages', '__return_true');
859
-    }
860
-
861
-
862
-    /**
863
-     * @throws EE_Error
864
-     * @throws InvalidArgumentException
865
-     * @throws InvalidDataTypeException
866
-     * @throws InvalidInterfaceException
867
-     * @throws ReflectionException
868
-     * @since 4.10.2.p
869
-     */
870
-    protected function _set_list_table_views_default()
871
-    {
872
-        // for notification related bulk actions we need to make sure only active messengers have an option.
873
-        EED_Messages::set_autoloaders();
874
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
875
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
876
-        $active_mts               = $message_resource_manager->list_of_active_message_types();
877
-        // key= bulk_action_slug, value= message type.
878
-        $match_array = [
879
-            'approve_registrations'    => 'registration',
880
-            'decline_registrations'    => 'declined_registration',
881
-            'pending_registrations'    => 'pending_approval',
882
-            'no_approve_registrations' => 'not_approved_registration',
883
-            'cancel_registrations'     => 'cancelled_registration',
884
-        ];
885
-        $can_send    = EE_Registry::instance()->CAP->current_user_can(
886
-            'ee_send_message',
887
-            'batch_send_messages'
888
-        );
889
-        /** setup reg status bulk actions **/
890
-        $def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
891
-        if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
892
-            $def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
893
-                'Approve and Notify Registrations',
894
-                'event_espresso'
895
-            );
896
-        }
897
-        $def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
898
-        if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
899
-            $def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
900
-                'Decline and Notify Registrations',
901
-                'event_espresso'
902
-            );
903
-        }
904
-        $def_reg_status_actions['pending_registrations'] = esc_html__(
905
-            'Set Registrations to Pending Payment',
906
-            'event_espresso'
907
-        );
908
-        if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
909
-            $def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
910
-                'Set Registrations to Pending Payment and Notify',
911
-                'event_espresso'
912
-            );
913
-        }
914
-        $def_reg_status_actions['no_approve_registrations'] = esc_html__(
915
-            'Set Registrations to Not Approved',
916
-            'event_espresso'
917
-        );
918
-        if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
919
-            $def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
920
-                'Set Registrations to Not Approved and Notify',
921
-                'event_espresso'
922
-            );
923
-        }
924
-        $def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
925
-        if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
926
-            $def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
927
-                'Cancel Registrations and Notify',
928
-                'event_espresso'
929
-            );
930
-        }
931
-        $def_reg_status_actions = apply_filters(
932
-            'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
933
-            $def_reg_status_actions,
934
-            $active_mts,
935
-            $can_send
936
-        );
937
-
938
-        $this->_views = [
939
-            'all'   => [
940
-                'slug'        => 'all',
941
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
942
-                'count'       => 0,
943
-                'bulk_action' => array_merge(
944
-                    $def_reg_status_actions,
945
-                    [
946
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
947
-                    ]
948
-                ),
949
-            ],
950
-            'month' => [
951
-                'slug'        => 'month',
952
-                'label'       => esc_html__('This Month', 'event_espresso'),
953
-                'count'       => 0,
954
-                'bulk_action' => array_merge(
955
-                    $def_reg_status_actions,
956
-                    [
957
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
958
-                    ]
959
-                ),
960
-            ],
961
-            'today' => [
962
-                'slug'        => 'today',
963
-                'label'       => sprintf(
964
-                    esc_html__('Today - %s', 'event_espresso'),
965
-                    date('M d, Y', current_time('timestamp'))
966
-                ),
967
-                'count'       => 0,
968
-                'bulk_action' => array_merge(
969
-                    $def_reg_status_actions,
970
-                    [
971
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
972
-                    ]
973
-                ),
974
-            ],
975
-        ];
976
-        if (
977
-            EE_Registry::instance()->CAP->current_user_can(
978
-                'ee_delete_registrations',
979
-                'espresso_registrations_delete_registration'
980
-            )
981
-        ) {
982
-            $this->_views['incomplete'] = [
983
-                'slug'        => 'incomplete',
984
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
985
-                'count'       => 0,
986
-                'bulk_action' => [
987
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
988
-                ],
989
-            ];
990
-            $this->_views['trash']      = [
991
-                'slug'        => 'trash',
992
-                'label'       => esc_html__('Trash', 'event_espresso'),
993
-                'count'       => 0,
994
-                'bulk_action' => [
995
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
996
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
997
-                ],
998
-            ];
999
-        }
1000
-    }
1001
-
1002
-
1003
-    protected function _set_list_table_views_contact_list()
1004
-    {
1005
-        $this->_views = [
1006
-            'in_use' => [
1007
-                'slug'        => 'in_use',
1008
-                'label'       => esc_html__('In Use', 'event_espresso'),
1009
-                'count'       => 0,
1010
-                'bulk_action' => [
1011
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1012
-                ],
1013
-            ],
1014
-        ];
1015
-        if (
1016
-            EE_Registry::instance()->CAP->current_user_can(
1017
-                'ee_delete_contacts',
1018
-                'espresso_registrations_trash_attendees'
1019
-            )
1020
-        ) {
1021
-            $this->_views['trash'] = [
1022
-                'slug'        => 'trash',
1023
-                'label'       => esc_html__('Trash', 'event_espresso'),
1024
-                'count'       => 0,
1025
-                'bulk_action' => [
1026
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1027
-                ],
1028
-            ];
1029
-        }
1030
-    }
1031
-
1032
-
1033
-    /**
1034
-     * @return array
1035
-     * @throws EE_Error
1036
-     */
1037
-    protected function _registration_legend_items()
1038
-    {
1039
-        $fc_items = [
1040
-            'star-icon'        => [
1041
-                'class' => 'dashicons dashicons-star-filled gold-icon ee-icon-size-8',
1042
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1043
-            ],
1044
-            'view_details'     => [
1045
-                'class' => 'dashicons dashicons-clipboard',
1046
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1047
-            ],
1048
-            'edit_attendee'    => [
1049
-                'class' => 'dashicons dashicons-groups ee-icon-size-16',
1050
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1051
-            ],
1052
-            'view_transaction' => [
1053
-                'class' => 'dashicons dashicons-cart',
1054
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1055
-            ],
1056
-            'view_invoice'     => [
1057
-                'class' => 'dashicons dashicons-media-spreadsheet',
1058
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1059
-            ],
1060
-        ];
1061
-        if (
1062
-            EE_Registry::instance()->CAP->current_user_can(
1063
-                'ee_send_message',
1064
-                'espresso_registrations_resend_registration'
1065
-            )
1066
-        ) {
1067
-            $fc_items['resend_registration'] = [
1068
-                'class' => 'dashicons dashicons-email-alt',
1069
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1070
-            ];
1071
-        } else {
1072
-            $fc_items['blank'] = ['class' => 'blank', 'desc' => ''];
1073
-        }
1074
-        if (
1075
-            EE_Registry::instance()->CAP->current_user_can(
1076
-                'ee_read_global_messages',
1077
-                'view_filtered_messages'
1078
-            )
1079
-        ) {
1080
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1081
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1082
-                $fc_items['view_related_messages'] = [
1083
-                    'class' => $related_for_icon['css_class'],
1084
-                    'desc'  => $related_for_icon['label'],
1085
-                ];
1086
-            }
1087
-        }
1088
-        $sc_items = [
1089
-            'approved_status'   => [
1090
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_approved,
1091
-                'desc'  => EEH_Template::pretty_status(
1092
-                    EEM_Registration::status_id_approved,
1093
-                    false,
1094
-                    'sentence'
1095
-                ),
1096
-            ],
1097
-            'pending_status'    => [
1098
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_pending_payment,
1099
-                'desc'  => EEH_Template::pretty_status(
1100
-                    EEM_Registration::status_id_pending_payment,
1101
-                    false,
1102
-                    'sentence'
1103
-                ),
1104
-            ],
1105
-            'wait_list'         => [
1106
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_wait_list,
1107
-                'desc'  => EEH_Template::pretty_status(
1108
-                    EEM_Registration::status_id_wait_list,
1109
-                    false,
1110
-                    'sentence'
1111
-                ),
1112
-            ],
1113
-            'incomplete_status' => [
1114
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_incomplete,
1115
-                'desc'  => EEH_Template::pretty_status(
1116
-                    EEM_Registration::status_id_incomplete,
1117
-                    false,
1118
-                    'sentence'
1119
-                ),
1120
-            ],
1121
-            'not_approved'      => [
1122
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_not_approved,
1123
-                'desc'  => EEH_Template::pretty_status(
1124
-                    EEM_Registration::status_id_not_approved,
1125
-                    false,
1126
-                    'sentence'
1127
-                ),
1128
-            ],
1129
-            'declined_status'   => [
1130
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_declined,
1131
-                'desc'  => EEH_Template::pretty_status(
1132
-                    EEM_Registration::status_id_declined,
1133
-                    false,
1134
-                    'sentence'
1135
-                ),
1136
-            ],
1137
-            'cancelled_status'  => [
1138
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_cancelled,
1139
-                'desc'  => EEH_Template::pretty_status(
1140
-                    EEM_Registration::status_id_cancelled,
1141
-                    false,
1142
-                    'sentence'
1143
-                ),
1144
-            ],
1145
-        ];
1146
-        return array_merge($fc_items, $sc_items);
1147
-    }
1148
-
1149
-
1150
-
1151
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
1152
-
1153
-
1154
-    /**
1155
-     * @throws DomainException
1156
-     * @throws EE_Error
1157
-     * @throws InvalidArgumentException
1158
-     * @throws InvalidDataTypeException
1159
-     * @throws InvalidInterfaceException
1160
-     */
1161
-    protected function _registrations_overview_list_table()
1162
-    {
1163
-        $this->appendAddNewRegistrationButtonToPageTitle();
1164
-        $header_text                  = '';
1165
-        $admin_page_header_decorators = [
1166
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1167
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1168
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1169
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1170
-        ];
1171
-        foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1172
-            $filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1173
-            $header_text = $filter_header_decorator->getHeaderText($header_text);
1174
-        }
1175
-        $this->_template_args['admin_page_header'] = $header_text;
1176
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1177
-        $this->display_admin_list_table_page_with_no_sidebar();
1178
-    }
1179
-
1180
-
1181
-    /**
1182
-     * @throws EE_Error
1183
-     * @throws InvalidArgumentException
1184
-     * @throws InvalidDataTypeException
1185
-     * @throws InvalidInterfaceException
1186
-     */
1187
-    private function appendAddNewRegistrationButtonToPageTitle()
1188
-    {
1189
-        $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
1190
-        if (
1191
-            $EVT_ID
1192
-            && EE_Registry::instance()->CAP->current_user_can(
1193
-                'ee_edit_registrations',
1194
-                'espresso_registrations_new_registration',
1195
-                $EVT_ID
1196
-            )
1197
-        ) {
1198
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1199
-                'new_registration',
1200
-                'add-registrant',
1201
-                ['event_id' => $EVT_ID],
1202
-                'add-new-h2'
1203
-            );
1204
-        }
1205
-    }
1206
-
1207
-
1208
-    /**
1209
-     * This sets the _registration property for the registration details screen
1210
-     *
1211
-     * @return void
1212
-     * @throws EE_Error
1213
-     * @throws InvalidArgumentException
1214
-     * @throws InvalidDataTypeException
1215
-     * @throws InvalidInterfaceException
1216
-     */
1217
-    private function _set_registration_object()
1218
-    {
1219
-        // get out if we've already set the object
1220
-        if ($this->_registration instanceof EE_Registration) {
1221
-            return;
1222
-        }
1223
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
1224
-        if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1225
-            return;
1226
-        }
1227
-        $error_msg = sprintf(
1228
-            esc_html__(
1229
-                'An error occurred and the details for Registration ID #%s could not be retrieved.',
1230
-                'event_espresso'
1231
-            ),
1232
-            $REG_ID
1233
-        );
1234
-        EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1235
-        $this->_registration = null;
1236
-    }
1237
-
1238
-
1239
-    /**
1240
-     * Used to retrieve registrations for the list table.
1241
-     *
1242
-     * @param int  $per_page
1243
-     * @param bool $count
1244
-     * @param bool $this_month
1245
-     * @param bool $today
1246
-     * @return EE_Registration[]|int
1247
-     * @throws EE_Error
1248
-     * @throws InvalidArgumentException
1249
-     * @throws InvalidDataTypeException
1250
-     * @throws InvalidInterfaceException
1251
-     */
1252
-    public function get_registrations(
1253
-        $per_page = 10,
1254
-        $count = false,
1255
-        $this_month = false,
1256
-        $today = false
1257
-    ) {
1258
-        if ($this_month) {
1259
-            $this->request->setRequestParam('status', 'month');
1260
-        }
1261
-        if ($today) {
1262
-            $this->request->setRequestParam('status', 'today');
1263
-        }
1264
-        $query_params = $this->_get_registration_query_parameters($this->request->requestParams(), $per_page, $count);
1265
-        /**
1266
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1267
-         *
1268
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1269
-         * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1270
-         *                      or if you have the development copy of EE you can view this at the path:
1271
-         *                      /docs/G--Model-System/model-query-params.md
1272
-         */
1273
-        $query_params['group_by'] = '';
1274
-
1275
-        return $count
1276
-            ? $this->getRegistrationModel()->count($query_params)
1277
-            /** @type EE_Registration[] */
1278
-            : $this->getRegistrationModel()->get_all($query_params);
1279
-    }
1280
-
1281
-
1282
-    /**
1283
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1284
-     * Note: this listens to values on the request for some of the query parameters.
1285
-     *
1286
-     * @param array $request
1287
-     * @param int   $per_page
1288
-     * @param bool  $count
1289
-     * @return array
1290
-     * @throws EE_Error
1291
-     * @throws InvalidArgumentException
1292
-     * @throws InvalidDataTypeException
1293
-     * @throws InvalidInterfaceException
1294
-     */
1295
-    protected function _get_registration_query_parameters(
1296
-        $request = [],
1297
-        $per_page = 10,
1298
-        $count = false
1299
-    ) {
1300
-        /** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1301
-        $list_table_query_builder = $this->loader->getNew(
1302
-            'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1303
-            [null, null, $request]
1304
-        );
1305
-        return $list_table_query_builder->getQueryParams($per_page, $count);
1306
-    }
1307
-
1308
-
1309
-    public function get_registration_status_array()
1310
-    {
1311
-        return self::$_reg_status;
1312
-    }
1313
-
1314
-
1315
-
1316
-
1317
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1318
-    /**
1319
-     * generates HTML for the View Registration Details Admin page
1320
-     *
1321
-     * @return void
1322
-     * @throws DomainException
1323
-     * @throws EE_Error
1324
-     * @throws InvalidArgumentException
1325
-     * @throws InvalidDataTypeException
1326
-     * @throws InvalidInterfaceException
1327
-     * @throws EntityNotFoundException
1328
-     * @throws ReflectionException
1329
-     */
1330
-    protected function _registration_details()
1331
-    {
1332
-        $this->_template_args = [];
1333
-        $this->_set_registration_object();
1334
-        if (is_object($this->_registration)) {
1335
-            $transaction                                   = $this->_registration->transaction()
1336
-                ? $this->_registration->transaction()
1337
-                : EE_Transaction::new_instance();
1338
-            $this->_session                                = $transaction->session_data();
1339
-            $event_id                                      = $this->_registration->event_ID();
1340
-            $this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1341
-            $this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1342
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1343
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1344
-            $this->_template_args['grand_total']           = $transaction->total();
1345
-            $this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1346
-            // link back to overview
1347
-            $this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1348
-            $this->_template_args['registration']                = $this->_registration;
1349
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1350
-                [
1351
-                    'action'   => 'default',
1352
-                    'event_id' => $event_id,
1353
-                ],
1354
-                REG_ADMIN_URL
1355
-            );
1356
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1357
-                [
1358
-                    'action' => 'default',
1359
-                    'EVT_ID' => $event_id,
1360
-                    'page'   => 'espresso_transactions',
1361
-                ],
1362
-                admin_url('admin.php')
1363
-            );
1364
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1365
-                [
1366
-                    'page'   => 'espresso_events',
1367
-                    'action' => 'edit',
1368
-                    'post'   => $event_id,
1369
-                ],
1370
-                admin_url('admin.php')
1371
-            );
1372
-            // next and previous links
1373
-            $next_reg                                      = $this->_registration->next(
1374
-                null,
1375
-                [],
1376
-                'REG_ID'
1377
-            );
1378
-            $this->_template_args['next_registration']     = $next_reg
1379
-                ? $this->_next_link(
1380
-                    EE_Admin_Page::add_query_args_and_nonce(
1381
-                        [
1382
-                            'action'  => 'view_registration',
1383
-                            '_REG_ID' => $next_reg['REG_ID'],
1384
-                        ],
1385
-                        REG_ADMIN_URL
1386
-                    ),
1387
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1388
-                )
1389
-                : '';
1390
-            $previous_reg                                  = $this->_registration->previous(
1391
-                null,
1392
-                [],
1393
-                'REG_ID'
1394
-            );
1395
-            $this->_template_args['previous_registration'] = $previous_reg
1396
-                ? $this->_previous_link(
1397
-                    EE_Admin_Page::add_query_args_and_nonce(
1398
-                        [
1399
-                            'action'  => 'view_registration',
1400
-                            '_REG_ID' => $previous_reg['REG_ID'],
1401
-                        ],
1402
-                        REG_ADMIN_URL
1403
-                    ),
1404
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1405
-                )
1406
-                : '';
1407
-            // grab header
1408
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1409
-            $this->_template_args['REG_ID']            = $this->_registration->ID();
1410
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1411
-                $template_path,
1412
-                $this->_template_args,
1413
-                true
1414
-            );
1415
-        } else {
1416
-            $this->_template_args['admin_page_header'] = '';
1417
-            $this->_display_espresso_notices();
1418
-        }
1419
-        // the details template wrapper
1420
-        $this->display_admin_page_with_sidebar();
1421
-    }
1422
-
1423
-
1424
-    /**
1425
-     * @throws EE_Error
1426
-     * @throws InvalidArgumentException
1427
-     * @throws InvalidDataTypeException
1428
-     * @throws InvalidInterfaceException
1429
-     * @throws ReflectionException
1430
-     * @since 4.10.2.p
1431
-     */
1432
-    protected function _registration_details_metaboxes()
1433
-    {
1434
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1435
-        $this->_set_registration_object();
1436
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1437
-        $this->addMetaBox(
1438
-            'edit-reg-status-mbox',
1439
-            esc_html__('Registration Status', 'event_espresso'),
1440
-            [$this, 'set_reg_status_buttons_metabox'],
1441
-            $this->_wp_page_slug
1442
-        );
1443
-        $this->addMetaBox(
1444
-            'edit-reg-details-mbox',
1445
-            '<span>' . esc_html__('Registration Details', 'event_espresso')
1446
-            . '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1447
-            [$this, '_reg_details_meta_box'],
1448
-            $this->_wp_page_slug
1449
-        );
1450
-        if (
1451
-            $attendee instanceof EE_Attendee
1452
-            && EE_Registry::instance()->CAP->current_user_can(
1453
-                'ee_read_registration',
1454
-                'edit-reg-questions-mbox',
1455
-                $this->_registration->ID()
1456
-            )
1457
-        ) {
1458
-            $this->addMetaBox(
1459
-                $this->_wp_page_slug,
1460
-                'edit-reg-questions-mbox',
1461
-                esc_html__('Registration Form Answers', 'event_espresso'),
1462
-                [$this, '_reg_questions_meta_box'],
1463
-                $this->_wp_page_slug
1464
-            );
1465
-        }
1466
-        $this->addMetaBox(
1467
-            'edit-reg-registrant-mbox',
1468
-            esc_html__('Contact Details', 'event_espresso'),
1469
-            [$this, '_reg_registrant_side_meta_box'],
1470
-            $this->_wp_page_slug,
1471
-            'side'
1472
-        );
1473
-        if ($this->_registration->group_size() > 1) {
1474
-            $this->addMetaBox(
1475
-                'edit-reg-attendees-mbox',
1476
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1477
-                [$this, '_reg_attendees_meta_box'],
1478
-                $this->_wp_page_slug
1479
-            );
1480
-        }
1481
-    }
1482
-
1483
-
1484
-    /**
1485
-     * set_reg_status_buttons_metabox
1486
-     *
1487
-     * @return void
1488
-     * @throws EE_Error
1489
-     * @throws EntityNotFoundException
1490
-     * @throws InvalidArgumentException
1491
-     * @throws InvalidDataTypeException
1492
-     * @throws InvalidInterfaceException
1493
-     * @throws ReflectionException
1494
-     */
1495
-    public function set_reg_status_buttons_metabox()
1496
-    {
1497
-        $this->_set_registration_object();
1498
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1499
-        $output                 = $change_reg_status_form->form_open(
1500
-            self::add_query_args_and_nonce(
1501
-                [
1502
-                    'action' => 'change_reg_status',
1503
-                ],
1504
-                REG_ADMIN_URL
1505
-            )
1506
-        );
1507
-        $output                 .= $change_reg_status_form->get_html();
1508
-        $output                 .= $change_reg_status_form->form_close();
1509
-        echo $output; // already escaped
1510
-    }
1511
-
1512
-
1513
-    /**
1514
-     * @return EE_Form_Section_Proper
1515
-     * @throws EE_Error
1516
-     * @throws InvalidArgumentException
1517
-     * @throws InvalidDataTypeException
1518
-     * @throws InvalidInterfaceException
1519
-     * @throws EntityNotFoundException
1520
-     * @throws ReflectionException
1521
-     */
1522
-    protected function _generate_reg_status_change_form()
1523
-    {
1524
-        $reg_status_change_form_array = [
1525
-            'name'            => 'reg_status_change_form',
1526
-            'html_id'         => 'reg-status-change-form',
1527
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1528
-            'subsections'     => [
1529
-                'return'         => new EE_Hidden_Input(
1530
-                    [
1531
-                        'name'    => 'return',
1532
-                        'default' => 'view_registration',
1533
-                    ]
1534
-                ),
1535
-                'REG_ID'         => new EE_Hidden_Input(
1536
-                    [
1537
-                        'name'    => 'REG_ID',
1538
-                        'default' => $this->_registration->ID(),
1539
-                    ]
1540
-                ),
1541
-                'current_status' => new EE_Form_Section_HTML(
1542
-                    EEH_HTML::table(
1543
-                        EEH_HTML::tr(
1544
-                            EEH_HTML::th(
1545
-                                EEH_HTML::label(
1546
-                                    EEH_HTML::strong(
1547
-                                        esc_html__('Current Registration Status', 'event_espresso')
1548
-                                    )
1549
-                                )
1550
-                            )
1551
-                            . EEH_HTML::td(
1552
-                                EEH_HTML::strong(
1553
-                                    $this->_registration->pretty_status(),
1554
-                                    '',
1555
-                                    'status-' . $this->_registration->status_ID(),
1556
-                                    'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1557
-                                )
1558
-                            )
1559
-                        )
1560
-                    )
1561
-                ),
1562
-            ],
1563
-        ];
1564
-        if (
1565
-            EE_Registry::instance()->CAP->current_user_can(
1566
-                'ee_edit_registration',
1567
-                'toggle_registration_status',
1568
-                $this->_registration->ID()
1569
-            )
1570
-        ) {
1571
-            $reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1572
-                $this->_get_reg_statuses(),
1573
-                [
1574
-                    'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1575
-                    'default'         => $this->_registration->status_ID(),
1576
-                ]
1577
-            );
1578
-            $reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1579
-                [
1580
-                    'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1581
-                    'default'         => false,
1582
-                    'html_help_text'  => esc_html__(
1583
-                        'If set to "Yes", then the related messages will be sent to the registrant.',
1584
-                        'event_espresso'
1585
-                    ),
1586
-                ]
1587
-            );
1588
-            $reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1589
-                [
1590
-                    'html_class'      => 'button--primary',
1591
-                    'html_label_text' => '&nbsp;',
1592
-                    'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1593
-                ]
1594
-            );
1595
-        }
1596
-        return new EE_Form_Section_Proper($reg_status_change_form_array);
1597
-    }
1598
-
1599
-
1600
-    /**
1601
-     * Returns an array of all the buttons for the various statuses and switch status actions
1602
-     *
1603
-     * @return array
1604
-     * @throws EE_Error
1605
-     * @throws InvalidArgumentException
1606
-     * @throws InvalidDataTypeException
1607
-     * @throws InvalidInterfaceException
1608
-     * @throws EntityNotFoundException
1609
-     */
1610
-    protected function _get_reg_statuses()
1611
-    {
1612
-        $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1613
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1614
-        // get current reg status
1615
-        $current_status = $this->_registration->status_ID();
1616
-        // is registration for free event? This will determine whether to display the pending payment option
1617
-        if (
1618
-            $current_status !== EEM_Registration::status_id_pending_payment
1619
-            && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1620
-        ) {
1621
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1622
-        }
1623
-        return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1624
-    }
1625
-
1626
-
1627
-    /**
1628
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1629
-     *
1630
-     * @param bool $status REG status given for changing registrations to.
1631
-     * @param bool $notify Whether to send messages notifications or not.
1632
-     * @return array (array with reg_id(s) updated and whether update was successful.
1633
-     * @throws DomainException
1634
-     * @throws EE_Error
1635
-     * @throws EntityNotFoundException
1636
-     * @throws InvalidArgumentException
1637
-     * @throws InvalidDataTypeException
1638
-     * @throws InvalidInterfaceException
1639
-     * @throws ReflectionException
1640
-     * @throws RuntimeException
1641
-     */
1642
-    protected function _set_registration_status_from_request($status = false, $notify = false)
1643
-    {
1644
-        $REG_IDs = $this->request->requestParamIsSet('reg_status_change_form')
1645
-            ? $this->request->getRequestParam('reg_status_change_form[REG_ID]', [], 'int', true)
1646
-            : $this->request->getRequestParam('_REG_ID', [], 'int', true);
1647
-
1648
-        // sanitize $REG_IDs
1649
-        $REG_IDs = array_map('absint', $REG_IDs);
1650
-        // and remove empty entries
1651
-        $REG_IDs = array_filter($REG_IDs);
1652
-
1653
-        $result = $this->_set_registration_status($REG_IDs, $status, $notify);
1654
-
1655
-        /**
1656
-         * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1657
-         * Currently this value is used downstream by the _process_resend_registration method.
1658
-         *
1659
-         * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1660
-         * @param bool                     $status           The status registrations were changed to.
1661
-         * @param bool                     $success          If the status was changed successfully for all registrations.
1662
-         * @param Registrations_Admin_Page $admin_page_object
1663
-         */
1664
-        $REG_ID = apply_filters(
1665
-            'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1666
-            $result['REG_ID'],
1667
-            $status,
1668
-            $result['success'],
1669
-            $this
1670
-        );
1671
-        $this->request->setRequestParam('_REG_ID', $REG_ID);
1672
-
1673
-        // notify?
1674
-        if (
1675
-            $notify
1676
-            && $result['success']
1677
-            && ! empty($REG_ID)
1678
-            && EE_Registry::instance()->CAP->current_user_can(
1679
-                'ee_send_message',
1680
-                'espresso_registrations_resend_registration'
1681
-            )
1682
-        ) {
1683
-            $this->_process_resend_registration();
1684
-        }
1685
-        return $result;
1686
-    }
1687
-
1688
-
1689
-    /**
1690
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1691
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1692
-     *
1693
-     * @param array  $REG_IDs
1694
-     * @param string $status
1695
-     * @param bool   $notify Used to indicate whether notification was requested or not.  This determines the context
1696
-     *                       slug sent with setting the registration status.
1697
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1698
-     * @throws EE_Error
1699
-     * @throws InvalidArgumentException
1700
-     * @throws InvalidDataTypeException
1701
-     * @throws InvalidInterfaceException
1702
-     * @throws ReflectionException
1703
-     * @throws RuntimeException
1704
-     * @throws EntityNotFoundException
1705
-     * @throws DomainException
1706
-     */
1707
-    protected function _set_registration_status($REG_IDs = [], $status = '', $notify = false)
1708
-    {
1709
-        $success = false;
1710
-        // typecast $REG_IDs
1711
-        $REG_IDs = (array) $REG_IDs;
1712
-        if (! empty($REG_IDs)) {
1713
-            $success = true;
1714
-            // set default status if none is passed
1715
-            $status         = $status ?: EEM_Registration::status_id_pending_payment;
1716
-            $status_context = $notify
1717
-                ? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1718
-                : Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1719
-            // loop through REG_ID's and change status
1720
-            foreach ($REG_IDs as $REG_ID) {
1721
-                $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1722
-                if ($registration instanceof EE_Registration) {
1723
-                    $registration->set_status(
1724
-                        $status,
1725
-                        false,
1726
-                        new Context(
1727
-                            $status_context,
1728
-                            esc_html__(
1729
-                                'Manually triggered status change on a Registration Admin Page route.',
1730
-                                'event_espresso'
1731
-                            )
1732
-                        )
1733
-                    );
1734
-                    $result = $registration->save();
1735
-                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1736
-                    $success = $result !== false ? $success : false;
1737
-                }
1738
-            }
1739
-        }
1740
-
1741
-        // return $success and processed registrations
1742
-        return ['REG_ID' => $REG_IDs, 'success' => $success];
1743
-    }
1744
-
1745
-
1746
-    /**
1747
-     * Common logic for setting up success message and redirecting to appropriate route
1748
-     *
1749
-     * @param string $STS_ID status id for the registration changed to
1750
-     * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1751
-     * @return void
1752
-     * @throws DomainException
1753
-     * @throws EE_Error
1754
-     * @throws EntityNotFoundException
1755
-     * @throws InvalidArgumentException
1756
-     * @throws InvalidDataTypeException
1757
-     * @throws InvalidInterfaceException
1758
-     * @throws ReflectionException
1759
-     * @throws RuntimeException
1760
-     */
1761
-    protected function _reg_status_change_return($STS_ID, $notify = false)
1762
-    {
1763
-        $result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1764
-            : ['success' => false];
1765
-        $success = isset($result['success']) && $result['success'];
1766
-        // setup success message
1767
-        if ($success) {
1768
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1769
-                $msg = sprintf(
1770
-                    esc_html__('Registration status has been set to %s', 'event_espresso'),
1771
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1772
-                );
1773
-            } else {
1774
-                $msg = sprintf(
1775
-                    esc_html__('Registrations have been set to %s.', 'event_espresso'),
1776
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1777
-                );
1778
-            }
1779
-            EE_Error::add_success($msg);
1780
-        } else {
1781
-            EE_Error::add_error(
1782
-                esc_html__(
1783
-                    'Something went wrong, and the status was not changed',
1784
-                    'event_espresso'
1785
-                ),
1786
-                __FILE__,
1787
-                __LINE__,
1788
-                __FUNCTION__
1789
-            );
1790
-        }
1791
-        $return = $this->request->getRequestParam('return');
1792
-        $route  = $return === 'view_registration'
1793
-            ? ['action' => 'view_registration', '_REG_ID' => reset($result['REG_ID'])]
1794
-            : ['action' => 'default'];
1795
-        $route  = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1796
-        $this->_redirect_after_action($success, '', '', $route, true);
1797
-    }
1798
-
1799
-
1800
-    /**
1801
-     * incoming reg status change from reg details page.
1802
-     *
1803
-     * @return void
1804
-     * @throws EE_Error
1805
-     * @throws EntityNotFoundException
1806
-     * @throws InvalidArgumentException
1807
-     * @throws InvalidDataTypeException
1808
-     * @throws InvalidInterfaceException
1809
-     * @throws ReflectionException
1810
-     * @throws RuntimeException
1811
-     * @throws DomainException
1812
-     */
1813
-    protected function _change_reg_status()
1814
-    {
1815
-        $this->request->setRequestParam('return', 'view_registration');
1816
-        // set notify based on whether the send notifications toggle is set or not
1817
-        $notify     = $this->request->getRequestParam('reg_status_change_form[send_notifications]', false, 'bool');
1818
-        $reg_status = $this->request->getRequestParam('reg_status_change_form[reg_status]', '');
1819
-        $this->request->setRequestParam('reg_status_change_form[reg_status]', $reg_status);
1820
-        switch ($reg_status) {
1821
-            case EEM_Registration::status_id_approved:
1822
-            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1823
-                $this->approve_registration($notify);
1824
-                break;
1825
-            case EEM_Registration::status_id_pending_payment:
1826
-            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1827
-                $this->pending_registration($notify);
1828
-                break;
1829
-            case EEM_Registration::status_id_not_approved:
1830
-            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1831
-                $this->not_approve_registration($notify);
1832
-                break;
1833
-            case EEM_Registration::status_id_declined:
1834
-            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1835
-                $this->decline_registration($notify);
1836
-                break;
1837
-            case EEM_Registration::status_id_cancelled:
1838
-            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1839
-                $this->cancel_registration($notify);
1840
-                break;
1841
-            case EEM_Registration::status_id_wait_list:
1842
-            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1843
-                $this->wait_list_registration($notify);
1844
-                break;
1845
-            case EEM_Registration::status_id_incomplete:
1846
-            default:
1847
-                $this->request->unSetRequestParam('return');
1848
-                $this->_reg_status_change_return('');
1849
-                break;
1850
-        }
1851
-    }
1852
-
1853
-
1854
-    /**
1855
-     * Callback for bulk action routes.
1856
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1857
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
1858
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1859
-     * when an action is happening on just a single registration).
1860
-     *
1861
-     * @param      $action
1862
-     * @param bool $notify
1863
-     */
1864
-    protected function bulk_action_on_registrations($action, $notify = false)
1865
-    {
1866
-        do_action(
1867
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1868
-            $this,
1869
-            $action,
1870
-            $notify
1871
-        );
1872
-        $method = $action . '_registration';
1873
-        if (method_exists($this, $method)) {
1874
-            $this->$method($notify);
1875
-        }
1876
-    }
1877
-
1878
-
1879
-    /**
1880
-     * approve_registration
1881
-     *
1882
-     * @param bool $notify whether or not to notify the registrant about their approval.
1883
-     * @return void
1884
-     * @throws EE_Error
1885
-     * @throws EntityNotFoundException
1886
-     * @throws InvalidArgumentException
1887
-     * @throws InvalidDataTypeException
1888
-     * @throws InvalidInterfaceException
1889
-     * @throws ReflectionException
1890
-     * @throws RuntimeException
1891
-     * @throws DomainException
1892
-     */
1893
-    protected function approve_registration($notify = false)
1894
-    {
1895
-        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1896
-    }
1897
-
1898
-
1899
-    /**
1900
-     * decline_registration
1901
-     *
1902
-     * @param bool $notify whether or not to notify the registrant about their status change.
1903
-     * @return void
1904
-     * @throws EE_Error
1905
-     * @throws EntityNotFoundException
1906
-     * @throws InvalidArgumentException
1907
-     * @throws InvalidDataTypeException
1908
-     * @throws InvalidInterfaceException
1909
-     * @throws ReflectionException
1910
-     * @throws RuntimeException
1911
-     * @throws DomainException
1912
-     */
1913
-    protected function decline_registration($notify = false)
1914
-    {
1915
-        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1916
-    }
1917
-
1918
-
1919
-    /**
1920
-     * cancel_registration
1921
-     *
1922
-     * @param bool $notify whether or not to notify the registrant about their status change.
1923
-     * @return void
1924
-     * @throws EE_Error
1925
-     * @throws EntityNotFoundException
1926
-     * @throws InvalidArgumentException
1927
-     * @throws InvalidDataTypeException
1928
-     * @throws InvalidInterfaceException
1929
-     * @throws ReflectionException
1930
-     * @throws RuntimeException
1931
-     * @throws DomainException
1932
-     */
1933
-    protected function cancel_registration($notify = false)
1934
-    {
1935
-        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1936
-    }
1937
-
1938
-
1939
-    /**
1940
-     * not_approve_registration
1941
-     *
1942
-     * @param bool $notify whether or not to notify the registrant about their status change.
1943
-     * @return void
1944
-     * @throws EE_Error
1945
-     * @throws EntityNotFoundException
1946
-     * @throws InvalidArgumentException
1947
-     * @throws InvalidDataTypeException
1948
-     * @throws InvalidInterfaceException
1949
-     * @throws ReflectionException
1950
-     * @throws RuntimeException
1951
-     * @throws DomainException
1952
-     */
1953
-    protected function not_approve_registration($notify = false)
1954
-    {
1955
-        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1956
-    }
1957
-
1958
-
1959
-    /**
1960
-     * decline_registration
1961
-     *
1962
-     * @param bool $notify whether or not to notify the registrant about their status change.
1963
-     * @return void
1964
-     * @throws EE_Error
1965
-     * @throws EntityNotFoundException
1966
-     * @throws InvalidArgumentException
1967
-     * @throws InvalidDataTypeException
1968
-     * @throws InvalidInterfaceException
1969
-     * @throws ReflectionException
1970
-     * @throws RuntimeException
1971
-     * @throws DomainException
1972
-     */
1973
-    protected function pending_registration($notify = false)
1974
-    {
1975
-        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1976
-    }
1977
-
1978
-
1979
-    /**
1980
-     * waitlist_registration
1981
-     *
1982
-     * @param bool $notify whether or not to notify the registrant about their status change.
1983
-     * @return void
1984
-     * @throws EE_Error
1985
-     * @throws EntityNotFoundException
1986
-     * @throws InvalidArgumentException
1987
-     * @throws InvalidDataTypeException
1988
-     * @throws InvalidInterfaceException
1989
-     * @throws ReflectionException
1990
-     * @throws RuntimeException
1991
-     * @throws DomainException
1992
-     */
1993
-    protected function wait_list_registration($notify = false)
1994
-    {
1995
-        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1996
-    }
1997
-
1998
-
1999
-    /**
2000
-     * generates HTML for the Registration main meta box
2001
-     *
2002
-     * @return void
2003
-     * @throws DomainException
2004
-     * @throws EE_Error
2005
-     * @throws InvalidArgumentException
2006
-     * @throws InvalidDataTypeException
2007
-     * @throws InvalidInterfaceException
2008
-     * @throws ReflectionException
2009
-     * @throws EntityNotFoundException
2010
-     */
2011
-    public function _reg_details_meta_box()
2012
-    {
2013
-        EEH_Autoloader::register_line_item_display_autoloaders();
2014
-        EEH_Autoloader::register_line_item_filter_autoloaders();
2015
-        EE_Registry::instance()->load_helper('Line_Item');
2016
-        $transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
2017
-            : EE_Transaction::new_instance();
2018
-        $this->_session = $transaction->session_data();
2019
-        $filters        = new EE_Line_Item_Filter_Collection();
2020
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2021
-        $filters->add(new EE_Non_Zero_Line_Item_Filter());
2022
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2023
-            $filters,
2024
-            $transaction->total_line_item()
2025
-        );
2026
-        $filtered_line_item_tree                 = $line_item_filter_processor->process();
2027
-        $line_item_display                       = new EE_Line_Item_Display(
2028
-            'reg_admin_table',
2029
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2030
-        );
2031
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2032
-            $filtered_line_item_tree,
2033
-            ['EE_Registration' => $this->_registration]
2034
-        );
2035
-        $attendee                                = $this->_registration->attendee();
2036
-        if (
2037
-            EE_Registry::instance()->CAP->current_user_can(
2038
-                'ee_read_transaction',
2039
-                'espresso_transactions_view_transaction'
2040
-            )
2041
-        ) {
2042
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2043
-                EE_Admin_Page::add_query_args_and_nonce(
2044
-                    [
2045
-                        'action' => 'view_transaction',
2046
-                        'TXN_ID' => $transaction->ID(),
2047
-                    ],
2048
-                    TXN_ADMIN_URL
2049
-                ),
2050
-                esc_html__(' View Transaction', 'event_espresso'),
2051
-                'button button--secondary right',
2052
-                'dashicons dashicons-cart'
2053
-            );
2054
-        } else {
2055
-            $this->_template_args['view_transaction_button'] = '';
2056
-        }
2057
-        if (
2058
-            $attendee instanceof EE_Attendee
2059
-            && EE_Registry::instance()->CAP->current_user_can(
2060
-                'ee_send_message',
2061
-                'espresso_registrations_resend_registration'
2062
-            )
2063
-        ) {
2064
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2065
-                EE_Admin_Page::add_query_args_and_nonce(
2066
-                    [
2067
-                        'action'      => 'resend_registration',
2068
-                        '_REG_ID'     => $this->_registration->ID(),
2069
-                        'redirect_to' => 'view_registration',
2070
-                    ],
2071
-                    REG_ADMIN_URL
2072
-                ),
2073
-                esc_html__(' Resend Registration', 'event_espresso'),
2074
-                'button button--secondary right',
2075
-                'dashicons dashicons-email-alt'
2076
-            );
2077
-        } else {
2078
-            $this->_template_args['resend_registration_button'] = '';
2079
-        }
2080
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2081
-        $payment                               = $transaction->get_first_related('Payment');
2082
-        $payment                               = ! $payment instanceof EE_Payment
2083
-            ? EE_Payment::new_instance()
2084
-            : $payment;
2085
-        $payment_method                        = $payment->get_first_related('Payment_Method');
2086
-        $payment_method                        = ! $payment_method instanceof EE_Payment_Method
2087
-            ? EE_Payment_Method::new_instance()
2088
-            : $payment_method;
2089
-        $reg_details                           = [
2090
-            'payment_method'       => $payment_method->name(),
2091
-            'response_msg'         => $payment->gateway_response(),
2092
-            'registration_id'      => $this->_registration->get('REG_code'),
2093
-            'registration_session' => $this->_registration->session_ID(),
2094
-            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2095
-            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2096
-        ];
2097
-        if (isset($reg_details['registration_id'])) {
2098
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2099
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2100
-                'Registration ID',
2101
-                'event_espresso'
2102
-            );
2103
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2104
-        }
2105
-        if (isset($reg_details['payment_method'])) {
2106
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2107
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2108
-                'Most Recent Payment Method',
2109
-                'event_espresso'
2110
-            );
2111
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2112
-            $this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2113
-            $this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2114
-                'Payment method response',
2115
-                'event_espresso'
2116
-            );
2117
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2118
-        }
2119
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2120
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2121
-            'Registration Session',
2122
-            'event_espresso'
2123
-        );
2124
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2125
-        $this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2126
-        $this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2127
-            'Registration placed from IP',
2128
-            'event_espresso'
2129
-        );
2130
-        $this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2131
-        $this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2132
-        $this->_template_args['reg_details']['user_agent']['label']           = esc_html__(
2133
-            'Registrant User Agent',
2134
-            'event_espresso'
2135
-        );
2136
-        $this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2137
-        $this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2138
-            [
2139
-                'action'   => 'default',
2140
-                'event_id' => $this->_registration->event_ID(),
2141
-            ],
2142
-            REG_ADMIN_URL
2143
-        );
2144
-
2145
-        $this->_template_args['REG_ID'] = $this->_registration->ID();
2146
-        $this->_template_args['event_id'] = $this->_registration->event_ID();
2147
-
2148
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2149
-        EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2150
-    }
2151
-
2152
-
2153
-    /**
2154
-     * generates HTML for the Registration Questions meta box.
2155
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2156
-     * otherwise uses new forms system
2157
-     *
2158
-     * @return void
2159
-     * @throws DomainException
2160
-     * @throws EE_Error
2161
-     * @throws InvalidArgumentException
2162
-     * @throws InvalidDataTypeException
2163
-     * @throws InvalidInterfaceException
2164
-     * @throws ReflectionException
2165
-     */
2166
-    public function _reg_questions_meta_box()
2167
-    {
2168
-        // allow someone to override this method entirely
2169
-        if (
2170
-            apply_filters(
2171
-                'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2172
-                true,
2173
-                $this,
2174
-                $this->_registration
2175
-            )
2176
-        ) {
2177
-            $form = $this->_get_reg_custom_questions_form(
2178
-                $this->_registration->ID()
2179
-            );
2180
-
2181
-            $this->_template_args['att_questions'] = count($form->subforms()) > 0
2182
-                ? $form->get_html_and_js()
2183
-                : '';
2184
-
2185
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2186
-            $this->_template_args['REG_ID'] = $this->_registration->ID();
2187
-            $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2188
-            EEH_Template::display_template($template_path, $this->_template_args);
2189
-        }
2190
-    }
2191
-
2192
-
2193
-    /**
2194
-     * form_before_question_group
2195
-     *
2196
-     * @param string $output
2197
-     * @return        string
2198
-     * @deprecated    as of 4.8.32.rc.000
2199
-     */
2200
-    public function form_before_question_group($output)
2201
-    {
2202
-        EE_Error::doing_it_wrong(
2203
-            __CLASS__ . '::' . __FUNCTION__,
2204
-            esc_html__(
2205
-                '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.',
2206
-                'event_espresso'
2207
-            ),
2208
-            '4.8.32.rc.000'
2209
-        );
2210
-        return '
22
+	/**
23
+	 * @var EE_Registration
24
+	 */
25
+	private $_registration;
26
+
27
+	/**
28
+	 * @var EE_Event
29
+	 */
30
+	private $_reg_event;
31
+
32
+	/**
33
+	 * @var EE_Session
34
+	 */
35
+	private $_session;
36
+
37
+	/**
38
+	 * @var array
39
+	 */
40
+	private static $_reg_status;
41
+
42
+	/**
43
+	 * Form for displaying the custom questions for this registration.
44
+	 * This gets used a few times throughout the request so its best to cache it
45
+	 *
46
+	 * @var EE_Registration_Custom_Questions_Form
47
+	 */
48
+	protected $_reg_custom_questions_form;
49
+
50
+	/**
51
+	 * @var EEM_Registration $registration_model
52
+	 */
53
+	private $registration_model;
54
+
55
+	/**
56
+	 * @var EEM_Attendee $attendee_model
57
+	 */
58
+	private $attendee_model;
59
+
60
+	/**
61
+	 * @var EEM_Event $event_model
62
+	 */
63
+	private $event_model;
64
+
65
+	/**
66
+	 * @var EEM_Status $status_model
67
+	 */
68
+	private $status_model;
69
+
70
+
71
+	/**
72
+	 * @param bool $routing
73
+	 * @throws EE_Error
74
+	 * @throws InvalidArgumentException
75
+	 * @throws InvalidDataTypeException
76
+	 * @throws InvalidInterfaceException
77
+	 * @throws ReflectionException
78
+	 */
79
+	public function __construct($routing = true)
80
+	{
81
+		parent::__construct($routing);
82
+		add_action('wp_loaded', [$this, 'wp_loaded']);
83
+	}
84
+
85
+
86
+	/**
87
+	 * @return EEM_Registration
88
+	 * @throws InvalidArgumentException
89
+	 * @throws InvalidDataTypeException
90
+	 * @throws InvalidInterfaceException
91
+	 * @since 4.10.2.p
92
+	 */
93
+	protected function getRegistrationModel()
94
+	{
95
+		if (! $this->registration_model instanceof EEM_Registration) {
96
+			$this->registration_model = $this->loader->getShared('EEM_Registration');
97
+		}
98
+		return $this->registration_model;
99
+	}
100
+
101
+
102
+	/**
103
+	 * @return EEM_Attendee
104
+	 * @throws InvalidArgumentException
105
+	 * @throws InvalidDataTypeException
106
+	 * @throws InvalidInterfaceException
107
+	 * @since 4.10.2.p
108
+	 */
109
+	protected function getAttendeeModel()
110
+	{
111
+		if (! $this->attendee_model instanceof EEM_Attendee) {
112
+			$this->attendee_model = $this->loader->getShared('EEM_Attendee');
113
+		}
114
+		return $this->attendee_model;
115
+	}
116
+
117
+
118
+	/**
119
+	 * @return EEM_Event
120
+	 * @throws InvalidArgumentException
121
+	 * @throws InvalidDataTypeException
122
+	 * @throws InvalidInterfaceException
123
+	 * @since 4.10.2.p
124
+	 */
125
+	protected function getEventModel()
126
+	{
127
+		if (! $this->event_model instanceof EEM_Event) {
128
+			$this->event_model = $this->loader->getShared('EEM_Event');
129
+		}
130
+		return $this->event_model;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @return EEM_Status
136
+	 * @throws InvalidArgumentException
137
+	 * @throws InvalidDataTypeException
138
+	 * @throws InvalidInterfaceException
139
+	 * @since 4.10.2.p
140
+	 */
141
+	protected function getStatusModel()
142
+	{
143
+		if (! $this->status_model instanceof EEM_Status) {
144
+			$this->status_model = $this->loader->getShared('EEM_Status');
145
+		}
146
+		return $this->status_model;
147
+	}
148
+
149
+
150
+	public function wp_loaded()
151
+	{
152
+		// when adding a new registration...
153
+		$action = $this->request->getRequestParam('action');
154
+		if ($action === 'new_registration') {
155
+			EE_System::do_not_cache();
156
+			if ($this->request->getRequestParam('processing_registration', 0, 'int') !== 1) {
157
+				// and it's NOT the attendee information reg step
158
+				// force cookie expiration by setting time to last week
159
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
160
+				// and update the global
161
+				$_COOKIE['ee_registration_added'] = 0;
162
+			}
163
+		}
164
+	}
165
+
166
+
167
+	protected function _init_page_props()
168
+	{
169
+		$this->page_slug        = REG_PG_SLUG;
170
+		$this->_admin_base_url  = REG_ADMIN_URL;
171
+		$this->_admin_base_path = REG_ADMIN;
172
+		$this->page_label       = esc_html__('Registrations', 'event_espresso');
173
+		$this->_cpt_routes      = [
174
+			'add_new_attendee' => 'espresso_attendees',
175
+			'edit_attendee'    => 'espresso_attendees',
176
+			'insert_attendee'  => 'espresso_attendees',
177
+			'update_attendee'  => 'espresso_attendees',
178
+		];
179
+		$this->_cpt_model_names = [
180
+			'add_new_attendee' => 'EEM_Attendee',
181
+			'edit_attendee'    => 'EEM_Attendee',
182
+		];
183
+		$this->_cpt_edit_routes = [
184
+			'espresso_attendees' => 'edit_attendee',
185
+		];
186
+		$this->_pagenow_map     = [
187
+			'add_new_attendee' => 'post-new.php',
188
+			'edit_attendee'    => 'post.php',
189
+			'trash'            => 'post.php',
190
+		];
191
+		add_action('edit_form_after_title', [$this, 'after_title_form_fields'], 10);
192
+		// add filters so that the comment urls don't take users to a confusing 404 page
193
+		add_filter('get_comment_link', [$this, 'clear_comment_link'], 10, 2);
194
+	}
195
+
196
+
197
+	/**
198
+	 * @param string     $link    The comment permalink with '#comment-$id' appended.
199
+	 * @param WP_Comment $comment The current comment object.
200
+	 * @return string
201
+	 */
202
+	public function clear_comment_link($link, WP_Comment $comment)
203
+	{
204
+		// gotta make sure this only happens on this route
205
+		$post_type = get_post_type($comment->comment_post_ID);
206
+		if ($post_type === 'espresso_attendees') {
207
+			return '#commentsdiv';
208
+		}
209
+		return $link;
210
+	}
211
+
212
+
213
+	protected function _ajax_hooks()
214
+	{
215
+		// todo: all hooks for registrations ajax goes in here
216
+		add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
217
+	}
218
+
219
+
220
+	protected function _define_page_props()
221
+	{
222
+		$this->_admin_page_title = $this->page_label;
223
+		$this->_labels           = [
224
+			'buttons'                      => [
225
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
226
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
227
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
228
+				'report'              => esc_html__('Event Registrations CSV Report', 'event_espresso'),
229
+				'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
230
+				'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
231
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
232
+				'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
233
+			],
234
+			'publishbox'                   => [
235
+				'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
236
+				'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
237
+			],
238
+			'hide_add_button_on_cpt_route' => [
239
+				'edit_attendee' => true,
240
+			],
241
+		];
242
+	}
243
+
244
+
245
+	/**
246
+	 * grab url requests and route them
247
+	 *
248
+	 * @return void
249
+	 * @throws EE_Error
250
+	 */
251
+	public function _set_page_routes()
252
+	{
253
+		$this->_get_registration_status_array();
254
+		$REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
255
+		$REG_ID             = $this->request->getRequestParam('reg_status_change_form[REG_ID]', $REG_ID, 'int');
256
+		$ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
257
+		$ATT_ID             = $this->request->getRequestParam('post', $ATT_ID, 'int');
258
+		$this->_page_routes = [
259
+			'default'                             => [
260
+				'func'       => '_registrations_overview_list_table',
261
+				'capability' => 'ee_read_registrations',
262
+			],
263
+			'view_registration'                   => [
264
+				'func'       => '_registration_details',
265
+				'capability' => 'ee_read_registration',
266
+				'obj_id'     => $REG_ID,
267
+			],
268
+			'edit_registration'                   => [
269
+				'func'               => '_update_attendee_registration_form',
270
+				'noheader'           => true,
271
+				'headers_sent_route' => 'view_registration',
272
+				'capability'         => 'ee_edit_registration',
273
+				'obj_id'             => $REG_ID,
274
+				'_REG_ID'            => $REG_ID,
275
+			],
276
+			'trash_registrations'                 => [
277
+				'func'       => '_trash_or_restore_registrations',
278
+				'args'       => ['trash' => true],
279
+				'noheader'   => true,
280
+				'capability' => 'ee_delete_registrations',
281
+			],
282
+			'restore_registrations'               => [
283
+				'func'       => '_trash_or_restore_registrations',
284
+				'args'       => ['trash' => false],
285
+				'noheader'   => true,
286
+				'capability' => 'ee_delete_registrations',
287
+			],
288
+			'delete_registrations'                => [
289
+				'func'       => '_delete_registrations',
290
+				'noheader'   => true,
291
+				'capability' => 'ee_delete_registrations',
292
+			],
293
+			'new_registration'                    => [
294
+				'func'       => 'new_registration',
295
+				'capability' => 'ee_edit_registrations',
296
+			],
297
+			'process_reg_step'                    => [
298
+				'func'       => 'process_reg_step',
299
+				'noheader'   => true,
300
+				'capability' => 'ee_edit_registrations',
301
+			],
302
+			'redirect_to_txn'                     => [
303
+				'func'       => 'redirect_to_txn',
304
+				'noheader'   => true,
305
+				'capability' => 'ee_edit_registrations',
306
+			],
307
+			'change_reg_status'                   => [
308
+				'func'       => '_change_reg_status',
309
+				'noheader'   => true,
310
+				'capability' => 'ee_edit_registration',
311
+				'obj_id'     => $REG_ID,
312
+			],
313
+			'approve_registration'                => [
314
+				'func'       => 'approve_registration',
315
+				'noheader'   => true,
316
+				'capability' => 'ee_edit_registration',
317
+				'obj_id'     => $REG_ID,
318
+			],
319
+			'approve_and_notify_registration'     => [
320
+				'func'       => 'approve_registration',
321
+				'noheader'   => true,
322
+				'args'       => [true],
323
+				'capability' => 'ee_edit_registration',
324
+				'obj_id'     => $REG_ID,
325
+			],
326
+			'approve_registrations'               => [
327
+				'func'       => 'bulk_action_on_registrations',
328
+				'noheader'   => true,
329
+				'capability' => 'ee_edit_registrations',
330
+				'args'       => ['approve'],
331
+			],
332
+			'approve_and_notify_registrations'    => [
333
+				'func'       => 'bulk_action_on_registrations',
334
+				'noheader'   => true,
335
+				'capability' => 'ee_edit_registrations',
336
+				'args'       => ['approve', true],
337
+			],
338
+			'decline_registration'                => [
339
+				'func'       => 'decline_registration',
340
+				'noheader'   => true,
341
+				'capability' => 'ee_edit_registration',
342
+				'obj_id'     => $REG_ID,
343
+			],
344
+			'decline_and_notify_registration'     => [
345
+				'func'       => 'decline_registration',
346
+				'noheader'   => true,
347
+				'args'       => [true],
348
+				'capability' => 'ee_edit_registration',
349
+				'obj_id'     => $REG_ID,
350
+			],
351
+			'decline_registrations'               => [
352
+				'func'       => 'bulk_action_on_registrations',
353
+				'noheader'   => true,
354
+				'capability' => 'ee_edit_registrations',
355
+				'args'       => ['decline'],
356
+			],
357
+			'decline_and_notify_registrations'    => [
358
+				'func'       => 'bulk_action_on_registrations',
359
+				'noheader'   => true,
360
+				'capability' => 'ee_edit_registrations',
361
+				'args'       => ['decline', true],
362
+			],
363
+			'pending_registration'                => [
364
+				'func'       => 'pending_registration',
365
+				'noheader'   => true,
366
+				'capability' => 'ee_edit_registration',
367
+				'obj_id'     => $REG_ID,
368
+			],
369
+			'pending_and_notify_registration'     => [
370
+				'func'       => 'pending_registration',
371
+				'noheader'   => true,
372
+				'args'       => [true],
373
+				'capability' => 'ee_edit_registration',
374
+				'obj_id'     => $REG_ID,
375
+			],
376
+			'pending_registrations'               => [
377
+				'func'       => 'bulk_action_on_registrations',
378
+				'noheader'   => true,
379
+				'capability' => 'ee_edit_registrations',
380
+				'args'       => ['pending'],
381
+			],
382
+			'pending_and_notify_registrations'    => [
383
+				'func'       => 'bulk_action_on_registrations',
384
+				'noheader'   => true,
385
+				'capability' => 'ee_edit_registrations',
386
+				'args'       => ['pending', true],
387
+			],
388
+			'no_approve_registration'             => [
389
+				'func'       => 'not_approve_registration',
390
+				'noheader'   => true,
391
+				'capability' => 'ee_edit_registration',
392
+				'obj_id'     => $REG_ID,
393
+			],
394
+			'no_approve_and_notify_registration'  => [
395
+				'func'       => 'not_approve_registration',
396
+				'noheader'   => true,
397
+				'args'       => [true],
398
+				'capability' => 'ee_edit_registration',
399
+				'obj_id'     => $REG_ID,
400
+			],
401
+			'no_approve_registrations'            => [
402
+				'func'       => 'bulk_action_on_registrations',
403
+				'noheader'   => true,
404
+				'capability' => 'ee_edit_registrations',
405
+				'args'       => ['not_approve'],
406
+			],
407
+			'no_approve_and_notify_registrations' => [
408
+				'func'       => 'bulk_action_on_registrations',
409
+				'noheader'   => true,
410
+				'capability' => 'ee_edit_registrations',
411
+				'args'       => ['not_approve', true],
412
+			],
413
+			'cancel_registration'                 => [
414
+				'func'       => 'cancel_registration',
415
+				'noheader'   => true,
416
+				'capability' => 'ee_edit_registration',
417
+				'obj_id'     => $REG_ID,
418
+			],
419
+			'cancel_and_notify_registration'      => [
420
+				'func'       => 'cancel_registration',
421
+				'noheader'   => true,
422
+				'args'       => [true],
423
+				'capability' => 'ee_edit_registration',
424
+				'obj_id'     => $REG_ID,
425
+			],
426
+			'cancel_registrations'                => [
427
+				'func'       => 'bulk_action_on_registrations',
428
+				'noheader'   => true,
429
+				'capability' => 'ee_edit_registrations',
430
+				'args'       => ['cancel'],
431
+			],
432
+			'cancel_and_notify_registrations'     => [
433
+				'func'       => 'bulk_action_on_registrations',
434
+				'noheader'   => true,
435
+				'capability' => 'ee_edit_registrations',
436
+				'args'       => ['cancel', true],
437
+			],
438
+			'wait_list_registration'              => [
439
+				'func'       => 'wait_list_registration',
440
+				'noheader'   => true,
441
+				'capability' => 'ee_edit_registration',
442
+				'obj_id'     => $REG_ID,
443
+			],
444
+			'wait_list_and_notify_registration'   => [
445
+				'func'       => 'wait_list_registration',
446
+				'noheader'   => true,
447
+				'args'       => [true],
448
+				'capability' => 'ee_edit_registration',
449
+				'obj_id'     => $REG_ID,
450
+			],
451
+			'contact_list'                        => [
452
+				'func'       => '_attendee_contact_list_table',
453
+				'capability' => 'ee_read_contacts',
454
+			],
455
+			'add_new_attendee'                    => [
456
+				'func' => '_create_new_cpt_item',
457
+				'args' => [
458
+					'new_attendee' => true,
459
+					'capability'   => 'ee_edit_contacts',
460
+				],
461
+			],
462
+			'edit_attendee'                       => [
463
+				'func'       => '_edit_cpt_item',
464
+				'capability' => 'ee_edit_contacts',
465
+				'obj_id'     => $ATT_ID,
466
+			],
467
+			'duplicate_attendee'                  => [
468
+				'func'       => '_duplicate_attendee',
469
+				'noheader'   => true,
470
+				'capability' => 'ee_edit_contacts',
471
+				'obj_id'     => $ATT_ID,
472
+			],
473
+			'insert_attendee'                     => [
474
+				'func'       => '_insert_or_update_attendee',
475
+				'args'       => [
476
+					'new_attendee' => true,
477
+				],
478
+				'noheader'   => true,
479
+				'capability' => 'ee_edit_contacts',
480
+			],
481
+			'update_attendee'                     => [
482
+				'func'       => '_insert_or_update_attendee',
483
+				'args'       => [
484
+					'new_attendee' => false,
485
+				],
486
+				'noheader'   => true,
487
+				'capability' => 'ee_edit_contacts',
488
+				'obj_id'     => $ATT_ID,
489
+			],
490
+			'trash_attendees'                     => [
491
+				'func'       => '_trash_or_restore_attendees',
492
+				'args'       => [
493
+					'trash' => 'true',
494
+				],
495
+				'noheader'   => true,
496
+				'capability' => 'ee_delete_contacts',
497
+			],
498
+			'trash_attendee'                      => [
499
+				'func'       => '_trash_or_restore_attendees',
500
+				'args'       => [
501
+					'trash' => true,
502
+				],
503
+				'noheader'   => true,
504
+				'capability' => 'ee_delete_contacts',
505
+				'obj_id'     => $ATT_ID,
506
+			],
507
+			'restore_attendees'                   => [
508
+				'func'       => '_trash_or_restore_attendees',
509
+				'args'       => [
510
+					'trash' => false,
511
+				],
512
+				'noheader'   => true,
513
+				'capability' => 'ee_delete_contacts',
514
+				'obj_id'     => $ATT_ID,
515
+			],
516
+			'resend_registration'                 => [
517
+				'func'       => '_resend_registration',
518
+				'noheader'   => true,
519
+				'capability' => 'ee_send_message',
520
+			],
521
+			'registrations_report'                => [
522
+				'func'       => '_registrations_report',
523
+				'noheader'   => true,
524
+				'capability' => 'ee_read_registrations',
525
+			],
526
+			'contact_list_export'                 => [
527
+				'func'       => '_contact_list_export',
528
+				'noheader'   => true,
529
+				'capability' => 'export',
530
+			],
531
+			'contact_list_report'                 => [
532
+				'func'       => '_contact_list_report',
533
+				'noheader'   => true,
534
+				'capability' => 'ee_read_contacts',
535
+			],
536
+		];
537
+	}
538
+
539
+
540
+	protected function _set_page_config()
541
+	{
542
+		$REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
543
+		$ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
544
+		$this->_page_config = [
545
+			'default'           => [
546
+				'nav'           => [
547
+					'label' => esc_html__('Overview', 'event_espresso'),
548
+					'order' => 5,
549
+				],
550
+				'help_tabs'     => [
551
+					'registrations_overview_help_tab'                       => [
552
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
553
+						'filename' => 'registrations_overview',
554
+					],
555
+					'registrations_overview_table_column_headings_help_tab' => [
556
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
557
+						'filename' => 'registrations_overview_table_column_headings',
558
+					],
559
+					'registrations_overview_filters_help_tab'               => [
560
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
561
+						'filename' => 'registrations_overview_filters',
562
+					],
563
+					'registrations_overview_views_help_tab'                 => [
564
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
565
+						'filename' => 'registrations_overview_views',
566
+					],
567
+					'registrations_regoverview_other_help_tab'              => [
568
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
569
+						'filename' => 'registrations_overview_other',
570
+					],
571
+				],
572
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
573
+				// 'help_tour'     => array('Registration_Overview_Help_Tour'),
574
+				'qtips'         => ['Registration_List_Table_Tips'],
575
+				'list_table'    => 'EE_Registrations_List_Table',
576
+				'require_nonce' => false,
577
+			],
578
+			'view_registration' => [
579
+				'nav'           => [
580
+					'label'      => esc_html__('REG Details', 'event_espresso'),
581
+					'order'      => 15,
582
+					'url'        => $REG_ID
583
+						? add_query_arg(['_REG_ID' => $REG_ID], $this->_current_page_view_url)
584
+						: $this->_admin_base_url,
585
+					'persistent' => false,
586
+				],
587
+				'help_tabs'     => [
588
+					'registrations_details_help_tab'                    => [
589
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
590
+						'filename' => 'registrations_details',
591
+					],
592
+					'registrations_details_table_help_tab'              => [
593
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
594
+						'filename' => 'registrations_details_table',
595
+					],
596
+					'registrations_details_form_answers_help_tab'       => [
597
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
598
+						'filename' => 'registrations_details_form_answers',
599
+					],
600
+					'registrations_details_registrant_details_help_tab' => [
601
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
602
+						'filename' => 'registrations_details_registrant_details',
603
+					],
604
+				],
605
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
606
+				// 'help_tour'     => array('Registration_Details_Help_Tour'),
607
+				'metaboxes'     => array_merge(
608
+					$this->_default_espresso_metaboxes,
609
+					['_registration_details_metaboxes']
610
+				),
611
+				'require_nonce' => false,
612
+			],
613
+			'new_registration'  => [
614
+				'nav'           => [
615
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
616
+					'url'        => '#',
617
+					'order'      => 15,
618
+					'persistent' => false,
619
+				],
620
+				'metaboxes'     => $this->_default_espresso_metaboxes,
621
+				'labels'        => [
622
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
623
+				],
624
+				'require_nonce' => false,
625
+			],
626
+			'add_new_attendee'  => [
627
+				'nav'           => [
628
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
629
+					'order'      => 15,
630
+					'persistent' => false,
631
+				],
632
+				'metaboxes'     => array_merge(
633
+					$this->_default_espresso_metaboxes,
634
+					['_publish_post_box', 'attendee_editor_metaboxes']
635
+				),
636
+				'require_nonce' => false,
637
+			],
638
+			'edit_attendee'     => [
639
+				'nav'           => [
640
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
641
+					'order'      => 15,
642
+					'persistent' => false,
643
+					'url'        => $ATT_ID
644
+						? add_query_arg(['ATT_ID' => $ATT_ID], $this->_current_page_view_url)
645
+						: $this->_admin_base_url,
646
+				],
647
+				'metaboxes'     => ['attendee_editor_metaboxes'],
648
+				'require_nonce' => false,
649
+			],
650
+			'contact_list'      => [
651
+				'nav'           => [
652
+					'label' => esc_html__('Contact List', 'event_espresso'),
653
+					'order' => 20,
654
+				],
655
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
656
+				'help_tabs'     => [
657
+					'registrations_contact_list_help_tab'                       => [
658
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
659
+						'filename' => 'registrations_contact_list',
660
+					],
661
+					'registrations_contact-list_table_column_headings_help_tab' => [
662
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
663
+						'filename' => 'registrations_contact_list_table_column_headings',
664
+					],
665
+					'registrations_contact_list_views_help_tab'                 => [
666
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
667
+						'filename' => 'registrations_contact_list_views',
668
+					],
669
+					'registrations_contact_list_other_help_tab'                 => [
670
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
671
+						'filename' => 'registrations_contact_list_other',
672
+					],
673
+				],
674
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
675
+				// 'help_tour'     => array('Contact_List_Help_Tour'),
676
+				'metaboxes'     => [],
677
+				'require_nonce' => false,
678
+			],
679
+			// override default cpt routes
680
+			'create_new'        => '',
681
+			'edit'              => '',
682
+		];
683
+	}
684
+
685
+
686
+	/**
687
+	 * The below methods aren't used by this class currently
688
+	 */
689
+	protected function _add_screen_options()
690
+	{
691
+	}
692
+
693
+
694
+	protected function _add_feature_pointers()
695
+	{
696
+	}
697
+
698
+
699
+	public function admin_init()
700
+	{
701
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
702
+			'click "Update Registration Questions" to save your changes',
703
+			'event_espresso'
704
+		);
705
+	}
706
+
707
+
708
+	public function admin_notices()
709
+	{
710
+	}
711
+
712
+
713
+	public function admin_footer_scripts()
714
+	{
715
+	}
716
+
717
+
718
+	/**
719
+	 * get list of registration statuses
720
+	 *
721
+	 * @return void
722
+	 * @throws EE_Error
723
+	 */
724
+	private function _get_registration_status_array()
725
+	{
726
+		self::$_reg_status = EEM_Registration::reg_status_array([], true);
727
+	}
728
+
729
+
730
+	/**
731
+	 * @throws InvalidArgumentException
732
+	 * @throws InvalidDataTypeException
733
+	 * @throws InvalidInterfaceException
734
+	 * @since 4.10.2.p
735
+	 */
736
+	protected function _add_screen_options_default()
737
+	{
738
+		$this->_per_page_screen_option();
739
+	}
740
+
741
+
742
+	/**
743
+	 * @throws InvalidArgumentException
744
+	 * @throws InvalidDataTypeException
745
+	 * @throws InvalidInterfaceException
746
+	 * @since 4.10.2.p
747
+	 */
748
+	protected function _add_screen_options_contact_list()
749
+	{
750
+		$page_title              = $this->_admin_page_title;
751
+		$this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
752
+		$this->_per_page_screen_option();
753
+		$this->_admin_page_title = $page_title;
754
+	}
755
+
756
+
757
+	public function load_scripts_styles()
758
+	{
759
+		// style
760
+		wp_register_style(
761
+			'espresso_reg',
762
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
763
+			['ee-admin-css'],
764
+			EVENT_ESPRESSO_VERSION
765
+		);
766
+		wp_enqueue_style('espresso_reg');
767
+		// script
768
+		wp_register_script(
769
+			'espresso_reg',
770
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
771
+			['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
772
+			EVENT_ESPRESSO_VERSION,
773
+			true
774
+		);
775
+		wp_enqueue_script('espresso_reg');
776
+	}
777
+
778
+
779
+	/**
780
+	 * @throws EE_Error
781
+	 * @throws InvalidArgumentException
782
+	 * @throws InvalidDataTypeException
783
+	 * @throws InvalidInterfaceException
784
+	 * @throws ReflectionException
785
+	 * @since 4.10.2.p
786
+	 */
787
+	public function load_scripts_styles_edit_attendee()
788
+	{
789
+		// stuff to only show up on our attendee edit details page.
790
+		$attendee_details_translations = [
791
+			'att_publish_text' => sprintf(
792
+			/* translators: The date and time */
793
+				wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
794
+				'<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
795
+			),
796
+		];
797
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
798
+		wp_enqueue_script('jquery-validate');
799
+	}
800
+
801
+
802
+	/**
803
+	 * @throws EE_Error
804
+	 * @throws InvalidArgumentException
805
+	 * @throws InvalidDataTypeException
806
+	 * @throws InvalidInterfaceException
807
+	 * @throws ReflectionException
808
+	 * @since 4.10.2.p
809
+	 */
810
+	public function load_scripts_styles_view_registration()
811
+	{
812
+		// styles
813
+		wp_enqueue_style('espresso-ui-theme');
814
+		// scripts
815
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
816
+		$this->_reg_custom_questions_form->wp_enqueue_scripts();
817
+	}
818
+
819
+
820
+	public function load_scripts_styles_contact_list()
821
+	{
822
+		wp_dequeue_style('espresso_reg');
823
+		wp_register_style(
824
+			'espresso_att',
825
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
826
+			['ee-admin-css'],
827
+			EVENT_ESPRESSO_VERSION
828
+		);
829
+		wp_enqueue_style('espresso_att');
830
+	}
831
+
832
+
833
+	public function load_scripts_styles_new_registration()
834
+	{
835
+		wp_register_script(
836
+			'ee-spco-for-admin',
837
+			REG_ASSETS_URL . 'spco_for_admin.js',
838
+			['underscore', 'jquery'],
839
+			EVENT_ESPRESSO_VERSION,
840
+			true
841
+		);
842
+		wp_enqueue_script('ee-spco-for-admin');
843
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
844
+		EE_Form_Section_Proper::wp_enqueue_scripts();
845
+		EED_Ticket_Selector::load_tckt_slctr_assets();
846
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
847
+	}
848
+
849
+
850
+	public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
851
+	{
852
+		add_filter('FHEE_load_EE_messages', '__return_true');
853
+	}
854
+
855
+
856
+	public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
857
+	{
858
+		add_filter('FHEE_load_EE_messages', '__return_true');
859
+	}
860
+
861
+
862
+	/**
863
+	 * @throws EE_Error
864
+	 * @throws InvalidArgumentException
865
+	 * @throws InvalidDataTypeException
866
+	 * @throws InvalidInterfaceException
867
+	 * @throws ReflectionException
868
+	 * @since 4.10.2.p
869
+	 */
870
+	protected function _set_list_table_views_default()
871
+	{
872
+		// for notification related bulk actions we need to make sure only active messengers have an option.
873
+		EED_Messages::set_autoloaders();
874
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
875
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
876
+		$active_mts               = $message_resource_manager->list_of_active_message_types();
877
+		// key= bulk_action_slug, value= message type.
878
+		$match_array = [
879
+			'approve_registrations'    => 'registration',
880
+			'decline_registrations'    => 'declined_registration',
881
+			'pending_registrations'    => 'pending_approval',
882
+			'no_approve_registrations' => 'not_approved_registration',
883
+			'cancel_registrations'     => 'cancelled_registration',
884
+		];
885
+		$can_send    = EE_Registry::instance()->CAP->current_user_can(
886
+			'ee_send_message',
887
+			'batch_send_messages'
888
+		);
889
+		/** setup reg status bulk actions **/
890
+		$def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
891
+		if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
892
+			$def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
893
+				'Approve and Notify Registrations',
894
+				'event_espresso'
895
+			);
896
+		}
897
+		$def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
898
+		if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
899
+			$def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
900
+				'Decline and Notify Registrations',
901
+				'event_espresso'
902
+			);
903
+		}
904
+		$def_reg_status_actions['pending_registrations'] = esc_html__(
905
+			'Set Registrations to Pending Payment',
906
+			'event_espresso'
907
+		);
908
+		if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
909
+			$def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
910
+				'Set Registrations to Pending Payment and Notify',
911
+				'event_espresso'
912
+			);
913
+		}
914
+		$def_reg_status_actions['no_approve_registrations'] = esc_html__(
915
+			'Set Registrations to Not Approved',
916
+			'event_espresso'
917
+		);
918
+		if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
919
+			$def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
920
+				'Set Registrations to Not Approved and Notify',
921
+				'event_espresso'
922
+			);
923
+		}
924
+		$def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
925
+		if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
926
+			$def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
927
+				'Cancel Registrations and Notify',
928
+				'event_espresso'
929
+			);
930
+		}
931
+		$def_reg_status_actions = apply_filters(
932
+			'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
933
+			$def_reg_status_actions,
934
+			$active_mts,
935
+			$can_send
936
+		);
937
+
938
+		$this->_views = [
939
+			'all'   => [
940
+				'slug'        => 'all',
941
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
942
+				'count'       => 0,
943
+				'bulk_action' => array_merge(
944
+					$def_reg_status_actions,
945
+					[
946
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
947
+					]
948
+				),
949
+			],
950
+			'month' => [
951
+				'slug'        => 'month',
952
+				'label'       => esc_html__('This Month', 'event_espresso'),
953
+				'count'       => 0,
954
+				'bulk_action' => array_merge(
955
+					$def_reg_status_actions,
956
+					[
957
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
958
+					]
959
+				),
960
+			],
961
+			'today' => [
962
+				'slug'        => 'today',
963
+				'label'       => sprintf(
964
+					esc_html__('Today - %s', 'event_espresso'),
965
+					date('M d, Y', current_time('timestamp'))
966
+				),
967
+				'count'       => 0,
968
+				'bulk_action' => array_merge(
969
+					$def_reg_status_actions,
970
+					[
971
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
972
+					]
973
+				),
974
+			],
975
+		];
976
+		if (
977
+			EE_Registry::instance()->CAP->current_user_can(
978
+				'ee_delete_registrations',
979
+				'espresso_registrations_delete_registration'
980
+			)
981
+		) {
982
+			$this->_views['incomplete'] = [
983
+				'slug'        => 'incomplete',
984
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
985
+				'count'       => 0,
986
+				'bulk_action' => [
987
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
988
+				],
989
+			];
990
+			$this->_views['trash']      = [
991
+				'slug'        => 'trash',
992
+				'label'       => esc_html__('Trash', 'event_espresso'),
993
+				'count'       => 0,
994
+				'bulk_action' => [
995
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
996
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
997
+				],
998
+			];
999
+		}
1000
+	}
1001
+
1002
+
1003
+	protected function _set_list_table_views_contact_list()
1004
+	{
1005
+		$this->_views = [
1006
+			'in_use' => [
1007
+				'slug'        => 'in_use',
1008
+				'label'       => esc_html__('In Use', 'event_espresso'),
1009
+				'count'       => 0,
1010
+				'bulk_action' => [
1011
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1012
+				],
1013
+			],
1014
+		];
1015
+		if (
1016
+			EE_Registry::instance()->CAP->current_user_can(
1017
+				'ee_delete_contacts',
1018
+				'espresso_registrations_trash_attendees'
1019
+			)
1020
+		) {
1021
+			$this->_views['trash'] = [
1022
+				'slug'        => 'trash',
1023
+				'label'       => esc_html__('Trash', 'event_espresso'),
1024
+				'count'       => 0,
1025
+				'bulk_action' => [
1026
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1027
+				],
1028
+			];
1029
+		}
1030
+	}
1031
+
1032
+
1033
+	/**
1034
+	 * @return array
1035
+	 * @throws EE_Error
1036
+	 */
1037
+	protected function _registration_legend_items()
1038
+	{
1039
+		$fc_items = [
1040
+			'star-icon'        => [
1041
+				'class' => 'dashicons dashicons-star-filled gold-icon ee-icon-size-8',
1042
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1043
+			],
1044
+			'view_details'     => [
1045
+				'class' => 'dashicons dashicons-clipboard',
1046
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1047
+			],
1048
+			'edit_attendee'    => [
1049
+				'class' => 'dashicons dashicons-groups ee-icon-size-16',
1050
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1051
+			],
1052
+			'view_transaction' => [
1053
+				'class' => 'dashicons dashicons-cart',
1054
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1055
+			],
1056
+			'view_invoice'     => [
1057
+				'class' => 'dashicons dashicons-media-spreadsheet',
1058
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1059
+			],
1060
+		];
1061
+		if (
1062
+			EE_Registry::instance()->CAP->current_user_can(
1063
+				'ee_send_message',
1064
+				'espresso_registrations_resend_registration'
1065
+			)
1066
+		) {
1067
+			$fc_items['resend_registration'] = [
1068
+				'class' => 'dashicons dashicons-email-alt',
1069
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1070
+			];
1071
+		} else {
1072
+			$fc_items['blank'] = ['class' => 'blank', 'desc' => ''];
1073
+		}
1074
+		if (
1075
+			EE_Registry::instance()->CAP->current_user_can(
1076
+				'ee_read_global_messages',
1077
+				'view_filtered_messages'
1078
+			)
1079
+		) {
1080
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1081
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1082
+				$fc_items['view_related_messages'] = [
1083
+					'class' => $related_for_icon['css_class'],
1084
+					'desc'  => $related_for_icon['label'],
1085
+				];
1086
+			}
1087
+		}
1088
+		$sc_items = [
1089
+			'approved_status'   => [
1090
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_approved,
1091
+				'desc'  => EEH_Template::pretty_status(
1092
+					EEM_Registration::status_id_approved,
1093
+					false,
1094
+					'sentence'
1095
+				),
1096
+			],
1097
+			'pending_status'    => [
1098
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_pending_payment,
1099
+				'desc'  => EEH_Template::pretty_status(
1100
+					EEM_Registration::status_id_pending_payment,
1101
+					false,
1102
+					'sentence'
1103
+				),
1104
+			],
1105
+			'wait_list'         => [
1106
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_wait_list,
1107
+				'desc'  => EEH_Template::pretty_status(
1108
+					EEM_Registration::status_id_wait_list,
1109
+					false,
1110
+					'sentence'
1111
+				),
1112
+			],
1113
+			'incomplete_status' => [
1114
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_incomplete,
1115
+				'desc'  => EEH_Template::pretty_status(
1116
+					EEM_Registration::status_id_incomplete,
1117
+					false,
1118
+					'sentence'
1119
+				),
1120
+			],
1121
+			'not_approved'      => [
1122
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_not_approved,
1123
+				'desc'  => EEH_Template::pretty_status(
1124
+					EEM_Registration::status_id_not_approved,
1125
+					false,
1126
+					'sentence'
1127
+				),
1128
+			],
1129
+			'declined_status'   => [
1130
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_declined,
1131
+				'desc'  => EEH_Template::pretty_status(
1132
+					EEM_Registration::status_id_declined,
1133
+					false,
1134
+					'sentence'
1135
+				),
1136
+			],
1137
+			'cancelled_status'  => [
1138
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_cancelled,
1139
+				'desc'  => EEH_Template::pretty_status(
1140
+					EEM_Registration::status_id_cancelled,
1141
+					false,
1142
+					'sentence'
1143
+				),
1144
+			],
1145
+		];
1146
+		return array_merge($fc_items, $sc_items);
1147
+	}
1148
+
1149
+
1150
+
1151
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
1152
+
1153
+
1154
+	/**
1155
+	 * @throws DomainException
1156
+	 * @throws EE_Error
1157
+	 * @throws InvalidArgumentException
1158
+	 * @throws InvalidDataTypeException
1159
+	 * @throws InvalidInterfaceException
1160
+	 */
1161
+	protected function _registrations_overview_list_table()
1162
+	{
1163
+		$this->appendAddNewRegistrationButtonToPageTitle();
1164
+		$header_text                  = '';
1165
+		$admin_page_header_decorators = [
1166
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1167
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1168
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1169
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1170
+		];
1171
+		foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1172
+			$filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1173
+			$header_text = $filter_header_decorator->getHeaderText($header_text);
1174
+		}
1175
+		$this->_template_args['admin_page_header'] = $header_text;
1176
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1177
+		$this->display_admin_list_table_page_with_no_sidebar();
1178
+	}
1179
+
1180
+
1181
+	/**
1182
+	 * @throws EE_Error
1183
+	 * @throws InvalidArgumentException
1184
+	 * @throws InvalidDataTypeException
1185
+	 * @throws InvalidInterfaceException
1186
+	 */
1187
+	private function appendAddNewRegistrationButtonToPageTitle()
1188
+	{
1189
+		$EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
1190
+		if (
1191
+			$EVT_ID
1192
+			&& EE_Registry::instance()->CAP->current_user_can(
1193
+				'ee_edit_registrations',
1194
+				'espresso_registrations_new_registration',
1195
+				$EVT_ID
1196
+			)
1197
+		) {
1198
+			$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1199
+				'new_registration',
1200
+				'add-registrant',
1201
+				['event_id' => $EVT_ID],
1202
+				'add-new-h2'
1203
+			);
1204
+		}
1205
+	}
1206
+
1207
+
1208
+	/**
1209
+	 * This sets the _registration property for the registration details screen
1210
+	 *
1211
+	 * @return void
1212
+	 * @throws EE_Error
1213
+	 * @throws InvalidArgumentException
1214
+	 * @throws InvalidDataTypeException
1215
+	 * @throws InvalidInterfaceException
1216
+	 */
1217
+	private function _set_registration_object()
1218
+	{
1219
+		// get out if we've already set the object
1220
+		if ($this->_registration instanceof EE_Registration) {
1221
+			return;
1222
+		}
1223
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
1224
+		if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1225
+			return;
1226
+		}
1227
+		$error_msg = sprintf(
1228
+			esc_html__(
1229
+				'An error occurred and the details for Registration ID #%s could not be retrieved.',
1230
+				'event_espresso'
1231
+			),
1232
+			$REG_ID
1233
+		);
1234
+		EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1235
+		$this->_registration = null;
1236
+	}
1237
+
1238
+
1239
+	/**
1240
+	 * Used to retrieve registrations for the list table.
1241
+	 *
1242
+	 * @param int  $per_page
1243
+	 * @param bool $count
1244
+	 * @param bool $this_month
1245
+	 * @param bool $today
1246
+	 * @return EE_Registration[]|int
1247
+	 * @throws EE_Error
1248
+	 * @throws InvalidArgumentException
1249
+	 * @throws InvalidDataTypeException
1250
+	 * @throws InvalidInterfaceException
1251
+	 */
1252
+	public function get_registrations(
1253
+		$per_page = 10,
1254
+		$count = false,
1255
+		$this_month = false,
1256
+		$today = false
1257
+	) {
1258
+		if ($this_month) {
1259
+			$this->request->setRequestParam('status', 'month');
1260
+		}
1261
+		if ($today) {
1262
+			$this->request->setRequestParam('status', 'today');
1263
+		}
1264
+		$query_params = $this->_get_registration_query_parameters($this->request->requestParams(), $per_page, $count);
1265
+		/**
1266
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1267
+		 *
1268
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1269
+		 * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1270
+		 *                      or if you have the development copy of EE you can view this at the path:
1271
+		 *                      /docs/G--Model-System/model-query-params.md
1272
+		 */
1273
+		$query_params['group_by'] = '';
1274
+
1275
+		return $count
1276
+			? $this->getRegistrationModel()->count($query_params)
1277
+			/** @type EE_Registration[] */
1278
+			: $this->getRegistrationModel()->get_all($query_params);
1279
+	}
1280
+
1281
+
1282
+	/**
1283
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1284
+	 * Note: this listens to values on the request for some of the query parameters.
1285
+	 *
1286
+	 * @param array $request
1287
+	 * @param int   $per_page
1288
+	 * @param bool  $count
1289
+	 * @return array
1290
+	 * @throws EE_Error
1291
+	 * @throws InvalidArgumentException
1292
+	 * @throws InvalidDataTypeException
1293
+	 * @throws InvalidInterfaceException
1294
+	 */
1295
+	protected function _get_registration_query_parameters(
1296
+		$request = [],
1297
+		$per_page = 10,
1298
+		$count = false
1299
+	) {
1300
+		/** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1301
+		$list_table_query_builder = $this->loader->getNew(
1302
+			'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1303
+			[null, null, $request]
1304
+		);
1305
+		return $list_table_query_builder->getQueryParams($per_page, $count);
1306
+	}
1307
+
1308
+
1309
+	public function get_registration_status_array()
1310
+	{
1311
+		return self::$_reg_status;
1312
+	}
1313
+
1314
+
1315
+
1316
+
1317
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1318
+	/**
1319
+	 * generates HTML for the View Registration Details Admin page
1320
+	 *
1321
+	 * @return void
1322
+	 * @throws DomainException
1323
+	 * @throws EE_Error
1324
+	 * @throws InvalidArgumentException
1325
+	 * @throws InvalidDataTypeException
1326
+	 * @throws InvalidInterfaceException
1327
+	 * @throws EntityNotFoundException
1328
+	 * @throws ReflectionException
1329
+	 */
1330
+	protected function _registration_details()
1331
+	{
1332
+		$this->_template_args = [];
1333
+		$this->_set_registration_object();
1334
+		if (is_object($this->_registration)) {
1335
+			$transaction                                   = $this->_registration->transaction()
1336
+				? $this->_registration->transaction()
1337
+				: EE_Transaction::new_instance();
1338
+			$this->_session                                = $transaction->session_data();
1339
+			$event_id                                      = $this->_registration->event_ID();
1340
+			$this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1341
+			$this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1342
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1343
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1344
+			$this->_template_args['grand_total']           = $transaction->total();
1345
+			$this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1346
+			// link back to overview
1347
+			$this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1348
+			$this->_template_args['registration']                = $this->_registration;
1349
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1350
+				[
1351
+					'action'   => 'default',
1352
+					'event_id' => $event_id,
1353
+				],
1354
+				REG_ADMIN_URL
1355
+			);
1356
+			$this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1357
+				[
1358
+					'action' => 'default',
1359
+					'EVT_ID' => $event_id,
1360
+					'page'   => 'espresso_transactions',
1361
+				],
1362
+				admin_url('admin.php')
1363
+			);
1364
+			$this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1365
+				[
1366
+					'page'   => 'espresso_events',
1367
+					'action' => 'edit',
1368
+					'post'   => $event_id,
1369
+				],
1370
+				admin_url('admin.php')
1371
+			);
1372
+			// next and previous links
1373
+			$next_reg                                      = $this->_registration->next(
1374
+				null,
1375
+				[],
1376
+				'REG_ID'
1377
+			);
1378
+			$this->_template_args['next_registration']     = $next_reg
1379
+				? $this->_next_link(
1380
+					EE_Admin_Page::add_query_args_and_nonce(
1381
+						[
1382
+							'action'  => 'view_registration',
1383
+							'_REG_ID' => $next_reg['REG_ID'],
1384
+						],
1385
+						REG_ADMIN_URL
1386
+					),
1387
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1388
+				)
1389
+				: '';
1390
+			$previous_reg                                  = $this->_registration->previous(
1391
+				null,
1392
+				[],
1393
+				'REG_ID'
1394
+			);
1395
+			$this->_template_args['previous_registration'] = $previous_reg
1396
+				? $this->_previous_link(
1397
+					EE_Admin_Page::add_query_args_and_nonce(
1398
+						[
1399
+							'action'  => 'view_registration',
1400
+							'_REG_ID' => $previous_reg['REG_ID'],
1401
+						],
1402
+						REG_ADMIN_URL
1403
+					),
1404
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1405
+				)
1406
+				: '';
1407
+			// grab header
1408
+			$template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1409
+			$this->_template_args['REG_ID']            = $this->_registration->ID();
1410
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1411
+				$template_path,
1412
+				$this->_template_args,
1413
+				true
1414
+			);
1415
+		} else {
1416
+			$this->_template_args['admin_page_header'] = '';
1417
+			$this->_display_espresso_notices();
1418
+		}
1419
+		// the details template wrapper
1420
+		$this->display_admin_page_with_sidebar();
1421
+	}
1422
+
1423
+
1424
+	/**
1425
+	 * @throws EE_Error
1426
+	 * @throws InvalidArgumentException
1427
+	 * @throws InvalidDataTypeException
1428
+	 * @throws InvalidInterfaceException
1429
+	 * @throws ReflectionException
1430
+	 * @since 4.10.2.p
1431
+	 */
1432
+	protected function _registration_details_metaboxes()
1433
+	{
1434
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1435
+		$this->_set_registration_object();
1436
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1437
+		$this->addMetaBox(
1438
+			'edit-reg-status-mbox',
1439
+			esc_html__('Registration Status', 'event_espresso'),
1440
+			[$this, 'set_reg_status_buttons_metabox'],
1441
+			$this->_wp_page_slug
1442
+		);
1443
+		$this->addMetaBox(
1444
+			'edit-reg-details-mbox',
1445
+			'<span>' . esc_html__('Registration Details', 'event_espresso')
1446
+			. '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1447
+			[$this, '_reg_details_meta_box'],
1448
+			$this->_wp_page_slug
1449
+		);
1450
+		if (
1451
+			$attendee instanceof EE_Attendee
1452
+			&& EE_Registry::instance()->CAP->current_user_can(
1453
+				'ee_read_registration',
1454
+				'edit-reg-questions-mbox',
1455
+				$this->_registration->ID()
1456
+			)
1457
+		) {
1458
+			$this->addMetaBox(
1459
+				$this->_wp_page_slug,
1460
+				'edit-reg-questions-mbox',
1461
+				esc_html__('Registration Form Answers', 'event_espresso'),
1462
+				[$this, '_reg_questions_meta_box'],
1463
+				$this->_wp_page_slug
1464
+			);
1465
+		}
1466
+		$this->addMetaBox(
1467
+			'edit-reg-registrant-mbox',
1468
+			esc_html__('Contact Details', 'event_espresso'),
1469
+			[$this, '_reg_registrant_side_meta_box'],
1470
+			$this->_wp_page_slug,
1471
+			'side'
1472
+		);
1473
+		if ($this->_registration->group_size() > 1) {
1474
+			$this->addMetaBox(
1475
+				'edit-reg-attendees-mbox',
1476
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1477
+				[$this, '_reg_attendees_meta_box'],
1478
+				$this->_wp_page_slug
1479
+			);
1480
+		}
1481
+	}
1482
+
1483
+
1484
+	/**
1485
+	 * set_reg_status_buttons_metabox
1486
+	 *
1487
+	 * @return void
1488
+	 * @throws EE_Error
1489
+	 * @throws EntityNotFoundException
1490
+	 * @throws InvalidArgumentException
1491
+	 * @throws InvalidDataTypeException
1492
+	 * @throws InvalidInterfaceException
1493
+	 * @throws ReflectionException
1494
+	 */
1495
+	public function set_reg_status_buttons_metabox()
1496
+	{
1497
+		$this->_set_registration_object();
1498
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1499
+		$output                 = $change_reg_status_form->form_open(
1500
+			self::add_query_args_and_nonce(
1501
+				[
1502
+					'action' => 'change_reg_status',
1503
+				],
1504
+				REG_ADMIN_URL
1505
+			)
1506
+		);
1507
+		$output                 .= $change_reg_status_form->get_html();
1508
+		$output                 .= $change_reg_status_form->form_close();
1509
+		echo $output; // already escaped
1510
+	}
1511
+
1512
+
1513
+	/**
1514
+	 * @return EE_Form_Section_Proper
1515
+	 * @throws EE_Error
1516
+	 * @throws InvalidArgumentException
1517
+	 * @throws InvalidDataTypeException
1518
+	 * @throws InvalidInterfaceException
1519
+	 * @throws EntityNotFoundException
1520
+	 * @throws ReflectionException
1521
+	 */
1522
+	protected function _generate_reg_status_change_form()
1523
+	{
1524
+		$reg_status_change_form_array = [
1525
+			'name'            => 'reg_status_change_form',
1526
+			'html_id'         => 'reg-status-change-form',
1527
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1528
+			'subsections'     => [
1529
+				'return'         => new EE_Hidden_Input(
1530
+					[
1531
+						'name'    => 'return',
1532
+						'default' => 'view_registration',
1533
+					]
1534
+				),
1535
+				'REG_ID'         => new EE_Hidden_Input(
1536
+					[
1537
+						'name'    => 'REG_ID',
1538
+						'default' => $this->_registration->ID(),
1539
+					]
1540
+				),
1541
+				'current_status' => new EE_Form_Section_HTML(
1542
+					EEH_HTML::table(
1543
+						EEH_HTML::tr(
1544
+							EEH_HTML::th(
1545
+								EEH_HTML::label(
1546
+									EEH_HTML::strong(
1547
+										esc_html__('Current Registration Status', 'event_espresso')
1548
+									)
1549
+								)
1550
+							)
1551
+							. EEH_HTML::td(
1552
+								EEH_HTML::strong(
1553
+									$this->_registration->pretty_status(),
1554
+									'',
1555
+									'status-' . $this->_registration->status_ID(),
1556
+									'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1557
+								)
1558
+							)
1559
+						)
1560
+					)
1561
+				),
1562
+			],
1563
+		];
1564
+		if (
1565
+			EE_Registry::instance()->CAP->current_user_can(
1566
+				'ee_edit_registration',
1567
+				'toggle_registration_status',
1568
+				$this->_registration->ID()
1569
+			)
1570
+		) {
1571
+			$reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1572
+				$this->_get_reg_statuses(),
1573
+				[
1574
+					'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1575
+					'default'         => $this->_registration->status_ID(),
1576
+				]
1577
+			);
1578
+			$reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1579
+				[
1580
+					'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1581
+					'default'         => false,
1582
+					'html_help_text'  => esc_html__(
1583
+						'If set to "Yes", then the related messages will be sent to the registrant.',
1584
+						'event_espresso'
1585
+					),
1586
+				]
1587
+			);
1588
+			$reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1589
+				[
1590
+					'html_class'      => 'button--primary',
1591
+					'html_label_text' => '&nbsp;',
1592
+					'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1593
+				]
1594
+			);
1595
+		}
1596
+		return new EE_Form_Section_Proper($reg_status_change_form_array);
1597
+	}
1598
+
1599
+
1600
+	/**
1601
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1602
+	 *
1603
+	 * @return array
1604
+	 * @throws EE_Error
1605
+	 * @throws InvalidArgumentException
1606
+	 * @throws InvalidDataTypeException
1607
+	 * @throws InvalidInterfaceException
1608
+	 * @throws EntityNotFoundException
1609
+	 */
1610
+	protected function _get_reg_statuses()
1611
+	{
1612
+		$reg_status_array = $this->getRegistrationModel()->reg_status_array();
1613
+		unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1614
+		// get current reg status
1615
+		$current_status = $this->_registration->status_ID();
1616
+		// is registration for free event? This will determine whether to display the pending payment option
1617
+		if (
1618
+			$current_status !== EEM_Registration::status_id_pending_payment
1619
+			&& EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1620
+		) {
1621
+			unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1622
+		}
1623
+		return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1624
+	}
1625
+
1626
+
1627
+	/**
1628
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1629
+	 *
1630
+	 * @param bool $status REG status given for changing registrations to.
1631
+	 * @param bool $notify Whether to send messages notifications or not.
1632
+	 * @return array (array with reg_id(s) updated and whether update was successful.
1633
+	 * @throws DomainException
1634
+	 * @throws EE_Error
1635
+	 * @throws EntityNotFoundException
1636
+	 * @throws InvalidArgumentException
1637
+	 * @throws InvalidDataTypeException
1638
+	 * @throws InvalidInterfaceException
1639
+	 * @throws ReflectionException
1640
+	 * @throws RuntimeException
1641
+	 */
1642
+	protected function _set_registration_status_from_request($status = false, $notify = false)
1643
+	{
1644
+		$REG_IDs = $this->request->requestParamIsSet('reg_status_change_form')
1645
+			? $this->request->getRequestParam('reg_status_change_form[REG_ID]', [], 'int', true)
1646
+			: $this->request->getRequestParam('_REG_ID', [], 'int', true);
1647
+
1648
+		// sanitize $REG_IDs
1649
+		$REG_IDs = array_map('absint', $REG_IDs);
1650
+		// and remove empty entries
1651
+		$REG_IDs = array_filter($REG_IDs);
1652
+
1653
+		$result = $this->_set_registration_status($REG_IDs, $status, $notify);
1654
+
1655
+		/**
1656
+		 * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1657
+		 * Currently this value is used downstream by the _process_resend_registration method.
1658
+		 *
1659
+		 * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1660
+		 * @param bool                     $status           The status registrations were changed to.
1661
+		 * @param bool                     $success          If the status was changed successfully for all registrations.
1662
+		 * @param Registrations_Admin_Page $admin_page_object
1663
+		 */
1664
+		$REG_ID = apply_filters(
1665
+			'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1666
+			$result['REG_ID'],
1667
+			$status,
1668
+			$result['success'],
1669
+			$this
1670
+		);
1671
+		$this->request->setRequestParam('_REG_ID', $REG_ID);
1672
+
1673
+		// notify?
1674
+		if (
1675
+			$notify
1676
+			&& $result['success']
1677
+			&& ! empty($REG_ID)
1678
+			&& EE_Registry::instance()->CAP->current_user_can(
1679
+				'ee_send_message',
1680
+				'espresso_registrations_resend_registration'
1681
+			)
1682
+		) {
1683
+			$this->_process_resend_registration();
1684
+		}
1685
+		return $result;
1686
+	}
1687
+
1688
+
1689
+	/**
1690
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1691
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1692
+	 *
1693
+	 * @param array  $REG_IDs
1694
+	 * @param string $status
1695
+	 * @param bool   $notify Used to indicate whether notification was requested or not.  This determines the context
1696
+	 *                       slug sent with setting the registration status.
1697
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1698
+	 * @throws EE_Error
1699
+	 * @throws InvalidArgumentException
1700
+	 * @throws InvalidDataTypeException
1701
+	 * @throws InvalidInterfaceException
1702
+	 * @throws ReflectionException
1703
+	 * @throws RuntimeException
1704
+	 * @throws EntityNotFoundException
1705
+	 * @throws DomainException
1706
+	 */
1707
+	protected function _set_registration_status($REG_IDs = [], $status = '', $notify = false)
1708
+	{
1709
+		$success = false;
1710
+		// typecast $REG_IDs
1711
+		$REG_IDs = (array) $REG_IDs;
1712
+		if (! empty($REG_IDs)) {
1713
+			$success = true;
1714
+			// set default status if none is passed
1715
+			$status         = $status ?: EEM_Registration::status_id_pending_payment;
1716
+			$status_context = $notify
1717
+				? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1718
+				: Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1719
+			// loop through REG_ID's and change status
1720
+			foreach ($REG_IDs as $REG_ID) {
1721
+				$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1722
+				if ($registration instanceof EE_Registration) {
1723
+					$registration->set_status(
1724
+						$status,
1725
+						false,
1726
+						new Context(
1727
+							$status_context,
1728
+							esc_html__(
1729
+								'Manually triggered status change on a Registration Admin Page route.',
1730
+								'event_espresso'
1731
+							)
1732
+						)
1733
+					);
1734
+					$result = $registration->save();
1735
+					// verifying explicit fails because update *may* just return 0 for 0 rows affected
1736
+					$success = $result !== false ? $success : false;
1737
+				}
1738
+			}
1739
+		}
1740
+
1741
+		// return $success and processed registrations
1742
+		return ['REG_ID' => $REG_IDs, 'success' => $success];
1743
+	}
1744
+
1745
+
1746
+	/**
1747
+	 * Common logic for setting up success message and redirecting to appropriate route
1748
+	 *
1749
+	 * @param string $STS_ID status id for the registration changed to
1750
+	 * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1751
+	 * @return void
1752
+	 * @throws DomainException
1753
+	 * @throws EE_Error
1754
+	 * @throws EntityNotFoundException
1755
+	 * @throws InvalidArgumentException
1756
+	 * @throws InvalidDataTypeException
1757
+	 * @throws InvalidInterfaceException
1758
+	 * @throws ReflectionException
1759
+	 * @throws RuntimeException
1760
+	 */
1761
+	protected function _reg_status_change_return($STS_ID, $notify = false)
1762
+	{
1763
+		$result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1764
+			: ['success' => false];
1765
+		$success = isset($result['success']) && $result['success'];
1766
+		// setup success message
1767
+		if ($success) {
1768
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1769
+				$msg = sprintf(
1770
+					esc_html__('Registration status has been set to %s', 'event_espresso'),
1771
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1772
+				);
1773
+			} else {
1774
+				$msg = sprintf(
1775
+					esc_html__('Registrations have been set to %s.', 'event_espresso'),
1776
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1777
+				);
1778
+			}
1779
+			EE_Error::add_success($msg);
1780
+		} else {
1781
+			EE_Error::add_error(
1782
+				esc_html__(
1783
+					'Something went wrong, and the status was not changed',
1784
+					'event_espresso'
1785
+				),
1786
+				__FILE__,
1787
+				__LINE__,
1788
+				__FUNCTION__
1789
+			);
1790
+		}
1791
+		$return = $this->request->getRequestParam('return');
1792
+		$route  = $return === 'view_registration'
1793
+			? ['action' => 'view_registration', '_REG_ID' => reset($result['REG_ID'])]
1794
+			: ['action' => 'default'];
1795
+		$route  = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1796
+		$this->_redirect_after_action($success, '', '', $route, true);
1797
+	}
1798
+
1799
+
1800
+	/**
1801
+	 * incoming reg status change from reg details page.
1802
+	 *
1803
+	 * @return void
1804
+	 * @throws EE_Error
1805
+	 * @throws EntityNotFoundException
1806
+	 * @throws InvalidArgumentException
1807
+	 * @throws InvalidDataTypeException
1808
+	 * @throws InvalidInterfaceException
1809
+	 * @throws ReflectionException
1810
+	 * @throws RuntimeException
1811
+	 * @throws DomainException
1812
+	 */
1813
+	protected function _change_reg_status()
1814
+	{
1815
+		$this->request->setRequestParam('return', 'view_registration');
1816
+		// set notify based on whether the send notifications toggle is set or not
1817
+		$notify     = $this->request->getRequestParam('reg_status_change_form[send_notifications]', false, 'bool');
1818
+		$reg_status = $this->request->getRequestParam('reg_status_change_form[reg_status]', '');
1819
+		$this->request->setRequestParam('reg_status_change_form[reg_status]', $reg_status);
1820
+		switch ($reg_status) {
1821
+			case EEM_Registration::status_id_approved:
1822
+			case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1823
+				$this->approve_registration($notify);
1824
+				break;
1825
+			case EEM_Registration::status_id_pending_payment:
1826
+			case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1827
+				$this->pending_registration($notify);
1828
+				break;
1829
+			case EEM_Registration::status_id_not_approved:
1830
+			case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1831
+				$this->not_approve_registration($notify);
1832
+				break;
1833
+			case EEM_Registration::status_id_declined:
1834
+			case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1835
+				$this->decline_registration($notify);
1836
+				break;
1837
+			case EEM_Registration::status_id_cancelled:
1838
+			case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1839
+				$this->cancel_registration($notify);
1840
+				break;
1841
+			case EEM_Registration::status_id_wait_list:
1842
+			case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1843
+				$this->wait_list_registration($notify);
1844
+				break;
1845
+			case EEM_Registration::status_id_incomplete:
1846
+			default:
1847
+				$this->request->unSetRequestParam('return');
1848
+				$this->_reg_status_change_return('');
1849
+				break;
1850
+		}
1851
+	}
1852
+
1853
+
1854
+	/**
1855
+	 * Callback for bulk action routes.
1856
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1857
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
1858
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1859
+	 * when an action is happening on just a single registration).
1860
+	 *
1861
+	 * @param      $action
1862
+	 * @param bool $notify
1863
+	 */
1864
+	protected function bulk_action_on_registrations($action, $notify = false)
1865
+	{
1866
+		do_action(
1867
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1868
+			$this,
1869
+			$action,
1870
+			$notify
1871
+		);
1872
+		$method = $action . '_registration';
1873
+		if (method_exists($this, $method)) {
1874
+			$this->$method($notify);
1875
+		}
1876
+	}
1877
+
1878
+
1879
+	/**
1880
+	 * approve_registration
1881
+	 *
1882
+	 * @param bool $notify whether or not to notify the registrant about their approval.
1883
+	 * @return void
1884
+	 * @throws EE_Error
1885
+	 * @throws EntityNotFoundException
1886
+	 * @throws InvalidArgumentException
1887
+	 * @throws InvalidDataTypeException
1888
+	 * @throws InvalidInterfaceException
1889
+	 * @throws ReflectionException
1890
+	 * @throws RuntimeException
1891
+	 * @throws DomainException
1892
+	 */
1893
+	protected function approve_registration($notify = false)
1894
+	{
1895
+		$this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1896
+	}
1897
+
1898
+
1899
+	/**
1900
+	 * decline_registration
1901
+	 *
1902
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1903
+	 * @return void
1904
+	 * @throws EE_Error
1905
+	 * @throws EntityNotFoundException
1906
+	 * @throws InvalidArgumentException
1907
+	 * @throws InvalidDataTypeException
1908
+	 * @throws InvalidInterfaceException
1909
+	 * @throws ReflectionException
1910
+	 * @throws RuntimeException
1911
+	 * @throws DomainException
1912
+	 */
1913
+	protected function decline_registration($notify = false)
1914
+	{
1915
+		$this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1916
+	}
1917
+
1918
+
1919
+	/**
1920
+	 * cancel_registration
1921
+	 *
1922
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1923
+	 * @return void
1924
+	 * @throws EE_Error
1925
+	 * @throws EntityNotFoundException
1926
+	 * @throws InvalidArgumentException
1927
+	 * @throws InvalidDataTypeException
1928
+	 * @throws InvalidInterfaceException
1929
+	 * @throws ReflectionException
1930
+	 * @throws RuntimeException
1931
+	 * @throws DomainException
1932
+	 */
1933
+	protected function cancel_registration($notify = false)
1934
+	{
1935
+		$this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1936
+	}
1937
+
1938
+
1939
+	/**
1940
+	 * not_approve_registration
1941
+	 *
1942
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1943
+	 * @return void
1944
+	 * @throws EE_Error
1945
+	 * @throws EntityNotFoundException
1946
+	 * @throws InvalidArgumentException
1947
+	 * @throws InvalidDataTypeException
1948
+	 * @throws InvalidInterfaceException
1949
+	 * @throws ReflectionException
1950
+	 * @throws RuntimeException
1951
+	 * @throws DomainException
1952
+	 */
1953
+	protected function not_approve_registration($notify = false)
1954
+	{
1955
+		$this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1956
+	}
1957
+
1958
+
1959
+	/**
1960
+	 * decline_registration
1961
+	 *
1962
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1963
+	 * @return void
1964
+	 * @throws EE_Error
1965
+	 * @throws EntityNotFoundException
1966
+	 * @throws InvalidArgumentException
1967
+	 * @throws InvalidDataTypeException
1968
+	 * @throws InvalidInterfaceException
1969
+	 * @throws ReflectionException
1970
+	 * @throws RuntimeException
1971
+	 * @throws DomainException
1972
+	 */
1973
+	protected function pending_registration($notify = false)
1974
+	{
1975
+		$this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1976
+	}
1977
+
1978
+
1979
+	/**
1980
+	 * waitlist_registration
1981
+	 *
1982
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1983
+	 * @return void
1984
+	 * @throws EE_Error
1985
+	 * @throws EntityNotFoundException
1986
+	 * @throws InvalidArgumentException
1987
+	 * @throws InvalidDataTypeException
1988
+	 * @throws InvalidInterfaceException
1989
+	 * @throws ReflectionException
1990
+	 * @throws RuntimeException
1991
+	 * @throws DomainException
1992
+	 */
1993
+	protected function wait_list_registration($notify = false)
1994
+	{
1995
+		$this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1996
+	}
1997
+
1998
+
1999
+	/**
2000
+	 * generates HTML for the Registration main meta box
2001
+	 *
2002
+	 * @return void
2003
+	 * @throws DomainException
2004
+	 * @throws EE_Error
2005
+	 * @throws InvalidArgumentException
2006
+	 * @throws InvalidDataTypeException
2007
+	 * @throws InvalidInterfaceException
2008
+	 * @throws ReflectionException
2009
+	 * @throws EntityNotFoundException
2010
+	 */
2011
+	public function _reg_details_meta_box()
2012
+	{
2013
+		EEH_Autoloader::register_line_item_display_autoloaders();
2014
+		EEH_Autoloader::register_line_item_filter_autoloaders();
2015
+		EE_Registry::instance()->load_helper('Line_Item');
2016
+		$transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
2017
+			: EE_Transaction::new_instance();
2018
+		$this->_session = $transaction->session_data();
2019
+		$filters        = new EE_Line_Item_Filter_Collection();
2020
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2021
+		$filters->add(new EE_Non_Zero_Line_Item_Filter());
2022
+		$line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2023
+			$filters,
2024
+			$transaction->total_line_item()
2025
+		);
2026
+		$filtered_line_item_tree                 = $line_item_filter_processor->process();
2027
+		$line_item_display                       = new EE_Line_Item_Display(
2028
+			'reg_admin_table',
2029
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2030
+		);
2031
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2032
+			$filtered_line_item_tree,
2033
+			['EE_Registration' => $this->_registration]
2034
+		);
2035
+		$attendee                                = $this->_registration->attendee();
2036
+		if (
2037
+			EE_Registry::instance()->CAP->current_user_can(
2038
+				'ee_read_transaction',
2039
+				'espresso_transactions_view_transaction'
2040
+			)
2041
+		) {
2042
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2043
+				EE_Admin_Page::add_query_args_and_nonce(
2044
+					[
2045
+						'action' => 'view_transaction',
2046
+						'TXN_ID' => $transaction->ID(),
2047
+					],
2048
+					TXN_ADMIN_URL
2049
+				),
2050
+				esc_html__(' View Transaction', 'event_espresso'),
2051
+				'button button--secondary right',
2052
+				'dashicons dashicons-cart'
2053
+			);
2054
+		} else {
2055
+			$this->_template_args['view_transaction_button'] = '';
2056
+		}
2057
+		if (
2058
+			$attendee instanceof EE_Attendee
2059
+			&& EE_Registry::instance()->CAP->current_user_can(
2060
+				'ee_send_message',
2061
+				'espresso_registrations_resend_registration'
2062
+			)
2063
+		) {
2064
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2065
+				EE_Admin_Page::add_query_args_and_nonce(
2066
+					[
2067
+						'action'      => 'resend_registration',
2068
+						'_REG_ID'     => $this->_registration->ID(),
2069
+						'redirect_to' => 'view_registration',
2070
+					],
2071
+					REG_ADMIN_URL
2072
+				),
2073
+				esc_html__(' Resend Registration', 'event_espresso'),
2074
+				'button button--secondary right',
2075
+				'dashicons dashicons-email-alt'
2076
+			);
2077
+		} else {
2078
+			$this->_template_args['resend_registration_button'] = '';
2079
+		}
2080
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2081
+		$payment                               = $transaction->get_first_related('Payment');
2082
+		$payment                               = ! $payment instanceof EE_Payment
2083
+			? EE_Payment::new_instance()
2084
+			: $payment;
2085
+		$payment_method                        = $payment->get_first_related('Payment_Method');
2086
+		$payment_method                        = ! $payment_method instanceof EE_Payment_Method
2087
+			? EE_Payment_Method::new_instance()
2088
+			: $payment_method;
2089
+		$reg_details                           = [
2090
+			'payment_method'       => $payment_method->name(),
2091
+			'response_msg'         => $payment->gateway_response(),
2092
+			'registration_id'      => $this->_registration->get('REG_code'),
2093
+			'registration_session' => $this->_registration->session_ID(),
2094
+			'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2095
+			'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2096
+		];
2097
+		if (isset($reg_details['registration_id'])) {
2098
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2099
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2100
+				'Registration ID',
2101
+				'event_espresso'
2102
+			);
2103
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2104
+		}
2105
+		if (isset($reg_details['payment_method'])) {
2106
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2107
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2108
+				'Most Recent Payment Method',
2109
+				'event_espresso'
2110
+			);
2111
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2112
+			$this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2113
+			$this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2114
+				'Payment method response',
2115
+				'event_espresso'
2116
+			);
2117
+			$this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2118
+		}
2119
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2120
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2121
+			'Registration Session',
2122
+			'event_espresso'
2123
+		);
2124
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2125
+		$this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2126
+		$this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2127
+			'Registration placed from IP',
2128
+			'event_espresso'
2129
+		);
2130
+		$this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2131
+		$this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2132
+		$this->_template_args['reg_details']['user_agent']['label']           = esc_html__(
2133
+			'Registrant User Agent',
2134
+			'event_espresso'
2135
+		);
2136
+		$this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2137
+		$this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2138
+			[
2139
+				'action'   => 'default',
2140
+				'event_id' => $this->_registration->event_ID(),
2141
+			],
2142
+			REG_ADMIN_URL
2143
+		);
2144
+
2145
+		$this->_template_args['REG_ID'] = $this->_registration->ID();
2146
+		$this->_template_args['event_id'] = $this->_registration->event_ID();
2147
+
2148
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2149
+		EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2150
+	}
2151
+
2152
+
2153
+	/**
2154
+	 * generates HTML for the Registration Questions meta box.
2155
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2156
+	 * otherwise uses new forms system
2157
+	 *
2158
+	 * @return void
2159
+	 * @throws DomainException
2160
+	 * @throws EE_Error
2161
+	 * @throws InvalidArgumentException
2162
+	 * @throws InvalidDataTypeException
2163
+	 * @throws InvalidInterfaceException
2164
+	 * @throws ReflectionException
2165
+	 */
2166
+	public function _reg_questions_meta_box()
2167
+	{
2168
+		// allow someone to override this method entirely
2169
+		if (
2170
+			apply_filters(
2171
+				'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2172
+				true,
2173
+				$this,
2174
+				$this->_registration
2175
+			)
2176
+		) {
2177
+			$form = $this->_get_reg_custom_questions_form(
2178
+				$this->_registration->ID()
2179
+			);
2180
+
2181
+			$this->_template_args['att_questions'] = count($form->subforms()) > 0
2182
+				? $form->get_html_and_js()
2183
+				: '';
2184
+
2185
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2186
+			$this->_template_args['REG_ID'] = $this->_registration->ID();
2187
+			$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2188
+			EEH_Template::display_template($template_path, $this->_template_args);
2189
+		}
2190
+	}
2191
+
2192
+
2193
+	/**
2194
+	 * form_before_question_group
2195
+	 *
2196
+	 * @param string $output
2197
+	 * @return        string
2198
+	 * @deprecated    as of 4.8.32.rc.000
2199
+	 */
2200
+	public function form_before_question_group($output)
2201
+	{
2202
+		EE_Error::doing_it_wrong(
2203
+			__CLASS__ . '::' . __FUNCTION__,
2204
+			esc_html__(
2205
+				'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.',
2206
+				'event_espresso'
2207
+			),
2208
+			'4.8.32.rc.000'
2209
+		);
2210
+		return '
2211 2211
 	<table class="form-table ee-width-100">
2212 2212
 		<tbody>
2213 2213
 			';
2214
-    }
2215
-
2216
-
2217
-    /**
2218
-     * form_after_question_group
2219
-     *
2220
-     * @param string $output
2221
-     * @return        string
2222
-     * @deprecated    as of 4.8.32.rc.000
2223
-     */
2224
-    public function form_after_question_group($output)
2225
-    {
2226
-        EE_Error::doing_it_wrong(
2227
-            __CLASS__ . '::' . __FUNCTION__,
2228
-            esc_html__(
2229
-                '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.',
2230
-                'event_espresso'
2231
-            ),
2232
-            '4.8.32.rc.000'
2233
-        );
2234
-        return '
2214
+	}
2215
+
2216
+
2217
+	/**
2218
+	 * form_after_question_group
2219
+	 *
2220
+	 * @param string $output
2221
+	 * @return        string
2222
+	 * @deprecated    as of 4.8.32.rc.000
2223
+	 */
2224
+	public function form_after_question_group($output)
2225
+	{
2226
+		EE_Error::doing_it_wrong(
2227
+			__CLASS__ . '::' . __FUNCTION__,
2228
+			esc_html__(
2229
+				'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.',
2230
+				'event_espresso'
2231
+			),
2232
+			'4.8.32.rc.000'
2233
+		);
2234
+		return '
2235 2235
 			<tr class="hide-if-no-js">
2236 2236
 				<th> </th>
2237 2237
 				<td class="reg-admin-edit-attendee-question-td">
2238 2238
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" title="'
2239
-               . esc_attr__('click to edit question', 'event_espresso')
2240
-               . '">
2239
+			   . esc_attr__('click to edit question', 'event_espresso')
2240
+			   . '">
2241 2241
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2242
-               . esc_html__('edit the above question group', 'event_espresso')
2243
-               . '</span>
2242
+			   . esc_html__('edit the above question group', 'event_espresso')
2243
+			   . '</span>
2244 2244
 						<div class="dashicons dashicons-edit"></div>
2245 2245
 					</a>
2246 2246
 				</td>
@@ -2248,636 +2248,636 @@  discard block
 block discarded – undo
2248 2248
 		</tbody>
2249 2249
 	</table>
2250 2250
 ';
2251
-    }
2252
-
2253
-
2254
-    /**
2255
-     * form_form_field_label_wrap
2256
-     *
2257
-     * @param string $label
2258
-     * @return        string
2259
-     * @deprecated    as of 4.8.32.rc.000
2260
-     */
2261
-    public function form_form_field_label_wrap($label)
2262
-    {
2263
-        EE_Error::doing_it_wrong(
2264
-            __CLASS__ . '::' . __FUNCTION__,
2265
-            esc_html__(
2266
-                '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.',
2267
-                'event_espresso'
2268
-            ),
2269
-            '4.8.32.rc.000'
2270
-        );
2271
-        return '
2251
+	}
2252
+
2253
+
2254
+	/**
2255
+	 * form_form_field_label_wrap
2256
+	 *
2257
+	 * @param string $label
2258
+	 * @return        string
2259
+	 * @deprecated    as of 4.8.32.rc.000
2260
+	 */
2261
+	public function form_form_field_label_wrap($label)
2262
+	{
2263
+		EE_Error::doing_it_wrong(
2264
+			__CLASS__ . '::' . __FUNCTION__,
2265
+			esc_html__(
2266
+				'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.',
2267
+				'event_espresso'
2268
+			),
2269
+			'4.8.32.rc.000'
2270
+		);
2271
+		return '
2272 2272
 			<tr>
2273 2273
 				<th>
2274 2274
 					' . $label . '
2275 2275
 				</th>';
2276
-    }
2277
-
2278
-
2279
-    /**
2280
-     * form_form_field_input__wrap
2281
-     *
2282
-     * @param string $input
2283
-     * @return        string
2284
-     * @deprecated    as of 4.8.32.rc.000
2285
-     */
2286
-    public function form_form_field_input__wrap($input)
2287
-    {
2288
-        EE_Error::doing_it_wrong(
2289
-            __CLASS__ . '::' . __FUNCTION__,
2290
-            esc_html__(
2291
-                '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.',
2292
-                'event_espresso'
2293
-            ),
2294
-            '4.8.32.rc.000'
2295
-        );
2296
-        return '
2276
+	}
2277
+
2278
+
2279
+	/**
2280
+	 * form_form_field_input__wrap
2281
+	 *
2282
+	 * @param string $input
2283
+	 * @return        string
2284
+	 * @deprecated    as of 4.8.32.rc.000
2285
+	 */
2286
+	public function form_form_field_input__wrap($input)
2287
+	{
2288
+		EE_Error::doing_it_wrong(
2289
+			__CLASS__ . '::' . __FUNCTION__,
2290
+			esc_html__(
2291
+				'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.',
2292
+				'event_espresso'
2293
+			),
2294
+			'4.8.32.rc.000'
2295
+		);
2296
+		return '
2297 2297
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2298 2298
 					' . $input . '
2299 2299
 				</td>
2300 2300
 			</tr>';
2301
-    }
2302
-
2303
-
2304
-    /**
2305
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2306
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2307
-     * to display the page
2308
-     *
2309
-     * @return void
2310
-     * @throws EE_Error
2311
-     * @throws InvalidArgumentException
2312
-     * @throws InvalidDataTypeException
2313
-     * @throws InvalidInterfaceException
2314
-     * @throws ReflectionException
2315
-     */
2316
-    protected function _update_attendee_registration_form()
2317
-    {
2318
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2319
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2320
-            $REG_ID  = $this->request->getRequestParam('_REG_ID', 0, 'int');
2321
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2322
-            if ($success) {
2323
-                $what  = esc_html__('Registration Form', 'event_espresso');
2324
-                $route = $REG_ID
2325
-                    ? ['action' => 'view_registration', '_REG_ID' => $REG_ID]
2326
-                    : ['action' => 'default'];
2327
-                $this->_redirect_after_action(true, $what, esc_html__('updated', 'event_espresso'), $route);
2328
-            }
2329
-        }
2330
-    }
2331
-
2332
-
2333
-    /**
2334
-     * Gets the form for saving registrations custom questions (if done
2335
-     * previously retrieves the cached form object, which may have validation errors in it)
2336
-     *
2337
-     * @param int $REG_ID
2338
-     * @return EE_Registration_Custom_Questions_Form
2339
-     * @throws EE_Error
2340
-     * @throws InvalidArgumentException
2341
-     * @throws InvalidDataTypeException
2342
-     * @throws InvalidInterfaceException
2343
-     * @throws ReflectionException
2344
-     */
2345
-    protected function _get_reg_custom_questions_form($REG_ID)
2346
-    {
2347
-        if (! $this->_reg_custom_questions_form) {
2348
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2349
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2350
-                $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2351
-            );
2352
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2353
-        }
2354
-        return $this->_reg_custom_questions_form;
2355
-    }
2356
-
2357
-
2358
-    /**
2359
-     * Saves
2360
-     *
2361
-     * @param bool $REG_ID
2362
-     * @return bool
2363
-     * @throws EE_Error
2364
-     * @throws InvalidArgumentException
2365
-     * @throws InvalidDataTypeException
2366
-     * @throws InvalidInterfaceException
2367
-     * @throws ReflectionException
2368
-     */
2369
-    private function _save_reg_custom_questions_form($REG_ID = 0)
2370
-    {
2371
-        if (! $REG_ID) {
2372
-            EE_Error::add_error(
2373
-                esc_html__(
2374
-                    'An error occurred. No registration ID was received.',
2375
-                    'event_espresso'
2376
-                ),
2377
-                __FILE__,
2378
-                __FUNCTION__,
2379
-                __LINE__
2380
-            );
2381
-        }
2382
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2383
-        $form->receive_form_submission($this->request->requestParams());
2384
-        $success = false;
2385
-        if ($form->is_valid()) {
2386
-            foreach ($form->subforms() as $question_group_form) {
2387
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2388
-                    $where_conditions    = [
2389
-                        'QST_ID' => $question_id,
2390
-                        'REG_ID' => $REG_ID,
2391
-                    ];
2392
-                    $possibly_new_values = [
2393
-                        'ANS_value' => $input->normalized_value(),
2394
-                    ];
2395
-                    $answer              = EEM_Answer::instance()->get_one([$where_conditions]);
2396
-                    if ($answer instanceof EE_Answer) {
2397
-                        $success = $answer->save($possibly_new_values);
2398
-                    } else {
2399
-                        // insert it then
2400
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2401
-                        $answer      = EE_Answer::new_instance($cols_n_vals);
2402
-                        $success     = $answer->save();
2403
-                    }
2404
-                }
2405
-            }
2406
-        } else {
2407
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2408
-        }
2409
-        return $success;
2410
-    }
2411
-
2412
-
2413
-    /**
2414
-     * generates HTML for the Registration main meta box
2415
-     *
2416
-     * @return void
2417
-     * @throws DomainException
2418
-     * @throws EE_Error
2419
-     * @throws InvalidArgumentException
2420
-     * @throws InvalidDataTypeException
2421
-     * @throws InvalidInterfaceException
2422
-     * @throws ReflectionException
2423
-     */
2424
-    public function _reg_attendees_meta_box()
2425
-    {
2426
-        $REG = $this->getRegistrationModel();
2427
-        // get all other registrations on this transaction, and cache
2428
-        // the attendees for them so we don't have to run another query using force_join
2429
-        $registrations                           = $REG->get_all(
2430
-            [
2431
-                [
2432
-                    'TXN_ID' => $this->_registration->transaction_ID(),
2433
-                    'REG_ID' => ['!=', $this->_registration->ID()],
2434
-                ],
2435
-                'force_join'               => ['Attendee'],
2436
-                'default_where_conditions' => 'other_models_only',
2437
-            ]
2438
-        );
2439
-        $this->_template_args['attendees']       = [];
2440
-        $this->_template_args['attendee_notice'] = '';
2441
-        if (
2442
-            empty($registrations)
2443
-            || (is_array($registrations)
2444
-                && ! EEH_Array::get_one_item_from_array($registrations))
2445
-        ) {
2446
-            EE_Error::add_error(
2447
-                esc_html__(
2448
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2449
-                    'event_espresso'
2450
-                ),
2451
-                __FILE__,
2452
-                __FUNCTION__,
2453
-                __LINE__
2454
-            );
2455
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2456
-        } else {
2457
-            $att_nmbr = 1;
2458
-            foreach ($registrations as $registration) {
2459
-                /* @var $registration EE_Registration */
2460
-                $attendee                                                      = $registration->attendee()
2461
-                    ? $registration->attendee()
2462
-                    : $this->getAttendeeModel()->create_default_object();
2463
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2464
-                $this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2465
-                $this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2466
-                $this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2467
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2468
-                $this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2469
-                    ', ',
2470
-                    $attendee->full_address_as_array()
2471
-                );
2472
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2473
-                    [
2474
-                        'action' => 'edit_attendee',
2475
-                        'post'   => $attendee->ID(),
2476
-                    ],
2477
-                    REG_ADMIN_URL
2478
-                );
2479
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2480
-                    $registration->event_obj() instanceof EE_Event
2481
-                        ? $registration->event_obj()->name()
2482
-                        : '';
2483
-                $att_nmbr++;
2484
-            }
2485
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2486
-        }
2487
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2488
-        EEH_Template::display_template($template_path, $this->_template_args);
2489
-    }
2490
-
2491
-
2492
-    /**
2493
-     * generates HTML for the Edit Registration side meta box
2494
-     *
2495
-     * @return void
2496
-     * @throws DomainException
2497
-     * @throws EE_Error
2498
-     * @throws InvalidArgumentException
2499
-     * @throws InvalidDataTypeException
2500
-     * @throws InvalidInterfaceException
2501
-     * @throws ReflectionException
2502
-     */
2503
-    public function _reg_registrant_side_meta_box()
2504
-    {
2505
-        /*@var $attendee EE_Attendee */
2506
-        $att_check = $this->_registration->attendee();
2507
-        $attendee  = $att_check instanceof EE_Attendee
2508
-            ? $att_check
2509
-            : $this->getAttendeeModel()->create_default_object();
2510
-        // now let's determine if this is not the primary registration.  If it isn't then we set the
2511
-        // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2512
-        // primary registration object (that way we know if we need to show create button or not)
2513
-        if (! $this->_registration->is_primary_registrant()) {
2514
-            $primary_registration = $this->_registration->get_primary_registration();
2515
-            $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2516
-                : null;
2517
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2518
-                // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2519
-                // custom attendee object so let's not worry about the primary reg.
2520
-                $primary_registration = null;
2521
-            }
2522
-        } else {
2523
-            $primary_registration = null;
2524
-        }
2525
-        $this->_template_args['ATT_ID']            = $attendee->ID();
2526
-        $this->_template_args['fname']             = $attendee->fname();
2527
-        $this->_template_args['lname']             = $attendee->lname();
2528
-        $this->_template_args['email']             = $attendee->email();
2529
-        $this->_template_args['phone']             = $attendee->phone();
2530
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2531
-        // edit link
2532
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2533
-            [
2534
-                'action' => 'edit_attendee',
2535
-                'post'   => $attendee->ID(),
2536
-            ],
2537
-            REG_ADMIN_URL
2538
-        );
2539
-        $this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2540
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2541
-        // create link
2542
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2543
-            ? EE_Admin_Page::add_query_args_and_nonce(
2544
-                [
2545
-                    'action'  => 'duplicate_attendee',
2546
-                    '_REG_ID' => $this->_registration->ID(),
2547
-                ],
2548
-                REG_ADMIN_URL
2549
-            ) : '';
2550
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2551
-        $this->_template_args['att_check'] = $att_check;
2552
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2553
-        EEH_Template::display_template($template_path, $this->_template_args);
2554
-    }
2555
-
2556
-
2557
-    /**
2558
-     * trash or restore registrations
2559
-     *
2560
-     * @param boolean $trash whether to archive or restore
2561
-     * @return void
2562
-     * @throws EE_Error
2563
-     * @throws InvalidArgumentException
2564
-     * @throws InvalidDataTypeException
2565
-     * @throws InvalidInterfaceException
2566
-     * @throws RuntimeException
2567
-     */
2568
-    protected function _trash_or_restore_registrations($trash = true)
2569
-    {
2570
-        // if empty _REG_ID then get out because there's nothing to do
2571
-        $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2572
-        if (empty($REG_IDs)) {
2573
-            EE_Error::add_error(
2574
-                sprintf(
2575
-                    esc_html__(
2576
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2577
-                        'event_espresso'
2578
-                    ),
2579
-                    $trash ? 'trash' : 'restore'
2580
-                ),
2581
-                __FILE__,
2582
-                __LINE__,
2583
-                __FUNCTION__
2584
-            );
2585
-            $this->_redirect_after_action(false, '', '', [], true);
2586
-        }
2587
-        $success        = 0;
2588
-        $overwrite_msgs = false;
2589
-        // Checkboxes
2590
-        $reg_count = count($REG_IDs);
2591
-        // cycle thru checkboxes
2592
-        foreach ($REG_IDs as $REG_ID) {
2593
-            /** @var EE_Registration $REG */
2594
-            $REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2595
-            $payments = $REG->registration_payments();
2596
-            if (! empty($payments)) {
2597
-                $name           = $REG->attendee() instanceof EE_Attendee
2598
-                    ? $REG->attendee()->full_name()
2599
-                    : esc_html__('Unknown Attendee', 'event_espresso');
2600
-                $overwrite_msgs = true;
2601
-                EE_Error::add_error(
2602
-                    sprintf(
2603
-                        esc_html__(
2604
-                            '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.',
2605
-                            'event_espresso'
2606
-                        ),
2607
-                        $name
2608
-                    ),
2609
-                    __FILE__,
2610
-                    __FUNCTION__,
2611
-                    __LINE__
2612
-                );
2613
-                // can't trash this registration because it has payments.
2614
-                continue;
2615
-            }
2616
-            $updated = $trash ? $REG->delete() : $REG->restore();
2617
-            if ($updated) {
2618
-                $success++;
2619
-            }
2620
-        }
2621
-        $this->_redirect_after_action(
2622
-            $success === $reg_count, // were ALL registrations affected?
2623
-            $success > 1
2624
-                ? esc_html__('Registrations', 'event_espresso')
2625
-                : esc_html__('Registration', 'event_espresso'),
2626
-            $trash
2627
-                ? esc_html__('moved to the trash', 'event_espresso')
2628
-                : esc_html__('restored', 'event_espresso'),
2629
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2630
-            $overwrite_msgs
2631
-        );
2632
-    }
2633
-
2634
-
2635
-    /**
2636
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2637
-     * registration but also.
2638
-     * 1. Removing relations to EE_Attendee
2639
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2640
-     * ALSO trashed.
2641
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2642
-     * 4. Removing relationships between all tickets and the related registrations
2643
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2644
-     * 6. Deleting permanently any related Checkins.
2645
-     *
2646
-     * @return void
2647
-     * @throws EE_Error
2648
-     * @throws InvalidArgumentException
2649
-     * @throws InvalidDataTypeException
2650
-     * @throws InvalidInterfaceException
2651
-     * @throws ReflectionException
2652
-     */
2653
-    protected function _delete_registrations()
2654
-    {
2655
-        $REG_MDL = $this->getRegistrationModel();
2656
-        $success = 0;
2657
-        // Checkboxes
2658
-        $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2659
-
2660
-        if (! empty($REG_IDs)) {
2661
-            // if array has more than one element than success message should be plural
2662
-            $success = count($REG_IDs) > 1 ? 2 : 1;
2663
-            // cycle thru checkboxes
2664
-            foreach ($REG_IDs as $REG_ID) {
2665
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2666
-                if (! $REG instanceof EE_Registration) {
2667
-                    continue;
2668
-                }
2669
-                $deleted = $this->_delete_registration($REG);
2670
-                if (! $deleted) {
2671
-                    $success = 0;
2672
-                }
2673
-            }
2674
-        }
2675
-
2676
-        $what        = $success > 1
2677
-            ? esc_html__('Registrations', 'event_espresso')
2678
-            : esc_html__('Registration', 'event_espresso');
2679
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2680
-        $this->_redirect_after_action(
2681
-            $success,
2682
-            $what,
2683
-            $action_desc,
2684
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2685
-            true
2686
-        );
2687
-    }
2688
-
2689
-
2690
-    /**
2691
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2692
-     * models get affected.
2693
-     *
2694
-     * @param EE_Registration $REG registration to be deleted permanently
2695
-     * @return bool true = successful deletion, false = fail.
2696
-     * @throws EE_Error
2697
-     * @throws InvalidArgumentException
2698
-     * @throws InvalidDataTypeException
2699
-     * @throws InvalidInterfaceException
2700
-     * @throws ReflectionException
2701
-     */
2702
-    protected function _delete_registration(EE_Registration $REG)
2703
-    {
2704
-        // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2705
-        // registrations on the transaction that are NOT trashed.
2706
-        $TXN = $REG->get_first_related('Transaction');
2707
-        if (! $TXN instanceof EE_Transaction) {
2708
-            EE_Error::add_error(
2709
-                sprintf(
2710
-                    esc_html__(
2711
-                        'Unable to permanently delete registration %d because its related transaction has already been deleted. If you can restore the related transaction to the database then this registration can be deleted.',
2712
-                        'event_espresso'
2713
-                    ),
2714
-                    $REG->id()
2715
-                ),
2716
-                __FILE__,
2717
-                __FUNCTION__,
2718
-                __LINE__
2719
-            );
2720
-            return false;
2721
-        }
2722
-        $REGS        = $TXN->get_many_related('Registration');
2723
-        $all_trashed = true;
2724
-        foreach ($REGS as $registration) {
2725
-            if (! $registration->get('REG_deleted')) {
2726
-                $all_trashed = false;
2727
-            }
2728
-        }
2729
-        if (! $all_trashed) {
2730
-            EE_Error::add_error(
2731
-                esc_html__(
2732
-                    '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.',
2733
-                    'event_espresso'
2734
-                ),
2735
-                __FILE__,
2736
-                __FUNCTION__,
2737
-                __LINE__
2738
-            );
2739
-            return false;
2740
-        }
2741
-        // k made it here so that means we can delete all the related transactions and their answers (but let's do them
2742
-        // separately from THIS one).
2743
-        foreach ($REGS as $registration) {
2744
-            // delete related answers
2745
-            $registration->delete_related_permanently('Answer');
2746
-            // remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2747
-            $attendee = $registration->get_first_related('Attendee');
2748
-            if ($attendee instanceof EE_Attendee) {
2749
-                $registration->_remove_relation_to($attendee, 'Attendee');
2750
-            }
2751
-            // now remove relationships to tickets on this registration.
2752
-            $registration->_remove_relations('Ticket');
2753
-            // now delete permanently the checkins related to this registration.
2754
-            $registration->delete_related_permanently('Checkin');
2755
-            if ($registration->ID() === $REG->ID()) {
2756
-                continue;
2757
-            } //we don't want to delete permanently the existing registration just yet.
2758
-            // remove relation to transaction for these registrations if NOT the existing registrations
2759
-            $registration->_remove_relations('Transaction');
2760
-            // delete permanently any related messages.
2761
-            $registration->delete_related_permanently('Message');
2762
-            // now delete this registration permanently
2763
-            $registration->delete_permanently();
2764
-        }
2765
-        // now all related registrations on the transaction are handled.  So let's just handle this registration itself
2766
-        // (the transaction and line items should be all that's left).
2767
-        // delete the line items related to the transaction for this registration.
2768
-        $TXN->delete_related_permanently('Line_Item');
2769
-        // we need to remove all the relationships on the transaction
2770
-        $TXN->delete_related_permanently('Payment');
2771
-        $TXN->delete_related_permanently('Extra_Meta');
2772
-        $TXN->delete_related_permanently('Message');
2773
-        // now we can delete this REG permanently (and the transaction of course)
2774
-        $REG->delete_related_permanently('Transaction');
2775
-        return $REG->delete_permanently();
2776
-    }
2777
-
2778
-
2779
-    /**
2780
-     *    generates HTML for the Register New Attendee Admin page
2781
-     *
2782
-     * @throws DomainException
2783
-     * @throws EE_Error
2784
-     * @throws InvalidArgumentException
2785
-     * @throws InvalidDataTypeException
2786
-     * @throws InvalidInterfaceException
2787
-     * @throws ReflectionException
2788
-     */
2789
-    public function new_registration()
2790
-    {
2791
-        if (! $this->_set_reg_event()) {
2792
-            throw new EE_Error(
2793
-                esc_html__(
2794
-                    'Unable to continue with registering because there is no Event ID in the request',
2795
-                    'event_espresso'
2796
-                )
2797
-            );
2798
-        }
2799
-        /** @var CurrentPage $current_page */
2800
-        $current_page = $this->loader->getShared(CurrentPage::class);
2801
-        $current_page->setEspressoPage(true);
2802
-        // gotta start with a clean slate if we're not coming here via ajax
2803
-        if (
2804
-            ! $this->request->isAjax()
2805
-            && (
2806
-                ! $this->request->requestParamIsSet('processing_registration')
2807
-                || $this->request->requestParamIsSet('step_error')
2808
-            )
2809
-        ) {
2810
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2811
-        }
2812
-        $this->_template_args['event_name'] = '';
2813
-        // event name
2814
-        if ($this->_reg_event) {
2815
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2816
-            $edit_event_url                     = self::add_query_args_and_nonce(
2817
-                [
2818
-                    'action' => 'edit',
2819
-                    'post'   => $this->_reg_event->ID(),
2820
-                ],
2821
-                EVENTS_ADMIN_URL
2822
-            );
2823
-            $edit_event_lnk                     = '<a href="'
2824
-                                                  . $edit_event_url
2825
-                                                  . '" title="'
2826
-                                                  . esc_attr__('Edit ', 'event_espresso')
2827
-                                                  . $this->_reg_event->name()
2828
-                                                  . '">'
2829
-                                                  . esc_html__('Edit Event', 'event_espresso')
2830
-                                                  . '</a>';
2831
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2832
-                                                   . $edit_event_lnk
2833
-                                                   . '</span>';
2834
-        }
2835
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2836
-        if ($this->request->isAjax()) {
2837
-            $this->_return_json();
2838
-        }
2839
-        // grab header
2840
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2841
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2842
-            $template_path,
2843
-            $this->_template_args,
2844
-            true
2845
-        );
2846
-        // $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2847
-        // the details template wrapper
2848
-        $this->display_admin_page_with_sidebar();
2849
-    }
2850
-
2851
-
2852
-    /**
2853
-     * This returns the content for a registration step
2854
-     *
2855
-     * @return string html
2856
-     * @throws DomainException
2857
-     * @throws EE_Error
2858
-     * @throws InvalidArgumentException
2859
-     * @throws InvalidDataTypeException
2860
-     * @throws InvalidInterfaceException
2861
-     * @throws ReflectionException
2862
-     */
2863
-    protected function _get_registration_step_content()
2864
-    {
2865
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2866
-            $warning_msg = sprintf(
2867
-                esc_html__(
2868
-                    '%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',
2869
-                    'event_espresso'
2870
-                ),
2871
-                '<br />',
2872
-                '<h3 class="important-notice">',
2873
-                '</h3>',
2874
-                '<div class="float-right">',
2875
-                '<span id="redirect_timer" class="important-notice">30</span>',
2876
-                '</div>',
2877
-                '<b>',
2878
-                '</b>'
2879
-            );
2880
-            return '
2301
+	}
2302
+
2303
+
2304
+	/**
2305
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2306
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2307
+	 * to display the page
2308
+	 *
2309
+	 * @return void
2310
+	 * @throws EE_Error
2311
+	 * @throws InvalidArgumentException
2312
+	 * @throws InvalidDataTypeException
2313
+	 * @throws InvalidInterfaceException
2314
+	 * @throws ReflectionException
2315
+	 */
2316
+	protected function _update_attendee_registration_form()
2317
+	{
2318
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2319
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2320
+			$REG_ID  = $this->request->getRequestParam('_REG_ID', 0, 'int');
2321
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2322
+			if ($success) {
2323
+				$what  = esc_html__('Registration Form', 'event_espresso');
2324
+				$route = $REG_ID
2325
+					? ['action' => 'view_registration', '_REG_ID' => $REG_ID]
2326
+					: ['action' => 'default'];
2327
+				$this->_redirect_after_action(true, $what, esc_html__('updated', 'event_espresso'), $route);
2328
+			}
2329
+		}
2330
+	}
2331
+
2332
+
2333
+	/**
2334
+	 * Gets the form for saving registrations custom questions (if done
2335
+	 * previously retrieves the cached form object, which may have validation errors in it)
2336
+	 *
2337
+	 * @param int $REG_ID
2338
+	 * @return EE_Registration_Custom_Questions_Form
2339
+	 * @throws EE_Error
2340
+	 * @throws InvalidArgumentException
2341
+	 * @throws InvalidDataTypeException
2342
+	 * @throws InvalidInterfaceException
2343
+	 * @throws ReflectionException
2344
+	 */
2345
+	protected function _get_reg_custom_questions_form($REG_ID)
2346
+	{
2347
+		if (! $this->_reg_custom_questions_form) {
2348
+			require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2349
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2350
+				$this->getRegistrationModel()->get_one_by_ID($REG_ID)
2351
+			);
2352
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2353
+		}
2354
+		return $this->_reg_custom_questions_form;
2355
+	}
2356
+
2357
+
2358
+	/**
2359
+	 * Saves
2360
+	 *
2361
+	 * @param bool $REG_ID
2362
+	 * @return bool
2363
+	 * @throws EE_Error
2364
+	 * @throws InvalidArgumentException
2365
+	 * @throws InvalidDataTypeException
2366
+	 * @throws InvalidInterfaceException
2367
+	 * @throws ReflectionException
2368
+	 */
2369
+	private function _save_reg_custom_questions_form($REG_ID = 0)
2370
+	{
2371
+		if (! $REG_ID) {
2372
+			EE_Error::add_error(
2373
+				esc_html__(
2374
+					'An error occurred. No registration ID was received.',
2375
+					'event_espresso'
2376
+				),
2377
+				__FILE__,
2378
+				__FUNCTION__,
2379
+				__LINE__
2380
+			);
2381
+		}
2382
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2383
+		$form->receive_form_submission($this->request->requestParams());
2384
+		$success = false;
2385
+		if ($form->is_valid()) {
2386
+			foreach ($form->subforms() as $question_group_form) {
2387
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2388
+					$where_conditions    = [
2389
+						'QST_ID' => $question_id,
2390
+						'REG_ID' => $REG_ID,
2391
+					];
2392
+					$possibly_new_values = [
2393
+						'ANS_value' => $input->normalized_value(),
2394
+					];
2395
+					$answer              = EEM_Answer::instance()->get_one([$where_conditions]);
2396
+					if ($answer instanceof EE_Answer) {
2397
+						$success = $answer->save($possibly_new_values);
2398
+					} else {
2399
+						// insert it then
2400
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2401
+						$answer      = EE_Answer::new_instance($cols_n_vals);
2402
+						$success     = $answer->save();
2403
+					}
2404
+				}
2405
+			}
2406
+		} else {
2407
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2408
+		}
2409
+		return $success;
2410
+	}
2411
+
2412
+
2413
+	/**
2414
+	 * generates HTML for the Registration main meta box
2415
+	 *
2416
+	 * @return void
2417
+	 * @throws DomainException
2418
+	 * @throws EE_Error
2419
+	 * @throws InvalidArgumentException
2420
+	 * @throws InvalidDataTypeException
2421
+	 * @throws InvalidInterfaceException
2422
+	 * @throws ReflectionException
2423
+	 */
2424
+	public function _reg_attendees_meta_box()
2425
+	{
2426
+		$REG = $this->getRegistrationModel();
2427
+		// get all other registrations on this transaction, and cache
2428
+		// the attendees for them so we don't have to run another query using force_join
2429
+		$registrations                           = $REG->get_all(
2430
+			[
2431
+				[
2432
+					'TXN_ID' => $this->_registration->transaction_ID(),
2433
+					'REG_ID' => ['!=', $this->_registration->ID()],
2434
+				],
2435
+				'force_join'               => ['Attendee'],
2436
+				'default_where_conditions' => 'other_models_only',
2437
+			]
2438
+		);
2439
+		$this->_template_args['attendees']       = [];
2440
+		$this->_template_args['attendee_notice'] = '';
2441
+		if (
2442
+			empty($registrations)
2443
+			|| (is_array($registrations)
2444
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2445
+		) {
2446
+			EE_Error::add_error(
2447
+				esc_html__(
2448
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2449
+					'event_espresso'
2450
+				),
2451
+				__FILE__,
2452
+				__FUNCTION__,
2453
+				__LINE__
2454
+			);
2455
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2456
+		} else {
2457
+			$att_nmbr = 1;
2458
+			foreach ($registrations as $registration) {
2459
+				/* @var $registration EE_Registration */
2460
+				$attendee                                                      = $registration->attendee()
2461
+					? $registration->attendee()
2462
+					: $this->getAttendeeModel()->create_default_object();
2463
+				$this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2464
+				$this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2465
+				$this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2466
+				$this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2467
+				$this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2468
+				$this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2469
+					', ',
2470
+					$attendee->full_address_as_array()
2471
+				);
2472
+				$this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2473
+					[
2474
+						'action' => 'edit_attendee',
2475
+						'post'   => $attendee->ID(),
2476
+					],
2477
+					REG_ADMIN_URL
2478
+				);
2479
+				$this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2480
+					$registration->event_obj() instanceof EE_Event
2481
+						? $registration->event_obj()->name()
2482
+						: '';
2483
+				$att_nmbr++;
2484
+			}
2485
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2486
+		}
2487
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2488
+		EEH_Template::display_template($template_path, $this->_template_args);
2489
+	}
2490
+
2491
+
2492
+	/**
2493
+	 * generates HTML for the Edit Registration side meta box
2494
+	 *
2495
+	 * @return void
2496
+	 * @throws DomainException
2497
+	 * @throws EE_Error
2498
+	 * @throws InvalidArgumentException
2499
+	 * @throws InvalidDataTypeException
2500
+	 * @throws InvalidInterfaceException
2501
+	 * @throws ReflectionException
2502
+	 */
2503
+	public function _reg_registrant_side_meta_box()
2504
+	{
2505
+		/*@var $attendee EE_Attendee */
2506
+		$att_check = $this->_registration->attendee();
2507
+		$attendee  = $att_check instanceof EE_Attendee
2508
+			? $att_check
2509
+			: $this->getAttendeeModel()->create_default_object();
2510
+		// now let's determine if this is not the primary registration.  If it isn't then we set the
2511
+		// primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2512
+		// primary registration object (that way we know if we need to show create button or not)
2513
+		if (! $this->_registration->is_primary_registrant()) {
2514
+			$primary_registration = $this->_registration->get_primary_registration();
2515
+			$primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2516
+				: null;
2517
+			if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2518
+				// in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2519
+				// custom attendee object so let's not worry about the primary reg.
2520
+				$primary_registration = null;
2521
+			}
2522
+		} else {
2523
+			$primary_registration = null;
2524
+		}
2525
+		$this->_template_args['ATT_ID']            = $attendee->ID();
2526
+		$this->_template_args['fname']             = $attendee->fname();
2527
+		$this->_template_args['lname']             = $attendee->lname();
2528
+		$this->_template_args['email']             = $attendee->email();
2529
+		$this->_template_args['phone']             = $attendee->phone();
2530
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2531
+		// edit link
2532
+		$this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2533
+			[
2534
+				'action' => 'edit_attendee',
2535
+				'post'   => $attendee->ID(),
2536
+			],
2537
+			REG_ADMIN_URL
2538
+		);
2539
+		$this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2540
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2541
+		// create link
2542
+		$this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2543
+			? EE_Admin_Page::add_query_args_and_nonce(
2544
+				[
2545
+					'action'  => 'duplicate_attendee',
2546
+					'_REG_ID' => $this->_registration->ID(),
2547
+				],
2548
+				REG_ADMIN_URL
2549
+			) : '';
2550
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2551
+		$this->_template_args['att_check'] = $att_check;
2552
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2553
+		EEH_Template::display_template($template_path, $this->_template_args);
2554
+	}
2555
+
2556
+
2557
+	/**
2558
+	 * trash or restore registrations
2559
+	 *
2560
+	 * @param boolean $trash whether to archive or restore
2561
+	 * @return void
2562
+	 * @throws EE_Error
2563
+	 * @throws InvalidArgumentException
2564
+	 * @throws InvalidDataTypeException
2565
+	 * @throws InvalidInterfaceException
2566
+	 * @throws RuntimeException
2567
+	 */
2568
+	protected function _trash_or_restore_registrations($trash = true)
2569
+	{
2570
+		// if empty _REG_ID then get out because there's nothing to do
2571
+		$REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2572
+		if (empty($REG_IDs)) {
2573
+			EE_Error::add_error(
2574
+				sprintf(
2575
+					esc_html__(
2576
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2577
+						'event_espresso'
2578
+					),
2579
+					$trash ? 'trash' : 'restore'
2580
+				),
2581
+				__FILE__,
2582
+				__LINE__,
2583
+				__FUNCTION__
2584
+			);
2585
+			$this->_redirect_after_action(false, '', '', [], true);
2586
+		}
2587
+		$success        = 0;
2588
+		$overwrite_msgs = false;
2589
+		// Checkboxes
2590
+		$reg_count = count($REG_IDs);
2591
+		// cycle thru checkboxes
2592
+		foreach ($REG_IDs as $REG_ID) {
2593
+			/** @var EE_Registration $REG */
2594
+			$REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2595
+			$payments = $REG->registration_payments();
2596
+			if (! empty($payments)) {
2597
+				$name           = $REG->attendee() instanceof EE_Attendee
2598
+					? $REG->attendee()->full_name()
2599
+					: esc_html__('Unknown Attendee', 'event_espresso');
2600
+				$overwrite_msgs = true;
2601
+				EE_Error::add_error(
2602
+					sprintf(
2603
+						esc_html__(
2604
+							'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.',
2605
+							'event_espresso'
2606
+						),
2607
+						$name
2608
+					),
2609
+					__FILE__,
2610
+					__FUNCTION__,
2611
+					__LINE__
2612
+				);
2613
+				// can't trash this registration because it has payments.
2614
+				continue;
2615
+			}
2616
+			$updated = $trash ? $REG->delete() : $REG->restore();
2617
+			if ($updated) {
2618
+				$success++;
2619
+			}
2620
+		}
2621
+		$this->_redirect_after_action(
2622
+			$success === $reg_count, // were ALL registrations affected?
2623
+			$success > 1
2624
+				? esc_html__('Registrations', 'event_espresso')
2625
+				: esc_html__('Registration', 'event_espresso'),
2626
+			$trash
2627
+				? esc_html__('moved to the trash', 'event_espresso')
2628
+				: esc_html__('restored', 'event_espresso'),
2629
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2630
+			$overwrite_msgs
2631
+		);
2632
+	}
2633
+
2634
+
2635
+	/**
2636
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2637
+	 * registration but also.
2638
+	 * 1. Removing relations to EE_Attendee
2639
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2640
+	 * ALSO trashed.
2641
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2642
+	 * 4. Removing relationships between all tickets and the related registrations
2643
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2644
+	 * 6. Deleting permanently any related Checkins.
2645
+	 *
2646
+	 * @return void
2647
+	 * @throws EE_Error
2648
+	 * @throws InvalidArgumentException
2649
+	 * @throws InvalidDataTypeException
2650
+	 * @throws InvalidInterfaceException
2651
+	 * @throws ReflectionException
2652
+	 */
2653
+	protected function _delete_registrations()
2654
+	{
2655
+		$REG_MDL = $this->getRegistrationModel();
2656
+		$success = 0;
2657
+		// Checkboxes
2658
+		$REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2659
+
2660
+		if (! empty($REG_IDs)) {
2661
+			// if array has more than one element than success message should be plural
2662
+			$success = count($REG_IDs) > 1 ? 2 : 1;
2663
+			// cycle thru checkboxes
2664
+			foreach ($REG_IDs as $REG_ID) {
2665
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2666
+				if (! $REG instanceof EE_Registration) {
2667
+					continue;
2668
+				}
2669
+				$deleted = $this->_delete_registration($REG);
2670
+				if (! $deleted) {
2671
+					$success = 0;
2672
+				}
2673
+			}
2674
+		}
2675
+
2676
+		$what        = $success > 1
2677
+			? esc_html__('Registrations', 'event_espresso')
2678
+			: esc_html__('Registration', 'event_espresso');
2679
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2680
+		$this->_redirect_after_action(
2681
+			$success,
2682
+			$what,
2683
+			$action_desc,
2684
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2685
+			true
2686
+		);
2687
+	}
2688
+
2689
+
2690
+	/**
2691
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2692
+	 * models get affected.
2693
+	 *
2694
+	 * @param EE_Registration $REG registration to be deleted permanently
2695
+	 * @return bool true = successful deletion, false = fail.
2696
+	 * @throws EE_Error
2697
+	 * @throws InvalidArgumentException
2698
+	 * @throws InvalidDataTypeException
2699
+	 * @throws InvalidInterfaceException
2700
+	 * @throws ReflectionException
2701
+	 */
2702
+	protected function _delete_registration(EE_Registration $REG)
2703
+	{
2704
+		// first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2705
+		// registrations on the transaction that are NOT trashed.
2706
+		$TXN = $REG->get_first_related('Transaction');
2707
+		if (! $TXN instanceof EE_Transaction) {
2708
+			EE_Error::add_error(
2709
+				sprintf(
2710
+					esc_html__(
2711
+						'Unable to permanently delete registration %d because its related transaction has already been deleted. If you can restore the related transaction to the database then this registration can be deleted.',
2712
+						'event_espresso'
2713
+					),
2714
+					$REG->id()
2715
+				),
2716
+				__FILE__,
2717
+				__FUNCTION__,
2718
+				__LINE__
2719
+			);
2720
+			return false;
2721
+		}
2722
+		$REGS        = $TXN->get_many_related('Registration');
2723
+		$all_trashed = true;
2724
+		foreach ($REGS as $registration) {
2725
+			if (! $registration->get('REG_deleted')) {
2726
+				$all_trashed = false;
2727
+			}
2728
+		}
2729
+		if (! $all_trashed) {
2730
+			EE_Error::add_error(
2731
+				esc_html__(
2732
+					'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.',
2733
+					'event_espresso'
2734
+				),
2735
+				__FILE__,
2736
+				__FUNCTION__,
2737
+				__LINE__
2738
+			);
2739
+			return false;
2740
+		}
2741
+		// k made it here so that means we can delete all the related transactions and their answers (but let's do them
2742
+		// separately from THIS one).
2743
+		foreach ($REGS as $registration) {
2744
+			// delete related answers
2745
+			$registration->delete_related_permanently('Answer');
2746
+			// remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2747
+			$attendee = $registration->get_first_related('Attendee');
2748
+			if ($attendee instanceof EE_Attendee) {
2749
+				$registration->_remove_relation_to($attendee, 'Attendee');
2750
+			}
2751
+			// now remove relationships to tickets on this registration.
2752
+			$registration->_remove_relations('Ticket');
2753
+			// now delete permanently the checkins related to this registration.
2754
+			$registration->delete_related_permanently('Checkin');
2755
+			if ($registration->ID() === $REG->ID()) {
2756
+				continue;
2757
+			} //we don't want to delete permanently the existing registration just yet.
2758
+			// remove relation to transaction for these registrations if NOT the existing registrations
2759
+			$registration->_remove_relations('Transaction');
2760
+			// delete permanently any related messages.
2761
+			$registration->delete_related_permanently('Message');
2762
+			// now delete this registration permanently
2763
+			$registration->delete_permanently();
2764
+		}
2765
+		// now all related registrations on the transaction are handled.  So let's just handle this registration itself
2766
+		// (the transaction and line items should be all that's left).
2767
+		// delete the line items related to the transaction for this registration.
2768
+		$TXN->delete_related_permanently('Line_Item');
2769
+		// we need to remove all the relationships on the transaction
2770
+		$TXN->delete_related_permanently('Payment');
2771
+		$TXN->delete_related_permanently('Extra_Meta');
2772
+		$TXN->delete_related_permanently('Message');
2773
+		// now we can delete this REG permanently (and the transaction of course)
2774
+		$REG->delete_related_permanently('Transaction');
2775
+		return $REG->delete_permanently();
2776
+	}
2777
+
2778
+
2779
+	/**
2780
+	 *    generates HTML for the Register New Attendee Admin page
2781
+	 *
2782
+	 * @throws DomainException
2783
+	 * @throws EE_Error
2784
+	 * @throws InvalidArgumentException
2785
+	 * @throws InvalidDataTypeException
2786
+	 * @throws InvalidInterfaceException
2787
+	 * @throws ReflectionException
2788
+	 */
2789
+	public function new_registration()
2790
+	{
2791
+		if (! $this->_set_reg_event()) {
2792
+			throw new EE_Error(
2793
+				esc_html__(
2794
+					'Unable to continue with registering because there is no Event ID in the request',
2795
+					'event_espresso'
2796
+				)
2797
+			);
2798
+		}
2799
+		/** @var CurrentPage $current_page */
2800
+		$current_page = $this->loader->getShared(CurrentPage::class);
2801
+		$current_page->setEspressoPage(true);
2802
+		// gotta start with a clean slate if we're not coming here via ajax
2803
+		if (
2804
+			! $this->request->isAjax()
2805
+			&& (
2806
+				! $this->request->requestParamIsSet('processing_registration')
2807
+				|| $this->request->requestParamIsSet('step_error')
2808
+			)
2809
+		) {
2810
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2811
+		}
2812
+		$this->_template_args['event_name'] = '';
2813
+		// event name
2814
+		if ($this->_reg_event) {
2815
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2816
+			$edit_event_url                     = self::add_query_args_and_nonce(
2817
+				[
2818
+					'action' => 'edit',
2819
+					'post'   => $this->_reg_event->ID(),
2820
+				],
2821
+				EVENTS_ADMIN_URL
2822
+			);
2823
+			$edit_event_lnk                     = '<a href="'
2824
+												  . $edit_event_url
2825
+												  . '" title="'
2826
+												  . esc_attr__('Edit ', 'event_espresso')
2827
+												  . $this->_reg_event->name()
2828
+												  . '">'
2829
+												  . esc_html__('Edit Event', 'event_espresso')
2830
+												  . '</a>';
2831
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2832
+												   . $edit_event_lnk
2833
+												   . '</span>';
2834
+		}
2835
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2836
+		if ($this->request->isAjax()) {
2837
+			$this->_return_json();
2838
+		}
2839
+		// grab header
2840
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2841
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2842
+			$template_path,
2843
+			$this->_template_args,
2844
+			true
2845
+		);
2846
+		// $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2847
+		// the details template wrapper
2848
+		$this->display_admin_page_with_sidebar();
2849
+	}
2850
+
2851
+
2852
+	/**
2853
+	 * This returns the content for a registration step
2854
+	 *
2855
+	 * @return string html
2856
+	 * @throws DomainException
2857
+	 * @throws EE_Error
2858
+	 * @throws InvalidArgumentException
2859
+	 * @throws InvalidDataTypeException
2860
+	 * @throws InvalidInterfaceException
2861
+	 * @throws ReflectionException
2862
+	 */
2863
+	protected function _get_registration_step_content()
2864
+	{
2865
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2866
+			$warning_msg = sprintf(
2867
+				esc_html__(
2868
+					'%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',
2869
+					'event_espresso'
2870
+				),
2871
+				'<br />',
2872
+				'<h3 class="important-notice">',
2873
+				'</h3>',
2874
+				'<div class="float-right">',
2875
+				'<span id="redirect_timer" class="important-notice">30</span>',
2876
+				'</div>',
2877
+				'<b>',
2878
+				'</b>'
2879
+			);
2880
+			return '
2881 2881
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2882 2882
 	<script >
2883 2883
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2890,840 +2890,840 @@  discard block
 block discarded – undo
2890 2890
 	        }
2891 2891
 	    }, 800 );
2892 2892
 	</script >';
2893
-        }
2894
-        $template_args = [
2895
-            'title'                    => '',
2896
-            'content'                  => '',
2897
-            'step_button_text'         => '',
2898
-            'show_notification_toggle' => false,
2899
-        ];
2900
-        // to indicate we're processing a new registration
2901
-        $hidden_fields = [
2902
-            'processing_registration' => [
2903
-                'type'  => 'hidden',
2904
-                'value' => 0,
2905
-            ],
2906
-            'event_id'                => [
2907
-                'type'  => 'hidden',
2908
-                'value' => $this->_reg_event->ID(),
2909
-            ],
2910
-        ];
2911
-        // if the cart is empty then we know we're at step one, so we'll display the ticket selector
2912
-        $cart = EE_Registry::instance()->SSN->cart();
2913
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2914
-        switch ($step) {
2915
-            case 'ticket':
2916
-                $hidden_fields['processing_registration']['value'] = 1;
2917
-                $template_args['title']                            = esc_html__(
2918
-                    'Step One: Select the Ticket for this registration',
2919
-                    'event_espresso'
2920
-                );
2921
-                $template_args['content'] = EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2922
-                $template_args['content'] .= '</div>';
2923
-                $template_args['step_button_text'] = esc_html__(
2924
-                    'Add Tickets and Continue to Registrant Details',
2925
-                    'event_espresso'
2926
-                );
2927
-                $template_args['show_notification_toggle']         = false;
2928
-                break;
2929
-            case 'questions':
2930
-                $hidden_fields['processing_registration']['value'] = 2;
2931
-                $template_args['title']                            = esc_html__(
2932
-                    'Step Two: Add Registrant Details for this Registration',
2933
-                    'event_espresso'
2934
-                );
2935
-                // in theory, we should be able to run EED_SPCO at this point
2936
-                // because the cart should have been set up properly by the first process_reg_step run.
2937
-                $template_args['content'] = EED_Single_Page_Checkout::registration_checkout_for_admin();
2938
-                $template_args['step_button_text'] = esc_html__(
2939
-                    'Save Registration and Continue to Details',
2940
-                    'event_espresso'
2941
-                );
2942
-                $template_args['show_notification_toggle'] = true;
2943
-                break;
2944
-        }
2945
-        // we come back to the process_registration_step route.
2946
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2947
-        return EEH_Template::display_template(
2948
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2949
-            $template_args,
2950
-            true
2951
-        );
2952
-    }
2953
-
2954
-
2955
-    /**
2956
-     * set_reg_event
2957
-     *
2958
-     * @return bool
2959
-     * @throws EE_Error
2960
-     * @throws InvalidArgumentException
2961
-     * @throws InvalidDataTypeException
2962
-     * @throws InvalidInterfaceException
2963
-     */
2964
-    private function _set_reg_event()
2965
-    {
2966
-        if (is_object($this->_reg_event)) {
2967
-            return true;
2968
-        }
2969
-
2970
-        $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2971
-        if (! $EVT_ID) {
2972
-            return false;
2973
-        }
2974
-        $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2975
-        return true;
2976
-    }
2977
-
2978
-
2979
-    /**
2980
-     * process_reg_step
2981
-     *
2982
-     * @return void
2983
-     * @throws DomainException
2984
-     * @throws EE_Error
2985
-     * @throws InvalidArgumentException
2986
-     * @throws InvalidDataTypeException
2987
-     * @throws InvalidInterfaceException
2988
-     * @throws ReflectionException
2989
-     * @throws RuntimeException
2990
-     */
2991
-    public function process_reg_step()
2992
-    {
2993
-        EE_System::do_not_cache();
2994
-        $this->_set_reg_event();
2995
-        /** @var CurrentPage $current_page */
2996
-        $current_page = $this->loader->getShared(CurrentPage::class);
2997
-        $current_page->setEspressoPage(true);
2998
-        $this->request->setRequestParam('uts', time());
2999
-        // what step are we on?
3000
-        $cart = EE_Registry::instance()->SSN->cart();
3001
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3002
-        // if doing ajax then we need to verify the nonce
3003
-        if ($this->request->isAjax()) {
3004
-            $nonce = $this->request->getRequestParam($this->_req_nonce, '');
3005
-            $this->_verify_nonce($nonce, $this->_req_nonce);
3006
-        }
3007
-        switch ($step) {
3008
-            case 'ticket':
3009
-                // process ticket selection
3010
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
3011
-                if ($success) {
3012
-                    EE_Error::add_success(
3013
-                        esc_html__(
3014
-                            'Tickets Selected. Now complete the registration.',
3015
-                            'event_espresso'
3016
-                        )
3017
-                    );
3018
-                } else {
3019
-                    $this->request->setRequestParam('step_error', true);
3020
-                    $query_args['step_error'] = $this->request->getRequestParam('step_error', true, 'bool');
3021
-                }
3022
-                if ($this->request->isAjax()) {
3023
-                    $this->new_registration(); // display next step
3024
-                } else {
3025
-                    $query_args = [
3026
-                        'action'                  => 'new_registration',
3027
-                        'processing_registration' => 1,
3028
-                        'event_id'                => $this->_reg_event->ID(),
3029
-                        'uts'                     => time(),
3030
-                    ];
3031
-                    $this->_redirect_after_action(
3032
-                        false,
3033
-                        '',
3034
-                        '',
3035
-                        $query_args,
3036
-                        true
3037
-                    );
3038
-                }
3039
-                break;
3040
-            case 'questions':
3041
-                if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3042
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3043
-                }
3044
-                // process registration
3045
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3046
-                if ($cart instanceof EE_Cart) {
3047
-                    $grand_total = $cart->get_grand_total();
3048
-                    if ($grand_total instanceof EE_Line_Item) {
3049
-                        $grand_total->save_this_and_descendants_to_txn();
3050
-                    }
3051
-                }
3052
-                if (! $transaction instanceof EE_Transaction) {
3053
-                    $query_args = [
3054
-                        'action'                  => 'new_registration',
3055
-                        'processing_registration' => 2,
3056
-                        'event_id'                => $this->_reg_event->ID(),
3057
-                        'uts'                     => time(),
3058
-                    ];
3059
-                    if ($this->request->isAjax()) {
3060
-                        // display registration form again because there are errors (maybe validation?)
3061
-                        $this->new_registration();
3062
-                        return;
3063
-                    }
3064
-                    $this->_redirect_after_action(
3065
-                        false,
3066
-                        '',
3067
-                        '',
3068
-                        $query_args,
3069
-                        true
3070
-                    );
3071
-                    return;
3072
-                }
3073
-                // maybe update status, and make sure to save transaction if not done already
3074
-                if (! $transaction->update_status_based_on_total_paid()) {
3075
-                    $transaction->save();
3076
-                }
3077
-                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3078
-                $query_args = [
3079
-                    'action'        => 'redirect_to_txn',
3080
-                    'TXN_ID'        => $transaction->ID(),
3081
-                    'EVT_ID'        => $this->_reg_event->ID(),
3082
-                    'event_name'    => urlencode($this->_reg_event->name()),
3083
-                    'redirect_from' => 'new_registration',
3084
-                ];
3085
-                $this->_redirect_after_action(false, '', '', $query_args, true);
3086
-                break;
3087
-        }
3088
-        // what are you looking here for?  Should be nothing to do at this point.
3089
-    }
3090
-
3091
-
3092
-    /**
3093
-     * redirect_to_txn
3094
-     *
3095
-     * @return void
3096
-     * @throws EE_Error
3097
-     * @throws InvalidArgumentException
3098
-     * @throws InvalidDataTypeException
3099
-     * @throws InvalidInterfaceException
3100
-     * @throws ReflectionException
3101
-     */
3102
-    public function redirect_to_txn()
3103
-    {
3104
-        EE_System::do_not_cache();
3105
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3106
-        $query_args = [
3107
-            'action' => 'view_transaction',
3108
-            'TXN_ID' => $this->request->getRequestParam('TXN_ID', 0, 'int'),
3109
-            'page'   => 'espresso_transactions',
3110
-        ];
3111
-        if ($this->request->requestParamIsSet('EVT_ID') && $this->request->requestParamIsSet('redirect_from')) {
3112
-            $query_args['EVT_ID']        = $this->request->getRequestParam('EVT_ID', 0, 'int');
3113
-            $query_args['event_name']    = urlencode($this->request->getRequestParam('event_name'));
3114
-            $query_args['redirect_from'] = $this->request->getRequestParam('redirect_from');
3115
-        }
3116
-        EE_Error::add_success(
3117
-            esc_html__(
3118
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3119
-                'event_espresso'
3120
-            )
3121
-        );
3122
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3123
-    }
3124
-
3125
-
3126
-    /**
3127
-     * generates HTML for the Attendee Contact List
3128
-     *
3129
-     * @return void
3130
-     * @throws DomainException
3131
-     * @throws EE_Error
3132
-     */
3133
-    protected function _attendee_contact_list_table()
3134
-    {
3135
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3136
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3137
-        $this->display_admin_list_table_page_with_no_sidebar();
3138
-    }
3139
-
3140
-
3141
-    /**
3142
-     * get_attendees
3143
-     *
3144
-     * @param      $per_page
3145
-     * @param bool $count whether to return count or data.
3146
-     * @param bool $trash
3147
-     * @return array|int
3148
-     * @throws EE_Error
3149
-     * @throws InvalidArgumentException
3150
-     * @throws InvalidDataTypeException
3151
-     * @throws InvalidInterfaceException
3152
-     */
3153
-    public function get_attendees($per_page, $count = false, $trash = false)
3154
-    {
3155
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3156
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3157
-        $orderby = $this->request->getRequestParam('orderby');
3158
-        switch ($orderby) {
3159
-            case 'ATT_ID':
3160
-            case 'ATT_fname':
3161
-            case 'ATT_email':
3162
-            case 'ATT_city':
3163
-            case 'STA_ID':
3164
-            case 'CNT_ID':
3165
-                break;
3166
-            case 'Registration_Count':
3167
-                $orderby = 'Registration_Count';
3168
-                break;
3169
-            default:
3170
-                $orderby = 'ATT_lname';
3171
-        }
3172
-        $sort         = $this->request->getRequestParam('order', 'ASC');
3173
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
3174
-        $per_page     = absint($per_page) ? $per_page : 10;
3175
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
3176
-        $_where       = [];
3177
-        $search_term  = $this->request->getRequestParam('s');
3178
-        if ($search_term) {
3179
-            $search_term  = '%' . $search_term . '%';
3180
-            $_where['OR'] = [
3181
-                'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3182
-                'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
3183
-                'Registration.Event.EVT_short_desc' => ['LIKE', $search_term],
3184
-                'ATT_fname'                         => ['LIKE', $search_term],
3185
-                'ATT_lname'                         => ['LIKE', $search_term],
3186
-                'ATT_short_bio'                     => ['LIKE', $search_term],
3187
-                'ATT_email'                         => ['LIKE', $search_term],
3188
-                'ATT_address'                       => ['LIKE', $search_term],
3189
-                'ATT_address2'                      => ['LIKE', $search_term],
3190
-                'ATT_city'                          => ['LIKE', $search_term],
3191
-                'Country.CNT_name'                  => ['LIKE', $search_term],
3192
-                'State.STA_name'                    => ['LIKE', $search_term],
3193
-                'ATT_phone'                         => ['LIKE', $search_term],
3194
-                'Registration.REG_final_price'      => ['LIKE', $search_term],
3195
-                'Registration.REG_code'             => ['LIKE', $search_term],
3196
-                'Registration.REG_group_size'       => ['LIKE', $search_term],
3197
-            ];
3198
-        }
3199
-        $offset     = ($current_page - 1) * $per_page;
3200
-        $limit      = $count ? null : [$offset, $per_page];
3201
-        $query_args = [
3202
-            $_where,
3203
-            'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3204
-            'limit'         => $limit,
3205
-        ];
3206
-        if (! $count) {
3207
-            $query_args['order_by'] = [$orderby => $sort];
3208
-        }
3209
-        $query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
3210
-        return $count
3211
-            ? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3212
-            : $this->getAttendeeModel()->get_all($query_args);
3213
-    }
3214
-
3215
-
3216
-    /**
3217
-     * This is just taking care of resending the registration confirmation
3218
-     *
3219
-     * @return void
3220
-     * @throws EE_Error
3221
-     * @throws InvalidArgumentException
3222
-     * @throws InvalidDataTypeException
3223
-     * @throws InvalidInterfaceException
3224
-     * @throws ReflectionException
3225
-     */
3226
-    protected function _resend_registration()
3227
-    {
3228
-        $this->_process_resend_registration();
3229
-        $REG_ID      = $this->request->getRequestParam('_REG_ID', 0, 'int');
3230
-        $redirect_to = $this->request->getRequestParam('redirect_to');
3231
-        $query_args  = $redirect_to
3232
-            ? ['action' => $redirect_to, '_REG_ID' => $REG_ID]
3233
-            : ['action' => 'default'];
3234
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3235
-    }
3236
-
3237
-
3238
-    /**
3239
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3240
-     * to use when selecting registrations
3241
-     *
3242
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3243
-     *                                                     the query parameters from the request
3244
-     * @return void ends the request with a redirect or download
3245
-     */
3246
-    public function _registrations_report_base($method_name_for_getting_query_params)
3247
-    {
3248
-        $EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3249
-            ? $this->request->getRequestParam('EVT_ID', 0, 'int')
3250
-            : null;
3251
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3252
-            $request_params = $this->request->requestParams();
3253
-            wp_redirect(
3254
-                EE_Admin_Page::add_query_args_and_nonce(
3255
-                    [
3256
-                        'page'        => 'espresso_batch',
3257
-                        'batch'       => 'file',
3258
-                        'EVT_ID'      => $EVT_ID,
3259
-                        'filters'     => urlencode(
3260
-                            serialize(
3261
-                                $this->$method_name_for_getting_query_params(
3262
-                                    EEH_Array::is_set($request_params, 'filters', [])
3263
-                                )
3264
-                            )
3265
-                        ),
3266
-                        'use_filters' => EEH_Array::is_set($request_params, 'use_filters', false),
3267
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3268
-                        'return_url'  => urlencode($this->request->getRequestParam('return_url', '', 'url')),
3269
-                    ]
3270
-                )
3271
-            );
3272
-        } else {
3273
-            $new_request_args = [
3274
-                'export' => 'report',
3275
-                'action' => 'registrations_report_for_event',
3276
-                'EVT_ID' => $EVT_ID,
3277
-            ];
3278
-            $this->request->mergeRequestParams($new_request_args);
3279
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3280
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3281
-                $EE_Export = EE_Export::instance($this->request->requestParams());
3282
-                $EE_Export->export();
3283
-            }
3284
-        }
3285
-    }
3286
-
3287
-
3288
-    /**
3289
-     * Creates a registration report using only query parameters in the request
3290
-     *
3291
-     * @return void
3292
-     */
3293
-    public function _registrations_report()
3294
-    {
3295
-        $this->_registrations_report_base('_get_registration_query_parameters');
3296
-    }
3297
-
3298
-
3299
-    public function _contact_list_export()
3300
-    {
3301
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3302
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3303
-            $EE_Export = EE_Export::instance($this->request->requestParams());
3304
-            $EE_Export->export_attendees();
3305
-        }
3306
-    }
3307
-
3308
-
3309
-    public function _contact_list_report()
3310
-    {
3311
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3312
-            wp_redirect(
3313
-                EE_Admin_Page::add_query_args_and_nonce(
3314
-                    [
3315
-                        'page'        => 'espresso_batch',
3316
-                        'batch'       => 'file',
3317
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3318
-                        'return_url'  => urlencode($this->request->getRequestParam('return_url', '', 'url')),
3319
-                    ]
3320
-                )
3321
-            );
3322
-        } else {
3323
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3324
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3325
-                $EE_Export = EE_Export::instance($this->request->requestParams());
3326
-                $EE_Export->report_attendees();
3327
-            }
3328
-        }
3329
-    }
3330
-
3331
-
3332
-
3333
-
3334
-
3335
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3336
-    /**
3337
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3338
-     *
3339
-     * @return void
3340
-     * @throws EE_Error
3341
-     * @throws InvalidArgumentException
3342
-     * @throws InvalidDataTypeException
3343
-     * @throws InvalidInterfaceException
3344
-     * @throws ReflectionException
3345
-     */
3346
-    protected function _duplicate_attendee()
3347
-    {
3348
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3349
-        $action = $this->request->getRequestParam('return', 'default');
3350
-        // verify we have necessary info
3351
-        if (! $REG_ID) {
3352
-            EE_Error::add_error(
3353
-                esc_html__(
3354
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3355
-                    'event_espresso'
3356
-                ),
3357
-                __FILE__,
3358
-                __LINE__,
3359
-                __FUNCTION__
3360
-            );
3361
-            $query_args = ['action' => $action];
3362
-            $this->_redirect_after_action('', '', '', $query_args, true);
3363
-        }
3364
-        // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3365
-        $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3366
-        if (! $registration instanceof EE_Registration) {
3367
-            throw new RuntimeException(
3368
-                sprintf(
3369
-                    esc_html__(
3370
-                        'Unable to create the contact because a valid registration could not be retrieved for REG ID: %1$d',
3371
-                        'event_espresso'
3372
-                    ),
3373
-                    $REG_ID
3374
-                )
3375
-            );
3376
-        }
3377
-        $attendee = $registration->attendee();
3378
-        // remove relation of existing attendee on registration
3379
-        $registration->_remove_relation_to($attendee, 'Attendee');
3380
-        // new attendee
3381
-        $new_attendee = clone $attendee;
3382
-        $new_attendee->set('ATT_ID', 0);
3383
-        $new_attendee->save();
3384
-        // add new attendee to reg
3385
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3386
-        EE_Error::add_success(
3387
-            esc_html__(
3388
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3389
-                'event_espresso'
3390
-            )
3391
-        );
3392
-        // redirect to edit page for attendee
3393
-        $query_args = ['post' => $new_attendee->ID(), 'action' => 'edit_attendee'];
3394
-        $this->_redirect_after_action('', '', '', $query_args, true);
3395
-    }
3396
-
3397
-
3398
-    /**
3399
-     * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3400
-     *
3401
-     * @param int     $post_id
3402
-     * @param WP_POST $post
3403
-     * @throws DomainException
3404
-     * @throws EE_Error
3405
-     * @throws InvalidArgumentException
3406
-     * @throws InvalidDataTypeException
3407
-     * @throws InvalidInterfaceException
3408
-     * @throws LogicException
3409
-     * @throws InvalidFormSubmissionException
3410
-     * @throws ReflectionException
3411
-     */
3412
-    protected function _insert_update_cpt_item($post_id, $post)
3413
-    {
3414
-        $success  = true;
3415
-        $attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3416
-            ? $this->getAttendeeModel()->get_one_by_ID($post_id)
3417
-            : null;
3418
-        // for attendee updates
3419
-        if ($attendee instanceof EE_Attendee) {
3420
-            // note we should only be UPDATING attendees at this point.
3421
-            $fname          = $this->request->getRequestParam('ATT_fname', '');
3422
-            $lname          = $this->request->getRequestParam('ATT_lname', '');
3423
-            $updated_fields = [
3424
-                'ATT_fname'     => $fname,
3425
-                'ATT_lname'     => $lname,
3426
-                'ATT_full_name' => "{$fname} {$lname}",
3427
-                'ATT_address'   => $this->request->getRequestParam('ATT_address', ''),
3428
-                'ATT_address2'  => $this->request->getRequestParam('ATT_address2', ''),
3429
-                'ATT_city'      => $this->request->getRequestParam('ATT_city', ''),
3430
-                'STA_ID'        => $this->request->getRequestParam('STA_ID', ''),
3431
-                'CNT_ISO'       => $this->request->getRequestParam('CNT_ISO', ''),
3432
-                'ATT_zip'       => $this->request->getRequestParam('ATT_zip', ''),
3433
-            ];
3434
-            foreach ($updated_fields as $field => $value) {
3435
-                $attendee->set($field, $value);
3436
-            }
3437
-
3438
-            // process contact details metabox form handler (which will also save the attendee)
3439
-            $contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3440
-            $success              = $contact_details_form->process($this->request->requestParams());
3441
-
3442
-            $attendee_update_callbacks = apply_filters(
3443
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3444
-                []
3445
-            );
3446
-            foreach ($attendee_update_callbacks as $a_callback) {
3447
-                if (false === call_user_func_array($a_callback, [$attendee, $this->request->requestParams()])) {
3448
-                    throw new EE_Error(
3449
-                        sprintf(
3450
-                            esc_html__(
3451
-                                '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.',
3452
-                                'event_espresso'
3453
-                            ),
3454
-                            $a_callback
3455
-                        )
3456
-                    );
3457
-                }
3458
-            }
3459
-        }
3460
-
3461
-        if ($success === false) {
3462
-            EE_Error::add_error(
3463
-                esc_html__(
3464
-                    'Something went wrong with updating the meta table data for the registration.',
3465
-                    'event_espresso'
3466
-                ),
3467
-                __FILE__,
3468
-                __FUNCTION__,
3469
-                __LINE__
3470
-            );
3471
-        }
3472
-    }
3473
-
3474
-
3475
-    public function trash_cpt_item($post_id)
3476
-    {
3477
-    }
3478
-
3479
-
3480
-    public function delete_cpt_item($post_id)
3481
-    {
3482
-    }
3483
-
3484
-
3485
-    public function restore_cpt_item($post_id)
3486
-    {
3487
-    }
3488
-
3489
-
3490
-    protected function _restore_cpt_item($post_id, $revision_id)
3491
-    {
3492
-    }
3493
-
3494
-
3495
-    /**
3496
-     * @throws EE_Error
3497
-     * @throws ReflectionException
3498
-     * @since 4.10.2.p
3499
-     */
3500
-    public function attendee_editor_metaboxes()
3501
-    {
3502
-        $this->verify_cpt_object();
3503
-        remove_meta_box(
3504
-            'postexcerpt',
3505
-            $this->_cpt_routes[ $this->_req_action ],
3506
-            'normal'
3507
-        );
3508
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3509
-        if (post_type_supports('espresso_attendees', 'excerpt')) {
3510
-            $this->addMetaBox(
3511
-                'postexcerpt',
3512
-                esc_html__('Short Biography', 'event_espresso'),
3513
-                'post_excerpt_meta_box',
3514
-                $this->_cpt_routes[ $this->_req_action ]
3515
-            );
3516
-        }
3517
-        if (post_type_supports('espresso_attendees', 'comments')) {
3518
-            $this->addMetaBox(
3519
-                'commentsdiv',
3520
-                esc_html__('Notes on the Contact', 'event_espresso'),
3521
-                'post_comment_meta_box',
3522
-                $this->_cpt_routes[ $this->_req_action ],
3523
-                'normal',
3524
-                'core'
3525
-            );
3526
-        }
3527
-        $this->addMetaBox(
3528
-            'attendee_contact_info',
3529
-            esc_html__('Contact Info', 'event_espresso'),
3530
-            [$this, 'attendee_contact_info'],
3531
-            $this->_cpt_routes[ $this->_req_action ],
3532
-            'side',
3533
-            'core'
3534
-        );
3535
-        $this->addMetaBox(
3536
-            'attendee_details_address',
3537
-            esc_html__('Address Details', 'event_espresso'),
3538
-            [$this, 'attendee_address_details'],
3539
-            $this->_cpt_routes[ $this->_req_action ],
3540
-            'normal',
3541
-            'core'
3542
-        );
3543
-        $this->addMetaBox(
3544
-            'attendee_registrations',
3545
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3546
-            [$this, 'attendee_registrations_meta_box'],
3547
-            $this->_cpt_routes[ $this->_req_action ]
3548
-        );
3549
-    }
3550
-
3551
-
3552
-    /**
3553
-     * Metabox for attendee contact info
3554
-     *
3555
-     * @param WP_Post $post wp post object
3556
-     * @return void attendee contact info ( and form )
3557
-     * @throws EE_Error
3558
-     * @throws InvalidArgumentException
3559
-     * @throws InvalidDataTypeException
3560
-     * @throws InvalidInterfaceException
3561
-     * @throws LogicException
3562
-     * @throws DomainException
3563
-     */
3564
-    public function attendee_contact_info($post)
3565
-    {
3566
-        // get attendee object ( should already have it )
3567
-        $form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3568
-        $form->enqueueStylesAndScripts();
3569
-        echo $form->display(); // already escaped
3570
-    }
3571
-
3572
-
3573
-    /**
3574
-     * Return form handler for the contact details metabox
3575
-     *
3576
-     * @param EE_Attendee $attendee
3577
-     * @return AttendeeContactDetailsMetaboxFormHandler
3578
-     * @throws DomainException
3579
-     * @throws InvalidArgumentException
3580
-     * @throws InvalidDataTypeException
3581
-     * @throws InvalidInterfaceException
3582
-     */
3583
-    protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3584
-    {
3585
-        return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3586
-    }
3587
-
3588
-
3589
-    /**
3590
-     * Metabox for attendee details
3591
-     *
3592
-     * @param WP_Post $post wp post object
3593
-     * @throws EE_Error
3594
-     * @throws ReflectionException
3595
-     */
3596
-    public function attendee_address_details($post)
3597
-    {
3598
-        // get attendee object (should already have it)
3599
-        $this->_template_args['attendee']     = $this->_cpt_model_obj;
3600
-        $this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3601
-            new EE_Question_Form_Input(
3602
-                EE_Question::new_instance(
3603
-                    [
3604
-                        'QST_ID'           => 0,
3605
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3606
-                        'QST_system'       => 'admin-state',
3607
-                    ]
3608
-                ),
3609
-                EE_Answer::new_instance(
3610
-                    [
3611
-                        'ANS_ID'    => 0,
3612
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3613
-                    ]
3614
-                ),
3615
-                [
3616
-                    'input_id'       => 'STA_ID',
3617
-                    'input_name'     => 'STA_ID',
3618
-                    'input_prefix'   => '',
3619
-                    'append_qstn_id' => false,
3620
-                ]
3621
-            )
3622
-        );
3623
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3624
-            new EE_Question_Form_Input(
3625
-                EE_Question::new_instance(
3626
-                    [
3627
-                        'QST_ID'           => 0,
3628
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3629
-                        'QST_system'       => 'admin-country',
3630
-                    ]
3631
-                ),
3632
-                EE_Answer::new_instance(
3633
-                    [
3634
-                        'ANS_ID'    => 0,
3635
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3636
-                    ]
3637
-                ),
3638
-                [
3639
-                    'input_id'       => 'CNT_ISO',
3640
-                    'input_name'     => 'CNT_ISO',
3641
-                    'input_prefix'   => '',
3642
-                    'append_qstn_id' => false,
3643
-                ]
3644
-            )
3645
-        );
3646
-        $template = REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3647
-        EEH_Template::display_template($template, $this->_template_args);
3648
-    }
3649
-
3650
-
3651
-    /**
3652
-     * _attendee_details
3653
-     *
3654
-     * @param $post
3655
-     * @return void
3656
-     * @throws DomainException
3657
-     * @throws EE_Error
3658
-     * @throws InvalidArgumentException
3659
-     * @throws InvalidDataTypeException
3660
-     * @throws InvalidInterfaceException
3661
-     * @throws ReflectionException
3662
-     */
3663
-    public function attendee_registrations_meta_box($post)
3664
-    {
3665
-        $this->_template_args['attendee']      = $this->_cpt_model_obj;
3666
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3667
-        $template = REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3668
-        EEH_Template::display_template($template, $this->_template_args);
3669
-    }
3670
-
3671
-
3672
-    /**
3673
-     * add in the form fields for the attendee edit
3674
-     *
3675
-     * @param WP_Post $post wp post object
3676
-     * @return void echos html for new form.
3677
-     * @throws DomainException
3678
-     */
3679
-    public function after_title_form_fields($post)
3680
-    {
3681
-        if ($post->post_type === 'espresso_attendees') {
3682
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3683
-            $template_args['attendee'] = $this->_cpt_model_obj;
3684
-            EEH_Template::display_template($template, $template_args);
3685
-        }
3686
-    }
3687
-
3688
-
3689
-    /**
3690
-     * _trash_or_restore_attendee
3691
-     *
3692
-     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3693
-     * @return void
3694
-     * @throws EE_Error
3695
-     * @throws InvalidArgumentException
3696
-     * @throws InvalidDataTypeException
3697
-     * @throws InvalidInterfaceException
3698
-     */
3699
-    protected function _trash_or_restore_attendees($trash = true)
3700
-    {
3701
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3702
-        $status = $trash ? 'trash' : 'publish';
3703
-        // Checkboxes
3704
-        if ($this->request->requestParamIsSet('checkbox')) {
3705
-            $ATT_IDs = $this->request->getRequestParam('checkbox', [], 'int', true);
3706
-            // if array has more than one element than success message should be plural
3707
-            $success = count($ATT_IDs) > 1 ? 2 : 1;
3708
-            // cycle thru checkboxes
3709
-            foreach ($ATT_IDs as $ATT_ID) {
3710
-                $updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3711
-                if (! $updated) {
3712
-                    $success = 0;
3713
-                }
3714
-            }
3715
-        } else {
3716
-            // grab single id and delete
3717
-            $ATT_ID = $this->request->getRequestParam('ATT_ID', 0, 'int');
3718
-            // update attendee
3719
-            $success = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID) ? 1 : 0;
3720
-        }
3721
-        $what        = $success > 1
3722
-            ? esc_html__('Contacts', 'event_espresso')
3723
-            : esc_html__('Contact', 'event_espresso');
3724
-        $action_desc = $trash
3725
-            ? esc_html__('moved to the trash', 'event_espresso')
3726
-            : esc_html__('restored', 'event_espresso');
3727
-        $this->_redirect_after_action($success, $what, $action_desc, ['action' => 'contact_list']);
3728
-    }
2893
+		}
2894
+		$template_args = [
2895
+			'title'                    => '',
2896
+			'content'                  => '',
2897
+			'step_button_text'         => '',
2898
+			'show_notification_toggle' => false,
2899
+		];
2900
+		// to indicate we're processing a new registration
2901
+		$hidden_fields = [
2902
+			'processing_registration' => [
2903
+				'type'  => 'hidden',
2904
+				'value' => 0,
2905
+			],
2906
+			'event_id'                => [
2907
+				'type'  => 'hidden',
2908
+				'value' => $this->_reg_event->ID(),
2909
+			],
2910
+		];
2911
+		// if the cart is empty then we know we're at step one, so we'll display the ticket selector
2912
+		$cart = EE_Registry::instance()->SSN->cart();
2913
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2914
+		switch ($step) {
2915
+			case 'ticket':
2916
+				$hidden_fields['processing_registration']['value'] = 1;
2917
+				$template_args['title']                            = esc_html__(
2918
+					'Step One: Select the Ticket for this registration',
2919
+					'event_espresso'
2920
+				);
2921
+				$template_args['content'] = EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2922
+				$template_args['content'] .= '</div>';
2923
+				$template_args['step_button_text'] = esc_html__(
2924
+					'Add Tickets and Continue to Registrant Details',
2925
+					'event_espresso'
2926
+				);
2927
+				$template_args['show_notification_toggle']         = false;
2928
+				break;
2929
+			case 'questions':
2930
+				$hidden_fields['processing_registration']['value'] = 2;
2931
+				$template_args['title']                            = esc_html__(
2932
+					'Step Two: Add Registrant Details for this Registration',
2933
+					'event_espresso'
2934
+				);
2935
+				// in theory, we should be able to run EED_SPCO at this point
2936
+				// because the cart should have been set up properly by the first process_reg_step run.
2937
+				$template_args['content'] = EED_Single_Page_Checkout::registration_checkout_for_admin();
2938
+				$template_args['step_button_text'] = esc_html__(
2939
+					'Save Registration and Continue to Details',
2940
+					'event_espresso'
2941
+				);
2942
+				$template_args['show_notification_toggle'] = true;
2943
+				break;
2944
+		}
2945
+		// we come back to the process_registration_step route.
2946
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2947
+		return EEH_Template::display_template(
2948
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2949
+			$template_args,
2950
+			true
2951
+		);
2952
+	}
2953
+
2954
+
2955
+	/**
2956
+	 * set_reg_event
2957
+	 *
2958
+	 * @return bool
2959
+	 * @throws EE_Error
2960
+	 * @throws InvalidArgumentException
2961
+	 * @throws InvalidDataTypeException
2962
+	 * @throws InvalidInterfaceException
2963
+	 */
2964
+	private function _set_reg_event()
2965
+	{
2966
+		if (is_object($this->_reg_event)) {
2967
+			return true;
2968
+		}
2969
+
2970
+		$EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2971
+		if (! $EVT_ID) {
2972
+			return false;
2973
+		}
2974
+		$this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2975
+		return true;
2976
+	}
2977
+
2978
+
2979
+	/**
2980
+	 * process_reg_step
2981
+	 *
2982
+	 * @return void
2983
+	 * @throws DomainException
2984
+	 * @throws EE_Error
2985
+	 * @throws InvalidArgumentException
2986
+	 * @throws InvalidDataTypeException
2987
+	 * @throws InvalidInterfaceException
2988
+	 * @throws ReflectionException
2989
+	 * @throws RuntimeException
2990
+	 */
2991
+	public function process_reg_step()
2992
+	{
2993
+		EE_System::do_not_cache();
2994
+		$this->_set_reg_event();
2995
+		/** @var CurrentPage $current_page */
2996
+		$current_page = $this->loader->getShared(CurrentPage::class);
2997
+		$current_page->setEspressoPage(true);
2998
+		$this->request->setRequestParam('uts', time());
2999
+		// what step are we on?
3000
+		$cart = EE_Registry::instance()->SSN->cart();
3001
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3002
+		// if doing ajax then we need to verify the nonce
3003
+		if ($this->request->isAjax()) {
3004
+			$nonce = $this->request->getRequestParam($this->_req_nonce, '');
3005
+			$this->_verify_nonce($nonce, $this->_req_nonce);
3006
+		}
3007
+		switch ($step) {
3008
+			case 'ticket':
3009
+				// process ticket selection
3010
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
3011
+				if ($success) {
3012
+					EE_Error::add_success(
3013
+						esc_html__(
3014
+							'Tickets Selected. Now complete the registration.',
3015
+							'event_espresso'
3016
+						)
3017
+					);
3018
+				} else {
3019
+					$this->request->setRequestParam('step_error', true);
3020
+					$query_args['step_error'] = $this->request->getRequestParam('step_error', true, 'bool');
3021
+				}
3022
+				if ($this->request->isAjax()) {
3023
+					$this->new_registration(); // display next step
3024
+				} else {
3025
+					$query_args = [
3026
+						'action'                  => 'new_registration',
3027
+						'processing_registration' => 1,
3028
+						'event_id'                => $this->_reg_event->ID(),
3029
+						'uts'                     => time(),
3030
+					];
3031
+					$this->_redirect_after_action(
3032
+						false,
3033
+						'',
3034
+						'',
3035
+						$query_args,
3036
+						true
3037
+					);
3038
+				}
3039
+				break;
3040
+			case 'questions':
3041
+				if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3042
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3043
+				}
3044
+				// process registration
3045
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3046
+				if ($cart instanceof EE_Cart) {
3047
+					$grand_total = $cart->get_grand_total();
3048
+					if ($grand_total instanceof EE_Line_Item) {
3049
+						$grand_total->save_this_and_descendants_to_txn();
3050
+					}
3051
+				}
3052
+				if (! $transaction instanceof EE_Transaction) {
3053
+					$query_args = [
3054
+						'action'                  => 'new_registration',
3055
+						'processing_registration' => 2,
3056
+						'event_id'                => $this->_reg_event->ID(),
3057
+						'uts'                     => time(),
3058
+					];
3059
+					if ($this->request->isAjax()) {
3060
+						// display registration form again because there are errors (maybe validation?)
3061
+						$this->new_registration();
3062
+						return;
3063
+					}
3064
+					$this->_redirect_after_action(
3065
+						false,
3066
+						'',
3067
+						'',
3068
+						$query_args,
3069
+						true
3070
+					);
3071
+					return;
3072
+				}
3073
+				// maybe update status, and make sure to save transaction if not done already
3074
+				if (! $transaction->update_status_based_on_total_paid()) {
3075
+					$transaction->save();
3076
+				}
3077
+				EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3078
+				$query_args = [
3079
+					'action'        => 'redirect_to_txn',
3080
+					'TXN_ID'        => $transaction->ID(),
3081
+					'EVT_ID'        => $this->_reg_event->ID(),
3082
+					'event_name'    => urlencode($this->_reg_event->name()),
3083
+					'redirect_from' => 'new_registration',
3084
+				];
3085
+				$this->_redirect_after_action(false, '', '', $query_args, true);
3086
+				break;
3087
+		}
3088
+		// what are you looking here for?  Should be nothing to do at this point.
3089
+	}
3090
+
3091
+
3092
+	/**
3093
+	 * redirect_to_txn
3094
+	 *
3095
+	 * @return void
3096
+	 * @throws EE_Error
3097
+	 * @throws InvalidArgumentException
3098
+	 * @throws InvalidDataTypeException
3099
+	 * @throws InvalidInterfaceException
3100
+	 * @throws ReflectionException
3101
+	 */
3102
+	public function redirect_to_txn()
3103
+	{
3104
+		EE_System::do_not_cache();
3105
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3106
+		$query_args = [
3107
+			'action' => 'view_transaction',
3108
+			'TXN_ID' => $this->request->getRequestParam('TXN_ID', 0, 'int'),
3109
+			'page'   => 'espresso_transactions',
3110
+		];
3111
+		if ($this->request->requestParamIsSet('EVT_ID') && $this->request->requestParamIsSet('redirect_from')) {
3112
+			$query_args['EVT_ID']        = $this->request->getRequestParam('EVT_ID', 0, 'int');
3113
+			$query_args['event_name']    = urlencode($this->request->getRequestParam('event_name'));
3114
+			$query_args['redirect_from'] = $this->request->getRequestParam('redirect_from');
3115
+		}
3116
+		EE_Error::add_success(
3117
+			esc_html__(
3118
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3119
+				'event_espresso'
3120
+			)
3121
+		);
3122
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3123
+	}
3124
+
3125
+
3126
+	/**
3127
+	 * generates HTML for the Attendee Contact List
3128
+	 *
3129
+	 * @return void
3130
+	 * @throws DomainException
3131
+	 * @throws EE_Error
3132
+	 */
3133
+	protected function _attendee_contact_list_table()
3134
+	{
3135
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3136
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3137
+		$this->display_admin_list_table_page_with_no_sidebar();
3138
+	}
3139
+
3140
+
3141
+	/**
3142
+	 * get_attendees
3143
+	 *
3144
+	 * @param      $per_page
3145
+	 * @param bool $count whether to return count or data.
3146
+	 * @param bool $trash
3147
+	 * @return array|int
3148
+	 * @throws EE_Error
3149
+	 * @throws InvalidArgumentException
3150
+	 * @throws InvalidDataTypeException
3151
+	 * @throws InvalidInterfaceException
3152
+	 */
3153
+	public function get_attendees($per_page, $count = false, $trash = false)
3154
+	{
3155
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3156
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3157
+		$orderby = $this->request->getRequestParam('orderby');
3158
+		switch ($orderby) {
3159
+			case 'ATT_ID':
3160
+			case 'ATT_fname':
3161
+			case 'ATT_email':
3162
+			case 'ATT_city':
3163
+			case 'STA_ID':
3164
+			case 'CNT_ID':
3165
+				break;
3166
+			case 'Registration_Count':
3167
+				$orderby = 'Registration_Count';
3168
+				break;
3169
+			default:
3170
+				$orderby = 'ATT_lname';
3171
+		}
3172
+		$sort         = $this->request->getRequestParam('order', 'ASC');
3173
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
3174
+		$per_page     = absint($per_page) ? $per_page : 10;
3175
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
3176
+		$_where       = [];
3177
+		$search_term  = $this->request->getRequestParam('s');
3178
+		if ($search_term) {
3179
+			$search_term  = '%' . $search_term . '%';
3180
+			$_where['OR'] = [
3181
+				'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3182
+				'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
3183
+				'Registration.Event.EVT_short_desc' => ['LIKE', $search_term],
3184
+				'ATT_fname'                         => ['LIKE', $search_term],
3185
+				'ATT_lname'                         => ['LIKE', $search_term],
3186
+				'ATT_short_bio'                     => ['LIKE', $search_term],
3187
+				'ATT_email'                         => ['LIKE', $search_term],
3188
+				'ATT_address'                       => ['LIKE', $search_term],
3189
+				'ATT_address2'                      => ['LIKE', $search_term],
3190
+				'ATT_city'                          => ['LIKE', $search_term],
3191
+				'Country.CNT_name'                  => ['LIKE', $search_term],
3192
+				'State.STA_name'                    => ['LIKE', $search_term],
3193
+				'ATT_phone'                         => ['LIKE', $search_term],
3194
+				'Registration.REG_final_price'      => ['LIKE', $search_term],
3195
+				'Registration.REG_code'             => ['LIKE', $search_term],
3196
+				'Registration.REG_group_size'       => ['LIKE', $search_term],
3197
+			];
3198
+		}
3199
+		$offset     = ($current_page - 1) * $per_page;
3200
+		$limit      = $count ? null : [$offset, $per_page];
3201
+		$query_args = [
3202
+			$_where,
3203
+			'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3204
+			'limit'         => $limit,
3205
+		];
3206
+		if (! $count) {
3207
+			$query_args['order_by'] = [$orderby => $sort];
3208
+		}
3209
+		$query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
3210
+		return $count
3211
+			? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3212
+			: $this->getAttendeeModel()->get_all($query_args);
3213
+	}
3214
+
3215
+
3216
+	/**
3217
+	 * This is just taking care of resending the registration confirmation
3218
+	 *
3219
+	 * @return void
3220
+	 * @throws EE_Error
3221
+	 * @throws InvalidArgumentException
3222
+	 * @throws InvalidDataTypeException
3223
+	 * @throws InvalidInterfaceException
3224
+	 * @throws ReflectionException
3225
+	 */
3226
+	protected function _resend_registration()
3227
+	{
3228
+		$this->_process_resend_registration();
3229
+		$REG_ID      = $this->request->getRequestParam('_REG_ID', 0, 'int');
3230
+		$redirect_to = $this->request->getRequestParam('redirect_to');
3231
+		$query_args  = $redirect_to
3232
+			? ['action' => $redirect_to, '_REG_ID' => $REG_ID]
3233
+			: ['action' => 'default'];
3234
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3235
+	}
3236
+
3237
+
3238
+	/**
3239
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3240
+	 * to use when selecting registrations
3241
+	 *
3242
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3243
+	 *                                                     the query parameters from the request
3244
+	 * @return void ends the request with a redirect or download
3245
+	 */
3246
+	public function _registrations_report_base($method_name_for_getting_query_params)
3247
+	{
3248
+		$EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3249
+			? $this->request->getRequestParam('EVT_ID', 0, 'int')
3250
+			: null;
3251
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3252
+			$request_params = $this->request->requestParams();
3253
+			wp_redirect(
3254
+				EE_Admin_Page::add_query_args_and_nonce(
3255
+					[
3256
+						'page'        => 'espresso_batch',
3257
+						'batch'       => 'file',
3258
+						'EVT_ID'      => $EVT_ID,
3259
+						'filters'     => urlencode(
3260
+							serialize(
3261
+								$this->$method_name_for_getting_query_params(
3262
+									EEH_Array::is_set($request_params, 'filters', [])
3263
+								)
3264
+							)
3265
+						),
3266
+						'use_filters' => EEH_Array::is_set($request_params, 'use_filters', false),
3267
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3268
+						'return_url'  => urlencode($this->request->getRequestParam('return_url', '', 'url')),
3269
+					]
3270
+				)
3271
+			);
3272
+		} else {
3273
+			$new_request_args = [
3274
+				'export' => 'report',
3275
+				'action' => 'registrations_report_for_event',
3276
+				'EVT_ID' => $EVT_ID,
3277
+			];
3278
+			$this->request->mergeRequestParams($new_request_args);
3279
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3280
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3281
+				$EE_Export = EE_Export::instance($this->request->requestParams());
3282
+				$EE_Export->export();
3283
+			}
3284
+		}
3285
+	}
3286
+
3287
+
3288
+	/**
3289
+	 * Creates a registration report using only query parameters in the request
3290
+	 *
3291
+	 * @return void
3292
+	 */
3293
+	public function _registrations_report()
3294
+	{
3295
+		$this->_registrations_report_base('_get_registration_query_parameters');
3296
+	}
3297
+
3298
+
3299
+	public function _contact_list_export()
3300
+	{
3301
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3302
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3303
+			$EE_Export = EE_Export::instance($this->request->requestParams());
3304
+			$EE_Export->export_attendees();
3305
+		}
3306
+	}
3307
+
3308
+
3309
+	public function _contact_list_report()
3310
+	{
3311
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3312
+			wp_redirect(
3313
+				EE_Admin_Page::add_query_args_and_nonce(
3314
+					[
3315
+						'page'        => 'espresso_batch',
3316
+						'batch'       => 'file',
3317
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3318
+						'return_url'  => urlencode($this->request->getRequestParam('return_url', '', 'url')),
3319
+					]
3320
+				)
3321
+			);
3322
+		} else {
3323
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3324
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3325
+				$EE_Export = EE_Export::instance($this->request->requestParams());
3326
+				$EE_Export->report_attendees();
3327
+			}
3328
+		}
3329
+	}
3330
+
3331
+
3332
+
3333
+
3334
+
3335
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3336
+	/**
3337
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3338
+	 *
3339
+	 * @return void
3340
+	 * @throws EE_Error
3341
+	 * @throws InvalidArgumentException
3342
+	 * @throws InvalidDataTypeException
3343
+	 * @throws InvalidInterfaceException
3344
+	 * @throws ReflectionException
3345
+	 */
3346
+	protected function _duplicate_attendee()
3347
+	{
3348
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3349
+		$action = $this->request->getRequestParam('return', 'default');
3350
+		// verify we have necessary info
3351
+		if (! $REG_ID) {
3352
+			EE_Error::add_error(
3353
+				esc_html__(
3354
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3355
+					'event_espresso'
3356
+				),
3357
+				__FILE__,
3358
+				__LINE__,
3359
+				__FUNCTION__
3360
+			);
3361
+			$query_args = ['action' => $action];
3362
+			$this->_redirect_after_action('', '', '', $query_args, true);
3363
+		}
3364
+		// okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3365
+		$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3366
+		if (! $registration instanceof EE_Registration) {
3367
+			throw new RuntimeException(
3368
+				sprintf(
3369
+					esc_html__(
3370
+						'Unable to create the contact because a valid registration could not be retrieved for REG ID: %1$d',
3371
+						'event_espresso'
3372
+					),
3373
+					$REG_ID
3374
+				)
3375
+			);
3376
+		}
3377
+		$attendee = $registration->attendee();
3378
+		// remove relation of existing attendee on registration
3379
+		$registration->_remove_relation_to($attendee, 'Attendee');
3380
+		// new attendee
3381
+		$new_attendee = clone $attendee;
3382
+		$new_attendee->set('ATT_ID', 0);
3383
+		$new_attendee->save();
3384
+		// add new attendee to reg
3385
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3386
+		EE_Error::add_success(
3387
+			esc_html__(
3388
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3389
+				'event_espresso'
3390
+			)
3391
+		);
3392
+		// redirect to edit page for attendee
3393
+		$query_args = ['post' => $new_attendee->ID(), 'action' => 'edit_attendee'];
3394
+		$this->_redirect_after_action('', '', '', $query_args, true);
3395
+	}
3396
+
3397
+
3398
+	/**
3399
+	 * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3400
+	 *
3401
+	 * @param int     $post_id
3402
+	 * @param WP_POST $post
3403
+	 * @throws DomainException
3404
+	 * @throws EE_Error
3405
+	 * @throws InvalidArgumentException
3406
+	 * @throws InvalidDataTypeException
3407
+	 * @throws InvalidInterfaceException
3408
+	 * @throws LogicException
3409
+	 * @throws InvalidFormSubmissionException
3410
+	 * @throws ReflectionException
3411
+	 */
3412
+	protected function _insert_update_cpt_item($post_id, $post)
3413
+	{
3414
+		$success  = true;
3415
+		$attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3416
+			? $this->getAttendeeModel()->get_one_by_ID($post_id)
3417
+			: null;
3418
+		// for attendee updates
3419
+		if ($attendee instanceof EE_Attendee) {
3420
+			// note we should only be UPDATING attendees at this point.
3421
+			$fname          = $this->request->getRequestParam('ATT_fname', '');
3422
+			$lname          = $this->request->getRequestParam('ATT_lname', '');
3423
+			$updated_fields = [
3424
+				'ATT_fname'     => $fname,
3425
+				'ATT_lname'     => $lname,
3426
+				'ATT_full_name' => "{$fname} {$lname}",
3427
+				'ATT_address'   => $this->request->getRequestParam('ATT_address', ''),
3428
+				'ATT_address2'  => $this->request->getRequestParam('ATT_address2', ''),
3429
+				'ATT_city'      => $this->request->getRequestParam('ATT_city', ''),
3430
+				'STA_ID'        => $this->request->getRequestParam('STA_ID', ''),
3431
+				'CNT_ISO'       => $this->request->getRequestParam('CNT_ISO', ''),
3432
+				'ATT_zip'       => $this->request->getRequestParam('ATT_zip', ''),
3433
+			];
3434
+			foreach ($updated_fields as $field => $value) {
3435
+				$attendee->set($field, $value);
3436
+			}
3437
+
3438
+			// process contact details metabox form handler (which will also save the attendee)
3439
+			$contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3440
+			$success              = $contact_details_form->process($this->request->requestParams());
3441
+
3442
+			$attendee_update_callbacks = apply_filters(
3443
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3444
+				[]
3445
+			);
3446
+			foreach ($attendee_update_callbacks as $a_callback) {
3447
+				if (false === call_user_func_array($a_callback, [$attendee, $this->request->requestParams()])) {
3448
+					throw new EE_Error(
3449
+						sprintf(
3450
+							esc_html__(
3451
+								'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.',
3452
+								'event_espresso'
3453
+							),
3454
+							$a_callback
3455
+						)
3456
+					);
3457
+				}
3458
+			}
3459
+		}
3460
+
3461
+		if ($success === false) {
3462
+			EE_Error::add_error(
3463
+				esc_html__(
3464
+					'Something went wrong with updating the meta table data for the registration.',
3465
+					'event_espresso'
3466
+				),
3467
+				__FILE__,
3468
+				__FUNCTION__,
3469
+				__LINE__
3470
+			);
3471
+		}
3472
+	}
3473
+
3474
+
3475
+	public function trash_cpt_item($post_id)
3476
+	{
3477
+	}
3478
+
3479
+
3480
+	public function delete_cpt_item($post_id)
3481
+	{
3482
+	}
3483
+
3484
+
3485
+	public function restore_cpt_item($post_id)
3486
+	{
3487
+	}
3488
+
3489
+
3490
+	protected function _restore_cpt_item($post_id, $revision_id)
3491
+	{
3492
+	}
3493
+
3494
+
3495
+	/**
3496
+	 * @throws EE_Error
3497
+	 * @throws ReflectionException
3498
+	 * @since 4.10.2.p
3499
+	 */
3500
+	public function attendee_editor_metaboxes()
3501
+	{
3502
+		$this->verify_cpt_object();
3503
+		remove_meta_box(
3504
+			'postexcerpt',
3505
+			$this->_cpt_routes[ $this->_req_action ],
3506
+			'normal'
3507
+		);
3508
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3509
+		if (post_type_supports('espresso_attendees', 'excerpt')) {
3510
+			$this->addMetaBox(
3511
+				'postexcerpt',
3512
+				esc_html__('Short Biography', 'event_espresso'),
3513
+				'post_excerpt_meta_box',
3514
+				$this->_cpt_routes[ $this->_req_action ]
3515
+			);
3516
+		}
3517
+		if (post_type_supports('espresso_attendees', 'comments')) {
3518
+			$this->addMetaBox(
3519
+				'commentsdiv',
3520
+				esc_html__('Notes on the Contact', 'event_espresso'),
3521
+				'post_comment_meta_box',
3522
+				$this->_cpt_routes[ $this->_req_action ],
3523
+				'normal',
3524
+				'core'
3525
+			);
3526
+		}
3527
+		$this->addMetaBox(
3528
+			'attendee_contact_info',
3529
+			esc_html__('Contact Info', 'event_espresso'),
3530
+			[$this, 'attendee_contact_info'],
3531
+			$this->_cpt_routes[ $this->_req_action ],
3532
+			'side',
3533
+			'core'
3534
+		);
3535
+		$this->addMetaBox(
3536
+			'attendee_details_address',
3537
+			esc_html__('Address Details', 'event_espresso'),
3538
+			[$this, 'attendee_address_details'],
3539
+			$this->_cpt_routes[ $this->_req_action ],
3540
+			'normal',
3541
+			'core'
3542
+		);
3543
+		$this->addMetaBox(
3544
+			'attendee_registrations',
3545
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3546
+			[$this, 'attendee_registrations_meta_box'],
3547
+			$this->_cpt_routes[ $this->_req_action ]
3548
+		);
3549
+	}
3550
+
3551
+
3552
+	/**
3553
+	 * Metabox for attendee contact info
3554
+	 *
3555
+	 * @param WP_Post $post wp post object
3556
+	 * @return void attendee contact info ( and form )
3557
+	 * @throws EE_Error
3558
+	 * @throws InvalidArgumentException
3559
+	 * @throws InvalidDataTypeException
3560
+	 * @throws InvalidInterfaceException
3561
+	 * @throws LogicException
3562
+	 * @throws DomainException
3563
+	 */
3564
+	public function attendee_contact_info($post)
3565
+	{
3566
+		// get attendee object ( should already have it )
3567
+		$form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3568
+		$form->enqueueStylesAndScripts();
3569
+		echo $form->display(); // already escaped
3570
+	}
3571
+
3572
+
3573
+	/**
3574
+	 * Return form handler for the contact details metabox
3575
+	 *
3576
+	 * @param EE_Attendee $attendee
3577
+	 * @return AttendeeContactDetailsMetaboxFormHandler
3578
+	 * @throws DomainException
3579
+	 * @throws InvalidArgumentException
3580
+	 * @throws InvalidDataTypeException
3581
+	 * @throws InvalidInterfaceException
3582
+	 */
3583
+	protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3584
+	{
3585
+		return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3586
+	}
3587
+
3588
+
3589
+	/**
3590
+	 * Metabox for attendee details
3591
+	 *
3592
+	 * @param WP_Post $post wp post object
3593
+	 * @throws EE_Error
3594
+	 * @throws ReflectionException
3595
+	 */
3596
+	public function attendee_address_details($post)
3597
+	{
3598
+		// get attendee object (should already have it)
3599
+		$this->_template_args['attendee']     = $this->_cpt_model_obj;
3600
+		$this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3601
+			new EE_Question_Form_Input(
3602
+				EE_Question::new_instance(
3603
+					[
3604
+						'QST_ID'           => 0,
3605
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3606
+						'QST_system'       => 'admin-state',
3607
+					]
3608
+				),
3609
+				EE_Answer::new_instance(
3610
+					[
3611
+						'ANS_ID'    => 0,
3612
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3613
+					]
3614
+				),
3615
+				[
3616
+					'input_id'       => 'STA_ID',
3617
+					'input_name'     => 'STA_ID',
3618
+					'input_prefix'   => '',
3619
+					'append_qstn_id' => false,
3620
+				]
3621
+			)
3622
+		);
3623
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3624
+			new EE_Question_Form_Input(
3625
+				EE_Question::new_instance(
3626
+					[
3627
+						'QST_ID'           => 0,
3628
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3629
+						'QST_system'       => 'admin-country',
3630
+					]
3631
+				),
3632
+				EE_Answer::new_instance(
3633
+					[
3634
+						'ANS_ID'    => 0,
3635
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3636
+					]
3637
+				),
3638
+				[
3639
+					'input_id'       => 'CNT_ISO',
3640
+					'input_name'     => 'CNT_ISO',
3641
+					'input_prefix'   => '',
3642
+					'append_qstn_id' => false,
3643
+				]
3644
+			)
3645
+		);
3646
+		$template = REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3647
+		EEH_Template::display_template($template, $this->_template_args);
3648
+	}
3649
+
3650
+
3651
+	/**
3652
+	 * _attendee_details
3653
+	 *
3654
+	 * @param $post
3655
+	 * @return void
3656
+	 * @throws DomainException
3657
+	 * @throws EE_Error
3658
+	 * @throws InvalidArgumentException
3659
+	 * @throws InvalidDataTypeException
3660
+	 * @throws InvalidInterfaceException
3661
+	 * @throws ReflectionException
3662
+	 */
3663
+	public function attendee_registrations_meta_box($post)
3664
+	{
3665
+		$this->_template_args['attendee']      = $this->_cpt_model_obj;
3666
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3667
+		$template = REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3668
+		EEH_Template::display_template($template, $this->_template_args);
3669
+	}
3670
+
3671
+
3672
+	/**
3673
+	 * add in the form fields for the attendee edit
3674
+	 *
3675
+	 * @param WP_Post $post wp post object
3676
+	 * @return void echos html for new form.
3677
+	 * @throws DomainException
3678
+	 */
3679
+	public function after_title_form_fields($post)
3680
+	{
3681
+		if ($post->post_type === 'espresso_attendees') {
3682
+			$template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3683
+			$template_args['attendee'] = $this->_cpt_model_obj;
3684
+			EEH_Template::display_template($template, $template_args);
3685
+		}
3686
+	}
3687
+
3688
+
3689
+	/**
3690
+	 * _trash_or_restore_attendee
3691
+	 *
3692
+	 * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3693
+	 * @return void
3694
+	 * @throws EE_Error
3695
+	 * @throws InvalidArgumentException
3696
+	 * @throws InvalidDataTypeException
3697
+	 * @throws InvalidInterfaceException
3698
+	 */
3699
+	protected function _trash_or_restore_attendees($trash = true)
3700
+	{
3701
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3702
+		$status = $trash ? 'trash' : 'publish';
3703
+		// Checkboxes
3704
+		if ($this->request->requestParamIsSet('checkbox')) {
3705
+			$ATT_IDs = $this->request->getRequestParam('checkbox', [], 'int', true);
3706
+			// if array has more than one element than success message should be plural
3707
+			$success = count($ATT_IDs) > 1 ? 2 : 1;
3708
+			// cycle thru checkboxes
3709
+			foreach ($ATT_IDs as $ATT_ID) {
3710
+				$updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3711
+				if (! $updated) {
3712
+					$success = 0;
3713
+				}
3714
+			}
3715
+		} else {
3716
+			// grab single id and delete
3717
+			$ATT_ID = $this->request->getRequestParam('ATT_ID', 0, 'int');
3718
+			// update attendee
3719
+			$success = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID) ? 1 : 0;
3720
+		}
3721
+		$what        = $success > 1
3722
+			? esc_html__('Contacts', 'event_espresso')
3723
+			: esc_html__('Contact', 'event_espresso');
3724
+		$action_desc = $trash
3725
+			? esc_html__('moved to the trash', 'event_espresso')
3726
+			: esc_html__('restored', 'event_espresso');
3727
+		$this->_redirect_after_action($success, $what, $action_desc, ['action' => 'contact_list']);
3728
+	}
3729 3729
 }
Please login to merge, or discard this patch.
Spacing   +103 added lines, -103 removed lines patch added patch discarded remove patch
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
      */
93 93
     protected function getRegistrationModel()
94 94
     {
95
-        if (! $this->registration_model instanceof EEM_Registration) {
95
+        if ( ! $this->registration_model instanceof EEM_Registration) {
96 96
             $this->registration_model = $this->loader->getShared('EEM_Registration');
97 97
         }
98 98
         return $this->registration_model;
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
      */
109 109
     protected function getAttendeeModel()
110 110
     {
111
-        if (! $this->attendee_model instanceof EEM_Attendee) {
111
+        if ( ! $this->attendee_model instanceof EEM_Attendee) {
112 112
             $this->attendee_model = $this->loader->getShared('EEM_Attendee');
113 113
         }
114 114
         return $this->attendee_model;
@@ -124,7 +124,7 @@  discard block
 block discarded – undo
124 124
      */
125 125
     protected function getEventModel()
126 126
     {
127
-        if (! $this->event_model instanceof EEM_Event) {
127
+        if ( ! $this->event_model instanceof EEM_Event) {
128 128
             $this->event_model = $this->loader->getShared('EEM_Event');
129 129
         }
130 130
         return $this->event_model;
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
      */
141 141
     protected function getStatusModel()
142 142
     {
143
-        if (! $this->status_model instanceof EEM_Status) {
143
+        if ( ! $this->status_model instanceof EEM_Status) {
144 144
             $this->status_model = $this->loader->getShared('EEM_Status');
145 145
         }
146 146
         return $this->status_model;
@@ -759,7 +759,7 @@  discard block
 block discarded – undo
759 759
         // style
760 760
         wp_register_style(
761 761
             'espresso_reg',
762
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
762
+            REG_ASSETS_URL.'espresso_registrations_admin.css',
763 763
             ['ee-admin-css'],
764 764
             EVENT_ESPRESSO_VERSION
765 765
         );
@@ -767,7 +767,7 @@  discard block
 block discarded – undo
767 767
         // script
768 768
         wp_register_script(
769 769
             'espresso_reg',
770
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
770
+            REG_ASSETS_URL.'espresso_registrations_admin.js',
771 771
             ['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
772 772
             EVENT_ESPRESSO_VERSION,
773 773
             true
@@ -791,7 +791,7 @@  discard block
 block discarded – undo
791 791
             'att_publish_text' => sprintf(
792 792
             /* translators: The date and time */
793 793
                 wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
794
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
794
+                '<b>'.$this->_cpt_model_obj->get_datetime('ATT_created').'</b>'
795 795
             ),
796 796
         ];
797 797
         wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
@@ -822,7 +822,7 @@  discard block
 block discarded – undo
822 822
         wp_dequeue_style('espresso_reg');
823 823
         wp_register_style(
824 824
             'espresso_att',
825
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
825
+            REG_ASSETS_URL.'espresso_attendees_admin.css',
826 826
             ['ee-admin-css'],
827 827
             EVENT_ESPRESSO_VERSION
828 828
         );
@@ -834,7 +834,7 @@  discard block
 block discarded – undo
834 834
     {
835 835
         wp_register_script(
836 836
             'ee-spco-for-admin',
837
-            REG_ASSETS_URL . 'spco_for_admin.js',
837
+            REG_ASSETS_URL.'spco_for_admin.js',
838 838
             ['underscore', 'jquery'],
839 839
             EVENT_ESPRESSO_VERSION,
840 840
             true
@@ -882,7 +882,7 @@  discard block
 block discarded – undo
882 882
             'no_approve_registrations' => 'not_approved_registration',
883 883
             'cancel_registrations'     => 'cancelled_registration',
884 884
         ];
885
-        $can_send    = EE_Registry::instance()->CAP->current_user_can(
885
+        $can_send = EE_Registry::instance()->CAP->current_user_can(
886 886
             'ee_send_message',
887 887
             'batch_send_messages'
888 888
         );
@@ -987,7 +987,7 @@  discard block
 block discarded – undo
987 987
                     'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
988 988
                 ],
989 989
             ];
990
-            $this->_views['trash']      = [
990
+            $this->_views['trash'] = [
991 991
                 'slug'        => 'trash',
992 992
                 'label'       => esc_html__('Trash', 'event_espresso'),
993 993
                 'count'       => 0,
@@ -1087,7 +1087,7 @@  discard block
 block discarded – undo
1087 1087
         }
1088 1088
         $sc_items = [
1089 1089
             'approved_status'   => [
1090
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_approved,
1090
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Registration::status_id_approved,
1091 1091
                 'desc'  => EEH_Template::pretty_status(
1092 1092
                     EEM_Registration::status_id_approved,
1093 1093
                     false,
@@ -1095,7 +1095,7 @@  discard block
 block discarded – undo
1095 1095
                 ),
1096 1096
             ],
1097 1097
             'pending_status'    => [
1098
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_pending_payment,
1098
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Registration::status_id_pending_payment,
1099 1099
                 'desc'  => EEH_Template::pretty_status(
1100 1100
                     EEM_Registration::status_id_pending_payment,
1101 1101
                     false,
@@ -1103,7 +1103,7 @@  discard block
 block discarded – undo
1103 1103
                 ),
1104 1104
             ],
1105 1105
             'wait_list'         => [
1106
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_wait_list,
1106
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Registration::status_id_wait_list,
1107 1107
                 'desc'  => EEH_Template::pretty_status(
1108 1108
                     EEM_Registration::status_id_wait_list,
1109 1109
                     false,
@@ -1111,7 +1111,7 @@  discard block
 block discarded – undo
1111 1111
                 ),
1112 1112
             ],
1113 1113
             'incomplete_status' => [
1114
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_incomplete,
1114
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Registration::status_id_incomplete,
1115 1115
                 'desc'  => EEH_Template::pretty_status(
1116 1116
                     EEM_Registration::status_id_incomplete,
1117 1117
                     false,
@@ -1119,7 +1119,7 @@  discard block
 block discarded – undo
1119 1119
                 ),
1120 1120
             ],
1121 1121
             'not_approved'      => [
1122
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_not_approved,
1122
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Registration::status_id_not_approved,
1123 1123
                 'desc'  => EEH_Template::pretty_status(
1124 1124
                     EEM_Registration::status_id_not_approved,
1125 1125
                     false,
@@ -1127,7 +1127,7 @@  discard block
 block discarded – undo
1127 1127
                 ),
1128 1128
             ],
1129 1129
             'declined_status'   => [
1130
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_declined,
1130
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Registration::status_id_declined,
1131 1131
                 'desc'  => EEH_Template::pretty_status(
1132 1132
                     EEM_Registration::status_id_declined,
1133 1133
                     false,
@@ -1135,7 +1135,7 @@  discard block
 block discarded – undo
1135 1135
                 ),
1136 1136
             ],
1137 1137
             'cancelled_status'  => [
1138
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Registration::status_id_cancelled,
1138
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Registration::status_id_cancelled,
1139 1139
                 'desc'  => EEH_Template::pretty_status(
1140 1140
                     EEM_Registration::status_id_cancelled,
1141 1141
                     false,
@@ -1195,7 +1195,7 @@  discard block
 block discarded – undo
1195 1195
                 $EVT_ID
1196 1196
             )
1197 1197
         ) {
1198
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1198
+            $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
1199 1199
                 'new_registration',
1200 1200
                 'add-registrant',
1201 1201
                 ['event_id' => $EVT_ID],
@@ -1353,7 +1353,7 @@  discard block
 block discarded – undo
1353 1353
                 ],
1354 1354
                 REG_ADMIN_URL
1355 1355
             );
1356
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1356
+            $this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1357 1357
                 [
1358 1358
                     'action' => 'default',
1359 1359
                     'EVT_ID' => $event_id,
@@ -1361,7 +1361,7 @@  discard block
 block discarded – undo
1361 1361
                 ],
1362 1362
                 admin_url('admin.php')
1363 1363
             );
1364
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1364
+            $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1365 1365
                 [
1366 1366
                     'page'   => 'espresso_events',
1367 1367
                     'action' => 'edit',
@@ -1370,12 +1370,12 @@  discard block
 block discarded – undo
1370 1370
                 admin_url('admin.php')
1371 1371
             );
1372 1372
             // next and previous links
1373
-            $next_reg                                      = $this->_registration->next(
1373
+            $next_reg = $this->_registration->next(
1374 1374
                 null,
1375 1375
                 [],
1376 1376
                 'REG_ID'
1377 1377
             );
1378
-            $this->_template_args['next_registration']     = $next_reg
1378
+            $this->_template_args['next_registration'] = $next_reg
1379 1379
                 ? $this->_next_link(
1380 1380
                     EE_Admin_Page::add_query_args_and_nonce(
1381 1381
                         [
@@ -1387,7 +1387,7 @@  discard block
 block discarded – undo
1387 1387
                     'dashicons dashicons-arrow-right ee-icon-size-22'
1388 1388
                 )
1389 1389
                 : '';
1390
-            $previous_reg                                  = $this->_registration->previous(
1390
+            $previous_reg = $this->_registration->previous(
1391 1391
                 null,
1392 1392
                 [],
1393 1393
                 'REG_ID'
@@ -1405,7 +1405,7 @@  discard block
 block discarded – undo
1405 1405
                 )
1406 1406
                 : '';
1407 1407
             // grab header
1408
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1408
+            $template_path                             = REG_TEMPLATE_PATH.'reg_admin_details_header.template.php';
1409 1409
             $this->_template_args['REG_ID']            = $this->_registration->ID();
1410 1410
             $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1411 1411
                 $template_path,
@@ -1442,7 +1442,7 @@  discard block
 block discarded – undo
1442 1442
         );
1443 1443
         $this->addMetaBox(
1444 1444
             'edit-reg-details-mbox',
1445
-            '<span>' . esc_html__('Registration Details', 'event_espresso')
1445
+            '<span>'.esc_html__('Registration Details', 'event_espresso')
1446 1446
             . '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1447 1447
             [$this, '_reg_details_meta_box'],
1448 1448
             $this->_wp_page_slug
@@ -1552,7 +1552,7 @@  discard block
 block discarded – undo
1552 1552
                                 EEH_HTML::strong(
1553 1553
                                     $this->_registration->pretty_status(),
1554 1554
                                     '',
1555
-                                    'status-' . $this->_registration->status_ID(),
1555
+                                    'status-'.$this->_registration->status_ID(),
1556 1556
                                     'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1557 1557
                                 )
1558 1558
                             )
@@ -1568,7 +1568,7 @@  discard block
 block discarded – undo
1568 1568
                 $this->_registration->ID()
1569 1569
             )
1570 1570
         ) {
1571
-            $reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1571
+            $reg_status_change_form_array['subsections']['reg_status'] = new EE_Select_Input(
1572 1572
                 $this->_get_reg_statuses(),
1573 1573
                 [
1574 1574
                     'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
@@ -1585,7 +1585,7 @@  discard block
 block discarded – undo
1585 1585
                     ),
1586 1586
                 ]
1587 1587
             );
1588
-            $reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1588
+            $reg_status_change_form_array['subsections']['submit'] = new EE_Submit_Input(
1589 1589
                 [
1590 1590
                     'html_class'      => 'button--primary',
1591 1591
                     'html_label_text' => '&nbsp;',
@@ -1610,7 +1610,7 @@  discard block
 block discarded – undo
1610 1610
     protected function _get_reg_statuses()
1611 1611
     {
1612 1612
         $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1613
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1613
+        unset($reg_status_array[EEM_Registration::status_id_incomplete]);
1614 1614
         // get current reg status
1615 1615
         $current_status = $this->_registration->status_ID();
1616 1616
         // is registration for free event? This will determine whether to display the pending payment option
@@ -1618,7 +1618,7 @@  discard block
 block discarded – undo
1618 1618
             $current_status !== EEM_Registration::status_id_pending_payment
1619 1619
             && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1620 1620
         ) {
1621
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1621
+            unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1622 1622
         }
1623 1623
         return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1624 1624
     }
@@ -1709,7 +1709,7 @@  discard block
 block discarded – undo
1709 1709
         $success = false;
1710 1710
         // typecast $REG_IDs
1711 1711
         $REG_IDs = (array) $REG_IDs;
1712
-        if (! empty($REG_IDs)) {
1712
+        if ( ! empty($REG_IDs)) {
1713 1713
             $success = true;
1714 1714
             // set default status if none is passed
1715 1715
             $status         = $status ?: EEM_Registration::status_id_pending_payment;
@@ -1869,7 +1869,7 @@  discard block
 block discarded – undo
1869 1869
             $action,
1870 1870
             $notify
1871 1871
         );
1872
-        $method = $action . '_registration';
1872
+        $method = $action.'_registration';
1873 1873
         if (method_exists($this, $method)) {
1874 1874
             $this->$method($notify);
1875 1875
         }
@@ -2019,7 +2019,7 @@  discard block
 block discarded – undo
2019 2019
         $filters        = new EE_Line_Item_Filter_Collection();
2020 2020
         $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2021 2021
         $filters->add(new EE_Non_Zero_Line_Item_Filter());
2022
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2022
+        $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
2023 2023
             $filters,
2024 2024
             $transaction->total_line_item()
2025 2025
         );
@@ -2032,7 +2032,7 @@  discard block
 block discarded – undo
2032 2032
             $filtered_line_item_tree,
2033 2033
             ['EE_Registration' => $this->_registration]
2034 2034
         );
2035
-        $attendee                                = $this->_registration->attendee();
2035
+        $attendee = $this->_registration->attendee();
2036 2036
         if (
2037 2037
             EE_Registry::instance()->CAP->current_user_can(
2038 2038
                 'ee_read_transaction',
@@ -2114,7 +2114,7 @@  discard block
 block discarded – undo
2114 2114
                 'Payment method response',
2115 2115
                 'event_espresso'
2116 2116
             );
2117
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2117
+            $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2118 2118
         }
2119 2119
         $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2120 2120
         $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
@@ -2145,7 +2145,7 @@  discard block
 block discarded – undo
2145 2145
         $this->_template_args['REG_ID'] = $this->_registration->ID();
2146 2146
         $this->_template_args['event_id'] = $this->_registration->event_ID();
2147 2147
 
2148
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2148
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_details.template.php';
2149 2149
         EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2150 2150
     }
2151 2151
 
@@ -2184,7 +2184,7 @@  discard block
 block discarded – undo
2184 2184
 
2185 2185
             $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2186 2186
             $this->_template_args['REG_ID'] = $this->_registration->ID();
2187
-            $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2187
+            $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_questions.template.php';
2188 2188
             EEH_Template::display_template($template_path, $this->_template_args);
2189 2189
         }
2190 2190
     }
@@ -2200,7 +2200,7 @@  discard block
 block discarded – undo
2200 2200
     public function form_before_question_group($output)
2201 2201
     {
2202 2202
         EE_Error::doing_it_wrong(
2203
-            __CLASS__ . '::' . __FUNCTION__,
2203
+            __CLASS__.'::'.__FUNCTION__,
2204 2204
             esc_html__(
2205 2205
                 '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.',
2206 2206
                 'event_espresso'
@@ -2224,7 +2224,7 @@  discard block
 block discarded – undo
2224 2224
     public function form_after_question_group($output)
2225 2225
     {
2226 2226
         EE_Error::doing_it_wrong(
2227
-            __CLASS__ . '::' . __FUNCTION__,
2227
+            __CLASS__.'::'.__FUNCTION__,
2228 2228
             esc_html__(
2229 2229
                 '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.',
2230 2230
                 'event_espresso'
@@ -2261,7 +2261,7 @@  discard block
 block discarded – undo
2261 2261
     public function form_form_field_label_wrap($label)
2262 2262
     {
2263 2263
         EE_Error::doing_it_wrong(
2264
-            __CLASS__ . '::' . __FUNCTION__,
2264
+            __CLASS__.'::'.__FUNCTION__,
2265 2265
             esc_html__(
2266 2266
                 '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.',
2267 2267
                 'event_espresso'
@@ -2271,7 +2271,7 @@  discard block
 block discarded – undo
2271 2271
         return '
2272 2272
 			<tr>
2273 2273
 				<th>
2274
-					' . $label . '
2274
+					' . $label.'
2275 2275
 				</th>';
2276 2276
     }
2277 2277
 
@@ -2286,7 +2286,7 @@  discard block
 block discarded – undo
2286 2286
     public function form_form_field_input__wrap($input)
2287 2287
     {
2288 2288
         EE_Error::doing_it_wrong(
2289
-            __CLASS__ . '::' . __FUNCTION__,
2289
+            __CLASS__.'::'.__FUNCTION__,
2290 2290
             esc_html__(
2291 2291
                 '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.',
2292 2292
                 'event_espresso'
@@ -2295,7 +2295,7 @@  discard block
 block discarded – undo
2295 2295
         );
2296 2296
         return '
2297 2297
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2298
-					' . $input . '
2298
+					' . $input.'
2299 2299
 				</td>
2300 2300
 			</tr>';
2301 2301
     }
@@ -2344,8 +2344,8 @@  discard block
 block discarded – undo
2344 2344
      */
2345 2345
     protected function _get_reg_custom_questions_form($REG_ID)
2346 2346
     {
2347
-        if (! $this->_reg_custom_questions_form) {
2348
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2347
+        if ( ! $this->_reg_custom_questions_form) {
2348
+            require_once(REG_ADMIN.'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2349 2349
             $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2350 2350
                 $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2351 2351
             );
@@ -2368,7 +2368,7 @@  discard block
 block discarded – undo
2368 2368
      */
2369 2369
     private function _save_reg_custom_questions_form($REG_ID = 0)
2370 2370
     {
2371
-        if (! $REG_ID) {
2371
+        if ( ! $REG_ID) {
2372 2372
             EE_Error::add_error(
2373 2373
                 esc_html__(
2374 2374
                     'An error occurred. No registration ID was received.',
@@ -2385,7 +2385,7 @@  discard block
 block discarded – undo
2385 2385
         if ($form->is_valid()) {
2386 2386
             foreach ($form->subforms() as $question_group_form) {
2387 2387
                 foreach ($question_group_form->inputs() as $question_id => $input) {
2388
-                    $where_conditions    = [
2388
+                    $where_conditions = [
2389 2389
                         'QST_ID' => $question_id,
2390 2390
                         'REG_ID' => $REG_ID,
2391 2391
                     ];
@@ -2426,7 +2426,7 @@  discard block
 block discarded – undo
2426 2426
         $REG = $this->getRegistrationModel();
2427 2427
         // get all other registrations on this transaction, and cache
2428 2428
         // the attendees for them so we don't have to run another query using force_join
2429
-        $registrations                           = $REG->get_all(
2429
+        $registrations = $REG->get_all(
2430 2430
             [
2431 2431
                 [
2432 2432
                     'TXN_ID' => $this->_registration->transaction_ID(),
@@ -2460,23 +2460,23 @@  discard block
 block discarded – undo
2460 2460
                 $attendee                                                      = $registration->attendee()
2461 2461
                     ? $registration->attendee()
2462 2462
                     : $this->getAttendeeModel()->create_default_object();
2463
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2464
-                $this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2465
-                $this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2466
-                $this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2467
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2468
-                $this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2463
+                $this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2464
+                $this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2465
+                $this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2466
+                $this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2467
+                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2468
+                $this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2469 2469
                     ', ',
2470 2470
                     $attendee->full_address_as_array()
2471 2471
                 );
2472
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2472
+                $this->_template_args['attendees'][$att_nmbr]['att_link'] = self::add_query_args_and_nonce(
2473 2473
                     [
2474 2474
                         'action' => 'edit_attendee',
2475 2475
                         'post'   => $attendee->ID(),
2476 2476
                     ],
2477 2477
                     REG_ADMIN_URL
2478 2478
                 );
2479
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2479
+                $this->_template_args['attendees'][$att_nmbr]['event_name'] =
2480 2480
                     $registration->event_obj() instanceof EE_Event
2481 2481
                         ? $registration->event_obj()->name()
2482 2482
                         : '';
@@ -2484,7 +2484,7 @@  discard block
 block discarded – undo
2484 2484
             }
2485 2485
             $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2486 2486
         }
2487
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2487
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_attendees.template.php';
2488 2488
         EEH_Template::display_template($template_path, $this->_template_args);
2489 2489
     }
2490 2490
 
@@ -2510,11 +2510,11 @@  discard block
 block discarded – undo
2510 2510
         // now let's determine if this is not the primary registration.  If it isn't then we set the
2511 2511
         // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2512 2512
         // primary registration object (that way we know if we need to show create button or not)
2513
-        if (! $this->_registration->is_primary_registrant()) {
2513
+        if ( ! $this->_registration->is_primary_registrant()) {
2514 2514
             $primary_registration = $this->_registration->get_primary_registration();
2515 2515
             $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2516 2516
                 : null;
2517
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2517
+            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2518 2518
                 // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2519 2519
                 // custom attendee object so let's not worry about the primary reg.
2520 2520
                 $primary_registration = null;
@@ -2529,7 +2529,7 @@  discard block
 block discarded – undo
2529 2529
         $this->_template_args['phone']             = $attendee->phone();
2530 2530
         $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2531 2531
         // edit link
2532
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2532
+        $this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(
2533 2533
             [
2534 2534
                 'action' => 'edit_attendee',
2535 2535
                 'post'   => $attendee->ID(),
@@ -2539,7 +2539,7 @@  discard block
 block discarded – undo
2539 2539
         $this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2540 2540
         $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2541 2541
         // create link
2542
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2542
+        $this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2543 2543
             ? EE_Admin_Page::add_query_args_and_nonce(
2544 2544
                 [
2545 2545
                     'action'  => 'duplicate_attendee',
@@ -2549,7 +2549,7 @@  discard block
 block discarded – undo
2549 2549
             ) : '';
2550 2550
         $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2551 2551
         $this->_template_args['att_check'] = $att_check;
2552
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2552
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_side_meta_box_registrant.template.php';
2553 2553
         EEH_Template::display_template($template_path, $this->_template_args);
2554 2554
     }
2555 2555
 
@@ -2593,7 +2593,7 @@  discard block
 block discarded – undo
2593 2593
             /** @var EE_Registration $REG */
2594 2594
             $REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2595 2595
             $payments = $REG->registration_payments();
2596
-            if (! empty($payments)) {
2596
+            if ( ! empty($payments)) {
2597 2597
                 $name           = $REG->attendee() instanceof EE_Attendee
2598 2598
                     ? $REG->attendee()->full_name()
2599 2599
                     : esc_html__('Unknown Attendee', 'event_espresso');
@@ -2657,17 +2657,17 @@  discard block
 block discarded – undo
2657 2657
         // Checkboxes
2658 2658
         $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2659 2659
 
2660
-        if (! empty($REG_IDs)) {
2660
+        if ( ! empty($REG_IDs)) {
2661 2661
             // if array has more than one element than success message should be plural
2662 2662
             $success = count($REG_IDs) > 1 ? 2 : 1;
2663 2663
             // cycle thru checkboxes
2664 2664
             foreach ($REG_IDs as $REG_ID) {
2665 2665
                 $REG = $REG_MDL->get_one_by_ID($REG_ID);
2666
-                if (! $REG instanceof EE_Registration) {
2666
+                if ( ! $REG instanceof EE_Registration) {
2667 2667
                     continue;
2668 2668
                 }
2669 2669
                 $deleted = $this->_delete_registration($REG);
2670
-                if (! $deleted) {
2670
+                if ( ! $deleted) {
2671 2671
                     $success = 0;
2672 2672
                 }
2673 2673
             }
@@ -2704,7 +2704,7 @@  discard block
 block discarded – undo
2704 2704
         // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2705 2705
         // registrations on the transaction that are NOT trashed.
2706 2706
         $TXN = $REG->get_first_related('Transaction');
2707
-        if (! $TXN instanceof EE_Transaction) {
2707
+        if ( ! $TXN instanceof EE_Transaction) {
2708 2708
             EE_Error::add_error(
2709 2709
                 sprintf(
2710 2710
                     esc_html__(
@@ -2722,11 +2722,11 @@  discard block
 block discarded – undo
2722 2722
         $REGS        = $TXN->get_many_related('Registration');
2723 2723
         $all_trashed = true;
2724 2724
         foreach ($REGS as $registration) {
2725
-            if (! $registration->get('REG_deleted')) {
2725
+            if ( ! $registration->get('REG_deleted')) {
2726 2726
                 $all_trashed = false;
2727 2727
             }
2728 2728
         }
2729
-        if (! $all_trashed) {
2729
+        if ( ! $all_trashed) {
2730 2730
             EE_Error::add_error(
2731 2731
                 esc_html__(
2732 2732
                     '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.',
@@ -2788,7 +2788,7 @@  discard block
 block discarded – undo
2788 2788
      */
2789 2789
     public function new_registration()
2790 2790
     {
2791
-        if (! $this->_set_reg_event()) {
2791
+        if ( ! $this->_set_reg_event()) {
2792 2792
             throw new EE_Error(
2793 2793
                 esc_html__(
2794 2794
                     'Unable to continue with registering because there is no Event ID in the request',
@@ -2820,7 +2820,7 @@  discard block
 block discarded – undo
2820 2820
                 ],
2821 2821
                 EVENTS_ADMIN_URL
2822 2822
             );
2823
-            $edit_event_lnk                     = '<a href="'
2823
+            $edit_event_lnk = '<a href="'
2824 2824
                                                   . $edit_event_url
2825 2825
                                                   . '" title="'
2826 2826
                                                   . esc_attr__('Edit ', 'event_espresso')
@@ -2837,7 +2837,7 @@  discard block
 block discarded – undo
2837 2837
             $this->_return_json();
2838 2838
         }
2839 2839
         // grab header
2840
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2840
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_register_new_attendee.template.php';
2841 2841
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2842 2842
             $template_path,
2843 2843
             $this->_template_args,
@@ -2878,7 +2878,7 @@  discard block
 block discarded – undo
2878 2878
                 '</b>'
2879 2879
             );
2880 2880
             return '
2881
-	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2881
+	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg.'</p></div>
2882 2882
 	<script >
2883 2883
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
2884 2884
 		// after just adding a new registration... we gotta try to put a stop to that !!!
@@ -2945,7 +2945,7 @@  discard block
 block discarded – undo
2945 2945
         // we come back to the process_registration_step route.
2946 2946
         $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2947 2947
         return EEH_Template::display_template(
2948
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2948
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee_step_content.template.php',
2949 2949
             $template_args,
2950 2950
             true
2951 2951
         );
@@ -2968,7 +2968,7 @@  discard block
 block discarded – undo
2968 2968
         }
2969 2969
 
2970 2970
         $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2971
-        if (! $EVT_ID) {
2971
+        if ( ! $EVT_ID) {
2972 2972
             return false;
2973 2973
         }
2974 2974
         $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
@@ -3038,7 +3038,7 @@  discard block
 block discarded – undo
3038 3038
                 }
3039 3039
                 break;
3040 3040
             case 'questions':
3041
-                if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3041
+                if ( ! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3042 3042
                     add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3043 3043
                 }
3044 3044
                 // process registration
@@ -3049,7 +3049,7 @@  discard block
 block discarded – undo
3049 3049
                         $grand_total->save_this_and_descendants_to_txn();
3050 3050
                     }
3051 3051
                 }
3052
-                if (! $transaction instanceof EE_Transaction) {
3052
+                if ( ! $transaction instanceof EE_Transaction) {
3053 3053
                     $query_args = [
3054 3054
                         'action'                  => 'new_registration',
3055 3055
                         'processing_registration' => 2,
@@ -3071,7 +3071,7 @@  discard block
 block discarded – undo
3071 3071
                     return;
3072 3072
                 }
3073 3073
                 // maybe update status, and make sure to save transaction if not done already
3074
-                if (! $transaction->update_status_based_on_total_paid()) {
3074
+                if ( ! $transaction->update_status_based_on_total_paid()) {
3075 3075
                     $transaction->save();
3076 3076
                 }
3077 3077
                 EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
@@ -3153,7 +3153,7 @@  discard block
 block discarded – undo
3153 3153
     public function get_attendees($per_page, $count = false, $trash = false)
3154 3154
     {
3155 3155
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3156
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3156
+        require_once(REG_ADMIN.'EE_Attendee_Contact_List_Table.class.php');
3157 3157
         $orderby = $this->request->getRequestParam('orderby');
3158 3158
         switch ($orderby) {
3159 3159
             case 'ATT_ID':
@@ -3176,7 +3176,7 @@  discard block
 block discarded – undo
3176 3176
         $_where       = [];
3177 3177
         $search_term  = $this->request->getRequestParam('s');
3178 3178
         if ($search_term) {
3179
-            $search_term  = '%' . $search_term . '%';
3179
+            $search_term  = '%'.$search_term.'%';
3180 3180
             $_where['OR'] = [
3181 3181
                 'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3182 3182
                 'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
@@ -3203,7 +3203,7 @@  discard block
 block discarded – undo
3203 3203
             'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3204 3204
             'limit'         => $limit,
3205 3205
         ];
3206
-        if (! $count) {
3206
+        if ( ! $count) {
3207 3207
             $query_args['order_by'] = [$orderby => $sort];
3208 3208
         }
3209 3209
         $query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
@@ -3248,7 +3248,7 @@  discard block
 block discarded – undo
3248 3248
         $EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3249 3249
             ? $this->request->getRequestParam('EVT_ID', 0, 'int')
3250 3250
             : null;
3251
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3251
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3252 3252
             $request_params = $this->request->requestParams();
3253 3253
             wp_redirect(
3254 3254
                 EE_Admin_Page::add_query_args_and_nonce(
@@ -3276,8 +3276,8 @@  discard block
 block discarded – undo
3276 3276
                 'EVT_ID' => $EVT_ID,
3277 3277
             ];
3278 3278
             $this->request->mergeRequestParams($new_request_args);
3279
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3280
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3279
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3280
+                require_once(EE_CLASSES.'EE_Export.class.php');
3281 3281
                 $EE_Export = EE_Export::instance($this->request->requestParams());
3282 3282
                 $EE_Export->export();
3283 3283
             }
@@ -3298,8 +3298,8 @@  discard block
 block discarded – undo
3298 3298
 
3299 3299
     public function _contact_list_export()
3300 3300
     {
3301
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3302
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3301
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3302
+            require_once(EE_CLASSES.'EE_Export.class.php');
3303 3303
             $EE_Export = EE_Export::instance($this->request->requestParams());
3304 3304
             $EE_Export->export_attendees();
3305 3305
         }
@@ -3308,7 +3308,7 @@  discard block
 block discarded – undo
3308 3308
 
3309 3309
     public function _contact_list_report()
3310 3310
     {
3311
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3311
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3312 3312
             wp_redirect(
3313 3313
                 EE_Admin_Page::add_query_args_and_nonce(
3314 3314
                     [
@@ -3320,8 +3320,8 @@  discard block
 block discarded – undo
3320 3320
                 )
3321 3321
             );
3322 3322
         } else {
3323
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3324
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3323
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3324
+                require_once(EE_CLASSES.'EE_Export.class.php');
3325 3325
                 $EE_Export = EE_Export::instance($this->request->requestParams());
3326 3326
                 $EE_Export->report_attendees();
3327 3327
             }
@@ -3348,7 +3348,7 @@  discard block
 block discarded – undo
3348 3348
         $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3349 3349
         $action = $this->request->getRequestParam('return', 'default');
3350 3350
         // verify we have necessary info
3351
-        if (! $REG_ID) {
3351
+        if ( ! $REG_ID) {
3352 3352
             EE_Error::add_error(
3353 3353
                 esc_html__(
3354 3354
                     'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
@@ -3363,7 +3363,7 @@  discard block
 block discarded – undo
3363 3363
         }
3364 3364
         // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3365 3365
         $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3366
-        if (! $registration instanceof EE_Registration) {
3366
+        if ( ! $registration instanceof EE_Registration) {
3367 3367
             throw new RuntimeException(
3368 3368
                 sprintf(
3369 3369
                     esc_html__(
@@ -3502,16 +3502,16 @@  discard block
 block discarded – undo
3502 3502
         $this->verify_cpt_object();
3503 3503
         remove_meta_box(
3504 3504
             'postexcerpt',
3505
-            $this->_cpt_routes[ $this->_req_action ],
3505
+            $this->_cpt_routes[$this->_req_action],
3506 3506
             'normal'
3507 3507
         );
3508
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3508
+        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal');
3509 3509
         if (post_type_supports('espresso_attendees', 'excerpt')) {
3510 3510
             $this->addMetaBox(
3511 3511
                 'postexcerpt',
3512 3512
                 esc_html__('Short Biography', 'event_espresso'),
3513 3513
                 'post_excerpt_meta_box',
3514
-                $this->_cpt_routes[ $this->_req_action ]
3514
+                $this->_cpt_routes[$this->_req_action]
3515 3515
             );
3516 3516
         }
3517 3517
         if (post_type_supports('espresso_attendees', 'comments')) {
@@ -3519,7 +3519,7 @@  discard block
 block discarded – undo
3519 3519
                 'commentsdiv',
3520 3520
                 esc_html__('Notes on the Contact', 'event_espresso'),
3521 3521
                 'post_comment_meta_box',
3522
-                $this->_cpt_routes[ $this->_req_action ],
3522
+                $this->_cpt_routes[$this->_req_action],
3523 3523
                 'normal',
3524 3524
                 'core'
3525 3525
             );
@@ -3528,7 +3528,7 @@  discard block
 block discarded – undo
3528 3528
             'attendee_contact_info',
3529 3529
             esc_html__('Contact Info', 'event_espresso'),
3530 3530
             [$this, 'attendee_contact_info'],
3531
-            $this->_cpt_routes[ $this->_req_action ],
3531
+            $this->_cpt_routes[$this->_req_action],
3532 3532
             'side',
3533 3533
             'core'
3534 3534
         );
@@ -3536,7 +3536,7 @@  discard block
 block discarded – undo
3536 3536
             'attendee_details_address',
3537 3537
             esc_html__('Address Details', 'event_espresso'),
3538 3538
             [$this, 'attendee_address_details'],
3539
-            $this->_cpt_routes[ $this->_req_action ],
3539
+            $this->_cpt_routes[$this->_req_action],
3540 3540
             'normal',
3541 3541
             'core'
3542 3542
         );
@@ -3544,7 +3544,7 @@  discard block
 block discarded – undo
3544 3544
             'attendee_registrations',
3545 3545
             esc_html__('Registrations for this Contact', 'event_espresso'),
3546 3546
             [$this, 'attendee_registrations_meta_box'],
3547
-            $this->_cpt_routes[ $this->_req_action ]
3547
+            $this->_cpt_routes[$this->_req_action]
3548 3548
         );
3549 3549
     }
3550 3550
 
@@ -3643,7 +3643,7 @@  discard block
 block discarded – undo
3643 3643
                 ]
3644 3644
             )
3645 3645
         );
3646
-        $template = REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3646
+        $template = REG_TEMPLATE_PATH.'attendee_address_details_metabox_content.template.php';
3647 3647
         EEH_Template::display_template($template, $this->_template_args);
3648 3648
     }
3649 3649
 
@@ -3664,7 +3664,7 @@  discard block
 block discarded – undo
3664 3664
     {
3665 3665
         $this->_template_args['attendee']      = $this->_cpt_model_obj;
3666 3666
         $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3667
-        $template = REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3667
+        $template = REG_TEMPLATE_PATH.'attendee_registrations_main_meta_box.template.php';
3668 3668
         EEH_Template::display_template($template, $this->_template_args);
3669 3669
     }
3670 3670
 
@@ -3679,7 +3679,7 @@  discard block
 block discarded – undo
3679 3679
     public function after_title_form_fields($post)
3680 3680
     {
3681 3681
         if ($post->post_type === 'espresso_attendees') {
3682
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3682
+            $template                  = REG_TEMPLATE_PATH.'attendee_details_after_title_form_fields.template.php';
3683 3683
             $template_args['attendee'] = $this->_cpt_model_obj;
3684 3684
             EEH_Template::display_template($template, $template_args);
3685 3685
         }
@@ -3708,7 +3708,7 @@  discard block
 block discarded – undo
3708 3708
             // cycle thru checkboxes
3709 3709
             foreach ($ATT_IDs as $ATT_ID) {
3710 3710
                 $updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3711
-                if (! $updated) {
3711
+                if ( ! $updated) {
3712 3712
                     $success = 0;
3713 3713
                 }
3714 3714
             }
Please login to merge, or discard this patch.
templates/reg_admin_details_main_meta_box_attendees.template.php 1 patch
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@  discard block
 block discarded – undo
10 10
 <div id="admin-primary-mbox-dv" class="admin-primary-mbox-dv">
11 11
     <br />
12 12
     <?php echo esc_html($attendee_notice); ?>
13
-    <?php if (! empty($attendees)) : ?>
13
+    <?php if ( ! empty($attendees)) : ?>
14 14
         <div class="admin-primary-mbox-tbl-wrap">
15 15
             <table id="reg-admin-transaction-attendees-table" class="admin-primary-mbox-tbl striped">
16 16
                 <thead>
@@ -30,7 +30,7 @@  discard block
 block discarded – undo
30 30
                         <tr>
31 31
                             <th class='jst-cntr no-pad'>
32 32
                                 <span class="ee-status-dot ee-status-dot--<?php echo esc_attr($attendee['STS_ID']); ?> ee-aria-tooltip"
33
-                                      aria-label="<?php echo esc_attr(EEH_Template::pretty_status($attendee['STS_ID'], false, "sentence" ));?>">
33
+                                      aria-label="<?php echo esc_attr(EEH_Template::pretty_status($attendee['STS_ID'], false, "sentence")); ?>">
34 34
                                 </span>
35 35
                             </th>
36 36
                             <td class="jst-left"><?php echo esc_html($att_nmbr); ?></td>
@@ -40,7 +40,7 @@  discard block
 block discarded – undo
40 40
                                    aria-label="<?php esc_attr_e('View details for this attendee', 'event_espresso'); ?>"
41 41
                                    class="ee-aria-tooltip"
42 42
                                 >
43
-                                    <?php echo esc_html($attendee['fname'] . ' ' . $attendee['lname']); ?>
43
+                                    <?php echo esc_html($attendee['fname'].' '.$attendee['lname']); ?>
44 44
                                 </a>
45 45
                             </td>
46 46
                             <td class="jst-rght">
Please login to merge, or discard this patch.
templates/reg_admin_details_side_meta_box_registrant.template.php 2 patches
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -59,11 +59,11 @@  discard block
 block discarded – undo
59 59
 <?php
60 60
 // only show if logged-in user has access
61 61
 if (
62
-    EE_Registry::instance()->CAP->current_user_can(
63
-        'ee_edit_contact',
64
-        'view_or_edit_contact_button',
65
-        $ATT_ID
66
-    )
62
+	EE_Registry::instance()->CAP->current_user_can(
63
+		'ee_edit_contact',
64
+		'view_or_edit_contact_button',
65
+		$ATT_ID
66
+	)
67 67
 ) : ?>
68 68
     <div class='ee-admin-button-row'>
69 69
         <a class="button button--secondary" href="<?php echo esc_url_raw($att_edit_link); ?>"
@@ -76,9 +76,9 @@  discard block
 block discarded – undo
76 76
     <?php if (! empty($create_link)) : ?>
77 77
         <a class="button button--secondary" href="<?php echo esc_url_raw($create_link); ?>"
78 78
            title="<?php esc_attr_e(
79
-               'This registration shares the contact details for the primary registration in this group.  If you\'d like this registration to have its own details, you can do so by clicking this button',
80
-               'event_espresso'
81
-           ); ?>"
79
+			   'This registration shares the contact details for the primary registration in this group.  If you\'d like this registration to have its own details, you can do so by clicking this button',
80
+			   'event_espresso'
81
+		   ); ?>"
82 82
         >
83 83
             <span class="ee-icon ee-icon-user-add-new"></span>
84 84
             <?php echo esc_html($create_label); ?>
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -14,11 +14,11 @@  discard block
 block discarded – undo
14 14
  */
15 15
 $attendee_full_name = "$fname $lname";
16 16
 $email = sanitize_email($email);
17
-$avatar  = get_avatar_url($email);
17
+$avatar = get_avatar_url($email);
18 18
 ?>
19 19
 
20 20
 <div id='admin-side-mbox-primary-registrant-dv' class='admin-side-mbox-dv'>
21
-    <?php if (! empty($avatar)) : ?>
21
+    <?php if ( ! empty($avatar)) : ?>
22 22
     <div class="ee-admin-attendee-avatar">
23 23
         <img alt="profile pic for <?php echo esc_html($attendee_full_name); ?>" src="<?php echo $avatar; ?>" />
24 24
     </div>
@@ -35,7 +35,7 @@  discard block
 block discarded – undo
35 35
                 </a>
36 36
             </div>
37 37
         </div>
38
-        <?php if (! empty($phone)) : ?>
38
+        <?php if ( ! empty($phone)) : ?>
39 39
             <div class='ee-admin-attendee-phone'>
40 40
                 <div class='ee-admin-contact-details-with-dashicon'>
41 41
                     <span class='dashicons dashicons-phone'></span>
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
                 </div>
46 46
             </div>
47 47
         <?php endif; ?>
48
-        <?php if (! empty($formatted_address)) : ?>
48
+        <?php if ( ! empty($formatted_address)) : ?>
49 49
         <div class='ee-admin-attendee-address'>
50 50
             <div class='ee-admin-contact-details-with-dashicon'>
51 51
                 <span class='dashicons dashicons-location'></span>
@@ -73,7 +73,7 @@  discard block
 block discarded – undo
73 73
             <?php echo esc_html($att_edit_label); ?>
74 74
         </a>
75 75
 
76
-    <?php if (! empty($create_link)) : ?>
76
+    <?php if ( ! empty($create_link)) : ?>
77 77
         <a class="button button--secondary" href="<?php echo esc_url_raw($create_link); ?>"
78 78
            title="<?php esc_attr_e(
79 79
                'This registration shares the contact details for the primary registration in this group.  If you\'d like this registration to have its own details, you can do so by clicking this button',
@@ -86,5 +86,5 @@  discard block
 block discarded – undo
86 86
     <?php endif; ?>
87 87
 
88 88
     </div>
89
-<?php endif;?>
89
+<?php endif; ?>
90 90
 
Please login to merge, or discard this patch.
admin_pages/transactions/Transactions_Admin_Page.core.php 2 patches
Indentation   +2528 added lines, -2528 removed lines patch added patch discarded remove patch
@@ -13,2532 +13,2532 @@
 block discarded – undo
13 13
 class Transactions_Admin_Page extends EE_Admin_Page
14 14
 {
15 15
 
16
-    /**
17
-     * @var EE_Transaction
18
-     */
19
-    private $_transaction;
20
-
21
-    /**
22
-     * @var EE_Session
23
-     */
24
-    private $_session;
25
-
26
-    /**
27
-     * @var array $_txn_status
28
-     */
29
-    private static $_txn_status;
30
-
31
-    /**
32
-     * @var array $_pay_status
33
-     */
34
-    private static $_pay_status;
35
-
36
-    /**
37
-     * @var array $_existing_reg_payment_REG_IDs
38
-     */
39
-    protected $_existing_reg_payment_REG_IDs;
40
-
41
-
42
-    /**
43
-     *    _init_page_props
44
-     *
45
-     * @return void
46
-     */
47
-    protected function _init_page_props()
48
-    {
49
-        $this->page_slug        = TXN_PG_SLUG;
50
-        $this->page_label       = esc_html__('Transactions', 'event_espresso');
51
-        $this->_admin_base_url  = TXN_ADMIN_URL;
52
-        $this->_admin_base_path = TXN_ADMIN;
53
-    }
54
-
55
-
56
-    /**
57
-     *    _ajax_hooks
58
-     *
59
-     * @return void
60
-     */
61
-    protected function _ajax_hooks()
62
-    {
63
-        add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
64
-        add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
65
-        add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
66
-    }
67
-
68
-
69
-    /**
70
-     *    _define_page_props
71
-     *
72
-     * @return void
73
-     */
74
-    protected function _define_page_props()
75
-    {
76
-        $this->_admin_page_title = $this->page_label;
77
-        $this->_labels           = [
78
-            'buttons' => [
79
-                'add'    => esc_html__('Add New Transaction', 'event_espresso'),
80
-                'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
81
-                'delete' => esc_html__('Delete Transaction', 'event_espresso'),
82
-            ],
83
-        ];
84
-    }
85
-
86
-
87
-    /**
88
-     *        grab url requests and route them
89
-     *
90
-     * @access private
91
-     * @return void
92
-     * @throws EE_Error
93
-     * @throws InvalidArgumentException
94
-     * @throws InvalidDataTypeException
95
-     * @throws InvalidInterfaceException
96
-     */
97
-    public function _set_page_routes()
98
-    {
99
-
100
-        $this->_set_transaction_status_array();
101
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
102
-
103
-        $this->_page_routes = [
104
-
105
-            'default' => [
106
-                'func'       => '_transactions_overview_list_table',
107
-                'capability' => 'ee_read_transactions',
108
-            ],
109
-
110
-            'view_transaction' => [
111
-                'func'       => '_transaction_details',
112
-                'capability' => 'ee_read_transaction',
113
-                'obj_id'     => $TXN_ID,
114
-            ],
115
-
116
-            'send_payment_reminder' => [
117
-                'func'       => '_send_payment_reminder',
118
-                'noheader'   => true,
119
-                'capability' => 'ee_send_message',
120
-            ],
121
-
122
-            'espresso_apply_payment' => [
123
-                'func'       => 'apply_payments_or_refunds',
124
-                'noheader'   => true,
125
-                'capability' => 'ee_edit_payments',
126
-            ],
127
-
128
-            'espresso_apply_refund' => [
129
-                'func'       => 'apply_payments_or_refunds',
130
-                'noheader'   => true,
131
-                'capability' => 'ee_edit_payments',
132
-            ],
133
-
134
-            'espresso_delete_payment' => [
135
-                'func'       => 'delete_payment',
136
-                'noheader'   => true,
137
-                'capability' => 'ee_delete_payments',
138
-            ],
139
-
140
-            'espresso_recalculate_line_items' => [
141
-                'func'       => 'recalculateLineItems',
142
-                'noheader'   => true,
143
-                'capability' => 'ee_edit_payments',
144
-            ],
145
-
146
-        ];
147
-    }
148
-
149
-
150
-    protected function _set_page_config()
151
-    {
152
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
153
-        $this->_page_config = [
154
-            'default'          => [
155
-                'nav'           => [
156
-                    'label' => esc_html__('Overview', 'event_espresso'),
157
-                    'order' => 10,
158
-                ],
159
-                'list_table'    => 'EE_Admin_Transactions_List_Table',
160
-                'help_tabs'     => [
161
-                    'transactions_overview_help_tab'                       => [
162
-                        'title'    => esc_html__('Transactions Overview', 'event_espresso'),
163
-                        'filename' => 'transactions_overview',
164
-                    ],
165
-                    'transactions_overview_table_column_headings_help_tab' => [
166
-                        'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
167
-                        'filename' => 'transactions_overview_table_column_headings',
168
-                    ],
169
-                    'transactions_overview_views_filters_help_tab'         => [
170
-                        'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
171
-                        'filename' => 'transactions_overview_views_filters_search',
172
-                    ],
173
-                ],
174
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
175
-                // 'help_tour'     => array('Transactions_Overview_Help_Tour'),
176
-                /**
177
-                 * commented out because currently we are not displaying tips for transaction list table status but this
178
-                 * may change in a later iteration so want to keep the code for then.
179
-                 */
180
-                // 'qtips' => array( 'Transactions_List_Table_Tips' ),
181
-                'require_nonce' => false,
182
-            ],
183
-            'view_transaction' => [
184
-                'nav'       => [
185
-                    'label'      => esc_html__('View Transaction', 'event_espresso'),
186
-                    'order'      => 5,
187
-                    'url'        => $TXN_ID
188
-                        ? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
189
-                        : $this->_admin_base_url,
190
-                    'persistent' => false,
191
-                ],
192
-                'help_tabs' => [
193
-                    'transactions_view_transaction_help_tab'                                              => [
194
-                        'title'    => esc_html__('View Transaction', 'event_espresso'),
195
-                        'filename' => 'transactions_view_transaction',
196
-                    ],
197
-                    'transactions_view_transaction_transaction_details_table_help_tab'                    => [
198
-                        'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
199
-                        'filename' => 'transactions_view_transaction_transaction_details_table',
200
-                    ],
201
-                    'transactions_view_transaction_attendees_registered_help_tab'                         => [
202
-                        'title'    => esc_html__('Attendees Registered', 'event_espresso'),
203
-                        'filename' => 'transactions_view_transaction_attendees_registered',
204
-                    ],
205
-                    'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
206
-                        'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
207
-                        'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
208
-                    ],
209
-                ],
210
-                'qtips'     => ['Transaction_Details_Tips'],
211
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
212
-                // 'help_tour' => array('Transaction_Details_Help_Tour'),
213
-                'metaboxes' => ['_transaction_details_metaboxes'],
214
-
215
-                'require_nonce' => false,
216
-            ],
217
-        ];
218
-    }
219
-
220
-
221
-    /**
222
-     * The below methods aren't used by this class currently
223
-     */
224
-    protected function _add_screen_options()
225
-    {
226
-        // noop
227
-    }
228
-
229
-
230
-    protected function _add_feature_pointers()
231
-    {
232
-        // noop
233
-    }
234
-
235
-
236
-    public function admin_init()
237
-    {
238
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
239
-        $event_name = $this->request->getRequestParam('event_name');
240
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
241
-        // IF a registration was JUST added via the admin...
242
-        if ($EVT_ID && $event_name && $redirect_from) {
243
-            // then set a cookie so that we can block any attempts to use
244
-            // the back button as a way to enter another registration.
245
-            setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
246
-            // and update the global
247
-            $_COOKIE['ee_registration_added'] = $EVT_ID;
248
-        }
249
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
250
-            'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
251
-            'event_espresso'
252
-        );
253
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
254
-            'An error occurred! Please refresh the page and try again.',
255
-            'event_espresso'
256
-        );
257
-        EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
258
-        EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
259
-        EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
260
-        EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
261
-            'This transaction has been overpaid ! Payments Total',
262
-            'event_espresso'
263
-        );
264
-    }
265
-
266
-
267
-    public function admin_notices()
268
-    {
269
-        // noop
270
-    }
271
-
272
-
273
-    public function admin_footer_scripts()
274
-    {
275
-        // noop
276
-    }
277
-
278
-
279
-    /**
280
-     * _set_transaction_status_array
281
-     * sets list of transaction statuses
282
-     *
283
-     * @access private
284
-     * @return void
285
-     * @throws EE_Error
286
-     * @throws InvalidArgumentException
287
-     * @throws InvalidDataTypeException
288
-     * @throws InvalidInterfaceException
289
-     */
290
-    private function _set_transaction_status_array()
291
-    {
292
-        self::$_txn_status = EEM_Transaction::instance()->status_array(true);
293
-    }
294
-
295
-
296
-    /**
297
-     * get_transaction_status_array
298
-     * return the transaction status array for wp_list_table
299
-     *
300
-     * @access public
301
-     * @return array
302
-     */
303
-    public function get_transaction_status_array()
304
-    {
305
-        return self::$_txn_status;
306
-    }
307
-
308
-
309
-    /**
310
-     *    get list of payment statuses
311
-     *
312
-     * @access private
313
-     * @return void
314
-     * @throws EE_Error
315
-     * @throws InvalidArgumentException
316
-     * @throws InvalidDataTypeException
317
-     * @throws InvalidInterfaceException
318
-     */
319
-    private function _get_payment_status_array()
320
-    {
321
-        self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
322
-        $this->_template_args['payment_status'] = self::$_pay_status;
323
-    }
324
-
325
-
326
-    /**
327
-     *    _add_screen_options_default
328
-     *
329
-     * @access protected
330
-     * @return void
331
-     * @throws InvalidArgumentException
332
-     * @throws InvalidDataTypeException
333
-     * @throws InvalidInterfaceException
334
-     */
335
-    protected function _add_screen_options_default()
336
-    {
337
-        $this->_per_page_screen_option();
338
-    }
339
-
340
-
341
-    /**
342
-     * load_scripts_styles
343
-     *
344
-     * @access public
345
-     * @return void
346
-     */
347
-    public function load_scripts_styles()
348
-    {
349
-        // enqueue style
350
-        wp_register_style(
351
-            'espresso_txn',
352
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
353
-            [],
354
-            EVENT_ESPRESSO_VERSION
355
-        );
356
-        wp_enqueue_style('espresso_txn');
357
-        // scripts
358
-        wp_register_script(
359
-            'espresso_txn',
360
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
361
-            [
362
-                'ee_admin_js',
363
-                'ee-datepicker',
364
-                'jquery-ui-datepicker',
365
-                'jquery-ui-draggable',
366
-                'ee-dialog',
367
-                'ee-accounting',
368
-                'ee-serialize-full-array',
369
-            ],
370
-            EVENT_ESPRESSO_VERSION,
371
-            true
372
-        );
373
-        wp_enqueue_script('espresso_txn');
374
-    }
375
-
376
-
377
-    /**
378
-     *    load_scripts_styles_view_transaction
379
-     *
380
-     * @access public
381
-     * @return void
382
-     */
383
-    public function load_scripts_styles_view_transaction()
384
-    {
385
-        // styles
386
-        wp_enqueue_style('espresso-ui-theme');
387
-    }
388
-
389
-
390
-    /**
391
-     *    load_scripts_styles_default
392
-     *
393
-     * @access public
394
-     * @return void
395
-     */
396
-    public function load_scripts_styles_default()
397
-    {
398
-        // styles
399
-        wp_enqueue_style('espresso-ui-theme');
400
-    }
401
-
402
-
403
-    /**
404
-     *    _set_list_table_views_default
405
-     *
406
-     * @access protected
407
-     * @return void
408
-     */
409
-    protected function _set_list_table_views_default()
410
-    {
411
-        $this->_views = [
412
-            'all'        => [
413
-                'slug'  => 'all',
414
-                'label' => esc_html__('View All Transactions', 'event_espresso'),
415
-                'count' => 0,
416
-            ],
417
-            'abandoned'  => [
418
-                'slug'  => 'abandoned',
419
-                'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
420
-                'count' => 0,
421
-            ],
422
-            'incomplete' => [
423
-                'slug'  => 'incomplete',
424
-                'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
425
-                'count' => 0,
426
-            ],
427
-        ];
428
-        if (
429
-            /**
430
-             * Filters whether a link to the "Failed Transactions" list table
431
-             * appears on the Transactions Admin Page list table.
432
-             * List display can be turned back on via the following:
433
-             * add_filter(
434
-             *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
435
-             *     '__return_true'
436
-             * );
437
-             *
438
-             * @param boolean                 $display_failed_txns_list
439
-             * @param Transactions_Admin_Page $this
440
-             * @since 4.9.70.p
441
-             */
442
-            apply_filters(
443
-                'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
444
-                false,
445
-                $this
446
-            )
447
-        ) {
448
-            $this->_views['failed'] = [
449
-                'slug'  => 'failed',
450
-                'label' => esc_html__('Failed Transactions', 'event_espresso'),
451
-                'count' => 0,
452
-            ];
453
-        }
454
-    }
455
-
456
-
457
-    /**
458
-     * _set_transaction_object
459
-     * This sets the _transaction property for the transaction details screen
460
-     *
461
-     * @access private
462
-     * @return void
463
-     * @throws EE_Error
464
-     * @throws InvalidArgumentException
465
-     * @throws RuntimeException
466
-     * @throws InvalidDataTypeException
467
-     * @throws InvalidInterfaceException
468
-     * @throws ReflectionException
469
-     */
470
-    private function _set_transaction_object()
471
-    {
472
-        if ($this->_transaction instanceof EE_Transaction) {
473
-            return;
474
-        } //get out we've already set the object
475
-
476
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
477
-
478
-        // get transaction object
479
-        $this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
480
-        $this->_session     = $this->_transaction instanceof EE_Transaction
481
-            ? $this->_transaction->session_data()
482
-            : null;
483
-        if ($this->_transaction instanceof EE_Transaction) {
484
-            $this->_transaction->verify_abandoned_transaction_status();
485
-        }
486
-
487
-        if (! $this->_transaction instanceof EE_Transaction) {
488
-            $error_msg = sprintf(
489
-                esc_html__(
490
-                    'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
491
-                    'event_espresso'
492
-                ),
493
-                $TXN_ID
494
-            );
495
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
496
-        }
497
-    }
498
-
499
-
500
-    /**
501
-     *    _transaction_legend_items
502
-     *
503
-     * @access protected
504
-     * @return array
505
-     * @throws EE_Error
506
-     * @throws InvalidArgumentException
507
-     * @throws ReflectionException
508
-     * @throws InvalidDataTypeException
509
-     * @throws InvalidInterfaceException
510
-     */
511
-    protected function _transaction_legend_items()
512
-    {
513
-        EE_Registry::instance()->load_helper('MSG_Template');
514
-        $items = [];
515
-
516
-        if (
517
-            EE_Registry::instance()->CAP->current_user_can(
518
-                'ee_read_global_messages',
519
-                'view_filtered_messages'
520
-            )
521
-        ) {
522
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
523
-            if (
524
-                is_array($related_for_icon)
525
-                && isset($related_for_icon['css_class'], $related_for_icon['label'])
526
-            ) {
527
-                $items['view_related_messages'] = [
528
-                    'class' => $related_for_icon['css_class'],
529
-                    'desc'  => $related_for_icon['label'],
530
-                ];
531
-            }
532
-        }
533
-
534
-        $items = apply_filters(
535
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
536
-            array_merge(
537
-                $items,
538
-                [
539
-                    'view_details'          => [
540
-                        'class' => 'dashicons dashicons-cart',
541
-                        'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
542
-                    ],
543
-                    'view_invoice'          => [
544
-                        'class' => 'dashicons dashicons-media-spreadsheet',
545
-                        'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
546
-                    ],
547
-                    'view_receipt'          => [
548
-                        'class' => 'dashicons dashicons-media-default',
549
-                        'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
550
-                    ],
551
-                    'view_registration'     => [
552
-                        'class' => 'dashicons dashicons-clipboard',
553
-                        'desc'  => esc_html__('View Registration Details', 'event_espresso'),
554
-                    ],
555
-                    'payment_overview_link' => [
556
-                        'class' => 'dashicons dashicons-money',
557
-                        'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
558
-                    ],
559
-                ]
560
-            )
561
-        );
562
-
563
-        if (
564
-            EEH_MSG_Template::is_mt_active('payment_reminder')
565
-            && EE_Registry::instance()->CAP->current_user_can(
566
-                'ee_send_message',
567
-                'espresso_transactions_send_payment_reminder'
568
-            )
569
-        ) {
570
-            $items['send_payment_reminder'] = [
571
-                'class' => 'dashicons dashicons-email-alt',
572
-                'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
573
-            ];
574
-        } else {
575
-            $items['blank*'] = [
576
-                'class' => '',
577
-                'desc'  => '',
578
-            ];
579
-        }
580
-        $more_items = apply_filters(
581
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
582
-            [
583
-                'overpaid'   => [
584
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::overpaid_status_code,
585
-                    'desc'  => EEH_Template::pretty_status(
586
-                        EEM_Transaction::overpaid_status_code,
587
-                        false,
588
-                        'sentence'
589
-                    ),
590
-                ],
591
-                'complete'   => [
592
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::complete_status_code,
593
-                    'desc'  => EEH_Template::pretty_status(
594
-                        EEM_Transaction::complete_status_code,
595
-                        false,
596
-                        'sentence'
597
-                    ),
598
-                ],
599
-                'incomplete' => [
600
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::incomplete_status_code,
601
-                    'desc'  => EEH_Template::pretty_status(
602
-                        EEM_Transaction::incomplete_status_code,
603
-                        false,
604
-                        'sentence'
605
-                    ),
606
-                ],
607
-                'abandoned'  => [
608
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::abandoned_status_code,
609
-                    'desc'  => EEH_Template::pretty_status(
610
-                        EEM_Transaction::abandoned_status_code,
611
-                        false,
612
-                        'sentence'
613
-                    ),
614
-                ],
615
-                'failed'     => [
616
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::failed_status_code,
617
-                    'desc'  => EEH_Template::pretty_status(
618
-                        EEM_Transaction::failed_status_code,
619
-                        false,
620
-                        'sentence'
621
-                    ),
622
-                ],
623
-            ]
624
-        );
625
-
626
-        return array_merge($items, $more_items);
627
-    }
628
-
629
-
630
-    /**
631
-     *    _transactions_overview_list_table
632
-     *
633
-     * @access protected
634
-     * @return void
635
-     * @throws DomainException
636
-     * @throws EE_Error
637
-     * @throws InvalidArgumentException
638
-     * @throws InvalidDataTypeException
639
-     * @throws InvalidInterfaceException
640
-     * @throws ReflectionException
641
-     */
642
-    protected function _transactions_overview_list_table()
643
-    {
644
-        $this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
645
-
646
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
647
-        $event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
648
-        $this->_template_args['admin_page_header'] = $event instanceof EE_Event
649
-            ? sprintf(
650
-                esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
651
-                '<h3>',
652
-                '<a href="'
653
-                . EE_Admin_Page::add_query_args_and_nonce(
654
-                    ['action' => 'edit', 'post' => $event->ID()],
655
-                    EVENTS_ADMIN_URL
656
-                )
657
-                . '" title="'
658
-                . esc_attr__('Click to Edit event', 'event_espresso')
659
-                . '">' . $event->name() . '</a>',
660
-                '</h3>'
661
-            )
662
-            : '';
663
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
664
-        $this->display_admin_list_table_page_with_no_sidebar();
665
-    }
666
-
667
-
668
-    /**
669
-     *    _transaction_details
670
-     * generates HTML for the View Transaction Details Admin page
671
-     *
672
-     * @access protected
673
-     * @return void
674
-     * @throws DomainException
675
-     * @throws EE_Error
676
-     * @throws InvalidArgumentException
677
-     * @throws InvalidDataTypeException
678
-     * @throws InvalidInterfaceException
679
-     * @throws RuntimeException
680
-     * @throws ReflectionException
681
-     */
682
-    protected function _transaction_details()
683
-    {
684
-        do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
685
-
686
-        $this->_set_transaction_status_array();
687
-
688
-        $this->_template_args                      = [];
689
-        $this->_template_args['transactions_page'] = $this->_wp_page_slug;
690
-
691
-        $this->_set_transaction_object();
692
-
693
-        if (! $this->_transaction instanceof EE_Transaction) {
694
-            return;
695
-        }
696
-
697
-        $this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
698
-        $this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
699
-
700
-        $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
701
-        $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
702
-
703
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
704
-        $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
705
-        $this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->status_ID();
706
-
707
-        $this->_template_args['grand_total'] = $this->_transaction->total();
708
-        $this->_template_args['total_paid']  = $this->_transaction->paid();
709
-
710
-        $amount_due                         = $this->_transaction->total() - $this->_transaction->paid();
711
-        $this->_template_args['amount_due'] = EEH_Template::format_currency(
712
-            $amount_due,
713
-            true
714
-        );
715
-        if (EE_Registry::instance()->CFG->currency->sign_b4) {
716
-            $this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign
717
-                                                  . $this->_template_args['amount_due'];
718
-        } else {
719
-            $this->_template_args['amount_due'] .= EE_Registry::instance()->CFG->currency->sign;
720
-        }
721
-        $this->_template_args['amount_due_class'] = '';
722
-
723
-        if ($this->_transaction->paid() === $this->_transaction->total()) {
724
-            // paid in full
725
-            $this->_template_args['amount_due'] = false;
726
-        } elseif ($this->_transaction->paid() > $this->_transaction->total()) {
727
-            // overpaid
728
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
729
-        } elseif ($this->_transaction->total() > (float) 0) {
730
-            if ($this->_transaction->paid() > (float) 0) {
731
-                // monies owing
732
-                $this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
733
-            } elseif ($this->_transaction->paid() === (float) 0) {
734
-                // no payments made yet
735
-                $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
736
-            }
737
-        } elseif ($this->_transaction->total() === (float) 0) {
738
-            // free event
739
-            $this->_template_args['amount_due'] = false;
740
-        }
741
-
742
-        $payment_method = $this->_transaction->payment_method();
743
-
744
-        $this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
745
-            ? $payment_method->admin_name()
746
-            : esc_html__('Unknown', 'event_espresso');
747
-
748
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
749
-        // link back to overview
750
-        $this->_template_args['txn_overview_url'] = $this->request->getServerParam(
751
-            'HTTP_REFERER',
752
-            TXN_ADMIN_URL
753
-        );
754
-
755
-
756
-        // next link
757
-        $next_txn                                 = $this->_transaction->next(
758
-            null,
759
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
760
-            'TXN_ID'
761
-        );
762
-        $this->_template_args['next_transaction'] = $next_txn
763
-            ? $this->_next_link(
764
-                EE_Admin_Page::add_query_args_and_nonce(
765
-                    ['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
766
-                    TXN_ADMIN_URL
767
-                ),
768
-                'dashicons dashicons-arrow-right ee-icon-size-22'
769
-            )
770
-            : '';
771
-        // previous link
772
-        $previous_txn                                 = $this->_transaction->previous(
773
-            null,
774
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
775
-            'TXN_ID'
776
-        );
777
-        $this->_template_args['previous_transaction'] = $previous_txn
778
-            ? $this->_previous_link(
779
-                EE_Admin_Page::add_query_args_and_nonce(
780
-                    ['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
781
-                    TXN_ADMIN_URL
782
-                ),
783
-                'dashicons dashicons-arrow-left ee-icon-size-22'
784
-            )
785
-            : '';
786
-
787
-        $EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
788
-        $event_name    = $this->request->getRequestParam('event_name');
789
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
790
-
791
-        // were we just redirected here after adding a new registration ???
792
-        if ($EVT_ID && $event_name && $redirect_from) {
793
-            if (
794
-                EE_Registry::instance()->CAP->current_user_can(
795
-                    'ee_edit_registrations',
796
-                    'espresso_registrations_new_registration',
797
-                    $EVT_ID
798
-                )
799
-            ) {
800
-                $this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button--primary" href="';
801
-                $this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
802
-                    [
803
-                        'page'     => 'espresso_registrations',
804
-                        'action'   => 'new_registration',
805
-                        'return'   => 'default',
806
-                        'TXN_ID'   => $this->_transaction->ID(),
807
-                        'event_id' => $EVT_ID,
808
-                    ],
809
-                    REG_ADMIN_URL
810
-                );
811
-                $this->_admin_page_title .= '">';
812
-
813
-                $this->_admin_page_title .= sprintf(
814
-                    esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
815
-                    htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
816
-                );
817
-                $this->_admin_page_title .= '</a>';
818
-            }
819
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
820
-        }
821
-        // grab messages at the last second
822
-        $this->_template_args['notices'] = EE_Error::get_notices();
823
-        // path to template
824
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
825
-        $this->_template_args['admin_page_header'] = EEH_Template::display_template(
826
-            $template_path,
827
-            $this->_template_args,
828
-            true
829
-        );
830
-
831
-        // the details template wrapper
832
-        $this->display_admin_page_with_sidebar();
833
-    }
834
-
835
-
836
-    /**
837
-     *        _transaction_details_metaboxes
838
-     *
839
-     * @access protected
840
-     * @return void
841
-     * @throws EE_Error
842
-     * @throws InvalidArgumentException
843
-     * @throws InvalidDataTypeException
844
-     * @throws InvalidInterfaceException
845
-     * @throws RuntimeException
846
-     * @throws ReflectionException
847
-     */
848
-    protected function _transaction_details_metaboxes()
849
-    {
850
-
851
-        $this->_set_transaction_object();
852
-
853
-        if (! $this->_transaction instanceof EE_Transaction) {
854
-            return;
855
-        }
856
-        $this->addMetaBox(
857
-            'edit-txn-details-mbox',
858
-            '<span>' . esc_html__('Transaction Details', 'event_espresso')
859
-            . '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
860
-            [$this, 'txn_details_meta_box'],
861
-            $this->_wp_page_slug
862
-        );
863
-        $this->addMetaBox(
864
-            'edit-txn-attendees-mbox',
865
-            '<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
866
-            . '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
867
-            [$this, 'txn_attendees_meta_box'],
868
-            $this->_wp_page_slug,
869
-            'normal',
870
-            'high',
871
-            ['TXN_ID' => $this->_transaction->ID()]
872
-        );
873
-        $this->addMetaBox(
874
-            'edit-txn-registrant-mbox',
875
-            esc_html__('Primary Contact', 'event_espresso'),
876
-            [$this, 'txn_registrant_side_meta_box'],
877
-            $this->_wp_page_slug,
878
-            'side'
879
-        );
880
-        $this->addMetaBox(
881
-            'edit-txn-billing-info-mbox',
882
-            esc_html__('Billing Information', 'event_espresso'),
883
-            [$this, 'txn_billing_info_side_meta_box'],
884
-            $this->_wp_page_slug,
885
-            'side'
886
-        );
887
-    }
888
-
889
-
890
-    /**
891
-     * Callback for transaction actions metabox.
892
-     *
893
-     * @param EE_Transaction|null $transaction
894
-     * @return string
895
-     * @throws DomainException
896
-     * @throws EE_Error
897
-     * @throws InvalidArgumentException
898
-     * @throws InvalidDataTypeException
899
-     * @throws InvalidInterfaceException
900
-     * @throws ReflectionException
901
-     * @throws RuntimeException
902
-     */
903
-    public function getActionButtons(EE_Transaction $transaction = null)
904
-    {
905
-        $content = '';
906
-        $actions = [];
907
-        if (! $transaction instanceof EE_Transaction) {
908
-            return $content;
909
-        }
910
-        /** @var EE_Registration $primary_registration */
911
-        $primary_registration = $transaction->primary_registration();
912
-        $attendee             = $primary_registration instanceof EE_Registration
913
-            ? $primary_registration->attendee()
914
-            : null;
915
-
916
-        if (
917
-            $attendee instanceof EE_Attendee
918
-            && EE_Registry::instance()->CAP->current_user_can(
919
-                'ee_send_message',
920
-                'espresso_transactions_send_payment_reminder'
921
-            )
922
-        ) {
923
-            $actions['payment_reminder'] =
924
-                EEH_MSG_Template::is_mt_active('payment_reminder')
925
-                && $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
926
-                && $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
927
-                    ? EEH_Template::get_button_or_link(
928
-                        EE_Admin_Page::add_query_args_and_nonce(
929
-                            [
930
-                            'action'      => 'send_payment_reminder',
931
-                            'TXN_ID'      => $this->_transaction->ID(),
932
-                            'redirect_to' => 'view_transaction',
933
-                            ],
934
-                            TXN_ADMIN_URL
935
-                        ),
936
-                        esc_html__(' Send Payment Reminder', 'event_espresso'),
937
-                        'button button--secondary',
938
-                        'dashicons dashicons-email-alt'
939
-                    )
940
-                    : '';
941
-        }
942
-
943
-        if (
944
-            EE_Registry::instance()->CAP->current_user_can(
945
-                'ee_edit_payments',
946
-                'espresso_transactions_recalculate_line_items'
947
-            )
948
-        ) {
949
-            $actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
950
-                EE_Admin_Page::add_query_args_and_nonce(
951
-                    [
952
-                        'action'      => 'espresso_recalculate_line_items',
953
-                        'TXN_ID'      => $this->_transaction->ID(),
954
-                        'redirect_to' => 'view_transaction',
955
-                    ],
956
-                    TXN_ADMIN_URL
957
-                ),
958
-                esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
959
-                'button button--secondary',
960
-                'dashicons dashicons-update'
961
-            );
962
-        }
963
-
964
-        if (
965
-            $primary_registration instanceof EE_Registration
966
-            && EEH_MSG_Template::is_mt_active('receipt')
967
-        ) {
968
-            $actions['receipt'] = EEH_Template::get_button_or_link(
969
-                $primary_registration->receipt_url(),
970
-                esc_html__('View Receipt', 'event_espresso'),
971
-                'button button--secondary',
972
-                'dashicons dashicons-media-text'
973
-            );
974
-        }
975
-
976
-        if (
977
-            $primary_registration instanceof EE_Registration
978
-            && EEH_MSG_Template::is_mt_active('invoice')
979
-        ) {
980
-            $actions['invoice'] = EEH_Template::get_button_or_link(
981
-                $primary_registration->invoice_url(),
982
-                esc_html__('View Invoice', 'event_espresso'),
983
-                'button button--secondary',
984
-                'dashicons dashicons-media-spreadsheet'
985
-            );
986
-        }
987
-        $actions = array_filter(
988
-            apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
989
-        );
990
-        if ($actions) {
991
-            // $content = '<ul>';
992
-            // $content .= '<li>' . implode('</li><li>', $actions) . '</li>';
993
-            // $content .= '</uL>';
994
-            $content .= implode('', $actions);
995
-        }
996
-        return $content;
997
-    }
998
-
999
-
1000
-    /**
1001
-     * txn_details_meta_box
1002
-     * generates HTML for the Transaction main meta box
1003
-     *
1004
-     * @return void
1005
-     * @throws DomainException
1006
-     * @throws EE_Error
1007
-     * @throws InvalidArgumentException
1008
-     * @throws InvalidDataTypeException
1009
-     * @throws InvalidInterfaceException
1010
-     * @throws RuntimeException
1011
-     * @throws ReflectionException
1012
-     */
1013
-    public function txn_details_meta_box()
1014
-    {
1015
-        $this->_set_transaction_object();
1016
-        $this->_template_args['TXN_ID']              = $this->_transaction->ID();
1017
-        $this->_template_args['attendee']            =
1018
-            $this->_transaction->primary_registration() instanceof EE_Registration
1019
-                ? $this->_transaction->primary_registration()->attendee()
1020
-                : null;
1021
-        $this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1022
-            'ee_edit_payments',
1023
-            'apply_payment_or_refund_from_registration_details'
1024
-        );
1025
-        $this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1026
-            'ee_delete_payments',
1027
-            'delete_payment_from_registration_details'
1028
-        );
1029
-
1030
-        // get line table
1031
-        EEH_Autoloader::register_line_item_display_autoloaders();
1032
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1033
-            'admin_table',
1034
-            'EE_Admin_Table_Line_Item_Display_Strategy'
1035
-        );
1036
-        $this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1037
-            $this->_transaction->total_line_item()
1038
-        );
1039
-        $this->_template_args['REG_code']        =
1040
-            $this->_transaction->primary_registration() instanceof EE_Registration
1041
-                ? $this->_transaction->primary_registration()->reg_code()
1042
-                : null;
1043
-        // process taxes
1044
-        $taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1045
-        $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1046
-
1047
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1048
-            $this->_transaction->total(),
1049
-            false,
1050
-            false
1051
-        );
1052
-        $this->_template_args['grand_raw_total'] = $this->_transaction->total();
1053
-        $this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1054
-
1055
-        // process payment details
1056
-        $payments = $this->_transaction->payments();
1057
-        if (! empty($payments)) {
1058
-            $this->_template_args['payments']              = $payments;
1059
-            $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1060
-        } else {
1061
-            $this->_template_args['payments']              = false;
1062
-            $this->_template_args['existing_reg_payments'] = [];
1063
-        }
1064
-
1065
-        $this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1066
-        $this->_template_args['delete_payment_url'] = add_query_arg(
1067
-            ['action' => 'espresso_delete_payment'],
1068
-            TXN_ADMIN_URL
1069
-        );
1070
-
1071
-        if (isset($txn_details['invoice_number'])) {
1072
-            $this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1073
-            $this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1074
-                'Invoice Number',
1075
-                'event_espresso'
1076
-            );
1077
-        }
1078
-
1079
-        $this->_template_args['txn_details']['registration_session']['value'] =
1080
-            $this->_transaction->primary_registration() instanceof EE_Registration
1081
-                ? $this->_transaction->primary_registration()->session_ID()
1082
-                : null;
1083
-        $this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1084
-            'Registration Session',
1085
-            'event_espresso'
1086
-        );
1087
-
1088
-        $this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address'])
1089
-            ? $this->_session['ip_address']
1090
-            : '';
1091
-        $this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1092
-            'Transaction placed from IP',
1093
-            'event_espresso'
1094
-        );
1095
-
1096
-        $this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent'])
1097
-            ? $this->_session['user_agent']
1098
-            : '';
1099
-        $this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1100
-            'Registrant User Agent',
1101
-            'event_espresso'
1102
-        );
1103
-
1104
-        $reg_steps = '<ul>';
1105
-        foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1106
-            if ($reg_step_status === true) {
1107
-                $reg_steps .= '<li style="color:#70cc50">'
1108
-                              . sprintf(
1109
-                                  esc_html__('%1$s : Completed', 'event_espresso'),
1110
-                                  ucwords(str_replace('_', ' ', $reg_step))
1111
-                              )
1112
-                              . '</li>';
1113
-            } elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1114
-                $reg_steps .= '<li style="color:#2EA2CC">'
1115
-                              . sprintf(
1116
-                                  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1117
-                                  ucwords(str_replace('_', ' ', $reg_step)),
1118
-                                  date(
1119
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1120
-                                      $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1121
-                                  )
1122
-                              )
1123
-                              . '</li>';
1124
-            } else {
1125
-                $reg_steps .= '<li style="color:#E76700">'
1126
-                              . sprintf(
1127
-                                  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1128
-                                  ucwords(str_replace('_', ' ', $reg_step))
1129
-                              )
1130
-                              . '</li>';
1131
-            }
1132
-        }
1133
-        $reg_steps                                                 .= '</ul>';
1134
-        $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1135
-        $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1136
-            'Registration Step Progress',
1137
-            'event_espresso'
1138
-        );
1139
-
1140
-
1141
-        $this->_get_registrations_to_apply_payment_to();
1142
-        $this->_get_payment_methods($payments);
1143
-        $this->_get_payment_status_array();
1144
-        $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1145
-
1146
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1147
-            [
1148
-                'action'  => 'edit_transaction',
1149
-                'process' => 'transaction',
1150
-            ],
1151
-            TXN_ADMIN_URL
1152
-        );
1153
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1154
-            [
1155
-                'page'   => 'espresso_transactions',
1156
-                'action' => 'espresso_apply_payment',
1157
-            ],
1158
-            WP_AJAX_URL
1159
-        );
1160
-        $this->_template_args['delete_payment_form_url'] = add_query_arg(
1161
-            [
1162
-                'page'   => 'espresso_transactions',
1163
-                'action' => 'espresso_delete_payment',
1164
-            ],
1165
-            WP_AJAX_URL
1166
-        );
1167
-
1168
-        $this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1169
-
1170
-        // 'espresso_delete_payment_nonce'
1171
-
1172
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1173
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * _get_registration_payment_IDs
1179
-     *    generates an array of Payment IDs and their corresponding Registration IDs
1180
-     *
1181
-     * @access protected
1182
-     * @param EE_Payment[] $payments
1183
-     * @return array
1184
-     * @throws EE_Error
1185
-     * @throws InvalidArgumentException
1186
-     * @throws InvalidDataTypeException
1187
-     * @throws InvalidInterfaceException
1188
-     * @throws ReflectionException
1189
-     */
1190
-    protected function _get_registration_payment_IDs($payments = [])
1191
-    {
1192
-        $existing_reg_payments = [];
1193
-        // get all reg payments for these payments
1194
-        $reg_payments = EEM_Registration_Payment::instance()->get_all(
1195
-            [
1196
-                [
1197
-                    'PAY_ID' => [
1198
-                        'IN',
1199
-                        array_keys($payments),
1200
-                    ],
1201
-                ],
1202
-            ]
1203
-        );
1204
-        if (! empty($reg_payments)) {
1205
-            foreach ($payments as $payment) {
1206
-                if (! $payment instanceof EE_Payment) {
1207
-                    continue;
1208
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1209
-                    $existing_reg_payments[ $payment->ID() ] = [];
1210
-                }
1211
-                foreach ($reg_payments as $reg_payment) {
1212
-                    if (
1213
-                        $reg_payment instanceof EE_Registration_Payment
1214
-                        && $reg_payment->payment_ID() === $payment->ID()
1215
-                    ) {
1216
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1217
-                    }
1218
-                }
1219
-            }
1220
-        }
1221
-
1222
-        return $existing_reg_payments;
1223
-    }
1224
-
1225
-
1226
-    /**
1227
-     * _get_registrations_to_apply_payment_to
1228
-     *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1229
-     * which allows the admin to only apply the payment to the specific registrations
1230
-     *
1231
-     * @access protected
1232
-     * @return void
1233
-     * @throws EE_Error
1234
-     * @throws InvalidArgumentException
1235
-     * @throws InvalidDataTypeException
1236
-     * @throws InvalidInterfaceException
1237
-     * @throws ReflectionException
1238
-     */
1239
-    protected function _get_registrations_to_apply_payment_to()
1240
-    {
1241
-        // we want any registration with an active status (ie: not deleted or cancelled)
1242
-        $query_params                      = [
1243
-            [
1244
-                'STS_ID' => [
1245
-                    'IN',
1246
-                    [
1247
-                        EEM_Registration::status_id_approved,
1248
-                        EEM_Registration::status_id_pending_payment,
1249
-                        EEM_Registration::status_id_not_approved,
1250
-                    ],
1251
-                ],
1252
-            ],
1253
-        ];
1254
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1255
-            '',
1256
-            'txn-admin-apply-payment-to-registrations-dv',
1257
-            '',
1258
-            'clear: both; margin: 1.5em 0 0; display: none;'
1259
-        );
1260
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1261
-        $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1262
-        $registrations_to_apply_payment_to .= EEH_HTML::thead(
1263
-            EEH_HTML::tr(
1264
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1265
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1266
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1267
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1268
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1269
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1270
-                EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1271
-            )
1272
-        );
1273
-        $registrations_to_apply_payment_to .= EEH_HTML::tbody();
1274
-        // get registrations for TXN
1275
-        $registrations         = $this->_transaction->registrations($query_params);
1276
-        $existing_reg_payments = $this->_template_args['existing_reg_payments'];
1277
-        foreach ($registrations as $registration) {
1278
-            if ($registration instanceof EE_Registration) {
1279
-                $attendee_name                     = $registration->attendee() instanceof EE_Attendee
1280
-                    ? $registration->attendee()->full_name()
1281
-                    : esc_html__('Unknown Attendee', 'event_espresso');
1282
-                $owing                             = $registration->final_price() - $registration->paid();
1283
-                $taxable                           = $registration->ticket()->taxable()
1284
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1285
-                    : '';
1286
-                $checked                           = empty($existing_reg_payments)
1287
-                                                     || in_array($registration->ID(), $existing_reg_payments, true)
1288
-                    ? ' checked="checked"'
1289
-                    : '';
1290
-                $disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1291
-                $registrations_to_apply_payment_to .= EEH_HTML::tr(
1292
-                    EEH_HTML::td($registration->ID()) .
1293
-                    EEH_HTML::td($attendee_name) .
1294
-                    EEH_HTML::td(
1295
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1296
-                    ) .
1297
-                    EEH_HTML::td($registration->event_name()) .
1298
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1299
-                    EEH_HTML::td(
1300
-                        EEH_Template::format_currency($owing),
1301
-                        '',
1302
-                        'txn-admin-payment-owing-td jst-cntr'
1303
-                    ) .
1304
-                    EEH_HTML::td(
1305
-                        '<input type="checkbox" value="' . $registration->ID()
1306
-                        . '" name="txn_admin_payment[registrations]"'
1307
-                        . $checked . $disabled . '>',
1308
-                        '',
1309
-                        'jst-cntr'
1310
-                    ),
1311
-                    'apply-payment-registration-row-' . $registration->ID()
1312
-                );
1313
-            }
1314
-        }
1315
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1316
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1317
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1318
-        $registrations_to_apply_payment_to                         .= EEH_HTML::p(
1319
-            esc_html__(
1320
-                'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1321
-                'event_espresso'
1322
-            ),
1323
-            '',
1324
-            'clear description'
1325
-        );
1326
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1327
-        $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1328
-    }
1329
-
1330
-
1331
-    /**
1332
-     * _get_reg_status_selection
1333
-     *
1334
-     * @return void
1335
-     * @throws EE_Error
1336
-     * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1337
-     *         instead of events.
1338
-     * @access protected
1339
-     */
1340
-    protected function _get_reg_status_selection()
1341
-    {
1342
-        // first get all possible statuses
1343
-        $statuses = EEM_Registration::reg_status_array([], true);
1344
-        // let's add a "don't change" option.
1345
-        $status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1346
-        $status_array                                        = array_merge($status_array, $statuses);
1347
-        $this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1348
-            'txn_reg_status_change[reg_status]',
1349
-            $status_array,
1350
-            'NAN',
1351
-            'id="txn-admin-payment-reg-status-inp"',
1352
-            'txn-reg-status-change-reg-status'
1353
-        );
1354
-        $this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1355
-            'delete_txn_reg_status_change[reg_status]',
1356
-            $status_array,
1357
-            'NAN',
1358
-            'delete-txn-admin-payment-reg-status-inp',
1359
-            'delete-txn-reg-status-change-reg-status'
1360
-        );
1361
-    }
1362
-
1363
-
1364
-    /**
1365
-     *    _get_payment_methods
1366
-     * Gets all the payment methods available generally, or the ones that are already
1367
-     * selected on these payments (in case their payment methods are no longer active).
1368
-     * Has the side-effect of updating the template args' payment_methods item
1369
-     *
1370
-     * @access private
1371
-     * @param EE_Payment[] to show on this page
1372
-     * @return void
1373
-     * @throws EE_Error
1374
-     * @throws InvalidArgumentException
1375
-     * @throws InvalidDataTypeException
1376
-     * @throws InvalidInterfaceException
1377
-     * @throws ReflectionException
1378
-     */
1379
-    private function _get_payment_methods($payments = [])
1380
-    {
1381
-        $payment_methods_of_payments = [];
1382
-        foreach ($payments as $payment) {
1383
-            if ($payment instanceof EE_Payment) {
1384
-                $payment_methods_of_payments[] = $payment->ID();
1385
-            }
1386
-        }
1387
-        if ($payment_methods_of_payments) {
1388
-            $query_args = [
1389
-                [
1390
-                    'OR*payment_method_for_payment' => [
1391
-                        'PMD_ID'    => ['IN', $payment_methods_of_payments],
1392
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1393
-                    ],
1394
-                ],
1395
-            ];
1396
-        } else {
1397
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1398
-        }
1399
-        $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1400
-    }
1401
-
1402
-
1403
-    /**
1404
-     * txn_attendees_meta_box
1405
-     *    generates HTML for the Attendees Transaction main meta box
1406
-     *
1407
-     * @access public
1408
-     * @param WP_Post $post
1409
-     * @param array   $metabox
1410
-     * @return void
1411
-     * @throws DomainException
1412
-     * @throws EE_Error
1413
-     * @throws InvalidArgumentException
1414
-     * @throws InvalidDataTypeException
1415
-     * @throws InvalidInterfaceException
1416
-     * @throws ReflectionException
1417
-     */
1418
-    public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1419
-    {
1420
-
1421
-        /** @noinspection NonSecureExtractUsageInspection */
1422
-        extract($metabox['args']);
1423
-        $this->_template_args['post']            = $post;
1424
-        $this->_template_args['event_attendees'] = [];
1425
-        // process items in cart
1426
-        $line_items = $this->_transaction->get_many_related(
1427
-            'Line_Item',
1428
-            [['LIN_type' => 'line-item']]
1429
-        );
1430
-        if (! empty($line_items)) {
1431
-            foreach ($line_items as $item) {
1432
-                if ($item instanceof EE_Line_Item) {
1433
-                    switch ($item->OBJ_type()) {
1434
-                        case 'Event':
1435
-                            break;
1436
-                        case 'Ticket':
1437
-                            $ticket = $item->ticket();
1438
-                            // right now we're only handling tickets here.
1439
-                            // Cause its expected that only tickets will have attendees right?
1440
-                            if (! $ticket instanceof EE_Ticket) {
1441
-                                break;
1442
-                            }
1443
-                            try {
1444
-                                $event_name = $ticket->get_event_name();
1445
-                            } catch (Exception $e) {
1446
-                                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1447
-                                $event_name = esc_html__('Unknown Event', 'event_espresso');
1448
-                            }
1449
-                            $event_name   .= ' - ' . $item->name();
1450
-                            $ticket_price = EEH_Template::format_currency($item->unit_price());
1451
-                            // now get all of the registrations for this transaction that use this ticket
1452
-                            $registrations = $ticket->registrations(
1453
-                                [['TXN_ID' => $this->_transaction->ID()]]
1454
-                            );
1455
-                            foreach ($registrations as $registration) {
1456
-                                if (! $registration instanceof EE_Registration) {
1457
-                                    break;
1458
-                                }
1459
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1460
-                                    = $registration->status_ID();
1461
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1462
-                                    = $registration->count();
1463
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1464
-                                    = $event_name;
1465
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1466
-                                    = $ticket_price;
1467
-                                // attendee info
1468
-                                $attendee = $registration->get_first_related('Attendee');
1469
-                                if ($attendee instanceof EE_Attendee) {
1470
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1471
-                                        = $attendee->ID();
1472
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1473
-                                        = $attendee->full_name();
1474
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1475
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1476
-                                          . esc_html__(
1477
-                                              ' Event',
1478
-                                              'event_espresso'
1479
-                                          )
1480
-                                          . '">' . $attendee->email() . '</a>';
1481
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1482
-                                        = EEH_Address::format($attendee, 'inline', false, false);
1483
-                                } else {
1484
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1485
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1486
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1487
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1488
-                                }
1489
-                            }
1490
-                            break;
1491
-                    }
1492
-                }
1493
-            }
1494
-
1495
-            $this->_template_args['transaction_form_url'] = add_query_arg(
1496
-                [
1497
-                    'action'  => 'edit_transaction',
1498
-                    'process' => 'attendees',
1499
-                ],
1500
-                TXN_ADMIN_URL
1501
-            );
1502
-            echo EEH_Template::display_template(
1503
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1504
-                $this->_template_args,
1505
-                true
1506
-            );
1507
-        } else {
1508
-            printf(
1509
-                esc_html__(
1510
-                    '%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1511
-                    'event_espresso'
1512
-                ),
1513
-                '<p class="important-notice">',
1514
-                '</p>'
1515
-            );
1516
-        }
1517
-    }
1518
-
1519
-
1520
-    /**
1521
-     * txn_registrant_side_meta_box
1522
-     * generates HTML for the Edit Transaction side meta box
1523
-     *
1524
-     * @access public
1525
-     * @return void
1526
-     * @throws DomainException
1527
-     * @throws EE_Error
1528
-     * @throws InvalidArgumentException
1529
-     * @throws InvalidDataTypeException
1530
-     * @throws InvalidInterfaceException
1531
-     * @throws ReflectionException
1532
-     */
1533
-    public function txn_registrant_side_meta_box()
1534
-    {
1535
-        $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1536
-            ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1537
-            : null;
1538
-        if (! $primary_att instanceof EE_Attendee) {
1539
-            $this->_template_args['no_attendee_message'] = esc_html__(
1540
-                'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1541
-                'event_espresso'
1542
-            );
1543
-            $primary_att                           = EEM_Attendee::instance()->create_default_object();
1544
-        }
1545
-        $this->_template_args['ATT_ID']            = $primary_att->ID();
1546
-        $this->_template_args['prime_reg_fname']   = $primary_att->fname();
1547
-        $this->_template_args['prime_reg_lname']   = $primary_att->lname();
1548
-        $this->_template_args['prime_reg_email']   = $primary_att->email();
1549
-        $this->_template_args['prime_reg_phone']   = $primary_att->phone();
1550
-        $this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1551
-            [
1552
-                'action' => 'edit_attendee',
1553
-                'post'   => $primary_att->ID(),
1554
-            ],
1555
-            REG_ADMIN_URL
1556
-        );
1557
-        // get formatted address for registrant
1558
-        $formatted_address = EEH_Address::format($primary_att);
1559
-        $formatted_address = $formatted_address !== '<div class="espresso-address-dv"><div></div></div>'
1560
-            ? $formatted_address
1561
-            : '';
1562
-        $this->_template_args['formatted_address'] = $formatted_address;
1563
-        echo EEH_Template::display_template(
1564
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1565
-            $this->_template_args,
1566
-            true
1567
-        );
1568
-    }
1569
-
1570
-
1571
-    /**
1572
-     * txn_billing_info_side_meta_box
1573
-     *    generates HTML for the Edit Transaction side meta box
1574
-     *
1575
-     * @access public
1576
-     * @return void
1577
-     * @throws DomainException
1578
-     * @throws EE_Error
1579
-     * @throws ReflectionException
1580
-     */
1581
-    public function txn_billing_info_side_meta_box()
1582
-    {
1583
-
1584
-        $this->_template_args['billing_form']     = $this->_transaction->billing_info();
1585
-        $this->_template_args['billing_form_url'] = add_query_arg(
1586
-            ['action' => 'edit_transaction', 'process' => 'billing'],
1587
-            TXN_ADMIN_URL
1588
-        );
1589
-
1590
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1591
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1592
-    }
1593
-
1594
-
1595
-    /**
1596
-     * apply_payments_or_refunds
1597
-     *    registers a payment or refund made towards a transaction
1598
-     *
1599
-     * @access public
1600
-     * @return void
1601
-     * @throws EE_Error
1602
-     * @throws InvalidArgumentException
1603
-     * @throws ReflectionException
1604
-     * @throws RuntimeException
1605
-     * @throws InvalidDataTypeException
1606
-     * @throws InvalidInterfaceException
1607
-     */
1608
-    public function apply_payments_or_refunds()
1609
-    {
1610
-        $json_response_data = ['return_data' => false];
1611
-        $valid_data         = $this->_validate_payment_request_data();
1612
-        $has_access         = EE_Registry::instance()->CAP->current_user_can(
1613
-            'ee_edit_payments',
1614
-            'apply_payment_or_refund_from_registration_details'
1615
-        );
1616
-        if (! empty($valid_data) && $has_access) {
1617
-            $PAY_ID = $valid_data['PAY_ID'];
1618
-            // save  the new payment
1619
-            $payment = $this->_create_payment_from_request_data($valid_data);
1620
-            // get the TXN for this payment
1621
-            $transaction = $payment->transaction();
1622
-            // verify transaction
1623
-            if ($transaction instanceof EE_Transaction) {
1624
-                // calculate_total_payments_and_update_status
1625
-                $this->_process_transaction_payments($transaction);
1626
-                $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1627
-                $this->_remove_existing_registration_payments($payment, $PAY_ID);
1628
-                // apply payment to registrations (if applicable)
1629
-                if (! empty($REG_IDs)) {
1630
-                    $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1631
-                    $this->_maybe_send_notifications();
1632
-                    // now process status changes for the same registrations
1633
-                    $this->_process_registration_status_change($transaction, $REG_IDs);
1634
-                }
1635
-                $this->_maybe_send_notifications($payment);
1636
-                // prepare to render page
1637
-                $json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1638
-                do_action(
1639
-                    'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1640
-                    $transaction,
1641
-                    $payment
1642
-                );
1643
-            } else {
1644
-                EE_Error::add_error(
1645
-                    esc_html__(
1646
-                        'A valid Transaction for this payment could not be retrieved.',
1647
-                        'event_espresso'
1648
-                    ),
1649
-                    __FILE__,
1650
-                    __FUNCTION__,
1651
-                    __LINE__
1652
-                );
1653
-            }
1654
-        } elseif ($has_access) {
1655
-            EE_Error::add_error(
1656
-                esc_html__(
1657
-                    'The payment form data could not be processed. Please try again.',
1658
-                    'event_espresso'
1659
-                ),
1660
-                __FILE__,
1661
-                __FUNCTION__,
1662
-                __LINE__
1663
-            );
1664
-        } else {
1665
-            EE_Error::add_error(
1666
-                esc_html__(
1667
-                    'You do not have access to apply payments or refunds to a registration.',
1668
-                    'event_espresso'
1669
-                ),
1670
-                __FILE__,
1671
-                __FUNCTION__,
1672
-                __LINE__
1673
-            );
1674
-        }
1675
-        $notices              = EE_Error::get_notices(
1676
-            false,
1677
-            false,
1678
-            false
1679
-        );
1680
-        $this->_template_args = [
1681
-            'data'    => $json_response_data,
1682
-            'error'   => $notices['errors'],
1683
-            'success' => $notices['success'],
1684
-        ];
1685
-        $this->_return_json();
1686
-    }
1687
-
1688
-
1689
-    /**
1690
-     * _validate_payment_request_data
1691
-     *
1692
-     * @return array
1693
-     * @throws EE_Error
1694
-     * @throws InvalidArgumentException
1695
-     * @throws InvalidDataTypeException
1696
-     * @throws InvalidInterfaceException
1697
-     */
1698
-    protected function _validate_payment_request_data()
1699
-    {
1700
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1701
-            return [];
1702
-        }
1703
-        $payment_form = $this->_generate_payment_form_section();
1704
-        try {
1705
-            if ($payment_form->was_submitted()) {
1706
-                $payment_form->receive_form_submission();
1707
-                if (! $payment_form->is_valid()) {
1708
-                    $submission_error_messages = [];
1709
-                    foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1710
-                        if ($validation_error instanceof EE_Validation_Error) {
1711
-                            $form_input = $validation_error->get_form_section();
1712
-                            $submission_error_messages[] = sprintf(
1713
-                                _x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1714
-                                $form_input instanceof EE_Form_Input_Base ? $form_input->html_label_text() : '',
1715
-                                $validation_error->getMessage()
1716
-                            );
1717
-                        }
1718
-                    }
1719
-                    EE_Error::add_error(
1720
-                        implode('<br />', $submission_error_messages),
1721
-                        __FILE__,
1722
-                        __FUNCTION__,
1723
-                        __LINE__
1724
-                    );
1725
-                    return [];
1726
-                }
1727
-            }
1728
-        } catch (EE_Error $e) {
1729
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1730
-            return [];
1731
-        }
1732
-
1733
-        return $payment_form->valid_data();
1734
-    }
1735
-
1736
-
1737
-    /**
1738
-     * _generate_payment_form_section
1739
-     *
1740
-     * @return EE_Form_Section_Proper
1741
-     * @throws EE_Error
1742
-     */
1743
-    protected function _generate_payment_form_section()
1744
-    {
1745
-        return new EE_Form_Section_Proper(
1746
-            [
1747
-                'name'        => 'txn_admin_payment',
1748
-                'subsections' => [
1749
-                    'PAY_ID'          => new EE_Text_Input(
1750
-                        [
1751
-                            'default'               => 0,
1752
-                            'required'              => false,
1753
-                            'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1754
-                            'validation_strategies' => [new EE_Int_Normalization()],
1755
-                        ]
1756
-                    ),
1757
-                    'TXN_ID'          => new EE_Text_Input(
1758
-                        [
1759
-                            'default'               => 0,
1760
-                            'required'              => true,
1761
-                            'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1762
-                            'validation_strategies' => [new EE_Int_Normalization()],
1763
-                        ]
1764
-                    ),
1765
-                    'type'            => new EE_Text_Input(
1766
-                        [
1767
-                            'default'               => 1,
1768
-                            'required'              => true,
1769
-                            'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1770
-                            'validation_strategies' => [new EE_Int_Normalization()],
1771
-                        ]
1772
-                    ),
1773
-                    'amount'          => new EE_Text_Input(
1774
-                        [
1775
-                            'default'               => 0,
1776
-                            'required'              => true,
1777
-                            'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1778
-                            'validation_strategies' => [new EE_Float_Normalization()],
1779
-                        ]
1780
-                    ),
1781
-                    'status'          => new EE_Text_Input(
1782
-                        [
1783
-                            'default'         => EEM_Payment::status_id_approved,
1784
-                            'required'        => true,
1785
-                            'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1786
-                        ]
1787
-                    ),
1788
-                    'PMD_ID'          => new EE_Text_Input(
1789
-                        [
1790
-                            'default'               => 2,
1791
-                            'required'              => true,
1792
-                            'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1793
-                            'validation_strategies' => [new EE_Int_Normalization()],
1794
-                        ]
1795
-                    ),
1796
-                    'date'            => new EE_Text_Input(
1797
-                        [
1798
-                            'default'         => time(),
1799
-                            'required'        => true,
1800
-                            'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1801
-                        ]
1802
-                    ),
1803
-                    'txn_id_chq_nmbr' => new EE_Text_Input(
1804
-                        [
1805
-                            'default'               => '',
1806
-                            'required'              => false,
1807
-                            'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1808
-                            'validation_strategies' => [
1809
-                                new EE_Max_Length_Validation_Strategy(
1810
-                                    esc_html__('Input too long', 'event_espresso'),
1811
-                                    100
1812
-                                ),
1813
-                            ],
1814
-                        ]
1815
-                    ),
1816
-                    'po_number'       => new EE_Text_Input(
1817
-                        [
1818
-                            'default'               => '',
1819
-                            'required'              => false,
1820
-                            'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1821
-                            'validation_strategies' => [
1822
-                                new EE_Max_Length_Validation_Strategy(
1823
-                                    esc_html__('Input too long', 'event_espresso'),
1824
-                                    100
1825
-                                ),
1826
-                            ],
1827
-                        ]
1828
-                    ),
1829
-                    'accounting'      => new EE_Text_Input(
1830
-                        [
1831
-                            'default'               => '',
1832
-                            'required'              => false,
1833
-                            'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1834
-                            'validation_strategies' => [
1835
-                                new EE_Max_Length_Validation_Strategy(
1836
-                                    esc_html__('Input too long', 'event_espresso'),
1837
-                                    100
1838
-                                ),
1839
-                            ],
1840
-                        ]
1841
-                    ),
1842
-                ],
1843
-            ]
1844
-        );
1845
-    }
1846
-
1847
-
1848
-    /**
1849
-     * _create_payment_from_request_data
1850
-     *
1851
-     * @param array $valid_data
1852
-     * @return EE_Payment
1853
-     * @throws EE_Error
1854
-     * @throws InvalidArgumentException
1855
-     * @throws InvalidDataTypeException
1856
-     * @throws InvalidInterfaceException
1857
-     * @throws ReflectionException
1858
-     */
1859
-    protected function _create_payment_from_request_data($valid_data)
1860
-    {
1861
-        $PAY_ID = $valid_data['PAY_ID'];
1862
-        // get payment amount
1863
-        $amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1864
-        // payments have a type value of 1 and refunds have a type value of -1
1865
-        // so multiplying amount by type will give a positive value for payments, and negative values for refunds
1866
-        $amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1867
-        // for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1868
-        $date    = $valid_data['date']
1869
-            ? preg_replace('/\s+/', ' ', $valid_data['date'])
1870
-            : date('Y-m-d g:i a', current_time('timestamp'));
1871
-        $payment = EE_Payment::new_instance(
1872
-            [
1873
-                'TXN_ID'              => $valid_data['TXN_ID'],
1874
-                'STS_ID'              => $valid_data['status'],
1875
-                'PAY_timestamp'       => $date,
1876
-                'PAY_source'          => EEM_Payment_Method::scope_admin,
1877
-                'PMD_ID'              => $valid_data['PMD_ID'],
1878
-                'PAY_amount'          => $amount,
1879
-                'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1880
-                'PAY_po_number'       => $valid_data['po_number'],
1881
-                'PAY_extra_accntng'   => $valid_data['accounting'],
1882
-                'PAY_details'         => $valid_data,
1883
-                'PAY_ID'              => $PAY_ID,
1884
-            ],
1885
-            '',
1886
-            ['Y-m-d', 'g:i a']
1887
-        );
1888
-
1889
-        if (! $payment->save()) {
1890
-            EE_Error::add_error(
1891
-                sprintf(
1892
-                    esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1893
-                    $payment->ID()
1894
-                ),
1895
-                __FILE__,
1896
-                __FUNCTION__,
1897
-                __LINE__
1898
-            );
1899
-        }
1900
-
1901
-        return $payment;
1902
-    }
1903
-
1904
-
1905
-    /**
1906
-     * _process_transaction_payments
1907
-     *
1908
-     * @param EE_Transaction $transaction
1909
-     * @return void
1910
-     * @throws EE_Error
1911
-     * @throws InvalidArgumentException
1912
-     * @throws ReflectionException
1913
-     * @throws InvalidDataTypeException
1914
-     * @throws InvalidInterfaceException
1915
-     */
1916
-    protected function _process_transaction_payments(EE_Transaction $transaction)
1917
-    {
1918
-        /** @type EE_Transaction_Payments $transaction_payments */
1919
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1920
-        // update the transaction with this payment
1921
-        if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1922
-            EE_Error::add_success(
1923
-                esc_html__(
1924
-                    'The payment has been processed successfully.',
1925
-                    'event_espresso'
1926
-                ),
1927
-                __FILE__,
1928
-                __FUNCTION__,
1929
-                __LINE__
1930
-            );
1931
-        } else {
1932
-            EE_Error::add_error(
1933
-                esc_html__(
1934
-                    'The payment was processed successfully but the amount paid for the transaction was not updated.',
1935
-                    'event_espresso'
1936
-                ),
1937
-                __FILE__,
1938
-                __FUNCTION__,
1939
-                __LINE__
1940
-            );
1941
-        }
1942
-    }
1943
-
1944
-
1945
-    /**
1946
-     * _get_REG_IDs_to_apply_payment_to
1947
-     * returns a list of registration IDs that the payment will apply to
1948
-     *
1949
-     * @param EE_Payment $payment
1950
-     * @return array
1951
-     * @throws EE_Error
1952
-     * @throws InvalidArgumentException
1953
-     * @throws InvalidDataTypeException
1954
-     * @throws InvalidInterfaceException
1955
-     * @throws ReflectionException
1956
-     */
1957
-    protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1958
-    {
1959
-        // grab array of IDs for specific registrations to apply changes to
1960
-        $REG_IDs = $this->request->getRequestParam('txn_admin_payment[registrations]', [], 'int', true);
1961
-        // nothing specified ? then get all reg IDs
1962
-        if (empty($REG_IDs)) {
1963
-            $registrations = $payment->transaction()->registrations();
1964
-            $REG_IDs       = ! empty($registrations)
1965
-                ? array_keys($registrations)
1966
-                : $this->_get_existing_reg_payment_REG_IDs($payment);
1967
-        }
1968
-
1969
-        // ensure that REG_IDs are integers and NOT strings
1970
-        return array_map('intval', $REG_IDs);
1971
-    }
1972
-
1973
-
1974
-    /**
1975
-     * @return array
1976
-     */
1977
-    public function existing_reg_payment_REG_IDs()
1978
-    {
1979
-        return $this->_existing_reg_payment_REG_IDs;
1980
-    }
1981
-
1982
-
1983
-    /**
1984
-     * @param array $existing_reg_payment_REG_IDs
1985
-     */
1986
-    public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1987
-    {
1988
-        $this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1989
-    }
1990
-
1991
-
1992
-    /**
1993
-     * _get_existing_reg_payment_REG_IDs
1994
-     * returns a list of registration IDs that the payment is currently related to
1995
-     * as recorded in the database
1996
-     *
1997
-     * @param EE_Payment $payment
1998
-     * @return array
1999
-     * @throws EE_Error
2000
-     * @throws InvalidArgumentException
2001
-     * @throws InvalidDataTypeException
2002
-     * @throws InvalidInterfaceException
2003
-     * @throws ReflectionException
2004
-     */
2005
-    protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2006
-    {
2007
-        if ($this->existing_reg_payment_REG_IDs() === null) {
2008
-            // let's get any existing reg payment records for this payment
2009
-            $existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2010
-            // but we only want the REG IDs, so grab the array keys
2011
-            $existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2012
-                ? array_keys($existing_reg_payment_REG_IDs)
2013
-                : [];
2014
-            $this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2015
-        }
2016
-
2017
-        return $this->existing_reg_payment_REG_IDs();
2018
-    }
2019
-
2020
-
2021
-    /**
2022
-     * _remove_existing_registration_payments
2023
-     * this calculates the difference between existing relations
2024
-     * to the supplied payment and the new list registration IDs,
2025
-     * removes any related registrations that no longer apply,
2026
-     * and then updates the registration paid fields
2027
-     *
2028
-     * @param EE_Payment $payment
2029
-     * @param int        $PAY_ID
2030
-     * @return bool;
2031
-     * @throws EE_Error
2032
-     * @throws InvalidArgumentException
2033
-     * @throws ReflectionException
2034
-     * @throws InvalidDataTypeException
2035
-     * @throws InvalidInterfaceException
2036
-     */
2037
-    protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2038
-    {
2039
-        // newly created payments will have nothing recorded for $PAY_ID
2040
-        if (absint($PAY_ID) === 0) {
2041
-            return false;
2042
-        }
2043
-        $existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2044
-        if (empty($existing_reg_payment_REG_IDs)) {
2045
-            return false;
2046
-        }
2047
-        /** @type EE_Transaction_Payments $transaction_payments */
2048
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2049
-
2050
-        return $transaction_payments->delete_registration_payments_and_update_registrations(
2051
-            $payment,
2052
-            [
2053
-                [
2054
-                    'PAY_ID' => $payment->ID(),
2055
-                    'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2056
-                ],
2057
-            ]
2058
-        );
2059
-    }
2060
-
2061
-
2062
-    /**
2063
-     * _update_registration_payments
2064
-     * this applies the payments to the selected registrations
2065
-     * but only if they have not already been paid for
2066
-     *
2067
-     * @param EE_Transaction $transaction
2068
-     * @param EE_Payment     $payment
2069
-     * @param array          $REG_IDs
2070
-     * @return void
2071
-     * @throws EE_Error
2072
-     * @throws InvalidArgumentException
2073
-     * @throws ReflectionException
2074
-     * @throws RuntimeException
2075
-     * @throws InvalidDataTypeException
2076
-     * @throws InvalidInterfaceException
2077
-     */
2078
-    protected function _update_registration_payments(
2079
-        EE_Transaction $transaction,
2080
-        EE_Payment $payment,
2081
-        $REG_IDs = []
2082
-    ) {
2083
-        // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2084
-        // so let's do that using our set of REG_IDs from the form
2085
-        $registration_query_where_params = [
2086
-            'REG_ID' => ['IN', $REG_IDs],
2087
-        ];
2088
-        // but add in some conditions regarding payment,
2089
-        // so that we don't apply payments to registrations that are free or have already been paid for
2090
-        // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2091
-        if (! $payment->is_a_refund()) {
2092
-            $registration_query_where_params['REG_final_price']  = ['!=', 0];
2093
-            $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2094
-        }
2095
-        $registrations = $transaction->registrations([$registration_query_where_params]);
2096
-        if (! empty($registrations)) {
2097
-            /** @type EE_Payment_Processor $payment_processor */
2098
-            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2099
-            $payment_processor->process_registration_payments($transaction, $payment, $registrations);
2100
-        }
2101
-    }
2102
-
2103
-
2104
-    /**
2105
-     * _process_registration_status_change
2106
-     * This processes requested registration status changes for all the registrations
2107
-     * on a given transaction and (optionally) sends out notifications for the changes.
2108
-     *
2109
-     * @param EE_Transaction $transaction
2110
-     * @param array          $REG_IDs
2111
-     * @return bool
2112
-     * @throws EE_Error
2113
-     * @throws InvalidArgumentException
2114
-     * @throws ReflectionException
2115
-     * @throws InvalidDataTypeException
2116
-     * @throws InvalidInterfaceException
2117
-     */
2118
-    protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [])
2119
-    {
2120
-        // first if there is no change in status then we get out.
2121
-        $reg_status = $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2122
-        if ($reg_status === 'NAN') {
2123
-            // no error message, no change requested, just nothing to do man.
2124
-            return false;
2125
-        }
2126
-        /** @type EE_Transaction_Processor $transaction_processor */
2127
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2128
-
2129
-        // made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2130
-        return $transaction_processor->manually_update_registration_statuses(
2131
-            $transaction,
2132
-            $reg_status,
2133
-            [['REG_ID' => ['IN', $REG_IDs]]]
2134
-        );
2135
-    }
2136
-
2137
-
2138
-    /**
2139
-     * _build_payment_json_response
2140
-     *
2141
-     * @access public
2142
-     * @param EE_Payment  $payment
2143
-     * @param array       $REG_IDs
2144
-     * @param bool | null $delete_txn_reg_status_change
2145
-     * @return array
2146
-     * @throws EE_Error
2147
-     * @throws InvalidArgumentException
2148
-     * @throws InvalidDataTypeException
2149
-     * @throws InvalidInterfaceException
2150
-     * @throws ReflectionException
2151
-     */
2152
-    protected function _build_payment_json_response(
2153
-        EE_Payment $payment,
2154
-        $REG_IDs = [],
2155
-        $delete_txn_reg_status_change = null
2156
-    ) {
2157
-        // was the payment deleted ?
2158
-        if (is_bool($delete_txn_reg_status_change)) {
2159
-            return [
2160
-                'PAY_ID'                       => $payment->ID(),
2161
-                'amount'                       => $payment->amount(),
2162
-                'total_paid'                   => $payment->transaction()->paid(),
2163
-                'txn_status'                   => $payment->transaction()->status_ID(),
2164
-                'pay_status'                   => $payment->STS_ID(),
2165
-                'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2166
-                'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2167
-            ];
2168
-        }
2169
-
2170
-        $this->_get_payment_status_array();
2171
-        return [
2172
-            'amount'           => $payment->amount(),
2173
-            'total_paid'       => $payment->transaction()->paid(),
2174
-            'txn_status'       => $payment->transaction()->status_ID(),
2175
-            'pay_status'       => $payment->STS_ID(),
2176
-            'PAY_ID'           => $payment->ID(),
2177
-            'STS_ID'           => $payment->STS_ID(),
2178
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2179
-            'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2180
-            'method'           => strtoupper($payment->source()),
2181
-            'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2182
-            'gateway'          => $payment->payment_method()
2183
-                ? $payment->payment_method()->admin_name()
2184
-                : esc_html__('Unknown', 'event_espresso'),
2185
-            'gateway_response' => $payment->gateway_response(),
2186
-            'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2187
-            'po_number'        => $payment->po_number(),
2188
-            'extra_accntng'    => $payment->extra_accntng(),
2189
-            'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2190
-        ];
2191
-    }
2192
-
2193
-
2194
-    /**
2195
-     * delete_payment
2196
-     *    delete a payment or refund made towards a transaction
2197
-     *
2198
-     * @access public
2199
-     * @return void
2200
-     * @throws EE_Error
2201
-     * @throws InvalidArgumentException
2202
-     * @throws ReflectionException
2203
-     * @throws InvalidDataTypeException
2204
-     * @throws InvalidInterfaceException
2205
-     */
2206
-    public function delete_payment()
2207
-    {
2208
-        $json_response_data = ['return_data' => false];
2209
-        $PAY_ID = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2210
-
2211
-        $can_delete         = EE_Registry::instance()->CAP->current_user_can(
2212
-            'ee_delete_payments',
2213
-            'delete_payment_from_registration_details'
2214
-        );
2215
-        if ($PAY_ID && $can_delete) {
2216
-            $delete_txn_reg_status_change = $this->request->getRequestParam(
2217
-                'delete_txn_reg_status_change',
2218
-                false,
2219
-                'bool'
2220
-            );
2221
-            $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2222
-            if ($payment instanceof EE_Payment) {
2223
-                $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2224
-                /** @type EE_Transaction_Payments $transaction_payments */
2225
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2226
-                if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2227
-                    $json_response_data['return_data'] = $this->_build_payment_json_response(
2228
-                        $payment,
2229
-                        $REG_IDs,
2230
-                        $delete_txn_reg_status_change
2231
-                    );
2232
-                    if ($delete_txn_reg_status_change) {
2233
-                        // MAKE sure we also add the delete_txn_req_status_change to the
2234
-                        // request data because that's how messages will be looking for it.
2235
-                        $this->request->setRequestParam('txn_reg_status_change', $delete_txn_reg_status_change);
2236
-                        $this->_maybe_send_notifications();
2237
-                        $this->_process_registration_status_change($payment->transaction(), $REG_IDs);
2238
-                    }
2239
-                }
2240
-            } else {
2241
-                EE_Error::add_error(
2242
-                    esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2243
-                    __FILE__,
2244
-                    __FUNCTION__,
2245
-                    __LINE__
2246
-                );
2247
-            }
2248
-        } elseif ($can_delete) {
2249
-            EE_Error::add_error(
2250
-                esc_html__(
2251
-                    'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2252
-                    'event_espresso'
2253
-                ),
2254
-                __FILE__,
2255
-                __FUNCTION__,
2256
-                __LINE__
2257
-            );
2258
-        } else {
2259
-            EE_Error::add_error(
2260
-                esc_html__(
2261
-                    'You do not have access to delete a payment.',
2262
-                    'event_espresso'
2263
-                ),
2264
-                __FILE__,
2265
-                __FUNCTION__,
2266
-                __LINE__
2267
-            );
2268
-        }
2269
-        $notices              = EE_Error::get_notices(false, false, false);
2270
-        $this->_template_args = [
2271
-            'data'      => $json_response_data,
2272
-            'success'   => $notices['success'],
2273
-            'error'     => $notices['errors'],
2274
-            'attention' => $notices['attention'],
2275
-        ];
2276
-        $this->_return_json();
2277
-    }
2278
-
2279
-
2280
-    /**
2281
-     * _registration_payment_data_array
2282
-     * adds info for 'owing' and 'paid' for each registration to the json response
2283
-     *
2284
-     * @access protected
2285
-     * @param array $REG_IDs
2286
-     * @return array
2287
-     * @throws EE_Error
2288
-     * @throws InvalidArgumentException
2289
-     * @throws InvalidDataTypeException
2290
-     * @throws InvalidInterfaceException
2291
-     * @throws ReflectionException
2292
-     */
2293
-    protected function _registration_payment_data_array($REG_IDs)
2294
-    {
2295
-        $registration_payment_data = [];
2296
-        // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2297
-        if (! empty($REG_IDs)) {
2298
-            $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2299
-            foreach ($registrations as $registration) {
2300
-                if ($registration instanceof EE_Registration) {
2301
-                    $registration_payment_data[ $registration->ID() ] = [
2302
-                        'paid'  => $registration->pretty_paid(),
2303
-                        'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2304
-                    ];
2305
-                }
2306
-            }
2307
-        }
2308
-
2309
-        return $registration_payment_data;
2310
-    }
2311
-
2312
-
2313
-    /**
2314
-     * _maybe_send_notifications
2315
-     * determines whether or not the admin has indicated that notifications should be sent.
2316
-     * If so, will toggle a filter switch for delivering registration notices.
2317
-     * If passed an EE_Payment object, then it will trigger payment notifications instead.
2318
-     *
2319
-     * @access protected
2320
-     * @param EE_Payment | null $payment
2321
-     */
2322
-    protected function _maybe_send_notifications($payment = null)
2323
-    {
2324
-        switch ($payment instanceof EE_Payment) {
2325
-            // payment notifications
2326
-            case true:
2327
-                if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2328
-                    $this->_process_payment_notification($payment);
2329
-                }
2330
-                break;
2331
-            // registration notifications
2332
-            case false:
2333
-                if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2334
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2335
-                }
2336
-                break;
2337
-        }
2338
-    }
2339
-
2340
-
2341
-    /**
2342
-     * _send_payment_reminder
2343
-     *    generates HTML for the View Transaction Details Admin page
2344
-     *
2345
-     * @access protected
2346
-     * @return void
2347
-     * @throws EE_Error
2348
-     * @throws InvalidArgumentException
2349
-     * @throws InvalidDataTypeException
2350
-     * @throws InvalidInterfaceException
2351
-     */
2352
-    protected function _send_payment_reminder()
2353
-    {
2354
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2355
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2356
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2357
-        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2358
-        do_action(
2359
-            'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2360
-            $transaction
2361
-        );
2362
-        $this->_redirect_after_action(
2363
-            false,
2364
-            esc_html__('payment reminder', 'event_espresso'),
2365
-            esc_html__('sent', 'event_espresso'),
2366
-            $query_args,
2367
-            true
2368
-        );
2369
-    }
2370
-
2371
-
2372
-    /**
2373
-     *  get_transactions
2374
-     *    get transactions for given parameters (used by list table)
2375
-     *
2376
-     * @param int     $per_page how many transactions displayed per page
2377
-     * @param boolean $count   return the count or objects
2378
-     * @param string  $view
2379
-     * @return EE_Transaction[]|int int = count || array of transaction objects
2380
-     * @throws EE_Error
2381
-     * @throws InvalidArgumentException
2382
-     * @throws InvalidDataTypeException
2383
-     * @throws InvalidInterfaceException
2384
-     */
2385
-    public function get_transactions($per_page, $count = false, $view = '')
2386
-    {
2387
-        $start_date = wp_strip_all_tags(
2388
-            $this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2389
-        );
2390
-        $end_date = wp_strip_all_tags(
2391
-            $this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2392
-        );
2393
-
2394
-        // make sure our timestamps start and end right at the boundaries for each day
2395
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2396
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2397
-
2398
-
2399
-        // convert to timestamps
2400
-        $start_date = strtotime($start_date);
2401
-        $end_date   = strtotime($end_date);
2402
-
2403
-        // makes sure start date is the lowest value and vice versa
2404
-        $start_date = min($start_date, $end_date);
2405
-        $end_date   = max($start_date, $end_date);
2406
-
2407
-        // convert to correct format for query
2408
-        $start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2409
-            'TXN_timestamp',
2410
-            date('Y-m-d H:i:s', $start_date),
2411
-            'Y-m-d H:i:s'
2412
-        );
2413
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2414
-            'TXN_timestamp',
2415
-            date('Y-m-d H:i:s', $end_date),
2416
-            'Y-m-d H:i:s'
2417
-        );
2418
-
2419
-
2420
-        // set orderby
2421
-        $orderby = $this->request->getRequestParam('orderby');
2422
-
2423
-        switch ($orderby) {
2424
-            case 'TXN_ID':
2425
-                break;
2426
-            case 'ATT_fname':
2427
-                $orderby = 'Registration.Attendee.ATT_fname';
2428
-                break;
2429
-            case 'event_name':
2430
-                $orderby = 'Registration.Event.EVT_name';
2431
-                break;
2432
-            default: // 'TXN_timestamp'
2433
-                $orderby = 'TXN_timestamp';
2434
-        }
2435
-
2436
-        $sort         = $this->request->getRequestParam('order', 'DESC');
2437
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
2438
-
2439
-        $per_page = absint($per_page) ? $per_page : 10;
2440
-        $per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2441
-
2442
-        $offset = ($current_page - 1) * $per_page;
2443
-        $limit  = [$offset, $per_page];
2444
-
2445
-        $_where = [
2446
-            'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2447
-            'Registration.REG_count' => 1,
2448
-        ];
2449
-
2450
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2451
-        if ($EVT_ID) {
2452
-            $_where['Registration.EVT_ID'] = $EVT_ID;
2453
-        }
2454
-
2455
-        $search_term = $this->request->getRequestParam('s');
2456
-        if ($search_term) {
2457
-            $search_term = '%' . $search_term . '%';
2458
-            $_where['OR']  = [
2459
-                'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2460
-                'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2461
-                'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2462
-                'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2463
-                'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2464
-                'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2465
-                'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2466
-                'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2467
-                'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2468
-                'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2469
-                'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2470
-                'Registration.REG_final_price'        => ['LIKE', $search_term],
2471
-                'Registration.REG_code'               => ['LIKE', $search_term],
2472
-                'Registration.REG_count'              => ['LIKE', $search_term],
2473
-                'Registration.REG_group_size'         => ['LIKE', $search_term],
2474
-                'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2475
-                'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2476
-                'Payment.PAY_source'                  => ['LIKE', $search_term],
2477
-                'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2478
-                'TXN_session_data'                    => ['LIKE', $search_term],
2479
-                'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2480
-            ];
2481
-        }
2482
-
2483
-        $status = $this->request->getRequestParam('status');
2484
-        // failed transactions
2485
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2486
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2487
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2488
-
2489
-        if ($failed) {
2490
-            $_where['STS_ID'] = EEM_Transaction::failed_status_code;
2491
-        } elseif ($abandoned) {
2492
-            $_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2493
-        } elseif ($incomplete) {
2494
-            $_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2495
-        } else {
2496
-            $_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2497
-            $_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2498
-        }
2499
-
2500
-        $query_params = apply_filters(
2501
-            'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2502
-            [
2503
-                $_where,
2504
-                'order_by'                 => [$orderby => $sort],
2505
-                'limit'                    => $limit,
2506
-                'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2507
-            ],
2508
-            $this->request->requestParams(),
2509
-            $view,
2510
-            $count
2511
-        );
2512
-
2513
-        return $count
2514
-            ? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2515
-            : EEM_Transaction::instance()->get_all($query_params);
2516
-    }
2517
-
2518
-
2519
-    /**
2520
-     * @throws EE_Error
2521
-     * @throws InvalidArgumentException
2522
-     * @throws InvalidDataTypeException
2523
-     * @throws InvalidInterfaceException
2524
-     * @throws ReflectionException
2525
-     * @throws RuntimeException
2526
-     * @since 4.9.79.p
2527
-     */
2528
-    public function recalculateLineItems()
2529
-    {
2530
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2531
-        /** @var EE_Transaction $transaction */
2532
-        $transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2533
-        $success         = $transaction->recalculateLineItems();
2534
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2535
-        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2536
-        $this->_redirect_after_action(
2537
-            $success,
2538
-            esc_html__('Transaction taxes and totals', 'event_espresso'),
2539
-            esc_html__('recalculated', 'event_espresso'),
2540
-            $query_args,
2541
-            true
2542
-        );
2543
-    }
16
+	/**
17
+	 * @var EE_Transaction
18
+	 */
19
+	private $_transaction;
20
+
21
+	/**
22
+	 * @var EE_Session
23
+	 */
24
+	private $_session;
25
+
26
+	/**
27
+	 * @var array $_txn_status
28
+	 */
29
+	private static $_txn_status;
30
+
31
+	/**
32
+	 * @var array $_pay_status
33
+	 */
34
+	private static $_pay_status;
35
+
36
+	/**
37
+	 * @var array $_existing_reg_payment_REG_IDs
38
+	 */
39
+	protected $_existing_reg_payment_REG_IDs;
40
+
41
+
42
+	/**
43
+	 *    _init_page_props
44
+	 *
45
+	 * @return void
46
+	 */
47
+	protected function _init_page_props()
48
+	{
49
+		$this->page_slug        = TXN_PG_SLUG;
50
+		$this->page_label       = esc_html__('Transactions', 'event_espresso');
51
+		$this->_admin_base_url  = TXN_ADMIN_URL;
52
+		$this->_admin_base_path = TXN_ADMIN;
53
+	}
54
+
55
+
56
+	/**
57
+	 *    _ajax_hooks
58
+	 *
59
+	 * @return void
60
+	 */
61
+	protected function _ajax_hooks()
62
+	{
63
+		add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
64
+		add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
65
+		add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
66
+	}
67
+
68
+
69
+	/**
70
+	 *    _define_page_props
71
+	 *
72
+	 * @return void
73
+	 */
74
+	protected function _define_page_props()
75
+	{
76
+		$this->_admin_page_title = $this->page_label;
77
+		$this->_labels           = [
78
+			'buttons' => [
79
+				'add'    => esc_html__('Add New Transaction', 'event_espresso'),
80
+				'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
81
+				'delete' => esc_html__('Delete Transaction', 'event_espresso'),
82
+			],
83
+		];
84
+	}
85
+
86
+
87
+	/**
88
+	 *        grab url requests and route them
89
+	 *
90
+	 * @access private
91
+	 * @return void
92
+	 * @throws EE_Error
93
+	 * @throws InvalidArgumentException
94
+	 * @throws InvalidDataTypeException
95
+	 * @throws InvalidInterfaceException
96
+	 */
97
+	public function _set_page_routes()
98
+	{
99
+
100
+		$this->_set_transaction_status_array();
101
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
102
+
103
+		$this->_page_routes = [
104
+
105
+			'default' => [
106
+				'func'       => '_transactions_overview_list_table',
107
+				'capability' => 'ee_read_transactions',
108
+			],
109
+
110
+			'view_transaction' => [
111
+				'func'       => '_transaction_details',
112
+				'capability' => 'ee_read_transaction',
113
+				'obj_id'     => $TXN_ID,
114
+			],
115
+
116
+			'send_payment_reminder' => [
117
+				'func'       => '_send_payment_reminder',
118
+				'noheader'   => true,
119
+				'capability' => 'ee_send_message',
120
+			],
121
+
122
+			'espresso_apply_payment' => [
123
+				'func'       => 'apply_payments_or_refunds',
124
+				'noheader'   => true,
125
+				'capability' => 'ee_edit_payments',
126
+			],
127
+
128
+			'espresso_apply_refund' => [
129
+				'func'       => 'apply_payments_or_refunds',
130
+				'noheader'   => true,
131
+				'capability' => 'ee_edit_payments',
132
+			],
133
+
134
+			'espresso_delete_payment' => [
135
+				'func'       => 'delete_payment',
136
+				'noheader'   => true,
137
+				'capability' => 'ee_delete_payments',
138
+			],
139
+
140
+			'espresso_recalculate_line_items' => [
141
+				'func'       => 'recalculateLineItems',
142
+				'noheader'   => true,
143
+				'capability' => 'ee_edit_payments',
144
+			],
145
+
146
+		];
147
+	}
148
+
149
+
150
+	protected function _set_page_config()
151
+	{
152
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
153
+		$this->_page_config = [
154
+			'default'          => [
155
+				'nav'           => [
156
+					'label' => esc_html__('Overview', 'event_espresso'),
157
+					'order' => 10,
158
+				],
159
+				'list_table'    => 'EE_Admin_Transactions_List_Table',
160
+				'help_tabs'     => [
161
+					'transactions_overview_help_tab'                       => [
162
+						'title'    => esc_html__('Transactions Overview', 'event_espresso'),
163
+						'filename' => 'transactions_overview',
164
+					],
165
+					'transactions_overview_table_column_headings_help_tab' => [
166
+						'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
167
+						'filename' => 'transactions_overview_table_column_headings',
168
+					],
169
+					'transactions_overview_views_filters_help_tab'         => [
170
+						'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
171
+						'filename' => 'transactions_overview_views_filters_search',
172
+					],
173
+				],
174
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
175
+				// 'help_tour'     => array('Transactions_Overview_Help_Tour'),
176
+				/**
177
+				 * commented out because currently we are not displaying tips for transaction list table status but this
178
+				 * may change in a later iteration so want to keep the code for then.
179
+				 */
180
+				// 'qtips' => array( 'Transactions_List_Table_Tips' ),
181
+				'require_nonce' => false,
182
+			],
183
+			'view_transaction' => [
184
+				'nav'       => [
185
+					'label'      => esc_html__('View Transaction', 'event_espresso'),
186
+					'order'      => 5,
187
+					'url'        => $TXN_ID
188
+						? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
189
+						: $this->_admin_base_url,
190
+					'persistent' => false,
191
+				],
192
+				'help_tabs' => [
193
+					'transactions_view_transaction_help_tab'                                              => [
194
+						'title'    => esc_html__('View Transaction', 'event_espresso'),
195
+						'filename' => 'transactions_view_transaction',
196
+					],
197
+					'transactions_view_transaction_transaction_details_table_help_tab'                    => [
198
+						'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
199
+						'filename' => 'transactions_view_transaction_transaction_details_table',
200
+					],
201
+					'transactions_view_transaction_attendees_registered_help_tab'                         => [
202
+						'title'    => esc_html__('Attendees Registered', 'event_espresso'),
203
+						'filename' => 'transactions_view_transaction_attendees_registered',
204
+					],
205
+					'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
206
+						'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
207
+						'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
208
+					],
209
+				],
210
+				'qtips'     => ['Transaction_Details_Tips'],
211
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
212
+				// 'help_tour' => array('Transaction_Details_Help_Tour'),
213
+				'metaboxes' => ['_transaction_details_metaboxes'],
214
+
215
+				'require_nonce' => false,
216
+			],
217
+		];
218
+	}
219
+
220
+
221
+	/**
222
+	 * The below methods aren't used by this class currently
223
+	 */
224
+	protected function _add_screen_options()
225
+	{
226
+		// noop
227
+	}
228
+
229
+
230
+	protected function _add_feature_pointers()
231
+	{
232
+		// noop
233
+	}
234
+
235
+
236
+	public function admin_init()
237
+	{
238
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
239
+		$event_name = $this->request->getRequestParam('event_name');
240
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
241
+		// IF a registration was JUST added via the admin...
242
+		if ($EVT_ID && $event_name && $redirect_from) {
243
+			// then set a cookie so that we can block any attempts to use
244
+			// the back button as a way to enter another registration.
245
+			setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
246
+			// and update the global
247
+			$_COOKIE['ee_registration_added'] = $EVT_ID;
248
+		}
249
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
250
+			'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
251
+			'event_espresso'
252
+		);
253
+		EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
254
+			'An error occurred! Please refresh the page and try again.',
255
+			'event_espresso'
256
+		);
257
+		EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
258
+		EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
259
+		EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
260
+		EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
261
+			'This transaction has been overpaid ! Payments Total',
262
+			'event_espresso'
263
+		);
264
+	}
265
+
266
+
267
+	public function admin_notices()
268
+	{
269
+		// noop
270
+	}
271
+
272
+
273
+	public function admin_footer_scripts()
274
+	{
275
+		// noop
276
+	}
277
+
278
+
279
+	/**
280
+	 * _set_transaction_status_array
281
+	 * sets list of transaction statuses
282
+	 *
283
+	 * @access private
284
+	 * @return void
285
+	 * @throws EE_Error
286
+	 * @throws InvalidArgumentException
287
+	 * @throws InvalidDataTypeException
288
+	 * @throws InvalidInterfaceException
289
+	 */
290
+	private function _set_transaction_status_array()
291
+	{
292
+		self::$_txn_status = EEM_Transaction::instance()->status_array(true);
293
+	}
294
+
295
+
296
+	/**
297
+	 * get_transaction_status_array
298
+	 * return the transaction status array for wp_list_table
299
+	 *
300
+	 * @access public
301
+	 * @return array
302
+	 */
303
+	public function get_transaction_status_array()
304
+	{
305
+		return self::$_txn_status;
306
+	}
307
+
308
+
309
+	/**
310
+	 *    get list of payment statuses
311
+	 *
312
+	 * @access private
313
+	 * @return void
314
+	 * @throws EE_Error
315
+	 * @throws InvalidArgumentException
316
+	 * @throws InvalidDataTypeException
317
+	 * @throws InvalidInterfaceException
318
+	 */
319
+	private function _get_payment_status_array()
320
+	{
321
+		self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
322
+		$this->_template_args['payment_status'] = self::$_pay_status;
323
+	}
324
+
325
+
326
+	/**
327
+	 *    _add_screen_options_default
328
+	 *
329
+	 * @access protected
330
+	 * @return void
331
+	 * @throws InvalidArgumentException
332
+	 * @throws InvalidDataTypeException
333
+	 * @throws InvalidInterfaceException
334
+	 */
335
+	protected function _add_screen_options_default()
336
+	{
337
+		$this->_per_page_screen_option();
338
+	}
339
+
340
+
341
+	/**
342
+	 * load_scripts_styles
343
+	 *
344
+	 * @access public
345
+	 * @return void
346
+	 */
347
+	public function load_scripts_styles()
348
+	{
349
+		// enqueue style
350
+		wp_register_style(
351
+			'espresso_txn',
352
+			TXN_ASSETS_URL . 'espresso_transactions_admin.css',
353
+			[],
354
+			EVENT_ESPRESSO_VERSION
355
+		);
356
+		wp_enqueue_style('espresso_txn');
357
+		// scripts
358
+		wp_register_script(
359
+			'espresso_txn',
360
+			TXN_ASSETS_URL . 'espresso_transactions_admin.js',
361
+			[
362
+				'ee_admin_js',
363
+				'ee-datepicker',
364
+				'jquery-ui-datepicker',
365
+				'jquery-ui-draggable',
366
+				'ee-dialog',
367
+				'ee-accounting',
368
+				'ee-serialize-full-array',
369
+			],
370
+			EVENT_ESPRESSO_VERSION,
371
+			true
372
+		);
373
+		wp_enqueue_script('espresso_txn');
374
+	}
375
+
376
+
377
+	/**
378
+	 *    load_scripts_styles_view_transaction
379
+	 *
380
+	 * @access public
381
+	 * @return void
382
+	 */
383
+	public function load_scripts_styles_view_transaction()
384
+	{
385
+		// styles
386
+		wp_enqueue_style('espresso-ui-theme');
387
+	}
388
+
389
+
390
+	/**
391
+	 *    load_scripts_styles_default
392
+	 *
393
+	 * @access public
394
+	 * @return void
395
+	 */
396
+	public function load_scripts_styles_default()
397
+	{
398
+		// styles
399
+		wp_enqueue_style('espresso-ui-theme');
400
+	}
401
+
402
+
403
+	/**
404
+	 *    _set_list_table_views_default
405
+	 *
406
+	 * @access protected
407
+	 * @return void
408
+	 */
409
+	protected function _set_list_table_views_default()
410
+	{
411
+		$this->_views = [
412
+			'all'        => [
413
+				'slug'  => 'all',
414
+				'label' => esc_html__('View All Transactions', 'event_espresso'),
415
+				'count' => 0,
416
+			],
417
+			'abandoned'  => [
418
+				'slug'  => 'abandoned',
419
+				'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
420
+				'count' => 0,
421
+			],
422
+			'incomplete' => [
423
+				'slug'  => 'incomplete',
424
+				'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
425
+				'count' => 0,
426
+			],
427
+		];
428
+		if (
429
+			/**
430
+			 * Filters whether a link to the "Failed Transactions" list table
431
+			 * appears on the Transactions Admin Page list table.
432
+			 * List display can be turned back on via the following:
433
+			 * add_filter(
434
+			 *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
435
+			 *     '__return_true'
436
+			 * );
437
+			 *
438
+			 * @param boolean                 $display_failed_txns_list
439
+			 * @param Transactions_Admin_Page $this
440
+			 * @since 4.9.70.p
441
+			 */
442
+			apply_filters(
443
+				'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
444
+				false,
445
+				$this
446
+			)
447
+		) {
448
+			$this->_views['failed'] = [
449
+				'slug'  => 'failed',
450
+				'label' => esc_html__('Failed Transactions', 'event_espresso'),
451
+				'count' => 0,
452
+			];
453
+		}
454
+	}
455
+
456
+
457
+	/**
458
+	 * _set_transaction_object
459
+	 * This sets the _transaction property for the transaction details screen
460
+	 *
461
+	 * @access private
462
+	 * @return void
463
+	 * @throws EE_Error
464
+	 * @throws InvalidArgumentException
465
+	 * @throws RuntimeException
466
+	 * @throws InvalidDataTypeException
467
+	 * @throws InvalidInterfaceException
468
+	 * @throws ReflectionException
469
+	 */
470
+	private function _set_transaction_object()
471
+	{
472
+		if ($this->_transaction instanceof EE_Transaction) {
473
+			return;
474
+		} //get out we've already set the object
475
+
476
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
477
+
478
+		// get transaction object
479
+		$this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
480
+		$this->_session     = $this->_transaction instanceof EE_Transaction
481
+			? $this->_transaction->session_data()
482
+			: null;
483
+		if ($this->_transaction instanceof EE_Transaction) {
484
+			$this->_transaction->verify_abandoned_transaction_status();
485
+		}
486
+
487
+		if (! $this->_transaction instanceof EE_Transaction) {
488
+			$error_msg = sprintf(
489
+				esc_html__(
490
+					'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
491
+					'event_espresso'
492
+				),
493
+				$TXN_ID
494
+			);
495
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
496
+		}
497
+	}
498
+
499
+
500
+	/**
501
+	 *    _transaction_legend_items
502
+	 *
503
+	 * @access protected
504
+	 * @return array
505
+	 * @throws EE_Error
506
+	 * @throws InvalidArgumentException
507
+	 * @throws ReflectionException
508
+	 * @throws InvalidDataTypeException
509
+	 * @throws InvalidInterfaceException
510
+	 */
511
+	protected function _transaction_legend_items()
512
+	{
513
+		EE_Registry::instance()->load_helper('MSG_Template');
514
+		$items = [];
515
+
516
+		if (
517
+			EE_Registry::instance()->CAP->current_user_can(
518
+				'ee_read_global_messages',
519
+				'view_filtered_messages'
520
+			)
521
+		) {
522
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
523
+			if (
524
+				is_array($related_for_icon)
525
+				&& isset($related_for_icon['css_class'], $related_for_icon['label'])
526
+			) {
527
+				$items['view_related_messages'] = [
528
+					'class' => $related_for_icon['css_class'],
529
+					'desc'  => $related_for_icon['label'],
530
+				];
531
+			}
532
+		}
533
+
534
+		$items = apply_filters(
535
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
536
+			array_merge(
537
+				$items,
538
+				[
539
+					'view_details'          => [
540
+						'class' => 'dashicons dashicons-cart',
541
+						'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
542
+					],
543
+					'view_invoice'          => [
544
+						'class' => 'dashicons dashicons-media-spreadsheet',
545
+						'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
546
+					],
547
+					'view_receipt'          => [
548
+						'class' => 'dashicons dashicons-media-default',
549
+						'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
550
+					],
551
+					'view_registration'     => [
552
+						'class' => 'dashicons dashicons-clipboard',
553
+						'desc'  => esc_html__('View Registration Details', 'event_espresso'),
554
+					],
555
+					'payment_overview_link' => [
556
+						'class' => 'dashicons dashicons-money',
557
+						'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
558
+					],
559
+				]
560
+			)
561
+		);
562
+
563
+		if (
564
+			EEH_MSG_Template::is_mt_active('payment_reminder')
565
+			&& EE_Registry::instance()->CAP->current_user_can(
566
+				'ee_send_message',
567
+				'espresso_transactions_send_payment_reminder'
568
+			)
569
+		) {
570
+			$items['send_payment_reminder'] = [
571
+				'class' => 'dashicons dashicons-email-alt',
572
+				'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
573
+			];
574
+		} else {
575
+			$items['blank*'] = [
576
+				'class' => '',
577
+				'desc'  => '',
578
+			];
579
+		}
580
+		$more_items = apply_filters(
581
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
582
+			[
583
+				'overpaid'   => [
584
+					'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::overpaid_status_code,
585
+					'desc'  => EEH_Template::pretty_status(
586
+						EEM_Transaction::overpaid_status_code,
587
+						false,
588
+						'sentence'
589
+					),
590
+				],
591
+				'complete'   => [
592
+					'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::complete_status_code,
593
+					'desc'  => EEH_Template::pretty_status(
594
+						EEM_Transaction::complete_status_code,
595
+						false,
596
+						'sentence'
597
+					),
598
+				],
599
+				'incomplete' => [
600
+					'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::incomplete_status_code,
601
+					'desc'  => EEH_Template::pretty_status(
602
+						EEM_Transaction::incomplete_status_code,
603
+						false,
604
+						'sentence'
605
+					),
606
+				],
607
+				'abandoned'  => [
608
+					'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::abandoned_status_code,
609
+					'desc'  => EEH_Template::pretty_status(
610
+						EEM_Transaction::abandoned_status_code,
611
+						false,
612
+						'sentence'
613
+					),
614
+				],
615
+				'failed'     => [
616
+					'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::failed_status_code,
617
+					'desc'  => EEH_Template::pretty_status(
618
+						EEM_Transaction::failed_status_code,
619
+						false,
620
+						'sentence'
621
+					),
622
+				],
623
+			]
624
+		);
625
+
626
+		return array_merge($items, $more_items);
627
+	}
628
+
629
+
630
+	/**
631
+	 *    _transactions_overview_list_table
632
+	 *
633
+	 * @access protected
634
+	 * @return void
635
+	 * @throws DomainException
636
+	 * @throws EE_Error
637
+	 * @throws InvalidArgumentException
638
+	 * @throws InvalidDataTypeException
639
+	 * @throws InvalidInterfaceException
640
+	 * @throws ReflectionException
641
+	 */
642
+	protected function _transactions_overview_list_table()
643
+	{
644
+		$this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
645
+
646
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
647
+		$event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
648
+		$this->_template_args['admin_page_header'] = $event instanceof EE_Event
649
+			? sprintf(
650
+				esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
651
+				'<h3>',
652
+				'<a href="'
653
+				. EE_Admin_Page::add_query_args_and_nonce(
654
+					['action' => 'edit', 'post' => $event->ID()],
655
+					EVENTS_ADMIN_URL
656
+				)
657
+				. '" title="'
658
+				. esc_attr__('Click to Edit event', 'event_espresso')
659
+				. '">' . $event->name() . '</a>',
660
+				'</h3>'
661
+			)
662
+			: '';
663
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
664
+		$this->display_admin_list_table_page_with_no_sidebar();
665
+	}
666
+
667
+
668
+	/**
669
+	 *    _transaction_details
670
+	 * generates HTML for the View Transaction Details Admin page
671
+	 *
672
+	 * @access protected
673
+	 * @return void
674
+	 * @throws DomainException
675
+	 * @throws EE_Error
676
+	 * @throws InvalidArgumentException
677
+	 * @throws InvalidDataTypeException
678
+	 * @throws InvalidInterfaceException
679
+	 * @throws RuntimeException
680
+	 * @throws ReflectionException
681
+	 */
682
+	protected function _transaction_details()
683
+	{
684
+		do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
685
+
686
+		$this->_set_transaction_status_array();
687
+
688
+		$this->_template_args                      = [];
689
+		$this->_template_args['transactions_page'] = $this->_wp_page_slug;
690
+
691
+		$this->_set_transaction_object();
692
+
693
+		if (! $this->_transaction instanceof EE_Transaction) {
694
+			return;
695
+		}
696
+
697
+		$this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
698
+		$this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
699
+
700
+		$this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
701
+		$this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
702
+
703
+		$this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
704
+		$this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
705
+		$this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->status_ID();
706
+
707
+		$this->_template_args['grand_total'] = $this->_transaction->total();
708
+		$this->_template_args['total_paid']  = $this->_transaction->paid();
709
+
710
+		$amount_due                         = $this->_transaction->total() - $this->_transaction->paid();
711
+		$this->_template_args['amount_due'] = EEH_Template::format_currency(
712
+			$amount_due,
713
+			true
714
+		);
715
+		if (EE_Registry::instance()->CFG->currency->sign_b4) {
716
+			$this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign
717
+												  . $this->_template_args['amount_due'];
718
+		} else {
719
+			$this->_template_args['amount_due'] .= EE_Registry::instance()->CFG->currency->sign;
720
+		}
721
+		$this->_template_args['amount_due_class'] = '';
722
+
723
+		if ($this->_transaction->paid() === $this->_transaction->total()) {
724
+			// paid in full
725
+			$this->_template_args['amount_due'] = false;
726
+		} elseif ($this->_transaction->paid() > $this->_transaction->total()) {
727
+			// overpaid
728
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
729
+		} elseif ($this->_transaction->total() > (float) 0) {
730
+			if ($this->_transaction->paid() > (float) 0) {
731
+				// monies owing
732
+				$this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
733
+			} elseif ($this->_transaction->paid() === (float) 0) {
734
+				// no payments made yet
735
+				$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
736
+			}
737
+		} elseif ($this->_transaction->total() === (float) 0) {
738
+			// free event
739
+			$this->_template_args['amount_due'] = false;
740
+		}
741
+
742
+		$payment_method = $this->_transaction->payment_method();
743
+
744
+		$this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
745
+			? $payment_method->admin_name()
746
+			: esc_html__('Unknown', 'event_espresso');
747
+
748
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
749
+		// link back to overview
750
+		$this->_template_args['txn_overview_url'] = $this->request->getServerParam(
751
+			'HTTP_REFERER',
752
+			TXN_ADMIN_URL
753
+		);
754
+
755
+
756
+		// next link
757
+		$next_txn                                 = $this->_transaction->next(
758
+			null,
759
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
760
+			'TXN_ID'
761
+		);
762
+		$this->_template_args['next_transaction'] = $next_txn
763
+			? $this->_next_link(
764
+				EE_Admin_Page::add_query_args_and_nonce(
765
+					['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
766
+					TXN_ADMIN_URL
767
+				),
768
+				'dashicons dashicons-arrow-right ee-icon-size-22'
769
+			)
770
+			: '';
771
+		// previous link
772
+		$previous_txn                                 = $this->_transaction->previous(
773
+			null,
774
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
775
+			'TXN_ID'
776
+		);
777
+		$this->_template_args['previous_transaction'] = $previous_txn
778
+			? $this->_previous_link(
779
+				EE_Admin_Page::add_query_args_and_nonce(
780
+					['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
781
+					TXN_ADMIN_URL
782
+				),
783
+				'dashicons dashicons-arrow-left ee-icon-size-22'
784
+			)
785
+			: '';
786
+
787
+		$EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
788
+		$event_name    = $this->request->getRequestParam('event_name');
789
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
790
+
791
+		// were we just redirected here after adding a new registration ???
792
+		if ($EVT_ID && $event_name && $redirect_from) {
793
+			if (
794
+				EE_Registry::instance()->CAP->current_user_can(
795
+					'ee_edit_registrations',
796
+					'espresso_registrations_new_registration',
797
+					$EVT_ID
798
+				)
799
+			) {
800
+				$this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button--primary" href="';
801
+				$this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
802
+					[
803
+						'page'     => 'espresso_registrations',
804
+						'action'   => 'new_registration',
805
+						'return'   => 'default',
806
+						'TXN_ID'   => $this->_transaction->ID(),
807
+						'event_id' => $EVT_ID,
808
+					],
809
+					REG_ADMIN_URL
810
+				);
811
+				$this->_admin_page_title .= '">';
812
+
813
+				$this->_admin_page_title .= sprintf(
814
+					esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
815
+					htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
816
+				);
817
+				$this->_admin_page_title .= '</a>';
818
+			}
819
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
820
+		}
821
+		// grab messages at the last second
822
+		$this->_template_args['notices'] = EE_Error::get_notices();
823
+		// path to template
824
+		$template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
825
+		$this->_template_args['admin_page_header'] = EEH_Template::display_template(
826
+			$template_path,
827
+			$this->_template_args,
828
+			true
829
+		);
830
+
831
+		// the details template wrapper
832
+		$this->display_admin_page_with_sidebar();
833
+	}
834
+
835
+
836
+	/**
837
+	 *        _transaction_details_metaboxes
838
+	 *
839
+	 * @access protected
840
+	 * @return void
841
+	 * @throws EE_Error
842
+	 * @throws InvalidArgumentException
843
+	 * @throws InvalidDataTypeException
844
+	 * @throws InvalidInterfaceException
845
+	 * @throws RuntimeException
846
+	 * @throws ReflectionException
847
+	 */
848
+	protected function _transaction_details_metaboxes()
849
+	{
850
+
851
+		$this->_set_transaction_object();
852
+
853
+		if (! $this->_transaction instanceof EE_Transaction) {
854
+			return;
855
+		}
856
+		$this->addMetaBox(
857
+			'edit-txn-details-mbox',
858
+			'<span>' . esc_html__('Transaction Details', 'event_espresso')
859
+			. '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
860
+			[$this, 'txn_details_meta_box'],
861
+			$this->_wp_page_slug
862
+		);
863
+		$this->addMetaBox(
864
+			'edit-txn-attendees-mbox',
865
+			'<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
866
+			. '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
867
+			[$this, 'txn_attendees_meta_box'],
868
+			$this->_wp_page_slug,
869
+			'normal',
870
+			'high',
871
+			['TXN_ID' => $this->_transaction->ID()]
872
+		);
873
+		$this->addMetaBox(
874
+			'edit-txn-registrant-mbox',
875
+			esc_html__('Primary Contact', 'event_espresso'),
876
+			[$this, 'txn_registrant_side_meta_box'],
877
+			$this->_wp_page_slug,
878
+			'side'
879
+		);
880
+		$this->addMetaBox(
881
+			'edit-txn-billing-info-mbox',
882
+			esc_html__('Billing Information', 'event_espresso'),
883
+			[$this, 'txn_billing_info_side_meta_box'],
884
+			$this->_wp_page_slug,
885
+			'side'
886
+		);
887
+	}
888
+
889
+
890
+	/**
891
+	 * Callback for transaction actions metabox.
892
+	 *
893
+	 * @param EE_Transaction|null $transaction
894
+	 * @return string
895
+	 * @throws DomainException
896
+	 * @throws EE_Error
897
+	 * @throws InvalidArgumentException
898
+	 * @throws InvalidDataTypeException
899
+	 * @throws InvalidInterfaceException
900
+	 * @throws ReflectionException
901
+	 * @throws RuntimeException
902
+	 */
903
+	public function getActionButtons(EE_Transaction $transaction = null)
904
+	{
905
+		$content = '';
906
+		$actions = [];
907
+		if (! $transaction instanceof EE_Transaction) {
908
+			return $content;
909
+		}
910
+		/** @var EE_Registration $primary_registration */
911
+		$primary_registration = $transaction->primary_registration();
912
+		$attendee             = $primary_registration instanceof EE_Registration
913
+			? $primary_registration->attendee()
914
+			: null;
915
+
916
+		if (
917
+			$attendee instanceof EE_Attendee
918
+			&& EE_Registry::instance()->CAP->current_user_can(
919
+				'ee_send_message',
920
+				'espresso_transactions_send_payment_reminder'
921
+			)
922
+		) {
923
+			$actions['payment_reminder'] =
924
+				EEH_MSG_Template::is_mt_active('payment_reminder')
925
+				&& $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
926
+				&& $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
927
+					? EEH_Template::get_button_or_link(
928
+						EE_Admin_Page::add_query_args_and_nonce(
929
+							[
930
+							'action'      => 'send_payment_reminder',
931
+							'TXN_ID'      => $this->_transaction->ID(),
932
+							'redirect_to' => 'view_transaction',
933
+							],
934
+							TXN_ADMIN_URL
935
+						),
936
+						esc_html__(' Send Payment Reminder', 'event_espresso'),
937
+						'button button--secondary',
938
+						'dashicons dashicons-email-alt'
939
+					)
940
+					: '';
941
+		}
942
+
943
+		if (
944
+			EE_Registry::instance()->CAP->current_user_can(
945
+				'ee_edit_payments',
946
+				'espresso_transactions_recalculate_line_items'
947
+			)
948
+		) {
949
+			$actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
950
+				EE_Admin_Page::add_query_args_and_nonce(
951
+					[
952
+						'action'      => 'espresso_recalculate_line_items',
953
+						'TXN_ID'      => $this->_transaction->ID(),
954
+						'redirect_to' => 'view_transaction',
955
+					],
956
+					TXN_ADMIN_URL
957
+				),
958
+				esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
959
+				'button button--secondary',
960
+				'dashicons dashicons-update'
961
+			);
962
+		}
963
+
964
+		if (
965
+			$primary_registration instanceof EE_Registration
966
+			&& EEH_MSG_Template::is_mt_active('receipt')
967
+		) {
968
+			$actions['receipt'] = EEH_Template::get_button_or_link(
969
+				$primary_registration->receipt_url(),
970
+				esc_html__('View Receipt', 'event_espresso'),
971
+				'button button--secondary',
972
+				'dashicons dashicons-media-text'
973
+			);
974
+		}
975
+
976
+		if (
977
+			$primary_registration instanceof EE_Registration
978
+			&& EEH_MSG_Template::is_mt_active('invoice')
979
+		) {
980
+			$actions['invoice'] = EEH_Template::get_button_or_link(
981
+				$primary_registration->invoice_url(),
982
+				esc_html__('View Invoice', 'event_espresso'),
983
+				'button button--secondary',
984
+				'dashicons dashicons-media-spreadsheet'
985
+			);
986
+		}
987
+		$actions = array_filter(
988
+			apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
989
+		);
990
+		if ($actions) {
991
+			// $content = '<ul>';
992
+			// $content .= '<li>' . implode('</li><li>', $actions) . '</li>';
993
+			// $content .= '</uL>';
994
+			$content .= implode('', $actions);
995
+		}
996
+		return $content;
997
+	}
998
+
999
+
1000
+	/**
1001
+	 * txn_details_meta_box
1002
+	 * generates HTML for the Transaction main meta box
1003
+	 *
1004
+	 * @return void
1005
+	 * @throws DomainException
1006
+	 * @throws EE_Error
1007
+	 * @throws InvalidArgumentException
1008
+	 * @throws InvalidDataTypeException
1009
+	 * @throws InvalidInterfaceException
1010
+	 * @throws RuntimeException
1011
+	 * @throws ReflectionException
1012
+	 */
1013
+	public function txn_details_meta_box()
1014
+	{
1015
+		$this->_set_transaction_object();
1016
+		$this->_template_args['TXN_ID']              = $this->_transaction->ID();
1017
+		$this->_template_args['attendee']            =
1018
+			$this->_transaction->primary_registration() instanceof EE_Registration
1019
+				? $this->_transaction->primary_registration()->attendee()
1020
+				: null;
1021
+		$this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1022
+			'ee_edit_payments',
1023
+			'apply_payment_or_refund_from_registration_details'
1024
+		);
1025
+		$this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1026
+			'ee_delete_payments',
1027
+			'delete_payment_from_registration_details'
1028
+		);
1029
+
1030
+		// get line table
1031
+		EEH_Autoloader::register_line_item_display_autoloaders();
1032
+		$Line_Item_Display                       = new EE_Line_Item_Display(
1033
+			'admin_table',
1034
+			'EE_Admin_Table_Line_Item_Display_Strategy'
1035
+		);
1036
+		$this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1037
+			$this->_transaction->total_line_item()
1038
+		);
1039
+		$this->_template_args['REG_code']        =
1040
+			$this->_transaction->primary_registration() instanceof EE_Registration
1041
+				? $this->_transaction->primary_registration()->reg_code()
1042
+				: null;
1043
+		// process taxes
1044
+		$taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1045
+		$this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1046
+
1047
+		$this->_template_args['grand_total']     = EEH_Template::format_currency(
1048
+			$this->_transaction->total(),
1049
+			false,
1050
+			false
1051
+		);
1052
+		$this->_template_args['grand_raw_total'] = $this->_transaction->total();
1053
+		$this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1054
+
1055
+		// process payment details
1056
+		$payments = $this->_transaction->payments();
1057
+		if (! empty($payments)) {
1058
+			$this->_template_args['payments']              = $payments;
1059
+			$this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1060
+		} else {
1061
+			$this->_template_args['payments']              = false;
1062
+			$this->_template_args['existing_reg_payments'] = [];
1063
+		}
1064
+
1065
+		$this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1066
+		$this->_template_args['delete_payment_url'] = add_query_arg(
1067
+			['action' => 'espresso_delete_payment'],
1068
+			TXN_ADMIN_URL
1069
+		);
1070
+
1071
+		if (isset($txn_details['invoice_number'])) {
1072
+			$this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1073
+			$this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1074
+				'Invoice Number',
1075
+				'event_espresso'
1076
+			);
1077
+		}
1078
+
1079
+		$this->_template_args['txn_details']['registration_session']['value'] =
1080
+			$this->_transaction->primary_registration() instanceof EE_Registration
1081
+				? $this->_transaction->primary_registration()->session_ID()
1082
+				: null;
1083
+		$this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1084
+			'Registration Session',
1085
+			'event_espresso'
1086
+		);
1087
+
1088
+		$this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address'])
1089
+			? $this->_session['ip_address']
1090
+			: '';
1091
+		$this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1092
+			'Transaction placed from IP',
1093
+			'event_espresso'
1094
+		);
1095
+
1096
+		$this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent'])
1097
+			? $this->_session['user_agent']
1098
+			: '';
1099
+		$this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1100
+			'Registrant User Agent',
1101
+			'event_espresso'
1102
+		);
1103
+
1104
+		$reg_steps = '<ul>';
1105
+		foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1106
+			if ($reg_step_status === true) {
1107
+				$reg_steps .= '<li style="color:#70cc50">'
1108
+							  . sprintf(
1109
+								  esc_html__('%1$s : Completed', 'event_espresso'),
1110
+								  ucwords(str_replace('_', ' ', $reg_step))
1111
+							  )
1112
+							  . '</li>';
1113
+			} elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1114
+				$reg_steps .= '<li style="color:#2EA2CC">'
1115
+							  . sprintf(
1116
+								  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1117
+								  ucwords(str_replace('_', ' ', $reg_step)),
1118
+								  date(
1119
+									  get_option('date_format') . ' ' . get_option('time_format'),
1120
+									  $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1121
+								  )
1122
+							  )
1123
+							  . '</li>';
1124
+			} else {
1125
+				$reg_steps .= '<li style="color:#E76700">'
1126
+							  . sprintf(
1127
+								  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1128
+								  ucwords(str_replace('_', ' ', $reg_step))
1129
+							  )
1130
+							  . '</li>';
1131
+			}
1132
+		}
1133
+		$reg_steps                                                 .= '</ul>';
1134
+		$this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1135
+		$this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1136
+			'Registration Step Progress',
1137
+			'event_espresso'
1138
+		);
1139
+
1140
+
1141
+		$this->_get_registrations_to_apply_payment_to();
1142
+		$this->_get_payment_methods($payments);
1143
+		$this->_get_payment_status_array();
1144
+		$this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1145
+
1146
+		$this->_template_args['transaction_form_url']    = add_query_arg(
1147
+			[
1148
+				'action'  => 'edit_transaction',
1149
+				'process' => 'transaction',
1150
+			],
1151
+			TXN_ADMIN_URL
1152
+		);
1153
+		$this->_template_args['apply_payment_form_url']  = add_query_arg(
1154
+			[
1155
+				'page'   => 'espresso_transactions',
1156
+				'action' => 'espresso_apply_payment',
1157
+			],
1158
+			WP_AJAX_URL
1159
+		);
1160
+		$this->_template_args['delete_payment_form_url'] = add_query_arg(
1161
+			[
1162
+				'page'   => 'espresso_transactions',
1163
+				'action' => 'espresso_delete_payment',
1164
+			],
1165
+			WP_AJAX_URL
1166
+		);
1167
+
1168
+		$this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1169
+
1170
+		// 'espresso_delete_payment_nonce'
1171
+
1172
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1173
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * _get_registration_payment_IDs
1179
+	 *    generates an array of Payment IDs and their corresponding Registration IDs
1180
+	 *
1181
+	 * @access protected
1182
+	 * @param EE_Payment[] $payments
1183
+	 * @return array
1184
+	 * @throws EE_Error
1185
+	 * @throws InvalidArgumentException
1186
+	 * @throws InvalidDataTypeException
1187
+	 * @throws InvalidInterfaceException
1188
+	 * @throws ReflectionException
1189
+	 */
1190
+	protected function _get_registration_payment_IDs($payments = [])
1191
+	{
1192
+		$existing_reg_payments = [];
1193
+		// get all reg payments for these payments
1194
+		$reg_payments = EEM_Registration_Payment::instance()->get_all(
1195
+			[
1196
+				[
1197
+					'PAY_ID' => [
1198
+						'IN',
1199
+						array_keys($payments),
1200
+					],
1201
+				],
1202
+			]
1203
+		);
1204
+		if (! empty($reg_payments)) {
1205
+			foreach ($payments as $payment) {
1206
+				if (! $payment instanceof EE_Payment) {
1207
+					continue;
1208
+				} elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1209
+					$existing_reg_payments[ $payment->ID() ] = [];
1210
+				}
1211
+				foreach ($reg_payments as $reg_payment) {
1212
+					if (
1213
+						$reg_payment instanceof EE_Registration_Payment
1214
+						&& $reg_payment->payment_ID() === $payment->ID()
1215
+					) {
1216
+						$existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1217
+					}
1218
+				}
1219
+			}
1220
+		}
1221
+
1222
+		return $existing_reg_payments;
1223
+	}
1224
+
1225
+
1226
+	/**
1227
+	 * _get_registrations_to_apply_payment_to
1228
+	 *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1229
+	 * which allows the admin to only apply the payment to the specific registrations
1230
+	 *
1231
+	 * @access protected
1232
+	 * @return void
1233
+	 * @throws EE_Error
1234
+	 * @throws InvalidArgumentException
1235
+	 * @throws InvalidDataTypeException
1236
+	 * @throws InvalidInterfaceException
1237
+	 * @throws ReflectionException
1238
+	 */
1239
+	protected function _get_registrations_to_apply_payment_to()
1240
+	{
1241
+		// we want any registration with an active status (ie: not deleted or cancelled)
1242
+		$query_params                      = [
1243
+			[
1244
+				'STS_ID' => [
1245
+					'IN',
1246
+					[
1247
+						EEM_Registration::status_id_approved,
1248
+						EEM_Registration::status_id_pending_payment,
1249
+						EEM_Registration::status_id_not_approved,
1250
+					],
1251
+				],
1252
+			],
1253
+		];
1254
+		$registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1255
+			'',
1256
+			'txn-admin-apply-payment-to-registrations-dv',
1257
+			'',
1258
+			'clear: both; margin: 1.5em 0 0; display: none;'
1259
+		);
1260
+		$registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1261
+		$registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1262
+		$registrations_to_apply_payment_to .= EEH_HTML::thead(
1263
+			EEH_HTML::tr(
1264
+				EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1265
+				EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1266
+				EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1267
+				EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1268
+				EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1269
+				EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1270
+				EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1271
+			)
1272
+		);
1273
+		$registrations_to_apply_payment_to .= EEH_HTML::tbody();
1274
+		// get registrations for TXN
1275
+		$registrations         = $this->_transaction->registrations($query_params);
1276
+		$existing_reg_payments = $this->_template_args['existing_reg_payments'];
1277
+		foreach ($registrations as $registration) {
1278
+			if ($registration instanceof EE_Registration) {
1279
+				$attendee_name                     = $registration->attendee() instanceof EE_Attendee
1280
+					? $registration->attendee()->full_name()
1281
+					: esc_html__('Unknown Attendee', 'event_espresso');
1282
+				$owing                             = $registration->final_price() - $registration->paid();
1283
+				$taxable                           = $registration->ticket()->taxable()
1284
+					? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1285
+					: '';
1286
+				$checked                           = empty($existing_reg_payments)
1287
+													 || in_array($registration->ID(), $existing_reg_payments, true)
1288
+					? ' checked="checked"'
1289
+					: '';
1290
+				$disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1291
+				$registrations_to_apply_payment_to .= EEH_HTML::tr(
1292
+					EEH_HTML::td($registration->ID()) .
1293
+					EEH_HTML::td($attendee_name) .
1294
+					EEH_HTML::td(
1295
+						$registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1296
+					) .
1297
+					EEH_HTML::td($registration->event_name()) .
1298
+					EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1299
+					EEH_HTML::td(
1300
+						EEH_Template::format_currency($owing),
1301
+						'',
1302
+						'txn-admin-payment-owing-td jst-cntr'
1303
+					) .
1304
+					EEH_HTML::td(
1305
+						'<input type="checkbox" value="' . $registration->ID()
1306
+						. '" name="txn_admin_payment[registrations]"'
1307
+						. $checked . $disabled . '>',
1308
+						'',
1309
+						'jst-cntr'
1310
+					),
1311
+					'apply-payment-registration-row-' . $registration->ID()
1312
+				);
1313
+			}
1314
+		}
1315
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1316
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1317
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1318
+		$registrations_to_apply_payment_to                         .= EEH_HTML::p(
1319
+			esc_html__(
1320
+				'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1321
+				'event_espresso'
1322
+			),
1323
+			'',
1324
+			'clear description'
1325
+		);
1326
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1327
+		$this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1328
+	}
1329
+
1330
+
1331
+	/**
1332
+	 * _get_reg_status_selection
1333
+	 *
1334
+	 * @return void
1335
+	 * @throws EE_Error
1336
+	 * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1337
+	 *         instead of events.
1338
+	 * @access protected
1339
+	 */
1340
+	protected function _get_reg_status_selection()
1341
+	{
1342
+		// first get all possible statuses
1343
+		$statuses = EEM_Registration::reg_status_array([], true);
1344
+		// let's add a "don't change" option.
1345
+		$status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1346
+		$status_array                                        = array_merge($status_array, $statuses);
1347
+		$this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1348
+			'txn_reg_status_change[reg_status]',
1349
+			$status_array,
1350
+			'NAN',
1351
+			'id="txn-admin-payment-reg-status-inp"',
1352
+			'txn-reg-status-change-reg-status'
1353
+		);
1354
+		$this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1355
+			'delete_txn_reg_status_change[reg_status]',
1356
+			$status_array,
1357
+			'NAN',
1358
+			'delete-txn-admin-payment-reg-status-inp',
1359
+			'delete-txn-reg-status-change-reg-status'
1360
+		);
1361
+	}
1362
+
1363
+
1364
+	/**
1365
+	 *    _get_payment_methods
1366
+	 * Gets all the payment methods available generally, or the ones that are already
1367
+	 * selected on these payments (in case their payment methods are no longer active).
1368
+	 * Has the side-effect of updating the template args' payment_methods item
1369
+	 *
1370
+	 * @access private
1371
+	 * @param EE_Payment[] to show on this page
1372
+	 * @return void
1373
+	 * @throws EE_Error
1374
+	 * @throws InvalidArgumentException
1375
+	 * @throws InvalidDataTypeException
1376
+	 * @throws InvalidInterfaceException
1377
+	 * @throws ReflectionException
1378
+	 */
1379
+	private function _get_payment_methods($payments = [])
1380
+	{
1381
+		$payment_methods_of_payments = [];
1382
+		foreach ($payments as $payment) {
1383
+			if ($payment instanceof EE_Payment) {
1384
+				$payment_methods_of_payments[] = $payment->ID();
1385
+			}
1386
+		}
1387
+		if ($payment_methods_of_payments) {
1388
+			$query_args = [
1389
+				[
1390
+					'OR*payment_method_for_payment' => [
1391
+						'PMD_ID'    => ['IN', $payment_methods_of_payments],
1392
+						'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1393
+					],
1394
+				],
1395
+			];
1396
+		} else {
1397
+			$query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1398
+		}
1399
+		$this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1400
+	}
1401
+
1402
+
1403
+	/**
1404
+	 * txn_attendees_meta_box
1405
+	 *    generates HTML for the Attendees Transaction main meta box
1406
+	 *
1407
+	 * @access public
1408
+	 * @param WP_Post $post
1409
+	 * @param array   $metabox
1410
+	 * @return void
1411
+	 * @throws DomainException
1412
+	 * @throws EE_Error
1413
+	 * @throws InvalidArgumentException
1414
+	 * @throws InvalidDataTypeException
1415
+	 * @throws InvalidInterfaceException
1416
+	 * @throws ReflectionException
1417
+	 */
1418
+	public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1419
+	{
1420
+
1421
+		/** @noinspection NonSecureExtractUsageInspection */
1422
+		extract($metabox['args']);
1423
+		$this->_template_args['post']            = $post;
1424
+		$this->_template_args['event_attendees'] = [];
1425
+		// process items in cart
1426
+		$line_items = $this->_transaction->get_many_related(
1427
+			'Line_Item',
1428
+			[['LIN_type' => 'line-item']]
1429
+		);
1430
+		if (! empty($line_items)) {
1431
+			foreach ($line_items as $item) {
1432
+				if ($item instanceof EE_Line_Item) {
1433
+					switch ($item->OBJ_type()) {
1434
+						case 'Event':
1435
+							break;
1436
+						case 'Ticket':
1437
+							$ticket = $item->ticket();
1438
+							// right now we're only handling tickets here.
1439
+							// Cause its expected that only tickets will have attendees right?
1440
+							if (! $ticket instanceof EE_Ticket) {
1441
+								break;
1442
+							}
1443
+							try {
1444
+								$event_name = $ticket->get_event_name();
1445
+							} catch (Exception $e) {
1446
+								EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1447
+								$event_name = esc_html__('Unknown Event', 'event_espresso');
1448
+							}
1449
+							$event_name   .= ' - ' . $item->name();
1450
+							$ticket_price = EEH_Template::format_currency($item->unit_price());
1451
+							// now get all of the registrations for this transaction that use this ticket
1452
+							$registrations = $ticket->registrations(
1453
+								[['TXN_ID' => $this->_transaction->ID()]]
1454
+							);
1455
+							foreach ($registrations as $registration) {
1456
+								if (! $registration instanceof EE_Registration) {
1457
+									break;
1458
+								}
1459
+								$this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1460
+									= $registration->status_ID();
1461
+								$this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1462
+									= $registration->count();
1463
+								$this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1464
+									= $event_name;
1465
+								$this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1466
+									= $ticket_price;
1467
+								// attendee info
1468
+								$attendee = $registration->get_first_related('Attendee');
1469
+								if ($attendee instanceof EE_Attendee) {
1470
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1471
+										= $attendee->ID();
1472
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1473
+										= $attendee->full_name();
1474
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']
1475
+										= '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1476
+										  . esc_html__(
1477
+											  ' Event',
1478
+											  'event_espresso'
1479
+										  )
1480
+										  . '">' . $attendee->email() . '</a>';
1481
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']
1482
+										= EEH_Address::format($attendee, 'inline', false, false);
1483
+								} else {
1484
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1485
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1486
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1487
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1488
+								}
1489
+							}
1490
+							break;
1491
+					}
1492
+				}
1493
+			}
1494
+
1495
+			$this->_template_args['transaction_form_url'] = add_query_arg(
1496
+				[
1497
+					'action'  => 'edit_transaction',
1498
+					'process' => 'attendees',
1499
+				],
1500
+				TXN_ADMIN_URL
1501
+			);
1502
+			echo EEH_Template::display_template(
1503
+				TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1504
+				$this->_template_args,
1505
+				true
1506
+			);
1507
+		} else {
1508
+			printf(
1509
+				esc_html__(
1510
+					'%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1511
+					'event_espresso'
1512
+				),
1513
+				'<p class="important-notice">',
1514
+				'</p>'
1515
+			);
1516
+		}
1517
+	}
1518
+
1519
+
1520
+	/**
1521
+	 * txn_registrant_side_meta_box
1522
+	 * generates HTML for the Edit Transaction side meta box
1523
+	 *
1524
+	 * @access public
1525
+	 * @return void
1526
+	 * @throws DomainException
1527
+	 * @throws EE_Error
1528
+	 * @throws InvalidArgumentException
1529
+	 * @throws InvalidDataTypeException
1530
+	 * @throws InvalidInterfaceException
1531
+	 * @throws ReflectionException
1532
+	 */
1533
+	public function txn_registrant_side_meta_box()
1534
+	{
1535
+		$primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1536
+			? $this->_transaction->primary_registration()->get_first_related('Attendee')
1537
+			: null;
1538
+		if (! $primary_att instanceof EE_Attendee) {
1539
+			$this->_template_args['no_attendee_message'] = esc_html__(
1540
+				'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1541
+				'event_espresso'
1542
+			);
1543
+			$primary_att                           = EEM_Attendee::instance()->create_default_object();
1544
+		}
1545
+		$this->_template_args['ATT_ID']            = $primary_att->ID();
1546
+		$this->_template_args['prime_reg_fname']   = $primary_att->fname();
1547
+		$this->_template_args['prime_reg_lname']   = $primary_att->lname();
1548
+		$this->_template_args['prime_reg_email']   = $primary_att->email();
1549
+		$this->_template_args['prime_reg_phone']   = $primary_att->phone();
1550
+		$this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1551
+			[
1552
+				'action' => 'edit_attendee',
1553
+				'post'   => $primary_att->ID(),
1554
+			],
1555
+			REG_ADMIN_URL
1556
+		);
1557
+		// get formatted address for registrant
1558
+		$formatted_address = EEH_Address::format($primary_att);
1559
+		$formatted_address = $formatted_address !== '<div class="espresso-address-dv"><div></div></div>'
1560
+			? $formatted_address
1561
+			: '';
1562
+		$this->_template_args['formatted_address'] = $formatted_address;
1563
+		echo EEH_Template::display_template(
1564
+			TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1565
+			$this->_template_args,
1566
+			true
1567
+		);
1568
+	}
1569
+
1570
+
1571
+	/**
1572
+	 * txn_billing_info_side_meta_box
1573
+	 *    generates HTML for the Edit Transaction side meta box
1574
+	 *
1575
+	 * @access public
1576
+	 * @return void
1577
+	 * @throws DomainException
1578
+	 * @throws EE_Error
1579
+	 * @throws ReflectionException
1580
+	 */
1581
+	public function txn_billing_info_side_meta_box()
1582
+	{
1583
+
1584
+		$this->_template_args['billing_form']     = $this->_transaction->billing_info();
1585
+		$this->_template_args['billing_form_url'] = add_query_arg(
1586
+			['action' => 'edit_transaction', 'process' => 'billing'],
1587
+			TXN_ADMIN_URL
1588
+		);
1589
+
1590
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1591
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1592
+	}
1593
+
1594
+
1595
+	/**
1596
+	 * apply_payments_or_refunds
1597
+	 *    registers a payment or refund made towards a transaction
1598
+	 *
1599
+	 * @access public
1600
+	 * @return void
1601
+	 * @throws EE_Error
1602
+	 * @throws InvalidArgumentException
1603
+	 * @throws ReflectionException
1604
+	 * @throws RuntimeException
1605
+	 * @throws InvalidDataTypeException
1606
+	 * @throws InvalidInterfaceException
1607
+	 */
1608
+	public function apply_payments_or_refunds()
1609
+	{
1610
+		$json_response_data = ['return_data' => false];
1611
+		$valid_data         = $this->_validate_payment_request_data();
1612
+		$has_access         = EE_Registry::instance()->CAP->current_user_can(
1613
+			'ee_edit_payments',
1614
+			'apply_payment_or_refund_from_registration_details'
1615
+		);
1616
+		if (! empty($valid_data) && $has_access) {
1617
+			$PAY_ID = $valid_data['PAY_ID'];
1618
+			// save  the new payment
1619
+			$payment = $this->_create_payment_from_request_data($valid_data);
1620
+			// get the TXN for this payment
1621
+			$transaction = $payment->transaction();
1622
+			// verify transaction
1623
+			if ($transaction instanceof EE_Transaction) {
1624
+				// calculate_total_payments_and_update_status
1625
+				$this->_process_transaction_payments($transaction);
1626
+				$REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1627
+				$this->_remove_existing_registration_payments($payment, $PAY_ID);
1628
+				// apply payment to registrations (if applicable)
1629
+				if (! empty($REG_IDs)) {
1630
+					$this->_update_registration_payments($transaction, $payment, $REG_IDs);
1631
+					$this->_maybe_send_notifications();
1632
+					// now process status changes for the same registrations
1633
+					$this->_process_registration_status_change($transaction, $REG_IDs);
1634
+				}
1635
+				$this->_maybe_send_notifications($payment);
1636
+				// prepare to render page
1637
+				$json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1638
+				do_action(
1639
+					'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1640
+					$transaction,
1641
+					$payment
1642
+				);
1643
+			} else {
1644
+				EE_Error::add_error(
1645
+					esc_html__(
1646
+						'A valid Transaction for this payment could not be retrieved.',
1647
+						'event_espresso'
1648
+					),
1649
+					__FILE__,
1650
+					__FUNCTION__,
1651
+					__LINE__
1652
+				);
1653
+			}
1654
+		} elseif ($has_access) {
1655
+			EE_Error::add_error(
1656
+				esc_html__(
1657
+					'The payment form data could not be processed. Please try again.',
1658
+					'event_espresso'
1659
+				),
1660
+				__FILE__,
1661
+				__FUNCTION__,
1662
+				__LINE__
1663
+			);
1664
+		} else {
1665
+			EE_Error::add_error(
1666
+				esc_html__(
1667
+					'You do not have access to apply payments or refunds to a registration.',
1668
+					'event_espresso'
1669
+				),
1670
+				__FILE__,
1671
+				__FUNCTION__,
1672
+				__LINE__
1673
+			);
1674
+		}
1675
+		$notices              = EE_Error::get_notices(
1676
+			false,
1677
+			false,
1678
+			false
1679
+		);
1680
+		$this->_template_args = [
1681
+			'data'    => $json_response_data,
1682
+			'error'   => $notices['errors'],
1683
+			'success' => $notices['success'],
1684
+		];
1685
+		$this->_return_json();
1686
+	}
1687
+
1688
+
1689
+	/**
1690
+	 * _validate_payment_request_data
1691
+	 *
1692
+	 * @return array
1693
+	 * @throws EE_Error
1694
+	 * @throws InvalidArgumentException
1695
+	 * @throws InvalidDataTypeException
1696
+	 * @throws InvalidInterfaceException
1697
+	 */
1698
+	protected function _validate_payment_request_data()
1699
+	{
1700
+		if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1701
+			return [];
1702
+		}
1703
+		$payment_form = $this->_generate_payment_form_section();
1704
+		try {
1705
+			if ($payment_form->was_submitted()) {
1706
+				$payment_form->receive_form_submission();
1707
+				if (! $payment_form->is_valid()) {
1708
+					$submission_error_messages = [];
1709
+					foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1710
+						if ($validation_error instanceof EE_Validation_Error) {
1711
+							$form_input = $validation_error->get_form_section();
1712
+							$submission_error_messages[] = sprintf(
1713
+								_x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1714
+								$form_input instanceof EE_Form_Input_Base ? $form_input->html_label_text() : '',
1715
+								$validation_error->getMessage()
1716
+							);
1717
+						}
1718
+					}
1719
+					EE_Error::add_error(
1720
+						implode('<br />', $submission_error_messages),
1721
+						__FILE__,
1722
+						__FUNCTION__,
1723
+						__LINE__
1724
+					);
1725
+					return [];
1726
+				}
1727
+			}
1728
+		} catch (EE_Error $e) {
1729
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1730
+			return [];
1731
+		}
1732
+
1733
+		return $payment_form->valid_data();
1734
+	}
1735
+
1736
+
1737
+	/**
1738
+	 * _generate_payment_form_section
1739
+	 *
1740
+	 * @return EE_Form_Section_Proper
1741
+	 * @throws EE_Error
1742
+	 */
1743
+	protected function _generate_payment_form_section()
1744
+	{
1745
+		return new EE_Form_Section_Proper(
1746
+			[
1747
+				'name'        => 'txn_admin_payment',
1748
+				'subsections' => [
1749
+					'PAY_ID'          => new EE_Text_Input(
1750
+						[
1751
+							'default'               => 0,
1752
+							'required'              => false,
1753
+							'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1754
+							'validation_strategies' => [new EE_Int_Normalization()],
1755
+						]
1756
+					),
1757
+					'TXN_ID'          => new EE_Text_Input(
1758
+						[
1759
+							'default'               => 0,
1760
+							'required'              => true,
1761
+							'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1762
+							'validation_strategies' => [new EE_Int_Normalization()],
1763
+						]
1764
+					),
1765
+					'type'            => new EE_Text_Input(
1766
+						[
1767
+							'default'               => 1,
1768
+							'required'              => true,
1769
+							'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1770
+							'validation_strategies' => [new EE_Int_Normalization()],
1771
+						]
1772
+					),
1773
+					'amount'          => new EE_Text_Input(
1774
+						[
1775
+							'default'               => 0,
1776
+							'required'              => true,
1777
+							'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1778
+							'validation_strategies' => [new EE_Float_Normalization()],
1779
+						]
1780
+					),
1781
+					'status'          => new EE_Text_Input(
1782
+						[
1783
+							'default'         => EEM_Payment::status_id_approved,
1784
+							'required'        => true,
1785
+							'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1786
+						]
1787
+					),
1788
+					'PMD_ID'          => new EE_Text_Input(
1789
+						[
1790
+							'default'               => 2,
1791
+							'required'              => true,
1792
+							'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1793
+							'validation_strategies' => [new EE_Int_Normalization()],
1794
+						]
1795
+					),
1796
+					'date'            => new EE_Text_Input(
1797
+						[
1798
+							'default'         => time(),
1799
+							'required'        => true,
1800
+							'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1801
+						]
1802
+					),
1803
+					'txn_id_chq_nmbr' => new EE_Text_Input(
1804
+						[
1805
+							'default'               => '',
1806
+							'required'              => false,
1807
+							'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1808
+							'validation_strategies' => [
1809
+								new EE_Max_Length_Validation_Strategy(
1810
+									esc_html__('Input too long', 'event_espresso'),
1811
+									100
1812
+								),
1813
+							],
1814
+						]
1815
+					),
1816
+					'po_number'       => new EE_Text_Input(
1817
+						[
1818
+							'default'               => '',
1819
+							'required'              => false,
1820
+							'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1821
+							'validation_strategies' => [
1822
+								new EE_Max_Length_Validation_Strategy(
1823
+									esc_html__('Input too long', 'event_espresso'),
1824
+									100
1825
+								),
1826
+							],
1827
+						]
1828
+					),
1829
+					'accounting'      => new EE_Text_Input(
1830
+						[
1831
+							'default'               => '',
1832
+							'required'              => false,
1833
+							'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1834
+							'validation_strategies' => [
1835
+								new EE_Max_Length_Validation_Strategy(
1836
+									esc_html__('Input too long', 'event_espresso'),
1837
+									100
1838
+								),
1839
+							],
1840
+						]
1841
+					),
1842
+				],
1843
+			]
1844
+		);
1845
+	}
1846
+
1847
+
1848
+	/**
1849
+	 * _create_payment_from_request_data
1850
+	 *
1851
+	 * @param array $valid_data
1852
+	 * @return EE_Payment
1853
+	 * @throws EE_Error
1854
+	 * @throws InvalidArgumentException
1855
+	 * @throws InvalidDataTypeException
1856
+	 * @throws InvalidInterfaceException
1857
+	 * @throws ReflectionException
1858
+	 */
1859
+	protected function _create_payment_from_request_data($valid_data)
1860
+	{
1861
+		$PAY_ID = $valid_data['PAY_ID'];
1862
+		// get payment amount
1863
+		$amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1864
+		// payments have a type value of 1 and refunds have a type value of -1
1865
+		// so multiplying amount by type will give a positive value for payments, and negative values for refunds
1866
+		$amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1867
+		// for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1868
+		$date    = $valid_data['date']
1869
+			? preg_replace('/\s+/', ' ', $valid_data['date'])
1870
+			: date('Y-m-d g:i a', current_time('timestamp'));
1871
+		$payment = EE_Payment::new_instance(
1872
+			[
1873
+				'TXN_ID'              => $valid_data['TXN_ID'],
1874
+				'STS_ID'              => $valid_data['status'],
1875
+				'PAY_timestamp'       => $date,
1876
+				'PAY_source'          => EEM_Payment_Method::scope_admin,
1877
+				'PMD_ID'              => $valid_data['PMD_ID'],
1878
+				'PAY_amount'          => $amount,
1879
+				'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1880
+				'PAY_po_number'       => $valid_data['po_number'],
1881
+				'PAY_extra_accntng'   => $valid_data['accounting'],
1882
+				'PAY_details'         => $valid_data,
1883
+				'PAY_ID'              => $PAY_ID,
1884
+			],
1885
+			'',
1886
+			['Y-m-d', 'g:i a']
1887
+		);
1888
+
1889
+		if (! $payment->save()) {
1890
+			EE_Error::add_error(
1891
+				sprintf(
1892
+					esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1893
+					$payment->ID()
1894
+				),
1895
+				__FILE__,
1896
+				__FUNCTION__,
1897
+				__LINE__
1898
+			);
1899
+		}
1900
+
1901
+		return $payment;
1902
+	}
1903
+
1904
+
1905
+	/**
1906
+	 * _process_transaction_payments
1907
+	 *
1908
+	 * @param EE_Transaction $transaction
1909
+	 * @return void
1910
+	 * @throws EE_Error
1911
+	 * @throws InvalidArgumentException
1912
+	 * @throws ReflectionException
1913
+	 * @throws InvalidDataTypeException
1914
+	 * @throws InvalidInterfaceException
1915
+	 */
1916
+	protected function _process_transaction_payments(EE_Transaction $transaction)
1917
+	{
1918
+		/** @type EE_Transaction_Payments $transaction_payments */
1919
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1920
+		// update the transaction with this payment
1921
+		if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1922
+			EE_Error::add_success(
1923
+				esc_html__(
1924
+					'The payment has been processed successfully.',
1925
+					'event_espresso'
1926
+				),
1927
+				__FILE__,
1928
+				__FUNCTION__,
1929
+				__LINE__
1930
+			);
1931
+		} else {
1932
+			EE_Error::add_error(
1933
+				esc_html__(
1934
+					'The payment was processed successfully but the amount paid for the transaction was not updated.',
1935
+					'event_espresso'
1936
+				),
1937
+				__FILE__,
1938
+				__FUNCTION__,
1939
+				__LINE__
1940
+			);
1941
+		}
1942
+	}
1943
+
1944
+
1945
+	/**
1946
+	 * _get_REG_IDs_to_apply_payment_to
1947
+	 * returns a list of registration IDs that the payment will apply to
1948
+	 *
1949
+	 * @param EE_Payment $payment
1950
+	 * @return array
1951
+	 * @throws EE_Error
1952
+	 * @throws InvalidArgumentException
1953
+	 * @throws InvalidDataTypeException
1954
+	 * @throws InvalidInterfaceException
1955
+	 * @throws ReflectionException
1956
+	 */
1957
+	protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1958
+	{
1959
+		// grab array of IDs for specific registrations to apply changes to
1960
+		$REG_IDs = $this->request->getRequestParam('txn_admin_payment[registrations]', [], 'int', true);
1961
+		// nothing specified ? then get all reg IDs
1962
+		if (empty($REG_IDs)) {
1963
+			$registrations = $payment->transaction()->registrations();
1964
+			$REG_IDs       = ! empty($registrations)
1965
+				? array_keys($registrations)
1966
+				: $this->_get_existing_reg_payment_REG_IDs($payment);
1967
+		}
1968
+
1969
+		// ensure that REG_IDs are integers and NOT strings
1970
+		return array_map('intval', $REG_IDs);
1971
+	}
1972
+
1973
+
1974
+	/**
1975
+	 * @return array
1976
+	 */
1977
+	public function existing_reg_payment_REG_IDs()
1978
+	{
1979
+		return $this->_existing_reg_payment_REG_IDs;
1980
+	}
1981
+
1982
+
1983
+	/**
1984
+	 * @param array $existing_reg_payment_REG_IDs
1985
+	 */
1986
+	public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1987
+	{
1988
+		$this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1989
+	}
1990
+
1991
+
1992
+	/**
1993
+	 * _get_existing_reg_payment_REG_IDs
1994
+	 * returns a list of registration IDs that the payment is currently related to
1995
+	 * as recorded in the database
1996
+	 *
1997
+	 * @param EE_Payment $payment
1998
+	 * @return array
1999
+	 * @throws EE_Error
2000
+	 * @throws InvalidArgumentException
2001
+	 * @throws InvalidDataTypeException
2002
+	 * @throws InvalidInterfaceException
2003
+	 * @throws ReflectionException
2004
+	 */
2005
+	protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2006
+	{
2007
+		if ($this->existing_reg_payment_REG_IDs() === null) {
2008
+			// let's get any existing reg payment records for this payment
2009
+			$existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2010
+			// but we only want the REG IDs, so grab the array keys
2011
+			$existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2012
+				? array_keys($existing_reg_payment_REG_IDs)
2013
+				: [];
2014
+			$this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2015
+		}
2016
+
2017
+		return $this->existing_reg_payment_REG_IDs();
2018
+	}
2019
+
2020
+
2021
+	/**
2022
+	 * _remove_existing_registration_payments
2023
+	 * this calculates the difference between existing relations
2024
+	 * to the supplied payment and the new list registration IDs,
2025
+	 * removes any related registrations that no longer apply,
2026
+	 * and then updates the registration paid fields
2027
+	 *
2028
+	 * @param EE_Payment $payment
2029
+	 * @param int        $PAY_ID
2030
+	 * @return bool;
2031
+	 * @throws EE_Error
2032
+	 * @throws InvalidArgumentException
2033
+	 * @throws ReflectionException
2034
+	 * @throws InvalidDataTypeException
2035
+	 * @throws InvalidInterfaceException
2036
+	 */
2037
+	protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2038
+	{
2039
+		// newly created payments will have nothing recorded for $PAY_ID
2040
+		if (absint($PAY_ID) === 0) {
2041
+			return false;
2042
+		}
2043
+		$existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2044
+		if (empty($existing_reg_payment_REG_IDs)) {
2045
+			return false;
2046
+		}
2047
+		/** @type EE_Transaction_Payments $transaction_payments */
2048
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2049
+
2050
+		return $transaction_payments->delete_registration_payments_and_update_registrations(
2051
+			$payment,
2052
+			[
2053
+				[
2054
+					'PAY_ID' => $payment->ID(),
2055
+					'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2056
+				],
2057
+			]
2058
+		);
2059
+	}
2060
+
2061
+
2062
+	/**
2063
+	 * _update_registration_payments
2064
+	 * this applies the payments to the selected registrations
2065
+	 * but only if they have not already been paid for
2066
+	 *
2067
+	 * @param EE_Transaction $transaction
2068
+	 * @param EE_Payment     $payment
2069
+	 * @param array          $REG_IDs
2070
+	 * @return void
2071
+	 * @throws EE_Error
2072
+	 * @throws InvalidArgumentException
2073
+	 * @throws ReflectionException
2074
+	 * @throws RuntimeException
2075
+	 * @throws InvalidDataTypeException
2076
+	 * @throws InvalidInterfaceException
2077
+	 */
2078
+	protected function _update_registration_payments(
2079
+		EE_Transaction $transaction,
2080
+		EE_Payment $payment,
2081
+		$REG_IDs = []
2082
+	) {
2083
+		// we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2084
+		// so let's do that using our set of REG_IDs from the form
2085
+		$registration_query_where_params = [
2086
+			'REG_ID' => ['IN', $REG_IDs],
2087
+		];
2088
+		// but add in some conditions regarding payment,
2089
+		// so that we don't apply payments to registrations that are free or have already been paid for
2090
+		// but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2091
+		if (! $payment->is_a_refund()) {
2092
+			$registration_query_where_params['REG_final_price']  = ['!=', 0];
2093
+			$registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2094
+		}
2095
+		$registrations = $transaction->registrations([$registration_query_where_params]);
2096
+		if (! empty($registrations)) {
2097
+			/** @type EE_Payment_Processor $payment_processor */
2098
+			$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2099
+			$payment_processor->process_registration_payments($transaction, $payment, $registrations);
2100
+		}
2101
+	}
2102
+
2103
+
2104
+	/**
2105
+	 * _process_registration_status_change
2106
+	 * This processes requested registration status changes for all the registrations
2107
+	 * on a given transaction and (optionally) sends out notifications for the changes.
2108
+	 *
2109
+	 * @param EE_Transaction $transaction
2110
+	 * @param array          $REG_IDs
2111
+	 * @return bool
2112
+	 * @throws EE_Error
2113
+	 * @throws InvalidArgumentException
2114
+	 * @throws ReflectionException
2115
+	 * @throws InvalidDataTypeException
2116
+	 * @throws InvalidInterfaceException
2117
+	 */
2118
+	protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [])
2119
+	{
2120
+		// first if there is no change in status then we get out.
2121
+		$reg_status = $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2122
+		if ($reg_status === 'NAN') {
2123
+			// no error message, no change requested, just nothing to do man.
2124
+			return false;
2125
+		}
2126
+		/** @type EE_Transaction_Processor $transaction_processor */
2127
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2128
+
2129
+		// made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2130
+		return $transaction_processor->manually_update_registration_statuses(
2131
+			$transaction,
2132
+			$reg_status,
2133
+			[['REG_ID' => ['IN', $REG_IDs]]]
2134
+		);
2135
+	}
2136
+
2137
+
2138
+	/**
2139
+	 * _build_payment_json_response
2140
+	 *
2141
+	 * @access public
2142
+	 * @param EE_Payment  $payment
2143
+	 * @param array       $REG_IDs
2144
+	 * @param bool | null $delete_txn_reg_status_change
2145
+	 * @return array
2146
+	 * @throws EE_Error
2147
+	 * @throws InvalidArgumentException
2148
+	 * @throws InvalidDataTypeException
2149
+	 * @throws InvalidInterfaceException
2150
+	 * @throws ReflectionException
2151
+	 */
2152
+	protected function _build_payment_json_response(
2153
+		EE_Payment $payment,
2154
+		$REG_IDs = [],
2155
+		$delete_txn_reg_status_change = null
2156
+	) {
2157
+		// was the payment deleted ?
2158
+		if (is_bool($delete_txn_reg_status_change)) {
2159
+			return [
2160
+				'PAY_ID'                       => $payment->ID(),
2161
+				'amount'                       => $payment->amount(),
2162
+				'total_paid'                   => $payment->transaction()->paid(),
2163
+				'txn_status'                   => $payment->transaction()->status_ID(),
2164
+				'pay_status'                   => $payment->STS_ID(),
2165
+				'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2166
+				'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2167
+			];
2168
+		}
2169
+
2170
+		$this->_get_payment_status_array();
2171
+		return [
2172
+			'amount'           => $payment->amount(),
2173
+			'total_paid'       => $payment->transaction()->paid(),
2174
+			'txn_status'       => $payment->transaction()->status_ID(),
2175
+			'pay_status'       => $payment->STS_ID(),
2176
+			'PAY_ID'           => $payment->ID(),
2177
+			'STS_ID'           => $payment->STS_ID(),
2178
+			'status'           => self::$_pay_status[ $payment->STS_ID() ],
2179
+			'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2180
+			'method'           => strtoupper($payment->source()),
2181
+			'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2182
+			'gateway'          => $payment->payment_method()
2183
+				? $payment->payment_method()->admin_name()
2184
+				: esc_html__('Unknown', 'event_espresso'),
2185
+			'gateway_response' => $payment->gateway_response(),
2186
+			'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2187
+			'po_number'        => $payment->po_number(),
2188
+			'extra_accntng'    => $payment->extra_accntng(),
2189
+			'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2190
+		];
2191
+	}
2192
+
2193
+
2194
+	/**
2195
+	 * delete_payment
2196
+	 *    delete a payment or refund made towards a transaction
2197
+	 *
2198
+	 * @access public
2199
+	 * @return void
2200
+	 * @throws EE_Error
2201
+	 * @throws InvalidArgumentException
2202
+	 * @throws ReflectionException
2203
+	 * @throws InvalidDataTypeException
2204
+	 * @throws InvalidInterfaceException
2205
+	 */
2206
+	public function delete_payment()
2207
+	{
2208
+		$json_response_data = ['return_data' => false];
2209
+		$PAY_ID = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2210
+
2211
+		$can_delete         = EE_Registry::instance()->CAP->current_user_can(
2212
+			'ee_delete_payments',
2213
+			'delete_payment_from_registration_details'
2214
+		);
2215
+		if ($PAY_ID && $can_delete) {
2216
+			$delete_txn_reg_status_change = $this->request->getRequestParam(
2217
+				'delete_txn_reg_status_change',
2218
+				false,
2219
+				'bool'
2220
+			);
2221
+			$payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2222
+			if ($payment instanceof EE_Payment) {
2223
+				$REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2224
+				/** @type EE_Transaction_Payments $transaction_payments */
2225
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2226
+				if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2227
+					$json_response_data['return_data'] = $this->_build_payment_json_response(
2228
+						$payment,
2229
+						$REG_IDs,
2230
+						$delete_txn_reg_status_change
2231
+					);
2232
+					if ($delete_txn_reg_status_change) {
2233
+						// MAKE sure we also add the delete_txn_req_status_change to the
2234
+						// request data because that's how messages will be looking for it.
2235
+						$this->request->setRequestParam('txn_reg_status_change', $delete_txn_reg_status_change);
2236
+						$this->_maybe_send_notifications();
2237
+						$this->_process_registration_status_change($payment->transaction(), $REG_IDs);
2238
+					}
2239
+				}
2240
+			} else {
2241
+				EE_Error::add_error(
2242
+					esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2243
+					__FILE__,
2244
+					__FUNCTION__,
2245
+					__LINE__
2246
+				);
2247
+			}
2248
+		} elseif ($can_delete) {
2249
+			EE_Error::add_error(
2250
+				esc_html__(
2251
+					'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2252
+					'event_espresso'
2253
+				),
2254
+				__FILE__,
2255
+				__FUNCTION__,
2256
+				__LINE__
2257
+			);
2258
+		} else {
2259
+			EE_Error::add_error(
2260
+				esc_html__(
2261
+					'You do not have access to delete a payment.',
2262
+					'event_espresso'
2263
+				),
2264
+				__FILE__,
2265
+				__FUNCTION__,
2266
+				__LINE__
2267
+			);
2268
+		}
2269
+		$notices              = EE_Error::get_notices(false, false, false);
2270
+		$this->_template_args = [
2271
+			'data'      => $json_response_data,
2272
+			'success'   => $notices['success'],
2273
+			'error'     => $notices['errors'],
2274
+			'attention' => $notices['attention'],
2275
+		];
2276
+		$this->_return_json();
2277
+	}
2278
+
2279
+
2280
+	/**
2281
+	 * _registration_payment_data_array
2282
+	 * adds info for 'owing' and 'paid' for each registration to the json response
2283
+	 *
2284
+	 * @access protected
2285
+	 * @param array $REG_IDs
2286
+	 * @return array
2287
+	 * @throws EE_Error
2288
+	 * @throws InvalidArgumentException
2289
+	 * @throws InvalidDataTypeException
2290
+	 * @throws InvalidInterfaceException
2291
+	 * @throws ReflectionException
2292
+	 */
2293
+	protected function _registration_payment_data_array($REG_IDs)
2294
+	{
2295
+		$registration_payment_data = [];
2296
+		// if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2297
+		if (! empty($REG_IDs)) {
2298
+			$registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2299
+			foreach ($registrations as $registration) {
2300
+				if ($registration instanceof EE_Registration) {
2301
+					$registration_payment_data[ $registration->ID() ] = [
2302
+						'paid'  => $registration->pretty_paid(),
2303
+						'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2304
+					];
2305
+				}
2306
+			}
2307
+		}
2308
+
2309
+		return $registration_payment_data;
2310
+	}
2311
+
2312
+
2313
+	/**
2314
+	 * _maybe_send_notifications
2315
+	 * determines whether or not the admin has indicated that notifications should be sent.
2316
+	 * If so, will toggle a filter switch for delivering registration notices.
2317
+	 * If passed an EE_Payment object, then it will trigger payment notifications instead.
2318
+	 *
2319
+	 * @access protected
2320
+	 * @param EE_Payment | null $payment
2321
+	 */
2322
+	protected function _maybe_send_notifications($payment = null)
2323
+	{
2324
+		switch ($payment instanceof EE_Payment) {
2325
+			// payment notifications
2326
+			case true:
2327
+				if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2328
+					$this->_process_payment_notification($payment);
2329
+				}
2330
+				break;
2331
+			// registration notifications
2332
+			case false:
2333
+				if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2334
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2335
+				}
2336
+				break;
2337
+		}
2338
+	}
2339
+
2340
+
2341
+	/**
2342
+	 * _send_payment_reminder
2343
+	 *    generates HTML for the View Transaction Details Admin page
2344
+	 *
2345
+	 * @access protected
2346
+	 * @return void
2347
+	 * @throws EE_Error
2348
+	 * @throws InvalidArgumentException
2349
+	 * @throws InvalidDataTypeException
2350
+	 * @throws InvalidInterfaceException
2351
+	 */
2352
+	protected function _send_payment_reminder()
2353
+	{
2354
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2355
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2356
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2357
+		$query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2358
+		do_action(
2359
+			'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2360
+			$transaction
2361
+		);
2362
+		$this->_redirect_after_action(
2363
+			false,
2364
+			esc_html__('payment reminder', 'event_espresso'),
2365
+			esc_html__('sent', 'event_espresso'),
2366
+			$query_args,
2367
+			true
2368
+		);
2369
+	}
2370
+
2371
+
2372
+	/**
2373
+	 *  get_transactions
2374
+	 *    get transactions for given parameters (used by list table)
2375
+	 *
2376
+	 * @param int     $per_page how many transactions displayed per page
2377
+	 * @param boolean $count   return the count or objects
2378
+	 * @param string  $view
2379
+	 * @return EE_Transaction[]|int int = count || array of transaction objects
2380
+	 * @throws EE_Error
2381
+	 * @throws InvalidArgumentException
2382
+	 * @throws InvalidDataTypeException
2383
+	 * @throws InvalidInterfaceException
2384
+	 */
2385
+	public function get_transactions($per_page, $count = false, $view = '')
2386
+	{
2387
+		$start_date = wp_strip_all_tags(
2388
+			$this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2389
+		);
2390
+		$end_date = wp_strip_all_tags(
2391
+			$this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2392
+		);
2393
+
2394
+		// make sure our timestamps start and end right at the boundaries for each day
2395
+		$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2396
+		$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2397
+
2398
+
2399
+		// convert to timestamps
2400
+		$start_date = strtotime($start_date);
2401
+		$end_date   = strtotime($end_date);
2402
+
2403
+		// makes sure start date is the lowest value and vice versa
2404
+		$start_date = min($start_date, $end_date);
2405
+		$end_date   = max($start_date, $end_date);
2406
+
2407
+		// convert to correct format for query
2408
+		$start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2409
+			'TXN_timestamp',
2410
+			date('Y-m-d H:i:s', $start_date),
2411
+			'Y-m-d H:i:s'
2412
+		);
2413
+		$end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2414
+			'TXN_timestamp',
2415
+			date('Y-m-d H:i:s', $end_date),
2416
+			'Y-m-d H:i:s'
2417
+		);
2418
+
2419
+
2420
+		// set orderby
2421
+		$orderby = $this->request->getRequestParam('orderby');
2422
+
2423
+		switch ($orderby) {
2424
+			case 'TXN_ID':
2425
+				break;
2426
+			case 'ATT_fname':
2427
+				$orderby = 'Registration.Attendee.ATT_fname';
2428
+				break;
2429
+			case 'event_name':
2430
+				$orderby = 'Registration.Event.EVT_name';
2431
+				break;
2432
+			default: // 'TXN_timestamp'
2433
+				$orderby = 'TXN_timestamp';
2434
+		}
2435
+
2436
+		$sort         = $this->request->getRequestParam('order', 'DESC');
2437
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
2438
+
2439
+		$per_page = absint($per_page) ? $per_page : 10;
2440
+		$per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2441
+
2442
+		$offset = ($current_page - 1) * $per_page;
2443
+		$limit  = [$offset, $per_page];
2444
+
2445
+		$_where = [
2446
+			'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2447
+			'Registration.REG_count' => 1,
2448
+		];
2449
+
2450
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2451
+		if ($EVT_ID) {
2452
+			$_where['Registration.EVT_ID'] = $EVT_ID;
2453
+		}
2454
+
2455
+		$search_term = $this->request->getRequestParam('s');
2456
+		if ($search_term) {
2457
+			$search_term = '%' . $search_term . '%';
2458
+			$_where['OR']  = [
2459
+				'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2460
+				'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2461
+				'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2462
+				'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2463
+				'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2464
+				'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2465
+				'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2466
+				'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2467
+				'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2468
+				'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2469
+				'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2470
+				'Registration.REG_final_price'        => ['LIKE', $search_term],
2471
+				'Registration.REG_code'               => ['LIKE', $search_term],
2472
+				'Registration.REG_count'              => ['LIKE', $search_term],
2473
+				'Registration.REG_group_size'         => ['LIKE', $search_term],
2474
+				'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2475
+				'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2476
+				'Payment.PAY_source'                  => ['LIKE', $search_term],
2477
+				'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2478
+				'TXN_session_data'                    => ['LIKE', $search_term],
2479
+				'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2480
+			];
2481
+		}
2482
+
2483
+		$status = $this->request->getRequestParam('status');
2484
+		// failed transactions
2485
+		$failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2486
+		$abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2487
+		$incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2488
+
2489
+		if ($failed) {
2490
+			$_where['STS_ID'] = EEM_Transaction::failed_status_code;
2491
+		} elseif ($abandoned) {
2492
+			$_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2493
+		} elseif ($incomplete) {
2494
+			$_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2495
+		} else {
2496
+			$_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2497
+			$_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2498
+		}
2499
+
2500
+		$query_params = apply_filters(
2501
+			'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2502
+			[
2503
+				$_where,
2504
+				'order_by'                 => [$orderby => $sort],
2505
+				'limit'                    => $limit,
2506
+				'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2507
+			],
2508
+			$this->request->requestParams(),
2509
+			$view,
2510
+			$count
2511
+		);
2512
+
2513
+		return $count
2514
+			? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2515
+			: EEM_Transaction::instance()->get_all($query_params);
2516
+	}
2517
+
2518
+
2519
+	/**
2520
+	 * @throws EE_Error
2521
+	 * @throws InvalidArgumentException
2522
+	 * @throws InvalidDataTypeException
2523
+	 * @throws InvalidInterfaceException
2524
+	 * @throws ReflectionException
2525
+	 * @throws RuntimeException
2526
+	 * @since 4.9.79.p
2527
+	 */
2528
+	public function recalculateLineItems()
2529
+	{
2530
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2531
+		/** @var EE_Transaction $transaction */
2532
+		$transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2533
+		$success         = $transaction->recalculateLineItems();
2534
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2535
+		$query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2536
+		$this->_redirect_after_action(
2537
+			$success,
2538
+			esc_html__('Transaction taxes and totals', 'event_espresso'),
2539
+			esc_html__('recalculated', 'event_espresso'),
2540
+			$query_args,
2541
+			true
2542
+		);
2543
+	}
2544 2544
 }
Please login to merge, or discard this patch.
Spacing   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
             'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
251 251
             'event_espresso'
252 252
         );
253
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
253
+        EE_Registry::$i18n_js_strings['error_occurred'] = esc_html__(
254 254
             'An error occurred! Please refresh the page and try again.',
255 255
             'event_espresso'
256 256
         );
@@ -349,7 +349,7 @@  discard block
 block discarded – undo
349 349
         // enqueue style
350 350
         wp_register_style(
351 351
             'espresso_txn',
352
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
352
+            TXN_ASSETS_URL.'espresso_transactions_admin.css',
353 353
             [],
354 354
             EVENT_ESPRESSO_VERSION
355 355
         );
@@ -357,7 +357,7 @@  discard block
 block discarded – undo
357 357
         // scripts
358 358
         wp_register_script(
359 359
             'espresso_txn',
360
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
360
+            TXN_ASSETS_URL.'espresso_transactions_admin.js',
361 361
             [
362 362
                 'ee_admin_js',
363 363
                 'ee-datepicker',
@@ -484,7 +484,7 @@  discard block
 block discarded – undo
484 484
             $this->_transaction->verify_abandoned_transaction_status();
485 485
         }
486 486
 
487
-        if (! $this->_transaction instanceof EE_Transaction) {
487
+        if ( ! $this->_transaction instanceof EE_Transaction) {
488 488
             $error_msg = sprintf(
489 489
                 esc_html__(
490 490
                     'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
@@ -581,7 +581,7 @@  discard block
 block discarded – undo
581 581
             'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
582 582
             [
583 583
                 'overpaid'   => [
584
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::overpaid_status_code,
584
+                    'class' => 'ee-status-legend ee-status-legend--'.EEM_Transaction::overpaid_status_code,
585 585
                     'desc'  => EEH_Template::pretty_status(
586 586
                         EEM_Transaction::overpaid_status_code,
587 587
                         false,
@@ -589,7 +589,7 @@  discard block
 block discarded – undo
589 589
                     ),
590 590
                 ],
591 591
                 'complete'   => [
592
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::complete_status_code,
592
+                    'class' => 'ee-status-legend ee-status-legend--'.EEM_Transaction::complete_status_code,
593 593
                     'desc'  => EEH_Template::pretty_status(
594 594
                         EEM_Transaction::complete_status_code,
595 595
                         false,
@@ -597,7 +597,7 @@  discard block
 block discarded – undo
597 597
                     ),
598 598
                 ],
599 599
                 'incomplete' => [
600
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::incomplete_status_code,
600
+                    'class' => 'ee-status-legend ee-status-legend--'.EEM_Transaction::incomplete_status_code,
601 601
                     'desc'  => EEH_Template::pretty_status(
602 602
                         EEM_Transaction::incomplete_status_code,
603 603
                         false,
@@ -605,7 +605,7 @@  discard block
 block discarded – undo
605 605
                     ),
606 606
                 ],
607 607
                 'abandoned'  => [
608
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::abandoned_status_code,
608
+                    'class' => 'ee-status-legend ee-status-legend--'.EEM_Transaction::abandoned_status_code,
609 609
                     'desc'  => EEH_Template::pretty_status(
610 610
                         EEM_Transaction::abandoned_status_code,
611 611
                         false,
@@ -613,7 +613,7 @@  discard block
 block discarded – undo
613 613
                     ),
614 614
                 ],
615 615
                 'failed'     => [
616
-                    'class' => 'ee-status-legend ee-status-legend--' . EEM_Transaction::failed_status_code,
616
+                    'class' => 'ee-status-legend ee-status-legend--'.EEM_Transaction::failed_status_code,
617 617
                     'desc'  => EEH_Template::pretty_status(
618 618
                         EEM_Transaction::failed_status_code,
619 619
                         false,
@@ -656,11 +656,11 @@  discard block
 block discarded – undo
656 656
                 )
657 657
                 . '" title="'
658 658
                 . esc_attr__('Click to Edit event', 'event_espresso')
659
-                . '">' . $event->name() . '</a>',
659
+                . '">'.$event->name().'</a>',
660 660
                 '</h3>'
661 661
             )
662 662
             : '';
663
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
663
+        $this->_template_args['after_list_table'] = $this->_display_legend($this->_transaction_legend_items());
664 664
         $this->display_admin_list_table_page_with_no_sidebar();
665 665
     }
666 666
 
@@ -690,7 +690,7 @@  discard block
 block discarded – undo
690 690
 
691 691
         $this->_set_transaction_object();
692 692
 
693
-        if (! $this->_transaction instanceof EE_Transaction) {
693
+        if ( ! $this->_transaction instanceof EE_Transaction) {
694 694
             return;
695 695
         }
696 696
 
@@ -700,9 +700,9 @@  discard block
 block discarded – undo
700 700
         $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
701 701
         $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
702 702
 
703
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
703
+        $this->_template_args['txn_status']['value'] = self::$_txn_status[$this->_transaction->status_ID()];
704 704
         $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
705
-        $this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->status_ID();
705
+        $this->_template_args['txn_status']['class'] = 'status-'.$this->_transaction->status_ID();
706 706
 
707 707
         $this->_template_args['grand_total'] = $this->_transaction->total();
708 708
         $this->_template_args['total_paid']  = $this->_transaction->paid();
@@ -754,7 +754,7 @@  discard block
 block discarded – undo
754 754
 
755 755
 
756 756
         // next link
757
-        $next_txn                                 = $this->_transaction->next(
757
+        $next_txn = $this->_transaction->next(
758 758
             null,
759 759
             [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
760 760
             'TXN_ID'
@@ -769,7 +769,7 @@  discard block
 block discarded – undo
769 769
             )
770 770
             : '';
771 771
         // previous link
772
-        $previous_txn                                 = $this->_transaction->previous(
772
+        $previous_txn = $this->_transaction->previous(
773 773
             null,
774 774
             [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
775 775
             'TXN_ID'
@@ -821,7 +821,7 @@  discard block
 block discarded – undo
821 821
         // grab messages at the last second
822 822
         $this->_template_args['notices'] = EE_Error::get_notices();
823 823
         // path to template
824
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
824
+        $template_path                             = TXN_TEMPLATE_PATH.'txn_admin_details_header.template.php';
825 825
         $this->_template_args['admin_page_header'] = EEH_Template::display_template(
826 826
             $template_path,
827 827
             $this->_template_args,
@@ -850,19 +850,19 @@  discard block
 block discarded – undo
850 850
 
851 851
         $this->_set_transaction_object();
852 852
 
853
-        if (! $this->_transaction instanceof EE_Transaction) {
853
+        if ( ! $this->_transaction instanceof EE_Transaction) {
854 854
             return;
855 855
         }
856 856
         $this->addMetaBox(
857 857
             'edit-txn-details-mbox',
858
-            '<span>' . esc_html__('Transaction Details', 'event_espresso')
858
+            '<span>'.esc_html__('Transaction Details', 'event_espresso')
859 859
             . '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
860 860
             [$this, 'txn_details_meta_box'],
861 861
             $this->_wp_page_slug
862 862
         );
863 863
         $this->addMetaBox(
864 864
             'edit-txn-attendees-mbox',
865
-            '<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
865
+            '<span>'.esc_html__('Attendees Registered in this Transaction', 'event_espresso')
866 866
             . '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
867 867
             [$this, 'txn_attendees_meta_box'],
868 868
             $this->_wp_page_slug,
@@ -904,7 +904,7 @@  discard block
 block discarded – undo
904 904
     {
905 905
         $content = '';
906 906
         $actions = [];
907
-        if (! $transaction instanceof EE_Transaction) {
907
+        if ( ! $transaction instanceof EE_Transaction) {
908 908
             return $content;
909 909
         }
910 910
         /** @var EE_Registration $primary_registration */
@@ -1018,7 +1018,7 @@  discard block
 block discarded – undo
1018 1018
             $this->_transaction->primary_registration() instanceof EE_Registration
1019 1019
                 ? $this->_transaction->primary_registration()->attendee()
1020 1020
                 : null;
1021
-        $this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1021
+        $this->_template_args['can_edit_payments'] = EE_Registry::instance()->CAP->current_user_can(
1022 1022
             'ee_edit_payments',
1023 1023
             'apply_payment_or_refund_from_registration_details'
1024 1024
         );
@@ -1029,7 +1029,7 @@  discard block
 block discarded – undo
1029 1029
 
1030 1030
         // get line table
1031 1031
         EEH_Autoloader::register_line_item_display_autoloaders();
1032
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1032
+        $Line_Item_Display = new EE_Line_Item_Display(
1033 1033
             'admin_table',
1034 1034
             'EE_Admin_Table_Line_Item_Display_Strategy'
1035 1035
         );
@@ -1044,7 +1044,7 @@  discard block
 block discarded – undo
1044 1044
         $taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1045 1045
         $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1046 1046
 
1047
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1047
+        $this->_template_args['grand_total'] = EEH_Template::format_currency(
1048 1048
             $this->_transaction->total(),
1049 1049
             false,
1050 1050
             false
@@ -1054,7 +1054,7 @@  discard block
 block discarded – undo
1054 1054
 
1055 1055
         // process payment details
1056 1056
         $payments = $this->_transaction->payments();
1057
-        if (! empty($payments)) {
1057
+        if ( ! empty($payments)) {
1058 1058
             $this->_template_args['payments']              = $payments;
1059 1059
             $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1060 1060
         } else {
@@ -1116,7 +1116,7 @@  discard block
 block discarded – undo
1116 1116
                                   esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1117 1117
                                   ucwords(str_replace('_', ' ', $reg_step)),
1118 1118
                                   date(
1119
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1119
+                                      get_option('date_format').' '.get_option('time_format'),
1120 1120
                                       $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1121 1121
                                   )
1122 1122
                               )
@@ -1130,7 +1130,7 @@  discard block
 block discarded – undo
1130 1130
                               . '</li>';
1131 1131
             }
1132 1132
         }
1133
-        $reg_steps                                                 .= '</ul>';
1133
+        $reg_steps .= '</ul>';
1134 1134
         $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1135 1135
         $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1136 1136
             'Registration Step Progress',
@@ -1143,14 +1143,14 @@  discard block
 block discarded – undo
1143 1143
         $this->_get_payment_status_array();
1144 1144
         $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1145 1145
 
1146
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1146
+        $this->_template_args['transaction_form_url'] = add_query_arg(
1147 1147
             [
1148 1148
                 'action'  => 'edit_transaction',
1149 1149
                 'process' => 'transaction',
1150 1150
             ],
1151 1151
             TXN_ADMIN_URL
1152 1152
         );
1153
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1153
+        $this->_template_args['apply_payment_form_url'] = add_query_arg(
1154 1154
             [
1155 1155
                 'page'   => 'espresso_transactions',
1156 1156
                 'action' => 'espresso_apply_payment',
@@ -1169,7 +1169,7 @@  discard block
 block discarded – undo
1169 1169
 
1170 1170
         // 'espresso_delete_payment_nonce'
1171 1171
 
1172
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1172
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_txn_details.template.php';
1173 1173
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
1174 1174
     }
1175 1175
 
@@ -1201,19 +1201,19 @@  discard block
 block discarded – undo
1201 1201
                 ],
1202 1202
             ]
1203 1203
         );
1204
-        if (! empty($reg_payments)) {
1204
+        if ( ! empty($reg_payments)) {
1205 1205
             foreach ($payments as $payment) {
1206
-                if (! $payment instanceof EE_Payment) {
1206
+                if ( ! $payment instanceof EE_Payment) {
1207 1207
                     continue;
1208
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1209
-                    $existing_reg_payments[ $payment->ID() ] = [];
1208
+                } elseif ( ! isset($existing_reg_payments[$payment->ID()])) {
1209
+                    $existing_reg_payments[$payment->ID()] = [];
1210 1210
                 }
1211 1211
                 foreach ($reg_payments as $reg_payment) {
1212 1212
                     if (
1213 1213
                         $reg_payment instanceof EE_Registration_Payment
1214 1214
                         && $reg_payment->payment_ID() === $payment->ID()
1215 1215
                     ) {
1216
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1216
+                        $existing_reg_payments[$payment->ID()][] = $reg_payment->registration_ID();
1217 1217
                     }
1218 1218
                 }
1219 1219
             }
@@ -1239,7 +1239,7 @@  discard block
 block discarded – undo
1239 1239
     protected function _get_registrations_to_apply_payment_to()
1240 1240
     {
1241 1241
         // we want any registration with an active status (ie: not deleted or cancelled)
1242
-        $query_params                      = [
1242
+        $query_params = [
1243 1243
             [
1244 1244
                 'STS_ID' => [
1245 1245
                     'IN',
@@ -1251,22 +1251,22 @@  discard block
 block discarded – undo
1251 1251
                 ],
1252 1252
             ],
1253 1253
         ];
1254
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1254
+        $registrations_to_apply_payment_to = EEH_HTML::br().EEH_HTML::div(
1255 1255
             '',
1256 1256
             'txn-admin-apply-payment-to-registrations-dv',
1257 1257
             '',
1258 1258
             'clear: both; margin: 1.5em 0 0; display: none;'
1259 1259
         );
1260
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1260
+        $registrations_to_apply_payment_to .= EEH_HTML::br().EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1261 1261
         $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1262 1262
         $registrations_to_apply_payment_to .= EEH_HTML::thead(
1263 1263
             EEH_HTML::tr(
1264
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1265
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1266
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1267
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1268
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1269
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1264
+                EEH_HTML::th(esc_html__('ID', 'event_espresso')).
1265
+                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')).
1266
+                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')).
1267
+                EEH_HTML::th(esc_html__('Event', 'event_espresso')).
1268
+                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr').
1269
+                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr').
1270 1270
                 EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1271 1271
             )
1272 1272
         );
@@ -1281,34 +1281,34 @@  discard block
 block discarded – undo
1281 1281
                     : esc_html__('Unknown Attendee', 'event_espresso');
1282 1282
                 $owing                             = $registration->final_price() - $registration->paid();
1283 1283
                 $taxable                           = $registration->ticket()->taxable()
1284
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1284
+                    ? ' <span class="smaller-text lt-grey-text"> '.esc_html__('+ tax', 'event_espresso').'</span>'
1285 1285
                     : '';
1286 1286
                 $checked                           = empty($existing_reg_payments)
1287 1287
                                                      || in_array($registration->ID(), $existing_reg_payments, true)
1288 1288
                     ? ' checked="checked"'
1289 1289
                     : '';
1290
-                $disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1290
+                $disabled = $registration->final_price() > 0 ? '' : ' disabled';
1291 1291
                 $registrations_to_apply_payment_to .= EEH_HTML::tr(
1292
-                    EEH_HTML::td($registration->ID()) .
1293
-                    EEH_HTML::td($attendee_name) .
1292
+                    EEH_HTML::td($registration->ID()).
1293
+                    EEH_HTML::td($attendee_name).
1294 1294
                     EEH_HTML::td(
1295
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1296
-                    ) .
1297
-                    EEH_HTML::td($registration->event_name()) .
1298
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1295
+                        $registration->ticket()->name().' : '.$registration->ticket()->pretty_price().$taxable
1296
+                    ).
1297
+                    EEH_HTML::td($registration->event_name()).
1298
+                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr').
1299 1299
                     EEH_HTML::td(
1300 1300
                         EEH_Template::format_currency($owing),
1301 1301
                         '',
1302 1302
                         'txn-admin-payment-owing-td jst-cntr'
1303
-                    ) .
1303
+                    ).
1304 1304
                     EEH_HTML::td(
1305
-                        '<input type="checkbox" value="' . $registration->ID()
1305
+                        '<input type="checkbox" value="'.$registration->ID()
1306 1306
                         . '" name="txn_admin_payment[registrations]"'
1307
-                        . $checked . $disabled . '>',
1307
+                        . $checked.$disabled.'>',
1308 1308
                         '',
1309 1309
                         'jst-cntr'
1310 1310
                     ),
1311
-                    'apply-payment-registration-row-' . $registration->ID()
1311
+                    'apply-payment-registration-row-'.$registration->ID()
1312 1312
                 );
1313 1313
             }
1314 1314
         }
@@ -1323,7 +1323,7 @@  discard block
 block discarded – undo
1323 1323
             '',
1324 1324
             'clear description'
1325 1325
         );
1326
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1326
+        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1327 1327
         $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1328 1328
     }
1329 1329
 
@@ -1389,12 +1389,12 @@  discard block
 block discarded – undo
1389 1389
                 [
1390 1390
                     'OR*payment_method_for_payment' => [
1391 1391
                         'PMD_ID'    => ['IN', $payment_methods_of_payments],
1392
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1392
+                        'PMD_scope' => ['LIKE', '%'.EEM_Payment_Method::scope_admin.'%'],
1393 1393
                     ],
1394 1394
                 ],
1395 1395
             ];
1396 1396
         } else {
1397
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1397
+            $query_args = [['PMD_scope' => ['LIKE', '%'.EEM_Payment_Method::scope_admin.'%']]];
1398 1398
         }
1399 1399
         $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1400 1400
     }
@@ -1427,7 +1427,7 @@  discard block
 block discarded – undo
1427 1427
             'Line_Item',
1428 1428
             [['LIN_type' => 'line-item']]
1429 1429
         );
1430
-        if (! empty($line_items)) {
1430
+        if ( ! empty($line_items)) {
1431 1431
             foreach ($line_items as $item) {
1432 1432
                 if ($item instanceof EE_Line_Item) {
1433 1433
                     switch ($item->OBJ_type()) {
@@ -1437,7 +1437,7 @@  discard block
 block discarded – undo
1437 1437
                             $ticket = $item->ticket();
1438 1438
                             // right now we're only handling tickets here.
1439 1439
                             // Cause its expected that only tickets will have attendees right?
1440
-                            if (! $ticket instanceof EE_Ticket) {
1440
+                            if ( ! $ticket instanceof EE_Ticket) {
1441 1441
                                 break;
1442 1442
                             }
1443 1443
                             try {
@@ -1446,45 +1446,45 @@  discard block
 block discarded – undo
1446 1446
                                 EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1447 1447
                                 $event_name = esc_html__('Unknown Event', 'event_espresso');
1448 1448
                             }
1449
-                            $event_name   .= ' - ' . $item->name();
1449
+                            $event_name   .= ' - '.$item->name();
1450 1450
                             $ticket_price = EEH_Template::format_currency($item->unit_price());
1451 1451
                             // now get all of the registrations for this transaction that use this ticket
1452 1452
                             $registrations = $ticket->registrations(
1453 1453
                                 [['TXN_ID' => $this->_transaction->ID()]]
1454 1454
                             );
1455 1455
                             foreach ($registrations as $registration) {
1456
-                                if (! $registration instanceof EE_Registration) {
1456
+                                if ( ! $registration instanceof EE_Registration) {
1457 1457
                                     break;
1458 1458
                                 }
1459
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1459
+                                $this->_template_args['event_attendees'][$registration->ID()]['STS_ID']
1460 1460
                                     = $registration->status_ID();
1461
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1461
+                                $this->_template_args['event_attendees'][$registration->ID()]['att_num']
1462 1462
                                     = $registration->count();
1463
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1463
+                                $this->_template_args['event_attendees'][$registration->ID()]['event_ticket_name']
1464 1464
                                     = $event_name;
1465
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1465
+                                $this->_template_args['event_attendees'][$registration->ID()]['ticket_price']
1466 1466
                                     = $ticket_price;
1467 1467
                                 // attendee info
1468 1468
                                 $attendee = $registration->get_first_related('Attendee');
1469 1469
                                 if ($attendee instanceof EE_Attendee) {
1470
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1470
+                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']
1471 1471
                                         = $attendee->ID();
1472
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1472
+                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee']
1473 1473
                                         = $attendee->full_name();
1474
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1475
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1474
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']
1475
+                                        = '<a href="mailto:'.$attendee->email().'?subject='.$event_name
1476 1476
                                           . esc_html__(
1477 1477
                                               ' Event',
1478 1478
                                               'event_espresso'
1479 1479
                                           )
1480
-                                          . '">' . $attendee->email() . '</a>';
1481
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1480
+                                          . '">'.$attendee->email().'</a>';
1481
+                                    $this->_template_args['event_attendees'][$registration->ID()]['address']
1482 1482
                                         = EEH_Address::format($attendee, 'inline', false, false);
1483 1483
                                 } else {
1484
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1485
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1486
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1487
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1484
+                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']   = '';
1485
+                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee'] = '';
1486
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']    = '';
1487
+                                    $this->_template_args['event_attendees'][$registration->ID()]['address']  = '';
1488 1488
                                 }
1489 1489
                             }
1490 1490
                             break;
@@ -1500,7 +1500,7 @@  discard block
 block discarded – undo
1500 1500
                 TXN_ADMIN_URL
1501 1501
             );
1502 1502
             echo EEH_Template::display_template(
1503
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1503
+                TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_attendees.template.php',
1504 1504
                 $this->_template_args,
1505 1505
                 true
1506 1506
             );
@@ -1535,7 +1535,7 @@  discard block
 block discarded – undo
1535 1535
         $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1536 1536
             ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1537 1537
             : null;
1538
-        if (! $primary_att instanceof EE_Attendee) {
1538
+        if ( ! $primary_att instanceof EE_Attendee) {
1539 1539
             $this->_template_args['no_attendee_message'] = esc_html__(
1540 1540
                 'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1541 1541
                 'event_espresso'
@@ -1561,7 +1561,7 @@  discard block
 block discarded – undo
1561 1561
             : '';
1562 1562
         $this->_template_args['formatted_address'] = $formatted_address;
1563 1563
         echo EEH_Template::display_template(
1564
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1564
+            TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_registrant.template.php',
1565 1565
             $this->_template_args,
1566 1566
             true
1567 1567
         );
@@ -1587,7 +1587,7 @@  discard block
 block discarded – undo
1587 1587
             TXN_ADMIN_URL
1588 1588
         );
1589 1589
 
1590
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1590
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_billing_info.template.php';
1591 1591
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
1592 1592
     }
1593 1593
 
@@ -1613,7 +1613,7 @@  discard block
 block discarded – undo
1613 1613
             'ee_edit_payments',
1614 1614
             'apply_payment_or_refund_from_registration_details'
1615 1615
         );
1616
-        if (! empty($valid_data) && $has_access) {
1616
+        if ( ! empty($valid_data) && $has_access) {
1617 1617
             $PAY_ID = $valid_data['PAY_ID'];
1618 1618
             // save  the new payment
1619 1619
             $payment = $this->_create_payment_from_request_data($valid_data);
@@ -1626,7 +1626,7 @@  discard block
 block discarded – undo
1626 1626
                 $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1627 1627
                 $this->_remove_existing_registration_payments($payment, $PAY_ID);
1628 1628
                 // apply payment to registrations (if applicable)
1629
-                if (! empty($REG_IDs)) {
1629
+                if ( ! empty($REG_IDs)) {
1630 1630
                     $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1631 1631
                     $this->_maybe_send_notifications();
1632 1632
                     // now process status changes for the same registrations
@@ -1672,7 +1672,7 @@  discard block
 block discarded – undo
1672 1672
                 __LINE__
1673 1673
             );
1674 1674
         }
1675
-        $notices              = EE_Error::get_notices(
1675
+        $notices = EE_Error::get_notices(
1676 1676
             false,
1677 1677
             false,
1678 1678
             false
@@ -1697,14 +1697,14 @@  discard block
 block discarded – undo
1697 1697
      */
1698 1698
     protected function _validate_payment_request_data()
1699 1699
     {
1700
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1700
+        if ( ! $this->request->requestParamIsSet('txn_admin_payment')) {
1701 1701
             return [];
1702 1702
         }
1703 1703
         $payment_form = $this->_generate_payment_form_section();
1704 1704
         try {
1705 1705
             if ($payment_form->was_submitted()) {
1706 1706
                 $payment_form->receive_form_submission();
1707
-                if (! $payment_form->is_valid()) {
1707
+                if ( ! $payment_form->is_valid()) {
1708 1708
                     $submission_error_messages = [];
1709 1709
                     foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1710 1710
                         if ($validation_error instanceof EE_Validation_Error) {
@@ -1886,7 +1886,7 @@  discard block
 block discarded – undo
1886 1886
             ['Y-m-d', 'g:i a']
1887 1887
         );
1888 1888
 
1889
-        if (! $payment->save()) {
1889
+        if ( ! $payment->save()) {
1890 1890
             EE_Error::add_error(
1891 1891
                 sprintf(
1892 1892
                     esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
@@ -2088,12 +2088,12 @@  discard block
 block discarded – undo
2088 2088
         // but add in some conditions regarding payment,
2089 2089
         // so that we don't apply payments to registrations that are free or have already been paid for
2090 2090
         // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2091
-        if (! $payment->is_a_refund()) {
2091
+        if ( ! $payment->is_a_refund()) {
2092 2092
             $registration_query_where_params['REG_final_price']  = ['!=', 0];
2093 2093
             $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2094 2094
         }
2095 2095
         $registrations = $transaction->registrations([$registration_query_where_params]);
2096
-        if (! empty($registrations)) {
2096
+        if ( ! empty($registrations)) {
2097 2097
             /** @type EE_Payment_Processor $payment_processor */
2098 2098
             $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2099 2099
             $payment_processor->process_registration_payments($transaction, $payment, $registrations);
@@ -2175,7 +2175,7 @@  discard block
 block discarded – undo
2175 2175
             'pay_status'       => $payment->STS_ID(),
2176 2176
             'PAY_ID'           => $payment->ID(),
2177 2177
             'STS_ID'           => $payment->STS_ID(),
2178
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2178
+            'status'           => self::$_pay_status[$payment->STS_ID()],
2179 2179
             'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2180 2180
             'method'           => strtoupper($payment->source()),
2181 2181
             'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
@@ -2294,11 +2294,11 @@  discard block
 block discarded – undo
2294 2294
     {
2295 2295
         $registration_payment_data = [];
2296 2296
         // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2297
-        if (! empty($REG_IDs)) {
2297
+        if ( ! empty($REG_IDs)) {
2298 2298
             $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2299 2299
             foreach ($registrations as $registration) {
2300 2300
                 if ($registration instanceof EE_Registration) {
2301
-                    $registration_payment_data[ $registration->ID() ] = [
2301
+                    $registration_payment_data[$registration->ID()] = [
2302 2302
                         'paid'  => $registration->pretty_paid(),
2303 2303
                         'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2304 2304
                     ];
@@ -2354,7 +2354,7 @@  discard block
 block discarded – undo
2354 2354
         $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2355 2355
         $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2356 2356
         $redirect_to = $this->request->getRequestParam('redirect_to');
2357
-        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2357
+        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID, ] : [];
2358 2358
         do_action(
2359 2359
             'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2360 2360
             $transaction
@@ -2392,8 +2392,8 @@  discard block
 block discarded – undo
2392 2392
         );
2393 2393
 
2394 2394
         // make sure our timestamps start and end right at the boundaries for each day
2395
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2396
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2395
+        $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
2396
+        $end_date   = date('Y-m-d', strtotime($end_date)).' 23:59:59';
2397 2397
 
2398 2398
 
2399 2399
         // convert to timestamps
@@ -2410,7 +2410,7 @@  discard block
 block discarded – undo
2410 2410
             date('Y-m-d H:i:s', $start_date),
2411 2411
             'Y-m-d H:i:s'
2412 2412
         );
2413
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2413
+        $end_date = EEM_Transaction::instance()->convert_datetime_for_query(
2414 2414
             'TXN_timestamp',
2415 2415
             date('Y-m-d H:i:s', $end_date),
2416 2416
             'Y-m-d H:i:s'
@@ -2454,8 +2454,8 @@  discard block
 block discarded – undo
2454 2454
 
2455 2455
         $search_term = $this->request->getRequestParam('s');
2456 2456
         if ($search_term) {
2457
-            $search_term = '%' . $search_term . '%';
2458
-            $_where['OR']  = [
2457
+            $search_term = '%'.$search_term.'%';
2458
+            $_where['OR'] = [
2459 2459
                 'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2460 2460
                 'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2461 2461
                 'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
@@ -2482,9 +2482,9 @@  discard block
 block discarded – undo
2482 2482
 
2483 2483
         $status = $this->request->getRequestParam('status');
2484 2484
         // failed transactions
2485
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2486
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2487
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2485
+        $failed     = ( ! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2486
+        $abandoned  = ( ! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2487
+        $incomplete = ( ! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2488 2488
 
2489 2489
         if ($failed) {
2490 2490
             $_where['STS_ID'] = EEM_Transaction::failed_status_code;
@@ -2532,7 +2532,7 @@  discard block
 block discarded – undo
2532 2532
         $transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2533 2533
         $success         = $transaction->recalculateLineItems();
2534 2534
         $redirect_to = $this->request->getRequestParam('redirect_to');
2535
-        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2535
+        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID, ] : [];
2536 2536
         $this->_redirect_after_action(
2537 2537
             $success,
2538 2538
             esc_html__('Transaction taxes and totals', 'event_espresso'),
Please login to merge, or discard this patch.
templates/txn_admin_details_side_meta_box_registrant.template.php 1 patch
Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -62,11 +62,11 @@
 block discarded – undo
62 62
 endif;
63 63
 // only show if logged-in user has access
64 64
 if (
65
-    EE_Registry::instance()->CAP->current_user_can(
66
-        'ee_edit_contact',
67
-        'view_or_edit_contact_button',
68
-        $ATT_ID
69
-    )
65
+	EE_Registry::instance()->CAP->current_user_can(
66
+		'ee_edit_contact',
67
+		'view_or_edit_contact_button',
68
+		$ATT_ID
69
+	)
70 70
 ) : ?>
71 71
     <div class='ee-admin-button-row'>
72 72
         <a class="button button--secondary" href="<?php echo esc_url_raw($edit_attendee_url); ?>"
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 2 patches
Indentation   +2893 added lines, -2893 removed lines patch added patch discarded remove patch
@@ -16,2900 +16,2900 @@
 block discarded – undo
16 16
 class Events_Admin_Page extends EE_Admin_Page_CPT
17 17
 {
18 18
 
19
-    /**
20
-     * This will hold the event object for event_details screen.
19
+	/**
20
+	 * This will hold the event object for event_details screen.
21
+	 *
22
+	 * @var EE_Event $_event
23
+	 */
24
+	protected $_event;
25
+
26
+
27
+	/**
28
+	 * This will hold the category object for category_details screen.
29
+	 *
30
+	 * @var stdClass $_category
31
+	 */
32
+	protected $_category;
33
+
34
+
35
+	/**
36
+	 * This will hold the event model instance
37
+	 *
38
+	 * @var EEM_Event $_event_model
39
+	 */
40
+	protected $_event_model;
41
+
42
+
43
+	/**
44
+	 * @var EE_Event
45
+	 */
46
+	protected $_cpt_model_obj = false;
47
+
48
+
49
+	/**
50
+	 * @var NodeGroupDao
51
+	 */
52
+	protected $model_obj_node_group_persister;
53
+
54
+
55
+	/**
56
+	 * Initialize page props for this admin page group.
57
+	 */
58
+	protected function _init_page_props()
59
+	{
60
+		$this->page_slug        = EVENTS_PG_SLUG;
61
+		$this->page_label       = EVENTS_LABEL;
62
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
63
+		$this->_admin_base_path = EVENTS_ADMIN;
64
+		$this->_cpt_model_names = [
65
+			'create_new' => 'EEM_Event',
66
+			'edit'       => 'EEM_Event',
67
+		];
68
+		$this->_cpt_edit_routes = [
69
+			'espresso_events' => 'edit',
70
+		];
71
+		add_action(
72
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
73
+			[$this, 'verify_event_edit'],
74
+			10,
75
+			2
76
+		);
77
+	}
78
+
79
+
80
+	/**
81
+	 * Sets the ajax hooks used for this admin page group.
82
+	 */
83
+	protected function _ajax_hooks()
84
+	{
85
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
86
+	}
87
+
88
+
89
+	/**
90
+	 * Sets the page properties for this admin page group.
91
+	 */
92
+	protected function _define_page_props()
93
+	{
94
+		$this->_admin_page_title = EVENTS_LABEL;
95
+		$this->_labels           = [
96
+			'buttons'      => [
97
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
98
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
99
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
100
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
101
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
102
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
103
+			],
104
+			'editor_title' => [
105
+				'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
106
+			],
107
+			'publishbox'   => [
108
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
109
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
110
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
111
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
112
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
113
+			],
114
+		];
115
+	}
116
+
117
+
118
+	/**
119
+	 * Sets the page routes property for this admin page group.
120
+	 */
121
+	protected function _set_page_routes()
122
+	{
123
+		// load formatter helper
124
+		// load field generator helper
125
+		// is there a evt_id in the request?
126
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
127
+		$EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
128
+
129
+		$this->_page_routes = [
130
+			'default'                       => [
131
+				'func'       => '_events_overview_list_table',
132
+				'capability' => 'ee_read_events',
133
+			],
134
+			'create_new'                    => [
135
+				'func'       => '_create_new_cpt_item',
136
+				'capability' => 'ee_edit_events',
137
+			],
138
+			'edit'                          => [
139
+				'func'       => '_edit_cpt_item',
140
+				'capability' => 'ee_edit_event',
141
+				'obj_id'     => $EVT_ID,
142
+			],
143
+			'copy_event'                    => [
144
+				'func'       => '_copy_events',
145
+				'capability' => 'ee_edit_event',
146
+				'obj_id'     => $EVT_ID,
147
+				'noheader'   => true,
148
+			],
149
+			'trash_event'                   => [
150
+				'func'       => '_trash_or_restore_event',
151
+				'args'       => ['event_status' => 'trash'],
152
+				'capability' => 'ee_delete_event',
153
+				'obj_id'     => $EVT_ID,
154
+				'noheader'   => true,
155
+			],
156
+			'trash_events'                  => [
157
+				'func'       => '_trash_or_restore_events',
158
+				'args'       => ['event_status' => 'trash'],
159
+				'capability' => 'ee_delete_events',
160
+				'noheader'   => true,
161
+			],
162
+			'restore_event'                 => [
163
+				'func'       => '_trash_or_restore_event',
164
+				'args'       => ['event_status' => 'draft'],
165
+				'capability' => 'ee_delete_event',
166
+				'obj_id'     => $EVT_ID,
167
+				'noheader'   => true,
168
+			],
169
+			'restore_events'                => [
170
+				'func'       => '_trash_or_restore_events',
171
+				'args'       => ['event_status' => 'draft'],
172
+				'capability' => 'ee_delete_events',
173
+				'noheader'   => true,
174
+			],
175
+			'delete_event'                  => [
176
+				'func'       => '_delete_event',
177
+				'capability' => 'ee_delete_event',
178
+				'obj_id'     => $EVT_ID,
179
+				'noheader'   => true,
180
+			],
181
+			'delete_events'                 => [
182
+				'func'       => '_delete_events',
183
+				'capability' => 'ee_delete_events',
184
+				'noheader'   => true,
185
+			],
186
+			'view_report'                   => [
187
+				'func'       => '_view_report',
188
+				'capability' => 'ee_edit_events',
189
+			],
190
+			'default_event_settings'        => [
191
+				'func'       => '_default_event_settings',
192
+				'capability' => 'manage_options',
193
+			],
194
+			'update_default_event_settings' => [
195
+				'func'       => '_update_default_event_settings',
196
+				'capability' => 'manage_options',
197
+				'noheader'   => true,
198
+			],
199
+			'template_settings'             => [
200
+				'func'       => '_template_settings',
201
+				'capability' => 'manage_options',
202
+			],
203
+			// event category tab related
204
+			'add_category'                  => [
205
+				'func'       => '_category_details',
206
+				'capability' => 'ee_edit_event_category',
207
+				'args'       => ['add'],
208
+			],
209
+			'edit_category'                 => [
210
+				'func'       => '_category_details',
211
+				'capability' => 'ee_edit_event_category',
212
+				'args'       => ['edit'],
213
+			],
214
+			'delete_categories'             => [
215
+				'func'       => '_delete_categories',
216
+				'capability' => 'ee_delete_event_category',
217
+				'noheader'   => true,
218
+			],
219
+			'delete_category'               => [
220
+				'func'       => '_delete_categories',
221
+				'capability' => 'ee_delete_event_category',
222
+				'noheader'   => true,
223
+			],
224
+			'insert_category'               => [
225
+				'func'       => '_insert_or_update_category',
226
+				'args'       => ['new_category' => true],
227
+				'capability' => 'ee_edit_event_category',
228
+				'noheader'   => true,
229
+			],
230
+			'update_category'               => [
231
+				'func'       => '_insert_or_update_category',
232
+				'args'       => ['new_category' => false],
233
+				'capability' => 'ee_edit_event_category',
234
+				'noheader'   => true,
235
+			],
236
+			'category_list'                 => [
237
+				'func'       => '_category_list_table',
238
+				'capability' => 'ee_manage_event_categories',
239
+			],
240
+			'preview_deletion'              => [
241
+				'func'       => 'previewDeletion',
242
+				'capability' => 'ee_delete_events',
243
+			],
244
+			'confirm_deletion'              => [
245
+				'func'       => 'confirmDeletion',
246
+				'capability' => 'ee_delete_events',
247
+				'noheader'   => true,
248
+			],
249
+		];
250
+	}
251
+
252
+
253
+	/**
254
+	 * Set the _page_config property for this admin page group.
255
+	 */
256
+	protected function _set_page_config()
257
+	{
258
+		$post_id            = $this->request->getRequestParam('post', 0, 'int');
259
+		$EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
260
+		$this->_page_config = [
261
+			'default'                => [
262
+				'nav'           => [
263
+					'label' => esc_html__('Overview', 'event_espresso'),
264
+					'order' => 10,
265
+				],
266
+				'list_table'    => 'Events_Admin_List_Table',
267
+				'help_tabs'     => [
268
+					'events_overview_help_tab'                       => [
269
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
270
+						'filename' => 'events_overview',
271
+					],
272
+					'events_overview_table_column_headings_help_tab' => [
273
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
274
+						'filename' => 'events_overview_table_column_headings',
275
+					],
276
+					'events_overview_filters_help_tab'               => [
277
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
278
+						'filename' => 'events_overview_filters',
279
+					],
280
+					'events_overview_view_help_tab'                  => [
281
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
282
+						'filename' => 'events_overview_views',
283
+					],
284
+					'events_overview_other_help_tab'                 => [
285
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
286
+						'filename' => 'events_overview_other',
287
+					],
288
+				],
289
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
290
+				// 'help_tour'     => [
291
+				//     'Event_Overview_Help_Tour',
292
+				//     // 'New_Features_Test_Help_Tour' for testing multiple help tour
293
+				// ],
294
+				'qtips'         => ['EE_Event_List_Table_Tips'],
295
+				'require_nonce' => false,
296
+			],
297
+			'create_new'             => [
298
+				'nav'           => [
299
+					'label'      => esc_html__('Add Event', 'event_espresso'),
300
+					'order'      => 5,
301
+					'persistent' => false,
302
+				],
303
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
304
+				'help_tabs'     => [
305
+					'event_editor_help_tab'                            => [
306
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
307
+						'filename' => 'event_editor',
308
+					],
309
+					'event_editor_title_richtexteditor_help_tab'       => [
310
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
311
+						'filename' => 'event_editor_title_richtexteditor',
312
+					],
313
+					'event_editor_venue_details_help_tab'              => [
314
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
315
+						'filename' => 'event_editor_venue_details',
316
+					],
317
+					'event_editor_event_datetimes_help_tab'            => [
318
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
319
+						'filename' => 'event_editor_event_datetimes',
320
+					],
321
+					'event_editor_event_tickets_help_tab'              => [
322
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
323
+						'filename' => 'event_editor_event_tickets',
324
+					],
325
+					'event_editor_event_registration_options_help_tab' => [
326
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
327
+						'filename' => 'event_editor_event_registration_options',
328
+					],
329
+					'event_editor_tags_categories_help_tab'            => [
330
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
331
+						'filename' => 'event_editor_tags_categories',
332
+					],
333
+					'event_editor_questions_registrants_help_tab'      => [
334
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
335
+						'filename' => 'event_editor_questions_registrants',
336
+					],
337
+					'event_editor_save_new_event_help_tab'             => [
338
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
339
+						'filename' => 'event_editor_save_new_event',
340
+					],
341
+					'event_editor_other_help_tab'                      => [
342
+						'title'    => esc_html__('Event Other', 'event_espresso'),
343
+						'filename' => 'event_editor_other',
344
+					],
345
+				],
346
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
347
+				// 'help_tour'     => [
348
+				//     'Event_Editor_Help_Tour',
349
+				// ],
350
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
351
+				'require_nonce' => false,
352
+			],
353
+			'edit'                   => [
354
+				'nav'           => [
355
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
356
+					'order'      => 5,
357
+					'persistent' => false,
358
+					'url'        => $post_id
359
+						? EE_Admin_Page::add_query_args_and_nonce(
360
+							['post' => $post_id, 'action' => 'edit'],
361
+							$this->_current_page_view_url
362
+						)
363
+						: $this->_admin_base_url,
364
+				],
365
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
366
+				'help_tabs'     => [
367
+					'event_editor_help_tab'                            => [
368
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
369
+						'filename' => 'event_editor',
370
+					],
371
+					'event_editor_title_richtexteditor_help_tab'       => [
372
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
373
+						'filename' => 'event_editor_title_richtexteditor',
374
+					],
375
+					'event_editor_venue_details_help_tab'              => [
376
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
377
+						'filename' => 'event_editor_venue_details',
378
+					],
379
+					'event_editor_event_datetimes_help_tab'            => [
380
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
381
+						'filename' => 'event_editor_event_datetimes',
382
+					],
383
+					'event_editor_event_tickets_help_tab'              => [
384
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
385
+						'filename' => 'event_editor_event_tickets',
386
+					],
387
+					'event_editor_event_registration_options_help_tab' => [
388
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
389
+						'filename' => 'event_editor_event_registration_options',
390
+					],
391
+					'event_editor_tags_categories_help_tab'            => [
392
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
393
+						'filename' => 'event_editor_tags_categories',
394
+					],
395
+					'event_editor_questions_registrants_help_tab'      => [
396
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
397
+						'filename' => 'event_editor_questions_registrants',
398
+					],
399
+					'event_editor_save_new_event_help_tab'             => [
400
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
401
+						'filename' => 'event_editor_save_new_event',
402
+					],
403
+					'event_editor_other_help_tab'                      => [
404
+						'title'    => esc_html__('Event Other', 'event_espresso'),
405
+						'filename' => 'event_editor_other',
406
+					],
407
+				],
408
+				'require_nonce' => false,
409
+			],
410
+			'default_event_settings' => [
411
+				'nav'           => [
412
+					'label' => esc_html__('Default Settings', 'event_espresso'),
413
+					'order' => 40,
414
+				],
415
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
416
+				'labels'        => [
417
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
418
+				],
419
+				'help_tabs'     => [
420
+					'default_settings_help_tab'        => [
421
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
422
+						'filename' => 'events_default_settings',
423
+					],
424
+					'default_settings_status_help_tab' => [
425
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
426
+						'filename' => 'events_default_settings_status',
427
+					],
428
+					'default_maximum_tickets_help_tab' => [
429
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
430
+						'filename' => 'events_default_settings_max_tickets',
431
+					],
432
+				],
433
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
434
+				// 'help_tour'     => ['Event_Default_Settings_Help_Tour'],
435
+				'require_nonce' => false,
436
+			],
437
+			// template settings
438
+			'template_settings'      => [
439
+				'nav'           => [
440
+					'label' => esc_html__('Templates', 'event_espresso'),
441
+					'order' => 30,
442
+				],
443
+				'metaboxes'     => $this->_default_espresso_metaboxes,
444
+				'help_tabs'     => [
445
+					'general_settings_templates_help_tab' => [
446
+						'title'    => esc_html__('Templates', 'event_espresso'),
447
+						'filename' => 'general_settings_templates',
448
+					],
449
+				],
450
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
451
+				// 'help_tour'     => ['Templates_Help_Tour'],
452
+				'require_nonce' => false,
453
+			],
454
+			// event category stuff
455
+			'add_category'           => [
456
+				'nav'           => [
457
+					'label'      => esc_html__('Add Category', 'event_espresso'),
458
+					'order'      => 15,
459
+					'persistent' => false,
460
+				],
461
+				'help_tabs'     => [
462
+					'add_category_help_tab' => [
463
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
464
+						'filename' => 'events_add_category',
465
+					],
466
+				],
467
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
468
+				// 'help_tour'     => ['Event_Add_Category_Help_Tour'],
469
+				'metaboxes'     => ['_publish_post_box'],
470
+				'require_nonce' => false,
471
+			],
472
+			'edit_category'          => [
473
+				'nav'           => [
474
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
475
+					'order'      => 15,
476
+					'persistent' => false,
477
+					'url'        => $EVT_CAT_ID
478
+						? add_query_arg(
479
+							['EVT_CAT_ID' => $EVT_CAT_ID],
480
+							$this->_current_page_view_url
481
+						)
482
+						: $this->_admin_base_url,
483
+				],
484
+				'help_tabs'     => [
485
+					'edit_category_help_tab' => [
486
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
487
+						'filename' => 'events_edit_category',
488
+					],
489
+				],
490
+				/*'help_tour' => ['Event_Edit_Category_Help_Tour'],*/
491
+				'metaboxes'     => ['_publish_post_box'],
492
+				'require_nonce' => false,
493
+			],
494
+			'category_list'          => [
495
+				'nav'           => [
496
+					'label' => esc_html__('Categories', 'event_espresso'),
497
+					'order' => 20,
498
+				],
499
+				'list_table'    => 'Event_Categories_Admin_List_Table',
500
+				'help_tabs'     => [
501
+					'events_categories_help_tab'                       => [
502
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
503
+						'filename' => 'events_categories',
504
+					],
505
+					'events_categories_table_column_headings_help_tab' => [
506
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
507
+						'filename' => 'events_categories_table_column_headings',
508
+					],
509
+					'events_categories_view_help_tab'                  => [
510
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
511
+						'filename' => 'events_categories_views',
512
+					],
513
+					'events_categories_other_help_tab'                 => [
514
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
515
+						'filename' => 'events_categories_other',
516
+					],
517
+				],
518
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
519
+				// 'help_tour'     => [
520
+				//     'Event_Categories_Help_Tour',
521
+				// ],
522
+				'metaboxes'     => $this->_default_espresso_metaboxes,
523
+				'require_nonce' => false,
524
+			],
525
+			'preview_deletion'       => [
526
+				'nav'           => [
527
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
528
+					'order'      => 15,
529
+					'persistent' => false,
530
+					'url'        => '',
531
+				],
532
+				'require_nonce' => false,
533
+			],
534
+		];
535
+	}
536
+
537
+
538
+	/**
539
+	 * Used to register any global screen options if necessary for every route in this admin page group.
540
+	 */
541
+	protected function _add_screen_options()
542
+	{
543
+	}
544
+
545
+
546
+	/**
547
+	 * Implementing the screen options for the 'default' route.
548
+	 *
549
+	 * @throws InvalidArgumentException
550
+	 * @throws InvalidDataTypeException
551
+	 * @throws InvalidInterfaceException
552
+	 */
553
+	protected function _add_screen_options_default()
554
+	{
555
+		$this->_per_page_screen_option();
556
+	}
557
+
558
+
559
+	/**
560
+	 * Implementing screen options for the category list route.
561
+	 *
562
+	 * @throws InvalidArgumentException
563
+	 * @throws InvalidDataTypeException
564
+	 * @throws InvalidInterfaceException
565
+	 */
566
+	protected function _add_screen_options_category_list()
567
+	{
568
+		$page_title              = $this->_admin_page_title;
569
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
570
+		$this->_per_page_screen_option();
571
+		$this->_admin_page_title = $page_title;
572
+	}
573
+
574
+
575
+	/**
576
+	 * Used to register any global feature pointers for the admin page group.
577
+	 */
578
+	protected function _add_feature_pointers()
579
+	{
580
+	}
581
+
582
+
583
+	/**
584
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
585
+	 */
586
+	public function load_scripts_styles()
587
+	{
588
+		wp_register_style(
589
+			'events-admin-css',
590
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
591
+			[],
592
+			EVENT_ESPRESSO_VERSION
593
+		);
594
+		wp_register_style(
595
+			'ee-cat-admin',
596
+			EVENTS_ASSETS_URL . 'ee-cat-admin.css',
597
+			[],
598
+			EVENT_ESPRESSO_VERSION
599
+		);
600
+		wp_enqueue_style('events-admin-css');
601
+		wp_enqueue_style('ee-cat-admin');
602
+		// scripts
603
+		wp_register_script(
604
+			'event_editor_js',
605
+			EVENTS_ASSETS_URL . 'event_editor.js',
606
+			['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
607
+			EVENT_ESPRESSO_VERSION,
608
+			true
609
+		);
610
+	}
611
+
612
+
613
+	/**
614
+	 * Enqueuing scripts and styles specific to this view
615
+	 */
616
+	public function load_scripts_styles_create_new()
617
+	{
618
+		$this->load_scripts_styles_edit();
619
+	}
620
+
621
+
622
+	/**
623
+	 * Enqueuing scripts and styles specific to this view
624
+	 */
625
+	public function load_scripts_styles_edit()
626
+	{
627
+		// styles
628
+		wp_enqueue_style('espresso-ui-theme');
629
+		wp_register_style(
630
+			'event-editor-css',
631
+			EVENTS_ASSETS_URL . 'event-editor.css',
632
+			['ee-admin-css'],
633
+			EVENT_ESPRESSO_VERSION
634
+		);
635
+		wp_enqueue_style('event-editor-css');
636
+		// scripts
637
+		if (! $this->admin_config->useAdvancedEditor()) {
638
+			wp_register_script(
639
+				'event-datetime-metabox',
640
+				EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
641
+				['event_editor_js', 'ee-datepicker'],
642
+				EVENT_ESPRESSO_VERSION
643
+			);
644
+			wp_enqueue_script('event-datetime-metabox');
645
+		}
646
+	}
647
+
648
+
649
+	/**
650
+	 * Populating the _views property for the category list table view.
651
+	 */
652
+	protected function _set_list_table_views_category_list()
653
+	{
654
+		$this->_views = [
655
+			'all' => [
656
+				'slug'        => 'all',
657
+				'label'       => esc_html__('All', 'event_espresso'),
658
+				'count'       => 0,
659
+				'bulk_action' => [
660
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
661
+				],
662
+			],
663
+		];
664
+	}
665
+
666
+
667
+	/**
668
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
669
+	 */
670
+	public function admin_init()
671
+	{
672
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
673
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
674
+			'event_espresso'
675
+		);
676
+	}
677
+
678
+
679
+	/**
680
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
681
+	 * group.
682
+	 */
683
+	public function admin_notices()
684
+	{
685
+	}
686
+
687
+
688
+	/**
689
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
690
+	 * this admin page group.
691
+	 */
692
+	public function admin_footer_scripts()
693
+	{
694
+	}
695
+
696
+
697
+	/**
698
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
699
+	 * warning (via EE_Error::add_error());
700
+	 *
701
+	 * @param EE_Event $event Event object
702
+	 * @param string   $req_type
703
+	 * @return void
704
+	 * @throws EE_Error
705
+	 * @throws ReflectionException
706
+	 */
707
+	public function verify_event_edit($event = null, $req_type = '')
708
+	{
709
+		// don't need to do this when processing
710
+		if (! empty($req_type)) {
711
+			return;
712
+		}
713
+		// no event?
714
+		if (! $event instanceof EE_Event) {
715
+			$event = $this->_cpt_model_obj;
716
+		}
717
+		// STILL no event?
718
+		if (! $event instanceof EE_Event) {
719
+			return;
720
+		}
721
+		$orig_status = $event->status();
722
+		// first check if event is active.
723
+		if (
724
+			$orig_status === EEM_Event::cancelled
725
+			|| $orig_status === EEM_Event::postponed
726
+			|| $event->is_expired()
727
+			|| $event->is_inactive()
728
+		) {
729
+			return;
730
+		}
731
+		// made it here so it IS active... next check that any of the tickets are sold.
732
+		if ($event->is_sold_out(true)) {
733
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
734
+				EE_Error::add_attention(
735
+					sprintf(
736
+						esc_html__(
737
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
738
+							'event_espresso'
739
+						),
740
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
741
+					)
742
+				);
743
+			}
744
+			return;
745
+		}
746
+		if ($orig_status === EEM_Event::sold_out) {
747
+			EE_Error::add_attention(
748
+				sprintf(
749
+					esc_html__(
750
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
751
+						'event_espresso'
752
+					),
753
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
754
+				)
755
+			);
756
+		}
757
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
758
+		if (! $event->tickets_on_sale()) {
759
+			return;
760
+		}
761
+		// made it here so show warning
762
+		$this->_edit_event_warning();
763
+	}
764
+
765
+
766
+	/**
767
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
768
+	 * When needed, hook this into a EE_Error::add_error() notice.
769
+	 *
770
+	 * @access protected
771
+	 * @return void
772
+	 */
773
+	protected function _edit_event_warning()
774
+	{
775
+		// we don't want to add warnings during these requests
776
+		if ($this->request->getRequestParam('action') === 'editpost') {
777
+			return;
778
+		}
779
+		EE_Error::add_attention(
780
+			sprintf(
781
+				esc_html__(
782
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
783
+					'event_espresso'
784
+				),
785
+				'<a class="espresso-help-tab-lnk">',
786
+				'</a>'
787
+			)
788
+		);
789
+	}
790
+
791
+
792
+	/**
793
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
794
+	 * Otherwise, do the normal logic
795
+	 *
796
+	 * @return void
797
+	 * @throws EE_Error
798
+	 * @throws InvalidArgumentException
799
+	 * @throws InvalidDataTypeException
800
+	 * @throws InvalidInterfaceException
801
+	 */
802
+	protected function _create_new_cpt_item()
803
+	{
804
+		$has_timezone_string = get_option('timezone_string');
805
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
806
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
807
+			EE_Error::add_attention(
808
+				sprintf(
809
+					esc_html__(
810
+						'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
811
+						'event_espresso'
812
+					),
813
+					'<br>',
814
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
815
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
816
+					. '</select>',
817
+					'<button class="button button--secondary timezone-submit">',
818
+					'</button><span class="spinner"></span>'
819
+				),
820
+				__FILE__,
821
+				__FUNCTION__,
822
+				__LINE__
823
+			);
824
+		}
825
+		parent::_create_new_cpt_item();
826
+	}
827
+
828
+
829
+	/**
830
+	 * Sets the _views property for the default route in this admin page group.
831
+	 */
832
+	protected function _set_list_table_views_default()
833
+	{
834
+		$this->_views = [
835
+			'all'   => [
836
+				'slug'        => 'all',
837
+				'label'       => esc_html__('View All Events', 'event_espresso'),
838
+				'count'       => 0,
839
+				'bulk_action' => [
840
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
841
+				],
842
+			],
843
+			'draft' => [
844
+				'slug'        => 'draft',
845
+				'label'       => esc_html__('Draft', 'event_espresso'),
846
+				'count'       => 0,
847
+				'bulk_action' => [
848
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
849
+				],
850
+			],
851
+		];
852
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
853
+			$this->_views['trash'] = [
854
+				'slug'        => 'trash',
855
+				'label'       => esc_html__('Trash', 'event_espresso'),
856
+				'count'       => 0,
857
+				'bulk_action' => [
858
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
859
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
860
+				],
861
+			];
862
+		}
863
+	}
864
+
865
+
866
+	/**
867
+	 * Provides the legend item array for the default list table view.
868
+	 *
869
+	 * @return array
870
+	 * @throws EE_Error
871
+	 * @throws EE_Error
872
+	 */
873
+	protected function _event_legend_items()
874
+	{
875
+		$items    = [
876
+			'view_details'   => [
877
+				'class' => 'dashicons dashicons-search',
878
+				'desc'  => esc_html__('View Event', 'event_espresso'),
879
+			],
880
+			'edit_event'     => [
881
+				'class' => 'ee-icon ee-icon-calendar-edit',
882
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
883
+			],
884
+			'view_attendees' => [
885
+				'class' => 'dashicons dashicons-groups',
886
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
887
+			],
888
+		];
889
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
890
+		$statuses = [
891
+			'sold_out_status'  => [
892
+				'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::sold_out,
893
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
894
+			],
895
+			'active_status'    => [
896
+				'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::active,
897
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
898
+			],
899
+			'upcoming_status'  => [
900
+				'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::upcoming,
901
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
902
+			],
903
+			'postponed_status' => [
904
+				'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::postponed,
905
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
906
+			],
907
+			'cancelled_status' => [
908
+				'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::cancelled,
909
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
910
+			],
911
+			'expired_status'   => [
912
+				'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::expired,
913
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
914
+			],
915
+			'inactive_status'  => [
916
+				'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::inactive,
917
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
918
+			],
919
+		];
920
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
921
+		return array_merge($items, $statuses);
922
+	}
923
+
924
+
925
+	/**
926
+	 * @return EEM_Event
927
+	 * @throws EE_Error
928
+	 * @throws InvalidArgumentException
929
+	 * @throws InvalidDataTypeException
930
+	 * @throws InvalidInterfaceException
931
+	 * @throws ReflectionException
932
+	 */
933
+	private function _event_model()
934
+	{
935
+		if (! $this->_event_model instanceof EEM_Event) {
936
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
937
+		}
938
+		return $this->_event_model;
939
+	}
940
+
941
+
942
+	/**
943
+	 * Adds extra buttons to the WP CPT permalink field row.
944
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
945
+	 *
946
+	 * @param string $return    the current html
947
+	 * @param int    $id        the post id for the page
948
+	 * @param string $new_title What the title is
949
+	 * @param string $new_slug  what the slug is
950
+	 * @return string            The new html string for the permalink area
951
+	 */
952
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
953
+	{
954
+		// make sure this is only when editing
955
+		if (! empty($id)) {
956
+			$post = get_post($id);
957
+			$return .= '<a class="button button--secondary" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
958
+					   . esc_html__('Shortcode', 'event_espresso')
959
+					   . '</a> ';
960
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
961
+					   . $post->ID
962
+					   . ']">';
963
+		}
964
+		return $return;
965
+	}
966
+
967
+
968
+	/**
969
+	 * _events_overview_list_table
970
+	 * This contains the logic for showing the events_overview list
971
+	 *
972
+	 * @access protected
973
+	 * @return void
974
+	 * @throws DomainException
975
+	 * @throws EE_Error
976
+	 * @throws InvalidArgumentException
977
+	 * @throws InvalidDataTypeException
978
+	 * @throws InvalidInterfaceException
979
+	 */
980
+	protected function _events_overview_list_table()
981
+	{
982
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
983
+		$after_list_table                           = [];
984
+		$after_list_table['view_event_list_button'] = EEH_HTML::br();
985
+		$after_list_table['view_event_list_button'] .= EEH_Template::get_button_or_link(
986
+			get_post_type_archive_link('espresso_events'),
987
+			esc_html__('View Event Archive Page', 'event_espresso'),
988
+			'button'
989
+		);
990
+		$after_list_table['legend']                 = $this->_display_legend($this->_event_legend_items());
991
+		$this->_admin_page_title                    .= ' ' . $this->get_action_link_or_button(
992
+			'create_new',
993
+			'add',
994
+			[],
995
+			'add-new-h2'
996
+		);
997
+		$this->_template_args['after_list_table']   = array_merge(
998
+			(array) $this->_template_args['after_list_table'],
999
+			$after_list_table
1000
+		);
1001
+		$this->display_admin_list_table_page_with_no_sidebar();
1002
+	}
1003
+
1004
+
1005
+	/**
1006
+	 * this allows for extra misc actions in the default WP publish box
1007
+	 *
1008
+	 * @return void
1009
+	 * @throws DomainException
1010
+	 * @throws EE_Error
1011
+	 * @throws InvalidArgumentException
1012
+	 * @throws InvalidDataTypeException
1013
+	 * @throws InvalidInterfaceException
1014
+	 * @throws ReflectionException
1015
+	 */
1016
+	public function extra_misc_actions_publish_box()
1017
+	{
1018
+		$this->_generate_publish_box_extra_content();
1019
+	}
1020
+
1021
+
1022
+	/**
1023
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1024
+	 * saved.
1025
+	 * Typically you would use this to save any additional data.
1026
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
1027
+	 * ALSO very important.  When a post transitions from scheduled to published,
1028
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1029
+	 * other meta saves. So MAKE sure that you handle this accordingly.
1030
+	 *
1031
+	 * @access protected
1032
+	 * @abstract
1033
+	 * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
1034
+	 * @param object $post    The post object of the cpt that was saved.
1035
+	 * @return void
1036
+	 * @throws EE_Error
1037
+	 * @throws InvalidArgumentException
1038
+	 * @throws InvalidDataTypeException
1039
+	 * @throws InvalidInterfaceException
1040
+	 * @throws ReflectionException
1041
+	 */
1042
+	protected function _insert_update_cpt_item($post_id, $post)
1043
+	{
1044
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1045
+			// get out we're not processing an event save.
1046
+			return;
1047
+		}
1048
+		$event_values = [
1049
+			'EVT_member_only'     => $this->request->getRequestParam('member_only', false, 'bool'),
1050
+			'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, 'bool'),
1051
+			'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1052
+		];
1053
+		// check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1054
+		if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1055
+			$event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1056
+				'display_ticket_selector',
1057
+				false,
1058
+				'bool'
1059
+			);
1060
+			$event_values['EVT_additional_limit']            = min(
1061
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1062
+				$this->request->getRequestParam('additional_limit', null, 'int')
1063
+			);
1064
+			$event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1065
+				'EVT_default_registration_status',
1066
+				EE_Registry::instance()->CFG->registration->default_STS_ID
1067
+			);
1068
+
1069
+			$event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1070
+			$event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1071
+			$event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, 'bool');
1072
+		}
1073
+		// update event
1074
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1075
+		// get event_object for other metaboxes...
1076
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1077
+		// i have to setup where conditions to override the filters in the model
1078
+		// that filter out autodraft and inherit statuses so we GET the inherit id!
1079
+		$event = $this->_event_model()->get_one(
1080
+			[
1081
+				[
1082
+					$this->_event_model()->primary_key_name() => $post_id,
1083
+					'OR'                                      => [
1084
+						'status'   => $post->post_status,
1085
+						// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1086
+						// but the returned object here has a status of "publish", so use the original post status as well
1087
+						'status*1' => $this->request->getRequestParam('original_post_status'),
1088
+					],
1089
+				],
1090
+			]
1091
+		);
1092
+
1093
+		// the following are default callbacks for event attachment updates
1094
+		// that can be overridden by caffeinated functionality and/or addons.
1095
+		$event_update_callbacks = [];
1096
+		if (! $this->admin_config->useAdvancedEditor()) {
1097
+			$event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1098
+			$event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1099
+		}
1100
+		$event_update_callbacks = apply_filters(
1101
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1102
+			$event_update_callbacks
1103
+		);
1104
+
1105
+		$att_success = true;
1106
+		foreach ($event_update_callbacks as $e_callback) {
1107
+			$_success = is_callable($e_callback)
1108
+				? $e_callback($event, $this->request->requestParams())
1109
+				: false;
1110
+			// if ANY of these updates fail then we want the appropriate global error message
1111
+			$att_success = $_success !== false ? $att_success : false;
1112
+		}
1113
+		// any errors?
1114
+		if ($success && $att_success === false) {
1115
+			EE_Error::add_error(
1116
+				esc_html__(
1117
+					'Event Details saved successfully but something went wrong with saving attachments.',
1118
+					'event_espresso'
1119
+				),
1120
+				__FILE__,
1121
+				__FUNCTION__,
1122
+				__LINE__
1123
+			);
1124
+		} elseif ($success === false) {
1125
+			EE_Error::add_error(
1126
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1127
+				__FILE__,
1128
+				__FUNCTION__,
1129
+				__LINE__
1130
+			);
1131
+		}
1132
+	}
1133
+
1134
+
1135
+	/**
1136
+	 * @param int $post_id
1137
+	 * @param int $revision_id
1138
+	 * @throws EE_Error
1139
+	 * @throws EE_Error
1140
+	 * @throws ReflectionException
1141
+	 * @see parent::restore_item()
1142
+	 */
1143
+	protected function _restore_cpt_item($post_id, $revision_id)
1144
+	{
1145
+		// copy existing event meta to new post
1146
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1147
+		if ($post_evt instanceof EE_Event) {
1148
+			// meta revision restore
1149
+			$post_evt->restore_revision($revision_id);
1150
+			// related objs restore
1151
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1152
+		}
1153
+	}
1154
+
1155
+
1156
+	/**
1157
+	 * Attach the venue to the Event
1158
+	 *
1159
+	 * @param EE_Event $event Event Object to add the venue to
1160
+	 * @param array    $data  The request data from the form
1161
+	 * @return bool           Success or fail.
1162
+	 * @throws EE_Error
1163
+	 * @throws ReflectionException
1164
+	 */
1165
+	protected function _default_venue_update(EE_Event $event, $data)
1166
+	{
1167
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1168
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1169
+		$venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1170
+		// very important.  If we don't have a venue name...
1171
+		// then we'll get out because not necessary to create empty venue
1172
+		if (empty($data['venue_title'])) {
1173
+			return false;
1174
+		}
1175
+		$venue_array = [
1176
+			'VNU_wp_user'         => $event->get('EVT_wp_user'),
1177
+			'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1178
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1179
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1180
+			'VNU_short_desc'      => ! empty($data['venue_short_description'])
1181
+				? $data['venue_short_description']
1182
+				: null,
1183
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1184
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1185
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1186
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1187
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1188
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1189
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1190
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1191
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1192
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1193
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1194
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1195
+			'status'              => 'publish',
1196
+		];
1197
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1198
+		if (! empty($venue_id)) {
1199
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1200
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1201
+			// we've gotta make sure that the venue is always attached to a revision..
1202
+			// add_relation_to should take care of making sure that the relation is already present.
1203
+			$event->_add_relation_to($venue_id, 'Venue');
1204
+			return $rows_affected > 0;
1205
+		}
1206
+		// we insert the venue
1207
+		$venue_id = $venue_model->insert($venue_array);
1208
+		$event->_add_relation_to($venue_id, 'Venue');
1209
+		return ! empty($venue_id);
1210
+		// when we have the ancestor come in it's already been handled by the revision save.
1211
+	}
1212
+
1213
+
1214
+	/**
1215
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1216
+	 *
1217
+	 * @param EE_Event $event The Event object we're attaching data to
1218
+	 * @param array    $data  The request data from the form
1219
+	 * @return array
1220
+	 * @throws EE_Error
1221
+	 * @throws ReflectionException
1222
+	 * @throws Exception
1223
+	 */
1224
+	protected function _default_tickets_update(EE_Event $event, $data)
1225
+	{
1226
+		if ($this->admin_config->useAdvancedEditor()) {
1227
+			return [];
1228
+		}
1229
+		$datetime       = null;
1230
+		$saved_tickets  = [];
1231
+		$event_timezone = $event->get_timezone();
1232
+		$date_formats   = ['Y-m-d', 'h:i a'];
1233
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1234
+			// trim all values to ensure any excess whitespace is removed.
1235
+			$datetime_data                = array_map('trim', $datetime_data);
1236
+			$datetime_data['DTT_EVT_end'] =
1237
+				isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1238
+					? $datetime_data['DTT_EVT_end']
1239
+					: $datetime_data['DTT_EVT_start'];
1240
+			$datetime_values              = [
1241
+				'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1242
+				'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1243
+				'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1244
+				'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1245
+				'DTT_order'     => $row,
1246
+			];
1247
+			// if we have an id then let's get existing object first and then set the new values.
1248
+			//  Otherwise we instantiate a new object for save.
1249
+			if (! empty($datetime_data['DTT_ID'])) {
1250
+				$datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1251
+				if (! $datetime instanceof EE_Ticket) {
1252
+					throw new RuntimeException(
1253
+						sprintf(
1254
+							esc_html__(
1255
+								'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1256
+								'event_espresso'
1257
+							),
1258
+							$datetime_data['DTT_ID']
1259
+						)
1260
+					);
1261
+				}
1262
+				$datetime->set_date_format($date_formats[0]);
1263
+				$datetime->set_time_format($date_formats[1]);
1264
+				foreach ($datetime_values as $field => $value) {
1265
+					$datetime->set($field, $value);
1266
+				}
1267
+			} else {
1268
+				$datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1269
+			}
1270
+			if (! $datetime instanceof EE_Datetime) {
1271
+				throw new RuntimeException(
1272
+					sprintf(
1273
+						esc_html__(
1274
+							'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1275
+							'event_espresso'
1276
+						),
1277
+						print_r($datetime_values, true)
1278
+					)
1279
+				);
1280
+			}
1281
+			// before going any further make sure our dates are setup correctly
1282
+			// so that the end date is always equal or greater than the start date.
1283
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1284
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1285
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1286
+			}
1287
+			$datetime->save();
1288
+			$event->_add_relation_to($datetime, 'Datetime');
1289
+		}
1290
+		// no datetimes get deleted so we don't do any of that logic here.
1291
+		// update tickets next
1292
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1293
+
1294
+		// set up some default start and end dates in case those are not present in the incoming data
1295
+		$default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1296
+		$default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1297
+		// use the start date of the first datetime for the end date
1298
+		$first_datetime   = $event->first_datetime();
1299
+		$default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1300
+
1301
+		// now process the incoming data
1302
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
1303
+			$update_prices = false;
1304
+			$ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1305
+				? $data['edit_prices'][ $row ][1]['PRC_amount']
1306
+				: 0;
1307
+			// trim inputs to ensure any excess whitespace is removed.
1308
+			$ticket_data   = array_map('trim', $ticket_data);
1309
+			$ticket_values = [
1310
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1311
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1312
+				'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1313
+				'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1314
+				'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1315
+					? $ticket_data['TKT_start_date']
1316
+					: $default_start_date,
1317
+				'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1318
+					? $ticket_data['TKT_end_date']
1319
+					: $default_end_date,
1320
+				'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1321
+									 || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1322
+					? $ticket_data['TKT_qty']
1323
+					: EE_INF,
1324
+				'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1325
+									 || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1326
+					? $ticket_data['TKT_uses']
1327
+					: EE_INF,
1328
+				'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1329
+				'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1330
+				'TKT_order'       => isset($ticket_data['TKT_order']) ? $ticket_data['TKT_order'] : $row,
1331
+				'TKT_price'       => $ticket_price,
1332
+				'TKT_row'         => $row,
1333
+			];
1334
+			// if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1335
+			// which means in turn that the prices will become new prices as well.
1336
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1337
+				$ticket_values['TKT_ID']         = 0;
1338
+				$ticket_values['TKT_is_default'] = 0;
1339
+				$update_prices                   = true;
1340
+			}
1341
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1342
+			// we actually do our saves ahead of adding any relations because its entirely possible that this
1343
+			// ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1344
+			// keep in mind that if the ticket has been sold (and we have changed pricing information),
1345
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1346
+			if (! empty($ticket_data['TKT_ID'])) {
1347
+				$existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1348
+				if (! $existing_ticket instanceof EE_Ticket) {
1349
+					throw new RuntimeException(
1350
+						sprintf(
1351
+							esc_html__(
1352
+								'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1353
+								'event_espresso'
1354
+							),
1355
+							$ticket_data['TKT_ID']
1356
+						)
1357
+					);
1358
+				}
1359
+				$ticket_sold = $existing_ticket->count_related(
1360
+					'Registration',
1361
+					[
1362
+							[
1363
+								'STS_ID' => [
1364
+									'NOT IN',
1365
+									[EEM_Registration::status_id_incomplete],
1366
+								],
1367
+							],
1368
+						]
1369
+				) > 0;
1370
+				// let's just check the total price for the existing ticket and determine if it matches the new total price.
1371
+				// if they are different then we create a new ticket (if $ticket_sold)
1372
+				// if they aren't different then we go ahead and modify existing ticket.
1373
+				$create_new_ticket = $ticket_sold
1374
+									 && $ticket_price !== $existing_ticket->price()
1375
+									 && ! $existing_ticket->deleted();
1376
+				$existing_ticket->set_date_format($date_formats[0]);
1377
+				$existing_ticket->set_time_format($date_formats[1]);
1378
+				// set new values
1379
+				foreach ($ticket_values as $field => $value) {
1380
+					if ($field == 'TKT_qty') {
1381
+						$existing_ticket->set_qty($value);
1382
+					} elseif ($field == 'TKT_price') {
1383
+						$existing_ticket->set('TKT_price', $ticket_price);
1384
+					} else {
1385
+						$existing_ticket->set($field, $value);
1386
+					}
1387
+				}
1388
+				$ticket = $existing_ticket;
1389
+				// if $create_new_ticket is false then we can safely update the existing ticket.
1390
+				//  Otherwise we have to create a new ticket.
1391
+				if ($create_new_ticket) {
1392
+					// archive the old ticket first
1393
+					$existing_ticket->set('TKT_deleted', 1);
1394
+					$existing_ticket->save();
1395
+					// make sure this ticket is still recorded in our $saved_tickets
1396
+					// so we don't run it through the regular trash routine.
1397
+					$saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1398
+					// create new ticket that's a copy of the existing except,
1399
+					// (a new id of course and not archived) AND has the new TKT_price associated with it.
1400
+					$new_ticket = clone $existing_ticket;
1401
+					$new_ticket->set('TKT_ID', 0);
1402
+					$new_ticket->set('TKT_deleted', 0);
1403
+					$new_ticket->set('TKT_sold', 0);
1404
+					// now we need to make sure that $new prices are created as well and attached to new ticket.
1405
+					$update_prices = true;
1406
+					$ticket        = $new_ticket;
1407
+				}
1408
+			} else {
1409
+				// no TKT_id so a new ticket
1410
+				$ticket_values['TKT_price'] = $ticket_price;
1411
+				$ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1412
+				$update_prices              = true;
1413
+			}
1414
+			if (! $ticket instanceof EE_Ticket) {
1415
+				throw new RuntimeException(
1416
+					sprintf(
1417
+						esc_html__(
1418
+							'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1419
+							'event_espresso'
1420
+						),
1421
+						print_r($ticket_values, true)
1422
+					)
1423
+				);
1424
+			}
1425
+			// cap ticket qty by datetime reg limits
1426
+			$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1427
+			// update ticket.
1428
+			$ticket->save();
1429
+			// before going any further make sure our dates are setup correctly
1430
+			// so that the end date is always equal or greater than the start date.
1431
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1432
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1433
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1434
+				$ticket->save();
1435
+			}
1436
+			// initially let's add the ticket to the datetime
1437
+			$datetime->_add_relation_to($ticket, 'Ticket');
1438
+			$saved_tickets[ $ticket->ID() ] = $ticket;
1439
+			// add prices to ticket
1440
+			$this->_add_prices_to_ticket($data['edit_prices'][ $row ], $ticket, $update_prices);
1441
+		}
1442
+		// however now we need to handle permanently deleting tickets via the ui.
1443
+		//  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1444
+		//  However, it does allow for deleting tickets that have no tickets sold,
1445
+		// in which case we want to get rid of permanently because there is no need to save in db.
1446
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1447
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1448
+		foreach ($tickets_removed as $id) {
1449
+			$id = absint($id);
1450
+			// get the ticket for this id
1451
+			$ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1452
+			if (! $ticket_to_remove instanceof EE_Ticket) {
1453
+				continue;
1454
+			}
1455
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1456
+			// (remember this process can ONLY kick off if there are NO tickets sold)
1457
+			$related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1458
+			foreach ($related_datetimes as $related_datetime) {
1459
+				$ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1460
+			}
1461
+			// need to do the same for prices (except these prices can also be deleted because again,
1462
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1463
+			$ticket_to_remove->delete_related_permanently('Price');
1464
+			// finally let's delete this ticket
1465
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1466
+			$ticket_to_remove->delete_permanently();
1467
+		}
1468
+		return [$datetime, $saved_tickets];
1469
+	}
1470
+
1471
+
1472
+	/**
1473
+	 * This attaches a list of given prices to a ticket.
1474
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices)
1475
+	 * because if there is a change in price information on a ticket, a new ticket is created anyways
1476
+	 * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1477
+	 *
1478
+	 * @access  private
1479
+	 * @param array     $prices_data Array of prices from the form.
1480
+	 * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1481
+	 * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1482
+	 * @return  void
1483
+	 * @throws EE_Error
1484
+	 * @throws ReflectionException
1485
+	 */
1486
+	private function _add_prices_to_ticket($prices_data, EE_Ticket $ticket, $new_prices = false)
1487
+	{
1488
+		$timezone = $ticket->get_timezone();
1489
+		foreach ($prices_data as $row => $price_data) {
1490
+			$price_values = [
1491
+				'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1492
+				'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1493
+				'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1494
+				'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1495
+				'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1496
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1497
+				'PRC_order'      => $row,
1498
+			];
1499
+			if ($new_prices || empty($price_values['PRC_ID'])) {
1500
+				$price_values['PRC_ID'] = 0;
1501
+				$price                  = EE_Price::new_instance($price_values, $timezone);
1502
+			} else {
1503
+				$price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1504
+				// update this price with new values
1505
+				foreach ($price_values as $field => $new_price) {
1506
+					$price->set($field, $new_price);
1507
+				}
1508
+			}
1509
+			if (! $price instanceof EE_Price) {
1510
+				throw new RuntimeException(
1511
+					sprintf(
1512
+						esc_html__(
1513
+							'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1514
+							'event_espresso'
1515
+						),
1516
+						print_r($price_values, true)
1517
+					)
1518
+				);
1519
+			}
1520
+			$price->save();
1521
+			$ticket->_add_relation_to($price, 'Price');
1522
+		}
1523
+	}
1524
+
1525
+
1526
+	/**
1527
+	 * Add in our autosave ajax handlers
1528
+	 *
1529
+	 */
1530
+	protected function _ee_autosave_create_new()
1531
+	{
1532
+	}
1533
+
1534
+
1535
+	/**
1536
+	 * More autosave handlers.
1537
+	 */
1538
+	protected function _ee_autosave_edit()
1539
+	{
1540
+	}
1541
+
1542
+
1543
+	/**
1544
+	 * @throws EE_Error
1545
+	 * @throws ReflectionException
1546
+	 */
1547
+	private function _generate_publish_box_extra_content()
1548
+	{
1549
+		// load formatter helper
1550
+		// args for getting related registrations
1551
+		$approved_query_args        = [
1552
+			[
1553
+				'REG_deleted' => 0,
1554
+				'STS_ID'      => EEM_Registration::status_id_approved,
1555
+			],
1556
+		];
1557
+		$not_approved_query_args    = [
1558
+			[
1559
+				'REG_deleted' => 0,
1560
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1561
+			],
1562
+		];
1563
+		$pending_payment_query_args = [
1564
+			[
1565
+				'REG_deleted' => 0,
1566
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1567
+			],
1568
+		];
1569
+		// publish box
1570
+		$publish_box_extra_args = [
1571
+			'view_approved_reg_url'        => add_query_arg(
1572
+				[
1573
+					'action'      => 'default',
1574
+					'event_id'    => $this->_cpt_model_obj->ID(),
1575
+					'_reg_status' => EEM_Registration::status_id_approved,
1576
+				],
1577
+				REG_ADMIN_URL
1578
+			),
1579
+			'view_not_approved_reg_url'    => add_query_arg(
1580
+				[
1581
+					'action'      => 'default',
1582
+					'event_id'    => $this->_cpt_model_obj->ID(),
1583
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1584
+				],
1585
+				REG_ADMIN_URL
1586
+			),
1587
+			'view_pending_payment_reg_url' => add_query_arg(
1588
+				[
1589
+					'action'      => 'default',
1590
+					'event_id'    => $this->_cpt_model_obj->ID(),
1591
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1592
+				],
1593
+				REG_ADMIN_URL
1594
+			),
1595
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1596
+				'Registration',
1597
+				$approved_query_args
1598
+			),
1599
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1600
+				'Registration',
1601
+				$not_approved_query_args
1602
+			),
1603
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1604
+				'Registration',
1605
+				$pending_payment_query_args
1606
+			),
1607
+			'misc_pub_section_class'       => apply_filters(
1608
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1609
+				'misc-pub-section'
1610
+			),
1611
+		];
1612
+		ob_start();
1613
+		do_action(
1614
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1615
+			$this->_cpt_model_obj
1616
+		);
1617
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1618
+		// load template
1619
+		EEH_Template::display_template(
1620
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1621
+			$publish_box_extra_args
1622
+		);
1623
+	}
1624
+
1625
+
1626
+	/**
1627
+	 * @return EE_Event
1628
+	 */
1629
+	public function get_event_object()
1630
+	{
1631
+		return $this->_cpt_model_obj;
1632
+	}
1633
+
1634
+
1635
+
1636
+
1637
+	/** METABOXES * */
1638
+	/**
1639
+	 * _register_event_editor_meta_boxes
1640
+	 * add all metaboxes related to the event_editor
1641
+	 *
1642
+	 * @return void
1643
+	 * @throws EE_Error
1644
+	 * @throws ReflectionException
1645
+	 */
1646
+	protected function _register_event_editor_meta_boxes()
1647
+	{
1648
+		$this->verify_cpt_object();
1649
+		$use_advanced_editor = $this->admin_config->useAdvancedEditor();
1650
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1651
+		if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1652
+			$this->addMetaBox(
1653
+				'espresso_event_editor_event_options',
1654
+				esc_html__('Event Registration Options', 'event_espresso'),
1655
+				[$this, 'registration_options_meta_box'],
1656
+				$this->page_slug,
1657
+				'side'
1658
+			);
1659
+		}
1660
+		if (! $use_advanced_editor) {
1661
+			$this->addMetaBox(
1662
+				'espresso_event_editor_tickets',
1663
+				esc_html__('Event Datetime & Ticket', 'event_espresso'),
1664
+				[$this, 'ticket_metabox'],
1665
+				$this->page_slug,
1666
+				'normal',
1667
+				'high'
1668
+			);
1669
+		} elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1670
+			add_action(
1671
+				'add_meta_boxes_espresso_events',
1672
+				function () {
1673
+					global $current_screen;
1674
+					remove_meta_box('authordiv', $current_screen, 'normal');
1675
+				},
1676
+				99
1677
+			);
1678
+		}
1679
+		// NOTE: if you're looking for other metaboxes in here,
1680
+		// where a metabox has a related management page in the admin
1681
+		// you will find it setup in the related management page's "_Hooks" file.
1682
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1683
+	}
1684
+
1685
+
1686
+	/**
1687
+	 * @throws DomainException
1688
+	 * @throws EE_Error
1689
+	 * @throws ReflectionException
1690
+	 */
1691
+	public function ticket_metabox()
1692
+	{
1693
+		$existing_datetime_ids = $existing_ticket_ids = [];
1694
+		// defaults for template args
1695
+		$template_args = [
1696
+			'existing_datetime_ids'    => '',
1697
+			'event_datetime_help_link' => '',
1698
+			'ticket_options_help_link' => '',
1699
+			'time'                     => null,
1700
+			'ticket_rows'              => '',
1701
+			'existing_ticket_ids'      => '',
1702
+			'total_ticket_rows'        => 1,
1703
+			'ticket_js_structure'      => '',
1704
+			'trash_icon'               => 'dashicons dashicons-lock',
1705
+			'disabled'                 => '',
1706
+		];
1707
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1708
+		/**
1709
+		 * 1. Start with retrieving Datetimes
1710
+		 * 2. Fore each datetime get related tickets
1711
+		 * 3. For each ticket get related prices
1712
+		 */
1713
+		/** @var EEM_Datetime $datetime_model */
1714
+		$datetime_model = EE_Registry::instance()->load_model('Datetime');
1715
+		/** @var EEM_Ticket $datetime_model */
1716
+		$ticket_model = EE_Registry::instance()->load_model('Ticket');
1717
+		$times        = $datetime_model->get_all_event_dates($event_id);
1718
+		/** @type EE_Datetime $first_datetime */
1719
+		$first_datetime = reset($times);
1720
+		// do we get related tickets?
1721
+		if (
1722
+			$first_datetime instanceof EE_Datetime
1723
+			&& $first_datetime->ID() !== 0
1724
+		) {
1725
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1726
+			$template_args['time']   = $first_datetime;
1727
+			$related_tickets         = $first_datetime->tickets(
1728
+				[
1729
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1730
+					'default_where_conditions' => 'none',
1731
+				]
1732
+			);
1733
+			if (! empty($related_tickets)) {
1734
+				$template_args['total_ticket_rows'] = count($related_tickets);
1735
+				$row                                = 0;
1736
+				foreach ($related_tickets as $ticket) {
1737
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1738
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1739
+					$row++;
1740
+				}
1741
+			} else {
1742
+				$template_args['total_ticket_rows'] = 1;
1743
+				/** @type EE_Ticket $ticket */
1744
+				$ticket                       = $ticket_model->create_default_object();
1745
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1746
+			}
1747
+		} else {
1748
+			$template_args['time'] = $times[0];
1749
+			/** @type EE_Ticket[] $tickets */
1750
+			$tickets                      = $ticket_model->get_all_default_tickets();
1751
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1752
+			// NOTE: we're just sending the first default row
1753
+			// (decaf can't manage default tickets so this should be sufficient);
1754
+		}
1755
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1756
+			'event_editor_event_datetimes_help_tab'
1757
+		);
1758
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1759
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1760
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1761
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1762
+			$ticket_model->create_default_object(),
1763
+			true
1764
+		);
1765
+		$template                                  = apply_filters(
1766
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1767
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1768
+		);
1769
+		EEH_Template::display_template($template, $template_args);
1770
+	}
1771
+
1772
+
1773
+	/**
1774
+	 * Setup an individual ticket form for the decaf event editor page
1775
+	 *
1776
+	 * @access private
1777
+	 * @param EE_Ticket $ticket   the ticket object
1778
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1779
+	 * @param int       $row
1780
+	 * @return string generated html for the ticket row.
1781
+	 * @throws EE_Error
1782
+	 * @throws ReflectionException
1783
+	 */
1784
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1785
+	{
1786
+		$template_args = [
1787
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1788
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1789
+				: '',
1790
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1791
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1792
+			'TKT_name'            => $ticket->get('TKT_name'),
1793
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1794
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1795
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1796
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1797
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1798
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1799
+			'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1800
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1801
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'dashicons dashicons-lock',
1802
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1803
+				: ' disabled=disabled',
1804
+		];
1805
+		$price         = $ticket->ID() !== 0
1806
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1807
+			: null;
1808
+		$price         = $price instanceof EE_Price
1809
+			? $price
1810
+			: EEM_Price::instance()->create_default_object();
1811
+		$price_args    = [
1812
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1813
+			'PRC_amount'            => $price->get('PRC_amount'),
1814
+			'PRT_ID'                => $price->get('PRT_ID'),
1815
+			'PRC_ID'                => $price->get('PRC_ID'),
1816
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1817
+		];
1818
+		// make sure we have default start and end dates if skeleton
1819
+		// handle rows that should NOT be empty
1820
+		if (empty($template_args['TKT_start_date'])) {
1821
+			// if empty then the start date will be now.
1822
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1823
+		}
1824
+		if (empty($template_args['TKT_end_date'])) {
1825
+			// get the earliest datetime (if present);
1826
+			$earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1827
+				? $this->_cpt_model_obj->get_first_related(
1828
+					'Datetime',
1829
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1830
+				)
1831
+				: null;
1832
+			$template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1833
+				? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1834
+				: date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1835
+		}
1836
+		$template_args = array_merge($template_args, $price_args);
1837
+		$template      = apply_filters(
1838
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1839
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1840
+			$ticket
1841
+		);
1842
+		return EEH_Template::display_template($template, $template_args, true);
1843
+	}
1844
+
1845
+
1846
+	/**
1847
+	 * @throws EE_Error
1848
+	 * @throws ReflectionException
1849
+	 */
1850
+	public function registration_options_meta_box()
1851
+	{
1852
+		$yes_no_values             = [
1853
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1854
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1855
+		];
1856
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1857
+			[
1858
+				EEM_Registration::status_id_cancelled,
1859
+				EEM_Registration::status_id_declined,
1860
+				EEM_Registration::status_id_incomplete,
1861
+			],
1862
+			true
1863
+		);
1864
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1865
+		$template_args['_event']                          = $this->_cpt_model_obj;
1866
+		$template_args['event']                           = $this->_cpt_model_obj;
1867
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1868
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1869
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1870
+			'default_reg_status',
1871
+			$default_reg_status_values,
1872
+			$this->_cpt_model_obj->default_registration_status()
1873
+		);
1874
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1875
+			'display_desc',
1876
+			$yes_no_values,
1877
+			$this->_cpt_model_obj->display_description()
1878
+		);
1879
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1880
+			'display_ticket_selector',
1881
+			$yes_no_values,
1882
+			$this->_cpt_model_obj->display_ticket_selector(),
1883
+			'',
1884
+			'',
1885
+			false
1886
+		);
1887
+		$template_args['additional_registration_options'] = apply_filters(
1888
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1889
+			'',
1890
+			$template_args,
1891
+			$yes_no_values,
1892
+			$default_reg_status_values
1893
+		);
1894
+		EEH_Template::display_template(
1895
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1896
+			$template_args
1897
+		);
1898
+	}
1899
+
1900
+
1901
+	/**
1902
+	 * _get_events()
1903
+	 * This method simply returns all the events (for the given _view and paging)
1904
+	 *
1905
+	 * @access public
1906
+	 * @param int  $per_page     count of items per page (20 default);
1907
+	 * @param int  $current_page what is the current page being viewed.
1908
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1909
+	 *                           If FALSE then we return an array of event objects
1910
+	 *                           that match the given _view and paging parameters.
1911
+	 * @return array|int         an array of event objects or a count of them.
1912
+	 * @throws Exception
1913
+	 */
1914
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1915
+	{
1916
+		$EEM_Event   = $this->_event_model();
1917
+		$offset      = ($current_page - 1) * $per_page;
1918
+		$limit       = $count ? null : $offset . ',' . $per_page;
1919
+		$orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1920
+		$order       = $this->request->getRequestParam('order', 'DESC');
1921
+		$month_range = $this->request->getRequestParam('month_range');
1922
+		if ($month_range) {
1923
+			$pieces = explode(' ', $month_range, 3);
1924
+			// simulate the FIRST day of the month, that fixes issues for months like February
1925
+			// where PHP doesn't know what to assume for date.
1926
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1927
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1928
+			$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1929
+		}
1930
+		$where  = [];
1931
+		$status = $this->request->getRequestParam('status');
1932
+		// determine what post_status our condition will have for the query.
1933
+		switch ($status) {
1934
+			case 'month':
1935
+			case 'today':
1936
+			case null:
1937
+			case 'all':
1938
+				break;
1939
+			case 'draft':
1940
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1941
+				break;
1942
+			default:
1943
+				$where['status'] = $status;
1944
+		}
1945
+		// categories? The default for all categories is -1
1946
+		$category = $this->request->getRequestParam('EVT_CAT', -1, 'int');
1947
+		if ($category !== -1) {
1948
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1949
+			$where['Term_Taxonomy.term_id']  = $category;
1950
+		}
1951
+		// date where conditions
1952
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1953
+		if ($month_range) {
1954
+			$DateTime = new DateTime(
1955
+				$year_r . '-' . $month_r . '-01 00:00:00',
1956
+				new DateTimeZone('UTC')
1957
+			);
1958
+			$start    = $DateTime->getTimestamp();
1959
+			// set the datetime to be the end of the month
1960
+			$DateTime->setDate(
1961
+				$year_r,
1962
+				$month_r,
1963
+				$DateTime->format('t')
1964
+			)->setTime(23, 59, 59);
1965
+			$end                             = $DateTime->getTimestamp();
1966
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1967
+		} elseif ($status === 'today') {
1968
+			$DateTime                        =
1969
+				new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1970
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1971
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1972
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1973
+		} elseif ($status === 'month') {
1974
+			$now                             = date('Y-m-01');
1975
+			$DateTime                        =
1976
+				new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1977
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1978
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1979
+														->setTime(23, 59, 59)
1980
+														->format(implode(' ', $start_formats));
1981
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1982
+		}
1983
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1984
+			$where['EVT_wp_user'] = get_current_user_id();
1985
+		} else {
1986
+			if (! isset($where['status'])) {
1987
+				if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1988
+					$where['OR'] = [
1989
+						'status*restrict_private' => ['!=', 'private'],
1990
+						'AND'                     => [
1991
+							'status*inclusive' => ['=', 'private'],
1992
+							'EVT_wp_user'      => get_current_user_id(),
1993
+						],
1994
+					];
1995
+				}
1996
+			}
1997
+		}
1998
+		$wp_user = $this->request->getRequestParam('EVT_wp_user', 0, 'int');
1999
+		if (
2000
+			$wp_user
2001
+			&& $wp_user !== get_current_user_id()
2002
+			&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
2003
+		) {
2004
+			$where['EVT_wp_user'] = $wp_user;
2005
+		}
2006
+		// search query handling
2007
+		$search_term = $this->request->getRequestParam('s');
2008
+		if ($search_term) {
2009
+			$search_term = '%' . $search_term . '%';
2010
+			$where['OR'] = [
2011
+				'EVT_name'       => ['LIKE', $search_term],
2012
+				'EVT_desc'       => ['LIKE', $search_term],
2013
+				'EVT_short_desc' => ['LIKE', $search_term],
2014
+			];
2015
+		}
2016
+		// filter events by venue.
2017
+		$venue = $this->request->getRequestParam('venue', 0, 'int');
2018
+		if ($venue) {
2019
+			$where['Venue.VNU_ID'] = $venue;
2020
+		}
2021
+		$request_params = $this->request->requestParams();
2022
+		$where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2023
+		$query_params   = apply_filters(
2024
+			'FHEE__Events_Admin_Page__get_events__query_params',
2025
+			[
2026
+				$where,
2027
+				'limit'    => $limit,
2028
+				'order_by' => $orderby,
2029
+				'order'    => $order,
2030
+				'group_by' => 'EVT_ID',
2031
+			],
2032
+			$request_params
2033
+		);
2034
+
2035
+		// let's first check if we have special requests coming in.
2036
+		$active_status = $this->request->getRequestParam('active_status');
2037
+		if ($active_status) {
2038
+			switch ($active_status) {
2039
+				case 'upcoming':
2040
+					return $EEM_Event->get_upcoming_events($query_params, $count);
2041
+				case 'expired':
2042
+					return $EEM_Event->get_expired_events($query_params, $count);
2043
+				case 'active':
2044
+					return $EEM_Event->get_active_events($query_params, $count);
2045
+				case 'inactive':
2046
+					return $EEM_Event->get_inactive_events($query_params, $count);
2047
+			}
2048
+		}
2049
+
2050
+		return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2051
+	}
2052
+
2053
+
2054
+	/**
2055
+	 * handling for WordPress CPT actions (trash, restore, delete)
2056
+	 *
2057
+	 * @param string $post_id
2058
+	 * @throws EE_Error
2059
+	 * @throws ReflectionException
2060
+	 */
2061
+	public function trash_cpt_item($post_id)
2062
+	{
2063
+		$this->request->setRequestParam('EVT_ID', $post_id);
2064
+		$this->_trash_or_restore_event('trash', false);
2065
+	}
2066
+
2067
+
2068
+	/**
2069
+	 * @param string $post_id
2070
+	 * @throws EE_Error
2071
+	 * @throws ReflectionException
2072
+	 */
2073
+	public function restore_cpt_item($post_id)
2074
+	{
2075
+		$this->request->setRequestParam('EVT_ID', $post_id);
2076
+		$this->_trash_or_restore_event('draft', false);
2077
+	}
2078
+
2079
+
2080
+	/**
2081
+	 * @param string $post_id
2082
+	 * @throws EE_Error
2083
+	 * @throws EE_Error
2084
+	 */
2085
+	public function delete_cpt_item($post_id)
2086
+	{
2087
+		throw new EE_Error(
2088
+			esc_html__(
2089
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2090
+				'event_espresso'
2091
+			)
2092
+		);
2093
+		// $this->request->setRequestParam('EVT_ID', $post_id);
2094
+		// $this->_delete_event();
2095
+	}
2096
+
2097
+
2098
+	/**
2099
+	 * _trash_or_restore_event
2100
+	 *
2101
+	 * @access protected
2102
+	 * @param string $event_status
2103
+	 * @param bool   $redirect_after
2104
+	 * @throws EE_Error
2105
+	 * @throws EE_Error
2106
+	 * @throws ReflectionException
2107
+	 */
2108
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2109
+	{
2110
+		// determine the event id and set to array.
2111
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2112
+		// loop thru events
2113
+		if ($EVT_ID) {
2114
+			// clean status
2115
+			$event_status = sanitize_key($event_status);
2116
+			// grab status
2117
+			if (! empty($event_status)) {
2118
+				$success = $this->_change_event_status($EVT_ID, $event_status);
2119
+			} else {
2120
+				$success = false;
2121
+				$msg     = esc_html__(
2122
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2123
+					'event_espresso'
2124
+				);
2125
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2126
+			}
2127
+		} else {
2128
+			$success = false;
2129
+			$msg     = esc_html__(
2130
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2131
+				'event_espresso'
2132
+			);
2133
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2134
+		}
2135
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2136
+		if ($redirect_after) {
2137
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2138
+		}
2139
+	}
2140
+
2141
+
2142
+	/**
2143
+	 * _trash_or_restore_events
2144
+	 *
2145
+	 * @access protected
2146
+	 * @param string $event_status
2147
+	 * @return void
2148
+	 * @throws EE_Error
2149
+	 * @throws EE_Error
2150
+	 * @throws ReflectionException
2151
+	 */
2152
+	protected function _trash_or_restore_events($event_status = 'trash')
2153
+	{
2154
+		// clean status
2155
+		$event_status = sanitize_key($event_status);
2156
+		// grab status
2157
+		if (! empty($event_status)) {
2158
+			$success = true;
2159
+			// determine the event id and set to array.
2160
+			$EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2161
+			// loop thru events
2162
+			foreach ($EVT_IDs as $EVT_ID) {
2163
+				if ($EVT_ID = absint($EVT_ID)) {
2164
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2165
+					$success = $results !== false ? $success : false;
2166
+				} else {
2167
+					$msg = sprintf(
2168
+						esc_html__(
2169
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2170
+							'event_espresso'
2171
+						),
2172
+						$EVT_ID
2173
+					);
2174
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2175
+					$success = false;
2176
+				}
2177
+			}
2178
+		} else {
2179
+			$success = false;
2180
+			$msg     = esc_html__(
2181
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2182
+				'event_espresso'
2183
+			);
2184
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2185
+		}
2186
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2187
+		$success = $success ? 2 : false;
2188
+		$action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2189
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2190
+	}
2191
+
2192
+
2193
+	/**
2194
+	 * @param int    $EVT_ID
2195
+	 * @param string $event_status
2196
+	 * @return bool
2197
+	 * @throws EE_Error
2198
+	 * @throws ReflectionException
2199
+	 */
2200
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
2201
+	{
2202
+		// grab event id
2203
+		if (! $EVT_ID) {
2204
+			$msg = esc_html__(
2205
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2206
+				'event_espresso'
2207
+			);
2208
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2209
+			return false;
2210
+		}
2211
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2212
+		// clean status
2213
+		$event_status = sanitize_key($event_status);
2214
+		// grab status
2215
+		if (empty($event_status)) {
2216
+			$msg = esc_html__(
2217
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2218
+				'event_espresso'
2219
+			);
2220
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2221
+			return false;
2222
+		}
2223
+		// was event trashed or restored ?
2224
+		switch ($event_status) {
2225
+			case 'draft':
2226
+				$action = 'restored from the trash';
2227
+				$hook   = 'AHEE_event_restored_from_trash';
2228
+				break;
2229
+			case 'trash':
2230
+				$action = 'moved to the trash';
2231
+				$hook   = 'AHEE_event_moved_to_trash';
2232
+				break;
2233
+			default:
2234
+				$action = 'updated';
2235
+				$hook   = false;
2236
+		}
2237
+		// use class to change status
2238
+		$this->_cpt_model_obj->set_status($event_status);
2239
+		$success = $this->_cpt_model_obj->save();
2240
+		if (! $success) {
2241
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2242
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2243
+			return false;
2244
+		}
2245
+		if ($hook) {
2246
+			do_action($hook);
2247
+		}
2248
+		return true;
2249
+	}
2250
+
2251
+
2252
+	/**
2253
+	 * @param array $event_ids
2254
+	 * @return array
2255
+	 * @since   4.10.23.p
2256
+	 */
2257
+	private function cleanEventIds(array $event_ids)
2258
+	{
2259
+		return array_map('absint', $event_ids);
2260
+	}
2261
+
2262
+
2263
+	/**
2264
+	 * @return array
2265
+	 * @since   4.10.23.p
2266
+	 */
2267
+	private function getEventIdsFromRequest()
2268
+	{
2269
+		if ($this->request->requestParamIsSet('EVT_IDs')) {
2270
+			return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2271
+		} else {
2272
+			return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2273
+		}
2274
+	}
2275
+
2276
+
2277
+	/**
2278
+	 * @param bool $preview_delete
2279
+	 * @throws EE_Error
2280
+	 */
2281
+	protected function _delete_event($preview_delete = true)
2282
+	{
2283
+		$this->_delete_events($preview_delete);
2284
+	}
2285
+
2286
+
2287
+	/**
2288
+	 * Gets the tree traversal batch persister.
2289
+	 *
2290
+	 * @return NodeGroupDao
2291
+	 * @throws InvalidArgumentException
2292
+	 * @throws InvalidDataTypeException
2293
+	 * @throws InvalidInterfaceException
2294
+	 * @since 4.10.12.p
2295
+	 */
2296
+	protected function getModelObjNodeGroupPersister()
2297
+	{
2298
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2299
+			$this->model_obj_node_group_persister =
2300
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2301
+		}
2302
+		return $this->model_obj_node_group_persister;
2303
+	}
2304
+
2305
+
2306
+	/**
2307
+	 * @param bool $preview_delete
2308
+	 * @return void
2309
+	 * @throws EE_Error
2310
+	 */
2311
+	protected function _delete_events($preview_delete = true)
2312
+	{
2313
+		$event_ids = $this->getEventIdsFromRequest();
2314
+		if ($preview_delete) {
2315
+			$this->generateDeletionPreview($event_ids);
2316
+		} else {
2317
+			EEM_Event::instance()->delete_permanently([['EVT_ID' => ['IN', $event_ids]]]);
2318
+		}
2319
+	}
2320
+
2321
+
2322
+	/**
2323
+	 * @param array $event_ids
2324
+	 */
2325
+	protected function generateDeletionPreview(array $event_ids)
2326
+	{
2327
+		$event_ids = $this->cleanEventIds($event_ids);
2328
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2329
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2330
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2331
+			[
2332
+				'action'            => 'preview_deletion',
2333
+				'deletion_job_code' => $deletion_job_code,
2334
+			],
2335
+			$this->_admin_base_url
2336
+		);
2337
+		EEH_URL::safeRedirectAndExit(
2338
+			EE_Admin_Page::add_query_args_and_nonce(
2339
+				[
2340
+					'page'              => 'espresso_batch',
2341
+					'batch'             => EED_Batch::batch_job,
2342
+					'EVT_IDs'           => $event_ids,
2343
+					'deletion_job_code' => $deletion_job_code,
2344
+					'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2345
+					'return_url'        => urlencode($return_url),
2346
+				],
2347
+				admin_url()
2348
+			)
2349
+		);
2350
+	}
2351
+
2352
+
2353
+	/**
2354
+	 * Checks for a POST submission
2355
+	 *
2356
+	 * @since 4.10.12.p
2357
+	 */
2358
+	protected function confirmDeletion()
2359
+	{
2360
+		$deletion_redirect_logic =
2361
+			$this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion');
2362
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2363
+	}
2364
+
2365
+
2366
+	/**
2367
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2368
+	 *
2369
+	 * @throws EE_Error
2370
+	 * @since 4.10.12.p
2371
+	 */
2372
+	protected function previewDeletion()
2373
+	{
2374
+		$preview_deletion_logic =
2375
+			$this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\PreviewDeletion');
2376
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2377
+		$this->display_admin_page_with_no_sidebar();
2378
+	}
2379
+
2380
+
2381
+	/**
2382
+	 * get total number of events
2383
+	 *
2384
+	 * @access public
2385
+	 * @return int
2386
+	 * @throws EE_Error
2387
+	 * @throws EE_Error
2388
+	 */
2389
+	public function total_events()
2390
+	{
2391
+		return EEM_Event::instance()->count(
2392
+			['caps' => 'read_admin'],
2393
+			'EVT_ID',
2394
+			true
2395
+		);
2396
+	}
2397
+
2398
+
2399
+	/**
2400
+	 * get total number of draft events
2401
+	 *
2402
+	 * @access public
2403
+	 * @return int
2404
+	 * @throws EE_Error
2405
+	 * @throws EE_Error
2406
+	 */
2407
+	public function total_events_draft()
2408
+	{
2409
+		return EEM_Event::instance()->count(
2410
+			[
2411
+				['status' => ['IN', ['draft', 'auto-draft']]],
2412
+				'caps' => 'read_admin',
2413
+			],
2414
+			'EVT_ID',
2415
+			true
2416
+		);
2417
+	}
2418
+
2419
+
2420
+	/**
2421
+	 * get total number of trashed events
2422
+	 *
2423
+	 * @access public
2424
+	 * @return int
2425
+	 * @throws EE_Error
2426
+	 * @throws EE_Error
2427
+	 */
2428
+	public function total_trashed_events()
2429
+	{
2430
+		return EEM_Event::instance()->count(
2431
+			[
2432
+				['status' => 'trash'],
2433
+				'caps' => 'read_admin',
2434
+			],
2435
+			'EVT_ID',
2436
+			true
2437
+		);
2438
+	}
2439
+
2440
+
2441
+	/**
2442
+	 *    _default_event_settings
2443
+	 *    This generates the Default Settings Tab
2444
+	 *
2445
+	 * @return void
2446
+	 * @throws DomainException
2447
+	 * @throws EE_Error
2448
+	 * @throws InvalidArgumentException
2449
+	 * @throws InvalidDataTypeException
2450
+	 * @throws InvalidInterfaceException
2451
+	 */
2452
+	protected function _default_event_settings()
2453
+	{
2454
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2455
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2456
+		$this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2457
+		$this->display_admin_page_with_sidebar();
2458
+	}
2459
+
2460
+
2461
+	/**
2462
+	 * Return the form for event settings.
2463
+	 *
2464
+	 * @return EE_Form_Section_Proper
2465
+	 * @throws EE_Error
2466
+	 */
2467
+	protected function _default_event_settings_form()
2468
+	{
2469
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2470
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2471
+		// exclude
2472
+			[
2473
+				EEM_Registration::status_id_cancelled,
2474
+				EEM_Registration::status_id_declined,
2475
+				EEM_Registration::status_id_incomplete,
2476
+				EEM_Registration::status_id_wait_list,
2477
+			],
2478
+			true
2479
+		);
2480
+		return new EE_Form_Section_Proper(
2481
+			[
2482
+				'name'            => 'update_default_event_settings',
2483
+				'html_id'         => 'update_default_event_settings',
2484
+				'html_class'      => 'form-table',
2485
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2486
+				'subsections'     => apply_filters(
2487
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2488
+					[
2489
+						'default_reg_status'  => new EE_Select_Input(
2490
+							$registration_stati_for_selection,
2491
+							[
2492
+								'default'         => isset($registration_config->default_STS_ID)
2493
+													 && array_key_exists(
2494
+														 $registration_config->default_STS_ID,
2495
+														 $registration_stati_for_selection
2496
+													 )
2497
+									? sanitize_text_field($registration_config->default_STS_ID)
2498
+									: EEM_Registration::status_id_pending_payment,
2499
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2500
+													 . EEH_Template::get_help_tab_link(
2501
+														 'default_settings_status_help_tab'
2502
+													 ),
2503
+								'html_help_text'  => esc_html__(
2504
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2505
+									'event_espresso'
2506
+								),
2507
+							]
2508
+						),
2509
+						'default_max_tickets' => new EE_Integer_Input(
2510
+							[
2511
+								'default'         => isset($registration_config->default_maximum_number_of_tickets)
2512
+									? $registration_config->default_maximum_number_of_tickets
2513
+									: EEM_Event::get_default_additional_limit(),
2514
+								'html_label_text' => esc_html__(
2515
+									'Default Maximum Tickets Allowed Per Order:',
2516
+									'event_espresso'
2517
+								)
2518
+													 . EEH_Template::get_help_tab_link(
2519
+														 'default_maximum_tickets_help_tab"'
2520
+													 ),
2521
+								'html_help_text'  => esc_html__(
2522
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2523
+									'event_espresso'
2524
+								),
2525
+							]
2526
+						),
2527
+					]
2528
+				),
2529
+			]
2530
+		);
2531
+	}
2532
+
2533
+
2534
+	/**
2535
+	 * @return void
2536
+	 * @throws EE_Error
2537
+	 * @throws InvalidArgumentException
2538
+	 * @throws InvalidDataTypeException
2539
+	 * @throws InvalidInterfaceException
2540
+	 */
2541
+	protected function _update_default_event_settings()
2542
+	{
2543
+		$form = $this->_default_event_settings_form();
2544
+		if ($form->was_submitted()) {
2545
+			$form->receive_form_submission();
2546
+			if ($form->is_valid()) {
2547
+				$registration_config = EE_Registry::instance()->CFG->registration;
2548
+				$valid_data          = $form->valid_data();
2549
+				if (isset($valid_data['default_reg_status'])) {
2550
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2551
+				}
2552
+				if (isset($valid_data['default_max_tickets'])) {
2553
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2554
+				}
2555
+				do_action(
2556
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2557
+					$valid_data,
2558
+					EE_Registry::instance()->CFG,
2559
+					$this
2560
+				);
2561
+				// update because data was valid!
2562
+				EE_Registry::instance()->CFG->update_espresso_config();
2563
+				EE_Error::overwrite_success();
2564
+				EE_Error::add_success(
2565
+					esc_html__('Default Event Settings were updated', 'event_espresso')
2566
+				);
2567
+			}
2568
+		}
2569
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2570
+	}
2571
+
2572
+
2573
+	/*************        Templates        *************
21 2574
      *
22
-     * @var EE_Event $_event
23
-     */
24
-    protected $_event;
25
-
26
-
27
-    /**
28
-     * This will hold the category object for category_details screen.
29
-     *
30
-     * @var stdClass $_category
31
-     */
32
-    protected $_category;
33
-
34
-
35
-    /**
36
-     * This will hold the event model instance
37
-     *
38
-     * @var EEM_Event $_event_model
39
-     */
40
-    protected $_event_model;
41
-
42
-
43
-    /**
44
-     * @var EE_Event
45
-     */
46
-    protected $_cpt_model_obj = false;
47
-
48
-
49
-    /**
50
-     * @var NodeGroupDao
51
-     */
52
-    protected $model_obj_node_group_persister;
53
-
54
-
55
-    /**
56
-     * Initialize page props for this admin page group.
57
-     */
58
-    protected function _init_page_props()
59
-    {
60
-        $this->page_slug        = EVENTS_PG_SLUG;
61
-        $this->page_label       = EVENTS_LABEL;
62
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
63
-        $this->_admin_base_path = EVENTS_ADMIN;
64
-        $this->_cpt_model_names = [
65
-            'create_new' => 'EEM_Event',
66
-            'edit'       => 'EEM_Event',
67
-        ];
68
-        $this->_cpt_edit_routes = [
69
-            'espresso_events' => 'edit',
70
-        ];
71
-        add_action(
72
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
73
-            [$this, 'verify_event_edit'],
74
-            10,
75
-            2
76
-        );
77
-    }
78
-
79
-
80
-    /**
81
-     * Sets the ajax hooks used for this admin page group.
82
-     */
83
-    protected function _ajax_hooks()
84
-    {
85
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
86
-    }
87
-
88
-
89
-    /**
90
-     * Sets the page properties for this admin page group.
91
-     */
92
-    protected function _define_page_props()
93
-    {
94
-        $this->_admin_page_title = EVENTS_LABEL;
95
-        $this->_labels           = [
96
-            'buttons'      => [
97
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
98
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
99
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
100
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
101
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
102
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
103
-            ],
104
-            'editor_title' => [
105
-                'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
106
-            ],
107
-            'publishbox'   => [
108
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
109
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
110
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
111
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
112
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
113
-            ],
114
-        ];
115
-    }
116
-
117
-
118
-    /**
119
-     * Sets the page routes property for this admin page group.
120
-     */
121
-    protected function _set_page_routes()
122
-    {
123
-        // load formatter helper
124
-        // load field generator helper
125
-        // is there a evt_id in the request?
126
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
127
-        $EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
128
-
129
-        $this->_page_routes = [
130
-            'default'                       => [
131
-                'func'       => '_events_overview_list_table',
132
-                'capability' => 'ee_read_events',
133
-            ],
134
-            'create_new'                    => [
135
-                'func'       => '_create_new_cpt_item',
136
-                'capability' => 'ee_edit_events',
137
-            ],
138
-            'edit'                          => [
139
-                'func'       => '_edit_cpt_item',
140
-                'capability' => 'ee_edit_event',
141
-                'obj_id'     => $EVT_ID,
142
-            ],
143
-            'copy_event'                    => [
144
-                'func'       => '_copy_events',
145
-                'capability' => 'ee_edit_event',
146
-                'obj_id'     => $EVT_ID,
147
-                'noheader'   => true,
148
-            ],
149
-            'trash_event'                   => [
150
-                'func'       => '_trash_or_restore_event',
151
-                'args'       => ['event_status' => 'trash'],
152
-                'capability' => 'ee_delete_event',
153
-                'obj_id'     => $EVT_ID,
154
-                'noheader'   => true,
155
-            ],
156
-            'trash_events'                  => [
157
-                'func'       => '_trash_or_restore_events',
158
-                'args'       => ['event_status' => 'trash'],
159
-                'capability' => 'ee_delete_events',
160
-                'noheader'   => true,
161
-            ],
162
-            'restore_event'                 => [
163
-                'func'       => '_trash_or_restore_event',
164
-                'args'       => ['event_status' => 'draft'],
165
-                'capability' => 'ee_delete_event',
166
-                'obj_id'     => $EVT_ID,
167
-                'noheader'   => true,
168
-            ],
169
-            'restore_events'                => [
170
-                'func'       => '_trash_or_restore_events',
171
-                'args'       => ['event_status' => 'draft'],
172
-                'capability' => 'ee_delete_events',
173
-                'noheader'   => true,
174
-            ],
175
-            'delete_event'                  => [
176
-                'func'       => '_delete_event',
177
-                'capability' => 'ee_delete_event',
178
-                'obj_id'     => $EVT_ID,
179
-                'noheader'   => true,
180
-            ],
181
-            'delete_events'                 => [
182
-                'func'       => '_delete_events',
183
-                'capability' => 'ee_delete_events',
184
-                'noheader'   => true,
185
-            ],
186
-            'view_report'                   => [
187
-                'func'       => '_view_report',
188
-                'capability' => 'ee_edit_events',
189
-            ],
190
-            'default_event_settings'        => [
191
-                'func'       => '_default_event_settings',
192
-                'capability' => 'manage_options',
193
-            ],
194
-            'update_default_event_settings' => [
195
-                'func'       => '_update_default_event_settings',
196
-                'capability' => 'manage_options',
197
-                'noheader'   => true,
198
-            ],
199
-            'template_settings'             => [
200
-                'func'       => '_template_settings',
201
-                'capability' => 'manage_options',
202
-            ],
203
-            // event category tab related
204
-            'add_category'                  => [
205
-                'func'       => '_category_details',
206
-                'capability' => 'ee_edit_event_category',
207
-                'args'       => ['add'],
208
-            ],
209
-            'edit_category'                 => [
210
-                'func'       => '_category_details',
211
-                'capability' => 'ee_edit_event_category',
212
-                'args'       => ['edit'],
213
-            ],
214
-            'delete_categories'             => [
215
-                'func'       => '_delete_categories',
216
-                'capability' => 'ee_delete_event_category',
217
-                'noheader'   => true,
218
-            ],
219
-            'delete_category'               => [
220
-                'func'       => '_delete_categories',
221
-                'capability' => 'ee_delete_event_category',
222
-                'noheader'   => true,
223
-            ],
224
-            'insert_category'               => [
225
-                'func'       => '_insert_or_update_category',
226
-                'args'       => ['new_category' => true],
227
-                'capability' => 'ee_edit_event_category',
228
-                'noheader'   => true,
229
-            ],
230
-            'update_category'               => [
231
-                'func'       => '_insert_or_update_category',
232
-                'args'       => ['new_category' => false],
233
-                'capability' => 'ee_edit_event_category',
234
-                'noheader'   => true,
235
-            ],
236
-            'category_list'                 => [
237
-                'func'       => '_category_list_table',
238
-                'capability' => 'ee_manage_event_categories',
239
-            ],
240
-            'preview_deletion'              => [
241
-                'func'       => 'previewDeletion',
242
-                'capability' => 'ee_delete_events',
243
-            ],
244
-            'confirm_deletion'              => [
245
-                'func'       => 'confirmDeletion',
246
-                'capability' => 'ee_delete_events',
247
-                'noheader'   => true,
248
-            ],
249
-        ];
250
-    }
251
-
252
-
253
-    /**
254
-     * Set the _page_config property for this admin page group.
255
-     */
256
-    protected function _set_page_config()
257
-    {
258
-        $post_id            = $this->request->getRequestParam('post', 0, 'int');
259
-        $EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
260
-        $this->_page_config = [
261
-            'default'                => [
262
-                'nav'           => [
263
-                    'label' => esc_html__('Overview', 'event_espresso'),
264
-                    'order' => 10,
265
-                ],
266
-                'list_table'    => 'Events_Admin_List_Table',
267
-                'help_tabs'     => [
268
-                    'events_overview_help_tab'                       => [
269
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
270
-                        'filename' => 'events_overview',
271
-                    ],
272
-                    'events_overview_table_column_headings_help_tab' => [
273
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
274
-                        'filename' => 'events_overview_table_column_headings',
275
-                    ],
276
-                    'events_overview_filters_help_tab'               => [
277
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
278
-                        'filename' => 'events_overview_filters',
279
-                    ],
280
-                    'events_overview_view_help_tab'                  => [
281
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
282
-                        'filename' => 'events_overview_views',
283
-                    ],
284
-                    'events_overview_other_help_tab'                 => [
285
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
286
-                        'filename' => 'events_overview_other',
287
-                    ],
288
-                ],
289
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
290
-                // 'help_tour'     => [
291
-                //     'Event_Overview_Help_Tour',
292
-                //     // 'New_Features_Test_Help_Tour' for testing multiple help tour
293
-                // ],
294
-                'qtips'         => ['EE_Event_List_Table_Tips'],
295
-                'require_nonce' => false,
296
-            ],
297
-            'create_new'             => [
298
-                'nav'           => [
299
-                    'label'      => esc_html__('Add Event', 'event_espresso'),
300
-                    'order'      => 5,
301
-                    'persistent' => false,
302
-                ],
303
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
304
-                'help_tabs'     => [
305
-                    'event_editor_help_tab'                            => [
306
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
307
-                        'filename' => 'event_editor',
308
-                    ],
309
-                    'event_editor_title_richtexteditor_help_tab'       => [
310
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
311
-                        'filename' => 'event_editor_title_richtexteditor',
312
-                    ],
313
-                    'event_editor_venue_details_help_tab'              => [
314
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
315
-                        'filename' => 'event_editor_venue_details',
316
-                    ],
317
-                    'event_editor_event_datetimes_help_tab'            => [
318
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
319
-                        'filename' => 'event_editor_event_datetimes',
320
-                    ],
321
-                    'event_editor_event_tickets_help_tab'              => [
322
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
323
-                        'filename' => 'event_editor_event_tickets',
324
-                    ],
325
-                    'event_editor_event_registration_options_help_tab' => [
326
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
327
-                        'filename' => 'event_editor_event_registration_options',
328
-                    ],
329
-                    'event_editor_tags_categories_help_tab'            => [
330
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
331
-                        'filename' => 'event_editor_tags_categories',
332
-                    ],
333
-                    'event_editor_questions_registrants_help_tab'      => [
334
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
335
-                        'filename' => 'event_editor_questions_registrants',
336
-                    ],
337
-                    'event_editor_save_new_event_help_tab'             => [
338
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
339
-                        'filename' => 'event_editor_save_new_event',
340
-                    ],
341
-                    'event_editor_other_help_tab'                      => [
342
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
343
-                        'filename' => 'event_editor_other',
344
-                    ],
345
-                ],
346
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
347
-                // 'help_tour'     => [
348
-                //     'Event_Editor_Help_Tour',
349
-                // ],
350
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
351
-                'require_nonce' => false,
352
-            ],
353
-            'edit'                   => [
354
-                'nav'           => [
355
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
356
-                    'order'      => 5,
357
-                    'persistent' => false,
358
-                    'url'        => $post_id
359
-                        ? EE_Admin_Page::add_query_args_and_nonce(
360
-                            ['post' => $post_id, 'action' => 'edit'],
361
-                            $this->_current_page_view_url
362
-                        )
363
-                        : $this->_admin_base_url,
364
-                ],
365
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
366
-                'help_tabs'     => [
367
-                    'event_editor_help_tab'                            => [
368
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
369
-                        'filename' => 'event_editor',
370
-                    ],
371
-                    'event_editor_title_richtexteditor_help_tab'       => [
372
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
373
-                        'filename' => 'event_editor_title_richtexteditor',
374
-                    ],
375
-                    'event_editor_venue_details_help_tab'              => [
376
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
377
-                        'filename' => 'event_editor_venue_details',
378
-                    ],
379
-                    'event_editor_event_datetimes_help_tab'            => [
380
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
381
-                        'filename' => 'event_editor_event_datetimes',
382
-                    ],
383
-                    'event_editor_event_tickets_help_tab'              => [
384
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
385
-                        'filename' => 'event_editor_event_tickets',
386
-                    ],
387
-                    'event_editor_event_registration_options_help_tab' => [
388
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
389
-                        'filename' => 'event_editor_event_registration_options',
390
-                    ],
391
-                    'event_editor_tags_categories_help_tab'            => [
392
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
393
-                        'filename' => 'event_editor_tags_categories',
394
-                    ],
395
-                    'event_editor_questions_registrants_help_tab'      => [
396
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
397
-                        'filename' => 'event_editor_questions_registrants',
398
-                    ],
399
-                    'event_editor_save_new_event_help_tab'             => [
400
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
401
-                        'filename' => 'event_editor_save_new_event',
402
-                    ],
403
-                    'event_editor_other_help_tab'                      => [
404
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
405
-                        'filename' => 'event_editor_other',
406
-                    ],
407
-                ],
408
-                'require_nonce' => false,
409
-            ],
410
-            'default_event_settings' => [
411
-                'nav'           => [
412
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
413
-                    'order' => 40,
414
-                ],
415
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
416
-                'labels'        => [
417
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
418
-                ],
419
-                'help_tabs'     => [
420
-                    'default_settings_help_tab'        => [
421
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
422
-                        'filename' => 'events_default_settings',
423
-                    ],
424
-                    'default_settings_status_help_tab' => [
425
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
426
-                        'filename' => 'events_default_settings_status',
427
-                    ],
428
-                    'default_maximum_tickets_help_tab' => [
429
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
430
-                        'filename' => 'events_default_settings_max_tickets',
431
-                    ],
432
-                ],
433
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
434
-                // 'help_tour'     => ['Event_Default_Settings_Help_Tour'],
435
-                'require_nonce' => false,
436
-            ],
437
-            // template settings
438
-            'template_settings'      => [
439
-                'nav'           => [
440
-                    'label' => esc_html__('Templates', 'event_espresso'),
441
-                    'order' => 30,
442
-                ],
443
-                'metaboxes'     => $this->_default_espresso_metaboxes,
444
-                'help_tabs'     => [
445
-                    'general_settings_templates_help_tab' => [
446
-                        'title'    => esc_html__('Templates', 'event_espresso'),
447
-                        'filename' => 'general_settings_templates',
448
-                    ],
449
-                ],
450
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
451
-                // 'help_tour'     => ['Templates_Help_Tour'],
452
-                'require_nonce' => false,
453
-            ],
454
-            // event category stuff
455
-            'add_category'           => [
456
-                'nav'           => [
457
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
458
-                    'order'      => 15,
459
-                    'persistent' => false,
460
-                ],
461
-                'help_tabs'     => [
462
-                    'add_category_help_tab' => [
463
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
464
-                        'filename' => 'events_add_category',
465
-                    ],
466
-                ],
467
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
468
-                // 'help_tour'     => ['Event_Add_Category_Help_Tour'],
469
-                'metaboxes'     => ['_publish_post_box'],
470
-                'require_nonce' => false,
471
-            ],
472
-            'edit_category'          => [
473
-                'nav'           => [
474
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
475
-                    'order'      => 15,
476
-                    'persistent' => false,
477
-                    'url'        => $EVT_CAT_ID
478
-                        ? add_query_arg(
479
-                            ['EVT_CAT_ID' => $EVT_CAT_ID],
480
-                            $this->_current_page_view_url
481
-                        )
482
-                        : $this->_admin_base_url,
483
-                ],
484
-                'help_tabs'     => [
485
-                    'edit_category_help_tab' => [
486
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
487
-                        'filename' => 'events_edit_category',
488
-                    ],
489
-                ],
490
-                /*'help_tour' => ['Event_Edit_Category_Help_Tour'],*/
491
-                'metaboxes'     => ['_publish_post_box'],
492
-                'require_nonce' => false,
493
-            ],
494
-            'category_list'          => [
495
-                'nav'           => [
496
-                    'label' => esc_html__('Categories', 'event_espresso'),
497
-                    'order' => 20,
498
-                ],
499
-                'list_table'    => 'Event_Categories_Admin_List_Table',
500
-                'help_tabs'     => [
501
-                    'events_categories_help_tab'                       => [
502
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
503
-                        'filename' => 'events_categories',
504
-                    ],
505
-                    'events_categories_table_column_headings_help_tab' => [
506
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
507
-                        'filename' => 'events_categories_table_column_headings',
508
-                    ],
509
-                    'events_categories_view_help_tab'                  => [
510
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
511
-                        'filename' => 'events_categories_views',
512
-                    ],
513
-                    'events_categories_other_help_tab'                 => [
514
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
515
-                        'filename' => 'events_categories_other',
516
-                    ],
517
-                ],
518
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
519
-                // 'help_tour'     => [
520
-                //     'Event_Categories_Help_Tour',
521
-                // ],
522
-                'metaboxes'     => $this->_default_espresso_metaboxes,
523
-                'require_nonce' => false,
524
-            ],
525
-            'preview_deletion'       => [
526
-                'nav'           => [
527
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
528
-                    'order'      => 15,
529
-                    'persistent' => false,
530
-                    'url'        => '',
531
-                ],
532
-                'require_nonce' => false,
533
-            ],
534
-        ];
535
-    }
536
-
537
-
538
-    /**
539
-     * Used to register any global screen options if necessary for every route in this admin page group.
540
-     */
541
-    protected function _add_screen_options()
542
-    {
543
-    }
544
-
545
-
546
-    /**
547
-     * Implementing the screen options for the 'default' route.
548
-     *
549
-     * @throws InvalidArgumentException
550
-     * @throws InvalidDataTypeException
551
-     * @throws InvalidInterfaceException
552
-     */
553
-    protected function _add_screen_options_default()
554
-    {
555
-        $this->_per_page_screen_option();
556
-    }
557
-
558
-
559
-    /**
560
-     * Implementing screen options for the category list route.
561
-     *
562
-     * @throws InvalidArgumentException
563
-     * @throws InvalidDataTypeException
564
-     * @throws InvalidInterfaceException
565
-     */
566
-    protected function _add_screen_options_category_list()
567
-    {
568
-        $page_title              = $this->_admin_page_title;
569
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
570
-        $this->_per_page_screen_option();
571
-        $this->_admin_page_title = $page_title;
572
-    }
573
-
574
-
575
-    /**
576
-     * Used to register any global feature pointers for the admin page group.
577
-     */
578
-    protected function _add_feature_pointers()
579
-    {
580
-    }
581
-
582
-
583
-    /**
584
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
585
-     */
586
-    public function load_scripts_styles()
587
-    {
588
-        wp_register_style(
589
-            'events-admin-css',
590
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
591
-            [],
592
-            EVENT_ESPRESSO_VERSION
593
-        );
594
-        wp_register_style(
595
-            'ee-cat-admin',
596
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
597
-            [],
598
-            EVENT_ESPRESSO_VERSION
599
-        );
600
-        wp_enqueue_style('events-admin-css');
601
-        wp_enqueue_style('ee-cat-admin');
602
-        // scripts
603
-        wp_register_script(
604
-            'event_editor_js',
605
-            EVENTS_ASSETS_URL . 'event_editor.js',
606
-            ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
607
-            EVENT_ESPRESSO_VERSION,
608
-            true
609
-        );
610
-    }
611
-
612
-
613
-    /**
614
-     * Enqueuing scripts and styles specific to this view
615
-     */
616
-    public function load_scripts_styles_create_new()
617
-    {
618
-        $this->load_scripts_styles_edit();
619
-    }
620
-
621
-
622
-    /**
623
-     * Enqueuing scripts and styles specific to this view
624
-     */
625
-    public function load_scripts_styles_edit()
626
-    {
627
-        // styles
628
-        wp_enqueue_style('espresso-ui-theme');
629
-        wp_register_style(
630
-            'event-editor-css',
631
-            EVENTS_ASSETS_URL . 'event-editor.css',
632
-            ['ee-admin-css'],
633
-            EVENT_ESPRESSO_VERSION
634
-        );
635
-        wp_enqueue_style('event-editor-css');
636
-        // scripts
637
-        if (! $this->admin_config->useAdvancedEditor()) {
638
-            wp_register_script(
639
-                'event-datetime-metabox',
640
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
641
-                ['event_editor_js', 'ee-datepicker'],
642
-                EVENT_ESPRESSO_VERSION
643
-            );
644
-            wp_enqueue_script('event-datetime-metabox');
645
-        }
646
-    }
647
-
648
-
649
-    /**
650
-     * Populating the _views property for the category list table view.
651
-     */
652
-    protected function _set_list_table_views_category_list()
653
-    {
654
-        $this->_views = [
655
-            'all' => [
656
-                'slug'        => 'all',
657
-                'label'       => esc_html__('All', 'event_espresso'),
658
-                'count'       => 0,
659
-                'bulk_action' => [
660
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
661
-                ],
662
-            ],
663
-        ];
664
-    }
665
-
666
-
667
-    /**
668
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
669
-     */
670
-    public function admin_init()
671
-    {
672
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
673
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
674
-            'event_espresso'
675
-        );
676
-    }
677
-
678
-
679
-    /**
680
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
681
-     * group.
682
-     */
683
-    public function admin_notices()
684
-    {
685
-    }
686
-
687
-
688
-    /**
689
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
690
-     * this admin page group.
691
-     */
692
-    public function admin_footer_scripts()
693
-    {
694
-    }
695
-
696
-
697
-    /**
698
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
699
-     * warning (via EE_Error::add_error());
700
-     *
701
-     * @param EE_Event $event Event object
702
-     * @param string   $req_type
703
-     * @return void
704
-     * @throws EE_Error
705
-     * @throws ReflectionException
706
-     */
707
-    public function verify_event_edit($event = null, $req_type = '')
708
-    {
709
-        // don't need to do this when processing
710
-        if (! empty($req_type)) {
711
-            return;
712
-        }
713
-        // no event?
714
-        if (! $event instanceof EE_Event) {
715
-            $event = $this->_cpt_model_obj;
716
-        }
717
-        // STILL no event?
718
-        if (! $event instanceof EE_Event) {
719
-            return;
720
-        }
721
-        $orig_status = $event->status();
722
-        // first check if event is active.
723
-        if (
724
-            $orig_status === EEM_Event::cancelled
725
-            || $orig_status === EEM_Event::postponed
726
-            || $event->is_expired()
727
-            || $event->is_inactive()
728
-        ) {
729
-            return;
730
-        }
731
-        // made it here so it IS active... next check that any of the tickets are sold.
732
-        if ($event->is_sold_out(true)) {
733
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
734
-                EE_Error::add_attention(
735
-                    sprintf(
736
-                        esc_html__(
737
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
738
-                            'event_espresso'
739
-                        ),
740
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
741
-                    )
742
-                );
743
-            }
744
-            return;
745
-        }
746
-        if ($orig_status === EEM_Event::sold_out) {
747
-            EE_Error::add_attention(
748
-                sprintf(
749
-                    esc_html__(
750
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
751
-                        'event_espresso'
752
-                    ),
753
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
754
-                )
755
-            );
756
-        }
757
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
758
-        if (! $event->tickets_on_sale()) {
759
-            return;
760
-        }
761
-        // made it here so show warning
762
-        $this->_edit_event_warning();
763
-    }
764
-
765
-
766
-    /**
767
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
768
-     * When needed, hook this into a EE_Error::add_error() notice.
769
-     *
770
-     * @access protected
771
-     * @return void
772
-     */
773
-    protected function _edit_event_warning()
774
-    {
775
-        // we don't want to add warnings during these requests
776
-        if ($this->request->getRequestParam('action') === 'editpost') {
777
-            return;
778
-        }
779
-        EE_Error::add_attention(
780
-            sprintf(
781
-                esc_html__(
782
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
783
-                    'event_espresso'
784
-                ),
785
-                '<a class="espresso-help-tab-lnk">',
786
-                '</a>'
787
-            )
788
-        );
789
-    }
790
-
791
-
792
-    /**
793
-     * When a user is creating a new event, notify them if they haven't set their timezone.
794
-     * Otherwise, do the normal logic
795
-     *
796
-     * @return void
797
-     * @throws EE_Error
798
-     * @throws InvalidArgumentException
799
-     * @throws InvalidDataTypeException
800
-     * @throws InvalidInterfaceException
801
-     */
802
-    protected function _create_new_cpt_item()
803
-    {
804
-        $has_timezone_string = get_option('timezone_string');
805
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
806
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
807
-            EE_Error::add_attention(
808
-                sprintf(
809
-                    esc_html__(
810
-                        'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
811
-                        'event_espresso'
812
-                    ),
813
-                    '<br>',
814
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
815
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
816
-                    . '</select>',
817
-                    '<button class="button button--secondary timezone-submit">',
818
-                    '</button><span class="spinner"></span>'
819
-                ),
820
-                __FILE__,
821
-                __FUNCTION__,
822
-                __LINE__
823
-            );
824
-        }
825
-        parent::_create_new_cpt_item();
826
-    }
827
-
828
-
829
-    /**
830
-     * Sets the _views property for the default route in this admin page group.
831
-     */
832
-    protected function _set_list_table_views_default()
833
-    {
834
-        $this->_views = [
835
-            'all'   => [
836
-                'slug'        => 'all',
837
-                'label'       => esc_html__('View All Events', 'event_espresso'),
838
-                'count'       => 0,
839
-                'bulk_action' => [
840
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
841
-                ],
842
-            ],
843
-            'draft' => [
844
-                'slug'        => 'draft',
845
-                'label'       => esc_html__('Draft', 'event_espresso'),
846
-                'count'       => 0,
847
-                'bulk_action' => [
848
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
849
-                ],
850
-            ],
851
-        ];
852
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
853
-            $this->_views['trash'] = [
854
-                'slug'        => 'trash',
855
-                'label'       => esc_html__('Trash', 'event_espresso'),
856
-                'count'       => 0,
857
-                'bulk_action' => [
858
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
859
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
860
-                ],
861
-            ];
862
-        }
863
-    }
864
-
865
-
866
-    /**
867
-     * Provides the legend item array for the default list table view.
868
-     *
869
-     * @return array
870
-     * @throws EE_Error
871
-     * @throws EE_Error
872
-     */
873
-    protected function _event_legend_items()
874
-    {
875
-        $items    = [
876
-            'view_details'   => [
877
-                'class' => 'dashicons dashicons-search',
878
-                'desc'  => esc_html__('View Event', 'event_espresso'),
879
-            ],
880
-            'edit_event'     => [
881
-                'class' => 'ee-icon ee-icon-calendar-edit',
882
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
883
-            ],
884
-            'view_attendees' => [
885
-                'class' => 'dashicons dashicons-groups',
886
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
887
-            ],
888
-        ];
889
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
890
-        $statuses = [
891
-            'sold_out_status'  => [
892
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::sold_out,
893
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
894
-            ],
895
-            'active_status'    => [
896
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::active,
897
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
898
-            ],
899
-            'upcoming_status'  => [
900
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::upcoming,
901
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
902
-            ],
903
-            'postponed_status' => [
904
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::postponed,
905
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
906
-            ],
907
-            'cancelled_status' => [
908
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::cancelled,
909
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
910
-            ],
911
-            'expired_status'   => [
912
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::expired,
913
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
914
-            ],
915
-            'inactive_status'  => [
916
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::inactive,
917
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
918
-            ],
919
-        ];
920
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
921
-        return array_merge($items, $statuses);
922
-    }
923
-
924
-
925
-    /**
926
-     * @return EEM_Event
927
-     * @throws EE_Error
928
-     * @throws InvalidArgumentException
929
-     * @throws InvalidDataTypeException
930
-     * @throws InvalidInterfaceException
931
-     * @throws ReflectionException
932
-     */
933
-    private function _event_model()
934
-    {
935
-        if (! $this->_event_model instanceof EEM_Event) {
936
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
937
-        }
938
-        return $this->_event_model;
939
-    }
940
-
941
-
942
-    /**
943
-     * Adds extra buttons to the WP CPT permalink field row.
944
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
945
-     *
946
-     * @param string $return    the current html
947
-     * @param int    $id        the post id for the page
948
-     * @param string $new_title What the title is
949
-     * @param string $new_slug  what the slug is
950
-     * @return string            The new html string for the permalink area
951
-     */
952
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
953
-    {
954
-        // make sure this is only when editing
955
-        if (! empty($id)) {
956
-            $post = get_post($id);
957
-            $return .= '<a class="button button--secondary" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
958
-                       . esc_html__('Shortcode', 'event_espresso')
959
-                       . '</a> ';
960
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
961
-                       . $post->ID
962
-                       . ']">';
963
-        }
964
-        return $return;
965
-    }
966
-
967
-
968
-    /**
969
-     * _events_overview_list_table
970
-     * This contains the logic for showing the events_overview list
971
-     *
972
-     * @access protected
973
-     * @return void
974
-     * @throws DomainException
975
-     * @throws EE_Error
976
-     * @throws InvalidArgumentException
977
-     * @throws InvalidDataTypeException
978
-     * @throws InvalidInterfaceException
979
-     */
980
-    protected function _events_overview_list_table()
981
-    {
982
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
983
-        $after_list_table                           = [];
984
-        $after_list_table['view_event_list_button'] = EEH_HTML::br();
985
-        $after_list_table['view_event_list_button'] .= EEH_Template::get_button_or_link(
986
-            get_post_type_archive_link('espresso_events'),
987
-            esc_html__('View Event Archive Page', 'event_espresso'),
988
-            'button'
989
-        );
990
-        $after_list_table['legend']                 = $this->_display_legend($this->_event_legend_items());
991
-        $this->_admin_page_title                    .= ' ' . $this->get_action_link_or_button(
992
-            'create_new',
993
-            'add',
994
-            [],
995
-            'add-new-h2'
996
-        );
997
-        $this->_template_args['after_list_table']   = array_merge(
998
-            (array) $this->_template_args['after_list_table'],
999
-            $after_list_table
1000
-        );
1001
-        $this->display_admin_list_table_page_with_no_sidebar();
1002
-    }
1003
-
1004
-
1005
-    /**
1006
-     * this allows for extra misc actions in the default WP publish box
1007
-     *
1008
-     * @return void
1009
-     * @throws DomainException
1010
-     * @throws EE_Error
1011
-     * @throws InvalidArgumentException
1012
-     * @throws InvalidDataTypeException
1013
-     * @throws InvalidInterfaceException
1014
-     * @throws ReflectionException
1015
-     */
1016
-    public function extra_misc_actions_publish_box()
1017
-    {
1018
-        $this->_generate_publish_box_extra_content();
1019
-    }
1020
-
1021
-
1022
-    /**
1023
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1024
-     * saved.
1025
-     * Typically you would use this to save any additional data.
1026
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
1027
-     * ALSO very important.  When a post transitions from scheduled to published,
1028
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1029
-     * other meta saves. So MAKE sure that you handle this accordingly.
1030
-     *
1031
-     * @access protected
1032
-     * @abstract
1033
-     * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
1034
-     * @param object $post    The post object of the cpt that was saved.
1035
-     * @return void
1036
-     * @throws EE_Error
1037
-     * @throws InvalidArgumentException
1038
-     * @throws InvalidDataTypeException
1039
-     * @throws InvalidInterfaceException
1040
-     * @throws ReflectionException
1041
-     */
1042
-    protected function _insert_update_cpt_item($post_id, $post)
1043
-    {
1044
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1045
-            // get out we're not processing an event save.
1046
-            return;
1047
-        }
1048
-        $event_values = [
1049
-            'EVT_member_only'     => $this->request->getRequestParam('member_only', false, 'bool'),
1050
-            'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, 'bool'),
1051
-            'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1052
-        ];
1053
-        // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1054
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1055
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1056
-                'display_ticket_selector',
1057
-                false,
1058
-                'bool'
1059
-            );
1060
-            $event_values['EVT_additional_limit']            = min(
1061
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1062
-                $this->request->getRequestParam('additional_limit', null, 'int')
1063
-            );
1064
-            $event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1065
-                'EVT_default_registration_status',
1066
-                EE_Registry::instance()->CFG->registration->default_STS_ID
1067
-            );
1068
-
1069
-            $event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1070
-            $event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1071
-            $event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, 'bool');
1072
-        }
1073
-        // update event
1074
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1075
-        // get event_object for other metaboxes...
1076
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1077
-        // i have to setup where conditions to override the filters in the model
1078
-        // that filter out autodraft and inherit statuses so we GET the inherit id!
1079
-        $event = $this->_event_model()->get_one(
1080
-            [
1081
-                [
1082
-                    $this->_event_model()->primary_key_name() => $post_id,
1083
-                    'OR'                                      => [
1084
-                        'status'   => $post->post_status,
1085
-                        // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1086
-                        // but the returned object here has a status of "publish", so use the original post status as well
1087
-                        'status*1' => $this->request->getRequestParam('original_post_status'),
1088
-                    ],
1089
-                ],
1090
-            ]
1091
-        );
1092
-
1093
-        // the following are default callbacks for event attachment updates
1094
-        // that can be overridden by caffeinated functionality and/or addons.
1095
-        $event_update_callbacks = [];
1096
-        if (! $this->admin_config->useAdvancedEditor()) {
1097
-            $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1098
-            $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1099
-        }
1100
-        $event_update_callbacks = apply_filters(
1101
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1102
-            $event_update_callbacks
1103
-        );
1104
-
1105
-        $att_success = true;
1106
-        foreach ($event_update_callbacks as $e_callback) {
1107
-            $_success = is_callable($e_callback)
1108
-                ? $e_callback($event, $this->request->requestParams())
1109
-                : false;
1110
-            // if ANY of these updates fail then we want the appropriate global error message
1111
-            $att_success = $_success !== false ? $att_success : false;
1112
-        }
1113
-        // any errors?
1114
-        if ($success && $att_success === false) {
1115
-            EE_Error::add_error(
1116
-                esc_html__(
1117
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1118
-                    'event_espresso'
1119
-                ),
1120
-                __FILE__,
1121
-                __FUNCTION__,
1122
-                __LINE__
1123
-            );
1124
-        } elseif ($success === false) {
1125
-            EE_Error::add_error(
1126
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1127
-                __FILE__,
1128
-                __FUNCTION__,
1129
-                __LINE__
1130
-            );
1131
-        }
1132
-    }
1133
-
1134
-
1135
-    /**
1136
-     * @param int $post_id
1137
-     * @param int $revision_id
1138
-     * @throws EE_Error
1139
-     * @throws EE_Error
1140
-     * @throws ReflectionException
1141
-     * @see parent::restore_item()
1142
-     */
1143
-    protected function _restore_cpt_item($post_id, $revision_id)
1144
-    {
1145
-        // copy existing event meta to new post
1146
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1147
-        if ($post_evt instanceof EE_Event) {
1148
-            // meta revision restore
1149
-            $post_evt->restore_revision($revision_id);
1150
-            // related objs restore
1151
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1152
-        }
1153
-    }
1154
-
1155
-
1156
-    /**
1157
-     * Attach the venue to the Event
1158
-     *
1159
-     * @param EE_Event $event Event Object to add the venue to
1160
-     * @param array    $data  The request data from the form
1161
-     * @return bool           Success or fail.
1162
-     * @throws EE_Error
1163
-     * @throws ReflectionException
1164
-     */
1165
-    protected function _default_venue_update(EE_Event $event, $data)
1166
-    {
1167
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1168
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1169
-        $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1170
-        // very important.  If we don't have a venue name...
1171
-        // then we'll get out because not necessary to create empty venue
1172
-        if (empty($data['venue_title'])) {
1173
-            return false;
1174
-        }
1175
-        $venue_array = [
1176
-            'VNU_wp_user'         => $event->get('EVT_wp_user'),
1177
-            'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1178
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1179
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1180
-            'VNU_short_desc'      => ! empty($data['venue_short_description'])
1181
-                ? $data['venue_short_description']
1182
-                : null,
1183
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1184
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1185
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1186
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1187
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1188
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1189
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1190
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1191
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1192
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1193
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1194
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1195
-            'status'              => 'publish',
1196
-        ];
1197
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1198
-        if (! empty($venue_id)) {
1199
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1200
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1201
-            // we've gotta make sure that the venue is always attached to a revision..
1202
-            // add_relation_to should take care of making sure that the relation is already present.
1203
-            $event->_add_relation_to($venue_id, 'Venue');
1204
-            return $rows_affected > 0;
1205
-        }
1206
-        // we insert the venue
1207
-        $venue_id = $venue_model->insert($venue_array);
1208
-        $event->_add_relation_to($venue_id, 'Venue');
1209
-        return ! empty($venue_id);
1210
-        // when we have the ancestor come in it's already been handled by the revision save.
1211
-    }
1212
-
1213
-
1214
-    /**
1215
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1216
-     *
1217
-     * @param EE_Event $event The Event object we're attaching data to
1218
-     * @param array    $data  The request data from the form
1219
-     * @return array
1220
-     * @throws EE_Error
1221
-     * @throws ReflectionException
1222
-     * @throws Exception
1223
-     */
1224
-    protected function _default_tickets_update(EE_Event $event, $data)
1225
-    {
1226
-        if ($this->admin_config->useAdvancedEditor()) {
1227
-            return [];
1228
-        }
1229
-        $datetime       = null;
1230
-        $saved_tickets  = [];
1231
-        $event_timezone = $event->get_timezone();
1232
-        $date_formats   = ['Y-m-d', 'h:i a'];
1233
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1234
-            // trim all values to ensure any excess whitespace is removed.
1235
-            $datetime_data                = array_map('trim', $datetime_data);
1236
-            $datetime_data['DTT_EVT_end'] =
1237
-                isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1238
-                    ? $datetime_data['DTT_EVT_end']
1239
-                    : $datetime_data['DTT_EVT_start'];
1240
-            $datetime_values              = [
1241
-                'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1242
-                'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1243
-                'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1244
-                'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1245
-                'DTT_order'     => $row,
1246
-            ];
1247
-            // if we have an id then let's get existing object first and then set the new values.
1248
-            //  Otherwise we instantiate a new object for save.
1249
-            if (! empty($datetime_data['DTT_ID'])) {
1250
-                $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1251
-                if (! $datetime instanceof EE_Ticket) {
1252
-                    throw new RuntimeException(
1253
-                        sprintf(
1254
-                            esc_html__(
1255
-                                'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1256
-                                'event_espresso'
1257
-                            ),
1258
-                            $datetime_data['DTT_ID']
1259
-                        )
1260
-                    );
1261
-                }
1262
-                $datetime->set_date_format($date_formats[0]);
1263
-                $datetime->set_time_format($date_formats[1]);
1264
-                foreach ($datetime_values as $field => $value) {
1265
-                    $datetime->set($field, $value);
1266
-                }
1267
-            } else {
1268
-                $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1269
-            }
1270
-            if (! $datetime instanceof EE_Datetime) {
1271
-                throw new RuntimeException(
1272
-                    sprintf(
1273
-                        esc_html__(
1274
-                            'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1275
-                            'event_espresso'
1276
-                        ),
1277
-                        print_r($datetime_values, true)
1278
-                    )
1279
-                );
1280
-            }
1281
-            // before going any further make sure our dates are setup correctly
1282
-            // so that the end date is always equal or greater than the start date.
1283
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1284
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1285
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1286
-            }
1287
-            $datetime->save();
1288
-            $event->_add_relation_to($datetime, 'Datetime');
1289
-        }
1290
-        // no datetimes get deleted so we don't do any of that logic here.
1291
-        // update tickets next
1292
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1293
-
1294
-        // set up some default start and end dates in case those are not present in the incoming data
1295
-        $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1296
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1297
-        // use the start date of the first datetime for the end date
1298
-        $first_datetime   = $event->first_datetime();
1299
-        $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1300
-
1301
-        // now process the incoming data
1302
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
1303
-            $update_prices = false;
1304
-            $ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1305
-                ? $data['edit_prices'][ $row ][1]['PRC_amount']
1306
-                : 0;
1307
-            // trim inputs to ensure any excess whitespace is removed.
1308
-            $ticket_data   = array_map('trim', $ticket_data);
1309
-            $ticket_values = [
1310
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1311
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1312
-                'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1313
-                'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1314
-                'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1315
-                    ? $ticket_data['TKT_start_date']
1316
-                    : $default_start_date,
1317
-                'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1318
-                    ? $ticket_data['TKT_end_date']
1319
-                    : $default_end_date,
1320
-                'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1321
-                                     || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1322
-                    ? $ticket_data['TKT_qty']
1323
-                    : EE_INF,
1324
-                'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1325
-                                     || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1326
-                    ? $ticket_data['TKT_uses']
1327
-                    : EE_INF,
1328
-                'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1329
-                'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1330
-                'TKT_order'       => isset($ticket_data['TKT_order']) ? $ticket_data['TKT_order'] : $row,
1331
-                'TKT_price'       => $ticket_price,
1332
-                'TKT_row'         => $row,
1333
-            ];
1334
-            // if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1335
-            // which means in turn that the prices will become new prices as well.
1336
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1337
-                $ticket_values['TKT_ID']         = 0;
1338
-                $ticket_values['TKT_is_default'] = 0;
1339
-                $update_prices                   = true;
1340
-            }
1341
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1342
-            // we actually do our saves ahead of adding any relations because its entirely possible that this
1343
-            // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1344
-            // keep in mind that if the ticket has been sold (and we have changed pricing information),
1345
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1346
-            if (! empty($ticket_data['TKT_ID'])) {
1347
-                $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1348
-                if (! $existing_ticket instanceof EE_Ticket) {
1349
-                    throw new RuntimeException(
1350
-                        sprintf(
1351
-                            esc_html__(
1352
-                                'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1353
-                                'event_espresso'
1354
-                            ),
1355
-                            $ticket_data['TKT_ID']
1356
-                        )
1357
-                    );
1358
-                }
1359
-                $ticket_sold = $existing_ticket->count_related(
1360
-                    'Registration',
1361
-                    [
1362
-                            [
1363
-                                'STS_ID' => [
1364
-                                    'NOT IN',
1365
-                                    [EEM_Registration::status_id_incomplete],
1366
-                                ],
1367
-                            ],
1368
-                        ]
1369
-                ) > 0;
1370
-                // let's just check the total price for the existing ticket and determine if it matches the new total price.
1371
-                // if they are different then we create a new ticket (if $ticket_sold)
1372
-                // if they aren't different then we go ahead and modify existing ticket.
1373
-                $create_new_ticket = $ticket_sold
1374
-                                     && $ticket_price !== $existing_ticket->price()
1375
-                                     && ! $existing_ticket->deleted();
1376
-                $existing_ticket->set_date_format($date_formats[0]);
1377
-                $existing_ticket->set_time_format($date_formats[1]);
1378
-                // set new values
1379
-                foreach ($ticket_values as $field => $value) {
1380
-                    if ($field == 'TKT_qty') {
1381
-                        $existing_ticket->set_qty($value);
1382
-                    } elseif ($field == 'TKT_price') {
1383
-                        $existing_ticket->set('TKT_price', $ticket_price);
1384
-                    } else {
1385
-                        $existing_ticket->set($field, $value);
1386
-                    }
1387
-                }
1388
-                $ticket = $existing_ticket;
1389
-                // if $create_new_ticket is false then we can safely update the existing ticket.
1390
-                //  Otherwise we have to create a new ticket.
1391
-                if ($create_new_ticket) {
1392
-                    // archive the old ticket first
1393
-                    $existing_ticket->set('TKT_deleted', 1);
1394
-                    $existing_ticket->save();
1395
-                    // make sure this ticket is still recorded in our $saved_tickets
1396
-                    // so we don't run it through the regular trash routine.
1397
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1398
-                    // create new ticket that's a copy of the existing except,
1399
-                    // (a new id of course and not archived) AND has the new TKT_price associated with it.
1400
-                    $new_ticket = clone $existing_ticket;
1401
-                    $new_ticket->set('TKT_ID', 0);
1402
-                    $new_ticket->set('TKT_deleted', 0);
1403
-                    $new_ticket->set('TKT_sold', 0);
1404
-                    // now we need to make sure that $new prices are created as well and attached to new ticket.
1405
-                    $update_prices = true;
1406
-                    $ticket        = $new_ticket;
1407
-                }
1408
-            } else {
1409
-                // no TKT_id so a new ticket
1410
-                $ticket_values['TKT_price'] = $ticket_price;
1411
-                $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1412
-                $update_prices              = true;
1413
-            }
1414
-            if (! $ticket instanceof EE_Ticket) {
1415
-                throw new RuntimeException(
1416
-                    sprintf(
1417
-                        esc_html__(
1418
-                            'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1419
-                            'event_espresso'
1420
-                        ),
1421
-                        print_r($ticket_values, true)
1422
-                    )
1423
-                );
1424
-            }
1425
-            // cap ticket qty by datetime reg limits
1426
-            $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1427
-            // update ticket.
1428
-            $ticket->save();
1429
-            // before going any further make sure our dates are setup correctly
1430
-            // so that the end date is always equal or greater than the start date.
1431
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1432
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1433
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1434
-                $ticket->save();
1435
-            }
1436
-            // initially let's add the ticket to the datetime
1437
-            $datetime->_add_relation_to($ticket, 'Ticket');
1438
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1439
-            // add prices to ticket
1440
-            $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $ticket, $update_prices);
1441
-        }
1442
-        // however now we need to handle permanently deleting tickets via the ui.
1443
-        //  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1444
-        //  However, it does allow for deleting tickets that have no tickets sold,
1445
-        // in which case we want to get rid of permanently because there is no need to save in db.
1446
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1447
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1448
-        foreach ($tickets_removed as $id) {
1449
-            $id = absint($id);
1450
-            // get the ticket for this id
1451
-            $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1452
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1453
-                continue;
1454
-            }
1455
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1456
-            // (remember this process can ONLY kick off if there are NO tickets sold)
1457
-            $related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1458
-            foreach ($related_datetimes as $related_datetime) {
1459
-                $ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1460
-            }
1461
-            // need to do the same for prices (except these prices can also be deleted because again,
1462
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1463
-            $ticket_to_remove->delete_related_permanently('Price');
1464
-            // finally let's delete this ticket
1465
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1466
-            $ticket_to_remove->delete_permanently();
1467
-        }
1468
-        return [$datetime, $saved_tickets];
1469
-    }
1470
-
1471
-
1472
-    /**
1473
-     * This attaches a list of given prices to a ticket.
1474
-     * Note we dont' have to worry about ever removing relationships (or archiving prices)
1475
-     * because if there is a change in price information on a ticket, a new ticket is created anyways
1476
-     * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1477
-     *
1478
-     * @access  private
1479
-     * @param array     $prices_data Array of prices from the form.
1480
-     * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1481
-     * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1482
-     * @return  void
1483
-     * @throws EE_Error
1484
-     * @throws ReflectionException
1485
-     */
1486
-    private function _add_prices_to_ticket($prices_data, EE_Ticket $ticket, $new_prices = false)
1487
-    {
1488
-        $timezone = $ticket->get_timezone();
1489
-        foreach ($prices_data as $row => $price_data) {
1490
-            $price_values = [
1491
-                'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1492
-                'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1493
-                'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1494
-                'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1495
-                'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1496
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1497
-                'PRC_order'      => $row,
1498
-            ];
1499
-            if ($new_prices || empty($price_values['PRC_ID'])) {
1500
-                $price_values['PRC_ID'] = 0;
1501
-                $price                  = EE_Price::new_instance($price_values, $timezone);
1502
-            } else {
1503
-                $price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1504
-                // update this price with new values
1505
-                foreach ($price_values as $field => $new_price) {
1506
-                    $price->set($field, $new_price);
1507
-                }
1508
-            }
1509
-            if (! $price instanceof EE_Price) {
1510
-                throw new RuntimeException(
1511
-                    sprintf(
1512
-                        esc_html__(
1513
-                            'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1514
-                            'event_espresso'
1515
-                        ),
1516
-                        print_r($price_values, true)
1517
-                    )
1518
-                );
1519
-            }
1520
-            $price->save();
1521
-            $ticket->_add_relation_to($price, 'Price');
1522
-        }
1523
-    }
1524
-
1525
-
1526
-    /**
1527
-     * Add in our autosave ajax handlers
1528
-     *
1529
-     */
1530
-    protected function _ee_autosave_create_new()
1531
-    {
1532
-    }
1533
-
1534
-
1535
-    /**
1536
-     * More autosave handlers.
1537
-     */
1538
-    protected function _ee_autosave_edit()
1539
-    {
1540
-    }
1541
-
1542
-
1543
-    /**
1544
-     * @throws EE_Error
1545
-     * @throws ReflectionException
1546
-     */
1547
-    private function _generate_publish_box_extra_content()
1548
-    {
1549
-        // load formatter helper
1550
-        // args for getting related registrations
1551
-        $approved_query_args        = [
1552
-            [
1553
-                'REG_deleted' => 0,
1554
-                'STS_ID'      => EEM_Registration::status_id_approved,
1555
-            ],
1556
-        ];
1557
-        $not_approved_query_args    = [
1558
-            [
1559
-                'REG_deleted' => 0,
1560
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1561
-            ],
1562
-        ];
1563
-        $pending_payment_query_args = [
1564
-            [
1565
-                'REG_deleted' => 0,
1566
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1567
-            ],
1568
-        ];
1569
-        // publish box
1570
-        $publish_box_extra_args = [
1571
-            'view_approved_reg_url'        => add_query_arg(
1572
-                [
1573
-                    'action'      => 'default',
1574
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1575
-                    '_reg_status' => EEM_Registration::status_id_approved,
1576
-                ],
1577
-                REG_ADMIN_URL
1578
-            ),
1579
-            'view_not_approved_reg_url'    => add_query_arg(
1580
-                [
1581
-                    'action'      => 'default',
1582
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1583
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1584
-                ],
1585
-                REG_ADMIN_URL
1586
-            ),
1587
-            'view_pending_payment_reg_url' => add_query_arg(
1588
-                [
1589
-                    'action'      => 'default',
1590
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1591
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1592
-                ],
1593
-                REG_ADMIN_URL
1594
-            ),
1595
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1596
-                'Registration',
1597
-                $approved_query_args
1598
-            ),
1599
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1600
-                'Registration',
1601
-                $not_approved_query_args
1602
-            ),
1603
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1604
-                'Registration',
1605
-                $pending_payment_query_args
1606
-            ),
1607
-            'misc_pub_section_class'       => apply_filters(
1608
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1609
-                'misc-pub-section'
1610
-            ),
1611
-        ];
1612
-        ob_start();
1613
-        do_action(
1614
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1615
-            $this->_cpt_model_obj
1616
-        );
1617
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1618
-        // load template
1619
-        EEH_Template::display_template(
1620
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1621
-            $publish_box_extra_args
1622
-        );
1623
-    }
1624
-
1625
-
1626
-    /**
1627
-     * @return EE_Event
1628
-     */
1629
-    public function get_event_object()
1630
-    {
1631
-        return $this->_cpt_model_obj;
1632
-    }
1633
-
1634
-
1635
-
1636
-
1637
-    /** METABOXES * */
1638
-    /**
1639
-     * _register_event_editor_meta_boxes
1640
-     * add all metaboxes related to the event_editor
1641
-     *
1642
-     * @return void
1643
-     * @throws EE_Error
1644
-     * @throws ReflectionException
1645
-     */
1646
-    protected function _register_event_editor_meta_boxes()
1647
-    {
1648
-        $this->verify_cpt_object();
1649
-        $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1650
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1651
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1652
-            $this->addMetaBox(
1653
-                'espresso_event_editor_event_options',
1654
-                esc_html__('Event Registration Options', 'event_espresso'),
1655
-                [$this, 'registration_options_meta_box'],
1656
-                $this->page_slug,
1657
-                'side'
1658
-            );
1659
-        }
1660
-        if (! $use_advanced_editor) {
1661
-            $this->addMetaBox(
1662
-                'espresso_event_editor_tickets',
1663
-                esc_html__('Event Datetime & Ticket', 'event_espresso'),
1664
-                [$this, 'ticket_metabox'],
1665
-                $this->page_slug,
1666
-                'normal',
1667
-                'high'
1668
-            );
1669
-        } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1670
-            add_action(
1671
-                'add_meta_boxes_espresso_events',
1672
-                function () {
1673
-                    global $current_screen;
1674
-                    remove_meta_box('authordiv', $current_screen, 'normal');
1675
-                },
1676
-                99
1677
-            );
1678
-        }
1679
-        // NOTE: if you're looking for other metaboxes in here,
1680
-        // where a metabox has a related management page in the admin
1681
-        // you will find it setup in the related management page's "_Hooks" file.
1682
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1683
-    }
1684
-
1685
-
1686
-    /**
1687
-     * @throws DomainException
1688
-     * @throws EE_Error
1689
-     * @throws ReflectionException
1690
-     */
1691
-    public function ticket_metabox()
1692
-    {
1693
-        $existing_datetime_ids = $existing_ticket_ids = [];
1694
-        // defaults for template args
1695
-        $template_args = [
1696
-            'existing_datetime_ids'    => '',
1697
-            'event_datetime_help_link' => '',
1698
-            'ticket_options_help_link' => '',
1699
-            'time'                     => null,
1700
-            'ticket_rows'              => '',
1701
-            'existing_ticket_ids'      => '',
1702
-            'total_ticket_rows'        => 1,
1703
-            'ticket_js_structure'      => '',
1704
-            'trash_icon'               => 'dashicons dashicons-lock',
1705
-            'disabled'                 => '',
1706
-        ];
1707
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1708
-        /**
1709
-         * 1. Start with retrieving Datetimes
1710
-         * 2. Fore each datetime get related tickets
1711
-         * 3. For each ticket get related prices
1712
-         */
1713
-        /** @var EEM_Datetime $datetime_model */
1714
-        $datetime_model = EE_Registry::instance()->load_model('Datetime');
1715
-        /** @var EEM_Ticket $datetime_model */
1716
-        $ticket_model = EE_Registry::instance()->load_model('Ticket');
1717
-        $times        = $datetime_model->get_all_event_dates($event_id);
1718
-        /** @type EE_Datetime $first_datetime */
1719
-        $first_datetime = reset($times);
1720
-        // do we get related tickets?
1721
-        if (
1722
-            $first_datetime instanceof EE_Datetime
1723
-            && $first_datetime->ID() !== 0
1724
-        ) {
1725
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1726
-            $template_args['time']   = $first_datetime;
1727
-            $related_tickets         = $first_datetime->tickets(
1728
-                [
1729
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1730
-                    'default_where_conditions' => 'none',
1731
-                ]
1732
-            );
1733
-            if (! empty($related_tickets)) {
1734
-                $template_args['total_ticket_rows'] = count($related_tickets);
1735
-                $row                                = 0;
1736
-                foreach ($related_tickets as $ticket) {
1737
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1738
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1739
-                    $row++;
1740
-                }
1741
-            } else {
1742
-                $template_args['total_ticket_rows'] = 1;
1743
-                /** @type EE_Ticket $ticket */
1744
-                $ticket                       = $ticket_model->create_default_object();
1745
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1746
-            }
1747
-        } else {
1748
-            $template_args['time'] = $times[0];
1749
-            /** @type EE_Ticket[] $tickets */
1750
-            $tickets                      = $ticket_model->get_all_default_tickets();
1751
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1752
-            // NOTE: we're just sending the first default row
1753
-            // (decaf can't manage default tickets so this should be sufficient);
1754
-        }
1755
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1756
-            'event_editor_event_datetimes_help_tab'
1757
-        );
1758
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1759
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1760
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1761
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1762
-            $ticket_model->create_default_object(),
1763
-            true
1764
-        );
1765
-        $template                                  = apply_filters(
1766
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1767
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1768
-        );
1769
-        EEH_Template::display_template($template, $template_args);
1770
-    }
1771
-
1772
-
1773
-    /**
1774
-     * Setup an individual ticket form for the decaf event editor page
1775
-     *
1776
-     * @access private
1777
-     * @param EE_Ticket $ticket   the ticket object
1778
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1779
-     * @param int       $row
1780
-     * @return string generated html for the ticket row.
1781
-     * @throws EE_Error
1782
-     * @throws ReflectionException
1783
-     */
1784
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1785
-    {
1786
-        $template_args = [
1787
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1788
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1789
-                : '',
1790
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1791
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1792
-            'TKT_name'            => $ticket->get('TKT_name'),
1793
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1794
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1795
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1796
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1797
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1798
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1799
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1800
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1801
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'dashicons dashicons-lock',
1802
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1803
-                : ' disabled=disabled',
1804
-        ];
1805
-        $price         = $ticket->ID() !== 0
1806
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1807
-            : null;
1808
-        $price         = $price instanceof EE_Price
1809
-            ? $price
1810
-            : EEM_Price::instance()->create_default_object();
1811
-        $price_args    = [
1812
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1813
-            'PRC_amount'            => $price->get('PRC_amount'),
1814
-            'PRT_ID'                => $price->get('PRT_ID'),
1815
-            'PRC_ID'                => $price->get('PRC_ID'),
1816
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1817
-        ];
1818
-        // make sure we have default start and end dates if skeleton
1819
-        // handle rows that should NOT be empty
1820
-        if (empty($template_args['TKT_start_date'])) {
1821
-            // if empty then the start date will be now.
1822
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1823
-        }
1824
-        if (empty($template_args['TKT_end_date'])) {
1825
-            // get the earliest datetime (if present);
1826
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1827
-                ? $this->_cpt_model_obj->get_first_related(
1828
-                    'Datetime',
1829
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1830
-                )
1831
-                : null;
1832
-            $template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1833
-                ? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1834
-                : date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1835
-        }
1836
-        $template_args = array_merge($template_args, $price_args);
1837
-        $template      = apply_filters(
1838
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1839
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1840
-            $ticket
1841
-        );
1842
-        return EEH_Template::display_template($template, $template_args, true);
1843
-    }
1844
-
1845
-
1846
-    /**
1847
-     * @throws EE_Error
1848
-     * @throws ReflectionException
1849
-     */
1850
-    public function registration_options_meta_box()
1851
-    {
1852
-        $yes_no_values             = [
1853
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1854
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1855
-        ];
1856
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1857
-            [
1858
-                EEM_Registration::status_id_cancelled,
1859
-                EEM_Registration::status_id_declined,
1860
-                EEM_Registration::status_id_incomplete,
1861
-            ],
1862
-            true
1863
-        );
1864
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1865
-        $template_args['_event']                          = $this->_cpt_model_obj;
1866
-        $template_args['event']                           = $this->_cpt_model_obj;
1867
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1868
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1869
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1870
-            'default_reg_status',
1871
-            $default_reg_status_values,
1872
-            $this->_cpt_model_obj->default_registration_status()
1873
-        );
1874
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1875
-            'display_desc',
1876
-            $yes_no_values,
1877
-            $this->_cpt_model_obj->display_description()
1878
-        );
1879
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1880
-            'display_ticket_selector',
1881
-            $yes_no_values,
1882
-            $this->_cpt_model_obj->display_ticket_selector(),
1883
-            '',
1884
-            '',
1885
-            false
1886
-        );
1887
-        $template_args['additional_registration_options'] = apply_filters(
1888
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1889
-            '',
1890
-            $template_args,
1891
-            $yes_no_values,
1892
-            $default_reg_status_values
1893
-        );
1894
-        EEH_Template::display_template(
1895
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1896
-            $template_args
1897
-        );
1898
-    }
1899
-
1900
-
1901
-    /**
1902
-     * _get_events()
1903
-     * This method simply returns all the events (for the given _view and paging)
1904
-     *
1905
-     * @access public
1906
-     * @param int  $per_page     count of items per page (20 default);
1907
-     * @param int  $current_page what is the current page being viewed.
1908
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1909
-     *                           If FALSE then we return an array of event objects
1910
-     *                           that match the given _view and paging parameters.
1911
-     * @return array|int         an array of event objects or a count of them.
1912
-     * @throws Exception
1913
-     */
1914
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1915
-    {
1916
-        $EEM_Event   = $this->_event_model();
1917
-        $offset      = ($current_page - 1) * $per_page;
1918
-        $limit       = $count ? null : $offset . ',' . $per_page;
1919
-        $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1920
-        $order       = $this->request->getRequestParam('order', 'DESC');
1921
-        $month_range = $this->request->getRequestParam('month_range');
1922
-        if ($month_range) {
1923
-            $pieces = explode(' ', $month_range, 3);
1924
-            // simulate the FIRST day of the month, that fixes issues for months like February
1925
-            // where PHP doesn't know what to assume for date.
1926
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1927
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1928
-            $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1929
-        }
1930
-        $where  = [];
1931
-        $status = $this->request->getRequestParam('status');
1932
-        // determine what post_status our condition will have for the query.
1933
-        switch ($status) {
1934
-            case 'month':
1935
-            case 'today':
1936
-            case null:
1937
-            case 'all':
1938
-                break;
1939
-            case 'draft':
1940
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1941
-                break;
1942
-            default:
1943
-                $where['status'] = $status;
1944
-        }
1945
-        // categories? The default for all categories is -1
1946
-        $category = $this->request->getRequestParam('EVT_CAT', -1, 'int');
1947
-        if ($category !== -1) {
1948
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1949
-            $where['Term_Taxonomy.term_id']  = $category;
1950
-        }
1951
-        // date where conditions
1952
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1953
-        if ($month_range) {
1954
-            $DateTime = new DateTime(
1955
-                $year_r . '-' . $month_r . '-01 00:00:00',
1956
-                new DateTimeZone('UTC')
1957
-            );
1958
-            $start    = $DateTime->getTimestamp();
1959
-            // set the datetime to be the end of the month
1960
-            $DateTime->setDate(
1961
-                $year_r,
1962
-                $month_r,
1963
-                $DateTime->format('t')
1964
-            )->setTime(23, 59, 59);
1965
-            $end                             = $DateTime->getTimestamp();
1966
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1967
-        } elseif ($status === 'today') {
1968
-            $DateTime                        =
1969
-                new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1970
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1971
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1972
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1973
-        } elseif ($status === 'month') {
1974
-            $now                             = date('Y-m-01');
1975
-            $DateTime                        =
1976
-                new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1977
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1978
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1979
-                                                        ->setTime(23, 59, 59)
1980
-                                                        ->format(implode(' ', $start_formats));
1981
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1982
-        }
1983
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1984
-            $where['EVT_wp_user'] = get_current_user_id();
1985
-        } else {
1986
-            if (! isset($where['status'])) {
1987
-                if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1988
-                    $where['OR'] = [
1989
-                        'status*restrict_private' => ['!=', 'private'],
1990
-                        'AND'                     => [
1991
-                            'status*inclusive' => ['=', 'private'],
1992
-                            'EVT_wp_user'      => get_current_user_id(),
1993
-                        ],
1994
-                    ];
1995
-                }
1996
-            }
1997
-        }
1998
-        $wp_user = $this->request->getRequestParam('EVT_wp_user', 0, 'int');
1999
-        if (
2000
-            $wp_user
2001
-            && $wp_user !== get_current_user_id()
2002
-            && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
2003
-        ) {
2004
-            $where['EVT_wp_user'] = $wp_user;
2005
-        }
2006
-        // search query handling
2007
-        $search_term = $this->request->getRequestParam('s');
2008
-        if ($search_term) {
2009
-            $search_term = '%' . $search_term . '%';
2010
-            $where['OR'] = [
2011
-                'EVT_name'       => ['LIKE', $search_term],
2012
-                'EVT_desc'       => ['LIKE', $search_term],
2013
-                'EVT_short_desc' => ['LIKE', $search_term],
2014
-            ];
2015
-        }
2016
-        // filter events by venue.
2017
-        $venue = $this->request->getRequestParam('venue', 0, 'int');
2018
-        if ($venue) {
2019
-            $where['Venue.VNU_ID'] = $venue;
2020
-        }
2021
-        $request_params = $this->request->requestParams();
2022
-        $where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2023
-        $query_params   = apply_filters(
2024
-            'FHEE__Events_Admin_Page__get_events__query_params',
2025
-            [
2026
-                $where,
2027
-                'limit'    => $limit,
2028
-                'order_by' => $orderby,
2029
-                'order'    => $order,
2030
-                'group_by' => 'EVT_ID',
2031
-            ],
2032
-            $request_params
2033
-        );
2034
-
2035
-        // let's first check if we have special requests coming in.
2036
-        $active_status = $this->request->getRequestParam('active_status');
2037
-        if ($active_status) {
2038
-            switch ($active_status) {
2039
-                case 'upcoming':
2040
-                    return $EEM_Event->get_upcoming_events($query_params, $count);
2041
-                case 'expired':
2042
-                    return $EEM_Event->get_expired_events($query_params, $count);
2043
-                case 'active':
2044
-                    return $EEM_Event->get_active_events($query_params, $count);
2045
-                case 'inactive':
2046
-                    return $EEM_Event->get_inactive_events($query_params, $count);
2047
-            }
2048
-        }
2049
-
2050
-        return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2051
-    }
2052
-
2053
-
2054
-    /**
2055
-     * handling for WordPress CPT actions (trash, restore, delete)
2056
-     *
2057
-     * @param string $post_id
2058
-     * @throws EE_Error
2059
-     * @throws ReflectionException
2060
-     */
2061
-    public function trash_cpt_item($post_id)
2062
-    {
2063
-        $this->request->setRequestParam('EVT_ID', $post_id);
2064
-        $this->_trash_or_restore_event('trash', false);
2065
-    }
2066
-
2067
-
2068
-    /**
2069
-     * @param string $post_id
2070
-     * @throws EE_Error
2071
-     * @throws ReflectionException
2072
-     */
2073
-    public function restore_cpt_item($post_id)
2074
-    {
2075
-        $this->request->setRequestParam('EVT_ID', $post_id);
2076
-        $this->_trash_or_restore_event('draft', false);
2077
-    }
2078
-
2079
-
2080
-    /**
2081
-     * @param string $post_id
2082
-     * @throws EE_Error
2083
-     * @throws EE_Error
2084
-     */
2085
-    public function delete_cpt_item($post_id)
2086
-    {
2087
-        throw new EE_Error(
2088
-            esc_html__(
2089
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2090
-                'event_espresso'
2091
-            )
2092
-        );
2093
-        // $this->request->setRequestParam('EVT_ID', $post_id);
2094
-        // $this->_delete_event();
2095
-    }
2096
-
2097
-
2098
-    /**
2099
-     * _trash_or_restore_event
2100
-     *
2101
-     * @access protected
2102
-     * @param string $event_status
2103
-     * @param bool   $redirect_after
2104
-     * @throws EE_Error
2105
-     * @throws EE_Error
2106
-     * @throws ReflectionException
2107
-     */
2108
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2109
-    {
2110
-        // determine the event id and set to array.
2111
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2112
-        // loop thru events
2113
-        if ($EVT_ID) {
2114
-            // clean status
2115
-            $event_status = sanitize_key($event_status);
2116
-            // grab status
2117
-            if (! empty($event_status)) {
2118
-                $success = $this->_change_event_status($EVT_ID, $event_status);
2119
-            } else {
2120
-                $success = false;
2121
-                $msg     = esc_html__(
2122
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2123
-                    'event_espresso'
2124
-                );
2125
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2126
-            }
2127
-        } else {
2128
-            $success = false;
2129
-            $msg     = esc_html__(
2130
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2131
-                'event_espresso'
2132
-            );
2133
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2134
-        }
2135
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2136
-        if ($redirect_after) {
2137
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2138
-        }
2139
-    }
2140
-
2141
-
2142
-    /**
2143
-     * _trash_or_restore_events
2144
-     *
2145
-     * @access protected
2146
-     * @param string $event_status
2147
-     * @return void
2148
-     * @throws EE_Error
2149
-     * @throws EE_Error
2150
-     * @throws ReflectionException
2151
-     */
2152
-    protected function _trash_or_restore_events($event_status = 'trash')
2153
-    {
2154
-        // clean status
2155
-        $event_status = sanitize_key($event_status);
2156
-        // grab status
2157
-        if (! empty($event_status)) {
2158
-            $success = true;
2159
-            // determine the event id and set to array.
2160
-            $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2161
-            // loop thru events
2162
-            foreach ($EVT_IDs as $EVT_ID) {
2163
-                if ($EVT_ID = absint($EVT_ID)) {
2164
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2165
-                    $success = $results !== false ? $success : false;
2166
-                } else {
2167
-                    $msg = sprintf(
2168
-                        esc_html__(
2169
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2170
-                            'event_espresso'
2171
-                        ),
2172
-                        $EVT_ID
2173
-                    );
2174
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2175
-                    $success = false;
2176
-                }
2177
-            }
2178
-        } else {
2179
-            $success = false;
2180
-            $msg     = esc_html__(
2181
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2182
-                'event_espresso'
2183
-            );
2184
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2185
-        }
2186
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2187
-        $success = $success ? 2 : false;
2188
-        $action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2189
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2190
-    }
2191
-
2192
-
2193
-    /**
2194
-     * @param int    $EVT_ID
2195
-     * @param string $event_status
2196
-     * @return bool
2197
-     * @throws EE_Error
2198
-     * @throws ReflectionException
2199
-     */
2200
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
2201
-    {
2202
-        // grab event id
2203
-        if (! $EVT_ID) {
2204
-            $msg = esc_html__(
2205
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2206
-                'event_espresso'
2207
-            );
2208
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2209
-            return false;
2210
-        }
2211
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2212
-        // clean status
2213
-        $event_status = sanitize_key($event_status);
2214
-        // grab status
2215
-        if (empty($event_status)) {
2216
-            $msg = esc_html__(
2217
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2218
-                'event_espresso'
2219
-            );
2220
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2221
-            return false;
2222
-        }
2223
-        // was event trashed or restored ?
2224
-        switch ($event_status) {
2225
-            case 'draft':
2226
-                $action = 'restored from the trash';
2227
-                $hook   = 'AHEE_event_restored_from_trash';
2228
-                break;
2229
-            case 'trash':
2230
-                $action = 'moved to the trash';
2231
-                $hook   = 'AHEE_event_moved_to_trash';
2232
-                break;
2233
-            default:
2234
-                $action = 'updated';
2235
-                $hook   = false;
2236
-        }
2237
-        // use class to change status
2238
-        $this->_cpt_model_obj->set_status($event_status);
2239
-        $success = $this->_cpt_model_obj->save();
2240
-        if (! $success) {
2241
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2242
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2243
-            return false;
2244
-        }
2245
-        if ($hook) {
2246
-            do_action($hook);
2247
-        }
2248
-        return true;
2249
-    }
2250
-
2251
-
2252
-    /**
2253
-     * @param array $event_ids
2254
-     * @return array
2255
-     * @since   4.10.23.p
2256
-     */
2257
-    private function cleanEventIds(array $event_ids)
2258
-    {
2259
-        return array_map('absint', $event_ids);
2260
-    }
2261
-
2262
-
2263
-    /**
2264
-     * @return array
2265
-     * @since   4.10.23.p
2266
-     */
2267
-    private function getEventIdsFromRequest()
2268
-    {
2269
-        if ($this->request->requestParamIsSet('EVT_IDs')) {
2270
-            return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2271
-        } else {
2272
-            return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2273
-        }
2274
-    }
2275
-
2276
-
2277
-    /**
2278
-     * @param bool $preview_delete
2279
-     * @throws EE_Error
2280
-     */
2281
-    protected function _delete_event($preview_delete = true)
2282
-    {
2283
-        $this->_delete_events($preview_delete);
2284
-    }
2285
-
2286
-
2287
-    /**
2288
-     * Gets the tree traversal batch persister.
2289
-     *
2290
-     * @return NodeGroupDao
2291
-     * @throws InvalidArgumentException
2292
-     * @throws InvalidDataTypeException
2293
-     * @throws InvalidInterfaceException
2294
-     * @since 4.10.12.p
2295
-     */
2296
-    protected function getModelObjNodeGroupPersister()
2297
-    {
2298
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2299
-            $this->model_obj_node_group_persister =
2300
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2301
-        }
2302
-        return $this->model_obj_node_group_persister;
2303
-    }
2304
-
2305
-
2306
-    /**
2307
-     * @param bool $preview_delete
2308
-     * @return void
2309
-     * @throws EE_Error
2310
-     */
2311
-    protected function _delete_events($preview_delete = true)
2312
-    {
2313
-        $event_ids = $this->getEventIdsFromRequest();
2314
-        if ($preview_delete) {
2315
-            $this->generateDeletionPreview($event_ids);
2316
-        } else {
2317
-            EEM_Event::instance()->delete_permanently([['EVT_ID' => ['IN', $event_ids]]]);
2318
-        }
2319
-    }
2320
-
2321
-
2322
-    /**
2323
-     * @param array $event_ids
2324
-     */
2325
-    protected function generateDeletionPreview(array $event_ids)
2326
-    {
2327
-        $event_ids = $this->cleanEventIds($event_ids);
2328
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2329
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2330
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2331
-            [
2332
-                'action'            => 'preview_deletion',
2333
-                'deletion_job_code' => $deletion_job_code,
2334
-            ],
2335
-            $this->_admin_base_url
2336
-        );
2337
-        EEH_URL::safeRedirectAndExit(
2338
-            EE_Admin_Page::add_query_args_and_nonce(
2339
-                [
2340
-                    'page'              => 'espresso_batch',
2341
-                    'batch'             => EED_Batch::batch_job,
2342
-                    'EVT_IDs'           => $event_ids,
2343
-                    'deletion_job_code' => $deletion_job_code,
2344
-                    'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2345
-                    'return_url'        => urlencode($return_url),
2346
-                ],
2347
-                admin_url()
2348
-            )
2349
-        );
2350
-    }
2351
-
2352
-
2353
-    /**
2354
-     * Checks for a POST submission
2355
-     *
2356
-     * @since 4.10.12.p
2357
-     */
2358
-    protected function confirmDeletion()
2359
-    {
2360
-        $deletion_redirect_logic =
2361
-            $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion');
2362
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2363
-    }
2364
-
2365
-
2366
-    /**
2367
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2368
-     *
2369
-     * @throws EE_Error
2370
-     * @since 4.10.12.p
2371
-     */
2372
-    protected function previewDeletion()
2373
-    {
2374
-        $preview_deletion_logic =
2375
-            $this->getLoader()->getShared('\EventEspresso\core\domain\services\admin\events\data\PreviewDeletion');
2376
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2377
-        $this->display_admin_page_with_no_sidebar();
2378
-    }
2379
-
2380
-
2381
-    /**
2382
-     * get total number of events
2383
-     *
2384
-     * @access public
2385
-     * @return int
2386
-     * @throws EE_Error
2387
-     * @throws EE_Error
2388
-     */
2389
-    public function total_events()
2390
-    {
2391
-        return EEM_Event::instance()->count(
2392
-            ['caps' => 'read_admin'],
2393
-            'EVT_ID',
2394
-            true
2395
-        );
2396
-    }
2397
-
2398
-
2399
-    /**
2400
-     * get total number of draft events
2401
-     *
2402
-     * @access public
2403
-     * @return int
2404
-     * @throws EE_Error
2405
-     * @throws EE_Error
2406
-     */
2407
-    public function total_events_draft()
2408
-    {
2409
-        return EEM_Event::instance()->count(
2410
-            [
2411
-                ['status' => ['IN', ['draft', 'auto-draft']]],
2412
-                'caps' => 'read_admin',
2413
-            ],
2414
-            'EVT_ID',
2415
-            true
2416
-        );
2417
-    }
2418
-
2419
-
2420
-    /**
2421
-     * get total number of trashed events
2422
-     *
2423
-     * @access public
2424
-     * @return int
2425
-     * @throws EE_Error
2426
-     * @throws EE_Error
2427
-     */
2428
-    public function total_trashed_events()
2429
-    {
2430
-        return EEM_Event::instance()->count(
2431
-            [
2432
-                ['status' => 'trash'],
2433
-                'caps' => 'read_admin',
2434
-            ],
2435
-            'EVT_ID',
2436
-            true
2437
-        );
2438
-    }
2439
-
2440
-
2441
-    /**
2442
-     *    _default_event_settings
2443
-     *    This generates the Default Settings Tab
2444
-     *
2445
-     * @return void
2446
-     * @throws DomainException
2447
-     * @throws EE_Error
2448
-     * @throws InvalidArgumentException
2449
-     * @throws InvalidDataTypeException
2450
-     * @throws InvalidInterfaceException
2451
-     */
2452
-    protected function _default_event_settings()
2453
-    {
2454
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2455
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2456
-        $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2457
-        $this->display_admin_page_with_sidebar();
2458
-    }
2459
-
2460
-
2461
-    /**
2462
-     * Return the form for event settings.
2463
-     *
2464
-     * @return EE_Form_Section_Proper
2465
-     * @throws EE_Error
2466
-     */
2467
-    protected function _default_event_settings_form()
2468
-    {
2469
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2470
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2471
-        // exclude
2472
-            [
2473
-                EEM_Registration::status_id_cancelled,
2474
-                EEM_Registration::status_id_declined,
2475
-                EEM_Registration::status_id_incomplete,
2476
-                EEM_Registration::status_id_wait_list,
2477
-            ],
2478
-            true
2479
-        );
2480
-        return new EE_Form_Section_Proper(
2481
-            [
2482
-                'name'            => 'update_default_event_settings',
2483
-                'html_id'         => 'update_default_event_settings',
2484
-                'html_class'      => 'form-table',
2485
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2486
-                'subsections'     => apply_filters(
2487
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2488
-                    [
2489
-                        'default_reg_status'  => new EE_Select_Input(
2490
-                            $registration_stati_for_selection,
2491
-                            [
2492
-                                'default'         => isset($registration_config->default_STS_ID)
2493
-                                                     && array_key_exists(
2494
-                                                         $registration_config->default_STS_ID,
2495
-                                                         $registration_stati_for_selection
2496
-                                                     )
2497
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2498
-                                    : EEM_Registration::status_id_pending_payment,
2499
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2500
-                                                     . EEH_Template::get_help_tab_link(
2501
-                                                         'default_settings_status_help_tab'
2502
-                                                     ),
2503
-                                'html_help_text'  => esc_html__(
2504
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2505
-                                    'event_espresso'
2506
-                                ),
2507
-                            ]
2508
-                        ),
2509
-                        'default_max_tickets' => new EE_Integer_Input(
2510
-                            [
2511
-                                'default'         => isset($registration_config->default_maximum_number_of_tickets)
2512
-                                    ? $registration_config->default_maximum_number_of_tickets
2513
-                                    : EEM_Event::get_default_additional_limit(),
2514
-                                'html_label_text' => esc_html__(
2515
-                                    'Default Maximum Tickets Allowed Per Order:',
2516
-                                    'event_espresso'
2517
-                                )
2518
-                                                     . EEH_Template::get_help_tab_link(
2519
-                                                         'default_maximum_tickets_help_tab"'
2520
-                                                     ),
2521
-                                'html_help_text'  => esc_html__(
2522
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2523
-                                    'event_espresso'
2524
-                                ),
2525
-                            ]
2526
-                        ),
2527
-                    ]
2528
-                ),
2529
-            ]
2530
-        );
2531
-    }
2532
-
2533
-
2534
-    /**
2535
-     * @return void
2536
-     * @throws EE_Error
2537
-     * @throws InvalidArgumentException
2538
-     * @throws InvalidDataTypeException
2539
-     * @throws InvalidInterfaceException
2540
-     */
2541
-    protected function _update_default_event_settings()
2542
-    {
2543
-        $form = $this->_default_event_settings_form();
2544
-        if ($form->was_submitted()) {
2545
-            $form->receive_form_submission();
2546
-            if ($form->is_valid()) {
2547
-                $registration_config = EE_Registry::instance()->CFG->registration;
2548
-                $valid_data          = $form->valid_data();
2549
-                if (isset($valid_data['default_reg_status'])) {
2550
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2551
-                }
2552
-                if (isset($valid_data['default_max_tickets'])) {
2553
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2554
-                }
2555
-                do_action(
2556
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2557
-                    $valid_data,
2558
-                    EE_Registry::instance()->CFG,
2559
-                    $this
2560
-                );
2561
-                // update because data was valid!
2562
-                EE_Registry::instance()->CFG->update_espresso_config();
2563
-                EE_Error::overwrite_success();
2564
-                EE_Error::add_success(
2565
-                    esc_html__('Default Event Settings were updated', 'event_espresso')
2566
-                );
2567
-            }
2568
-        }
2569
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2570
-    }
2571
-
2572
-
2573
-    /*************        Templates        *************
2574
-     *
2575
-     * @throws EE_Error
2576
-     */
2577
-    protected function _template_settings()
2578
-    {
2579
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2580
-        $this->_template_args['preview_img']  = '<img src="'
2581
-                                                . EVENTS_ASSETS_URL
2582
-                                                . '/images/'
2583
-                                                . 'caffeinated_template_features.jpg" alt="'
2584
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2585
-                                                . '" />';
2586
-        $this->_template_args['preview_text'] = '<strong>'
2587
-                                                . esc_html__(
2588
-                                                    'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2589
-                                                    'event_espresso'
2590
-                                                ) . '</strong>';
2591
-        $this->display_admin_caf_preview_page('template_settings_tab');
2592
-    }
2593
-
2594
-
2595
-    /** Event Category Stuff **/
2596
-    /**
2597
-     * set the _category property with the category object for the loaded page.
2598
-     *
2599
-     * @access private
2600
-     * @return void
2601
-     */
2602
-    private function _set_category_object()
2603
-    {
2604
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2605
-            return;
2606
-        } //already have the category object so get out.
2607
-        // set default category object
2608
-        $this->_set_empty_category_object();
2609
-        // only set if we've got an id
2610
-        $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2611
-        if (! $category_ID) {
2612
-            return;
2613
-        }
2614
-        $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2615
-        if (! empty($term)) {
2616
-            $this->_category->category_name       = $term->name;
2617
-            $this->_category->category_identifier = $term->slug;
2618
-            $this->_category->category_desc       = $term->description;
2619
-            $this->_category->id                  = $term->term_id;
2620
-            $this->_category->parent              = $term->parent;
2621
-        }
2622
-    }
2623
-
2624
-
2625
-    /**
2626
-     * Clears out category properties.
2627
-     */
2628
-    private function _set_empty_category_object()
2629
-    {
2630
-        $this->_category                = new stdClass();
2631
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2632
-        $this->_category->id            = $this->_category->parent = 0;
2633
-    }
2634
-
2635
-
2636
-    /**
2637
-     * @throws DomainException
2638
-     * @throws EE_Error
2639
-     * @throws InvalidArgumentException
2640
-     * @throws InvalidDataTypeException
2641
-     * @throws InvalidInterfaceException
2642
-     */
2643
-    protected function _category_list_table()
2644
-    {
2645
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2646
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2647
-        $this->_admin_page_title .= ' ';
2648
-        $this->_admin_page_title .= $this->get_action_link_or_button(
2649
-            'add_category',
2650
-            'add_category',
2651
-            [],
2652
-            'add-new-h2'
2653
-        );
2654
-        $this->display_admin_list_table_page_with_sidebar();
2655
-    }
2656
-
2657
-
2658
-    /**
2659
-     * Output category details view.
2660
-     *
2661
-     * @throws EE_Error
2662
-     * @throws EE_Error
2663
-     */
2664
-    protected function _category_details($view)
2665
-    {
2666
-        // load formatter helper
2667
-        // load field generator helper
2668
-        $route = $view === 'edit' ? 'update_category' : 'insert_category';
2669
-        $this->_set_add_edit_form_tags($route);
2670
-        $this->_set_category_object();
2671
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2672
-        $delete_action = 'delete_category';
2673
-        // custom redirect
2674
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2675
-            ['action' => 'category_list'],
2676
-            $this->_admin_base_url
2677
-        );
2678
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2679
-        // take care of contents
2680
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2681
-        $this->display_admin_page_with_sidebar();
2682
-    }
2683
-
2684
-
2685
-    /**
2686
-     * Output category details content.
2687
-     *
2688
-     * @throws DomainException
2689
-     */
2690
-    protected function _category_details_content()
2691
-    {
2692
-        $editor_args['category_desc'] = [
2693
-            'type'          => 'wp_editor',
2694
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2695
-            'class'         => 'my_editor_custom',
2696
-            'wpeditor_args' => ['media_buttons' => false],
2697
-        ];
2698
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2699
-        $all_terms                    = get_terms(
2700
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2701
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2702
-        );
2703
-        // setup category select for term parents.
2704
-        $category_select_values[] = [
2705
-            'text' => esc_html__('No Parent', 'event_espresso'),
2706
-            'id'   => 0,
2707
-        ];
2708
-        foreach ($all_terms as $term) {
2709
-            $category_select_values[] = [
2710
-                'text' => $term->name,
2711
-                'id'   => $term->term_id,
2712
-            ];
2713
-        }
2714
-        $category_select = EEH_Form_Fields::select_input(
2715
-            'category_parent',
2716
-            $category_select_values,
2717
-            $this->_category->parent
2718
-        );
2719
-        $template_args   = [
2720
-            'category'                 => $this->_category,
2721
-            'category_select'          => $category_select,
2722
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2723
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2724
-            'disable'                  => '',
2725
-            'disabled_message'         => false,
2726
-        ];
2727
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2728
-        return EEH_Template::display_template($template, $template_args, true);
2729
-    }
2730
-
2731
-
2732
-    /**
2733
-     * Handles deleting categories.
2734
-     *
2735
-     * @throws EE_Error
2736
-     */
2737
-    protected function _delete_categories()
2738
-    {
2739
-        $category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2740
-        foreach ($category_IDs as $category_ID) {
2741
-            $this->_delete_category($category_ID);
2742
-        }
2743
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2744
-        $query_args = [
2745
-            'action' => 'category_list',
2746
-        ];
2747
-        $this->_redirect_after_action(0, '', '', $query_args);
2748
-    }
2749
-
2750
-
2751
-    /**
2752
-     * Handles deleting specific category.
2753
-     *
2754
-     * @param int $cat_id
2755
-     */
2756
-    protected function _delete_category($cat_id)
2757
-    {
2758
-        $cat_id = absint($cat_id);
2759
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2760
-    }
2761
-
2762
-
2763
-    /**
2764
-     * Handles triggering the update or insertion of a new category.
2765
-     *
2766
-     * @param bool $new_category true means we're triggering the insert of a new category.
2767
-     * @throws EE_Error
2768
-     * @throws EE_Error
2769
-     */
2770
-    protected function _insert_or_update_category($new_category)
2771
-    {
2772
-        $cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2773
-        $success = 0; // we already have a success message so lets not send another.
2774
-        if ($cat_id) {
2775
-            $query_args = [
2776
-                'action'     => 'edit_category',
2777
-                'EVT_CAT_ID' => $cat_id,
2778
-            ];
2779
-        } else {
2780
-            $query_args = ['action' => 'add_category'];
2781
-        }
2782
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2783
-    }
2784
-
2785
-
2786
-    /**
2787
-     * Inserts or updates category
2788
-     *
2789
-     * @param bool $update (true indicates we're updating a category).
2790
-     * @return bool|mixed|string
2791
-     */
2792
-    private function _insert_category($update = false)
2793
-    {
2794
-        $category_ID         = $update ? $this->request->getRequestParam('EVT_CAT_ID', 0, 'int') : 0;
2795
-        $category_name       = $this->request->getRequestParam('category_name', '');
2796
-        $category_desc       = $this->request->getRequestParam('category_desc', '');
2797
-        $category_parent     = $this->request->getRequestParam('category_parent', 0, 'int');
2798
-        $category_identifier = $this->request->getRequestParam('category_identifier', '');
2799
-
2800
-        if (empty($category_name)) {
2801
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2802
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2803
-            return false;
2804
-        }
2805
-        $term_args = [
2806
-            'name'        => $category_name,
2807
-            'description' => $category_desc,
2808
-            'parent'      => $category_parent,
2809
-        ];
2810
-        // was the category_identifier input disabled?
2811
-        if ($category_identifier) {
2812
-            $term_args['slug'] = $category_identifier;
2813
-        }
2814
-        $insert_ids = $update
2815
-            ? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2816
-            : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2817
-        if (! is_array($insert_ids)) {
2818
-            $msg = esc_html__(
2819
-                'An error occurred and the category has not been saved to the database.',
2820
-                'event_espresso'
2821
-            );
2822
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2823
-        } else {
2824
-            $category_ID = $insert_ids['term_id'];
2825
-            $msg         = sprintf(
2826
-                esc_html__('The category %s was successfully saved', 'event_espresso'),
2827
-                $category_name
2828
-            );
2829
-            EE_Error::add_success($msg);
2830
-        }
2831
-        return $category_ID;
2832
-    }
2833
-
2834
-
2835
-    /**
2836
-     * Gets categories or count of categories matching the arguments in the request.
2837
-     *
2838
-     * @param int  $per_page
2839
-     * @param int  $current_page
2840
-     * @param bool $count
2841
-     * @return EE_Term_Taxonomy[]|int
2842
-     * @throws EE_Error
2843
-     */
2844
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2845
-    {
2846
-        // testing term stuff
2847
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2848
-        $order       = $this->request->getRequestParam('order', 'DESC');
2849
-        $limit       = ($current_page - 1) * $per_page;
2850
-        $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2851
-        $search_term = $this->request->getRequestParam('s');
2852
-        if ($search_term) {
2853
-            $search_term = '%' . $search_term . '%';
2854
-            $where['OR'] = [
2855
-                'Term.name'   => ['LIKE', $search_term],
2856
-                'description' => ['LIKE', $search_term],
2857
-            ];
2858
-        }
2859
-        $query_params = [
2860
-            $where,
2861
-            'order_by'   => [$orderby => $order],
2862
-            'limit'      => $limit . ',' . $per_page,
2863
-            'force_join' => ['Term'],
2864
-        ];
2865
-        return $count
2866
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2867
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2868
-    }
2869
-
2870
-    /* end category stuff */
2871
-
2872
-
2873
-    /**************/
2874
-
2875
-
2876
-    /**
2877
-     * Callback for the `ee_save_timezone_setting` ajax action.
2878
-     *
2879
-     * @throws EE_Error
2880
-     * @throws InvalidArgumentException
2881
-     * @throws InvalidDataTypeException
2882
-     * @throws InvalidInterfaceException
2883
-     */
2884
-    public function saveTimezoneString()
2885
-    {
2886
-        $timezone_string = $this->request->getRequestParam('timezone_selected');
2887
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2888
-            EE_Error::add_error(
2889
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2890
-                __FILE__,
2891
-                __FUNCTION__,
2892
-                __LINE__
2893
-            );
2894
-            $this->_template_args['error'] = true;
2895
-            $this->_return_json();
2896
-        }
2897
-
2898
-        update_option('timezone_string', $timezone_string);
2899
-        EE_Error::add_success(
2900
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2901
-        );
2902
-        $this->_template_args['success'] = true;
2903
-        $this->_return_json(true, ['action' => 'create_new']);
2904
-    }
2905
-
2906
-
2907
-    /**
2908 2575
      * @throws EE_Error
2909
-     * @deprecated 4.10.25.p
2910 2576
      */
2911
-    public function save_timezonestring_setting()
2912
-    {
2913
-        $this->saveTimezoneString();
2914
-    }
2577
+	protected function _template_settings()
2578
+	{
2579
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2580
+		$this->_template_args['preview_img']  = '<img src="'
2581
+												. EVENTS_ASSETS_URL
2582
+												. '/images/'
2583
+												. 'caffeinated_template_features.jpg" alt="'
2584
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2585
+												. '" />';
2586
+		$this->_template_args['preview_text'] = '<strong>'
2587
+												. esc_html__(
2588
+													'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2589
+													'event_espresso'
2590
+												) . '</strong>';
2591
+		$this->display_admin_caf_preview_page('template_settings_tab');
2592
+	}
2593
+
2594
+
2595
+	/** Event Category Stuff **/
2596
+	/**
2597
+	 * set the _category property with the category object for the loaded page.
2598
+	 *
2599
+	 * @access private
2600
+	 * @return void
2601
+	 */
2602
+	private function _set_category_object()
2603
+	{
2604
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2605
+			return;
2606
+		} //already have the category object so get out.
2607
+		// set default category object
2608
+		$this->_set_empty_category_object();
2609
+		// only set if we've got an id
2610
+		$category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2611
+		if (! $category_ID) {
2612
+			return;
2613
+		}
2614
+		$term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2615
+		if (! empty($term)) {
2616
+			$this->_category->category_name       = $term->name;
2617
+			$this->_category->category_identifier = $term->slug;
2618
+			$this->_category->category_desc       = $term->description;
2619
+			$this->_category->id                  = $term->term_id;
2620
+			$this->_category->parent              = $term->parent;
2621
+		}
2622
+	}
2623
+
2624
+
2625
+	/**
2626
+	 * Clears out category properties.
2627
+	 */
2628
+	private function _set_empty_category_object()
2629
+	{
2630
+		$this->_category                = new stdClass();
2631
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2632
+		$this->_category->id            = $this->_category->parent = 0;
2633
+	}
2634
+
2635
+
2636
+	/**
2637
+	 * @throws DomainException
2638
+	 * @throws EE_Error
2639
+	 * @throws InvalidArgumentException
2640
+	 * @throws InvalidDataTypeException
2641
+	 * @throws InvalidInterfaceException
2642
+	 */
2643
+	protected function _category_list_table()
2644
+	{
2645
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2646
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2647
+		$this->_admin_page_title .= ' ';
2648
+		$this->_admin_page_title .= $this->get_action_link_or_button(
2649
+			'add_category',
2650
+			'add_category',
2651
+			[],
2652
+			'add-new-h2'
2653
+		);
2654
+		$this->display_admin_list_table_page_with_sidebar();
2655
+	}
2656
+
2657
+
2658
+	/**
2659
+	 * Output category details view.
2660
+	 *
2661
+	 * @throws EE_Error
2662
+	 * @throws EE_Error
2663
+	 */
2664
+	protected function _category_details($view)
2665
+	{
2666
+		// load formatter helper
2667
+		// load field generator helper
2668
+		$route = $view === 'edit' ? 'update_category' : 'insert_category';
2669
+		$this->_set_add_edit_form_tags($route);
2670
+		$this->_set_category_object();
2671
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2672
+		$delete_action = 'delete_category';
2673
+		// custom redirect
2674
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2675
+			['action' => 'category_list'],
2676
+			$this->_admin_base_url
2677
+		);
2678
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2679
+		// take care of contents
2680
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2681
+		$this->display_admin_page_with_sidebar();
2682
+	}
2683
+
2684
+
2685
+	/**
2686
+	 * Output category details content.
2687
+	 *
2688
+	 * @throws DomainException
2689
+	 */
2690
+	protected function _category_details_content()
2691
+	{
2692
+		$editor_args['category_desc'] = [
2693
+			'type'          => 'wp_editor',
2694
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2695
+			'class'         => 'my_editor_custom',
2696
+			'wpeditor_args' => ['media_buttons' => false],
2697
+		];
2698
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2699
+		$all_terms                    = get_terms(
2700
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2701
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2702
+		);
2703
+		// setup category select for term parents.
2704
+		$category_select_values[] = [
2705
+			'text' => esc_html__('No Parent', 'event_espresso'),
2706
+			'id'   => 0,
2707
+		];
2708
+		foreach ($all_terms as $term) {
2709
+			$category_select_values[] = [
2710
+				'text' => $term->name,
2711
+				'id'   => $term->term_id,
2712
+			];
2713
+		}
2714
+		$category_select = EEH_Form_Fields::select_input(
2715
+			'category_parent',
2716
+			$category_select_values,
2717
+			$this->_category->parent
2718
+		);
2719
+		$template_args   = [
2720
+			'category'                 => $this->_category,
2721
+			'category_select'          => $category_select,
2722
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2723
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2724
+			'disable'                  => '',
2725
+			'disabled_message'         => false,
2726
+		];
2727
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2728
+		return EEH_Template::display_template($template, $template_args, true);
2729
+	}
2730
+
2731
+
2732
+	/**
2733
+	 * Handles deleting categories.
2734
+	 *
2735
+	 * @throws EE_Error
2736
+	 */
2737
+	protected function _delete_categories()
2738
+	{
2739
+		$category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2740
+		foreach ($category_IDs as $category_ID) {
2741
+			$this->_delete_category($category_ID);
2742
+		}
2743
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2744
+		$query_args = [
2745
+			'action' => 'category_list',
2746
+		];
2747
+		$this->_redirect_after_action(0, '', '', $query_args);
2748
+	}
2749
+
2750
+
2751
+	/**
2752
+	 * Handles deleting specific category.
2753
+	 *
2754
+	 * @param int $cat_id
2755
+	 */
2756
+	protected function _delete_category($cat_id)
2757
+	{
2758
+		$cat_id = absint($cat_id);
2759
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2760
+	}
2761
+
2762
+
2763
+	/**
2764
+	 * Handles triggering the update or insertion of a new category.
2765
+	 *
2766
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2767
+	 * @throws EE_Error
2768
+	 * @throws EE_Error
2769
+	 */
2770
+	protected function _insert_or_update_category($new_category)
2771
+	{
2772
+		$cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2773
+		$success = 0; // we already have a success message so lets not send another.
2774
+		if ($cat_id) {
2775
+			$query_args = [
2776
+				'action'     => 'edit_category',
2777
+				'EVT_CAT_ID' => $cat_id,
2778
+			];
2779
+		} else {
2780
+			$query_args = ['action' => 'add_category'];
2781
+		}
2782
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2783
+	}
2784
+
2785
+
2786
+	/**
2787
+	 * Inserts or updates category
2788
+	 *
2789
+	 * @param bool $update (true indicates we're updating a category).
2790
+	 * @return bool|mixed|string
2791
+	 */
2792
+	private function _insert_category($update = false)
2793
+	{
2794
+		$category_ID         = $update ? $this->request->getRequestParam('EVT_CAT_ID', 0, 'int') : 0;
2795
+		$category_name       = $this->request->getRequestParam('category_name', '');
2796
+		$category_desc       = $this->request->getRequestParam('category_desc', '');
2797
+		$category_parent     = $this->request->getRequestParam('category_parent', 0, 'int');
2798
+		$category_identifier = $this->request->getRequestParam('category_identifier', '');
2799
+
2800
+		if (empty($category_name)) {
2801
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2802
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2803
+			return false;
2804
+		}
2805
+		$term_args = [
2806
+			'name'        => $category_name,
2807
+			'description' => $category_desc,
2808
+			'parent'      => $category_parent,
2809
+		];
2810
+		// was the category_identifier input disabled?
2811
+		if ($category_identifier) {
2812
+			$term_args['slug'] = $category_identifier;
2813
+		}
2814
+		$insert_ids = $update
2815
+			? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2816
+			: wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2817
+		if (! is_array($insert_ids)) {
2818
+			$msg = esc_html__(
2819
+				'An error occurred and the category has not been saved to the database.',
2820
+				'event_espresso'
2821
+			);
2822
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2823
+		} else {
2824
+			$category_ID = $insert_ids['term_id'];
2825
+			$msg         = sprintf(
2826
+				esc_html__('The category %s was successfully saved', 'event_espresso'),
2827
+				$category_name
2828
+			);
2829
+			EE_Error::add_success($msg);
2830
+		}
2831
+		return $category_ID;
2832
+	}
2833
+
2834
+
2835
+	/**
2836
+	 * Gets categories or count of categories matching the arguments in the request.
2837
+	 *
2838
+	 * @param int  $per_page
2839
+	 * @param int  $current_page
2840
+	 * @param bool $count
2841
+	 * @return EE_Term_Taxonomy[]|int
2842
+	 * @throws EE_Error
2843
+	 */
2844
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2845
+	{
2846
+		// testing term stuff
2847
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2848
+		$order       = $this->request->getRequestParam('order', 'DESC');
2849
+		$limit       = ($current_page - 1) * $per_page;
2850
+		$where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2851
+		$search_term = $this->request->getRequestParam('s');
2852
+		if ($search_term) {
2853
+			$search_term = '%' . $search_term . '%';
2854
+			$where['OR'] = [
2855
+				'Term.name'   => ['LIKE', $search_term],
2856
+				'description' => ['LIKE', $search_term],
2857
+			];
2858
+		}
2859
+		$query_params = [
2860
+			$where,
2861
+			'order_by'   => [$orderby => $order],
2862
+			'limit'      => $limit . ',' . $per_page,
2863
+			'force_join' => ['Term'],
2864
+		];
2865
+		return $count
2866
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2867
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2868
+	}
2869
+
2870
+	/* end category stuff */
2871
+
2872
+
2873
+	/**************/
2874
+
2875
+
2876
+	/**
2877
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2878
+	 *
2879
+	 * @throws EE_Error
2880
+	 * @throws InvalidArgumentException
2881
+	 * @throws InvalidDataTypeException
2882
+	 * @throws InvalidInterfaceException
2883
+	 */
2884
+	public function saveTimezoneString()
2885
+	{
2886
+		$timezone_string = $this->request->getRequestParam('timezone_selected');
2887
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2888
+			EE_Error::add_error(
2889
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2890
+				__FILE__,
2891
+				__FUNCTION__,
2892
+				__LINE__
2893
+			);
2894
+			$this->_template_args['error'] = true;
2895
+			$this->_return_json();
2896
+		}
2897
+
2898
+		update_option('timezone_string', $timezone_string);
2899
+		EE_Error::add_success(
2900
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2901
+		);
2902
+		$this->_template_args['success'] = true;
2903
+		$this->_return_json(true, ['action' => 'create_new']);
2904
+	}
2905
+
2906
+
2907
+	/**
2908
+	 * @throws EE_Error
2909
+	 * @deprecated 4.10.25.p
2910
+	 */
2911
+	public function save_timezonestring_setting()
2912
+	{
2913
+		$this->saveTimezoneString();
2914
+	}
2915 2915
 }
Please login to merge, or discard this patch.
Spacing   +88 added lines, -88 removed lines patch added patch discarded remove patch
@@ -587,13 +587,13 @@  discard block
 block discarded – undo
587 587
     {
588 588
         wp_register_style(
589 589
             'events-admin-css',
590
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
590
+            EVENTS_ASSETS_URL.'events-admin-page.css',
591 591
             [],
592 592
             EVENT_ESPRESSO_VERSION
593 593
         );
594 594
         wp_register_style(
595 595
             'ee-cat-admin',
596
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
596
+            EVENTS_ASSETS_URL.'ee-cat-admin.css',
597 597
             [],
598 598
             EVENT_ESPRESSO_VERSION
599 599
         );
@@ -602,7 +602,7 @@  discard block
 block discarded – undo
602 602
         // scripts
603 603
         wp_register_script(
604 604
             'event_editor_js',
605
-            EVENTS_ASSETS_URL . 'event_editor.js',
605
+            EVENTS_ASSETS_URL.'event_editor.js',
606 606
             ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
607 607
             EVENT_ESPRESSO_VERSION,
608 608
             true
@@ -628,16 +628,16 @@  discard block
 block discarded – undo
628 628
         wp_enqueue_style('espresso-ui-theme');
629 629
         wp_register_style(
630 630
             'event-editor-css',
631
-            EVENTS_ASSETS_URL . 'event-editor.css',
631
+            EVENTS_ASSETS_URL.'event-editor.css',
632 632
             ['ee-admin-css'],
633 633
             EVENT_ESPRESSO_VERSION
634 634
         );
635 635
         wp_enqueue_style('event-editor-css');
636 636
         // scripts
637
-        if (! $this->admin_config->useAdvancedEditor()) {
637
+        if ( ! $this->admin_config->useAdvancedEditor()) {
638 638
             wp_register_script(
639 639
                 'event-datetime-metabox',
640
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
640
+                EVENTS_ASSETS_URL.'event-datetime-metabox.js',
641 641
                 ['event_editor_js', 'ee-datepicker'],
642 642
                 EVENT_ESPRESSO_VERSION
643 643
             );
@@ -707,15 +707,15 @@  discard block
 block discarded – undo
707 707
     public function verify_event_edit($event = null, $req_type = '')
708 708
     {
709 709
         // don't need to do this when processing
710
-        if (! empty($req_type)) {
710
+        if ( ! empty($req_type)) {
711 711
             return;
712 712
         }
713 713
         // no event?
714
-        if (! $event instanceof EE_Event) {
714
+        if ( ! $event instanceof EE_Event) {
715 715
             $event = $this->_cpt_model_obj;
716 716
         }
717 717
         // STILL no event?
718
-        if (! $event instanceof EE_Event) {
718
+        if ( ! $event instanceof EE_Event) {
719 719
             return;
720 720
         }
721 721
         $orig_status = $event->status();
@@ -755,7 +755,7 @@  discard block
 block discarded – undo
755 755
             );
756 756
         }
757 757
         // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
758
-        if (! $event->tickets_on_sale()) {
758
+        if ( ! $event->tickets_on_sale()) {
759 759
             return;
760 760
         }
761 761
         // made it here so show warning
@@ -803,7 +803,7 @@  discard block
 block discarded – undo
803 803
     {
804 804
         $has_timezone_string = get_option('timezone_string');
805 805
         // only nag them about setting their timezone if it's their first event, and they haven't already done it
806
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
806
+        if ( ! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
807 807
             EE_Error::add_attention(
808 808
                 sprintf(
809 809
                     esc_html__(
@@ -872,7 +872,7 @@  discard block
 block discarded – undo
872 872
      */
873 873
     protected function _event_legend_items()
874 874
     {
875
-        $items    = [
875
+        $items = [
876 876
             'view_details'   => [
877 877
                 'class' => 'dashicons dashicons-search',
878 878
                 'desc'  => esc_html__('View Event', 'event_espresso'),
@@ -889,31 +889,31 @@  discard block
 block discarded – undo
889 889
         $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
890 890
         $statuses = [
891 891
             'sold_out_status'  => [
892
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::sold_out,
892
+                'class' => 'ee-status-legend ee-status-legend--'.EE_Datetime::sold_out,
893 893
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
894 894
             ],
895 895
             'active_status'    => [
896
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::active,
896
+                'class' => 'ee-status-legend ee-status-legend--'.EE_Datetime::active,
897 897
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
898 898
             ],
899 899
             'upcoming_status'  => [
900
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::upcoming,
900
+                'class' => 'ee-status-legend ee-status-legend--'.EE_Datetime::upcoming,
901 901
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
902 902
             ],
903 903
             'postponed_status' => [
904
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::postponed,
904
+                'class' => 'ee-status-legend ee-status-legend--'.EE_Datetime::postponed,
905 905
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
906 906
             ],
907 907
             'cancelled_status' => [
908
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::cancelled,
908
+                'class' => 'ee-status-legend ee-status-legend--'.EE_Datetime::cancelled,
909 909
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
910 910
             ],
911 911
             'expired_status'   => [
912
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::expired,
912
+                'class' => 'ee-status-legend ee-status-legend--'.EE_Datetime::expired,
913 913
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
914 914
             ],
915 915
             'inactive_status'  => [
916
-                'class' => 'ee-status-legend ee-status-legend--' . EE_Datetime::inactive,
916
+                'class' => 'ee-status-legend ee-status-legend--'.EE_Datetime::inactive,
917 917
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
918 918
             ],
919 919
         ];
@@ -932,7 +932,7 @@  discard block
 block discarded – undo
932 932
      */
933 933
     private function _event_model()
934 934
     {
935
-        if (! $this->_event_model instanceof EEM_Event) {
935
+        if ( ! $this->_event_model instanceof EEM_Event) {
936 936
             $this->_event_model = EE_Registry::instance()->load_model('Event');
937 937
         }
938 938
         return $this->_event_model;
@@ -952,7 +952,7 @@  discard block
 block discarded – undo
952 952
     public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
953 953
     {
954 954
         // make sure this is only when editing
955
-        if (! empty($id)) {
955
+        if ( ! empty($id)) {
956 956
             $post = get_post($id);
957 957
             $return .= '<a class="button button--secondary" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
958 958
                        . esc_html__('Shortcode', 'event_espresso')
@@ -987,14 +987,14 @@  discard block
 block discarded – undo
987 987
             esc_html__('View Event Archive Page', 'event_espresso'),
988 988
             'button'
989 989
         );
990
-        $after_list_table['legend']                 = $this->_display_legend($this->_event_legend_items());
991
-        $this->_admin_page_title                    .= ' ' . $this->get_action_link_or_button(
990
+        $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
991
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
992 992
             'create_new',
993 993
             'add',
994 994
             [],
995 995
             'add-new-h2'
996 996
         );
997
-        $this->_template_args['after_list_table']   = array_merge(
997
+        $this->_template_args['after_list_table'] = array_merge(
998 998
             (array) $this->_template_args['after_list_table'],
999 999
             $after_list_table
1000 1000
         );
@@ -1051,13 +1051,13 @@  discard block
 block discarded – undo
1051 1051
             'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1052 1052
         ];
1053 1053
         // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1054
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1055
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1054
+        if ( ! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1055
+            $event_values['EVT_display_ticket_selector'] = $this->request->getRequestParam(
1056 1056
                 'display_ticket_selector',
1057 1057
                 false,
1058 1058
                 'bool'
1059 1059
             );
1060
-            $event_values['EVT_additional_limit']            = min(
1060
+            $event_values['EVT_additional_limit'] = min(
1061 1061
                 apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1062 1062
                 $this->request->getRequestParam('additional_limit', null, 'int')
1063 1063
             );
@@ -1093,7 +1093,7 @@  discard block
 block discarded – undo
1093 1093
         // the following are default callbacks for event attachment updates
1094 1094
         // that can be overridden by caffeinated functionality and/or addons.
1095 1095
         $event_update_callbacks = [];
1096
-        if (! $this->admin_config->useAdvancedEditor()) {
1096
+        if ( ! $this->admin_config->useAdvancedEditor()) {
1097 1097
             $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1098 1098
             $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1099 1099
         }
@@ -1164,7 +1164,7 @@  discard block
 block discarded – undo
1164 1164
      */
1165 1165
     protected function _default_venue_update(EE_Event $event, $data)
1166 1166
     {
1167
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1167
+        require_once(EE_MODELS.'EEM_Venue.model.php');
1168 1168
         $venue_model = EE_Registry::instance()->load_model('Venue');
1169 1169
         $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1170 1170
         // very important.  If we don't have a venue name...
@@ -1195,7 +1195,7 @@  discard block
 block discarded – undo
1195 1195
             'status'              => 'publish',
1196 1196
         ];
1197 1197
         // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1198
-        if (! empty($venue_id)) {
1198
+        if ( ! empty($venue_id)) {
1199 1199
             $update_where  = [$venue_model->primary_key_name() => $venue_id];
1200 1200
             $rows_affected = $venue_model->update($venue_array, [$update_where]);
1201 1201
             // we've gotta make sure that the venue is always attached to a revision..
@@ -1237,7 +1237,7 @@  discard block
 block discarded – undo
1237 1237
                 isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1238 1238
                     ? $datetime_data['DTT_EVT_end']
1239 1239
                     : $datetime_data['DTT_EVT_start'];
1240
-            $datetime_values              = [
1240
+            $datetime_values = [
1241 1241
                 'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1242 1242
                 'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1243 1243
                 'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
@@ -1246,9 +1246,9 @@  discard block
 block discarded – undo
1246 1246
             ];
1247 1247
             // if we have an id then let's get existing object first and then set the new values.
1248 1248
             //  Otherwise we instantiate a new object for save.
1249
-            if (! empty($datetime_data['DTT_ID'])) {
1249
+            if ( ! empty($datetime_data['DTT_ID'])) {
1250 1250
                 $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1251
-                if (! $datetime instanceof EE_Ticket) {
1251
+                if ( ! $datetime instanceof EE_Ticket) {
1252 1252
                     throw new RuntimeException(
1253 1253
                         sprintf(
1254 1254
                             esc_html__(
@@ -1267,7 +1267,7 @@  discard block
 block discarded – undo
1267 1267
             } else {
1268 1268
                 $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1269 1269
             }
1270
-            if (! $datetime instanceof EE_Datetime) {
1270
+            if ( ! $datetime instanceof EE_Datetime) {
1271 1271
                 throw new RuntimeException(
1272 1272
                     sprintf(
1273 1273
                         esc_html__(
@@ -1293,7 +1293,7 @@  discard block
 block discarded – undo
1293 1293
 
1294 1294
         // set up some default start and end dates in case those are not present in the incoming data
1295 1295
         $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1296
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1296
+        $default_start_date = $default_start_date->format($date_formats[0].' '.$date_formats[1]);
1297 1297
         // use the start date of the first datetime for the end date
1298 1298
         $first_datetime   = $event->first_datetime();
1299 1299
         $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
@@ -1301,8 +1301,8 @@  discard block
 block discarded – undo
1301 1301
         // now process the incoming data
1302 1302
         foreach ($data['edit_tickets'] as $row => $ticket_data) {
1303 1303
             $update_prices = false;
1304
-            $ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1305
-                ? $data['edit_prices'][ $row ][1]['PRC_amount']
1304
+            $ticket_price  = isset($data['edit_prices'][$row][1]['PRC_amount'])
1305
+                ? $data['edit_prices'][$row][1]['PRC_amount']
1306 1306
                 : 0;
1307 1307
             // trim inputs to ensure any excess whitespace is removed.
1308 1308
             $ticket_data   = array_map('trim', $ticket_data);
@@ -1343,9 +1343,9 @@  discard block
 block discarded – undo
1343 1343
             // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1344 1344
             // keep in mind that if the ticket has been sold (and we have changed pricing information),
1345 1345
             // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1346
-            if (! empty($ticket_data['TKT_ID'])) {
1346
+            if ( ! empty($ticket_data['TKT_ID'])) {
1347 1347
                 $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1348
-                if (! $existing_ticket instanceof EE_Ticket) {
1348
+                if ( ! $existing_ticket instanceof EE_Ticket) {
1349 1349
                     throw new RuntimeException(
1350 1350
                         sprintf(
1351 1351
                             esc_html__(
@@ -1394,7 +1394,7 @@  discard block
 block discarded – undo
1394 1394
                     $existing_ticket->save();
1395 1395
                     // make sure this ticket is still recorded in our $saved_tickets
1396 1396
                     // so we don't run it through the regular trash routine.
1397
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1397
+                    $saved_tickets[$existing_ticket->ID()] = $existing_ticket;
1398 1398
                     // create new ticket that's a copy of the existing except,
1399 1399
                     // (a new id of course and not archived) AND has the new TKT_price associated with it.
1400 1400
                     $new_ticket = clone $existing_ticket;
@@ -1411,7 +1411,7 @@  discard block
 block discarded – undo
1411 1411
                 $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1412 1412
                 $update_prices              = true;
1413 1413
             }
1414
-            if (! $ticket instanceof EE_Ticket) {
1414
+            if ( ! $ticket instanceof EE_Ticket) {
1415 1415
                 throw new RuntimeException(
1416 1416
                     sprintf(
1417 1417
                         esc_html__(
@@ -1435,9 +1435,9 @@  discard block
 block discarded – undo
1435 1435
             }
1436 1436
             // initially let's add the ticket to the datetime
1437 1437
             $datetime->_add_relation_to($ticket, 'Ticket');
1438
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1438
+            $saved_tickets[$ticket->ID()] = $ticket;
1439 1439
             // add prices to ticket
1440
-            $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $ticket, $update_prices);
1440
+            $this->_add_prices_to_ticket($data['edit_prices'][$row], $ticket, $update_prices);
1441 1441
         }
1442 1442
         // however now we need to handle permanently deleting tickets via the ui.
1443 1443
         //  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
@@ -1449,7 +1449,7 @@  discard block
 block discarded – undo
1449 1449
             $id = absint($id);
1450 1450
             // get the ticket for this id
1451 1451
             $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1452
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1452
+            if ( ! $ticket_to_remove instanceof EE_Ticket) {
1453 1453
                 continue;
1454 1454
             }
1455 1455
             // need to get all the related datetimes on this ticket and remove from every single one of them
@@ -1506,7 +1506,7 @@  discard block
 block discarded – undo
1506 1506
                     $price->set($field, $new_price);
1507 1507
                 }
1508 1508
             }
1509
-            if (! $price instanceof EE_Price) {
1509
+            if ( ! $price instanceof EE_Price) {
1510 1510
                 throw new RuntimeException(
1511 1511
                     sprintf(
1512 1512
                         esc_html__(
@@ -1548,13 +1548,13 @@  discard block
 block discarded – undo
1548 1548
     {
1549 1549
         // load formatter helper
1550 1550
         // args for getting related registrations
1551
-        $approved_query_args        = [
1551
+        $approved_query_args = [
1552 1552
             [
1553 1553
                 'REG_deleted' => 0,
1554 1554
                 'STS_ID'      => EEM_Registration::status_id_approved,
1555 1555
             ],
1556 1556
         ];
1557
-        $not_approved_query_args    = [
1557
+        $not_approved_query_args = [
1558 1558
             [
1559 1559
                 'REG_deleted' => 0,
1560 1560
                 'STS_ID'      => EEM_Registration::status_id_not_approved,
@@ -1617,7 +1617,7 @@  discard block
 block discarded – undo
1617 1617
         $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1618 1618
         // load template
1619 1619
         EEH_Template::display_template(
1620
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1620
+            EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php',
1621 1621
             $publish_box_extra_args
1622 1622
         );
1623 1623
     }
@@ -1648,7 +1648,7 @@  discard block
 block discarded – undo
1648 1648
         $this->verify_cpt_object();
1649 1649
         $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1650 1650
         // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1651
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1651
+        if ( ! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1652 1652
             $this->addMetaBox(
1653 1653
                 'espresso_event_editor_event_options',
1654 1654
                 esc_html__('Event Registration Options', 'event_espresso'),
@@ -1657,7 +1657,7 @@  discard block
 block discarded – undo
1657 1657
                 'side'
1658 1658
             );
1659 1659
         }
1660
-        if (! $use_advanced_editor) {
1660
+        if ( ! $use_advanced_editor) {
1661 1661
             $this->addMetaBox(
1662 1662
                 'espresso_event_editor_tickets',
1663 1663
                 esc_html__('Event Datetime & Ticket', 'event_espresso'),
@@ -1669,7 +1669,7 @@  discard block
 block discarded – undo
1669 1669
         } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1670 1670
             add_action(
1671 1671
                 'add_meta_boxes_espresso_events',
1672
-                function () {
1672
+                function() {
1673 1673
                     global $current_screen;
1674 1674
                     remove_meta_box('authordiv', $current_screen, 'normal');
1675 1675
                 },
@@ -1704,7 +1704,7 @@  discard block
 block discarded – undo
1704 1704
             'trash_icon'               => 'dashicons dashicons-lock',
1705 1705
             'disabled'                 => '',
1706 1706
         ];
1707
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1707
+        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1708 1708
         /**
1709 1709
          * 1. Start with retrieving Datetimes
1710 1710
          * 2. Fore each datetime get related tickets
@@ -1730,24 +1730,24 @@  discard block
 block discarded – undo
1730 1730
                     'default_where_conditions' => 'none',
1731 1731
                 ]
1732 1732
             );
1733
-            if (! empty($related_tickets)) {
1733
+            if ( ! empty($related_tickets)) {
1734 1734
                 $template_args['total_ticket_rows'] = count($related_tickets);
1735 1735
                 $row                                = 0;
1736 1736
                 foreach ($related_tickets as $ticket) {
1737
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1737
+                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1738 1738
                     $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1739 1739
                     $row++;
1740 1740
                 }
1741 1741
             } else {
1742 1742
                 $template_args['total_ticket_rows'] = 1;
1743 1743
                 /** @type EE_Ticket $ticket */
1744
-                $ticket                       = $ticket_model->create_default_object();
1744
+                $ticket = $ticket_model->create_default_object();
1745 1745
                 $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1746 1746
             }
1747 1747
         } else {
1748 1748
             $template_args['time'] = $times[0];
1749 1749
             /** @type EE_Ticket[] $tickets */
1750
-            $tickets                      = $ticket_model->get_all_default_tickets();
1750
+            $tickets = $ticket_model->get_all_default_tickets();
1751 1751
             $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1752 1752
             // NOTE: we're just sending the first default row
1753 1753
             // (decaf can't manage default tickets so this should be sufficient);
@@ -1762,9 +1762,9 @@  discard block
 block discarded – undo
1762 1762
             $ticket_model->create_default_object(),
1763 1763
             true
1764 1764
         );
1765
-        $template                                  = apply_filters(
1765
+        $template = apply_filters(
1766 1766
             'FHEE__Events_Admin_Page__ticket_metabox__template',
1767
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1767
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php'
1768 1768
         );
1769 1769
         EEH_Template::display_template($template, $template_args);
1770 1770
     }
@@ -1784,7 +1784,7 @@  discard block
 block discarded – undo
1784 1784
     private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1785 1785
     {
1786 1786
         $template_args = [
1787
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1787
+            'tkt_status_class'    => ' tkt-status-'.$ticket->ticket_status(),
1788 1788
             'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1789 1789
                 : '',
1790 1790
             'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
@@ -1796,10 +1796,10 @@  discard block
 block discarded – undo
1796 1796
             'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1797 1797
             'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1798 1798
             'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1799
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1800
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1799
+            'trash_icon'          => ($skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')))
1800
+                                     && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1801 1801
                 ? 'trash-icon dashicons dashicons-post-trash clickable' : 'dashicons dashicons-lock',
1802
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1802
+            'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1803 1803
                 : ' disabled=disabled',
1804 1804
         ];
1805 1805
         $price         = $ticket->ID() !== 0
@@ -1823,7 +1823,7 @@  discard block
 block discarded – undo
1823 1823
         }
1824 1824
         if (empty($template_args['TKT_end_date'])) {
1825 1825
             // get the earliest datetime (if present);
1826
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1826
+            $earliest_datetime = $this->_cpt_model_obj->ID() > 0
1827 1827
                 ? $this->_cpt_model_obj->get_first_related(
1828 1828
                     'Datetime',
1829 1829
                     ['order_by' => ['DTT_EVT_start' => 'ASC']]
@@ -1836,7 +1836,7 @@  discard block
 block discarded – undo
1836 1836
         $template_args = array_merge($template_args, $price_args);
1837 1837
         $template      = apply_filters(
1838 1838
             'FHEE__Events_Admin_Page__get_ticket_row__template',
1839
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1839
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php',
1840 1840
             $ticket
1841 1841
         );
1842 1842
         return EEH_Template::display_template($template, $template_args, true);
@@ -1849,7 +1849,7 @@  discard block
 block discarded – undo
1849 1849
      */
1850 1850
     public function registration_options_meta_box()
1851 1851
     {
1852
-        $yes_no_values             = [
1852
+        $yes_no_values = [
1853 1853
             ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1854 1854
             ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1855 1855
         ];
@@ -1871,12 +1871,12 @@  discard block
 block discarded – undo
1871 1871
             $default_reg_status_values,
1872 1872
             $this->_cpt_model_obj->default_registration_status()
1873 1873
         );
1874
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1874
+        $template_args['display_description'] = EEH_Form_Fields::select_input(
1875 1875
             'display_desc',
1876 1876
             $yes_no_values,
1877 1877
             $this->_cpt_model_obj->display_description()
1878 1878
         );
1879
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1879
+        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1880 1880
             'display_ticket_selector',
1881 1881
             $yes_no_values,
1882 1882
             $this->_cpt_model_obj->display_ticket_selector(),
@@ -1892,7 +1892,7 @@  discard block
 block discarded – undo
1892 1892
             $default_reg_status_values
1893 1893
         );
1894 1894
         EEH_Template::display_template(
1895
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1895
+            EVENTS_TEMPLATE_PATH.'event_registration_options.template.php',
1896 1896
             $template_args
1897 1897
         );
1898 1898
     }
@@ -1915,7 +1915,7 @@  discard block
 block discarded – undo
1915 1915
     {
1916 1916
         $EEM_Event   = $this->_event_model();
1917 1917
         $offset      = ($current_page - 1) * $per_page;
1918
-        $limit       = $count ? null : $offset . ',' . $per_page;
1918
+        $limit       = $count ? null : $offset.','.$per_page;
1919 1919
         $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1920 1920
         $order       = $this->request->getRequestParam('order', 'DESC');
1921 1921
         $month_range = $this->request->getRequestParam('month_range');
@@ -1952,10 +1952,10 @@  discard block
 block discarded – undo
1952 1952
         $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1953 1953
         if ($month_range) {
1954 1954
             $DateTime = new DateTime(
1955
-                $year_r . '-' . $month_r . '-01 00:00:00',
1955
+                $year_r.'-'.$month_r.'-01 00:00:00',
1956 1956
                 new DateTimeZone('UTC')
1957 1957
             );
1958
-            $start    = $DateTime->getTimestamp();
1958
+            $start = $DateTime->getTimestamp();
1959 1959
             // set the datetime to be the end of the month
1960 1960
             $DateTime->setDate(
1961 1961
                 $year_r,
@@ -1980,11 +1980,11 @@  discard block
 block discarded – undo
1980 1980
                                                         ->format(implode(' ', $start_formats));
1981 1981
             $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1982 1982
         }
1983
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1983
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1984 1984
             $where['EVT_wp_user'] = get_current_user_id();
1985 1985
         } else {
1986
-            if (! isset($where['status'])) {
1987
-                if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1986
+            if ( ! isset($where['status'])) {
1987
+                if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1988 1988
                     $where['OR'] = [
1989 1989
                         'status*restrict_private' => ['!=', 'private'],
1990 1990
                         'AND'                     => [
@@ -2006,7 +2006,7 @@  discard block
 block discarded – undo
2006 2006
         // search query handling
2007 2007
         $search_term = $this->request->getRequestParam('s');
2008 2008
         if ($search_term) {
2009
-            $search_term = '%' . $search_term . '%';
2009
+            $search_term = '%'.$search_term.'%';
2010 2010
             $where['OR'] = [
2011 2011
                 'EVT_name'       => ['LIKE', $search_term],
2012 2012
                 'EVT_desc'       => ['LIKE', $search_term],
@@ -2114,7 +2114,7 @@  discard block
 block discarded – undo
2114 2114
             // clean status
2115 2115
             $event_status = sanitize_key($event_status);
2116 2116
             // grab status
2117
-            if (! empty($event_status)) {
2117
+            if ( ! empty($event_status)) {
2118 2118
                 $success = $this->_change_event_status($EVT_ID, $event_status);
2119 2119
             } else {
2120 2120
                 $success = false;
@@ -2154,7 +2154,7 @@  discard block
 block discarded – undo
2154 2154
         // clean status
2155 2155
         $event_status = sanitize_key($event_status);
2156 2156
         // grab status
2157
-        if (! empty($event_status)) {
2157
+        if ( ! empty($event_status)) {
2158 2158
             $success = true;
2159 2159
             // determine the event id and set to array.
2160 2160
             $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
@@ -2200,7 +2200,7 @@  discard block
 block discarded – undo
2200 2200
     private function _change_event_status($EVT_ID = 0, $event_status = '')
2201 2201
     {
2202 2202
         // grab event id
2203
-        if (! $EVT_ID) {
2203
+        if ( ! $EVT_ID) {
2204 2204
             $msg = esc_html__(
2205 2205
                 'An error occurred. No Event ID or an invalid Event ID was received.',
2206 2206
                 'event_espresso'
@@ -2237,7 +2237,7 @@  discard block
 block discarded – undo
2237 2237
         // use class to change status
2238 2238
         $this->_cpt_model_obj->set_status($event_status);
2239 2239
         $success = $this->_cpt_model_obj->save();
2240
-        if (! $success) {
2240
+        if ( ! $success) {
2241 2241
             $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2242 2242
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2243 2243
             return false;
@@ -2295,7 +2295,7 @@  discard block
 block discarded – undo
2295 2295
      */
2296 2296
     protected function getModelObjNodeGroupPersister()
2297 2297
     {
2298
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2298
+        if ( ! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2299 2299
             $this->model_obj_node_group_persister =
2300 2300
                 $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2301 2301
         }
@@ -2587,7 +2587,7 @@  discard block
 block discarded – undo
2587 2587
                                                 . esc_html__(
2588 2588
                                                     'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2589 2589
                                                     'event_espresso'
2590
-                                                ) . '</strong>';
2590
+                                                ).'</strong>';
2591 2591
         $this->display_admin_caf_preview_page('template_settings_tab');
2592 2592
     }
2593 2593
 
@@ -2608,11 +2608,11 @@  discard block
 block discarded – undo
2608 2608
         $this->_set_empty_category_object();
2609 2609
         // only set if we've got an id
2610 2610
         $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2611
-        if (! $category_ID) {
2611
+        if ( ! $category_ID) {
2612 2612
             return;
2613 2613
         }
2614 2614
         $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2615
-        if (! empty($term)) {
2615
+        if ( ! empty($term)) {
2616 2616
             $this->_category->category_name       = $term->name;
2617 2617
             $this->_category->category_identifier = $term->slug;
2618 2618
             $this->_category->category_desc       = $term->description;
@@ -2716,7 +2716,7 @@  discard block
 block discarded – undo
2716 2716
             $category_select_values,
2717 2717
             $this->_category->parent
2718 2718
         );
2719
-        $template_args   = [
2719
+        $template_args = [
2720 2720
             'category'                 => $this->_category,
2721 2721
             'category_select'          => $category_select,
2722 2722
             'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
@@ -2724,7 +2724,7 @@  discard block
 block discarded – undo
2724 2724
             'disable'                  => '',
2725 2725
             'disabled_message'         => false,
2726 2726
         ];
2727
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2727
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
2728 2728
         return EEH_Template::display_template($template, $template_args, true);
2729 2729
     }
2730 2730
 
@@ -2814,7 +2814,7 @@  discard block
 block discarded – undo
2814 2814
         $insert_ids = $update
2815 2815
             ? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2816 2816
             : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2817
-        if (! is_array($insert_ids)) {
2817
+        if ( ! is_array($insert_ids)) {
2818 2818
             $msg = esc_html__(
2819 2819
                 'An error occurred and the category has not been saved to the database.',
2820 2820
                 'event_espresso'
@@ -2850,7 +2850,7 @@  discard block
 block discarded – undo
2850 2850
         $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2851 2851
         $search_term = $this->request->getRequestParam('s');
2852 2852
         if ($search_term) {
2853
-            $search_term = '%' . $search_term . '%';
2853
+            $search_term = '%'.$search_term.'%';
2854 2854
             $where['OR'] = [
2855 2855
                 'Term.name'   => ['LIKE', $search_term],
2856 2856
                 'description' => ['LIKE', $search_term],
@@ -2859,7 +2859,7 @@  discard block
 block discarded – undo
2859 2859
         $query_params = [
2860 2860
             $where,
2861 2861
             'order_by'   => [$orderby => $order],
2862
-            'limit'      => $limit . ',' . $per_page,
2862
+            'limit'      => $limit.','.$per_page,
2863 2863
             'force_join' => ['Term'],
2864 2864
         ];
2865 2865
         return $count
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page.core.php 2 patches
Indentation   +4551 added lines, -4551 removed lines patch added patch discarded remove patch
@@ -17,2658 +17,2658 @@  discard block
 block discarded – undo
17 17
 class Messages_Admin_Page extends EE_Admin_Page
18 18
 {
19 19
 
20
-    /**
21
-     * @type EE_Message_Resource_Manager $_message_resource_manager
22
-     */
23
-    protected $_message_resource_manager;
20
+	/**
21
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
22
+	 */
23
+	protected $_message_resource_manager;
24 24
 
25
-    /**
26
-     * @type string $_active_message_type_name
27
-     */
28
-    protected $_active_message_type_name = '';
29
-
30
-    /**
31
-     * @type EE_messenger $_active_messenger
32
-     */
33
-    protected $_active_messenger;
34
-
35
-    protected $_activate_state;
36
-
37
-    protected $_activate_meta_box_type;
38
-
39
-    protected $_current_message_meta_box;
40
-
41
-    protected $_current_message_meta_box_object;
42
-
43
-    protected $_context_switcher;
44
-
45
-    protected $_shortcodes           = [];
46
-
47
-    protected $_active_messengers    = [];
48
-
49
-    protected $_active_message_types = [];
50
-
51
-    /**
52
-     * @var EE_Message_Template_Group $_message_template_group
53
-     */
54
-    protected $_message_template_group;
55
-
56
-    protected $_m_mt_settings = [];
57
-
58
-
59
-    /**
60
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
61
-     * IF there is no group then it gets automatically set to the Default template pack.
62
-     *
63
-     * @since 4.5.0
64
-     *
65
-     * @var EE_Messages_Template_Pack
66
-     */
67
-    protected $_template_pack;
68
-
69
-
70
-    /**
71
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
72
-     * group is.  If there is no group then it automatically gets set to default.
73
-     *
74
-     * @since 4.5.0
75
-     *
76
-     * @var string
77
-     */
78
-    protected $_variation;
79
-
80
-
81
-    /**
82
-     * @param bool $routing
83
-     * @throws EE_Error
84
-     */
85
-    public function __construct($routing = true)
86
-    {
87
-        // make sure messages autoloader is running
88
-        EED_Messages::set_autoloaders();
89
-        parent::__construct($routing);
90
-    }
91
-
92
-
93
-    protected function _init_page_props()
94
-    {
95
-        $this->page_slug        = EE_MSG_PG_SLUG;
96
-        $this->page_label       = esc_html__('Messages Settings', 'event_espresso');
97
-        $this->_admin_base_url  = EE_MSG_ADMIN_URL;
98
-        $this->_admin_base_path = EE_MSG_ADMIN;
99
-
100
-        $this->_activate_state = isset($this->_req_data['activate_state'])
101
-            ? (array) $this->_req_data['activate_state']
102
-            : [];
103
-
104
-        $this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
105
-        $this->_load_message_resource_manager();
106
-    }
107
-
108
-
109
-    /**
110
-     * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
111
-     *
112
-     * @throws EE_Error
113
-     * @throws InvalidDataTypeException
114
-     * @throws InvalidInterfaceException
115
-     * @throws InvalidArgumentException
116
-     * @throws ReflectionException
117
-     */
118
-    protected function _load_message_resource_manager()
119
-    {
120
-        $this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
121
-    }
122
-
123
-
124
-    /**
125
-     * @return array
126
-     * @throws EE_Error
127
-     * @throws InvalidArgumentException
128
-     * @throws InvalidDataTypeException
129
-     * @throws InvalidInterfaceException
130
-     * @deprecated 4.9.9.rc.014
131
-     */
132
-    public function get_messengers_for_list_table()
133
-    {
134
-        EE_Error::doing_it_wrong(
135
-            __METHOD__,
136
-            sprintf(
137
-                esc_html__(
138
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
139
-                    'event_espresso'
140
-                ),
141
-                'Messages_Admin_Page::get_messengers_select_input()'
142
-            ),
143
-            '4.9.9.rc.014'
144
-        );
145
-
146
-        $m_values          = [];
147
-        $active_messengers = EEM_Message::instance()->get_all(['group_by' => 'MSG_messenger']);
148
-        // setup messengers for selects
149
-        $i = 1;
150
-        foreach ($active_messengers as $active_messenger) {
151
-            if ($active_messenger instanceof EE_Message) {
152
-                $m_values[ $i ]['id']   = $active_messenger->messenger();
153
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
154
-                $i++;
155
-            }
156
-        }
157
-
158
-        return $m_values;
159
-    }
160
-
161
-
162
-    /**
163
-     * @return array
164
-     * @throws EE_Error
165
-     * @throws InvalidArgumentException
166
-     * @throws InvalidDataTypeException
167
-     * @throws InvalidInterfaceException
168
-     * @deprecated 4.9.9.rc.014
169
-     */
170
-    public function get_message_types_for_list_table()
171
-    {
172
-        EE_Error::doing_it_wrong(
173
-            __METHOD__,
174
-            sprintf(
175
-                esc_html__(
176
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
177
-                    'event_espresso'
178
-                ),
179
-                'Messages_Admin_Page::get_message_types_select_input()'
180
-            ),
181
-            '4.9.9.rc.014'
182
-        );
183
-
184
-        $mt_values       = [];
185
-        $active_messages = EEM_Message::instance()->get_all(['group_by' => 'MSG_message_type']);
186
-        $i               = 1;
187
-        foreach ($active_messages as $active_message) {
188
-            if ($active_message instanceof EE_Message) {
189
-                $mt_values[ $i ]['id']   = $active_message->message_type();
190
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
191
-                $i++;
192
-            }
193
-        }
194
-
195
-        return $mt_values;
196
-    }
197
-
198
-
199
-    /**
200
-     * @return array
201
-     * @throws EE_Error
202
-     * @throws InvalidArgumentException
203
-     * @throws InvalidDataTypeException
204
-     * @throws InvalidInterfaceException
205
-     * @deprecated 4.9.9.rc.014
206
-     */
207
-    public function get_contexts_for_message_types_for_list_table()
208
-    {
209
-        EE_Error::doing_it_wrong(
210
-            __METHOD__,
211
-            sprintf(
212
-                esc_html__(
213
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
214
-                    'event_espresso'
215
-                ),
216
-                'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
217
-            ),
218
-            '4.9.9.rc.014'
219
-        );
220
-
221
-        $contexts                = [];
222
-        $active_message_contexts = EEM_Message::instance()->get_all(['group_by' => 'MSG_context']);
223
-        foreach ($active_message_contexts as $active_message) {
224
-            if ($active_message instanceof EE_Message) {
225
-                $message_type = $active_message->message_type_object();
226
-                if ($message_type instanceof EE_message_type) {
227
-                    $message_type_contexts = $message_type->get_contexts();
228
-                    foreach ($message_type_contexts as $context => $context_details) {
229
-                        $contexts[ $context ] = $context_details['label'];
230
-                    }
231
-                }
232
-            }
233
-        }
234
-
235
-        return $contexts;
236
-    }
237
-
238
-
239
-    /**
240
-     * Generate select input with provided messenger options array.
241
-     *
242
-     * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
243
-     *                                 labels.
244
-     * @return string
245
-     * @throws EE_Error
246
-     */
247
-    public function get_messengers_select_input($messenger_options)
248
-    {
249
-        // if empty or just one value then just return an empty string
250
-        if (
251
-            empty($messenger_options)
252
-            || ! is_array($messenger_options)
253
-            || count($messenger_options) === 1
254
-        ) {
255
-            return '';
256
-        }
257
-        // merge in default
258
-        $messenger_options = array_merge(
259
-            ['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
260
-            $messenger_options
261
-        );
262
-        $input             = new EE_Select_Input(
263
-            $messenger_options,
264
-            [
265
-                'html_name'  => 'ee_messenger_filter_by',
266
-                'html_id'    => 'ee_messenger_filter_by',
267
-                'html_class' => 'wide',
268
-                'default'    => isset($this->_req_data['ee_messenger_filter_by'])
269
-                    ? sanitize_title($this->_req_data['ee_messenger_filter_by'])
270
-                    : 'none_selected',
271
-            ]
272
-        );
273
-
274
-        return $input->get_html_for_input();
275
-    }
276
-
277
-
278
-    /**
279
-     * Generate select input with provided message type options array.
280
-     *
281
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
282
-     *                                    message type labels
283
-     * @return string
284
-     * @throws EE_Error
285
-     */
286
-    public function get_message_types_select_input($message_type_options)
287
-    {
288
-        // if empty or count of options is 1 then just return an empty string
289
-        if (
290
-            empty($message_type_options)
291
-            || ! is_array($message_type_options)
292
-            || count($message_type_options) === 1
293
-        ) {
294
-            return '';
295
-        }
296
-        // merge in default
297
-        $message_type_options = array_merge(
298
-            ['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
299
-            $message_type_options
300
-        );
301
-        $input                = new EE_Select_Input(
302
-            $message_type_options,
303
-            [
304
-                'html_name'  => 'ee_message_type_filter_by',
305
-                'html_id'    => 'ee_message_type_filter_by',
306
-                'html_class' => 'wide',
307
-                'default'    => isset($this->_req_data['ee_message_type_filter_by'])
308
-                    ? sanitize_title($this->_req_data['ee_message_type_filter_by'])
309
-                    : 'none_selected',
310
-            ]
311
-        );
312
-
313
-        return $input->get_html_for_input();
314
-    }
315
-
316
-
317
-    /**
318
-     * Generate select input with provide message type contexts array.
319
-     *
320
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
321
-     *                               context label.
322
-     * @return string
323
-     * @throws EE_Error
324
-     */
325
-    public function get_contexts_for_message_types_select_input($context_options)
326
-    {
327
-        // if empty or count of options is one then just return empty string
328
-        if (
329
-            empty($context_options)
330
-            || ! is_array($context_options)
331
-            || count($context_options) === 1
332
-        ) {
333
-            return '';
334
-        }
335
-        // merge in default
336
-        $context_options = array_merge(
337
-            ['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
338
-            $context_options
339
-        );
340
-        $input           = new EE_Select_Input(
341
-            $context_options,
342
-            [
343
-                'html_name'  => 'ee_context_filter_by',
344
-                'html_id'    => 'ee_context_filter_by',
345
-                'html_class' => 'wide',
346
-                'default'    => isset($this->_req_data['ee_context_filter_by'])
347
-                    ? sanitize_title($this->_req_data['ee_context_filter_by'])
348
-                    : 'none_selected',
349
-            ]
350
-        );
351
-
352
-        return $input->get_html_for_input();
353
-    }
354
-
355
-
356
-    protected function _ajax_hooks()
357
-    {
358
-        add_action('wp_ajax_activate_messenger', [$this, 'activate_messenger_toggle']);
359
-        add_action('wp_ajax_activate_mt', [$this, 'activate_mt_toggle']);
360
-        add_action('wp_ajax_ee_msgs_save_settings', [$this, 'save_settings']);
361
-        add_action('wp_ajax_ee_msgs_update_mt_form', [$this, 'update_mt_form']);
362
-        add_action('wp_ajax_switch_template_pack', [$this, 'switch_template_pack']);
363
-        add_action('wp_ajax_toggle_context_template', [$this, 'toggle_context_template']);
364
-    }
365
-
366
-
367
-    protected function _define_page_props()
368
-    {
369
-        $this->_admin_page_title = $this->page_label;
370
-        $this->_labels           = [
371
-            'buttons'    => [
372
-                'add'    => esc_html__('Add New Message Template', 'event_espresso'),
373
-                'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
374
-                'delete' => esc_html__('Delete Message Template', 'event_espresso'),
375
-            ],
376
-            'publishbox' => esc_html__('Update Actions', 'event_espresso'),
377
-        ];
378
-    }
379
-
380
-
381
-    /**
382
-     *        an array for storing key => value pairs of request actions and their corresponding methods
383
-     *
384
-     * @access protected
385
-     * @return void
386
-     */
387
-    protected function _set_page_routes()
388
-    {
389
-        $grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
390
-            ? $this->_req_data['GRP_ID']
391
-            : 0;
392
-        $grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
393
-            ? $this->_req_data['id']
394
-            : $grp_id;
395
-        $msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
396
-            ? $this->_req_data['MSG_ID']
397
-            : 0;
398
-
399
-        $this->_page_routes = [
400
-            'default'                          => [
401
-                'func'       => '_message_queue_list_table',
402
-                'capability' => 'ee_read_global_messages',
403
-            ],
404
-            'global_mtps'                      => [
405
-                'func'       => '_ee_default_messages_overview_list_table',
406
-                'capability' => 'ee_read_global_messages',
407
-            ],
408
-            'custom_mtps'                      => [
409
-                'func'       => '_custom_mtps_preview',
410
-                'capability' => 'ee_read_messages',
411
-            ],
412
-            'add_new_message_template'         => [
413
-                'func'       => '_add_message_template',
414
-                'capability' => 'ee_edit_messages',
415
-                'noheader'   => true,
416
-            ],
417
-            'edit_message_template'            => [
418
-                'func'       => '_edit_message_template',
419
-                'capability' => 'ee_edit_message',
420
-                'obj_id'     => $grp_id,
421
-            ],
422
-            'preview_message'                  => [
423
-                'func'               => '_preview_message',
424
-                'capability'         => 'ee_read_message',
425
-                'obj_id'             => $grp_id,
426
-                'noheader'           => true,
427
-                'headers_sent_route' => 'display_preview_message',
428
-            ],
429
-            'display_preview_message'          => [
430
-                'func'       => '_display_preview_message',
431
-                'capability' => 'ee_read_message',
432
-                'obj_id'     => $grp_id,
433
-            ],
434
-            'insert_message_template'          => [
435
-                'func'       => '_insert_or_update_message_template',
436
-                'capability' => 'ee_edit_messages',
437
-                'args'       => ['new' => true],
438
-                'noheader'   => true,
439
-            ],
440
-            'update_message_template'          => [
441
-                'func'       => '_insert_or_update_message_template',
442
-                'capability' => 'ee_edit_message',
443
-                'obj_id'     => $grp_id,
444
-                'args'       => ['new' => false],
445
-                'noheader'   => true,
446
-            ],
447
-            'trash_message_template'           => [
448
-                'func'       => '_trash_or_restore_message_template',
449
-                'capability' => 'ee_delete_message',
450
-                'obj_id'     => $grp_id,
451
-                'args'       => ['trash' => true, 'all' => true],
452
-                'noheader'   => true,
453
-            ],
454
-            'trash_message_template_context'   => [
455
-                'func'       => '_trash_or_restore_message_template',
456
-                'capability' => 'ee_delete_message',
457
-                'obj_id'     => $grp_id,
458
-                'args'       => ['trash' => true],
459
-                'noheader'   => true,
460
-            ],
461
-            'restore_message_template'         => [
462
-                'func'       => '_trash_or_restore_message_template',
463
-                'capability' => 'ee_delete_message',
464
-                'obj_id'     => $grp_id,
465
-                'args'       => ['trash' => false, 'all' => true],
466
-                'noheader'   => true,
467
-            ],
468
-            'restore_message_template_context' => [
469
-                'func'       => '_trash_or_restore_message_template',
470
-                'capability' => 'ee_delete_message',
471
-                'obj_id'     => $grp_id,
472
-                'args'       => ['trash' => false],
473
-                'noheader'   => true,
474
-            ],
475
-            'delete_message_template'          => [
476
-                'func'       => '_delete_message_template',
477
-                'capability' => 'ee_delete_message',
478
-                'obj_id'     => $grp_id,
479
-                'noheader'   => true,
480
-            ],
481
-            'reset_to_default'                 => [
482
-                'func'       => '_reset_to_default_template',
483
-                'capability' => 'ee_edit_message',
484
-                'obj_id'     => $grp_id,
485
-                'noheader'   => true,
486
-            ],
487
-            'settings'                         => [
488
-                'func'       => '_settings',
489
-                'capability' => 'manage_options',
490
-            ],
491
-            'update_global_settings'           => [
492
-                'func'       => '_update_global_settings',
493
-                'capability' => 'manage_options',
494
-                'noheader'   => true,
495
-            ],
496
-            'generate_now'                     => [
497
-                'func'       => '_generate_now',
498
-                'capability' => 'ee_send_message',
499
-                'noheader'   => true,
500
-            ],
501
-            'generate_and_send_now'            => [
502
-                'func'       => '_generate_and_send_now',
503
-                'capability' => 'ee_send_message',
504
-                'noheader'   => true,
505
-            ],
506
-            'queue_for_resending'              => [
507
-                'func'       => '_queue_for_resending',
508
-                'capability' => 'ee_send_message',
509
-                'noheader'   => true,
510
-            ],
511
-            'send_now'                         => [
512
-                'func'       => '_send_now',
513
-                'capability' => 'ee_send_message',
514
-                'noheader'   => true,
515
-            ],
516
-            'delete_ee_message'                => [
517
-                'func'       => '_delete_ee_messages',
518
-                'capability' => 'ee_delete_messages',
519
-                'noheader'   => true,
520
-            ],
521
-            'delete_ee_messages'               => [
522
-                'func'       => '_delete_ee_messages',
523
-                'capability' => 'ee_delete_messages',
524
-                'noheader'   => true,
525
-                'obj_id'     => $msg_id,
526
-            ],
527
-        ];
528
-    }
529
-
530
-
531
-    protected function _set_page_config()
532
-    {
533
-        $this->_page_config = [
534
-            'default'                  => [
535
-                'nav'           => [
536
-                    'label' => esc_html__('Message Activity', 'event_espresso'),
537
-                    'order' => 10,
538
-                ],
539
-                'list_table'    => 'EE_Message_List_Table',
540
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
541
-                'require_nonce' => false,
542
-            ],
543
-            'global_mtps'              => [
544
-                'nav'           => [
545
-                    'label' => esc_html__('Default Message Templates', 'event_espresso'),
546
-                    'order' => 20,
547
-                ],
548
-                'list_table'    => 'Messages_Template_List_Table',
549
-                'help_tabs'     => [
550
-                    'messages_overview_help_tab'                                => [
551
-                        'title'    => esc_html__('Messages Overview', 'event_espresso'),
552
-                        'filename' => 'messages_overview',
553
-                    ],
554
-                    'messages_overview_messages_table_column_headings_help_tab' => [
555
-                        'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
556
-                        'filename' => 'messages_overview_table_column_headings',
557
-                    ],
558
-                    'messages_overview_messages_filters_help_tab'               => [
559
-                        'title'    => esc_html__('Message Filters', 'event_espresso'),
560
-                        'filename' => 'messages_overview_filters',
561
-                    ],
562
-                    'messages_overview_messages_views_help_tab'                 => [
563
-                        'title'    => esc_html__('Message Views', 'event_espresso'),
564
-                        'filename' => 'messages_overview_views',
565
-                    ],
566
-                    'message_overview_message_types_help_tab'                   => [
567
-                        'title'    => esc_html__('Message Types', 'event_espresso'),
568
-                        'filename' => 'messages_overview_types',
569
-                    ],
570
-                    'messages_overview_messengers_help_tab'                     => [
571
-                        'title'    => esc_html__('Messengers', 'event_espresso'),
572
-                        'filename' => 'messages_overview_messengers',
573
-                    ],
574
-                ],
575
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
576
-                // 'help_tour'     => array('Messages_Overview_Help_Tour'),
577
-                'require_nonce' => false,
578
-            ],
579
-            'custom_mtps'              => [
580
-                'nav'           => [
581
-                    'label' => esc_html__('Custom Message Templates', 'event_espresso'),
582
-                    'order' => 30,
583
-                ],
584
-                'help_tabs'     => [],
585
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
586
-                // 'help_tour'     => array(),
587
-                'require_nonce' => false,
588
-            ],
589
-            'add_new_message_template' => [
590
-                'nav'           => [
591
-                    'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
592
-                    'order'      => 5,
593
-                    'persistent' => false,
594
-                ],
595
-                'require_nonce' => false,
596
-            ],
597
-            'edit_message_template'    => [
598
-                'labels'        => [
599
-                    'buttons'    => [
600
-                        'reset' => esc_html__('Reset Templates', 'event_espresso'),
601
-                    ],
602
-                    'publishbox' => esc_html__('Update Actions', 'event_espresso'),
603
-                ],
604
-                'nav'           => [
605
-                    'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
606
-                    'order'      => 5,
607
-                    'persistent' => false,
608
-                    'url'        => '',
609
-                ],
610
-                'metaboxes'     => ['_publish_post_box', '_register_edit_meta_boxes'],
611
-                'has_metaboxes' => true,
612
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
613
-                // 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
614
-                'help_tabs'     => [
615
-                    'edit_message_template'            => [
616
-                        'title'    => esc_html__('Message Template Editor', 'event_espresso'),
617
-                        'callback' => 'edit_message_template_help_tab',
618
-                    ],
619
-                    'message_templates_help_tab'       => [
620
-                        'title'    => esc_html__('Message Templates', 'event_espresso'),
621
-                        'filename' => 'messages_templates',
622
-                    ],
623
-                    'message_template_shortcodes'      => [
624
-                        'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
625
-                        'callback' => 'message_template_shortcodes_help_tab',
626
-                    ],
627
-                    'message_preview_help_tab'         => [
628
-                        'title'    => esc_html__('Message Preview', 'event_espresso'),
629
-                        'filename' => 'messages_preview',
630
-                    ],
631
-                    'messages_overview_other_help_tab' => [
632
-                        'title'    => esc_html__('Messages Other', 'event_espresso'),
633
-                        'filename' => 'messages_overview_other',
634
-                    ],
635
-                ],
636
-                'require_nonce' => false,
637
-            ],
638
-            'display_preview_message'  => [
639
-                'nav'           => [
640
-                    'label'      => esc_html__('Message Preview', 'event_espresso'),
641
-                    'order'      => 5,
642
-                    'url'        => '',
643
-                    'persistent' => false,
644
-                ],
645
-                'help_tabs'     => [
646
-                    'preview_message' => [
647
-                        'title'    => esc_html__('About Previews', 'event_espresso'),
648
-                        'callback' => 'preview_message_help_tab',
649
-                    ],
650
-                ],
651
-                'require_nonce' => false,
652
-            ],
653
-            'settings'                 => [
654
-                'nav'           => [
655
-                    'label' => esc_html__('Settings', 'event_espresso'),
656
-                    'order' => 40,
657
-                ],
658
-                'metaboxes'     => ['_messages_settings_metaboxes'],
659
-                'help_tabs'     => [
660
-                    'messages_settings_help_tab'               => [
661
-                        'title'    => esc_html__('Messages Settings', 'event_espresso'),
662
-                        'filename' => 'messages_settings',
663
-                    ],
664
-                    'messages_settings_message_types_help_tab' => [
665
-                        'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
666
-                        'filename' => 'messages_settings_message_types',
667
-                    ],
668
-                    'messages_settings_messengers_help_tab'    => [
669
-                        'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
670
-                        'filename' => 'messages_settings_messengers',
671
-                    ],
672
-                ],
673
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
674
-                // 'help_tour'     => array('Messages_Settings_Help_Tour'),
675
-                'require_nonce' => false,
676
-            ],
677
-        ];
678
-    }
679
-
680
-
681
-    protected function _add_screen_options()
682
-    {
683
-        // todo
684
-    }
685
-
686
-
687
-    protected function _add_screen_options_global_mtps()
688
-    {
689
-        /**
690
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
691
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
692
-         */
693
-        $page_title              = $this->_admin_page_title;
694
-        $this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
695
-        $this->_per_page_screen_option();
696
-        $this->_admin_page_title = $page_title;
697
-    }
698
-
699
-
700
-    protected function _add_screen_options_default()
701
-    {
702
-        $this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
703
-        $this->_per_page_screen_option();
704
-    }
705
-
706
-
707
-    // none of the below group are currently used for Messages
708
-    protected function _add_feature_pointers()
709
-    {
710
-    }
711
-
712
-
713
-    public function admin_init()
714
-    {
715
-    }
716
-
717
-
718
-    public function admin_notices()
719
-    {
720
-    }
721
-
722
-
723
-    public function admin_footer_scripts()
724
-    {
725
-    }
726
-
727
-
728
-    public function messages_help_tab()
729
-    {
730
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
731
-    }
732
-
733
-
734
-    public function messengers_help_tab()
735
-    {
736
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
737
-    }
738
-
739
-
740
-    public function message_types_help_tab()
741
-    {
742
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
743
-    }
744
-
745
-
746
-    public function messages_overview_help_tab()
747
-    {
748
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
749
-    }
750
-
751
-
752
-    public function message_templates_help_tab()
753
-    {
754
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
755
-    }
756
-
757
-
758
-    public function edit_message_template_help_tab()
759
-    {
760
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
761
-                        . esc_attr__('Editor Title', 'event_espresso')
762
-                        . '" />';
763
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
764
-                        . esc_attr__('Context Switcher and Preview', 'event_espresso')
765
-                        . '" />';
766
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
767
-                        . esc_attr__('Message Template Form Fields', 'event_espresso')
768
-                        . '" />';
769
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
770
-                        . esc_attr__('Shortcodes Metabox', 'event_espresso')
771
-                        . '" />';
772
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
773
-                        . esc_attr__('Publish Metabox', 'event_espresso')
774
-                        . '" />';
775
-        EEH_Template::display_template(
776
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
777
-            $args
778
-        );
779
-    }
780
-
781
-
782
-    public function message_template_shortcodes_help_tab()
783
-    {
784
-        $this->_set_shortcodes();
785
-        $args['shortcodes'] = $this->_shortcodes;
786
-        EEH_Template::display_template(
787
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
788
-            $args
789
-        );
790
-    }
791
-
792
-
793
-    public function preview_message_help_tab()
794
-    {
795
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
796
-    }
797
-
798
-
799
-    public function settings_help_tab()
800
-    {
801
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
802
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
803
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
804
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
805
-        $args['img3'] = '<div class="switch">'
806
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
807
-                        . ' type="checkbox" checked="checked">'
808
-                        . '<label for="ee-on-off-toggle-on"></label>'
809
-                        . '</div>';
810
-        $args['img4'] = '<div class="switch">'
811
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
812
-                        . ' type="checkbox">'
813
-                        . '<label for="ee-on-off-toggle-on"></label>'
814
-                        . '</div>';
815
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
816
-    }
817
-
818
-
819
-    public function load_scripts_styles()
820
-    {
821
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
822
-        wp_enqueue_style('espresso_ee_msg');
823
-
824
-        wp_register_script(
825
-            'ee-messages-settings',
826
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
827
-            ['jquery-ui-droppable', 'ee-serialize-full-array'],
828
-            EVENT_ESPRESSO_VERSION,
829
-            true
830
-        );
831
-        wp_register_script(
832
-            'ee-msg-list-table-js',
833
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
834
-            ['ee-dialog'],
835
-            EVENT_ESPRESSO_VERSION
836
-        );
837
-    }
838
-
839
-
840
-    public function load_scripts_styles_default()
841
-    {
842
-        wp_enqueue_script('ee-msg-list-table-js');
843
-    }
844
-
845
-
846
-    public function wp_editor_css($mce_css)
847
-    {
848
-        // if we're on the edit_message_template route
849
-        if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
850
-            $message_type_name = $this->_active_message_type_name;
851
-
852
-            // we're going to REPLACE the existing mce css
853
-            // we need to get the css file location from the active messenger
854
-            $mce_css = $this->_active_messenger->get_variation(
855
-                $this->_template_pack,
856
-                $message_type_name,
857
-                true,
858
-                'wpeditor',
859
-                $this->_variation
860
-            );
861
-        }
862
-
863
-        return $mce_css;
864
-    }
865
-
866
-
867
-    public function load_scripts_styles_edit_message_template()
868
-    {
869
-
870
-        $this->_set_shortcodes();
871
-
872
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
873
-            esc_html__(
874
-                'Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
875
-                'event_espresso'
876
-            ),
877
-            $this->_message_template_group->messenger_obj()->label['singular'],
878
-            $this->_message_template_group->message_type_obj()->label['singular']
879
-        );
880
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
881
-            'Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
882
-            'event_espresso'
883
-        );
884
-        EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
885
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
886
-            'event_espresso'
887
-        );
888
-
889
-        wp_register_script(
890
-            'ee_msgs_edit_js',
891
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
892
-            ['jquery'],
893
-            EVENT_ESPRESSO_VERSION
894
-        );
895
-
896
-        wp_enqueue_script('ee_admin_js');
897
-        wp_enqueue_script('ee_msgs_edit_js');
898
-
899
-        // add in special css for tiny_mce
900
-        add_filter('mce_css', [$this, 'wp_editor_css']);
901
-    }
902
-
903
-
904
-    public function load_scripts_styles_display_preview_message()
905
-    {
906
-
907
-        $this->_set_message_template_group();
908
-
909
-        if (isset($this->_req_data['messenger'])) {
910
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
911
-                $this->_req_data['messenger']
912
-            );
913
-        }
914
-
915
-        $message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
916
-
917
-
918
-        wp_enqueue_style(
919
-            'espresso_preview_css',
920
-            $this->_active_messenger->get_variation(
921
-                $this->_template_pack,
922
-                $message_type_name,
923
-                true,
924
-                'preview',
925
-                $this->_variation
926
-            )
927
-        );
928
-    }
929
-
930
-
931
-    public function load_scripts_styles_settings()
932
-    {
933
-        wp_register_style(
934
-            'ee-message-settings',
935
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
936
-            [],
937
-            EVENT_ESPRESSO_VERSION
938
-        );
939
-        wp_enqueue_style('ee-text-links');
940
-        wp_enqueue_style('ee-message-settings');
941
-        wp_enqueue_script('ee-messages-settings');
942
-    }
943
-
944
-
945
-    /**
946
-     * set views array for List Table
947
-     */
948
-    public function _set_list_table_views_global_mtps()
949
-    {
950
-        $this->_views = [
951
-            'in_use' => [
952
-                'slug'  => 'in_use',
953
-                'label' => esc_html__('In Use', 'event_espresso'),
954
-                'count' => 0,
955
-            ],
956
-        ];
957
-    }
958
-
959
-
960
-    /**
961
-     * Set views array for the Custom Template List Table
962
-     */
963
-    public function _set_list_table_views_custom_mtps()
964
-    {
965
-        $this->_set_list_table_views_global_mtps();
966
-        $this->_views['in_use']['bulk_action'] = [
967
-            'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
968
-        ];
969
-    }
970
-
971
-
972
-    /**
973
-     * set views array for message queue list table
974
-     *
975
-     * @throws InvalidDataTypeException
976
-     * @throws InvalidInterfaceException
977
-     * @throws InvalidArgumentException
978
-     * @throws EE_Error
979
-     * @throws ReflectionException
980
-     */
981
-    public function _set_list_table_views_default()
982
-    {
983
-        EE_Registry::instance()->load_helper('Template');
984
-
985
-        $common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
986
-            'ee_send_message',
987
-            'message_list_table_bulk_actions'
988
-        )
989
-            ? [
990
-                'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
991
-                'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
992
-                'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
993
-                'send_now'              => esc_html__('Send Now', 'event_espresso'),
994
-            ]
995
-            : [];
996
-
997
-        $delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
998
-            'ee_delete_messages',
999
-            'message_list_table_bulk_actions'
1000
-        )
1001
-            ? ['delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso')]
1002
-            : [];
1003
-
1004
-
1005
-        $this->_views = [
1006
-            'all' => [
1007
-                'slug'        => 'all',
1008
-                'label'       => esc_html__('All', 'event_espresso'),
1009
-                'count'       => 0,
1010
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
1011
-            ],
1012
-        ];
1013
-
1014
-
1015
-        foreach (EEM_Message::instance()->all_statuses() as $status) {
1016
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1017
-                continue;
1018
-            }
1019
-            $status_bulk_actions = $common_bulk_actions;
1020
-            // unset bulk actions not applying to status
1021
-            if (! empty($status_bulk_actions)) {
1022
-                switch ($status) {
1023
-                    case EEM_Message::status_idle:
1024
-                    case EEM_Message::status_resend:
1025
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1026
-                        break;
1027
-
1028
-                    case EEM_Message::status_failed:
1029
-                    case EEM_Message::status_debug_only:
1030
-                    case EEM_Message::status_messenger_executing:
1031
-                        $status_bulk_actions = [];
1032
-                        break;
1033
-
1034
-                    case EEM_Message::status_incomplete:
1035
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1036
-                        break;
1037
-
1038
-                    case EEM_Message::status_retry:
1039
-                    case EEM_Message::status_sent:
1040
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1041
-                        break;
1042
-                }
1043
-            }
1044
-
1045
-            // skip adding messenger executing status to views because it will be included with the Failed view.
1046
-            if ($status === EEM_Message::status_messenger_executing) {
1047
-                continue;
1048
-            }
1049
-
1050
-            $this->_views[ strtolower($status) ] = [
1051
-                'slug'        => strtolower($status),
1052
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1053
-                'count'       => 0,
1054
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1055
-            ];
1056
-        }
1057
-    }
1058
-
1059
-
1060
-    protected function _ee_default_messages_overview_list_table()
1061
-    {
1062
-        $this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1063
-        $this->display_admin_list_table_page_with_no_sidebar();
1064
-    }
1065
-
1066
-
1067
-    protected function _message_queue_list_table()
1068
-    {
1069
-        $this->_search_btn_label                   = esc_html__('Message Activity', 'event_espresso');
1070
-        $this->_template_args['per_column']        = 6;
1071
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
1072
-        $this->_template_args['before_list_table'] = '<h3>'
1073
-                                                     . EEM_Message::instance()->get_pretty_label_for_results()
1074
-                                                     . '</h3>';
1075
-        $this->display_admin_list_table_page_with_no_sidebar();
1076
-    }
1077
-
1078
-
1079
-    protected function _message_legend_items()
1080
-    {
1081
-
1082
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
1083
-        $action_items       = [];
1084
-
1085
-        foreach ($action_css_classes as $action_item => $action_details) {
1086
-            if ($action_item === 'see_notifications_for') {
1087
-                continue;
1088
-            }
1089
-            $action_items[ $action_item ] = [
1090
-                'class' => $action_details['css_class'],
1091
-                'desc'  => $action_details['label'],
1092
-            ];
1093
-        }
1094
-
1095
-        /** @type array $status_items status legend setup */
1096
-        $status_items = [
1097
-            'sent_status'                => [
1098
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_sent,
1099
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1100
-            ],
1101
-            'idle_status'                => [
1102
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_idle,
1103
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1104
-            ],
1105
-            'failed_status'              => [
1106
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_failed,
1107
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1108
-            ],
1109
-            'messenger_executing_status' => [
1110
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_messenger_executing,
1111
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1112
-            ],
1113
-            'resend_status'              => [
1114
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_resend,
1115
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1116
-            ],
1117
-            'incomplete_status'          => [
1118
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_incomplete,
1119
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1120
-            ],
1121
-            'retry_status'               => [
1122
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_retry,
1123
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1124
-            ],
1125
-        ];
1126
-        if (EEM_Message::debug()) {
1127
-            $status_items['debug_only_status'] = [
1128
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_debug_only,
1129
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1130
-            ];
1131
-        }
1132
-
1133
-        return array_merge($action_items, $status_items);
1134
-    }
1135
-
1136
-
1137
-    protected function _custom_mtps_preview()
1138
-    {
1139
-        $this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1140
-        $this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1141
-                                                . ' alt="' . esc_attr__(
1142
-                                                    'Preview Custom Message Templates screenshot',
1143
-                                                    'event_espresso'
1144
-                                                ) . '" />';
1145
-        $this->_template_args['preview_text'] = '<strong>'
1146
-                                                . esc_html__(
1147
-                                                    'Custom Message Templates is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
1148
-                                                    'event_espresso'
1149
-                                                )
1150
-                                                . '</strong>';
1151
-
1152
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1153
-    }
1154
-
1155
-
1156
-    /**
1157
-     * get_message_templates
1158
-     * This gets all the message templates for listing on the overview list.
1159
-     *
1160
-     * @access public
1161
-     * @param int    $perpage the amount of templates groups to show per page
1162
-     * @param string $type    the current _view we're getting templates for
1163
-     * @param bool   $count   return count?
1164
-     * @param bool   $all     disregard any paging info (get all data);
1165
-     * @param bool   $global  whether to return just global (true) or custom templates (false)
1166
-     * @return array
1167
-     * @throws EE_Error
1168
-     * @throws InvalidArgumentException
1169
-     * @throws InvalidDataTypeException
1170
-     * @throws InvalidInterfaceException
1171
-     */
1172
-    public function get_message_templates(
1173
-        $perpage = 10,
1174
-        $type = 'in_use',
1175
-        $count = false,
1176
-        $all = false,
1177
-        $global = true
1178
-    ) {
1179
-
1180
-        $MTP = EEM_Message_Template_Group::instance();
1181
-
1182
-        $this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1183
-        $orderby                    = $this->_req_data['orderby'];
1184
-
1185
-        $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1186
-            ? $this->_req_data['order']
1187
-            : 'ASC';
1188
-
1189
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1190
-            ? $this->_req_data['paged']
1191
-            : 1;
1192
-        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1193
-            ? $this->_req_data['perpage']
1194
-            : $perpage;
1195
-
1196
-        $offset = ($current_page - 1) * $per_page;
1197
-        $limit  = $all ? null : [$offset, $per_page];
1198
-
1199
-
1200
-        // options will match what is in the _views array property
1201
-        switch ($type) {
1202
-            case 'in_use':
1203
-                $templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1204
-                break;
1205
-            default:
1206
-                $templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1207
-        }
1208
-
1209
-        return $templates;
1210
-    }
1211
-
1212
-
1213
-    /**
1214
-     * filters etc might need a list of installed message_types
1215
-     *
1216
-     * @return array an array of message type objects
1217
-     */
1218
-    public function get_installed_message_types()
1219
-    {
1220
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1221
-        $installed               = [];
1222
-
1223
-        foreach ($installed_message_types as $message_type) {
1224
-            $installed[ $message_type->name ] = $message_type;
1225
-        }
1226
-
1227
-        return $installed;
1228
-    }
1229
-
1230
-
1231
-    /**
1232
-     * _add_message_template
1233
-     *
1234
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1235
-     *
1236
-     * @param string $message_type
1237
-     * @param string $messenger
1238
-     * @param string $GRP_ID
1239
-     *
1240
-     * @throws EE_error
1241
-     */
1242
-    protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1243
-    {
1244
-        // set values override any request data
1245
-        $message_type = ! empty($message_type) ? $message_type : $this->request->getRequestParam('message_type');
1246
-        $messenger    = ! empty($messenger) ? $messenger : $this->request->getRequestParam('messenger');
1247
-        $GRP_ID       = ! empty($GRP_ID) ? $GRP_ID : $this->request->getRequestParam('GRP_ID', 0, 'int');
1248
-
1249
-        // we need messenger and message type.  They should be coming from the event editor. If not here then return error
1250
-        if (empty($message_type) || empty($messenger)) {
1251
-            throw new EE_Error(
1252
-                esc_html__(
1253
-                    'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1254
-                    'event_espresso'
1255
-                )
1256
-            );
1257
-        }
1258
-
1259
-        // we need the GRP_ID for the template being used as the base for the new template
1260
-        if (empty($GRP_ID)) {
1261
-            throw new EE_Error(
1262
-                esc_html__(
1263
-                    'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1264
-                    'event_espresso'
1265
-                )
1266
-            );
1267
-        }
1268
-
1269
-        // let's just make sure the template gets generated!
1270
-
1271
-        // we need to reassign some variables for what the insert is expecting
1272
-        $this->_req_data['MTP_messenger']    = $messenger;
1273
-        $this->_req_data['MTP_message_type'] = $message_type;
1274
-        $this->_req_data['GRP_ID']           = $GRP_ID;
1275
-        $this->_insert_or_update_message_template(true);
1276
-    }
1277
-
1278
-
1279
-    /**
1280
-     * public wrapper for the _add_message_template method
1281
-     *
1282
-     * @param string $message_type     message type slug
1283
-     * @param string $messenger        messenger slug
1284
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1285
-     *                                 off of.
1286
-     * @throws EE_error
1287
-     */
1288
-    public function add_message_template($message_type, $messenger, $GRP_ID)
1289
-    {
1290
-        $this->_add_message_template($message_type, $messenger, $GRP_ID);
1291
-    }
1292
-
1293
-
1294
-    /**
1295
-     * _edit_message_template
1296
-     *
1297
-     * @access protected
1298
-     * @return void
1299
-     * @throws InvalidIdentifierException
1300
-     * @throws DomainException
1301
-     * @throws EE_Error
1302
-     * @throws InvalidArgumentException
1303
-     * @throws ReflectionException
1304
-     * @throws InvalidDataTypeException
1305
-     * @throws InvalidInterfaceException
1306
-     */
1307
-    protected function _edit_message_template()
1308
-    {
1309
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1310
-        $template_fields = '';
1311
-        $sidebar_fields  = '';
1312
-        // we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1313
-        // valid html in the templates.
1314
-        add_filter('tiny_mce_before_init', [$this, 'filter_tinymce_init'], 10, 2);
1315
-
1316
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1317
-            ? absint($this->_req_data['id'])
1318
-            : false;
1319
-
1320
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1321
-            ? absint($this->_req_data['evt_id'])
1322
-            : false;
1323
-
1324
-        $this->_set_shortcodes(); // this also sets the _message_template property.
1325
-        $message_template_group = $this->_message_template_group;
1326
-        $c_label                = $message_template_group->context_label();
1327
-        $c_config               = $message_template_group->contexts_config();
1328
-
1329
-        reset($c_config);
1330
-        $context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1331
-            ? strtolower($this->_req_data['context'])
1332
-            : key($c_config);
1333
-
1334
-
1335
-        if (empty($GRP_ID)) {
1336
-            $action                         = 'insert_message_template';
1337
-            $edit_message_template_form_url = add_query_arg(
1338
-                ['action' => $action, 'noheader' => true],
1339
-                EE_MSG_ADMIN_URL
1340
-            );
1341
-        } else {
1342
-            $action                         = 'update_message_template';
1343
-            $edit_message_template_form_url = add_query_arg(
1344
-                ['action' => $action, 'noheader' => true],
1345
-                EE_MSG_ADMIN_URL
1346
-            );
1347
-        }
1348
-
1349
-        // set active messenger for this view
1350
-        $this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1351
-            $message_template_group->messenger()
1352
-        );
1353
-        $this->_active_message_type_name = $message_template_group->message_type();
1354
-
1355
-
1356
-        // Do we have any validation errors?
1357
-        $validators = $this->_get_transient();
1358
-        $v_fields   = ! empty($validators) ? array_keys($validators) : [];
1359
-
1360
-
1361
-        // we need to assemble the title from Various details
1362
-        $context_label = sprintf(
1363
-            esc_html__('(%s %s)', 'event_espresso'),
1364
-            $c_config[ $context ]['label'],
1365
-            ucwords($c_label['label'])
1366
-        );
1367
-
1368
-        $title = sprintf(
1369
-            esc_html__(' %s %s Template %s', 'event_espresso'),
1370
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1371
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1372
-            $context_label
1373
-        );
1374
-
1375
-        $this->_template_args['GRP_ID']           = $GRP_ID;
1376
-        $this->_template_args['message_template'] = $message_template_group;
1377
-        $this->_template_args['is_extra_fields']  = false;
1378
-
1379
-
1380
-        // let's get EEH_MSG_Template so we can get template form fields
1381
-        $template_field_structure = EEH_MSG_Template::get_fields(
1382
-            $message_template_group->messenger(),
1383
-            $message_template_group->message_type()
1384
-        );
1385
-
1386
-        if (! $template_field_structure) {
1387
-            $template_field_structure = false;
1388
-            $template_fields          = esc_html__(
1389
-                'There was an error in assembling the fields for this display (you should see an error message)',
1390
-                'event_espresso'
1391
-            );
1392
-        }
1393
-
1394
-
1395
-        $message_templates = $message_template_group->context_templates();
1396
-
1397
-
1398
-        // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1399
-        // will get handled in the "extra" array.
1400
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1401
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1402
-                unset($template_field_structure[ $context ][ $reference_field ]);
1403
-            }
1404
-        }
1405
-
1406
-        // let's loop through the template_field_structure and actually assemble the input fields!
1407
-        if (! empty($template_field_structure)) {
1408
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1409
-                // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1410
-                // the extra array and reset them.
1411
-                if ($template_field === 'extra') {
1412
-                    $this->_template_args['is_extra_fields'] = true;
1413
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1414
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1415
-                        $content          = $message_template instanceof EE_Message_Template
1416
-                            ? $message_template->get('MTP_content')
1417
-                            : '';
1418
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1419
-                            // let's verify if we need this extra field via the shortcodes parameter.
1420
-                            $continue = false;
1421
-                            if (isset($extra_array['shortcodes_required'])) {
1422
-                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1423
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1424
-                                        $continue = true;
1425
-                                    }
1426
-                                }
1427
-                                if ($continue) {
1428
-                                    continue;
1429
-                                }
1430
-                            }
1431
-
1432
-                            $field_id                                  = $reference_field
1433
-                                                                         . '-'
1434
-                                                                         . $extra_field
1435
-                                                                         . '-content';
1436
-                            $template_form_fields[ $field_id ]         = $extra_array;
1437
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1438
-                                                                         . $reference_field
1439
-                                                                         . '][content]['
1440
-                                                                         . $extra_field . ']';
1441
-                            $css_class                                 = isset($extra_array['css_class'])
1442
-                                ? $extra_array['css_class']
1443
-                                : '';
1444
-
1445
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1446
-                                                                              && in_array($extra_field, $v_fields, true)
1447
-                                                                              && (
1448
-                                                                                  is_array($validators[ $extra_field ])
1449
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1450
-                                                                              )
1451
-                                ? 'validate-error ' . $css_class
1452
-                                : $css_class;
1453
-
1454
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1455
-                                                                          && isset($content[ $extra_field ])
1456
-                                ? $content[ $extra_field ]
1457
-                                : '';
1458
-
1459
-                            // do we have a validation error?  if we do then let's use that value instead
1460
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1461
-                                ? $validators[ $extra_field ]['value']
1462
-                                : $template_form_fields[ $field_id ]['value'];
1463
-
1464
-
1465
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1466
-
1467
-                            // shortcode selector
1468
-                            $field_name_to_use                                   = $extra_field === 'main'
1469
-                                ? 'content'
1470
-                                : $extra_field;
1471
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1472
-                                $field_name_to_use,
1473
-                                $field_id
1474
-                            );
1475
-
1476
-                            if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1477
-                                // we want to decode the entities
1478
-                                $template_form_fields[ $field_id ]['value'] =
1479
-                                    $template_form_fields[ $field_id ]['value'];
1480
-                            }
1481
-                        }
1482
-                        $templatefield_MTP_id          = $reference_field . '-MTP_ID';
1483
-                        $templatefield_templatename_id = $reference_field . '-name';
1484
-
1485
-                        $template_form_fields[ $templatefield_MTP_id ] = [
1486
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1487
-                            'label'      => null,
1488
-                            'input'      => 'hidden',
1489
-                            'type'       => 'int',
1490
-                            'required'   => false,
1491
-                            'validation' => false,
1492
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1493
-                            'css_class'  => '',
1494
-                            'format'     => '%d',
1495
-                            'db-col'     => 'MTP_ID',
1496
-                        ];
1497
-
1498
-                        $template_form_fields[ $templatefield_templatename_id ] = [
1499
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1500
-                            'label'      => null,
1501
-                            'input'      => 'hidden',
1502
-                            'type'       => 'string',
1503
-                            'required'   => false,
1504
-                            'validation' => true,
1505
-                            'value'      => $reference_field,
1506
-                            'css_class'  => '',
1507
-                            'format'     => '%s',
1508
-                            'db-col'     => 'MTP_template_field',
1509
-                        ];
1510
-                    }
1511
-                    continue; // skip the next stuff, we got the necessary fields here for this dataset.
1512
-                } else {
1513
-                    $field_id                                   = $template_field . '-content';
1514
-                    $template_form_fields[ $field_id ]          = $field_setup_array;
1515
-                    $template_form_fields[ $field_id ]['name']  =
1516
-                        'MTP_template_fields[' . $template_field . '][content]';
1517
-                    $message_template                           =
1518
-                        isset($message_templates[ $context ][ $template_field ])
1519
-                            ? $message_templates[ $context ][ $template_field ]
1520
-                            : null;
1521
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1522
-                                                                  && is_array($message_templates[ $context ])
1523
-                                                                  && $message_template instanceof EE_Message_Template
1524
-                        ? $message_template->get('MTP_content')
1525
-                        : '';
1526
-
1527
-                    // do we have a validator error for this field?  if we do then we'll use that value instead
1528
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1529
-                        ? $validators[ $template_field ]['value']
1530
-                        : $template_form_fields[ $field_id ]['value'];
1531
-
1532
-
1533
-                    $template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1534
-                    $css_class                                      = isset($field_setup_array['css_class'])
1535
-                        ? $field_setup_array['css_class']
1536
-                        : '';
1537
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1538
-                                                                      && in_array($template_field, $v_fields, true)
1539
-                                                                      && isset($validators[ $template_field ]['msg'])
1540
-                        ? 'validate-error ' . $css_class
1541
-                        : $css_class;
1542
-
1543
-                    // shortcode selector
1544
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1545
-                        $template_field,
1546
-                        $field_id
1547
-                    );
1548
-                }
1549
-
1550
-                // k took care of content field(s) now let's take care of others.
1551
-
1552
-                $templatefield_MTP_id                = $template_field . '-MTP_ID';
1553
-                $templatefield_field_templatename_id = $template_field . '-name';
1554
-
1555
-                // foreach template field there are actually two form fields created
1556
-                $template_form_fields[ $templatefield_MTP_id ] = [
1557
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1558
-                    'label'      => null,
1559
-                    'input'      => 'hidden',
1560
-                    'type'       => 'int',
1561
-                    'required'   => false,
1562
-                    'validation' => true,
1563
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1564
-                    'css_class'  => '',
1565
-                    'format'     => '%d',
1566
-                    'db-col'     => 'MTP_ID',
1567
-                ];
1568
-
1569
-                $template_form_fields[ $templatefield_field_templatename_id ] = [
1570
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1571
-                    'label'      => null,
1572
-                    'input'      => 'hidden',
1573
-                    'type'       => 'string',
1574
-                    'required'   => false,
1575
-                    'validation' => true,
1576
-                    'value'      => $template_field,
1577
-                    'css_class'  => '',
1578
-                    'format'     => '%s',
1579
-                    'db-col'     => 'MTP_template_field',
1580
-                ];
1581
-            }
1582
-
1583
-            // add other fields
1584
-            $template_form_fields['ee-msg-current-context'] = [
1585
-                'name'       => 'MTP_context',
1586
-                'label'      => null,
1587
-                'input'      => 'hidden',
1588
-                'type'       => 'string',
1589
-                'required'   => false,
1590
-                'validation' => true,
1591
-                'value'      => $context,
1592
-                'css_class'  => '',
1593
-                'format'     => '%s',
1594
-                'db-col'     => 'MTP_context',
1595
-            ];
1596
-
1597
-            $template_form_fields['ee-msg-grp-id'] = [
1598
-                'name'       => 'GRP_ID',
1599
-                'label'      => null,
1600
-                'input'      => 'hidden',
1601
-                'type'       => 'int',
1602
-                'required'   => false,
1603
-                'validation' => true,
1604
-                'value'      => $GRP_ID,
1605
-                'css_class'  => '',
1606
-                'format'     => '%d',
1607
-                'db-col'     => 'GRP_ID',
1608
-            ];
1609
-
1610
-            $template_form_fields['ee-msg-messenger'] = [
1611
-                'name'       => 'MTP_messenger',
1612
-                'label'      => null,
1613
-                'input'      => 'hidden',
1614
-                'type'       => 'string',
1615
-                'required'   => false,
1616
-                'validation' => true,
1617
-                'value'      => $message_template_group->messenger(),
1618
-                'css_class'  => '',
1619
-                'format'     => '%s',
1620
-                'db-col'     => 'MTP_messenger',
1621
-            ];
1622
-
1623
-            $template_form_fields['ee-msg-message-type'] = [
1624
-                'name'       => 'MTP_message_type',
1625
-                'label'      => null,
1626
-                'input'      => 'hidden',
1627
-                'type'       => 'string',
1628
-                'required'   => false,
1629
-                'validation' => true,
1630
-                'value'      => $message_template_group->message_type(),
1631
-                'css_class'  => '',
1632
-                'format'     => '%s',
1633
-                'db-col'     => 'MTP_message_type',
1634
-            ];
1635
-
1636
-            $sidebar_form_fields['ee-msg-is-global'] = [
1637
-                'name'       => 'MTP_is_global',
1638
-                'label'      => esc_html__('Global Template', 'event_espresso'),
1639
-                'input'      => 'hidden',
1640
-                'type'       => 'int',
1641
-                'required'   => false,
1642
-                'validation' => true,
1643
-                'value'      => $message_template_group->get('MTP_is_global'),
1644
-                'css_class'  => '',
1645
-                'format'     => '%d',
1646
-                'db-col'     => 'MTP_is_global',
1647
-            ];
1648
-
1649
-            $sidebar_form_fields['ee-msg-is-override'] = [
1650
-                'name'       => 'MTP_is_override',
1651
-                'label'      => esc_html__('Override all custom', 'event_espresso'),
1652
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1653
-                'type'       => 'int',
1654
-                'required'   => false,
1655
-                'validation' => true,
1656
-                'value'      => $message_template_group->get('MTP_is_override'),
1657
-                'css_class'  => '',
1658
-                'format'     => '%d',
1659
-                'db-col'     => 'MTP_is_override',
1660
-            ];
1661
-
1662
-            $sidebar_form_fields['ee-msg-is-active'] = [
1663
-                'name'       => 'MTP_is_active',
1664
-                'label'      => esc_html__('Active Template', 'event_espresso'),
1665
-                'input'      => 'hidden',
1666
-                'type'       => 'int',
1667
-                'required'   => false,
1668
-                'validation' => true,
1669
-                'value'      => $message_template_group->is_active(),
1670
-                'css_class'  => '',
1671
-                'format'     => '%d',
1672
-                'db-col'     => 'MTP_is_active',
1673
-            ];
1674
-
1675
-            $sidebar_form_fields['ee-msg-deleted'] = [
1676
-                'name'       => 'MTP_deleted',
1677
-                'label'      => null,
1678
-                'input'      => 'hidden',
1679
-                'type'       => 'int',
1680
-                'required'   => false,
1681
-                'validation' => true,
1682
-                'value'      => $message_template_group->get('MTP_deleted'),
1683
-                'css_class'  => '',
1684
-                'format'     => '%d',
1685
-                'db-col'     => 'MTP_deleted',
1686
-            ];
1687
-            $sidebar_form_fields['ee-msg-author']  = [
1688
-                'name'       => 'MTP_user_id',
1689
-                'label'      => esc_html__('Author', 'event_espresso'),
1690
-                'input'      => 'hidden',
1691
-                'type'       => 'int',
1692
-                'required'   => false,
1693
-                'validation' => false,
1694
-                'value'      => $message_template_group->user(),
1695
-                'format'     => '%d',
1696
-                'db-col'     => 'MTP_user_id',
1697
-            ];
1698
-
1699
-            $sidebar_form_fields['ee-msg-route'] = [
1700
-                'name'  => 'action',
1701
-                'input' => 'hidden',
1702
-                'type'  => 'string',
1703
-                'value' => $action,
1704
-            ];
1705
-
1706
-            $sidebar_form_fields['ee-msg-id']        = [
1707
-                'name'  => 'id',
1708
-                'input' => 'hidden',
1709
-                'type'  => 'int',
1710
-                'value' => $GRP_ID,
1711
-            ];
1712
-            $sidebar_form_fields['ee-msg-evt-nonce'] = [
1713
-                'name'  => $action . '_nonce',
1714
-                'input' => 'hidden',
1715
-                'type'  => 'string',
1716
-                'value' => wp_create_nonce($action . '_nonce'),
1717
-            ];
1718
-
1719
-            if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1720
-                $sidebar_form_fields['ee-msg-template-switch'] = [
1721
-                    'name'  => 'template_switch',
1722
-                    'input' => 'hidden',
1723
-                    'type'  => 'int',
1724
-                    'value' => 1,
1725
-                ];
1726
-            }
1727
-
1728
-
1729
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1730
-            $sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1731
-        } //end if ( !empty($template_field_structure) )
1732
-
1733
-        // set extra content for publish box
1734
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1735
-        $this->_set_publish_post_box_vars(
1736
-            'id',
1737
-            $GRP_ID,
1738
-            false,
1739
-            add_query_arg(
1740
-                ['action' => 'global_mtps'],
1741
-                $this->_admin_base_url
1742
-            )
1743
-        );
1744
-
1745
-        // add preview button
1746
-        $preview_url    = parent::add_query_args_and_nonce(
1747
-            [
1748
-                'message_type' => $message_template_group->message_type(),
1749
-                'messenger'    => $message_template_group->messenger(),
1750
-                'context'      => $context,
1751
-                'GRP_ID'       => $GRP_ID,
1752
-                'evt_id'       => $EVT_ID,
1753
-                'action'       => 'preview_message',
1754
-            ],
1755
-            $this->_admin_base_url
1756
-        );
1757
-        $preview_button = '<a href="' . $preview_url . '" class="button--secondary messages-preview-button">'
1758
-                          . esc_html__('Preview', 'event_espresso')
1759
-                          . '</a>';
1760
-
1761
-
1762
-        // setup context switcher
1763
-        $context_switcher_args = [
1764
-            'page'    => 'espresso_messages',
1765
-            'action'  => 'edit_message_template',
1766
-            'id'      => $GRP_ID,
1767
-            'evt_id'  => $EVT_ID,
1768
-            'context' => $context,
1769
-            'extra'   => $preview_button,
1770
-        ];
1771
-        $this->_set_context_switcher($message_template_group, $context_switcher_args);
1772
-
1773
-
1774
-        // main box
1775
-        $this->_template_args['template_fields']                         = $template_fields;
1776
-        $this->_template_args['sidebar_box_id']                          = 'details';
1777
-        $this->_template_args['action']                                  = $action;
1778
-        $this->_template_args['context']                                 = $context;
1779
-        $this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1780
-        $this->_template_args['learn_more_about_message_templates_link'] =
1781
-            $this->_learn_more_about_message_templates_link();
1782
-
1783
-
1784
-        $this->_template_args['before_admin_page_content'] = '<div class="ee-msg-admin-header">';
1785
-        $this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1786
-            $message_template_group,
1787
-            $context,
1788
-            $context_label
1789
-        );
1790
-        $this->_template_args['before_admin_page_content'] .= $this->add_context_switcher();
1791
-        $this->_template_args['before_admin_page_content'] .= '</div>';
1792
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1793
-        $this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1794
-
1795
-        $this->_template_path = $this->_template_args['GRP_ID']
1796
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1797
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1798
-
1799
-        // send along EE_Message_Template_Group object for further template use.
1800
-        $this->_template_args['MTP'] = $message_template_group;
1801
-
1802
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1803
-            $this->_template_path,
1804
-            $this->_template_args,
1805
-            true
1806
-        );
1807
-
1808
-
1809
-        // finally, let's set the admin_page title
1810
-        $this->_admin_page_title = sprintf(esc_html__('Editing %s', 'event_espresso'), $title);
1811
-
1812
-
1813
-        // we need to take care of setting the shortcodes property for use elsewhere.
1814
-        $this->_set_shortcodes();
1815
-
1816
-
1817
-        // final template wrapper
1818
-        $this->display_admin_page_with_sidebar();
1819
-    }
1820
-
1821
-
1822
-    public function filter_tinymce_init($mceInit, $editor_id)
1823
-    {
1824
-        return $mceInit;
1825
-    }
1826
-
1827
-
1828
-    public function add_context_switcher()
1829
-    {
1830
-        return $this->_context_switcher;
1831
-    }
1832
-
1833
-
1834
-    /**
1835
-     * Adds the activation/deactivation toggle for the message template context.
1836
-     *
1837
-     * @param EE_Message_Template_Group $message_template_group
1838
-     * @param string                    $context
1839
-     * @param string                    $context_label
1840
-     * @return string
1841
-     * @throws DomainException
1842
-     * @throws EE_Error
1843
-     * @throws InvalidIdentifierException
1844
-     */
1845
-    protected function add_active_context_element(
1846
-        EE_Message_Template_Group $message_template_group,
1847
-        $context,
1848
-        $context_label
1849
-    ) {
1850
-        $template_args = [
1851
-            'context'                   => $context,
1852
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1853
-            'is_active'                 => $message_template_group->is_context_active($context),
1854
-            'on_off_action'             => $message_template_group->is_context_active($context)
1855
-                ? 'context-off'
1856
-                : 'context-on',
1857
-            'context_label'             => str_replace(['(', ')'], '', $context_label),
1858
-            'message_template_group_id' => $message_template_group->ID(),
1859
-        ];
1860
-        return EEH_Template::display_template(
1861
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1862
-            $template_args,
1863
-            true
1864
-        );
1865
-    }
1866
-
1867
-
1868
-    /**
1869
-     * Ajax callback for `toggle_context_template` ajax action.
1870
-     * Handles toggling the message context on or off.
1871
-     *
1872
-     * @throws EE_Error
1873
-     * @throws InvalidArgumentException
1874
-     * @throws InvalidDataTypeException
1875
-     * @throws InvalidIdentifierException
1876
-     * @throws InvalidInterfaceException
1877
-     */
1878
-    public function toggle_context_template()
1879
-    {
1880
-        $success = true;
1881
-        // check for required data
1882
-        if (
1883
-            ! isset(
1884
-                $this->_req_data['message_template_group_id'],
1885
-                $this->_req_data['context'],
1886
-                $this->_req_data['status']
1887
-            )
1888
-        ) {
1889
-            EE_Error::add_error(
1890
-                esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1891
-                __FILE__,
1892
-                __FUNCTION__,
1893
-                __LINE__
1894
-            );
1895
-            $success = false;
1896
-        }
1897
-
1898
-        $nonce     = isset($this->_req_data['toggle_context_nonce'])
1899
-            ? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1900
-            : '';
1901
-        $nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1902
-        $this->_verify_nonce($nonce, $nonce_ref);
1903
-        $status = $this->_req_data['status'];
1904
-        if ($status !== 'off' && $status !== 'on') {
1905
-            EE_Error::add_error(
1906
-                sprintf(
1907
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1908
-                    $this->_req_data['status']
1909
-                ),
1910
-                __FILE__,
1911
-                __FUNCTION__,
1912
-                __LINE__
1913
-            );
1914
-            $success = false;
1915
-        }
1916
-        $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1917
-            $this->_req_data['message_template_group_id']
1918
-        );
1919
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1920
-            EE_Error::add_error(
1921
-                sprintf(
1922
-                    esc_html__(
1923
-                        'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1924
-                        'event_espresso'
1925
-                    ),
1926
-                    $this->_req_data['message_template_group_id'],
1927
-                    'EE_Message_Template_Group'
1928
-                ),
1929
-                __FILE__,
1930
-                __FUNCTION__,
1931
-                __LINE__
1932
-            );
1933
-            $success = false;
1934
-        }
1935
-        if ($success) {
1936
-            $success = $status === 'off'
1937
-                ? $message_template_group->deactivate_context($this->_req_data['context'])
1938
-                : $message_template_group->activate_context($this->_req_data['context']);
1939
-        }
1940
-        $this->_template_args['success'] = $success;
1941
-        $this->_return_json();
1942
-    }
1943
-
1944
-
1945
-    public function _add_form_element_before()
1946
-    {
1947
-        return '<form method="post" action="'
1948
-               . $this->_template_args['edit_message_template_form_url']
1949
-               . '" id="ee-msg-edit-frm">';
1950
-    }
1951
-
1952
-
1953
-    public function _add_form_element_after()
1954
-    {
1955
-        return '</form>';
1956
-    }
1957
-
1958
-
1959
-    /**
1960
-     * This executes switching the template pack for a message template.
1961
-     *
1962
-     * @throws EE_Error
1963
-     * @throws InvalidDataTypeException
1964
-     * @throws InvalidInterfaceException
1965
-     * @throws InvalidArgumentException
1966
-     * @throws ReflectionException
1967
-     * @since 4.5.0
1968
-     */
1969
-    public function switch_template_pack()
1970
-    {
1971
-        $GRP_ID        = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1972
-        $template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1973
-
1974
-        // verify we have needed values.
1975
-        if (empty($GRP_ID) || empty($template_pack)) {
1976
-            $this->_template_args['error'] = true;
1977
-            EE_Error::add_error(
1978
-                esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1979
-                __FILE__,
1980
-                __FUNCTION__,
1981
-                __LINE__
1982
-            );
1983
-        } else {
1984
-            // get template, set the new template_pack and then reset to default
1985
-            /** @type EE_Message_Template_Group $message_template_group */
1986
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1987
-
1988
-            $message_template_group->set_template_pack_name($template_pack);
1989
-            $this->_req_data['msgr'] = $message_template_group->messenger();
1990
-            $this->_req_data['mt']   = $message_template_group->message_type();
1991
-
1992
-            $query_args = $this->_reset_to_default_template();
1993
-
1994
-            if (empty($query_args['id'])) {
1995
-                EE_Error::add_error(
1996
-                    esc_html__(
1997
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
1998
-                        'event_espresso'
1999
-                    ),
2000
-                    __FILE__,
2001
-                    __FUNCTION__,
2002
-                    __LINE__
2003
-                );
2004
-                $this->_template_args['error'] = true;
2005
-            } else {
2006
-                $template_label       = $message_template_group->get_template_pack()->label;
2007
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
2008
-                EE_Error::add_success(
2009
-                    sprintf(
2010
-                        esc_html__(
2011
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2012
-                            'event_espresso'
2013
-                        ),
2014
-                        $template_label,
2015
-                        $template_pack_labels->template_pack
2016
-                    )
2017
-                );
2018
-                // generate the redirect url for js.
2019
-                $url                                          = self::add_query_args_and_nonce(
2020
-                    $query_args,
2021
-                    $this->_admin_base_url
2022
-                );
2023
-                $this->_template_args['data']['redirect_url'] = $url;
2024
-                $this->_template_args['success']              = true;
2025
-            }
2026
-
2027
-            $this->_return_json();
2028
-        }
2029
-    }
2030
-
2031
-
2032
-    /**
2033
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2034
-     * they want.
2035
-     *
2036
-     * @access protected
2037
-     * @return array|null
2038
-     * @throws EE_Error
2039
-     * @throws InvalidArgumentException
2040
-     * @throws InvalidDataTypeException
2041
-     * @throws InvalidInterfaceException
2042
-     */
2043
-    protected function _reset_to_default_template()
2044
-    {
2045
-
2046
-        $templates = [];
2047
-        $GRP_ID    = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2048
-        // we need to make sure we've got the info we need.
2049
-        if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2050
-            EE_Error::add_error(
2051
-                esc_html__(
2052
-                    'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
2053
-                    'event_espresso'
2054
-                ),
2055
-                __FILE__,
2056
-                __FUNCTION__,
2057
-                __LINE__
2058
-            );
2059
-        }
2060
-
2061
-        // all templates will be reset to whatever the defaults are
2062
-        // for the global template matching the messenger and message type.
2063
-        $success = ! empty($GRP_ID) ? true : false;
2064
-
2065
-        if ($success) {
2066
-            // let's first determine if the incoming template is a global template,
2067
-            // if it isn't then we need to get the global template matching messenger and message type.
2068
-            // $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2069
-
2070
-
2071
-            // note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2072
-            $success = $this->_delete_mtp_permanently($GRP_ID, false);
2073
-
2074
-            if ($success) {
2075
-                // if successfully deleted, lets generate the new ones.
2076
-                // Note. We set GLOBAL to true, because resets on ANY template
2077
-                // will use the related global template defaults for regeneration.
2078
-                // This means that if a custom template is reset it resets to whatever the related global template is.
2079
-                // HOWEVER, we DO keep the template pack and template variation set
2080
-                // for the current custom template when resetting.
2081
-                $templates = $this->_generate_new_templates(
2082
-                    $this->_req_data['msgr'],
2083
-                    $this->_req_data['mt'],
2084
-                    $GRP_ID,
2085
-                    true
2086
-                );
2087
-            }
2088
-        }
2089
-
2090
-        // any error messages?
2091
-        if (! $success) {
2092
-            EE_Error::add_error(
2093
-                esc_html__(
2094
-                    'Something went wrong with deleting existing templates. Unable to reset to default',
2095
-                    'event_espresso'
2096
-                ),
2097
-                __FILE__,
2098
-                __FUNCTION__,
2099
-                __LINE__
2100
-            );
2101
-        }
2102
-
2103
-        // all good, let's add a success message!
2104
-        if ($success && ! empty($templates)) {
2105
-            // the info for the template we generated is the first element in the returned array
2106
-            // $templates = $templates[0];
2107
-            EE_Error::overwrite_success();
2108
-            EE_Error::add_success(esc_html__('Templates have been reset to defaults.', 'event_espresso'));
2109
-        }
2110
-
2111
-
2112
-        $query_args = [
2113
-            'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2114
-            'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2115
-            'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2116
-        ];
2117
-
2118
-        // if called via ajax then we return query args otherwise redirect
2119
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2120
-            return $query_args;
2121
-        } else {
2122
-            $this->_redirect_after_action(false, '', '', $query_args, true);
2123
-
2124
-            return null;
2125
-        }
2126
-    }
2127
-
2128
-
2129
-    /**
2130
-     * Retrieve and set the message preview for display.
2131
-     *
2132
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2133
-     * @return string
2134
-     * @throws ReflectionException
2135
-     * @throws EE_Error
2136
-     * @throws InvalidArgumentException
2137
-     * @throws InvalidDataTypeException
2138
-     * @throws InvalidInterfaceException
2139
-     */
2140
-    public function _preview_message($send = false)
2141
-    {
2142
-        // first make sure we've got the necessary parameters
2143
-        if (
2144
-            ! (
2145
-                $this->_req_data['message_type']
2146
-                && $this->_req_data['messenger']
2147
-                && $this->_req_data['GRP_ID']
2148
-            )
2149
-        ) {
2150
-            EE_Error::add_error(
2151
-                esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2152
-                __FILE__,
2153
-                __FUNCTION__,
2154
-                __LINE__
2155
-            );
2156
-        }
2157
-
2158
-        // get the preview!
2159
-        $preview = EED_Messages::preview_message(
2160
-            $this->_req_data['message_type'],
2161
-            $this->_req_data['context'],
2162
-            $this->_req_data['messenger'],
2163
-            $send
2164
-        );
2165
-
2166
-        if ($send) {
2167
-            return $preview;
2168
-        }
2169
-
2170
-        // if we have an evt_id set on the request, use it.
2171
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2172
-            ? absint($this->_req_data['evt_id'])
2173
-            : false;
2174
-
2175
-        // let's add a button to go back to the edit view
2176
-        $query_args             = [
2177
-            'id'      => $this->_req_data['GRP_ID'],
2178
-            'evt_id'  => $EVT_ID,
2179
-            'context' => $this->_req_data['context'],
2180
-            'action'  => 'edit_message_template',
2181
-        ];
2182
-        $go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2183
-        $preview_button         = '<a href="'
2184
-                                  . $go_back_url
2185
-                                  . '" class="button--secondary messages-preview-go-back-button">'
2186
-                                  . esc_html__('Go Back to Edit', 'event_espresso')
2187
-                                  . '</a>';
2188
-        $message_types          = $this->get_installed_message_types();
2189
-        $active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
2190
-        $active_messenger_label = $active_messenger instanceof EE_messenger
2191
-            ? ucwords($active_messenger->label['singular'])
2192
-            : esc_html__('Unknown Messenger', 'event_espresso');
2193
-        // let's provide a helpful title for context
2194
-        $preview_title = sprintf(
2195
-            esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2196
-            $active_messenger_label,
2197
-            ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2198
-        );
2199
-        if (empty($preview)) {
2200
-            $this->noEventsErrorMessage();
2201
-        }
2202
-        // setup display of preview.
2203
-        $this->_admin_page_title                    = $preview_title;
2204
-        $this->_template_args['admin_page_title']   = $preview_title;
2205
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2206
-        $this->_template_args['data']['force_json'] = true;
2207
-
2208
-        return '';
2209
-    }
2210
-
2211
-
2212
-    /**
2213
-     * Used to set an error if there are no events available for generating a preview/test send.
2214
-     *
2215
-     * @param bool $test_send Whether the error should be generated for the context of a test send.
2216
-     */
2217
-    protected function noEventsErrorMessage($test_send = false)
2218
-    {
2219
-        $events_url = parent::add_query_args_and_nonce(
2220
-            [
2221
-                'action' => 'default',
2222
-                'page'   => 'espresso_events',
2223
-            ],
2224
-            admin_url('admin.php')
2225
-        );
2226
-        $message    = $test_send
2227
-            ? esc_html__(
2228
-                'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2229
-                'event_espresso'
2230
-            )
2231
-            : esc_html__(
2232
-                'There is no preview for this message template available because there are no events created yet. The preview system uses actual events for generating the preview. %1$sGo see your events%2$s!',
2233
-                'event_espresso'
2234
-            );
2235
-
2236
-        EE_Error::add_attention(
2237
-            sprintf(
2238
-                $message,
2239
-                "<a href='{$events_url}'>",
2240
-                '</a>'
2241
-            )
2242
-        );
2243
-    }
2244
-
2245
-
2246
-    /**
2247
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2248
-     * gets called automatically.
2249
-     *
2250
-     * @return string
2251
-     * @since 4.5.0
2252
-     *
2253
-     */
2254
-    protected function _display_preview_message()
2255
-    {
2256
-        $this->display_admin_page_with_no_sidebar();
2257
-    }
2258
-
2259
-
2260
-    /**
2261
-     * registers metaboxes that should show up on the "edit_message_template" page
2262
-     *
2263
-     * @access protected
2264
-     * @return void
2265
-     */
2266
-    protected function _register_edit_meta_boxes()
2267
-    {
2268
-        $this->addMetaBox(
2269
-            'mtp_valid_shortcodes',
2270
-            esc_html__('Valid Shortcodes', 'event_espresso'),
2271
-            [$this, 'shortcode_meta_box'],
2272
-            $this->_current_screen->id,
2273
-            'side',
2274
-            'default'
2275
-        );
2276
-        $this->addMetaBox(
2277
-            'mtp_extra_actions',
2278
-            esc_html__('Extra Actions', 'event_espresso'),
2279
-            [$this, 'extra_actions_meta_box'],
2280
-            $this->_current_screen->id,
2281
-            'side',
2282
-            'high'
2283
-        );
2284
-        $this->addMetaBox(
2285
-            'mtp_templates',
2286
-            esc_html__('Template Styles', 'event_espresso'),
2287
-            [$this, 'template_pack_meta_box'],
2288
-            $this->_current_screen->id,
2289
-            'side',
2290
-            'high'
2291
-        );
2292
-    }
2293
-
2294
-
2295
-    /**
2296
-     * metabox content for all template pack and variation selection.
2297
-     *
2298
-     * @return string
2299
-     * @throws DomainException
2300
-     * @throws EE_Error
2301
-     * @throws InvalidArgumentException
2302
-     * @throws ReflectionException
2303
-     * @throws InvalidDataTypeException
2304
-     * @throws InvalidInterfaceException
2305
-     * @since 4.5.0
2306
-     */
2307
-    public function template_pack_meta_box()
2308
-    {
2309
-        $this->_set_message_template_group();
2310
-
2311
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
2312
-
2313
-        $tp_select_values = [];
2314
-
2315
-        foreach ($tp_collection as $tp) {
2316
-            // only include template packs that support this messenger and message type!
2317
-            $supports = $tp->get_supports();
2318
-            if (
2319
-                ! isset($supports[ $this->_message_template_group->messenger() ])
2320
-                || ! in_array(
2321
-                    $this->_message_template_group->message_type(),
2322
-                    $supports[ $this->_message_template_group->messenger() ],
2323
-                    true
2324
-                )
2325
-            ) {
2326
-                // not supported
2327
-                continue;
2328
-            }
2329
-
2330
-            $tp_select_values[] = [
2331
-                'text' => $tp->label,
2332
-                'id'   => $tp->dbref,
2333
-            ];
2334
-        }
2335
-
2336
-        // if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2337
-        // the default template pack.  This still allows for the odd template pack to override.
2338
-        if (empty($tp_select_values)) {
2339
-            $tp_select_values[] = [
2340
-                'text' => esc_html__('Default', 'event_espresso'),
2341
-                'id'   => 'default',
2342
-            ];
2343
-        }
2344
-
2345
-        // setup variation select values for the currently selected template.
2346
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
2347
-            $this->_message_template_group->messenger(),
2348
-            $this->_message_template_group->message_type()
2349
-        );
2350
-        $variations_select_values = [];
2351
-        foreach ($variations as $variation => $label) {
2352
-            $variations_select_values[] = [
2353
-                'text' => $label,
2354
-                'id'   => $variation,
2355
-            ];
2356
-        }
2357
-
2358
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2359
-
2360
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2361
-            'MTP_template_pack',
2362
-            $tp_select_values,
2363
-            $this->_message_template_group->get_template_pack_name()
2364
-        );
2365
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
2366
-            'MTP_template_variation',
2367
-            $variations_select_values,
2368
-            $this->_message_template_group->get_template_pack_variation()
2369
-        );
2370
-        $template_args['template_pack_label']            = $template_pack_labels->template_pack;
2371
-        $template_args['template_variation_label']       = $template_pack_labels->template_variation;
2372
-        $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2373
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2374
-
2375
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2376
-
2377
-        EEH_Template::display_template($template, $template_args);
2378
-    }
2379
-
2380
-
2381
-    /**
2382
-     * This meta box holds any extra actions related to Message Templates
2383
-     * For now, this includes Resetting templates to defaults and sending a test email.
2384
-     *
2385
-     * @access  public
2386
-     * @return void
2387
-     * @throws EE_Error
2388
-     */
2389
-    public function extra_actions_meta_box()
2390
-    {
2391
-        $template_form_fields = [];
2392
-
2393
-        $extra_args = [
2394
-            'msgr'   => $this->_message_template_group->messenger(),
2395
-            'mt'     => $this->_message_template_group->message_type(),
2396
-            'GRP_ID' => $this->_message_template_group->GRP_ID(),
2397
-        ];
2398
-        // first we need to see if there are any fields
2399
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2400
-
2401
-        if (! empty($fields)) {
2402
-            // yup there be fields
2403
-            foreach ($fields as $field => $config) {
2404
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2405
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2406
-                $default  = isset($config['default']) ? $config['default'] : '';
2407
-                $default  = isset($config['value']) ? $config['value'] : $default;
2408
-
2409
-                // if type is hidden and the value is empty
2410
-                // something may have gone wrong so let's correct with the defaults
2411
-                $fix                = $config['input'] === 'hidden'
2412
-                                      && isset($existing[ $field ])
2413
-                                      && empty($existing[ $field ])
2414
-                    ? $default
2415
-                    : '';
2416
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2417
-                    ? $existing[ $field ]
2418
-                    : $fix;
2419
-
2420
-                $template_form_fields[ $field_id ] = [
2421
-                    'name'       => 'test_settings_fld[' . $field . ']',
2422
-                    'label'      => $config['label'],
2423
-                    'input'      => $config['input'],
2424
-                    'type'       => $config['type'],
2425
-                    'required'   => $config['required'],
2426
-                    'validation' => $config['validation'],
2427
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2428
-                    'css_class'  => $config['css_class'],
2429
-                    'options'    => isset($config['options']) ? $config['options'] : [],
2430
-                    'default'    => $default,
2431
-                    'format'     => $config['format'],
2432
-                ];
2433
-            }
2434
-        }
2435
-
2436
-        $test_settings_html = ! empty($template_form_fields)
2437
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2438
-            : '';
2439
-
2440
-        // print out $test_settings_fields
2441
-        if (! empty($test_settings_html)) {
2442
-            $test_settings_html .= '<input type="submit" class="button--primary mtp-test-button alignright" ';
2443
-            $test_settings_html .= 'name="test_button" value="';
2444
-            $test_settings_html .= esc_html__('Test Send', 'event_espresso');
2445
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2446
-        }
2447
-
2448
-        // and button
2449
-        $test_settings_html .= '<p>';
2450
-        $test_settings_html .= esc_html__('Need to reset this message type and start over?', 'event_espresso');
2451
-        $test_settings_html .= '</p>';
2452
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2453
-        $test_settings_html .= $this->get_action_link_or_button(
2454
-            'reset_to_default',
2455
-            'reset',
2456
-            $extra_args,
2457
-            'button--primary reset-default-button'
2458
-        );
2459
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2460
-        echo $test_settings_html; // already escaped
2461
-    }
2462
-
2463
-
2464
-    /**
2465
-     * This returns the shortcode selector skeleton for a given context and field.
2466
-     *
2467
-     * @param string $field           The name of the field retrieving shortcodes for.
2468
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2469
-     * @return string
2470
-     * @throws DomainException
2471
-     * @throws EE_Error
2472
-     * @throws InvalidArgumentException
2473
-     * @throws ReflectionException
2474
-     * @throws InvalidDataTypeException
2475
-     * @throws InvalidInterfaceException
2476
-     * @since 4.9.rc.000
2477
-     */
2478
-    protected function _get_shortcode_selector($field, $linked_input_id)
2479
-    {
2480
-        $template_args = [
2481
-            'shortcodes'      => $this->_get_shortcodes([$field], true),
2482
-            'fieldname'       => $field,
2483
-            'linked_input_id' => $linked_input_id,
2484
-        ];
2485
-
2486
-        return EEH_Template::display_template(
2487
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2488
-            $template_args,
2489
-            true
2490
-        );
2491
-    }
2492
-
2493
-
2494
-    /**
2495
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2496
-     * page)
2497
-     *
2498
-     * @access public
2499
-     * @return void
2500
-     * @throws EE_Error
2501
-     * @throws InvalidArgumentException
2502
-     * @throws ReflectionException
2503
-     * @throws InvalidDataTypeException
2504
-     * @throws InvalidInterfaceException
2505
-     */
2506
-    public function shortcode_meta_box()
2507
-    {
2508
-        $shortcodes = $this->_get_shortcodes([], false);
2509
-        // just make sure the shortcodes property is set
2510
-        // $messenger = $this->_message_template_group->messenger_obj();
2511
-        // now let's set the content depending on the status of the shortcodes array
2512
-        if (empty($shortcodes)) {
2513
-            echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2514
-            return;
2515
-        }
2516
-        ?>
25
+	/**
26
+	 * @type string $_active_message_type_name
27
+	 */
28
+	protected $_active_message_type_name = '';
29
+
30
+	/**
31
+	 * @type EE_messenger $_active_messenger
32
+	 */
33
+	protected $_active_messenger;
34
+
35
+	protected $_activate_state;
36
+
37
+	protected $_activate_meta_box_type;
38
+
39
+	protected $_current_message_meta_box;
40
+
41
+	protected $_current_message_meta_box_object;
42
+
43
+	protected $_context_switcher;
44
+
45
+	protected $_shortcodes           = [];
46
+
47
+	protected $_active_messengers    = [];
48
+
49
+	protected $_active_message_types = [];
50
+
51
+	/**
52
+	 * @var EE_Message_Template_Group $_message_template_group
53
+	 */
54
+	protected $_message_template_group;
55
+
56
+	protected $_m_mt_settings = [];
57
+
58
+
59
+	/**
60
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
61
+	 * IF there is no group then it gets automatically set to the Default template pack.
62
+	 *
63
+	 * @since 4.5.0
64
+	 *
65
+	 * @var EE_Messages_Template_Pack
66
+	 */
67
+	protected $_template_pack;
68
+
69
+
70
+	/**
71
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
72
+	 * group is.  If there is no group then it automatically gets set to default.
73
+	 *
74
+	 * @since 4.5.0
75
+	 *
76
+	 * @var string
77
+	 */
78
+	protected $_variation;
79
+
80
+
81
+	/**
82
+	 * @param bool $routing
83
+	 * @throws EE_Error
84
+	 */
85
+	public function __construct($routing = true)
86
+	{
87
+		// make sure messages autoloader is running
88
+		EED_Messages::set_autoloaders();
89
+		parent::__construct($routing);
90
+	}
91
+
92
+
93
+	protected function _init_page_props()
94
+	{
95
+		$this->page_slug        = EE_MSG_PG_SLUG;
96
+		$this->page_label       = esc_html__('Messages Settings', 'event_espresso');
97
+		$this->_admin_base_url  = EE_MSG_ADMIN_URL;
98
+		$this->_admin_base_path = EE_MSG_ADMIN;
99
+
100
+		$this->_activate_state = isset($this->_req_data['activate_state'])
101
+			? (array) $this->_req_data['activate_state']
102
+			: [];
103
+
104
+		$this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
105
+		$this->_load_message_resource_manager();
106
+	}
107
+
108
+
109
+	/**
110
+	 * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
111
+	 *
112
+	 * @throws EE_Error
113
+	 * @throws InvalidDataTypeException
114
+	 * @throws InvalidInterfaceException
115
+	 * @throws InvalidArgumentException
116
+	 * @throws ReflectionException
117
+	 */
118
+	protected function _load_message_resource_manager()
119
+	{
120
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
121
+	}
122
+
123
+
124
+	/**
125
+	 * @return array
126
+	 * @throws EE_Error
127
+	 * @throws InvalidArgumentException
128
+	 * @throws InvalidDataTypeException
129
+	 * @throws InvalidInterfaceException
130
+	 * @deprecated 4.9.9.rc.014
131
+	 */
132
+	public function get_messengers_for_list_table()
133
+	{
134
+		EE_Error::doing_it_wrong(
135
+			__METHOD__,
136
+			sprintf(
137
+				esc_html__(
138
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
139
+					'event_espresso'
140
+				),
141
+				'Messages_Admin_Page::get_messengers_select_input()'
142
+			),
143
+			'4.9.9.rc.014'
144
+		);
145
+
146
+		$m_values          = [];
147
+		$active_messengers = EEM_Message::instance()->get_all(['group_by' => 'MSG_messenger']);
148
+		// setup messengers for selects
149
+		$i = 1;
150
+		foreach ($active_messengers as $active_messenger) {
151
+			if ($active_messenger instanceof EE_Message) {
152
+				$m_values[ $i ]['id']   = $active_messenger->messenger();
153
+				$m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
154
+				$i++;
155
+			}
156
+		}
157
+
158
+		return $m_values;
159
+	}
160
+
161
+
162
+	/**
163
+	 * @return array
164
+	 * @throws EE_Error
165
+	 * @throws InvalidArgumentException
166
+	 * @throws InvalidDataTypeException
167
+	 * @throws InvalidInterfaceException
168
+	 * @deprecated 4.9.9.rc.014
169
+	 */
170
+	public function get_message_types_for_list_table()
171
+	{
172
+		EE_Error::doing_it_wrong(
173
+			__METHOD__,
174
+			sprintf(
175
+				esc_html__(
176
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
177
+					'event_espresso'
178
+				),
179
+				'Messages_Admin_Page::get_message_types_select_input()'
180
+			),
181
+			'4.9.9.rc.014'
182
+		);
183
+
184
+		$mt_values       = [];
185
+		$active_messages = EEM_Message::instance()->get_all(['group_by' => 'MSG_message_type']);
186
+		$i               = 1;
187
+		foreach ($active_messages as $active_message) {
188
+			if ($active_message instanceof EE_Message) {
189
+				$mt_values[ $i ]['id']   = $active_message->message_type();
190
+				$mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
191
+				$i++;
192
+			}
193
+		}
194
+
195
+		return $mt_values;
196
+	}
197
+
198
+
199
+	/**
200
+	 * @return array
201
+	 * @throws EE_Error
202
+	 * @throws InvalidArgumentException
203
+	 * @throws InvalidDataTypeException
204
+	 * @throws InvalidInterfaceException
205
+	 * @deprecated 4.9.9.rc.014
206
+	 */
207
+	public function get_contexts_for_message_types_for_list_table()
208
+	{
209
+		EE_Error::doing_it_wrong(
210
+			__METHOD__,
211
+			sprintf(
212
+				esc_html__(
213
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
214
+					'event_espresso'
215
+				),
216
+				'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
217
+			),
218
+			'4.9.9.rc.014'
219
+		);
220
+
221
+		$contexts                = [];
222
+		$active_message_contexts = EEM_Message::instance()->get_all(['group_by' => 'MSG_context']);
223
+		foreach ($active_message_contexts as $active_message) {
224
+			if ($active_message instanceof EE_Message) {
225
+				$message_type = $active_message->message_type_object();
226
+				if ($message_type instanceof EE_message_type) {
227
+					$message_type_contexts = $message_type->get_contexts();
228
+					foreach ($message_type_contexts as $context => $context_details) {
229
+						$contexts[ $context ] = $context_details['label'];
230
+					}
231
+				}
232
+			}
233
+		}
234
+
235
+		return $contexts;
236
+	}
237
+
238
+
239
+	/**
240
+	 * Generate select input with provided messenger options array.
241
+	 *
242
+	 * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
243
+	 *                                 labels.
244
+	 * @return string
245
+	 * @throws EE_Error
246
+	 */
247
+	public function get_messengers_select_input($messenger_options)
248
+	{
249
+		// if empty or just one value then just return an empty string
250
+		if (
251
+			empty($messenger_options)
252
+			|| ! is_array($messenger_options)
253
+			|| count($messenger_options) === 1
254
+		) {
255
+			return '';
256
+		}
257
+		// merge in default
258
+		$messenger_options = array_merge(
259
+			['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
260
+			$messenger_options
261
+		);
262
+		$input             = new EE_Select_Input(
263
+			$messenger_options,
264
+			[
265
+				'html_name'  => 'ee_messenger_filter_by',
266
+				'html_id'    => 'ee_messenger_filter_by',
267
+				'html_class' => 'wide',
268
+				'default'    => isset($this->_req_data['ee_messenger_filter_by'])
269
+					? sanitize_title($this->_req_data['ee_messenger_filter_by'])
270
+					: 'none_selected',
271
+			]
272
+		);
273
+
274
+		return $input->get_html_for_input();
275
+	}
276
+
277
+
278
+	/**
279
+	 * Generate select input with provided message type options array.
280
+	 *
281
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
282
+	 *                                    message type labels
283
+	 * @return string
284
+	 * @throws EE_Error
285
+	 */
286
+	public function get_message_types_select_input($message_type_options)
287
+	{
288
+		// if empty or count of options is 1 then just return an empty string
289
+		if (
290
+			empty($message_type_options)
291
+			|| ! is_array($message_type_options)
292
+			|| count($message_type_options) === 1
293
+		) {
294
+			return '';
295
+		}
296
+		// merge in default
297
+		$message_type_options = array_merge(
298
+			['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
299
+			$message_type_options
300
+		);
301
+		$input                = new EE_Select_Input(
302
+			$message_type_options,
303
+			[
304
+				'html_name'  => 'ee_message_type_filter_by',
305
+				'html_id'    => 'ee_message_type_filter_by',
306
+				'html_class' => 'wide',
307
+				'default'    => isset($this->_req_data['ee_message_type_filter_by'])
308
+					? sanitize_title($this->_req_data['ee_message_type_filter_by'])
309
+					: 'none_selected',
310
+			]
311
+		);
312
+
313
+		return $input->get_html_for_input();
314
+	}
315
+
316
+
317
+	/**
318
+	 * Generate select input with provide message type contexts array.
319
+	 *
320
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
321
+	 *                               context label.
322
+	 * @return string
323
+	 * @throws EE_Error
324
+	 */
325
+	public function get_contexts_for_message_types_select_input($context_options)
326
+	{
327
+		// if empty or count of options is one then just return empty string
328
+		if (
329
+			empty($context_options)
330
+			|| ! is_array($context_options)
331
+			|| count($context_options) === 1
332
+		) {
333
+			return '';
334
+		}
335
+		// merge in default
336
+		$context_options = array_merge(
337
+			['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
338
+			$context_options
339
+		);
340
+		$input           = new EE_Select_Input(
341
+			$context_options,
342
+			[
343
+				'html_name'  => 'ee_context_filter_by',
344
+				'html_id'    => 'ee_context_filter_by',
345
+				'html_class' => 'wide',
346
+				'default'    => isset($this->_req_data['ee_context_filter_by'])
347
+					? sanitize_title($this->_req_data['ee_context_filter_by'])
348
+					: 'none_selected',
349
+			]
350
+		);
351
+
352
+		return $input->get_html_for_input();
353
+	}
354
+
355
+
356
+	protected function _ajax_hooks()
357
+	{
358
+		add_action('wp_ajax_activate_messenger', [$this, 'activate_messenger_toggle']);
359
+		add_action('wp_ajax_activate_mt', [$this, 'activate_mt_toggle']);
360
+		add_action('wp_ajax_ee_msgs_save_settings', [$this, 'save_settings']);
361
+		add_action('wp_ajax_ee_msgs_update_mt_form', [$this, 'update_mt_form']);
362
+		add_action('wp_ajax_switch_template_pack', [$this, 'switch_template_pack']);
363
+		add_action('wp_ajax_toggle_context_template', [$this, 'toggle_context_template']);
364
+	}
365
+
366
+
367
+	protected function _define_page_props()
368
+	{
369
+		$this->_admin_page_title = $this->page_label;
370
+		$this->_labels           = [
371
+			'buttons'    => [
372
+				'add'    => esc_html__('Add New Message Template', 'event_espresso'),
373
+				'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
374
+				'delete' => esc_html__('Delete Message Template', 'event_espresso'),
375
+			],
376
+			'publishbox' => esc_html__('Update Actions', 'event_espresso'),
377
+		];
378
+	}
379
+
380
+
381
+	/**
382
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
383
+	 *
384
+	 * @access protected
385
+	 * @return void
386
+	 */
387
+	protected function _set_page_routes()
388
+	{
389
+		$grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
390
+			? $this->_req_data['GRP_ID']
391
+			: 0;
392
+		$grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
393
+			? $this->_req_data['id']
394
+			: $grp_id;
395
+		$msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
396
+			? $this->_req_data['MSG_ID']
397
+			: 0;
398
+
399
+		$this->_page_routes = [
400
+			'default'                          => [
401
+				'func'       => '_message_queue_list_table',
402
+				'capability' => 'ee_read_global_messages',
403
+			],
404
+			'global_mtps'                      => [
405
+				'func'       => '_ee_default_messages_overview_list_table',
406
+				'capability' => 'ee_read_global_messages',
407
+			],
408
+			'custom_mtps'                      => [
409
+				'func'       => '_custom_mtps_preview',
410
+				'capability' => 'ee_read_messages',
411
+			],
412
+			'add_new_message_template'         => [
413
+				'func'       => '_add_message_template',
414
+				'capability' => 'ee_edit_messages',
415
+				'noheader'   => true,
416
+			],
417
+			'edit_message_template'            => [
418
+				'func'       => '_edit_message_template',
419
+				'capability' => 'ee_edit_message',
420
+				'obj_id'     => $grp_id,
421
+			],
422
+			'preview_message'                  => [
423
+				'func'               => '_preview_message',
424
+				'capability'         => 'ee_read_message',
425
+				'obj_id'             => $grp_id,
426
+				'noheader'           => true,
427
+				'headers_sent_route' => 'display_preview_message',
428
+			],
429
+			'display_preview_message'          => [
430
+				'func'       => '_display_preview_message',
431
+				'capability' => 'ee_read_message',
432
+				'obj_id'     => $grp_id,
433
+			],
434
+			'insert_message_template'          => [
435
+				'func'       => '_insert_or_update_message_template',
436
+				'capability' => 'ee_edit_messages',
437
+				'args'       => ['new' => true],
438
+				'noheader'   => true,
439
+			],
440
+			'update_message_template'          => [
441
+				'func'       => '_insert_or_update_message_template',
442
+				'capability' => 'ee_edit_message',
443
+				'obj_id'     => $grp_id,
444
+				'args'       => ['new' => false],
445
+				'noheader'   => true,
446
+			],
447
+			'trash_message_template'           => [
448
+				'func'       => '_trash_or_restore_message_template',
449
+				'capability' => 'ee_delete_message',
450
+				'obj_id'     => $grp_id,
451
+				'args'       => ['trash' => true, 'all' => true],
452
+				'noheader'   => true,
453
+			],
454
+			'trash_message_template_context'   => [
455
+				'func'       => '_trash_or_restore_message_template',
456
+				'capability' => 'ee_delete_message',
457
+				'obj_id'     => $grp_id,
458
+				'args'       => ['trash' => true],
459
+				'noheader'   => true,
460
+			],
461
+			'restore_message_template'         => [
462
+				'func'       => '_trash_or_restore_message_template',
463
+				'capability' => 'ee_delete_message',
464
+				'obj_id'     => $grp_id,
465
+				'args'       => ['trash' => false, 'all' => true],
466
+				'noheader'   => true,
467
+			],
468
+			'restore_message_template_context' => [
469
+				'func'       => '_trash_or_restore_message_template',
470
+				'capability' => 'ee_delete_message',
471
+				'obj_id'     => $grp_id,
472
+				'args'       => ['trash' => false],
473
+				'noheader'   => true,
474
+			],
475
+			'delete_message_template'          => [
476
+				'func'       => '_delete_message_template',
477
+				'capability' => 'ee_delete_message',
478
+				'obj_id'     => $grp_id,
479
+				'noheader'   => true,
480
+			],
481
+			'reset_to_default'                 => [
482
+				'func'       => '_reset_to_default_template',
483
+				'capability' => 'ee_edit_message',
484
+				'obj_id'     => $grp_id,
485
+				'noheader'   => true,
486
+			],
487
+			'settings'                         => [
488
+				'func'       => '_settings',
489
+				'capability' => 'manage_options',
490
+			],
491
+			'update_global_settings'           => [
492
+				'func'       => '_update_global_settings',
493
+				'capability' => 'manage_options',
494
+				'noheader'   => true,
495
+			],
496
+			'generate_now'                     => [
497
+				'func'       => '_generate_now',
498
+				'capability' => 'ee_send_message',
499
+				'noheader'   => true,
500
+			],
501
+			'generate_and_send_now'            => [
502
+				'func'       => '_generate_and_send_now',
503
+				'capability' => 'ee_send_message',
504
+				'noheader'   => true,
505
+			],
506
+			'queue_for_resending'              => [
507
+				'func'       => '_queue_for_resending',
508
+				'capability' => 'ee_send_message',
509
+				'noheader'   => true,
510
+			],
511
+			'send_now'                         => [
512
+				'func'       => '_send_now',
513
+				'capability' => 'ee_send_message',
514
+				'noheader'   => true,
515
+			],
516
+			'delete_ee_message'                => [
517
+				'func'       => '_delete_ee_messages',
518
+				'capability' => 'ee_delete_messages',
519
+				'noheader'   => true,
520
+			],
521
+			'delete_ee_messages'               => [
522
+				'func'       => '_delete_ee_messages',
523
+				'capability' => 'ee_delete_messages',
524
+				'noheader'   => true,
525
+				'obj_id'     => $msg_id,
526
+			],
527
+		];
528
+	}
529
+
530
+
531
+	protected function _set_page_config()
532
+	{
533
+		$this->_page_config = [
534
+			'default'                  => [
535
+				'nav'           => [
536
+					'label' => esc_html__('Message Activity', 'event_espresso'),
537
+					'order' => 10,
538
+				],
539
+				'list_table'    => 'EE_Message_List_Table',
540
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
541
+				'require_nonce' => false,
542
+			],
543
+			'global_mtps'              => [
544
+				'nav'           => [
545
+					'label' => esc_html__('Default Message Templates', 'event_espresso'),
546
+					'order' => 20,
547
+				],
548
+				'list_table'    => 'Messages_Template_List_Table',
549
+				'help_tabs'     => [
550
+					'messages_overview_help_tab'                                => [
551
+						'title'    => esc_html__('Messages Overview', 'event_espresso'),
552
+						'filename' => 'messages_overview',
553
+					],
554
+					'messages_overview_messages_table_column_headings_help_tab' => [
555
+						'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
556
+						'filename' => 'messages_overview_table_column_headings',
557
+					],
558
+					'messages_overview_messages_filters_help_tab'               => [
559
+						'title'    => esc_html__('Message Filters', 'event_espresso'),
560
+						'filename' => 'messages_overview_filters',
561
+					],
562
+					'messages_overview_messages_views_help_tab'                 => [
563
+						'title'    => esc_html__('Message Views', 'event_espresso'),
564
+						'filename' => 'messages_overview_views',
565
+					],
566
+					'message_overview_message_types_help_tab'                   => [
567
+						'title'    => esc_html__('Message Types', 'event_espresso'),
568
+						'filename' => 'messages_overview_types',
569
+					],
570
+					'messages_overview_messengers_help_tab'                     => [
571
+						'title'    => esc_html__('Messengers', 'event_espresso'),
572
+						'filename' => 'messages_overview_messengers',
573
+					],
574
+				],
575
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
576
+				// 'help_tour'     => array('Messages_Overview_Help_Tour'),
577
+				'require_nonce' => false,
578
+			],
579
+			'custom_mtps'              => [
580
+				'nav'           => [
581
+					'label' => esc_html__('Custom Message Templates', 'event_espresso'),
582
+					'order' => 30,
583
+				],
584
+				'help_tabs'     => [],
585
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
586
+				// 'help_tour'     => array(),
587
+				'require_nonce' => false,
588
+			],
589
+			'add_new_message_template' => [
590
+				'nav'           => [
591
+					'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
592
+					'order'      => 5,
593
+					'persistent' => false,
594
+				],
595
+				'require_nonce' => false,
596
+			],
597
+			'edit_message_template'    => [
598
+				'labels'        => [
599
+					'buttons'    => [
600
+						'reset' => esc_html__('Reset Templates', 'event_espresso'),
601
+					],
602
+					'publishbox' => esc_html__('Update Actions', 'event_espresso'),
603
+				],
604
+				'nav'           => [
605
+					'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
606
+					'order'      => 5,
607
+					'persistent' => false,
608
+					'url'        => '',
609
+				],
610
+				'metaboxes'     => ['_publish_post_box', '_register_edit_meta_boxes'],
611
+				'has_metaboxes' => true,
612
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
613
+				// 'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
614
+				'help_tabs'     => [
615
+					'edit_message_template'            => [
616
+						'title'    => esc_html__('Message Template Editor', 'event_espresso'),
617
+						'callback' => 'edit_message_template_help_tab',
618
+					],
619
+					'message_templates_help_tab'       => [
620
+						'title'    => esc_html__('Message Templates', 'event_espresso'),
621
+						'filename' => 'messages_templates',
622
+					],
623
+					'message_template_shortcodes'      => [
624
+						'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
625
+						'callback' => 'message_template_shortcodes_help_tab',
626
+					],
627
+					'message_preview_help_tab'         => [
628
+						'title'    => esc_html__('Message Preview', 'event_espresso'),
629
+						'filename' => 'messages_preview',
630
+					],
631
+					'messages_overview_other_help_tab' => [
632
+						'title'    => esc_html__('Messages Other', 'event_espresso'),
633
+						'filename' => 'messages_overview_other',
634
+					],
635
+				],
636
+				'require_nonce' => false,
637
+			],
638
+			'display_preview_message'  => [
639
+				'nav'           => [
640
+					'label'      => esc_html__('Message Preview', 'event_espresso'),
641
+					'order'      => 5,
642
+					'url'        => '',
643
+					'persistent' => false,
644
+				],
645
+				'help_tabs'     => [
646
+					'preview_message' => [
647
+						'title'    => esc_html__('About Previews', 'event_espresso'),
648
+						'callback' => 'preview_message_help_tab',
649
+					],
650
+				],
651
+				'require_nonce' => false,
652
+			],
653
+			'settings'                 => [
654
+				'nav'           => [
655
+					'label' => esc_html__('Settings', 'event_espresso'),
656
+					'order' => 40,
657
+				],
658
+				'metaboxes'     => ['_messages_settings_metaboxes'],
659
+				'help_tabs'     => [
660
+					'messages_settings_help_tab'               => [
661
+						'title'    => esc_html__('Messages Settings', 'event_espresso'),
662
+						'filename' => 'messages_settings',
663
+					],
664
+					'messages_settings_message_types_help_tab' => [
665
+						'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
666
+						'filename' => 'messages_settings_message_types',
667
+					],
668
+					'messages_settings_messengers_help_tab'    => [
669
+						'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
670
+						'filename' => 'messages_settings_messengers',
671
+					],
672
+				],
673
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
674
+				// 'help_tour'     => array('Messages_Settings_Help_Tour'),
675
+				'require_nonce' => false,
676
+			],
677
+		];
678
+	}
679
+
680
+
681
+	protected function _add_screen_options()
682
+	{
683
+		// todo
684
+	}
685
+
686
+
687
+	protected function _add_screen_options_global_mtps()
688
+	{
689
+		/**
690
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
691
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
692
+		 */
693
+		$page_title              = $this->_admin_page_title;
694
+		$this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
695
+		$this->_per_page_screen_option();
696
+		$this->_admin_page_title = $page_title;
697
+	}
698
+
699
+
700
+	protected function _add_screen_options_default()
701
+	{
702
+		$this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
703
+		$this->_per_page_screen_option();
704
+	}
705
+
706
+
707
+	// none of the below group are currently used for Messages
708
+	protected function _add_feature_pointers()
709
+	{
710
+	}
711
+
712
+
713
+	public function admin_init()
714
+	{
715
+	}
716
+
717
+
718
+	public function admin_notices()
719
+	{
720
+	}
721
+
722
+
723
+	public function admin_footer_scripts()
724
+	{
725
+	}
726
+
727
+
728
+	public function messages_help_tab()
729
+	{
730
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
731
+	}
732
+
733
+
734
+	public function messengers_help_tab()
735
+	{
736
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
737
+	}
738
+
739
+
740
+	public function message_types_help_tab()
741
+	{
742
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
743
+	}
744
+
745
+
746
+	public function messages_overview_help_tab()
747
+	{
748
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
749
+	}
750
+
751
+
752
+	public function message_templates_help_tab()
753
+	{
754
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
755
+	}
756
+
757
+
758
+	public function edit_message_template_help_tab()
759
+	{
760
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
761
+						. esc_attr__('Editor Title', 'event_espresso')
762
+						. '" />';
763
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
764
+						. esc_attr__('Context Switcher and Preview', 'event_espresso')
765
+						. '" />';
766
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
767
+						. esc_attr__('Message Template Form Fields', 'event_espresso')
768
+						. '" />';
769
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
770
+						. esc_attr__('Shortcodes Metabox', 'event_espresso')
771
+						. '" />';
772
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
773
+						. esc_attr__('Publish Metabox', 'event_espresso')
774
+						. '" />';
775
+		EEH_Template::display_template(
776
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
777
+			$args
778
+		);
779
+	}
780
+
781
+
782
+	public function message_template_shortcodes_help_tab()
783
+	{
784
+		$this->_set_shortcodes();
785
+		$args['shortcodes'] = $this->_shortcodes;
786
+		EEH_Template::display_template(
787
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
788
+			$args
789
+		);
790
+	}
791
+
792
+
793
+	public function preview_message_help_tab()
794
+	{
795
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
796
+	}
797
+
798
+
799
+	public function settings_help_tab()
800
+	{
801
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
802
+						. '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
803
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
804
+						. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
805
+		$args['img3'] = '<div class="switch">'
806
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
807
+						. ' type="checkbox" checked="checked">'
808
+						. '<label for="ee-on-off-toggle-on"></label>'
809
+						. '</div>';
810
+		$args['img4'] = '<div class="switch">'
811
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
812
+						. ' type="checkbox">'
813
+						. '<label for="ee-on-off-toggle-on"></label>'
814
+						. '</div>';
815
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
816
+	}
817
+
818
+
819
+	public function load_scripts_styles()
820
+	{
821
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
822
+		wp_enqueue_style('espresso_ee_msg');
823
+
824
+		wp_register_script(
825
+			'ee-messages-settings',
826
+			EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
827
+			['jquery-ui-droppable', 'ee-serialize-full-array'],
828
+			EVENT_ESPRESSO_VERSION,
829
+			true
830
+		);
831
+		wp_register_script(
832
+			'ee-msg-list-table-js',
833
+			EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
834
+			['ee-dialog'],
835
+			EVENT_ESPRESSO_VERSION
836
+		);
837
+	}
838
+
839
+
840
+	public function load_scripts_styles_default()
841
+	{
842
+		wp_enqueue_script('ee-msg-list-table-js');
843
+	}
844
+
845
+
846
+	public function wp_editor_css($mce_css)
847
+	{
848
+		// if we're on the edit_message_template route
849
+		if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
850
+			$message_type_name = $this->_active_message_type_name;
851
+
852
+			// we're going to REPLACE the existing mce css
853
+			// we need to get the css file location from the active messenger
854
+			$mce_css = $this->_active_messenger->get_variation(
855
+				$this->_template_pack,
856
+				$message_type_name,
857
+				true,
858
+				'wpeditor',
859
+				$this->_variation
860
+			);
861
+		}
862
+
863
+		return $mce_css;
864
+	}
865
+
866
+
867
+	public function load_scripts_styles_edit_message_template()
868
+	{
869
+
870
+		$this->_set_shortcodes();
871
+
872
+		EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
873
+			esc_html__(
874
+				'Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
875
+				'event_espresso'
876
+			),
877
+			$this->_message_template_group->messenger_obj()->label['singular'],
878
+			$this->_message_template_group->message_type_obj()->label['singular']
879
+		);
880
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
881
+			'Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
882
+			'event_espresso'
883
+		);
884
+		EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
885
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
886
+			'event_espresso'
887
+		);
888
+
889
+		wp_register_script(
890
+			'ee_msgs_edit_js',
891
+			EE_MSG_ASSETS_URL . 'ee_message_editor.js',
892
+			['jquery'],
893
+			EVENT_ESPRESSO_VERSION
894
+		);
895
+
896
+		wp_enqueue_script('ee_admin_js');
897
+		wp_enqueue_script('ee_msgs_edit_js');
898
+
899
+		// add in special css for tiny_mce
900
+		add_filter('mce_css', [$this, 'wp_editor_css']);
901
+	}
902
+
903
+
904
+	public function load_scripts_styles_display_preview_message()
905
+	{
906
+
907
+		$this->_set_message_template_group();
908
+
909
+		if (isset($this->_req_data['messenger'])) {
910
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
911
+				$this->_req_data['messenger']
912
+			);
913
+		}
914
+
915
+		$message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
916
+
917
+
918
+		wp_enqueue_style(
919
+			'espresso_preview_css',
920
+			$this->_active_messenger->get_variation(
921
+				$this->_template_pack,
922
+				$message_type_name,
923
+				true,
924
+				'preview',
925
+				$this->_variation
926
+			)
927
+		);
928
+	}
929
+
930
+
931
+	public function load_scripts_styles_settings()
932
+	{
933
+		wp_register_style(
934
+			'ee-message-settings',
935
+			EE_MSG_ASSETS_URL . 'ee_message_settings.css',
936
+			[],
937
+			EVENT_ESPRESSO_VERSION
938
+		);
939
+		wp_enqueue_style('ee-text-links');
940
+		wp_enqueue_style('ee-message-settings');
941
+		wp_enqueue_script('ee-messages-settings');
942
+	}
943
+
944
+
945
+	/**
946
+	 * set views array for List Table
947
+	 */
948
+	public function _set_list_table_views_global_mtps()
949
+	{
950
+		$this->_views = [
951
+			'in_use' => [
952
+				'slug'  => 'in_use',
953
+				'label' => esc_html__('In Use', 'event_espresso'),
954
+				'count' => 0,
955
+			],
956
+		];
957
+	}
958
+
959
+
960
+	/**
961
+	 * Set views array for the Custom Template List Table
962
+	 */
963
+	public function _set_list_table_views_custom_mtps()
964
+	{
965
+		$this->_set_list_table_views_global_mtps();
966
+		$this->_views['in_use']['bulk_action'] = [
967
+			'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
968
+		];
969
+	}
970
+
971
+
972
+	/**
973
+	 * set views array for message queue list table
974
+	 *
975
+	 * @throws InvalidDataTypeException
976
+	 * @throws InvalidInterfaceException
977
+	 * @throws InvalidArgumentException
978
+	 * @throws EE_Error
979
+	 * @throws ReflectionException
980
+	 */
981
+	public function _set_list_table_views_default()
982
+	{
983
+		EE_Registry::instance()->load_helper('Template');
984
+
985
+		$common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
986
+			'ee_send_message',
987
+			'message_list_table_bulk_actions'
988
+		)
989
+			? [
990
+				'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
991
+				'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
992
+				'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
993
+				'send_now'              => esc_html__('Send Now', 'event_espresso'),
994
+			]
995
+			: [];
996
+
997
+		$delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
998
+			'ee_delete_messages',
999
+			'message_list_table_bulk_actions'
1000
+		)
1001
+			? ['delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso')]
1002
+			: [];
1003
+
1004
+
1005
+		$this->_views = [
1006
+			'all' => [
1007
+				'slug'        => 'all',
1008
+				'label'       => esc_html__('All', 'event_espresso'),
1009
+				'count'       => 0,
1010
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
1011
+			],
1012
+		];
1013
+
1014
+
1015
+		foreach (EEM_Message::instance()->all_statuses() as $status) {
1016
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1017
+				continue;
1018
+			}
1019
+			$status_bulk_actions = $common_bulk_actions;
1020
+			// unset bulk actions not applying to status
1021
+			if (! empty($status_bulk_actions)) {
1022
+				switch ($status) {
1023
+					case EEM_Message::status_idle:
1024
+					case EEM_Message::status_resend:
1025
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1026
+						break;
1027
+
1028
+					case EEM_Message::status_failed:
1029
+					case EEM_Message::status_debug_only:
1030
+					case EEM_Message::status_messenger_executing:
1031
+						$status_bulk_actions = [];
1032
+						break;
1033
+
1034
+					case EEM_Message::status_incomplete:
1035
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1036
+						break;
1037
+
1038
+					case EEM_Message::status_retry:
1039
+					case EEM_Message::status_sent:
1040
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1041
+						break;
1042
+				}
1043
+			}
1044
+
1045
+			// skip adding messenger executing status to views because it will be included with the Failed view.
1046
+			if ($status === EEM_Message::status_messenger_executing) {
1047
+				continue;
1048
+			}
1049
+
1050
+			$this->_views[ strtolower($status) ] = [
1051
+				'slug'        => strtolower($status),
1052
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1053
+				'count'       => 0,
1054
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1055
+			];
1056
+		}
1057
+	}
1058
+
1059
+
1060
+	protected function _ee_default_messages_overview_list_table()
1061
+	{
1062
+		$this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1063
+		$this->display_admin_list_table_page_with_no_sidebar();
1064
+	}
1065
+
1066
+
1067
+	protected function _message_queue_list_table()
1068
+	{
1069
+		$this->_search_btn_label                   = esc_html__('Message Activity', 'event_espresso');
1070
+		$this->_template_args['per_column']        = 6;
1071
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
1072
+		$this->_template_args['before_list_table'] = '<h3>'
1073
+													 . EEM_Message::instance()->get_pretty_label_for_results()
1074
+													 . '</h3>';
1075
+		$this->display_admin_list_table_page_with_no_sidebar();
1076
+	}
1077
+
1078
+
1079
+	protected function _message_legend_items()
1080
+	{
1081
+
1082
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
1083
+		$action_items       = [];
1084
+
1085
+		foreach ($action_css_classes as $action_item => $action_details) {
1086
+			if ($action_item === 'see_notifications_for') {
1087
+				continue;
1088
+			}
1089
+			$action_items[ $action_item ] = [
1090
+				'class' => $action_details['css_class'],
1091
+				'desc'  => $action_details['label'],
1092
+			];
1093
+		}
1094
+
1095
+		/** @type array $status_items status legend setup */
1096
+		$status_items = [
1097
+			'sent_status'                => [
1098
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_sent,
1099
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1100
+			],
1101
+			'idle_status'                => [
1102
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_idle,
1103
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1104
+			],
1105
+			'failed_status'              => [
1106
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_failed,
1107
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1108
+			],
1109
+			'messenger_executing_status' => [
1110
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_messenger_executing,
1111
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1112
+			],
1113
+			'resend_status'              => [
1114
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_resend,
1115
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1116
+			],
1117
+			'incomplete_status'          => [
1118
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_incomplete,
1119
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1120
+			],
1121
+			'retry_status'               => [
1122
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_retry,
1123
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1124
+			],
1125
+		];
1126
+		if (EEM_Message::debug()) {
1127
+			$status_items['debug_only_status'] = [
1128
+				'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_debug_only,
1129
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1130
+			];
1131
+		}
1132
+
1133
+		return array_merge($action_items, $status_items);
1134
+	}
1135
+
1136
+
1137
+	protected function _custom_mtps_preview()
1138
+	{
1139
+		$this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1140
+		$this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1141
+												. ' alt="' . esc_attr__(
1142
+													'Preview Custom Message Templates screenshot',
1143
+													'event_espresso'
1144
+												) . '" />';
1145
+		$this->_template_args['preview_text'] = '<strong>'
1146
+												. esc_html__(
1147
+													'Custom Message Templates is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
1148
+													'event_espresso'
1149
+												)
1150
+												. '</strong>';
1151
+
1152
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1153
+	}
1154
+
1155
+
1156
+	/**
1157
+	 * get_message_templates
1158
+	 * This gets all the message templates for listing on the overview list.
1159
+	 *
1160
+	 * @access public
1161
+	 * @param int    $perpage the amount of templates groups to show per page
1162
+	 * @param string $type    the current _view we're getting templates for
1163
+	 * @param bool   $count   return count?
1164
+	 * @param bool   $all     disregard any paging info (get all data);
1165
+	 * @param bool   $global  whether to return just global (true) or custom templates (false)
1166
+	 * @return array
1167
+	 * @throws EE_Error
1168
+	 * @throws InvalidArgumentException
1169
+	 * @throws InvalidDataTypeException
1170
+	 * @throws InvalidInterfaceException
1171
+	 */
1172
+	public function get_message_templates(
1173
+		$perpage = 10,
1174
+		$type = 'in_use',
1175
+		$count = false,
1176
+		$all = false,
1177
+		$global = true
1178
+	) {
1179
+
1180
+		$MTP = EEM_Message_Template_Group::instance();
1181
+
1182
+		$this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1183
+		$orderby                    = $this->_req_data['orderby'];
1184
+
1185
+		$order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1186
+			? $this->_req_data['order']
1187
+			: 'ASC';
1188
+
1189
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1190
+			? $this->_req_data['paged']
1191
+			: 1;
1192
+		$per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1193
+			? $this->_req_data['perpage']
1194
+			: $perpage;
1195
+
1196
+		$offset = ($current_page - 1) * $per_page;
1197
+		$limit  = $all ? null : [$offset, $per_page];
1198
+
1199
+
1200
+		// options will match what is in the _views array property
1201
+		switch ($type) {
1202
+			case 'in_use':
1203
+				$templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1204
+				break;
1205
+			default:
1206
+				$templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1207
+		}
1208
+
1209
+		return $templates;
1210
+	}
1211
+
1212
+
1213
+	/**
1214
+	 * filters etc might need a list of installed message_types
1215
+	 *
1216
+	 * @return array an array of message type objects
1217
+	 */
1218
+	public function get_installed_message_types()
1219
+	{
1220
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1221
+		$installed               = [];
1222
+
1223
+		foreach ($installed_message_types as $message_type) {
1224
+			$installed[ $message_type->name ] = $message_type;
1225
+		}
1226
+
1227
+		return $installed;
1228
+	}
1229
+
1230
+
1231
+	/**
1232
+	 * _add_message_template
1233
+	 *
1234
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1235
+	 *
1236
+	 * @param string $message_type
1237
+	 * @param string $messenger
1238
+	 * @param string $GRP_ID
1239
+	 *
1240
+	 * @throws EE_error
1241
+	 */
1242
+	protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1243
+	{
1244
+		// set values override any request data
1245
+		$message_type = ! empty($message_type) ? $message_type : $this->request->getRequestParam('message_type');
1246
+		$messenger    = ! empty($messenger) ? $messenger : $this->request->getRequestParam('messenger');
1247
+		$GRP_ID       = ! empty($GRP_ID) ? $GRP_ID : $this->request->getRequestParam('GRP_ID', 0, 'int');
1248
+
1249
+		// we need messenger and message type.  They should be coming from the event editor. If not here then return error
1250
+		if (empty($message_type) || empty($messenger)) {
1251
+			throw new EE_Error(
1252
+				esc_html__(
1253
+					'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1254
+					'event_espresso'
1255
+				)
1256
+			);
1257
+		}
1258
+
1259
+		// we need the GRP_ID for the template being used as the base for the new template
1260
+		if (empty($GRP_ID)) {
1261
+			throw new EE_Error(
1262
+				esc_html__(
1263
+					'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1264
+					'event_espresso'
1265
+				)
1266
+			);
1267
+		}
1268
+
1269
+		// let's just make sure the template gets generated!
1270
+
1271
+		// we need to reassign some variables for what the insert is expecting
1272
+		$this->_req_data['MTP_messenger']    = $messenger;
1273
+		$this->_req_data['MTP_message_type'] = $message_type;
1274
+		$this->_req_data['GRP_ID']           = $GRP_ID;
1275
+		$this->_insert_or_update_message_template(true);
1276
+	}
1277
+
1278
+
1279
+	/**
1280
+	 * public wrapper for the _add_message_template method
1281
+	 *
1282
+	 * @param string $message_type     message type slug
1283
+	 * @param string $messenger        messenger slug
1284
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1285
+	 *                                 off of.
1286
+	 * @throws EE_error
1287
+	 */
1288
+	public function add_message_template($message_type, $messenger, $GRP_ID)
1289
+	{
1290
+		$this->_add_message_template($message_type, $messenger, $GRP_ID);
1291
+	}
1292
+
1293
+
1294
+	/**
1295
+	 * _edit_message_template
1296
+	 *
1297
+	 * @access protected
1298
+	 * @return void
1299
+	 * @throws InvalidIdentifierException
1300
+	 * @throws DomainException
1301
+	 * @throws EE_Error
1302
+	 * @throws InvalidArgumentException
1303
+	 * @throws ReflectionException
1304
+	 * @throws InvalidDataTypeException
1305
+	 * @throws InvalidInterfaceException
1306
+	 */
1307
+	protected function _edit_message_template()
1308
+	{
1309
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1310
+		$template_fields = '';
1311
+		$sidebar_fields  = '';
1312
+		// we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1313
+		// valid html in the templates.
1314
+		add_filter('tiny_mce_before_init', [$this, 'filter_tinymce_init'], 10, 2);
1315
+
1316
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1317
+			? absint($this->_req_data['id'])
1318
+			: false;
1319
+
1320
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1321
+			? absint($this->_req_data['evt_id'])
1322
+			: false;
1323
+
1324
+		$this->_set_shortcodes(); // this also sets the _message_template property.
1325
+		$message_template_group = $this->_message_template_group;
1326
+		$c_label                = $message_template_group->context_label();
1327
+		$c_config               = $message_template_group->contexts_config();
1328
+
1329
+		reset($c_config);
1330
+		$context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1331
+			? strtolower($this->_req_data['context'])
1332
+			: key($c_config);
1333
+
1334
+
1335
+		if (empty($GRP_ID)) {
1336
+			$action                         = 'insert_message_template';
1337
+			$edit_message_template_form_url = add_query_arg(
1338
+				['action' => $action, 'noheader' => true],
1339
+				EE_MSG_ADMIN_URL
1340
+			);
1341
+		} else {
1342
+			$action                         = 'update_message_template';
1343
+			$edit_message_template_form_url = add_query_arg(
1344
+				['action' => $action, 'noheader' => true],
1345
+				EE_MSG_ADMIN_URL
1346
+			);
1347
+		}
1348
+
1349
+		// set active messenger for this view
1350
+		$this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1351
+			$message_template_group->messenger()
1352
+		);
1353
+		$this->_active_message_type_name = $message_template_group->message_type();
1354
+
1355
+
1356
+		// Do we have any validation errors?
1357
+		$validators = $this->_get_transient();
1358
+		$v_fields   = ! empty($validators) ? array_keys($validators) : [];
1359
+
1360
+
1361
+		// we need to assemble the title from Various details
1362
+		$context_label = sprintf(
1363
+			esc_html__('(%s %s)', 'event_espresso'),
1364
+			$c_config[ $context ]['label'],
1365
+			ucwords($c_label['label'])
1366
+		);
1367
+
1368
+		$title = sprintf(
1369
+			esc_html__(' %s %s Template %s', 'event_espresso'),
1370
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1371
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1372
+			$context_label
1373
+		);
1374
+
1375
+		$this->_template_args['GRP_ID']           = $GRP_ID;
1376
+		$this->_template_args['message_template'] = $message_template_group;
1377
+		$this->_template_args['is_extra_fields']  = false;
1378
+
1379
+
1380
+		// let's get EEH_MSG_Template so we can get template form fields
1381
+		$template_field_structure = EEH_MSG_Template::get_fields(
1382
+			$message_template_group->messenger(),
1383
+			$message_template_group->message_type()
1384
+		);
1385
+
1386
+		if (! $template_field_structure) {
1387
+			$template_field_structure = false;
1388
+			$template_fields          = esc_html__(
1389
+				'There was an error in assembling the fields for this display (you should see an error message)',
1390
+				'event_espresso'
1391
+			);
1392
+		}
1393
+
1394
+
1395
+		$message_templates = $message_template_group->context_templates();
1396
+
1397
+
1398
+		// if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1399
+		// will get handled in the "extra" array.
1400
+		if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1401
+			foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1402
+				unset($template_field_structure[ $context ][ $reference_field ]);
1403
+			}
1404
+		}
1405
+
1406
+		// let's loop through the template_field_structure and actually assemble the input fields!
1407
+		if (! empty($template_field_structure)) {
1408
+			foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1409
+				// if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1410
+				// the extra array and reset them.
1411
+				if ($template_field === 'extra') {
1412
+					$this->_template_args['is_extra_fields'] = true;
1413
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1414
+						$message_template = $message_templates[ $context ][ $reference_field ];
1415
+						$content          = $message_template instanceof EE_Message_Template
1416
+							? $message_template->get('MTP_content')
1417
+							: '';
1418
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1419
+							// let's verify if we need this extra field via the shortcodes parameter.
1420
+							$continue = false;
1421
+							if (isset($extra_array['shortcodes_required'])) {
1422
+								foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1423
+									if (! array_key_exists($shortcode, $this->_shortcodes)) {
1424
+										$continue = true;
1425
+									}
1426
+								}
1427
+								if ($continue) {
1428
+									continue;
1429
+								}
1430
+							}
1431
+
1432
+							$field_id                                  = $reference_field
1433
+																		 . '-'
1434
+																		 . $extra_field
1435
+																		 . '-content';
1436
+							$template_form_fields[ $field_id ]         = $extra_array;
1437
+							$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1438
+																		 . $reference_field
1439
+																		 . '][content]['
1440
+																		 . $extra_field . ']';
1441
+							$css_class                                 = isset($extra_array['css_class'])
1442
+								? $extra_array['css_class']
1443
+								: '';
1444
+
1445
+							$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1446
+																			  && in_array($extra_field, $v_fields, true)
1447
+																			  && (
1448
+																				  is_array($validators[ $extra_field ])
1449
+																				  && isset($validators[ $extra_field ]['msg'])
1450
+																			  )
1451
+								? 'validate-error ' . $css_class
1452
+								: $css_class;
1453
+
1454
+							$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1455
+																		  && isset($content[ $extra_field ])
1456
+								? $content[ $extra_field ]
1457
+								: '';
1458
+
1459
+							// do we have a validation error?  if we do then let's use that value instead
1460
+							$template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1461
+								? $validators[ $extra_field ]['value']
1462
+								: $template_form_fields[ $field_id ]['value'];
1463
+
1464
+
1465
+							$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1466
+
1467
+							// shortcode selector
1468
+							$field_name_to_use                                   = $extra_field === 'main'
1469
+								? 'content'
1470
+								: $extra_field;
1471
+							$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1472
+								$field_name_to_use,
1473
+								$field_id
1474
+							);
1475
+
1476
+							if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1477
+								// we want to decode the entities
1478
+								$template_form_fields[ $field_id ]['value'] =
1479
+									$template_form_fields[ $field_id ]['value'];
1480
+							}
1481
+						}
1482
+						$templatefield_MTP_id          = $reference_field . '-MTP_ID';
1483
+						$templatefield_templatename_id = $reference_field . '-name';
1484
+
1485
+						$template_form_fields[ $templatefield_MTP_id ] = [
1486
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1487
+							'label'      => null,
1488
+							'input'      => 'hidden',
1489
+							'type'       => 'int',
1490
+							'required'   => false,
1491
+							'validation' => false,
1492
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1493
+							'css_class'  => '',
1494
+							'format'     => '%d',
1495
+							'db-col'     => 'MTP_ID',
1496
+						];
1497
+
1498
+						$template_form_fields[ $templatefield_templatename_id ] = [
1499
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1500
+							'label'      => null,
1501
+							'input'      => 'hidden',
1502
+							'type'       => 'string',
1503
+							'required'   => false,
1504
+							'validation' => true,
1505
+							'value'      => $reference_field,
1506
+							'css_class'  => '',
1507
+							'format'     => '%s',
1508
+							'db-col'     => 'MTP_template_field',
1509
+						];
1510
+					}
1511
+					continue; // skip the next stuff, we got the necessary fields here for this dataset.
1512
+				} else {
1513
+					$field_id                                   = $template_field . '-content';
1514
+					$template_form_fields[ $field_id ]          = $field_setup_array;
1515
+					$template_form_fields[ $field_id ]['name']  =
1516
+						'MTP_template_fields[' . $template_field . '][content]';
1517
+					$message_template                           =
1518
+						isset($message_templates[ $context ][ $template_field ])
1519
+							? $message_templates[ $context ][ $template_field ]
1520
+							: null;
1521
+					$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1522
+																  && is_array($message_templates[ $context ])
1523
+																  && $message_template instanceof EE_Message_Template
1524
+						? $message_template->get('MTP_content')
1525
+						: '';
1526
+
1527
+					// do we have a validator error for this field?  if we do then we'll use that value instead
1528
+					$template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1529
+						? $validators[ $template_field ]['value']
1530
+						: $template_form_fields[ $field_id ]['value'];
1531
+
1532
+
1533
+					$template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1534
+					$css_class                                      = isset($field_setup_array['css_class'])
1535
+						? $field_setup_array['css_class']
1536
+						: '';
1537
+					$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1538
+																	  && in_array($template_field, $v_fields, true)
1539
+																	  && isset($validators[ $template_field ]['msg'])
1540
+						? 'validate-error ' . $css_class
1541
+						: $css_class;
1542
+
1543
+					// shortcode selector
1544
+					$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1545
+						$template_field,
1546
+						$field_id
1547
+					);
1548
+				}
1549
+
1550
+				// k took care of content field(s) now let's take care of others.
1551
+
1552
+				$templatefield_MTP_id                = $template_field . '-MTP_ID';
1553
+				$templatefield_field_templatename_id = $template_field . '-name';
1554
+
1555
+				// foreach template field there are actually two form fields created
1556
+				$template_form_fields[ $templatefield_MTP_id ] = [
1557
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1558
+					'label'      => null,
1559
+					'input'      => 'hidden',
1560
+					'type'       => 'int',
1561
+					'required'   => false,
1562
+					'validation' => true,
1563
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1564
+					'css_class'  => '',
1565
+					'format'     => '%d',
1566
+					'db-col'     => 'MTP_ID',
1567
+				];
1568
+
1569
+				$template_form_fields[ $templatefield_field_templatename_id ] = [
1570
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1571
+					'label'      => null,
1572
+					'input'      => 'hidden',
1573
+					'type'       => 'string',
1574
+					'required'   => false,
1575
+					'validation' => true,
1576
+					'value'      => $template_field,
1577
+					'css_class'  => '',
1578
+					'format'     => '%s',
1579
+					'db-col'     => 'MTP_template_field',
1580
+				];
1581
+			}
1582
+
1583
+			// add other fields
1584
+			$template_form_fields['ee-msg-current-context'] = [
1585
+				'name'       => 'MTP_context',
1586
+				'label'      => null,
1587
+				'input'      => 'hidden',
1588
+				'type'       => 'string',
1589
+				'required'   => false,
1590
+				'validation' => true,
1591
+				'value'      => $context,
1592
+				'css_class'  => '',
1593
+				'format'     => '%s',
1594
+				'db-col'     => 'MTP_context',
1595
+			];
1596
+
1597
+			$template_form_fields['ee-msg-grp-id'] = [
1598
+				'name'       => 'GRP_ID',
1599
+				'label'      => null,
1600
+				'input'      => 'hidden',
1601
+				'type'       => 'int',
1602
+				'required'   => false,
1603
+				'validation' => true,
1604
+				'value'      => $GRP_ID,
1605
+				'css_class'  => '',
1606
+				'format'     => '%d',
1607
+				'db-col'     => 'GRP_ID',
1608
+			];
1609
+
1610
+			$template_form_fields['ee-msg-messenger'] = [
1611
+				'name'       => 'MTP_messenger',
1612
+				'label'      => null,
1613
+				'input'      => 'hidden',
1614
+				'type'       => 'string',
1615
+				'required'   => false,
1616
+				'validation' => true,
1617
+				'value'      => $message_template_group->messenger(),
1618
+				'css_class'  => '',
1619
+				'format'     => '%s',
1620
+				'db-col'     => 'MTP_messenger',
1621
+			];
1622
+
1623
+			$template_form_fields['ee-msg-message-type'] = [
1624
+				'name'       => 'MTP_message_type',
1625
+				'label'      => null,
1626
+				'input'      => 'hidden',
1627
+				'type'       => 'string',
1628
+				'required'   => false,
1629
+				'validation' => true,
1630
+				'value'      => $message_template_group->message_type(),
1631
+				'css_class'  => '',
1632
+				'format'     => '%s',
1633
+				'db-col'     => 'MTP_message_type',
1634
+			];
1635
+
1636
+			$sidebar_form_fields['ee-msg-is-global'] = [
1637
+				'name'       => 'MTP_is_global',
1638
+				'label'      => esc_html__('Global Template', 'event_espresso'),
1639
+				'input'      => 'hidden',
1640
+				'type'       => 'int',
1641
+				'required'   => false,
1642
+				'validation' => true,
1643
+				'value'      => $message_template_group->get('MTP_is_global'),
1644
+				'css_class'  => '',
1645
+				'format'     => '%d',
1646
+				'db-col'     => 'MTP_is_global',
1647
+			];
1648
+
1649
+			$sidebar_form_fields['ee-msg-is-override'] = [
1650
+				'name'       => 'MTP_is_override',
1651
+				'label'      => esc_html__('Override all custom', 'event_espresso'),
1652
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1653
+				'type'       => 'int',
1654
+				'required'   => false,
1655
+				'validation' => true,
1656
+				'value'      => $message_template_group->get('MTP_is_override'),
1657
+				'css_class'  => '',
1658
+				'format'     => '%d',
1659
+				'db-col'     => 'MTP_is_override',
1660
+			];
1661
+
1662
+			$sidebar_form_fields['ee-msg-is-active'] = [
1663
+				'name'       => 'MTP_is_active',
1664
+				'label'      => esc_html__('Active Template', 'event_espresso'),
1665
+				'input'      => 'hidden',
1666
+				'type'       => 'int',
1667
+				'required'   => false,
1668
+				'validation' => true,
1669
+				'value'      => $message_template_group->is_active(),
1670
+				'css_class'  => '',
1671
+				'format'     => '%d',
1672
+				'db-col'     => 'MTP_is_active',
1673
+			];
1674
+
1675
+			$sidebar_form_fields['ee-msg-deleted'] = [
1676
+				'name'       => 'MTP_deleted',
1677
+				'label'      => null,
1678
+				'input'      => 'hidden',
1679
+				'type'       => 'int',
1680
+				'required'   => false,
1681
+				'validation' => true,
1682
+				'value'      => $message_template_group->get('MTP_deleted'),
1683
+				'css_class'  => '',
1684
+				'format'     => '%d',
1685
+				'db-col'     => 'MTP_deleted',
1686
+			];
1687
+			$sidebar_form_fields['ee-msg-author']  = [
1688
+				'name'       => 'MTP_user_id',
1689
+				'label'      => esc_html__('Author', 'event_espresso'),
1690
+				'input'      => 'hidden',
1691
+				'type'       => 'int',
1692
+				'required'   => false,
1693
+				'validation' => false,
1694
+				'value'      => $message_template_group->user(),
1695
+				'format'     => '%d',
1696
+				'db-col'     => 'MTP_user_id',
1697
+			];
1698
+
1699
+			$sidebar_form_fields['ee-msg-route'] = [
1700
+				'name'  => 'action',
1701
+				'input' => 'hidden',
1702
+				'type'  => 'string',
1703
+				'value' => $action,
1704
+			];
1705
+
1706
+			$sidebar_form_fields['ee-msg-id']        = [
1707
+				'name'  => 'id',
1708
+				'input' => 'hidden',
1709
+				'type'  => 'int',
1710
+				'value' => $GRP_ID,
1711
+			];
1712
+			$sidebar_form_fields['ee-msg-evt-nonce'] = [
1713
+				'name'  => $action . '_nonce',
1714
+				'input' => 'hidden',
1715
+				'type'  => 'string',
1716
+				'value' => wp_create_nonce($action . '_nonce'),
1717
+			];
1718
+
1719
+			if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1720
+				$sidebar_form_fields['ee-msg-template-switch'] = [
1721
+					'name'  => 'template_switch',
1722
+					'input' => 'hidden',
1723
+					'type'  => 'int',
1724
+					'value' => 1,
1725
+				];
1726
+			}
1727
+
1728
+
1729
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1730
+			$sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1731
+		} //end if ( !empty($template_field_structure) )
1732
+
1733
+		// set extra content for publish box
1734
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1735
+		$this->_set_publish_post_box_vars(
1736
+			'id',
1737
+			$GRP_ID,
1738
+			false,
1739
+			add_query_arg(
1740
+				['action' => 'global_mtps'],
1741
+				$this->_admin_base_url
1742
+			)
1743
+		);
1744
+
1745
+		// add preview button
1746
+		$preview_url    = parent::add_query_args_and_nonce(
1747
+			[
1748
+				'message_type' => $message_template_group->message_type(),
1749
+				'messenger'    => $message_template_group->messenger(),
1750
+				'context'      => $context,
1751
+				'GRP_ID'       => $GRP_ID,
1752
+				'evt_id'       => $EVT_ID,
1753
+				'action'       => 'preview_message',
1754
+			],
1755
+			$this->_admin_base_url
1756
+		);
1757
+		$preview_button = '<a href="' . $preview_url . '" class="button--secondary messages-preview-button">'
1758
+						  . esc_html__('Preview', 'event_espresso')
1759
+						  . '</a>';
1760
+
1761
+
1762
+		// setup context switcher
1763
+		$context_switcher_args = [
1764
+			'page'    => 'espresso_messages',
1765
+			'action'  => 'edit_message_template',
1766
+			'id'      => $GRP_ID,
1767
+			'evt_id'  => $EVT_ID,
1768
+			'context' => $context,
1769
+			'extra'   => $preview_button,
1770
+		];
1771
+		$this->_set_context_switcher($message_template_group, $context_switcher_args);
1772
+
1773
+
1774
+		// main box
1775
+		$this->_template_args['template_fields']                         = $template_fields;
1776
+		$this->_template_args['sidebar_box_id']                          = 'details';
1777
+		$this->_template_args['action']                                  = $action;
1778
+		$this->_template_args['context']                                 = $context;
1779
+		$this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1780
+		$this->_template_args['learn_more_about_message_templates_link'] =
1781
+			$this->_learn_more_about_message_templates_link();
1782
+
1783
+
1784
+		$this->_template_args['before_admin_page_content'] = '<div class="ee-msg-admin-header">';
1785
+		$this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1786
+			$message_template_group,
1787
+			$context,
1788
+			$context_label
1789
+		);
1790
+		$this->_template_args['before_admin_page_content'] .= $this->add_context_switcher();
1791
+		$this->_template_args['before_admin_page_content'] .= '</div>';
1792
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1793
+		$this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1794
+
1795
+		$this->_template_path = $this->_template_args['GRP_ID']
1796
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1797
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1798
+
1799
+		// send along EE_Message_Template_Group object for further template use.
1800
+		$this->_template_args['MTP'] = $message_template_group;
1801
+
1802
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1803
+			$this->_template_path,
1804
+			$this->_template_args,
1805
+			true
1806
+		);
1807
+
1808
+
1809
+		// finally, let's set the admin_page title
1810
+		$this->_admin_page_title = sprintf(esc_html__('Editing %s', 'event_espresso'), $title);
1811
+
1812
+
1813
+		// we need to take care of setting the shortcodes property for use elsewhere.
1814
+		$this->_set_shortcodes();
1815
+
1816
+
1817
+		// final template wrapper
1818
+		$this->display_admin_page_with_sidebar();
1819
+	}
1820
+
1821
+
1822
+	public function filter_tinymce_init($mceInit, $editor_id)
1823
+	{
1824
+		return $mceInit;
1825
+	}
1826
+
1827
+
1828
+	public function add_context_switcher()
1829
+	{
1830
+		return $this->_context_switcher;
1831
+	}
1832
+
1833
+
1834
+	/**
1835
+	 * Adds the activation/deactivation toggle for the message template context.
1836
+	 *
1837
+	 * @param EE_Message_Template_Group $message_template_group
1838
+	 * @param string                    $context
1839
+	 * @param string                    $context_label
1840
+	 * @return string
1841
+	 * @throws DomainException
1842
+	 * @throws EE_Error
1843
+	 * @throws InvalidIdentifierException
1844
+	 */
1845
+	protected function add_active_context_element(
1846
+		EE_Message_Template_Group $message_template_group,
1847
+		$context,
1848
+		$context_label
1849
+	) {
1850
+		$template_args = [
1851
+			'context'                   => $context,
1852
+			'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1853
+			'is_active'                 => $message_template_group->is_context_active($context),
1854
+			'on_off_action'             => $message_template_group->is_context_active($context)
1855
+				? 'context-off'
1856
+				: 'context-on',
1857
+			'context_label'             => str_replace(['(', ')'], '', $context_label),
1858
+			'message_template_group_id' => $message_template_group->ID(),
1859
+		];
1860
+		return EEH_Template::display_template(
1861
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1862
+			$template_args,
1863
+			true
1864
+		);
1865
+	}
1866
+
1867
+
1868
+	/**
1869
+	 * Ajax callback for `toggle_context_template` ajax action.
1870
+	 * Handles toggling the message context on or off.
1871
+	 *
1872
+	 * @throws EE_Error
1873
+	 * @throws InvalidArgumentException
1874
+	 * @throws InvalidDataTypeException
1875
+	 * @throws InvalidIdentifierException
1876
+	 * @throws InvalidInterfaceException
1877
+	 */
1878
+	public function toggle_context_template()
1879
+	{
1880
+		$success = true;
1881
+		// check for required data
1882
+		if (
1883
+			! isset(
1884
+				$this->_req_data['message_template_group_id'],
1885
+				$this->_req_data['context'],
1886
+				$this->_req_data['status']
1887
+			)
1888
+		) {
1889
+			EE_Error::add_error(
1890
+				esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1891
+				__FILE__,
1892
+				__FUNCTION__,
1893
+				__LINE__
1894
+			);
1895
+			$success = false;
1896
+		}
1897
+
1898
+		$nonce     = isset($this->_req_data['toggle_context_nonce'])
1899
+			? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1900
+			: '';
1901
+		$nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1902
+		$this->_verify_nonce($nonce, $nonce_ref);
1903
+		$status = $this->_req_data['status'];
1904
+		if ($status !== 'off' && $status !== 'on') {
1905
+			EE_Error::add_error(
1906
+				sprintf(
1907
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1908
+					$this->_req_data['status']
1909
+				),
1910
+				__FILE__,
1911
+				__FUNCTION__,
1912
+				__LINE__
1913
+			);
1914
+			$success = false;
1915
+		}
1916
+		$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1917
+			$this->_req_data['message_template_group_id']
1918
+		);
1919
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
1920
+			EE_Error::add_error(
1921
+				sprintf(
1922
+					esc_html__(
1923
+						'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1924
+						'event_espresso'
1925
+					),
1926
+					$this->_req_data['message_template_group_id'],
1927
+					'EE_Message_Template_Group'
1928
+				),
1929
+				__FILE__,
1930
+				__FUNCTION__,
1931
+				__LINE__
1932
+			);
1933
+			$success = false;
1934
+		}
1935
+		if ($success) {
1936
+			$success = $status === 'off'
1937
+				? $message_template_group->deactivate_context($this->_req_data['context'])
1938
+				: $message_template_group->activate_context($this->_req_data['context']);
1939
+		}
1940
+		$this->_template_args['success'] = $success;
1941
+		$this->_return_json();
1942
+	}
1943
+
1944
+
1945
+	public function _add_form_element_before()
1946
+	{
1947
+		return '<form method="post" action="'
1948
+			   . $this->_template_args['edit_message_template_form_url']
1949
+			   . '" id="ee-msg-edit-frm">';
1950
+	}
1951
+
1952
+
1953
+	public function _add_form_element_after()
1954
+	{
1955
+		return '</form>';
1956
+	}
1957
+
1958
+
1959
+	/**
1960
+	 * This executes switching the template pack for a message template.
1961
+	 *
1962
+	 * @throws EE_Error
1963
+	 * @throws InvalidDataTypeException
1964
+	 * @throws InvalidInterfaceException
1965
+	 * @throws InvalidArgumentException
1966
+	 * @throws ReflectionException
1967
+	 * @since 4.5.0
1968
+	 */
1969
+	public function switch_template_pack()
1970
+	{
1971
+		$GRP_ID        = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1972
+		$template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1973
+
1974
+		// verify we have needed values.
1975
+		if (empty($GRP_ID) || empty($template_pack)) {
1976
+			$this->_template_args['error'] = true;
1977
+			EE_Error::add_error(
1978
+				esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1979
+				__FILE__,
1980
+				__FUNCTION__,
1981
+				__LINE__
1982
+			);
1983
+		} else {
1984
+			// get template, set the new template_pack and then reset to default
1985
+			/** @type EE_Message_Template_Group $message_template_group */
1986
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1987
+
1988
+			$message_template_group->set_template_pack_name($template_pack);
1989
+			$this->_req_data['msgr'] = $message_template_group->messenger();
1990
+			$this->_req_data['mt']   = $message_template_group->message_type();
1991
+
1992
+			$query_args = $this->_reset_to_default_template();
1993
+
1994
+			if (empty($query_args['id'])) {
1995
+				EE_Error::add_error(
1996
+					esc_html__(
1997
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
1998
+						'event_espresso'
1999
+					),
2000
+					__FILE__,
2001
+					__FUNCTION__,
2002
+					__LINE__
2003
+				);
2004
+				$this->_template_args['error'] = true;
2005
+			} else {
2006
+				$template_label       = $message_template_group->get_template_pack()->label;
2007
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
2008
+				EE_Error::add_success(
2009
+					sprintf(
2010
+						esc_html__(
2011
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2012
+							'event_espresso'
2013
+						),
2014
+						$template_label,
2015
+						$template_pack_labels->template_pack
2016
+					)
2017
+				);
2018
+				// generate the redirect url for js.
2019
+				$url                                          = self::add_query_args_and_nonce(
2020
+					$query_args,
2021
+					$this->_admin_base_url
2022
+				);
2023
+				$this->_template_args['data']['redirect_url'] = $url;
2024
+				$this->_template_args['success']              = true;
2025
+			}
2026
+
2027
+			$this->_return_json();
2028
+		}
2029
+	}
2030
+
2031
+
2032
+	/**
2033
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2034
+	 * they want.
2035
+	 *
2036
+	 * @access protected
2037
+	 * @return array|null
2038
+	 * @throws EE_Error
2039
+	 * @throws InvalidArgumentException
2040
+	 * @throws InvalidDataTypeException
2041
+	 * @throws InvalidInterfaceException
2042
+	 */
2043
+	protected function _reset_to_default_template()
2044
+	{
2045
+
2046
+		$templates = [];
2047
+		$GRP_ID    = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2048
+		// we need to make sure we've got the info we need.
2049
+		if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2050
+			EE_Error::add_error(
2051
+				esc_html__(
2052
+					'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
2053
+					'event_espresso'
2054
+				),
2055
+				__FILE__,
2056
+				__FUNCTION__,
2057
+				__LINE__
2058
+			);
2059
+		}
2060
+
2061
+		// all templates will be reset to whatever the defaults are
2062
+		// for the global template matching the messenger and message type.
2063
+		$success = ! empty($GRP_ID) ? true : false;
2064
+
2065
+		if ($success) {
2066
+			// let's first determine if the incoming template is a global template,
2067
+			// if it isn't then we need to get the global template matching messenger and message type.
2068
+			// $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2069
+
2070
+
2071
+			// note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2072
+			$success = $this->_delete_mtp_permanently($GRP_ID, false);
2073
+
2074
+			if ($success) {
2075
+				// if successfully deleted, lets generate the new ones.
2076
+				// Note. We set GLOBAL to true, because resets on ANY template
2077
+				// will use the related global template defaults for regeneration.
2078
+				// This means that if a custom template is reset it resets to whatever the related global template is.
2079
+				// HOWEVER, we DO keep the template pack and template variation set
2080
+				// for the current custom template when resetting.
2081
+				$templates = $this->_generate_new_templates(
2082
+					$this->_req_data['msgr'],
2083
+					$this->_req_data['mt'],
2084
+					$GRP_ID,
2085
+					true
2086
+				);
2087
+			}
2088
+		}
2089
+
2090
+		// any error messages?
2091
+		if (! $success) {
2092
+			EE_Error::add_error(
2093
+				esc_html__(
2094
+					'Something went wrong with deleting existing templates. Unable to reset to default',
2095
+					'event_espresso'
2096
+				),
2097
+				__FILE__,
2098
+				__FUNCTION__,
2099
+				__LINE__
2100
+			);
2101
+		}
2102
+
2103
+		// all good, let's add a success message!
2104
+		if ($success && ! empty($templates)) {
2105
+			// the info for the template we generated is the first element in the returned array
2106
+			// $templates = $templates[0];
2107
+			EE_Error::overwrite_success();
2108
+			EE_Error::add_success(esc_html__('Templates have been reset to defaults.', 'event_espresso'));
2109
+		}
2110
+
2111
+
2112
+		$query_args = [
2113
+			'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2114
+			'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2115
+			'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2116
+		];
2117
+
2118
+		// if called via ajax then we return query args otherwise redirect
2119
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2120
+			return $query_args;
2121
+		} else {
2122
+			$this->_redirect_after_action(false, '', '', $query_args, true);
2123
+
2124
+			return null;
2125
+		}
2126
+	}
2127
+
2128
+
2129
+	/**
2130
+	 * Retrieve and set the message preview for display.
2131
+	 *
2132
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2133
+	 * @return string
2134
+	 * @throws ReflectionException
2135
+	 * @throws EE_Error
2136
+	 * @throws InvalidArgumentException
2137
+	 * @throws InvalidDataTypeException
2138
+	 * @throws InvalidInterfaceException
2139
+	 */
2140
+	public function _preview_message($send = false)
2141
+	{
2142
+		// first make sure we've got the necessary parameters
2143
+		if (
2144
+			! (
2145
+				$this->_req_data['message_type']
2146
+				&& $this->_req_data['messenger']
2147
+				&& $this->_req_data['GRP_ID']
2148
+			)
2149
+		) {
2150
+			EE_Error::add_error(
2151
+				esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2152
+				__FILE__,
2153
+				__FUNCTION__,
2154
+				__LINE__
2155
+			);
2156
+		}
2157
+
2158
+		// get the preview!
2159
+		$preview = EED_Messages::preview_message(
2160
+			$this->_req_data['message_type'],
2161
+			$this->_req_data['context'],
2162
+			$this->_req_data['messenger'],
2163
+			$send
2164
+		);
2165
+
2166
+		if ($send) {
2167
+			return $preview;
2168
+		}
2169
+
2170
+		// if we have an evt_id set on the request, use it.
2171
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2172
+			? absint($this->_req_data['evt_id'])
2173
+			: false;
2174
+
2175
+		// let's add a button to go back to the edit view
2176
+		$query_args             = [
2177
+			'id'      => $this->_req_data['GRP_ID'],
2178
+			'evt_id'  => $EVT_ID,
2179
+			'context' => $this->_req_data['context'],
2180
+			'action'  => 'edit_message_template',
2181
+		];
2182
+		$go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2183
+		$preview_button         = '<a href="'
2184
+								  . $go_back_url
2185
+								  . '" class="button--secondary messages-preview-go-back-button">'
2186
+								  . esc_html__('Go Back to Edit', 'event_espresso')
2187
+								  . '</a>';
2188
+		$message_types          = $this->get_installed_message_types();
2189
+		$active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
2190
+		$active_messenger_label = $active_messenger instanceof EE_messenger
2191
+			? ucwords($active_messenger->label['singular'])
2192
+			: esc_html__('Unknown Messenger', 'event_espresso');
2193
+		// let's provide a helpful title for context
2194
+		$preview_title = sprintf(
2195
+			esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2196
+			$active_messenger_label,
2197
+			ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2198
+		);
2199
+		if (empty($preview)) {
2200
+			$this->noEventsErrorMessage();
2201
+		}
2202
+		// setup display of preview.
2203
+		$this->_admin_page_title                    = $preview_title;
2204
+		$this->_template_args['admin_page_title']   = $preview_title;
2205
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2206
+		$this->_template_args['data']['force_json'] = true;
2207
+
2208
+		return '';
2209
+	}
2210
+
2211
+
2212
+	/**
2213
+	 * Used to set an error if there are no events available for generating a preview/test send.
2214
+	 *
2215
+	 * @param bool $test_send Whether the error should be generated for the context of a test send.
2216
+	 */
2217
+	protected function noEventsErrorMessage($test_send = false)
2218
+	{
2219
+		$events_url = parent::add_query_args_and_nonce(
2220
+			[
2221
+				'action' => 'default',
2222
+				'page'   => 'espresso_events',
2223
+			],
2224
+			admin_url('admin.php')
2225
+		);
2226
+		$message    = $test_send
2227
+			? esc_html__(
2228
+				'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2229
+				'event_espresso'
2230
+			)
2231
+			: esc_html__(
2232
+				'There is no preview for this message template available because there are no events created yet. The preview system uses actual events for generating the preview. %1$sGo see your events%2$s!',
2233
+				'event_espresso'
2234
+			);
2235
+
2236
+		EE_Error::add_attention(
2237
+			sprintf(
2238
+				$message,
2239
+				"<a href='{$events_url}'>",
2240
+				'</a>'
2241
+			)
2242
+		);
2243
+	}
2244
+
2245
+
2246
+	/**
2247
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2248
+	 * gets called automatically.
2249
+	 *
2250
+	 * @return string
2251
+	 * @since 4.5.0
2252
+	 *
2253
+	 */
2254
+	protected function _display_preview_message()
2255
+	{
2256
+		$this->display_admin_page_with_no_sidebar();
2257
+	}
2258
+
2259
+
2260
+	/**
2261
+	 * registers metaboxes that should show up on the "edit_message_template" page
2262
+	 *
2263
+	 * @access protected
2264
+	 * @return void
2265
+	 */
2266
+	protected function _register_edit_meta_boxes()
2267
+	{
2268
+		$this->addMetaBox(
2269
+			'mtp_valid_shortcodes',
2270
+			esc_html__('Valid Shortcodes', 'event_espresso'),
2271
+			[$this, 'shortcode_meta_box'],
2272
+			$this->_current_screen->id,
2273
+			'side',
2274
+			'default'
2275
+		);
2276
+		$this->addMetaBox(
2277
+			'mtp_extra_actions',
2278
+			esc_html__('Extra Actions', 'event_espresso'),
2279
+			[$this, 'extra_actions_meta_box'],
2280
+			$this->_current_screen->id,
2281
+			'side',
2282
+			'high'
2283
+		);
2284
+		$this->addMetaBox(
2285
+			'mtp_templates',
2286
+			esc_html__('Template Styles', 'event_espresso'),
2287
+			[$this, 'template_pack_meta_box'],
2288
+			$this->_current_screen->id,
2289
+			'side',
2290
+			'high'
2291
+		);
2292
+	}
2293
+
2294
+
2295
+	/**
2296
+	 * metabox content for all template pack and variation selection.
2297
+	 *
2298
+	 * @return string
2299
+	 * @throws DomainException
2300
+	 * @throws EE_Error
2301
+	 * @throws InvalidArgumentException
2302
+	 * @throws ReflectionException
2303
+	 * @throws InvalidDataTypeException
2304
+	 * @throws InvalidInterfaceException
2305
+	 * @since 4.5.0
2306
+	 */
2307
+	public function template_pack_meta_box()
2308
+	{
2309
+		$this->_set_message_template_group();
2310
+
2311
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
2312
+
2313
+		$tp_select_values = [];
2314
+
2315
+		foreach ($tp_collection as $tp) {
2316
+			// only include template packs that support this messenger and message type!
2317
+			$supports = $tp->get_supports();
2318
+			if (
2319
+				! isset($supports[ $this->_message_template_group->messenger() ])
2320
+				|| ! in_array(
2321
+					$this->_message_template_group->message_type(),
2322
+					$supports[ $this->_message_template_group->messenger() ],
2323
+					true
2324
+				)
2325
+			) {
2326
+				// not supported
2327
+				continue;
2328
+			}
2329
+
2330
+			$tp_select_values[] = [
2331
+				'text' => $tp->label,
2332
+				'id'   => $tp->dbref,
2333
+			];
2334
+		}
2335
+
2336
+		// if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2337
+		// the default template pack.  This still allows for the odd template pack to override.
2338
+		if (empty($tp_select_values)) {
2339
+			$tp_select_values[] = [
2340
+				'text' => esc_html__('Default', 'event_espresso'),
2341
+				'id'   => 'default',
2342
+			];
2343
+		}
2344
+
2345
+		// setup variation select values for the currently selected template.
2346
+		$variations               = $this->_message_template_group->get_template_pack()->get_variations(
2347
+			$this->_message_template_group->messenger(),
2348
+			$this->_message_template_group->message_type()
2349
+		);
2350
+		$variations_select_values = [];
2351
+		foreach ($variations as $variation => $label) {
2352
+			$variations_select_values[] = [
2353
+				'text' => $label,
2354
+				'id'   => $variation,
2355
+			];
2356
+		}
2357
+
2358
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2359
+
2360
+		$template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2361
+			'MTP_template_pack',
2362
+			$tp_select_values,
2363
+			$this->_message_template_group->get_template_pack_name()
2364
+		);
2365
+		$template_args['variations_selector']            = EEH_Form_Fields::select_input(
2366
+			'MTP_template_variation',
2367
+			$variations_select_values,
2368
+			$this->_message_template_group->get_template_pack_variation()
2369
+		);
2370
+		$template_args['template_pack_label']            = $template_pack_labels->template_pack;
2371
+		$template_args['template_variation_label']       = $template_pack_labels->template_variation;
2372
+		$template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2373
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2374
+
2375
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2376
+
2377
+		EEH_Template::display_template($template, $template_args);
2378
+	}
2379
+
2380
+
2381
+	/**
2382
+	 * This meta box holds any extra actions related to Message Templates
2383
+	 * For now, this includes Resetting templates to defaults and sending a test email.
2384
+	 *
2385
+	 * @access  public
2386
+	 * @return void
2387
+	 * @throws EE_Error
2388
+	 */
2389
+	public function extra_actions_meta_box()
2390
+	{
2391
+		$template_form_fields = [];
2392
+
2393
+		$extra_args = [
2394
+			'msgr'   => $this->_message_template_group->messenger(),
2395
+			'mt'     => $this->_message_template_group->message_type(),
2396
+			'GRP_ID' => $this->_message_template_group->GRP_ID(),
2397
+		];
2398
+		// first we need to see if there are any fields
2399
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2400
+
2401
+		if (! empty($fields)) {
2402
+			// yup there be fields
2403
+			foreach ($fields as $field => $config) {
2404
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2405
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2406
+				$default  = isset($config['default']) ? $config['default'] : '';
2407
+				$default  = isset($config['value']) ? $config['value'] : $default;
2408
+
2409
+				// if type is hidden and the value is empty
2410
+				// something may have gone wrong so let's correct with the defaults
2411
+				$fix                = $config['input'] === 'hidden'
2412
+									  && isset($existing[ $field ])
2413
+									  && empty($existing[ $field ])
2414
+					? $default
2415
+					: '';
2416
+				$existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2417
+					? $existing[ $field ]
2418
+					: $fix;
2419
+
2420
+				$template_form_fields[ $field_id ] = [
2421
+					'name'       => 'test_settings_fld[' . $field . ']',
2422
+					'label'      => $config['label'],
2423
+					'input'      => $config['input'],
2424
+					'type'       => $config['type'],
2425
+					'required'   => $config['required'],
2426
+					'validation' => $config['validation'],
2427
+					'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2428
+					'css_class'  => $config['css_class'],
2429
+					'options'    => isset($config['options']) ? $config['options'] : [],
2430
+					'default'    => $default,
2431
+					'format'     => $config['format'],
2432
+				];
2433
+			}
2434
+		}
2435
+
2436
+		$test_settings_html = ! empty($template_form_fields)
2437
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2438
+			: '';
2439
+
2440
+		// print out $test_settings_fields
2441
+		if (! empty($test_settings_html)) {
2442
+			$test_settings_html .= '<input type="submit" class="button--primary mtp-test-button alignright" ';
2443
+			$test_settings_html .= 'name="test_button" value="';
2444
+			$test_settings_html .= esc_html__('Test Send', 'event_espresso');
2445
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2446
+		}
2447
+
2448
+		// and button
2449
+		$test_settings_html .= '<p>';
2450
+		$test_settings_html .= esc_html__('Need to reset this message type and start over?', 'event_espresso');
2451
+		$test_settings_html .= '</p>';
2452
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2453
+		$test_settings_html .= $this->get_action_link_or_button(
2454
+			'reset_to_default',
2455
+			'reset',
2456
+			$extra_args,
2457
+			'button--primary reset-default-button'
2458
+		);
2459
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2460
+		echo $test_settings_html; // already escaped
2461
+	}
2462
+
2463
+
2464
+	/**
2465
+	 * This returns the shortcode selector skeleton for a given context and field.
2466
+	 *
2467
+	 * @param string $field           The name of the field retrieving shortcodes for.
2468
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2469
+	 * @return string
2470
+	 * @throws DomainException
2471
+	 * @throws EE_Error
2472
+	 * @throws InvalidArgumentException
2473
+	 * @throws ReflectionException
2474
+	 * @throws InvalidDataTypeException
2475
+	 * @throws InvalidInterfaceException
2476
+	 * @since 4.9.rc.000
2477
+	 */
2478
+	protected function _get_shortcode_selector($field, $linked_input_id)
2479
+	{
2480
+		$template_args = [
2481
+			'shortcodes'      => $this->_get_shortcodes([$field], true),
2482
+			'fieldname'       => $field,
2483
+			'linked_input_id' => $linked_input_id,
2484
+		];
2485
+
2486
+		return EEH_Template::display_template(
2487
+			EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2488
+			$template_args,
2489
+			true
2490
+		);
2491
+	}
2492
+
2493
+
2494
+	/**
2495
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2496
+	 * page)
2497
+	 *
2498
+	 * @access public
2499
+	 * @return void
2500
+	 * @throws EE_Error
2501
+	 * @throws InvalidArgumentException
2502
+	 * @throws ReflectionException
2503
+	 * @throws InvalidDataTypeException
2504
+	 * @throws InvalidInterfaceException
2505
+	 */
2506
+	public function shortcode_meta_box()
2507
+	{
2508
+		$shortcodes = $this->_get_shortcodes([], false);
2509
+		// just make sure the shortcodes property is set
2510
+		// $messenger = $this->_message_template_group->messenger_obj();
2511
+		// now let's set the content depending on the status of the shortcodes array
2512
+		if (empty($shortcodes)) {
2513
+			echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2514
+			return;
2515
+		}
2516
+		?>
2517 2517
         <div style="float:right; margin-top:10px">
2518 2518
             <?php echo $this->_get_help_tab_link('message_template_shortcodes'); // already escaped ?>
2519 2519
         </div>
2520 2520
         <p class="small-text">
2521 2521
             <?php printf(
2522
-                esc_html__(
2523
-                    'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2524
-                    'event_espresso'
2525
-                ),
2526
-                '<span class="dashicons dashicons-menu"></span>'
2527
-            ); ?>
2522
+				esc_html__(
2523
+					'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2524
+					'event_espresso'
2525
+				),
2526
+				'<span class="dashicons dashicons-menu"></span>'
2527
+			); ?>
2528 2528
         </p>
2529 2529
         <?php
2530
-    }
2531
-
2532
-
2533
-    /**
2534
-     * used to set the $_shortcodes property for when its needed elsewhere.
2535
-     *
2536
-     * @access protected
2537
-     * @return void
2538
-     * @throws EE_Error
2539
-     * @throws InvalidArgumentException
2540
-     * @throws ReflectionException
2541
-     * @throws InvalidDataTypeException
2542
-     * @throws InvalidInterfaceException
2543
-     */
2544
-    protected function _set_shortcodes()
2545
-    {
2546
-
2547
-        // no need to run this if the property is already set
2548
-        if (! empty($this->_shortcodes)) {
2549
-            return;
2550
-        }
2551
-
2552
-        $this->_shortcodes = $this->_get_shortcodes();
2553
-    }
2554
-
2555
-
2556
-    /**
2557
-     * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2558
-     * property)
2559
-     *
2560
-     * @access  protected
2561
-     * @param array   $fields  include an array of specific field names that you want to be used to get the shortcodes
2562
-     *                         for. Defaults to all (for the given context)
2563
-     * @param boolean $merged  Whether to merge all the shortcodes into one list of unique shortcodes
2564
-     * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2565
-     *                         true just an array of shortcode/label pairs.
2566
-     * @throws EE_Error
2567
-     * @throws InvalidArgumentException
2568
-     * @throws ReflectionException
2569
-     * @throws InvalidDataTypeException
2570
-     * @throws InvalidInterfaceException
2571
-     */
2572
-    protected function _get_shortcodes($fields = [], $merged = true)
2573
-    {
2574
-        $this->_set_message_template_group();
2575
-
2576
-        // we need the messenger and message template to retrieve the valid shortcodes array.
2577
-        $GRP_ID  = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2578
-            ? absint($this->_req_data['id'])
2579
-            : false;
2580
-        $context = isset($this->_req_data['context'])
2581
-            ? $this->_req_data['context']
2582
-            : key($this->_message_template_group->contexts_config());
2583
-
2584
-        return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : [];
2585
-    }
2586
-
2587
-
2588
-    /**
2589
-     * This sets the _message_template property (containing the called message_template object)
2590
-     *
2591
-     * @access protected
2592
-     * @return void
2593
-     * @throws EE_Error
2594
-     * @throws InvalidArgumentException
2595
-     * @throws ReflectionException
2596
-     * @throws InvalidDataTypeException
2597
-     * @throws InvalidInterfaceException
2598
-     */
2599
-    protected function _set_message_template_group()
2600
-    {
2601
-
2602
-        if (! empty($this->_message_template_group)) {
2603
-            return;
2604
-        } //get out if this is already set.
2605
-
2606
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2607
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2608
-
2609
-        // let's get the message templates
2610
-        $MTP = EEM_Message_Template_Group::instance();
2611
-
2612
-        if (empty($GRP_ID)) {
2613
-            $this->_message_template_group = $MTP->create_default_object();
2614
-        } else {
2615
-            $this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2616
-        }
2617
-
2618
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2619
-        $this->_variation     = $this->_message_template_group->get_template_pack_variation();
2620
-    }
2621
-
2622
-
2623
-    /**
2624
-     * sets up a context switcher for edit forms
2625
-     *
2626
-     * @access  protected
2627
-     * @param EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2628
-     * @param array                     $args                  various things the context switcher needs.
2629
-     * @throws EE_Error
2630
-     */
2631
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2632
-    {
2633
-        $context_details = $template_group_object->contexts_config();
2634
-        $context_label   = $template_group_object->context_label();
2635
-        ob_start();
2636
-        ?>
2530
+	}
2531
+
2532
+
2533
+	/**
2534
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2535
+	 *
2536
+	 * @access protected
2537
+	 * @return void
2538
+	 * @throws EE_Error
2539
+	 * @throws InvalidArgumentException
2540
+	 * @throws ReflectionException
2541
+	 * @throws InvalidDataTypeException
2542
+	 * @throws InvalidInterfaceException
2543
+	 */
2544
+	protected function _set_shortcodes()
2545
+	{
2546
+
2547
+		// no need to run this if the property is already set
2548
+		if (! empty($this->_shortcodes)) {
2549
+			return;
2550
+		}
2551
+
2552
+		$this->_shortcodes = $this->_get_shortcodes();
2553
+	}
2554
+
2555
+
2556
+	/**
2557
+	 * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2558
+	 * property)
2559
+	 *
2560
+	 * @access  protected
2561
+	 * @param array   $fields  include an array of specific field names that you want to be used to get the shortcodes
2562
+	 *                         for. Defaults to all (for the given context)
2563
+	 * @param boolean $merged  Whether to merge all the shortcodes into one list of unique shortcodes
2564
+	 * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2565
+	 *                         true just an array of shortcode/label pairs.
2566
+	 * @throws EE_Error
2567
+	 * @throws InvalidArgumentException
2568
+	 * @throws ReflectionException
2569
+	 * @throws InvalidDataTypeException
2570
+	 * @throws InvalidInterfaceException
2571
+	 */
2572
+	protected function _get_shortcodes($fields = [], $merged = true)
2573
+	{
2574
+		$this->_set_message_template_group();
2575
+
2576
+		// we need the messenger and message template to retrieve the valid shortcodes array.
2577
+		$GRP_ID  = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2578
+			? absint($this->_req_data['id'])
2579
+			: false;
2580
+		$context = isset($this->_req_data['context'])
2581
+			? $this->_req_data['context']
2582
+			: key($this->_message_template_group->contexts_config());
2583
+
2584
+		return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : [];
2585
+	}
2586
+
2587
+
2588
+	/**
2589
+	 * This sets the _message_template property (containing the called message_template object)
2590
+	 *
2591
+	 * @access protected
2592
+	 * @return void
2593
+	 * @throws EE_Error
2594
+	 * @throws InvalidArgumentException
2595
+	 * @throws ReflectionException
2596
+	 * @throws InvalidDataTypeException
2597
+	 * @throws InvalidInterfaceException
2598
+	 */
2599
+	protected function _set_message_template_group()
2600
+	{
2601
+
2602
+		if (! empty($this->_message_template_group)) {
2603
+			return;
2604
+		} //get out if this is already set.
2605
+
2606
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2607
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2608
+
2609
+		// let's get the message templates
2610
+		$MTP = EEM_Message_Template_Group::instance();
2611
+
2612
+		if (empty($GRP_ID)) {
2613
+			$this->_message_template_group = $MTP->create_default_object();
2614
+		} else {
2615
+			$this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2616
+		}
2617
+
2618
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2619
+		$this->_variation     = $this->_message_template_group->get_template_pack_variation();
2620
+	}
2621
+
2622
+
2623
+	/**
2624
+	 * sets up a context switcher for edit forms
2625
+	 *
2626
+	 * @access  protected
2627
+	 * @param EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2628
+	 * @param array                     $args                  various things the context switcher needs.
2629
+	 * @throws EE_Error
2630
+	 */
2631
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2632
+	{
2633
+		$context_details = $template_group_object->contexts_config();
2634
+		$context_label   = $template_group_object->context_label();
2635
+		ob_start();
2636
+		?>
2637 2637
         <div class="ee-msg-switcher-container">
2638 2638
             <form method="get" action="<?php echo esc_url_raw(EE_MSG_ADMIN_URL); ?>" id="ee-msg-context-switcher-frm">
2639 2639
                 <?php
2640
-                foreach ($args as $name => $value) {
2641
-                    if ($name === 'context' || empty($value) || $name === 'extra') {
2642
-                        continue;
2643
-                    }
2644
-                    ?>
2640
+				foreach ($args as $name => $value) {
2641
+					if ($name === 'context' || empty($value) || $name === 'extra') {
2642
+						continue;
2643
+					}
2644
+					?>
2645 2645
                     <input type="hidden"
2646 2646
                            name="<?php echo esc_attr($name); ?>"
2647 2647
                            value="<?php echo esc_attr($value); ?>"
2648 2648
                     />
2649 2649
                     <?php
2650
-                }
2651
-                // setup nonce_url
2652
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2653
-                ?>
2650
+				}
2651
+				// setup nonce_url
2652
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2653
+				?>
2654 2654
                 <select name="context">
2655 2655
                     <?php
2656
-                    $context_templates = $template_group_object->context_templates();
2657
-                    if (is_array($context_templates)) :
2658
-                        foreach ($context_templates as $context => $template_fields) :
2659
-                            $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2660
-                            ?>
2656
+					$context_templates = $template_group_object->context_templates();
2657
+					if (is_array($context_templates)) :
2658
+						foreach ($context_templates as $context => $template_fields) :
2659
+							$checked = ($context === $args['context']) ? 'selected="selected"' : '';
2660
+							?>
2661 2661
                             <option value="<?php echo esc_attr($context); ?>" <?php echo esc_attr($checked); ?>>
2662 2662
                                 <?php echo $context_details[ $context ]['label']; // already escaped
2663
-                                ?>
2663
+								?>
2664 2664
                             </option>
2665 2665
                         <?php endforeach;
2666
-                    endif; ?>
2666
+					endif; ?>
2667 2667
                 </select>
2668 2668
                 <?php $button_text = sprintf(
2669
-                    esc_html__('Switch %s', 'event_espresso'),
2670
-                    ucwords($context_label['label'])
2671
-                ); ?>
2669
+					esc_html__('Switch %s', 'event_espresso'),
2670
+					ucwords($context_label['label'])
2671
+				); ?>
2672 2672
                 <input class='button--secondary'
2673 2673
                        id="submit-msg-context-switcher-sbmt"
2674 2674
                        type="submit"
@@ -2676,1929 +2676,1929 @@  discard block
 block discarded – undo
2676 2676
                 />
2677 2677
             </form>
2678 2678
             <?php echo $args['extra']; // already escaped
2679
-            ?>
2679
+			?>
2680 2680
         </div> <!-- end .ee-msg-switcher-container -->
2681 2681
         <?php $this->_context_switcher = ob_get_clean();
2682
-    }
2683
-
2684
-
2685
-    /**
2686
-     * utility for sanitizing new values coming in.
2687
-     * Note: this is only used when updating a context.
2688
-     *
2689
-     * @access protected
2690
-     *
2691
-     * @param int $index This helps us know which template field to select from the request array.
2692
-     *
2693
-     * @return array
2694
-     */
2695
-    protected function _set_message_template_column_values($index)
2696
-    {
2697
-        if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2698
-            foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2699
-                $this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2700
-            }
2701
-        }
2702
-
2703
-
2704
-        $set_column_values = [
2705
-            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2706
-            'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2707
-            'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2708
-            'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2709
-            'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2710
-            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2711
-            'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2712
-            'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2713
-            'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2714
-                ? absint($this->_req_data['MTP_is_global'])
2715
-                : 0,
2716
-            'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2717
-                ? absint($this->_req_data['MTP_is_override'])
2718
-                : 0,
2719
-            'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2720
-            'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2721
-        ];
2722
-
2723
-
2724
-        return $set_column_values;
2725
-    }
2726
-
2727
-
2728
-    protected function _insert_or_update_message_template($new = false)
2729
-    {
2730
-        $success = 0;
2731
-        $override = false;
2732
-
2733
-        // setup notices description
2734
-        $messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2735
-
2736
-        // need the message type and messenger objects to be able to use the labels for the notices
2737
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2738
-        $messenger_label  = $messenger_object instanceof EE_messenger
2739
-            ? ucwords($messenger_object->label['singular'])
2740
-            : '';
2741
-
2742
-        $message_type_slug   = ! empty($this->_req_data['MTP_message_type'])
2743
-            ? $this->_req_data['MTP_message_type']
2744
-            : '';
2745
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2746
-
2747
-        $message_type_label = $message_type_object instanceof EE_message_type
2748
-            ? ucwords($message_type_object->label['singular'])
2749
-            : '';
2750
-
2751
-        $context_slug = ! empty($this->_req_data['MTP_context'])
2752
-            ? $this->_req_data['MTP_context']
2753
-            : '';
2754
-        $context      = ucwords(str_replace('_', ' ', $context_slug));
2755
-
2756
-        $item_desc   = $messenger_label && $message_type_label
2757
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2758
-            : '';
2759
-        $item_desc   .= 'Message Template';
2760
-        $query_args  = [];
2761
-        $edit_array  = [];
2762
-        $action_desc = '';
2763
-
2764
-        // if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2765
-        // user to edit.
2766
-        if ($new) {
2767
-            $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2768
-            if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2769
-                if (empty($edit_array)) {
2770
-                    $success = 0;
2771
-                } else {
2772
-                    $success    = 1;
2773
-                    $edit_array = $edit_array[0];
2774
-                    $query_args = [
2775
-                        'id'      => $edit_array['GRP_ID'],
2776
-                        'context' => $edit_array['MTP_context'],
2777
-                        'action'  => 'edit_message_template',
2778
-                    ];
2779
-                }
2780
-            }
2781
-            $action_desc = 'created';
2782
-        } else {
2783
-            $MTPG = EEM_Message_Template_Group::instance();
2784
-            $MTP  = EEM_Message_Template::instance();
2785
-
2786
-
2787
-            // run update for each template field in displayed context
2788
-            if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2789
-                EE_Error::add_error(
2790
-                    esc_html__(
2791
-                        'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2792
-                        'event_espresso'
2793
-                    ),
2794
-                    __FILE__,
2795
-                    __FUNCTION__,
2796
-                    __LINE__
2797
-                );
2798
-                $success = 0;
2799
-            } else {
2800
-                // first validate all fields!
2801
-                // this filter allows client code to add its own validation to the template fields as well.
2802
-                // returning an empty array means everything passed validation.
2803
-                // errors in validation should be represented in an array with the following shape:
2804
-                // array(
2805
-                //   'fieldname' => array(
2806
-                //          'msg' => 'error message'
2807
-                //          'value' => 'value for field producing error'
2808
-                // )
2809
-                $custom_validation = (array) apply_filters(
2810
-                    'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2811
-                    [],
2812
-                    $this->_req_data['MTP_template_fields'],
2813
-                    $context_slug,
2814
-                    $messenger_slug,
2815
-                    $message_type_slug
2816
-                );
2817
-
2818
-                $system_validation = $MTPG->validate(
2819
-                    $this->_req_data['MTP_template_fields'],
2820
-                    $context_slug,
2821
-                    $messenger_slug,
2822
-                    $message_type_slug
2823
-                );
2824
-
2825
-                $system_validation = ! is_array($system_validation) && $system_validation ? []
2826
-                    : $system_validation;
2827
-                $validates         = array_merge($custom_validation, $system_validation);
2828
-
2829
-                // if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2830
-                // appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2831
-                //  WE need to make sure there is no actual error messages in validates.
2832
-                if (is_array($validates) && ! empty($validates)) {
2833
-                    // add the transient so when the form loads we know which fields to highlight
2834
-                    $this->_add_transient('edit_message_template', $validates);
2835
-
2836
-                    $success = 0;
2837
-
2838
-                    // setup notices
2839
-                    foreach ($validates as $field => $error) {
2840
-                        if (isset($error['msg'])) {
2841
-                            EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2842
-                        }
2843
-                    }
2844
-                } else {
2845
-                    $set_column_values = [];
2846
-                    foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2847
-                        $set_column_values = $this->_set_message_template_column_values($template_field);
2848
-
2849
-                        $where_cols_n_values = [
2850
-                            'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2851
-                        ];
2852
-                        // if they aren't allowed to use all JS, restrict them to just posty-y tags
2853
-                        if (! current_user_can('unfiltered_html')) {
2854
-                            if (is_array($set_column_values['MTP_content'])) {
2855
-                                foreach ($set_column_values['MTP_content'] as $key => $value) {
2856
-                                    // remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2857
-                                    // only removes slashes from double-quotes, so attributes using single quotes always
2858
-                                    // appear invalid.) But currently the models expect slashed data, so after wp_kses
2859
-                                    // runs we need to re-slash the data. Sheesh. See
2860
-                                    // https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2861
-                                    $set_column_values['MTP_content'][ $key ] = addslashes(
2862
-                                        wp_kses(
2863
-                                            stripslashes($value),
2864
-                                            wp_kses_allowed_html('post')
2865
-                                        )
2866
-                                    );
2867
-                                }
2868
-                            } else {
2869
-                                $set_column_values['MTP_content'] = wp_kses(
2870
-                                    $set_column_values['MTP_content'],
2871
-                                    wp_kses_allowed_html('post')
2872
-                                );
2873
-                            }
2874
-                        }
2875
-                        $message_template_fields = [
2876
-                            'GRP_ID'             => $set_column_values['GRP_ID'],
2877
-                            'MTP_template_field' => $set_column_values['MTP_template_field'],
2878
-                            'MTP_context'        => $set_column_values['MTP_context'],
2879
-                            'MTP_content'        => $set_column_values['MTP_content'],
2880
-                        ];
2881
-                        if ($updated = $MTP->update($message_template_fields, [$where_cols_n_values])) {
2882
-                            if ($updated === false) {
2883
-                                EE_Error::add_error(
2884
-                                    sprintf(
2885
-                                        esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2886
-                                        $template_field
2887
-                                    ),
2888
-                                    __FILE__,
2889
-                                    __FUNCTION__,
2890
-                                    __LINE__
2891
-                                );
2892
-                            } else {
2893
-                                $success = 1;
2894
-                            }
2895
-                        } else {
2896
-                            // only do this logic if we don't have a MTP_ID for this field
2897
-                            if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2898
-                                // this has already been through the template field validator and sanitized, so it will be
2899
-                                // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2900
-                                // message template field in a messenger/message type and existing users don't have the
2901
-                                // default setup for it.
2902
-                                // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2903
-                                $updated = $MTP->insert($message_template_fields);
2904
-                                if (! $updated || is_wp_error($updated)) {
2905
-                                    EE_Error::add_error(
2906
-                                        sprintf(
2907
-                                            esc_html__('%s field could not be updated.', 'event_espresso'),
2908
-                                            $template_field
2909
-                                        ),
2910
-                                        __FILE__,
2911
-                                        __FUNCTION__,
2912
-                                        __LINE__
2913
-                                    );
2914
-                                    $success = 0;
2915
-                                } else {
2916
-                                    $success = 1;
2917
-                                }
2918
-                            }
2919
-                        }
2920
-                        $action_desc = 'updated';
2921
-                    }
2922
-
2923
-                    // we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2924
-                    $mtpg_fields = [
2925
-                        'MTP_user_id'      => $set_column_values['MTP_user_id'],
2926
-                        'MTP_messenger'    => $set_column_values['MTP_messenger'],
2927
-                        'MTP_message_type' => $set_column_values['MTP_message_type'],
2928
-                        'MTP_is_global'    => $set_column_values['MTP_is_global'],
2929
-                        'MTP_is_override'  => $set_column_values['MTP_is_override'],
2930
-                        'MTP_deleted'      => $set_column_values['MTP_deleted'],
2931
-                        'MTP_is_active'    => $set_column_values['MTP_is_active'],
2932
-                        'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2933
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2934
-                            : '',
2935
-                        'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2936
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2937
-                            : '',
2938
-                    ];
2939
-
2940
-                    $mtpg_where = ['GRP_ID' => $set_column_values['GRP_ID']];
2941
-                    $updated    = $MTPG->update($mtpg_fields, [$mtpg_where]);
2942
-
2943
-                    if ($updated === false) {
2944
-                        EE_Error::add_error(
2945
-                            sprintf(
2946
-                                esc_html__(
2947
-                                    'The Message Template Group (%d) was NOT updated for some reason',
2948
-                                    'event_espresso'
2949
-                                ),
2950
-                                $set_column_values['GRP_ID']
2951
-                            ),
2952
-                            __FILE__,
2953
-                            __FUNCTION__,
2954
-                            __LINE__
2955
-                        );
2956
-                    } else {
2957
-                        // k now we need to ensure the template_pack and template_variation fields are set.
2958
-                        $template_pack = ! empty($this->_req_data['MTP_template_pack'])
2959
-                            ? $this->_req_data['MTP_template_pack']
2960
-                            : 'default';
2961
-
2962
-                        $template_variation = ! empty($this->_req_data['MTP_template_variation'])
2963
-                            ? $this->_req_data['MTP_template_variation']
2964
-                            : 'default';
2965
-
2966
-                        $mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2967
-                        if ($mtpg_obj instanceof EE_Message_Template_Group) {
2968
-                            $mtpg_obj->set_template_pack_name($template_pack);
2969
-                            $mtpg_obj->set_template_pack_variation($template_variation);
2970
-                        }
2971
-                        $success = 1;
2972
-                    }
2973
-                }
2974
-            }
2975
-        }
2976
-
2977
-        // we return things differently if doing ajax
2978
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2979
-            $this->_template_args['success'] = $success;
2980
-            $this->_template_args['error']   = ! $success ? true : false;
2981
-            $this->_template_args['content'] = '';
2982
-            $this->_template_args['data']    = [
2983
-                'grpID'        => $edit_array['GRP_ID'],
2984
-                'templateName' => $edit_array['template_name'],
2985
-            ];
2986
-            if ($success) {
2987
-                EE_Error::overwrite_success();
2988
-                EE_Error::add_success(
2989
-                    esc_html__(
2990
-                        'The new template has been created and automatically selected for this event.  You can edit the new template by clicking the edit button.  Note before this template is assigned to this event, the event must be saved.',
2991
-                        'event_espresso'
2992
-                    )
2993
-                );
2994
-            }
2995
-
2996
-            $this->_return_json();
2997
-        }
2998
-
2999
-
3000
-        // was a test send triggered?
3001
-        if (isset($this->_req_data['test_button'])) {
3002
-            EE_Error::overwrite_success();
3003
-            $this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
3004
-            $override = true;
3005
-        }
3006
-
3007
-        if (empty($query_args)) {
3008
-            $query_args = [
3009
-                'id'      => $this->_req_data['GRP_ID'],
3010
-                'context' => $context_slug,
3011
-                'action'  => 'edit_message_template',
3012
-            ];
3013
-        }
3014
-
3015
-        $this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3016
-    }
3017
-
3018
-
3019
-    /**
3020
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
3021
-     *
3022
-     * @param string $context      what context being tested
3023
-     * @param string $messenger    messenger being tested
3024
-     * @param string $message_type message type being tested
3025
-     * @throws EE_Error
3026
-     * @throws InvalidArgumentException
3027
-     * @throws InvalidDataTypeException
3028
-     * @throws InvalidInterfaceException
3029
-     */
3030
-    protected function _do_test_send($context, $messenger, $message_type)
3031
-    {
3032
-        // set things up for preview
3033
-        $this->_req_data['messenger']    = $messenger;
3034
-        $this->_req_data['message_type'] = $message_type;
3035
-        $this->_req_data['context']      = $context;
3036
-        $this->_req_data['GRP_ID']       = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3037
-        $active_messenger                = $this->_message_resource_manager->get_active_messenger($messenger);
3038
-
3039
-        // let's save any existing fields that might be required by the messenger
3040
-        if (
3041
-            isset($this->_req_data['test_settings_fld'])
3042
-            && $active_messenger instanceof EE_messenger
3043
-            && apply_filters(
3044
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3045
-                true,
3046
-                $this->_req_data['test_settings_fld'],
3047
-                $active_messenger
3048
-            )
3049
-        ) {
3050
-            $active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3051
-        }
3052
-
3053
-        /**
3054
-         * Use filter to add additional controls on whether message can send or not
3055
-         */
3056
-        if (
3057
-            apply_filters(
3058
-                'FHEE__Messages_Admin_Page__do_test_send__can_send',
3059
-                true,
3060
-                $context,
3061
-                $this->_req_data,
3062
-                $messenger,
3063
-                $message_type
3064
-            )
3065
-        ) {
3066
-            if (EEM_Event::instance()->count() > 0) {
3067
-                $success = $this->_preview_message(true);
3068
-                if ($success) {
3069
-                    EE_Error::add_success(esc_html__('Test message sent', 'event_espresso'));
3070
-                } else {
3071
-                    EE_Error::add_error(
3072
-                        esc_html__('The test message was not sent', 'event_espresso'),
3073
-                        __FILE__,
3074
-                        __FUNCTION__,
3075
-                        __LINE__
3076
-                    );
3077
-                }
3078
-            } else {
3079
-                $this->noEventsErrorMessage(true);
3080
-            }
3081
-        }
3082
-    }
3083
-
3084
-
3085
-    /**
3086
-     * _generate_new_templates
3087
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3088
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3089
-     * for the event.
3090
-     *
3091
-     *
3092
-     * @param string $messenger      the messenger we are generating templates for
3093
-     * @param array  $message_types  array of message types that the templates are generated for.
3094
-     * @param int    $GRP_ID         If this is a custom template being generated then a GRP_ID needs to be included to
3095
-     *                               indicate the message_template_group being used as the base.
3096
-     *
3097
-     * @param bool   $global
3098
-     *
3099
-     * @return array|bool array of data required for the redirect to the correct edit page or bool if
3100
-     *                               encountering problems.
3101
-     * @throws EE_Error
3102
-     */
3103
-    protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3104
-    {
3105
-
3106
-        // if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3107
-        // just don't generate any templates.
3108
-        if (empty($message_types)) {
3109
-            return true;
3110
-        }
3111
-
3112
-        return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3113
-    }
3114
-
3115
-
3116
-    /**
3117
-     * [_trash_or_restore_message_template]
3118
-     *
3119
-     * @param boolean $trash  whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3120
-     * @param boolean $all    whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3121
-     *                        an individual context (FALSE).
3122
-     * @return void
3123
-     * @throws EE_Error
3124
-     * @throws InvalidArgumentException
3125
-     * @throws InvalidDataTypeException
3126
-     * @throws InvalidInterfaceException
3127
-     */
3128
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
3129
-    {
3130
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3131
-        $MTP = EEM_Message_Template_Group::instance();
3132
-
3133
-        $success = 1;
3134
-
3135
-        // incoming GRP_IDs
3136
-        if ($all) {
3137
-            // Checkboxes
3138
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3139
-                // if array has more than one element then success message should be plural.
3140
-                // todo: what about nonce?
3141
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3142
-
3143
-                // cycle through checkboxes
3144
-                while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3145
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3146
-                    if (! $trashed_or_restored) {
3147
-                        $success = 0;
3148
-                    }
3149
-                }
3150
-            } else {
3151
-                // grab single GRP_ID and handle
3152
-                $GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3153
-                if (! empty($GRP_ID)) {
3154
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3155
-                    if (! $trashed_or_restored) {
3156
-                        $success = 0;
3157
-                    }
3158
-                } else {
3159
-                    $success = 0;
3160
-                }
3161
-            }
3162
-        }
3163
-
3164
-        $action_desc = $trash
3165
-            ? esc_html__('moved to the trash', 'event_espresso')
3166
-            : esc_html__('restored', 'event_espresso');
3167
-
3168
-        $action_desc =
3169
-            ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3170
-
3171
-        $item_desc = $all ? _n(
3172
-            'Message Template Group',
3173
-            'Message Template Groups',
3174
-            $success,
3175
-            'event_espresso'
3176
-        ) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3177
-
3178
-        $item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3179
-            'template',
3180
-            'templates',
3181
-            $success,
3182
-            'event_espresso'
3183
-        ) : $item_desc;
3184
-
3185
-        $this->_redirect_after_action($success, $item_desc, $action_desc, []);
3186
-    }
3187
-
3188
-
3189
-    /**
3190
-     * [_delete_message_template]
3191
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3192
-     *
3193
-     * @return void
3194
-     * @throws EE_Error
3195
-     * @throws InvalidArgumentException
3196
-     * @throws InvalidDataTypeException
3197
-     * @throws InvalidInterfaceException
3198
-     */
3199
-    protected function _delete_message_template()
3200
-    {
3201
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3202
-
3203
-        // checkboxes
3204
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3205
-            // if array has more than one element then success message should be plural
3206
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3207
-
3208
-            // cycle through bulk action checkboxes
3209
-            while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3210
-                $success = $this->_delete_mtp_permanently($GRP_ID);
3211
-            }
3212
-        } else {
3213
-            // grab single grp_id and delete
3214
-            $GRP_ID  = absint($this->_req_data['id']);
3215
-            $success = $this->_delete_mtp_permanently($GRP_ID);
3216
-        }
3217
-
3218
-        $this->_redirect_after_action($success, 'Message Templates', 'deleted', []);
3219
-    }
3220
-
3221
-
3222
-    /**
3223
-     * helper for permanently deleting a mtP group and all related message_templates
3224
-     *
3225
-     * @param int  $GRP_ID        The group being deleted
3226
-     * @param bool $include_group whether to delete the Message Template Group as well.
3227
-     * @return bool boolean to indicate the success of the deletes or not.
3228
-     * @throws EE_Error
3229
-     * @throws InvalidArgumentException
3230
-     * @throws InvalidDataTypeException
3231
-     * @throws InvalidInterfaceException
3232
-     */
3233
-    private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3234
-    {
3235
-        $success = 1;
3236
-        $MTPG    = EEM_Message_Template_Group::instance();
3237
-        // first let's GET this group
3238
-        $MTG = $MTPG->get_one_by_ID($GRP_ID);
3239
-        // then delete permanently all the related Message Templates
3240
-        $deleted = $MTG->delete_related_permanently('Message_Template');
3241
-
3242
-        if ($deleted === 0) {
3243
-            $success = 0;
3244
-        }
3245
-
3246
-        // now delete permanently this particular group
3247
-
3248
-        if ($include_group && ! $MTG->delete_permanently()) {
3249
-            $success = 0;
3250
-        }
3251
-
3252
-        return $success;
3253
-    }
3254
-
3255
-
3256
-    /**
3257
-     *    _learn_more_about_message_templates_link
3258
-     *
3259
-     * @access protected
3260
-     * @return string
3261
-     */
3262
-    protected function _learn_more_about_message_templates_link()
3263
-    {
3264
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3265
-               . esc_html__('learn more about how message templates works', 'event_espresso')
3266
-               . '</a>';
3267
-    }
3268
-
3269
-
3270
-    /**
3271
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3272
-     * ajax and other routes.
3273
-     *
3274
-     * @return void
3275
-     * @throws DomainException
3276
-     */
3277
-    protected function _settings()
3278
-    {
3279
-
3280
-
3281
-        $this->_set_m_mt_settings();
3282
-
3283
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3284
-            ? $this->_req_data['selected_messenger']
3285
-            : 'email';
3286
-
3287
-        // let's setup the messenger tabs
3288
-        $this->_template_args['admin_page_header']         = EEH_Tabbed_Content::tab_text_links(
3289
-            $this->_m_mt_settings['messenger_tabs'],
3290
-            'messenger_links',
3291
-            '|',
3292
-            $selected_messenger
3293
-        );
3294
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3295
-        $this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
3296
-
3297
-        $this->display_admin_page_with_sidebar();
3298
-    }
3299
-
3300
-
3301
-    /**
3302
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3303
-     *
3304
-     * @access protected
3305
-     * @return void
3306
-     * @throws DomainException
3307
-     */
3308
-    protected function _set_m_mt_settings()
3309
-    {
3310
-        // first if this is already set then lets get out no need to regenerate data.
3311
-        if (! empty($this->_m_mt_settings)) {
3312
-            return;
3313
-        }
3314
-
3315
-        // get all installed messengers and message_types
3316
-        /** @type EE_messenger[] $messengers */
3317
-        $messengers = $this->_message_resource_manager->installed_messengers();
3318
-        /** @type EE_message_type[] $message_types */
3319
-        $message_types = $this->_message_resource_manager->installed_message_types();
3320
-
3321
-
3322
-        // assemble the array for the _tab_text_links helper
3323
-
3324
-        foreach ($messengers as $messenger) {
3325
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
3326
-                'label' => ucwords($messenger->label['singular']),
3327
-                'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3328
-                    ? 'messenger-active'
3329
-                    : '',
3330
-                'href'  => $messenger->name,
3331
-                'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3332
-                'slug'  => $messenger->name,
3333
-                'obj'   => $messenger,
3334
-            ];
3335
-
3336
-
3337
-            $message_types_for_messenger = $messenger->get_valid_message_types();
3338
-
3339
-            foreach ($message_types as $message_type) {
3340
-                // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3341
-                // it shouldn't show in either the inactive OR active metabox.
3342
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3343
-                    continue;
3344
-                }
3345
-
3346
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3347
-                    $messenger->name,
3348
-                    $message_type->name
3349
-                )
3350
-                    ? 'active'
3351
-                    : 'inactive';
3352
-
3353
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
3354
-                    'label'    => ucwords($message_type->label['singular']),
3355
-                    'class'    => 'message-type-' . $a_or_i,
3356
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3357
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3358
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3359
-                    'title'    => $a_or_i === 'active'
3360
-                        ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3361
-                        : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3362
-                    'content'  => $a_or_i === 'active'
3363
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
3364
-                        : $this->_message_type_settings_content($message_type, $messenger),
3365
-                    'slug'     => $message_type->name,
3366
-                    'active'   => $a_or_i === 'active',
3367
-                    'obj'      => $message_type,
3368
-                ];
3369
-            }
3370
-        }
3371
-    }
3372
-
3373
-
3374
-    /**
3375
-     * This just prepares the content for the message type settings
3376
-     *
3377
-     * @param EE_message_type $message_type The message type object
3378
-     * @param EE_messenger    $messenger    The messenger object
3379
-     * @param boolean         $active       Whether the message type is active or not
3380
-     * @return string html output for the content
3381
-     * @throws DomainException
3382
-     */
3383
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
3384
-    {
3385
-        // get message type fields
3386
-        $fields                                         = $message_type->get_admin_settings_fields();
3387
-        $settings_template_args['template_form_fields'] = '';
3388
-
3389
-        if (! empty($fields) && $active) {
3390
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3391
-            foreach ($fields as $fldname => $fldprops) {
3392
-                $field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3393
-                $template_form_field[ $field_id ] = [
3394
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3395
-                    'label'      => $fldprops['label'],
3396
-                    'input'      => $fldprops['field_type'],
3397
-                    'type'       => $fldprops['value_type'],
3398
-                    'required'   => $fldprops['required'],
3399
-                    'validation' => $fldprops['validation'],
3400
-                    'value'      => isset($existing_settings[ $fldname ])
3401
-                        ? $existing_settings[ $fldname ]
3402
-                        : $fldprops['default'],
3403
-                    'options'    => isset($fldprops['options'])
3404
-                        ? $fldprops['options']
3405
-                        : [],
3406
-                    'default'    => isset($existing_settings[ $fldname ])
3407
-                        ? $existing_settings[ $fldname ]
3408
-                        : $fldprops['default'],
3409
-                    'css_class'  => 'no-drag',
3410
-                    'format'     => $fldprops['format'],
3411
-                ];
3412
-            }
3413
-
3414
-
3415
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3416
-                ? $this->_generate_admin_form_fields(
3417
-                    $template_form_field,
3418
-                    'string',
3419
-                    'ee_mt_activate_form'
3420
-                )
3421
-                : '';
3422
-        }
3423
-
3424
-        $settings_template_args['description'] = $message_type->description;
3425
-        // we also need some hidden fields
3426
-        $hidden_fields = [
3427
-            'message_type_settings[messenger]' . $message_type->name   => [
3428
-                'type'  => 'hidden',
3429
-                'value' => $messenger->name,
3430
-            ],
3431
-            'message_type_settings[message_type]' . $message_type->name => [
3432
-                'type'  => 'hidden',
3433
-                'value' => $message_type->name,
3434
-            ],
3435
-            'type'   . $message_type->name                             => [
3436
-                'type'  => 'hidden',
3437
-                'value' => 'message_type',
3438
-            ],
3439
-        ];
3440
-
3441
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3442
-            $hidden_fields,
3443
-            'array'
3444
-        );
3445
-        $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3446
-            ? ' hidden'
3447
-            : '';
3448
-
3449
-
3450
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3451
-        $content  = EEH_Template::display_template($template, $settings_template_args, true);
3452
-
3453
-        return $content;
3454
-    }
3455
-
3456
-
3457
-    /**
3458
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
3459
-     *
3460
-     * @access protected
3461
-     * @return void
3462
-     * @throws DomainException
3463
-     */
3464
-    protected function _messages_settings_metaboxes()
3465
-    {
3466
-        $this->_set_m_mt_settings();
3467
-        $m_boxes         = $mt_boxes = [];
3468
-        $m_template_args = $mt_template_args = [];
3469
-
3470
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3471
-            ? $this->_req_data['selected_messenger']
3472
-            : 'email';
3473
-
3474
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
3475
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3476
-                $hide_on_message  = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3477
-                $hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3478
-                // messenger meta boxes
3479
-                $active                                   = $selected_messenger === $messenger;
3480
-                $active_mt_tabs                           = isset(
3481
-                    $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3482
-                )
3483
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3484
-                    : '';
3485
-                $m_boxes[ $messenger . '_a_box' ]         = sprintf(
3486
-                    esc_html__('%s Settings', 'event_espresso'),
3487
-                    $tab_array['label']
3488
-                );
3489
-                $m_template_args[ $messenger . '_a_box' ] = [
3490
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3491
-                    'inactive_message_types' => isset(
3492
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3493
-                    )
3494
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3495
-                        : '',
3496
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3497
-                    'hidden'                 => $active ? '' : ' hidden',
3498
-                    'hide_on_message'        => $hide_on_message,
3499
-                    'messenger'              => $messenger,
3500
-                    'active'                 => $active,
3501
-                ];
3502
-                // message type meta boxes
3503
-                // (which is really just the inactive container for each messenger
3504
-                // showing inactive message types for that messenger)
3505
-                $mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3506
-                $mt_template_args[ $messenger . '_i_box' ] = [
3507
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3508
-                    'inactive_message_types' => isset(
3509
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3510
-                    )
3511
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3512
-                        : '',
3513
-                    'hidden'                 => $active ? '' : ' hidden',
3514
-                    'hide_on_message'        => $hide_on_message,
3515
-                    'hide_off_message'       => $hide_off_message,
3516
-                    'messenger'              => $messenger,
3517
-                    'active'                 => $active,
3518
-                ];
3519
-            }
3520
-        }
3521
-
3522
-
3523
-        // register messenger metaboxes
3524
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3525
-        foreach ($m_boxes as $box => $label) {
3526
-            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3527
-            $msgr          = str_replace('_a_box', '', $box);
3528
-            $this->addMetaBox(
3529
-                'espresso_' . $msgr . '_settings',
3530
-                $label,
3531
-                function ($post, $metabox) {
3532
-                    EEH_Template::display_template(
3533
-                        $metabox['args']['template_path'],
3534
-                        $metabox['args']['template_args']
3535
-                    );
3536
-                },
3537
-                $this->_current_screen->id,
3538
-                'normal',
3539
-                'high',
3540
-                $callback_args
3541
-            );
3542
-        }
3543
-
3544
-        // register message type metaboxes
3545
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3546
-        foreach ($mt_boxes as $box => $label) {
3547
-            $callback_args = [
3548
-                'template_path' => $mt_template_path,
3549
-                'template_args' => $mt_template_args[ $box ],
3550
-            ];
3551
-            $mt            = str_replace('_i_box', '', $box);
3552
-            $this->addMetaBox(
3553
-                'espresso_' . $mt . '_inactive_mts',
3554
-                $label,
3555
-                function ($post, $metabox) {
3556
-                    EEH_Template::display_template(
3557
-                        $metabox['args']['template_path'],
3558
-                        $metabox['args']['template_args']
3559
-                    );
3560
-                },
3561
-                $this->_current_screen->id,
3562
-                'side',
3563
-                'high',
3564
-                $callback_args
3565
-            );
3566
-        }
3567
-
3568
-        // register metabox for global messages settings but only when on the main site.  On single site installs this
3569
-        // will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3570
-        if (is_main_site()) {
3571
-            $this->addMetaBox(
3572
-                'espresso_global_message_settings',
3573
-                esc_html__('Global Message Settings', 'event_espresso'),
3574
-                [$this, 'global_messages_settings_metabox_content'],
3575
-                $this->_current_screen->id,
3576
-                'normal',
3577
-                'low',
3578
-                []
3579
-            );
3580
-        }
3581
-    }
3582
-
3583
-
3584
-    /**
3585
-     *  This generates the content for the global messages settings metabox.
3586
-     *
3587
-     * @return void
3588
-     * @throws EE_Error
3589
-     * @throws InvalidArgumentException
3590
-     * @throws ReflectionException
3591
-     * @throws InvalidDataTypeException
3592
-     * @throws InvalidInterfaceException
3593
-     */
3594
-    public function global_messages_settings_metabox_content()
3595
-    {
3596
-        $form = $this->_generate_global_settings_form();
3597
-        // already escaped
3598
-        echo $form->form_open(
3599
-            $this->add_query_args_and_nonce(['action' => 'update_global_settings'], EE_MSG_ADMIN_URL),
3600
-            'POST'
3601
-        );
3602
-        echo $form->get_html();
3603
-        echo $form->form_close();
3604
-    }
3605
-
3606
-
3607
-    /**
3608
-     * This generates and returns the form object for the global messages settings.
3609
-     *
3610
-     * @return EE_Form_Section_Proper
3611
-     * @throws EE_Error
3612
-     * @throws InvalidArgumentException
3613
-     * @throws ReflectionException
3614
-     * @throws InvalidDataTypeException
3615
-     * @throws InvalidInterfaceException
3616
-     */
3617
-    protected function _generate_global_settings_form()
3618
-    {
3619
-        EE_Registry::instance()->load_helper('HTML');
3620
-        /** @var EE_Network_Core_Config $network_config */
3621
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3622
-
3623
-        return new EE_Form_Section_Proper(
3624
-            [
3625
-                'name'            => 'global_messages_settings',
3626
-                'html_id'         => 'global_messages_settings',
3627
-                'html_class'      => 'form-table',
3628
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3629
-                'subsections'     => apply_filters(
3630
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3631
-                    [
3632
-                        'do_messages_on_same_request' => new EE_Select_Input(
3633
-                            [
3634
-                                true  => esc_html__('On the same request', 'event_espresso'),
3635
-                                false => esc_html__('On a separate request', 'event_espresso'),
3636
-                            ],
3637
-                            [
3638
-                                'default'         => $network_config->do_messages_on_same_request,
3639
-                                'html_label_text' => esc_html__(
3640
-                                    'Generate and send all messages:',
3641
-                                    'event_espresso'
3642
-                                ),
3643
-                                'html_help_text'  => esc_html__(
3644
-                                    'By default the messages system uses a more efficient means of processing messages on separate requests and utilizes the wp-cron scheduling system.  This makes things execute faster for people registering for your events.  However, if the wp-cron system is disabled on your site and there is no alternative in place, then you can change this so messages are always executed on the same request.',
3645
-                                    'event_espresso'
3646
-                                ),
3647
-                            ]
3648
-                        ),
3649
-                        'delete_threshold'            => new EE_Select_Input(
3650
-                            [
3651
-                                0  => esc_html__('Forever', 'event_espresso'),
3652
-                                3  => esc_html__('3 Months', 'event_espresso'),
3653
-                                6  => esc_html__('6 Months', 'event_espresso'),
3654
-                                9  => esc_html__('9 Months', 'event_espresso'),
3655
-                                12 => esc_html__('12 Months', 'event_espresso'),
3656
-                                24 => esc_html__('24 Months', 'event_espresso'),
3657
-                                36 => esc_html__('36 Months', 'event_espresso'),
3658
-                            ],
3659
-                            [
3660
-                                'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3661
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3662
-                                'html_help_text'  => esc_html__(
3663
-                                    'You can control how long a record of processed messages is kept via this option.',
3664
-                                    'event_espresso'
3665
-                                ),
3666
-                            ]
3667
-                        ),
3668
-                        'update_settings'             => new EE_Submit_Input(
3669
-                            [
3670
-                                'default'         => esc_html__('Update', 'event_espresso'),
3671
-                                'html_label_text' => '&nbsp',
3672
-                            ]
3673
-                        ),
3674
-                    ]
3675
-                ),
3676
-            ]
3677
-        );
3678
-    }
3679
-
3680
-
3681
-    /**
3682
-     * This handles updating the global settings set on the admin page.
3683
-     *
3684
-     * @throws EE_Error
3685
-     * @throws InvalidDataTypeException
3686
-     * @throws InvalidInterfaceException
3687
-     * @throws InvalidArgumentException
3688
-     * @throws ReflectionException
3689
-     */
3690
-    protected function _update_global_settings()
3691
-    {
3692
-        /** @var EE_Network_Core_Config $network_config */
3693
-        $network_config  = EE_Registry::instance()->NET_CFG->core;
3694
-        $messages_config = EE_Registry::instance()->CFG->messages;
3695
-        $form            = $this->_generate_global_settings_form();
3696
-        if ($form->was_submitted()) {
3697
-            $form->receive_form_submission();
3698
-            if ($form->is_valid()) {
3699
-                $valid_data = $form->valid_data();
3700
-                foreach ($valid_data as $property => $value) {
3701
-                    $setter = 'set_' . $property;
3702
-                    if (method_exists($network_config, $setter)) {
3703
-                        $network_config->{$setter}($value);
3704
-                    } elseif (
3705
-                        property_exists($network_config, $property)
3706
-                        && $network_config->{$property} !== $value
3707
-                    ) {
3708
-                        $network_config->{$property} = $value;
3709
-                    } elseif (
3710
-                        property_exists($messages_config, $property)
3711
-                        && $messages_config->{$property} !== $value
3712
-                    ) {
3713
-                        $messages_config->{$property} = $value;
3714
-                    }
3715
-                }
3716
-                // only update if the form submission was valid!
3717
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3718
-                EE_Registry::instance()->CFG->update_espresso_config();
3719
-                EE_Error::overwrite_success();
3720
-                EE_Error::add_success(esc_html__('Global message settings were updated', 'event_espresso'));
3721
-            }
3722
-        }
3723
-        $this->_redirect_after_action(0, '', '', ['action' => 'settings'], true);
3724
-    }
3725
-
3726
-
3727
-    /**
3728
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3729
-     *
3730
-     * @param array $tab_array This is an array of message type tab details used to generate the tabs
3731
-     * @return string html formatted tabs
3732
-     * @throws DomainException
3733
-     */
3734
-    protected function _get_mt_tabs($tab_array)
3735
-    {
3736
-        $tab_array = (array) $tab_array;
3737
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3738
-        $tabs      = '';
3739
-
3740
-        foreach ($tab_array as $tab) {
3741
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3742
-        }
3743
-
3744
-        return $tabs;
3745
-    }
3746
-
3747
-
3748
-    /**
3749
-     * This prepares the content of the messenger meta box admin settings
3750
-     *
3751
-     * @param EE_messenger $messenger The messenger we're setting up content for
3752
-     * @return string html formatted content
3753
-     * @throws DomainException
3754
-     */
3755
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3756
-    {
3757
-
3758
-        $fields                                         = $messenger->get_admin_settings_fields();
3759
-        $settings_template_args['template_form_fields'] = '';
3760
-
3761
-        // is $messenger active?
3762
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3763
-
3764
-
3765
-        if (! empty($fields)) {
3766
-            $existing_settings = $messenger->get_existing_admin_settings();
3767
-
3768
-            foreach ($fields as $fldname => $fldprops) {
3769
-                $field_id                         = $messenger->name . '-' . $fldname;
3770
-                $template_form_field[ $field_id ] = [
3771
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3772
-                    'label'      => $fldprops['label'],
3773
-                    'input'      => $fldprops['field_type'],
3774
-                    'type'       => $fldprops['value_type'],
3775
-                    'required'   => $fldprops['required'],
3776
-                    'validation' => $fldprops['validation'],
3777
-                    'value'      => isset($existing_settings[ $field_id ])
3778
-                        ? $existing_settings[ $field_id ]
3779
-                        : $fldprops['default'],
3780
-                    'css_class'  => '',
3781
-                    'format'     => $fldprops['format'],
3782
-                ];
3783
-            }
3784
-
3785
-
3786
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3787
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3788
-                : '';
3789
-        }
3790
-
3791
-        // we also need some hidden fields
3792
-        $settings_template_args['hidden_fields'] = [
3793
-            'messenger_settings[messenger]' . $messenger->name => [
3794
-                'type'  => 'hidden',
3795
-                'value' => $messenger->name,
3796
-            ],
3797
-            'type' . $messenger->name                          => [
3798
-                'type'  => 'hidden',
3799
-                'value' => 'messenger',
3800
-            ],
3801
-        ];
3802
-
3803
-        // make sure any active message types that are existing are included in the hidden fields
3804
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3805
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3806
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3807
-                    'type'  => 'hidden',
3808
-                    'value' => $mt,
3809
-                ];
3810
-            }
3811
-        }
3812
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3813
-            $settings_template_args['hidden_fields'],
3814
-            'array'
3815
-        );
3816
-        $active                                  =
3817
-            $this->_message_resource_manager->is_messenger_active($messenger->name);
3818
-
3819
-        $settings_template_args['messenger']           = $messenger->name;
3820
-        $settings_template_args['description']         = $messenger->description;
3821
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3822
-
3823
-
3824
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3825
-            $messenger->name
3826
-        )
3827
-            ? $settings_template_args['show_hide_edit_form']
3828
-            : ' hidden';
3829
-
3830
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3831
-            ? ' hidden'
3832
-            : $settings_template_args['show_hide_edit_form'];
3833
-
3834
-
3835
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3836
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3837
-        $settings_template_args['on_off_status'] = $active;
3838
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3839
-        return EEH_Template::display_template(
3840
-            $template,
3841
-            $settings_template_args,
3842
-            true
3843
-        );
3844
-    }
3845
-
3846
-
3847
-    /**
3848
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3849
-     *
3850
-     * @throws DomainException
3851
-     * @throws EE_Error
3852
-     * @throws InvalidDataTypeException
3853
-     * @throws InvalidInterfaceException
3854
-     * @throws InvalidArgumentException
3855
-     * @throws ReflectionException
3856
-     */
3857
-    public function activate_messenger_toggle()
3858
-    {
3859
-        $success = true;
3860
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3861
-        // let's check that we have required data
3862
-        if (! isset($this->_req_data['messenger'])) {
3863
-            EE_Error::add_error(
3864
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3865
-                __FILE__,
3866
-                __FUNCTION__,
3867
-                __LINE__
3868
-            );
3869
-            $success = false;
3870
-        }
3871
-
3872
-        // do a nonce check here since we're not arriving via a normal route
3873
-        $nonce     = isset($this->_req_data['activate_nonce'])
3874
-            ? sanitize_text_field($this->_req_data['activate_nonce'])
3875
-            : '';
3876
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3877
-
3878
-        $this->_verify_nonce($nonce, $nonce_ref);
3879
-
3880
-
3881
-        if (! isset($this->_req_data['status'])) {
3882
-            EE_Error::add_error(
3883
-                esc_html__(
3884
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3885
-                    'event_espresso'
3886
-                ),
3887
-                __FILE__,
3888
-                __FUNCTION__,
3889
-                __LINE__
3890
-            );
3891
-            $success = false;
3892
-        }
3893
-
3894
-        // do check to verify we have a valid status.
3895
-        $status = $this->_req_data['status'];
3896
-
3897
-        if ($status !== 'off' && $status !== 'on') {
3898
-            EE_Error::add_error(
3899
-                sprintf(
3900
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3901
-                    $this->_req_data['status']
3902
-                ),
3903
-                __FILE__,
3904
-                __FUNCTION__,
3905
-                __LINE__
3906
-            );
3907
-            $success = false;
3908
-        }
3909
-
3910
-        if ($success) {
3911
-            // made it here?  Stop dawdling then!!
3912
-            $success = $status === 'off'
3913
-                ? $this->_deactivate_messenger($this->_req_data['messenger'])
3914
-                : $this->_activate_messenger($this->_req_data['messenger']);
3915
-        }
3916
-
3917
-        $this->_template_args['success'] = $success;
3918
-
3919
-        // no special instructions so let's just do the json return (which should automatically do all the special stuff).
3920
-        $this->_return_json();
3921
-    }
3922
-
3923
-
3924
-    /**
3925
-     * used by ajax from the messages settings page to activate|deactivate a message type
3926
-     *
3927
-     * @throws DomainException
3928
-     * @throws EE_Error
3929
-     * @throws ReflectionException
3930
-     * @throws InvalidDataTypeException
3931
-     * @throws InvalidInterfaceException
3932
-     * @throws InvalidArgumentException
3933
-     */
3934
-    public function activate_mt_toggle()
3935
-    {
3936
-        $success = true;
3937
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3938
-
3939
-        // let's make sure we have the necessary data
3940
-        if (! isset($this->_req_data['message_type'])) {
3941
-            EE_Error::add_error(
3942
-                esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3943
-                __FILE__,
3944
-                __FUNCTION__,
3945
-                __LINE__
3946
-            );
3947
-            $success = false;
3948
-        }
3949
-
3950
-        if (! isset($this->_req_data['messenger'])) {
3951
-            EE_Error::add_error(
3952
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3953
-                __FILE__,
3954
-                __FUNCTION__,
3955
-                __LINE__
3956
-            );
3957
-            $success = false;
3958
-        }
3959
-
3960
-        if (! isset($this->_req_data['status'])) {
3961
-            EE_Error::add_error(
3962
-                esc_html__(
3963
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3964
-                    'event_espresso'
3965
-                ),
3966
-                __FILE__,
3967
-                __FUNCTION__,
3968
-                __LINE__
3969
-            );
3970
-            $success = false;
3971
-        }
3972
-
3973
-
3974
-        // do check to verify we have a valid status.
3975
-        $status = $this->_req_data['status'];
3976
-
3977
-        if ($status !== 'activate' && $status !== 'deactivate') {
3978
-            EE_Error::add_error(
3979
-                sprintf(
3980
-                    esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3981
-                    $this->_req_data['status']
3982
-                ),
3983
-                __FILE__,
3984
-                __FUNCTION__,
3985
-                __LINE__
3986
-            );
3987
-            $success = false;
3988
-        }
3989
-
3990
-
3991
-        // do a nonce check here since we're not arriving via a normal route
3992
-        $nonce     = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3993
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3994
-
3995
-        $this->_verify_nonce($nonce, $nonce_ref);
3996
-
3997
-        if ($success) {
3998
-            // made it here? um, what are you waiting for then?
3999
-            $success = $status === 'deactivate'
4000
-                ? $this->_deactivate_message_type_for_messenger(
4001
-                    $this->_req_data['messenger'],
4002
-                    $this->_req_data['message_type']
4003
-                )
4004
-                : $this->_activate_message_type_for_messenger(
4005
-                    $this->_req_data['messenger'],
4006
-                    $this->_req_data['message_type']
4007
-                );
4008
-        }
4009
-
4010
-        $this->_template_args['success'] = $success;
4011
-        $this->_return_json();
4012
-    }
4013
-
4014
-
4015
-    /**
4016
-     * Takes care of processing activating a messenger and preparing the appropriate response.
4017
-     *
4018
-     * @param string $messenger_name The name of the messenger being activated
4019
-     * @return bool
4020
-     * @throws DomainException
4021
-     * @throws EE_Error
4022
-     * @throws InvalidArgumentException
4023
-     * @throws ReflectionException
4024
-     * @throws InvalidDataTypeException
4025
-     * @throws InvalidInterfaceException
4026
-     */
4027
-    protected function _activate_messenger($messenger_name)
4028
-    {
4029
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4030
-        $active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
4031
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger
4032
-            ? $active_messenger->get_default_message_types()
4033
-            : [];
4034
-
4035
-        // ensure is active
4036
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4037
-
4038
-        // set response_data for reload
4039
-        foreach ($message_types_to_activate as $message_type_name) {
4040
-            /** @var EE_message_type $message_type */
4041
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4042
-            if (
4043
-                $this->_message_resource_manager->is_message_type_active_for_messenger(
4044
-                    $messenger_name,
4045
-                    $message_type_name
4046
-                )
4047
-                && $message_type instanceof EE_message_type
4048
-            ) {
4049
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
4050
-                if ($message_type->get_admin_settings_fields()) {
4051
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
4052
-                }
4053
-            }
4054
-        }
4055
-
4056
-        // add success message for activating messenger
4057
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4058
-    }
4059
-
4060
-
4061
-    /**
4062
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
4063
-     *
4064
-     * @param string $messenger_name The name of the messenger being activated
4065
-     * @return bool
4066
-     * @throws DomainException
4067
-     * @throws EE_Error
4068
-     * @throws InvalidArgumentException
4069
-     * @throws ReflectionException
4070
-     * @throws InvalidDataTypeException
4071
-     * @throws InvalidInterfaceException
4072
-     */
4073
-    protected function _deactivate_messenger($messenger_name)
4074
-    {
4075
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4076
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4077
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
4078
-
4079
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4080
-    }
4081
-
4082
-
4083
-    /**
4084
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4085
-     *
4086
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
4087
-     * @param string $message_type_name The name of the message type being activated for the messenger
4088
-     * @return bool
4089
-     * @throws DomainException
4090
-     * @throws EE_Error
4091
-     * @throws InvalidArgumentException
4092
-     * @throws ReflectionException
4093
-     * @throws InvalidDataTypeException
4094
-     * @throws InvalidInterfaceException
4095
-     */
4096
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4097
-    {
4098
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4099
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4100
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4101
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4102
-
4103
-        // ensure is active
4104
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4105
-
4106
-        // set response for load
4107
-        if (
4108
-            $this->_message_resource_manager->is_message_type_active_for_messenger(
4109
-                $messenger_name,
4110
-                $message_type_name
4111
-            )
4112
-        ) {
4113
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
4114
-            if ($message_type_to_activate->get_admin_settings_fields()) {
4115
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
4116
-            }
4117
-        }
4118
-
4119
-        return $this->_setup_response_message_for_activating_messenger_with_message_types(
4120
-            $active_messenger,
4121
-            $message_type_to_activate
4122
-        );
4123
-    }
4124
-
4125
-
4126
-    /**
4127
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4128
-     *
4129
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4130
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
4131
-     * @return bool
4132
-     * @throws DomainException
4133
-     * @throws EE_Error
4134
-     * @throws InvalidArgumentException
4135
-     * @throws ReflectionException
4136
-     * @throws InvalidDataTypeException
4137
-     * @throws InvalidInterfaceException
4138
-     */
4139
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4140
-    {
4141
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4142
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4143
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4144
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4145
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4146
-
4147
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4148
-            $active_messenger,
4149
-            $message_type_to_deactivate
4150
-        );
4151
-    }
4152
-
4153
-
4154
-    /**
4155
-     * This just initializes the defaults for activating messenger and message type responses.
4156
-     */
4157
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
4158
-    {
4159
-        $this->_template_args['data']['active_mts'] = [];
4160
-        $this->_template_args['data']['mt_reload']  = [];
4161
-    }
4162
-
4163
-
4164
-    /**
4165
-     * Setup appropriate response for activating a messenger and/or message types
4166
-     *
4167
-     * @param EE_messenger         $messenger
4168
-     * @param EE_message_type|null $message_type
4169
-     * @return bool
4170
-     * @throws DomainException
4171
-     * @throws EE_Error
4172
-     * @throws InvalidArgumentException
4173
-     * @throws ReflectionException
4174
-     * @throws InvalidDataTypeException
4175
-     * @throws InvalidInterfaceException
4176
-     */
4177
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
4178
-        $messenger,
4179
-        EE_Message_Type $message_type = null
4180
-    ) {
4181
-        // if $messenger isn't a valid messenger object then get out.
4182
-        if (! $messenger instanceof EE_Messenger) {
4183
-            EE_Error::add_error(
4184
-                esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4185
-                __FILE__,
4186
-                __FUNCTION__,
4187
-                __LINE__
4188
-            );
4189
-
4190
-            return false;
4191
-        }
4192
-        // activated
4193
-        if ($this->_template_args['data']['active_mts']) {
4194
-            EE_Error::overwrite_success();
4195
-            // activated a message type with the messenger
4196
-            if ($message_type instanceof EE_message_type) {
4197
-                EE_Error::add_success(
4198
-                    sprintf(
4199
-                        esc_html__(
4200
-                            '%s message type has been successfully activated with the %s messenger',
4201
-                            'event_espresso'
4202
-                        ),
4203
-                        ucwords($message_type->label['singular']),
4204
-                        ucwords($messenger->label['singular'])
4205
-                    )
4206
-                );
4207
-
4208
-                // if message type was invoice then let's make sure we activate the invoice payment method.
4209
-                if ($message_type->name === 'invoice') {
4210
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
4211
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4212
-                    if ($pm instanceof EE_Payment_Method) {
4213
-                        EE_Error::add_attention(
4214
-                            esc_html__(
4215
-                                'Activating the invoice message type also automatically activates the invoice payment method.  If you do not wish the invoice payment method to be active, or to change its settings, visit the payment method admin page.',
4216
-                                'event_espresso'
4217
-                            )
4218
-                        );
4219
-                    }
4220
-                }
4221
-                // just toggles the entire messenger
4222
-            } else {
4223
-                EE_Error::add_success(
4224
-                    sprintf(
4225
-                        esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4226
-                        ucwords($messenger->label['singular'])
4227
-                    )
4228
-                );
4229
-            }
4230
-
4231
-            return true;
4232
-
4233
-            // possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4234
-            // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4235
-            // in which case we just give a success message for the messenger being successfully activated.
4236
-        } else {
4237
-            if (! $messenger->get_default_message_types()) {
4238
-                // messenger doesn't have any default message types so still a success.
4239
-                EE_Error::add_success(
4240
-                    sprintf(
4241
-                        esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4242
-                        ucwords($messenger->label['singular'])
4243
-                    )
4244
-                );
4245
-
4246
-                return true;
4247
-            } else {
4248
-                EE_Error::add_error(
4249
-                    $message_type instanceof EE_message_type
4250
-                        ? sprintf(
4251
-                            esc_html__(
4252
-                                '%s message type was not successfully activated with the %s messenger',
4253
-                                'event_espresso'
4254
-                            ),
4255
-                            ucwords($message_type->label['singular']),
4256
-                            ucwords($messenger->label['singular'])
4257
-                        )
4258
-                        : sprintf(
4259
-                            esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4260
-                            ucwords($messenger->label['singular'])
4261
-                        ),
4262
-                    __FILE__,
4263
-                    __FUNCTION__,
4264
-                    __LINE__
4265
-                );
4266
-
4267
-                return false;
4268
-            }
4269
-        }
4270
-    }
4271
-
4272
-
4273
-    /**
4274
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
4275
-     *
4276
-     * @param EE_messenger         $messenger
4277
-     * @param EE_message_type|null $message_type
4278
-     * @return bool
4279
-     * @throws DomainException
4280
-     * @throws EE_Error
4281
-     * @throws InvalidArgumentException
4282
-     * @throws ReflectionException
4283
-     * @throws InvalidDataTypeException
4284
-     * @throws InvalidInterfaceException
4285
-     */
4286
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4287
-        $messenger,
4288
-        EE_message_type $message_type = null
4289
-    ) {
4290
-        EE_Error::overwrite_success();
4291
-
4292
-        // if $messenger isn't a valid messenger object then get out.
4293
-        if (! $messenger instanceof EE_Messenger) {
4294
-            EE_Error::add_error(
4295
-                esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4296
-                __FILE__,
4297
-                __FUNCTION__,
4298
-                __LINE__
4299
-            );
4300
-
4301
-            return false;
4302
-        }
4303
-
4304
-        if ($message_type instanceof EE_message_type) {
4305
-            $message_type_name = $message_type->name;
4306
-            EE_Error::add_success(
4307
-                sprintf(
4308
-                    esc_html__(
4309
-                        '%s message type has been successfully deactivated for the %s messenger.',
4310
-                        'event_espresso'
4311
-                    ),
4312
-                    ucwords($message_type->label['singular']),
4313
-                    ucwords($messenger->label['singular'])
4314
-                )
4315
-            );
4316
-        } else {
4317
-            $message_type_name = '';
4318
-            EE_Error::add_success(
4319
-                sprintf(
4320
-                    esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4321
-                    ucwords($messenger->label['singular'])
4322
-                )
4323
-            );
4324
-        }
4325
-
4326
-        // if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4327
-        if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4328
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
4329
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4330
-            if ($count_updated > 0) {
4331
-                $msg = $message_type_name === 'invoice'
4332
-                    ? esc_html__(
4333
-                        'Deactivating the invoice message type also automatically deactivates the invoice payment method. In order for invoices to be generated the invoice message type must be active. If you completed this action by mistake, simply reactivate the invoice message type and then visit the payment methods admin page to reactivate the invoice payment method.',
4334
-                        'event_espresso'
4335
-                    )
4336
-                    : esc_html__(
4337
-                        'Deactivating the html messenger also automatically deactivates the invoice payment method.  In order for invoices to be generated the html messenger must be be active.  If you completed this action by mistake, simply reactivate the html messenger, then visit the payment methods admin page to reactivate the invoice payment method.',
4338
-                        'event_espresso'
4339
-                    );
4340
-                EE_Error::add_attention($msg);
4341
-            }
4342
-        }
4343
-
4344
-        return true;
4345
-    }
4346
-
4347
-
4348
-    /**
4349
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4350
-     *
4351
-     * @throws DomainException
4352
-     */
4353
-    public function update_mt_form()
4354
-    {
4355
-        if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4356
-            EE_Error::add_error(
4357
-                esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4358
-                __FILE__,
4359
-                __FUNCTION__,
4360
-                __LINE__
4361
-            );
4362
-            $this->_return_json();
4363
-        }
4364
-
4365
-        $message_types = $this->get_installed_message_types();
4366
-
4367
-        $message_type = $message_types[ $this->_req_data['message_type'] ];
4368
-        $messenger    = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4369
-
4370
-        $content                         = $this->_message_type_settings_content(
4371
-            $message_type,
4372
-            $messenger,
4373
-            true
4374
-        );
4375
-        $this->_template_args['success'] = true;
4376
-        $this->_template_args['content'] = $content;
4377
-        $this->_return_json();
4378
-    }
4379
-
4380
-
4381
-    /**
4382
-     * this handles saving the settings for a messenger or message type
4383
-     *
4384
-     */
4385
-    public function save_settings()
4386
-    {
4387
-        if (! isset($this->_req_data['type'])) {
4388
-            EE_Error::add_error(
4389
-                esc_html__(
4390
-                    'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4391
-                    'event_espresso'
4392
-                ),
4393
-                __FILE__,
4394
-                __FUNCTION__,
4395
-                __LINE__
4396
-            );
4397
-            $this->_template_args['error'] = true;
4398
-            $this->_return_json();
4399
-        }
4400
-
4401
-
4402
-        if ($this->_req_data['type'] === 'messenger') {
4403
-            // this should be an array.
4404
-            $settings  = $this->_req_data['messenger_settings'];
4405
-            $messenger = $settings['messenger'];
4406
-            // let's setup the settings data
4407
-            foreach ($settings as $key => $value) {
4408
-                switch ($key) {
4409
-                    case 'messenger':
4410
-                        unset($settings['messenger']);
4411
-                        break;
4412
-                    case 'message_types':
4413
-                        unset($settings['message_types']);
4414
-                        break;
4415
-                    default:
4416
-                        $settings[ $key ] = $value;
4417
-                        break;
4418
-                }
4419
-            }
4420
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4421
-        } elseif ($this->_req_data['type'] === 'message_type') {
4422
-            $settings     = $this->_req_data['message_type_settings'];
4423
-            $messenger    = $settings['messenger'];
4424
-            $message_type = $settings['message_type'];
4425
-
4426
-            foreach ($settings as $key => $value) {
4427
-                switch ($key) {
4428
-                    case 'messenger':
4429
-                        unset($settings['messenger']);
4430
-                        break;
4431
-                    case 'message_type':
4432
-                        unset($settings['message_type']);
4433
-                        break;
4434
-                    default:
4435
-                        $settings[ $key ] = $value;
4436
-                        break;
4437
-                }
4438
-            }
4439
-
4440
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4441
-        }
4442
-
4443
-        // okay we should have the data all setup.  Now we just update!
4444
-        $success = $this->_message_resource_manager->update_active_messengers_option();
4445
-
4446
-        if ($success) {
4447
-            EE_Error::add_success(esc_html__('Settings updated', 'event_espresso'));
4448
-        } else {
4449
-            EE_Error::add_error(
4450
-                esc_html__(
4451
-                    'Settings did not get updated',
4452
-                    'event_espresso'
4453
-                ),
4454
-                __FILE__,
4455
-                __FUNCTION__,
4456
-                __LINE__
4457
-            );
4458
-        }
4459
-
4460
-        $this->_template_args['success'] = $success;
4461
-        $this->_return_json();
4462
-    }
4463
-
4464
-
4465
-
4466
-
4467
-    /**  EE MESSAGE PROCESSING ACTIONS **/
4468
-
4469
-
4470
-    /**
4471
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4472
-     * However, this does not send immediately, it just queues for sending.
4473
-     *
4474
-     * @throws EE_Error
4475
-     * @throws InvalidDataTypeException
4476
-     * @throws InvalidInterfaceException
4477
-     * @throws InvalidArgumentException
4478
-     * @throws ReflectionException
4479
-     * @since 4.9.0
4480
-     */
4481
-    protected function _generate_now()
4482
-    {
4483
-        EED_Messages::generate_now($this->_get_msg_ids_from_request());
4484
-        $this->_redirect_after_action(false, '', '', [], true);
4485
-    }
4486
-
4487
-
4488
-    /**
4489
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4490
-     * are EEM_Message::status_resend or EEM_Message::status_idle
4491
-     *
4492
-     * @throws EE_Error
4493
-     * @throws InvalidDataTypeException
4494
-     * @throws InvalidInterfaceException
4495
-     * @throws InvalidArgumentException
4496
-     * @throws ReflectionException
4497
-     * @since 4.9.0
4498
-     */
4499
-    protected function _generate_and_send_now()
4500
-    {
4501
-        EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4502
-        $this->_redirect_after_action(false, '', '', [], true);
4503
-    }
4504
-
4505
-
4506
-    /**
4507
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4508
-     *
4509
-     * @throws EE_Error
4510
-     * @throws InvalidDataTypeException
4511
-     * @throws InvalidInterfaceException
4512
-     * @throws InvalidArgumentException
4513
-     * @throws ReflectionException
4514
-     * @since 4.9.0
4515
-     */
4516
-    protected function _queue_for_resending()
4517
-    {
4518
-        EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4519
-        $this->_redirect_after_action(false, '', '', [], true);
4520
-    }
4521
-
4522
-
4523
-    /**
4524
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4525
-     *
4526
-     * @throws EE_Error
4527
-     * @throws InvalidDataTypeException
4528
-     * @throws InvalidInterfaceException
4529
-     * @throws InvalidArgumentException
4530
-     * @throws ReflectionException
4531
-     * @since 4.9.0
4532
-     */
4533
-    protected function _send_now()
4534
-    {
4535
-        EED_Messages::send_now($this->_get_msg_ids_from_request());
4536
-        $this->_redirect_after_action(false, '', '', [], true);
4537
-    }
4538
-
4539
-
4540
-    /**
4541
-     * Deletes EE_messages for IDs in the request.
4542
-     *
4543
-     * @throws EE_Error
4544
-     * @throws InvalidDataTypeException
4545
-     * @throws InvalidInterfaceException
4546
-     * @throws InvalidArgumentException
4547
-     * @since 4.9.0
4548
-     */
4549
-    protected function _delete_ee_messages()
4550
-    {
4551
-        $msg_ids       = $this->_get_msg_ids_from_request();
4552
-        $deleted_count = 0;
4553
-        foreach ($msg_ids as $msg_id) {
4554
-            if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4555
-                $deleted_count++;
4556
-            }
4557
-        }
4558
-        if ($deleted_count) {
4559
-            EE_Error::add_success(
4560
-                esc_html(
4561
-                    _n(
4562
-                        'Message successfully deleted',
4563
-                        'Messages successfully deleted',
4564
-                        $deleted_count,
4565
-                        'event_espresso'
4566
-                    )
4567
-                )
4568
-            );
4569
-            $this->_redirect_after_action(
4570
-                false,
4571
-                '',
4572
-                '',
4573
-                [],
4574
-                true
4575
-            );
4576
-        } else {
4577
-            EE_Error::add_error(
4578
-                _n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4579
-                __FILE__,
4580
-                __FUNCTION__,
4581
-                __LINE__
4582
-            );
4583
-            $this->_redirect_after_action(false, '', '', [], true);
4584
-        }
4585
-    }
4586
-
4587
-
4588
-    /**
4589
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4590
-     *
4591
-     * @return array
4592
-     * @since 4.9.0
4593
-     */
4594
-    protected function _get_msg_ids_from_request()
4595
-    {
4596
-        if (! isset($this->_req_data['MSG_ID'])) {
4597
-            return [];
4598
-        }
4599
-
4600
-        return is_array($this->_req_data['MSG_ID'])
4601
-            ? array_keys($this->_req_data['MSG_ID'])
4602
-            : [$this->_req_data['MSG_ID']];
4603
-    }
2682
+	}
2683
+
2684
+
2685
+	/**
2686
+	 * utility for sanitizing new values coming in.
2687
+	 * Note: this is only used when updating a context.
2688
+	 *
2689
+	 * @access protected
2690
+	 *
2691
+	 * @param int $index This helps us know which template field to select from the request array.
2692
+	 *
2693
+	 * @return array
2694
+	 */
2695
+	protected function _set_message_template_column_values($index)
2696
+	{
2697
+		if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2698
+			foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2699
+				$this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2700
+			}
2701
+		}
2702
+
2703
+
2704
+		$set_column_values = [
2705
+			'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2706
+			'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2707
+			'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2708
+			'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2709
+			'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2710
+			'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2711
+			'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2712
+			'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2713
+			'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2714
+				? absint($this->_req_data['MTP_is_global'])
2715
+				: 0,
2716
+			'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2717
+				? absint($this->_req_data['MTP_is_override'])
2718
+				: 0,
2719
+			'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2720
+			'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2721
+		];
2722
+
2723
+
2724
+		return $set_column_values;
2725
+	}
2726
+
2727
+
2728
+	protected function _insert_or_update_message_template($new = false)
2729
+	{
2730
+		$success = 0;
2731
+		$override = false;
2732
+
2733
+		// setup notices description
2734
+		$messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2735
+
2736
+		// need the message type and messenger objects to be able to use the labels for the notices
2737
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2738
+		$messenger_label  = $messenger_object instanceof EE_messenger
2739
+			? ucwords($messenger_object->label['singular'])
2740
+			: '';
2741
+
2742
+		$message_type_slug   = ! empty($this->_req_data['MTP_message_type'])
2743
+			? $this->_req_data['MTP_message_type']
2744
+			: '';
2745
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2746
+
2747
+		$message_type_label = $message_type_object instanceof EE_message_type
2748
+			? ucwords($message_type_object->label['singular'])
2749
+			: '';
2750
+
2751
+		$context_slug = ! empty($this->_req_data['MTP_context'])
2752
+			? $this->_req_data['MTP_context']
2753
+			: '';
2754
+		$context      = ucwords(str_replace('_', ' ', $context_slug));
2755
+
2756
+		$item_desc   = $messenger_label && $message_type_label
2757
+			? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2758
+			: '';
2759
+		$item_desc   .= 'Message Template';
2760
+		$query_args  = [];
2761
+		$edit_array  = [];
2762
+		$action_desc = '';
2763
+
2764
+		// if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2765
+		// user to edit.
2766
+		if ($new) {
2767
+			$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2768
+			if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2769
+				if (empty($edit_array)) {
2770
+					$success = 0;
2771
+				} else {
2772
+					$success    = 1;
2773
+					$edit_array = $edit_array[0];
2774
+					$query_args = [
2775
+						'id'      => $edit_array['GRP_ID'],
2776
+						'context' => $edit_array['MTP_context'],
2777
+						'action'  => 'edit_message_template',
2778
+					];
2779
+				}
2780
+			}
2781
+			$action_desc = 'created';
2782
+		} else {
2783
+			$MTPG = EEM_Message_Template_Group::instance();
2784
+			$MTP  = EEM_Message_Template::instance();
2785
+
2786
+
2787
+			// run update for each template field in displayed context
2788
+			if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2789
+				EE_Error::add_error(
2790
+					esc_html__(
2791
+						'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2792
+						'event_espresso'
2793
+					),
2794
+					__FILE__,
2795
+					__FUNCTION__,
2796
+					__LINE__
2797
+				);
2798
+				$success = 0;
2799
+			} else {
2800
+				// first validate all fields!
2801
+				// this filter allows client code to add its own validation to the template fields as well.
2802
+				// returning an empty array means everything passed validation.
2803
+				// errors in validation should be represented in an array with the following shape:
2804
+				// array(
2805
+				//   'fieldname' => array(
2806
+				//          'msg' => 'error message'
2807
+				//          'value' => 'value for field producing error'
2808
+				// )
2809
+				$custom_validation = (array) apply_filters(
2810
+					'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2811
+					[],
2812
+					$this->_req_data['MTP_template_fields'],
2813
+					$context_slug,
2814
+					$messenger_slug,
2815
+					$message_type_slug
2816
+				);
2817
+
2818
+				$system_validation = $MTPG->validate(
2819
+					$this->_req_data['MTP_template_fields'],
2820
+					$context_slug,
2821
+					$messenger_slug,
2822
+					$message_type_slug
2823
+				);
2824
+
2825
+				$system_validation = ! is_array($system_validation) && $system_validation ? []
2826
+					: $system_validation;
2827
+				$validates         = array_merge($custom_validation, $system_validation);
2828
+
2829
+				// if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2830
+				// appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2831
+				//  WE need to make sure there is no actual error messages in validates.
2832
+				if (is_array($validates) && ! empty($validates)) {
2833
+					// add the transient so when the form loads we know which fields to highlight
2834
+					$this->_add_transient('edit_message_template', $validates);
2835
+
2836
+					$success = 0;
2837
+
2838
+					// setup notices
2839
+					foreach ($validates as $field => $error) {
2840
+						if (isset($error['msg'])) {
2841
+							EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2842
+						}
2843
+					}
2844
+				} else {
2845
+					$set_column_values = [];
2846
+					foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2847
+						$set_column_values = $this->_set_message_template_column_values($template_field);
2848
+
2849
+						$where_cols_n_values = [
2850
+							'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2851
+						];
2852
+						// if they aren't allowed to use all JS, restrict them to just posty-y tags
2853
+						if (! current_user_can('unfiltered_html')) {
2854
+							if (is_array($set_column_values['MTP_content'])) {
2855
+								foreach ($set_column_values['MTP_content'] as $key => $value) {
2856
+									// remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2857
+									// only removes slashes from double-quotes, so attributes using single quotes always
2858
+									// appear invalid.) But currently the models expect slashed data, so after wp_kses
2859
+									// runs we need to re-slash the data. Sheesh. See
2860
+									// https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2861
+									$set_column_values['MTP_content'][ $key ] = addslashes(
2862
+										wp_kses(
2863
+											stripslashes($value),
2864
+											wp_kses_allowed_html('post')
2865
+										)
2866
+									);
2867
+								}
2868
+							} else {
2869
+								$set_column_values['MTP_content'] = wp_kses(
2870
+									$set_column_values['MTP_content'],
2871
+									wp_kses_allowed_html('post')
2872
+								);
2873
+							}
2874
+						}
2875
+						$message_template_fields = [
2876
+							'GRP_ID'             => $set_column_values['GRP_ID'],
2877
+							'MTP_template_field' => $set_column_values['MTP_template_field'],
2878
+							'MTP_context'        => $set_column_values['MTP_context'],
2879
+							'MTP_content'        => $set_column_values['MTP_content'],
2880
+						];
2881
+						if ($updated = $MTP->update($message_template_fields, [$where_cols_n_values])) {
2882
+							if ($updated === false) {
2883
+								EE_Error::add_error(
2884
+									sprintf(
2885
+										esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2886
+										$template_field
2887
+									),
2888
+									__FILE__,
2889
+									__FUNCTION__,
2890
+									__LINE__
2891
+								);
2892
+							} else {
2893
+								$success = 1;
2894
+							}
2895
+						} else {
2896
+							// only do this logic if we don't have a MTP_ID for this field
2897
+							if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2898
+								// this has already been through the template field validator and sanitized, so it will be
2899
+								// safe to insert this field.  Why insert?  This typically happens when we introduce a new
2900
+								// message template field in a messenger/message type and existing users don't have the
2901
+								// default setup for it.
2902
+								// @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2903
+								$updated = $MTP->insert($message_template_fields);
2904
+								if (! $updated || is_wp_error($updated)) {
2905
+									EE_Error::add_error(
2906
+										sprintf(
2907
+											esc_html__('%s field could not be updated.', 'event_espresso'),
2908
+											$template_field
2909
+										),
2910
+										__FILE__,
2911
+										__FUNCTION__,
2912
+										__LINE__
2913
+									);
2914
+									$success = 0;
2915
+								} else {
2916
+									$success = 1;
2917
+								}
2918
+							}
2919
+						}
2920
+						$action_desc = 'updated';
2921
+					}
2922
+
2923
+					// we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2924
+					$mtpg_fields = [
2925
+						'MTP_user_id'      => $set_column_values['MTP_user_id'],
2926
+						'MTP_messenger'    => $set_column_values['MTP_messenger'],
2927
+						'MTP_message_type' => $set_column_values['MTP_message_type'],
2928
+						'MTP_is_global'    => $set_column_values['MTP_is_global'],
2929
+						'MTP_is_override'  => $set_column_values['MTP_is_override'],
2930
+						'MTP_deleted'      => $set_column_values['MTP_deleted'],
2931
+						'MTP_is_active'    => $set_column_values['MTP_is_active'],
2932
+						'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2933
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2934
+							: '',
2935
+						'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2936
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2937
+							: '',
2938
+					];
2939
+
2940
+					$mtpg_where = ['GRP_ID' => $set_column_values['GRP_ID']];
2941
+					$updated    = $MTPG->update($mtpg_fields, [$mtpg_where]);
2942
+
2943
+					if ($updated === false) {
2944
+						EE_Error::add_error(
2945
+							sprintf(
2946
+								esc_html__(
2947
+									'The Message Template Group (%d) was NOT updated for some reason',
2948
+									'event_espresso'
2949
+								),
2950
+								$set_column_values['GRP_ID']
2951
+							),
2952
+							__FILE__,
2953
+							__FUNCTION__,
2954
+							__LINE__
2955
+						);
2956
+					} else {
2957
+						// k now we need to ensure the template_pack and template_variation fields are set.
2958
+						$template_pack = ! empty($this->_req_data['MTP_template_pack'])
2959
+							? $this->_req_data['MTP_template_pack']
2960
+							: 'default';
2961
+
2962
+						$template_variation = ! empty($this->_req_data['MTP_template_variation'])
2963
+							? $this->_req_data['MTP_template_variation']
2964
+							: 'default';
2965
+
2966
+						$mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2967
+						if ($mtpg_obj instanceof EE_Message_Template_Group) {
2968
+							$mtpg_obj->set_template_pack_name($template_pack);
2969
+							$mtpg_obj->set_template_pack_variation($template_variation);
2970
+						}
2971
+						$success = 1;
2972
+					}
2973
+				}
2974
+			}
2975
+		}
2976
+
2977
+		// we return things differently if doing ajax
2978
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2979
+			$this->_template_args['success'] = $success;
2980
+			$this->_template_args['error']   = ! $success ? true : false;
2981
+			$this->_template_args['content'] = '';
2982
+			$this->_template_args['data']    = [
2983
+				'grpID'        => $edit_array['GRP_ID'],
2984
+				'templateName' => $edit_array['template_name'],
2985
+			];
2986
+			if ($success) {
2987
+				EE_Error::overwrite_success();
2988
+				EE_Error::add_success(
2989
+					esc_html__(
2990
+						'The new template has been created and automatically selected for this event.  You can edit the new template by clicking the edit button.  Note before this template is assigned to this event, the event must be saved.',
2991
+						'event_espresso'
2992
+					)
2993
+				);
2994
+			}
2995
+
2996
+			$this->_return_json();
2997
+		}
2998
+
2999
+
3000
+		// was a test send triggered?
3001
+		if (isset($this->_req_data['test_button'])) {
3002
+			EE_Error::overwrite_success();
3003
+			$this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
3004
+			$override = true;
3005
+		}
3006
+
3007
+		if (empty($query_args)) {
3008
+			$query_args = [
3009
+				'id'      => $this->_req_data['GRP_ID'],
3010
+				'context' => $context_slug,
3011
+				'action'  => 'edit_message_template',
3012
+			];
3013
+		}
3014
+
3015
+		$this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3016
+	}
3017
+
3018
+
3019
+	/**
3020
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
3021
+	 *
3022
+	 * @param string $context      what context being tested
3023
+	 * @param string $messenger    messenger being tested
3024
+	 * @param string $message_type message type being tested
3025
+	 * @throws EE_Error
3026
+	 * @throws InvalidArgumentException
3027
+	 * @throws InvalidDataTypeException
3028
+	 * @throws InvalidInterfaceException
3029
+	 */
3030
+	protected function _do_test_send($context, $messenger, $message_type)
3031
+	{
3032
+		// set things up for preview
3033
+		$this->_req_data['messenger']    = $messenger;
3034
+		$this->_req_data['message_type'] = $message_type;
3035
+		$this->_req_data['context']      = $context;
3036
+		$this->_req_data['GRP_ID']       = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3037
+		$active_messenger                = $this->_message_resource_manager->get_active_messenger($messenger);
3038
+
3039
+		// let's save any existing fields that might be required by the messenger
3040
+		if (
3041
+			isset($this->_req_data['test_settings_fld'])
3042
+			&& $active_messenger instanceof EE_messenger
3043
+			&& apply_filters(
3044
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3045
+				true,
3046
+				$this->_req_data['test_settings_fld'],
3047
+				$active_messenger
3048
+			)
3049
+		) {
3050
+			$active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3051
+		}
3052
+
3053
+		/**
3054
+		 * Use filter to add additional controls on whether message can send or not
3055
+		 */
3056
+		if (
3057
+			apply_filters(
3058
+				'FHEE__Messages_Admin_Page__do_test_send__can_send',
3059
+				true,
3060
+				$context,
3061
+				$this->_req_data,
3062
+				$messenger,
3063
+				$message_type
3064
+			)
3065
+		) {
3066
+			if (EEM_Event::instance()->count() > 0) {
3067
+				$success = $this->_preview_message(true);
3068
+				if ($success) {
3069
+					EE_Error::add_success(esc_html__('Test message sent', 'event_espresso'));
3070
+				} else {
3071
+					EE_Error::add_error(
3072
+						esc_html__('The test message was not sent', 'event_espresso'),
3073
+						__FILE__,
3074
+						__FUNCTION__,
3075
+						__LINE__
3076
+					);
3077
+				}
3078
+			} else {
3079
+				$this->noEventsErrorMessage(true);
3080
+			}
3081
+		}
3082
+	}
3083
+
3084
+
3085
+	/**
3086
+	 * _generate_new_templates
3087
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3088
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3089
+	 * for the event.
3090
+	 *
3091
+	 *
3092
+	 * @param string $messenger      the messenger we are generating templates for
3093
+	 * @param array  $message_types  array of message types that the templates are generated for.
3094
+	 * @param int    $GRP_ID         If this is a custom template being generated then a GRP_ID needs to be included to
3095
+	 *                               indicate the message_template_group being used as the base.
3096
+	 *
3097
+	 * @param bool   $global
3098
+	 *
3099
+	 * @return array|bool array of data required for the redirect to the correct edit page or bool if
3100
+	 *                               encountering problems.
3101
+	 * @throws EE_Error
3102
+	 */
3103
+	protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3104
+	{
3105
+
3106
+		// if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3107
+		// just don't generate any templates.
3108
+		if (empty($message_types)) {
3109
+			return true;
3110
+		}
3111
+
3112
+		return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3113
+	}
3114
+
3115
+
3116
+	/**
3117
+	 * [_trash_or_restore_message_template]
3118
+	 *
3119
+	 * @param boolean $trash  whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3120
+	 * @param boolean $all    whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3121
+	 *                        an individual context (FALSE).
3122
+	 * @return void
3123
+	 * @throws EE_Error
3124
+	 * @throws InvalidArgumentException
3125
+	 * @throws InvalidDataTypeException
3126
+	 * @throws InvalidInterfaceException
3127
+	 */
3128
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
3129
+	{
3130
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3131
+		$MTP = EEM_Message_Template_Group::instance();
3132
+
3133
+		$success = 1;
3134
+
3135
+		// incoming GRP_IDs
3136
+		if ($all) {
3137
+			// Checkboxes
3138
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3139
+				// if array has more than one element then success message should be plural.
3140
+				// todo: what about nonce?
3141
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3142
+
3143
+				// cycle through checkboxes
3144
+				while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3145
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3146
+					if (! $trashed_or_restored) {
3147
+						$success = 0;
3148
+					}
3149
+				}
3150
+			} else {
3151
+				// grab single GRP_ID and handle
3152
+				$GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3153
+				if (! empty($GRP_ID)) {
3154
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3155
+					if (! $trashed_or_restored) {
3156
+						$success = 0;
3157
+					}
3158
+				} else {
3159
+					$success = 0;
3160
+				}
3161
+			}
3162
+		}
3163
+
3164
+		$action_desc = $trash
3165
+			? esc_html__('moved to the trash', 'event_espresso')
3166
+			: esc_html__('restored', 'event_espresso');
3167
+
3168
+		$action_desc =
3169
+			! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3170
+
3171
+		$item_desc = $all ? _n(
3172
+			'Message Template Group',
3173
+			'Message Template Groups',
3174
+			$success,
3175
+			'event_espresso'
3176
+		) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3177
+
3178
+		$item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3179
+			'template',
3180
+			'templates',
3181
+			$success,
3182
+			'event_espresso'
3183
+		) : $item_desc;
3184
+
3185
+		$this->_redirect_after_action($success, $item_desc, $action_desc, []);
3186
+	}
3187
+
3188
+
3189
+	/**
3190
+	 * [_delete_message_template]
3191
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3192
+	 *
3193
+	 * @return void
3194
+	 * @throws EE_Error
3195
+	 * @throws InvalidArgumentException
3196
+	 * @throws InvalidDataTypeException
3197
+	 * @throws InvalidInterfaceException
3198
+	 */
3199
+	protected function _delete_message_template()
3200
+	{
3201
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3202
+
3203
+		// checkboxes
3204
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3205
+			// if array has more than one element then success message should be plural
3206
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3207
+
3208
+			// cycle through bulk action checkboxes
3209
+			while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3210
+				$success = $this->_delete_mtp_permanently($GRP_ID);
3211
+			}
3212
+		} else {
3213
+			// grab single grp_id and delete
3214
+			$GRP_ID  = absint($this->_req_data['id']);
3215
+			$success = $this->_delete_mtp_permanently($GRP_ID);
3216
+		}
3217
+
3218
+		$this->_redirect_after_action($success, 'Message Templates', 'deleted', []);
3219
+	}
3220
+
3221
+
3222
+	/**
3223
+	 * helper for permanently deleting a mtP group and all related message_templates
3224
+	 *
3225
+	 * @param int  $GRP_ID        The group being deleted
3226
+	 * @param bool $include_group whether to delete the Message Template Group as well.
3227
+	 * @return bool boolean to indicate the success of the deletes or not.
3228
+	 * @throws EE_Error
3229
+	 * @throws InvalidArgumentException
3230
+	 * @throws InvalidDataTypeException
3231
+	 * @throws InvalidInterfaceException
3232
+	 */
3233
+	private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3234
+	{
3235
+		$success = 1;
3236
+		$MTPG    = EEM_Message_Template_Group::instance();
3237
+		// first let's GET this group
3238
+		$MTG = $MTPG->get_one_by_ID($GRP_ID);
3239
+		// then delete permanently all the related Message Templates
3240
+		$deleted = $MTG->delete_related_permanently('Message_Template');
3241
+
3242
+		if ($deleted === 0) {
3243
+			$success = 0;
3244
+		}
3245
+
3246
+		// now delete permanently this particular group
3247
+
3248
+		if ($include_group && ! $MTG->delete_permanently()) {
3249
+			$success = 0;
3250
+		}
3251
+
3252
+		return $success;
3253
+	}
3254
+
3255
+
3256
+	/**
3257
+	 *    _learn_more_about_message_templates_link
3258
+	 *
3259
+	 * @access protected
3260
+	 * @return string
3261
+	 */
3262
+	protected function _learn_more_about_message_templates_link()
3263
+	{
3264
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3265
+			   . esc_html__('learn more about how message templates works', 'event_espresso')
3266
+			   . '</a>';
3267
+	}
3268
+
3269
+
3270
+	/**
3271
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3272
+	 * ajax and other routes.
3273
+	 *
3274
+	 * @return void
3275
+	 * @throws DomainException
3276
+	 */
3277
+	protected function _settings()
3278
+	{
3279
+
3280
+
3281
+		$this->_set_m_mt_settings();
3282
+
3283
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3284
+			? $this->_req_data['selected_messenger']
3285
+			: 'email';
3286
+
3287
+		// let's setup the messenger tabs
3288
+		$this->_template_args['admin_page_header']         = EEH_Tabbed_Content::tab_text_links(
3289
+			$this->_m_mt_settings['messenger_tabs'],
3290
+			'messenger_links',
3291
+			'|',
3292
+			$selected_messenger
3293
+		);
3294
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3295
+		$this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
3296
+
3297
+		$this->display_admin_page_with_sidebar();
3298
+	}
3299
+
3300
+
3301
+	/**
3302
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3303
+	 *
3304
+	 * @access protected
3305
+	 * @return void
3306
+	 * @throws DomainException
3307
+	 */
3308
+	protected function _set_m_mt_settings()
3309
+	{
3310
+		// first if this is already set then lets get out no need to regenerate data.
3311
+		if (! empty($this->_m_mt_settings)) {
3312
+			return;
3313
+		}
3314
+
3315
+		// get all installed messengers and message_types
3316
+		/** @type EE_messenger[] $messengers */
3317
+		$messengers = $this->_message_resource_manager->installed_messengers();
3318
+		/** @type EE_message_type[] $message_types */
3319
+		$message_types = $this->_message_resource_manager->installed_message_types();
3320
+
3321
+
3322
+		// assemble the array for the _tab_text_links helper
3323
+
3324
+		foreach ($messengers as $messenger) {
3325
+			$this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
3326
+				'label' => ucwords($messenger->label['singular']),
3327
+				'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3328
+					? 'messenger-active'
3329
+					: '',
3330
+				'href'  => $messenger->name,
3331
+				'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3332
+				'slug'  => $messenger->name,
3333
+				'obj'   => $messenger,
3334
+			];
3335
+
3336
+
3337
+			$message_types_for_messenger = $messenger->get_valid_message_types();
3338
+
3339
+			foreach ($message_types as $message_type) {
3340
+				// first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3341
+				// it shouldn't show in either the inactive OR active metabox.
3342
+				if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3343
+					continue;
3344
+				}
3345
+
3346
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3347
+					$messenger->name,
3348
+					$message_type->name
3349
+				)
3350
+					? 'active'
3351
+					: 'inactive';
3352
+
3353
+				$this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
3354
+					'label'    => ucwords($message_type->label['singular']),
3355
+					'class'    => 'message-type-' . $a_or_i,
3356
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3357
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3358
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3359
+					'title'    => $a_or_i === 'active'
3360
+						? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3361
+						: esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3362
+					'content'  => $a_or_i === 'active'
3363
+						? $this->_message_type_settings_content($message_type, $messenger, true)
3364
+						: $this->_message_type_settings_content($message_type, $messenger),
3365
+					'slug'     => $message_type->name,
3366
+					'active'   => $a_or_i === 'active',
3367
+					'obj'      => $message_type,
3368
+				];
3369
+			}
3370
+		}
3371
+	}
3372
+
3373
+
3374
+	/**
3375
+	 * This just prepares the content for the message type settings
3376
+	 *
3377
+	 * @param EE_message_type $message_type The message type object
3378
+	 * @param EE_messenger    $messenger    The messenger object
3379
+	 * @param boolean         $active       Whether the message type is active or not
3380
+	 * @return string html output for the content
3381
+	 * @throws DomainException
3382
+	 */
3383
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
3384
+	{
3385
+		// get message type fields
3386
+		$fields                                         = $message_type->get_admin_settings_fields();
3387
+		$settings_template_args['template_form_fields'] = '';
3388
+
3389
+		if (! empty($fields) && $active) {
3390
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3391
+			foreach ($fields as $fldname => $fldprops) {
3392
+				$field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3393
+				$template_form_field[ $field_id ] = [
3394
+					'name'       => 'message_type_settings[' . $fldname . ']',
3395
+					'label'      => $fldprops['label'],
3396
+					'input'      => $fldprops['field_type'],
3397
+					'type'       => $fldprops['value_type'],
3398
+					'required'   => $fldprops['required'],
3399
+					'validation' => $fldprops['validation'],
3400
+					'value'      => isset($existing_settings[ $fldname ])
3401
+						? $existing_settings[ $fldname ]
3402
+						: $fldprops['default'],
3403
+					'options'    => isset($fldprops['options'])
3404
+						? $fldprops['options']
3405
+						: [],
3406
+					'default'    => isset($existing_settings[ $fldname ])
3407
+						? $existing_settings[ $fldname ]
3408
+						: $fldprops['default'],
3409
+					'css_class'  => 'no-drag',
3410
+					'format'     => $fldprops['format'],
3411
+				];
3412
+			}
3413
+
3414
+
3415
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3416
+				? $this->_generate_admin_form_fields(
3417
+					$template_form_field,
3418
+					'string',
3419
+					'ee_mt_activate_form'
3420
+				)
3421
+				: '';
3422
+		}
3423
+
3424
+		$settings_template_args['description'] = $message_type->description;
3425
+		// we also need some hidden fields
3426
+		$hidden_fields = [
3427
+			'message_type_settings[messenger]' . $message_type->name   => [
3428
+				'type'  => 'hidden',
3429
+				'value' => $messenger->name,
3430
+			],
3431
+			'message_type_settings[message_type]' . $message_type->name => [
3432
+				'type'  => 'hidden',
3433
+				'value' => $message_type->name,
3434
+			],
3435
+			'type'   . $message_type->name                             => [
3436
+				'type'  => 'hidden',
3437
+				'value' => 'message_type',
3438
+			],
3439
+		];
3440
+
3441
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3442
+			$hidden_fields,
3443
+			'array'
3444
+		);
3445
+		$settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3446
+			? ' hidden'
3447
+			: '';
3448
+
3449
+
3450
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3451
+		$content  = EEH_Template::display_template($template, $settings_template_args, true);
3452
+
3453
+		return $content;
3454
+	}
3455
+
3456
+
3457
+	/**
3458
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
3459
+	 *
3460
+	 * @access protected
3461
+	 * @return void
3462
+	 * @throws DomainException
3463
+	 */
3464
+	protected function _messages_settings_metaboxes()
3465
+	{
3466
+		$this->_set_m_mt_settings();
3467
+		$m_boxes         = $mt_boxes = [];
3468
+		$m_template_args = $mt_template_args = [];
3469
+
3470
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3471
+			? $this->_req_data['selected_messenger']
3472
+			: 'email';
3473
+
3474
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
3475
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3476
+				$hide_on_message  = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3477
+				$hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3478
+				// messenger meta boxes
3479
+				$active                                   = $selected_messenger === $messenger;
3480
+				$active_mt_tabs                           = isset(
3481
+					$this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3482
+				)
3483
+					? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3484
+					: '';
3485
+				$m_boxes[ $messenger . '_a_box' ]         = sprintf(
3486
+					esc_html__('%s Settings', 'event_espresso'),
3487
+					$tab_array['label']
3488
+				);
3489
+				$m_template_args[ $messenger . '_a_box' ] = [
3490
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3491
+					'inactive_message_types' => isset(
3492
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3493
+					)
3494
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3495
+						: '',
3496
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3497
+					'hidden'                 => $active ? '' : ' hidden',
3498
+					'hide_on_message'        => $hide_on_message,
3499
+					'messenger'              => $messenger,
3500
+					'active'                 => $active,
3501
+				];
3502
+				// message type meta boxes
3503
+				// (which is really just the inactive container for each messenger
3504
+				// showing inactive message types for that messenger)
3505
+				$mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3506
+				$mt_template_args[ $messenger . '_i_box' ] = [
3507
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3508
+					'inactive_message_types' => isset(
3509
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3510
+					)
3511
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3512
+						: '',
3513
+					'hidden'                 => $active ? '' : ' hidden',
3514
+					'hide_on_message'        => $hide_on_message,
3515
+					'hide_off_message'       => $hide_off_message,
3516
+					'messenger'              => $messenger,
3517
+					'active'                 => $active,
3518
+				];
3519
+			}
3520
+		}
3521
+
3522
+
3523
+		// register messenger metaboxes
3524
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3525
+		foreach ($m_boxes as $box => $label) {
3526
+			$callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3527
+			$msgr          = str_replace('_a_box', '', $box);
3528
+			$this->addMetaBox(
3529
+				'espresso_' . $msgr . '_settings',
3530
+				$label,
3531
+				function ($post, $metabox) {
3532
+					EEH_Template::display_template(
3533
+						$metabox['args']['template_path'],
3534
+						$metabox['args']['template_args']
3535
+					);
3536
+				},
3537
+				$this->_current_screen->id,
3538
+				'normal',
3539
+				'high',
3540
+				$callback_args
3541
+			);
3542
+		}
3543
+
3544
+		// register message type metaboxes
3545
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3546
+		foreach ($mt_boxes as $box => $label) {
3547
+			$callback_args = [
3548
+				'template_path' => $mt_template_path,
3549
+				'template_args' => $mt_template_args[ $box ],
3550
+			];
3551
+			$mt            = str_replace('_i_box', '', $box);
3552
+			$this->addMetaBox(
3553
+				'espresso_' . $mt . '_inactive_mts',
3554
+				$label,
3555
+				function ($post, $metabox) {
3556
+					EEH_Template::display_template(
3557
+						$metabox['args']['template_path'],
3558
+						$metabox['args']['template_args']
3559
+					);
3560
+				},
3561
+				$this->_current_screen->id,
3562
+				'side',
3563
+				'high',
3564
+				$callback_args
3565
+			);
3566
+		}
3567
+
3568
+		// register metabox for global messages settings but only when on the main site.  On single site installs this
3569
+		// will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3570
+		if (is_main_site()) {
3571
+			$this->addMetaBox(
3572
+				'espresso_global_message_settings',
3573
+				esc_html__('Global Message Settings', 'event_espresso'),
3574
+				[$this, 'global_messages_settings_metabox_content'],
3575
+				$this->_current_screen->id,
3576
+				'normal',
3577
+				'low',
3578
+				[]
3579
+			);
3580
+		}
3581
+	}
3582
+
3583
+
3584
+	/**
3585
+	 *  This generates the content for the global messages settings metabox.
3586
+	 *
3587
+	 * @return void
3588
+	 * @throws EE_Error
3589
+	 * @throws InvalidArgumentException
3590
+	 * @throws ReflectionException
3591
+	 * @throws InvalidDataTypeException
3592
+	 * @throws InvalidInterfaceException
3593
+	 */
3594
+	public function global_messages_settings_metabox_content()
3595
+	{
3596
+		$form = $this->_generate_global_settings_form();
3597
+		// already escaped
3598
+		echo $form->form_open(
3599
+			$this->add_query_args_and_nonce(['action' => 'update_global_settings'], EE_MSG_ADMIN_URL),
3600
+			'POST'
3601
+		);
3602
+		echo $form->get_html();
3603
+		echo $form->form_close();
3604
+	}
3605
+
3606
+
3607
+	/**
3608
+	 * This generates and returns the form object for the global messages settings.
3609
+	 *
3610
+	 * @return EE_Form_Section_Proper
3611
+	 * @throws EE_Error
3612
+	 * @throws InvalidArgumentException
3613
+	 * @throws ReflectionException
3614
+	 * @throws InvalidDataTypeException
3615
+	 * @throws InvalidInterfaceException
3616
+	 */
3617
+	protected function _generate_global_settings_form()
3618
+	{
3619
+		EE_Registry::instance()->load_helper('HTML');
3620
+		/** @var EE_Network_Core_Config $network_config */
3621
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3622
+
3623
+		return new EE_Form_Section_Proper(
3624
+			[
3625
+				'name'            => 'global_messages_settings',
3626
+				'html_id'         => 'global_messages_settings',
3627
+				'html_class'      => 'form-table',
3628
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3629
+				'subsections'     => apply_filters(
3630
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3631
+					[
3632
+						'do_messages_on_same_request' => new EE_Select_Input(
3633
+							[
3634
+								true  => esc_html__('On the same request', 'event_espresso'),
3635
+								false => esc_html__('On a separate request', 'event_espresso'),
3636
+							],
3637
+							[
3638
+								'default'         => $network_config->do_messages_on_same_request,
3639
+								'html_label_text' => esc_html__(
3640
+									'Generate and send all messages:',
3641
+									'event_espresso'
3642
+								),
3643
+								'html_help_text'  => esc_html__(
3644
+									'By default the messages system uses a more efficient means of processing messages on separate requests and utilizes the wp-cron scheduling system.  This makes things execute faster for people registering for your events.  However, if the wp-cron system is disabled on your site and there is no alternative in place, then you can change this so messages are always executed on the same request.',
3645
+									'event_espresso'
3646
+								),
3647
+							]
3648
+						),
3649
+						'delete_threshold'            => new EE_Select_Input(
3650
+							[
3651
+								0  => esc_html__('Forever', 'event_espresso'),
3652
+								3  => esc_html__('3 Months', 'event_espresso'),
3653
+								6  => esc_html__('6 Months', 'event_espresso'),
3654
+								9  => esc_html__('9 Months', 'event_espresso'),
3655
+								12 => esc_html__('12 Months', 'event_espresso'),
3656
+								24 => esc_html__('24 Months', 'event_espresso'),
3657
+								36 => esc_html__('36 Months', 'event_espresso'),
3658
+							],
3659
+							[
3660
+								'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3661
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3662
+								'html_help_text'  => esc_html__(
3663
+									'You can control how long a record of processed messages is kept via this option.',
3664
+									'event_espresso'
3665
+								),
3666
+							]
3667
+						),
3668
+						'update_settings'             => new EE_Submit_Input(
3669
+							[
3670
+								'default'         => esc_html__('Update', 'event_espresso'),
3671
+								'html_label_text' => '&nbsp',
3672
+							]
3673
+						),
3674
+					]
3675
+				),
3676
+			]
3677
+		);
3678
+	}
3679
+
3680
+
3681
+	/**
3682
+	 * This handles updating the global settings set on the admin page.
3683
+	 *
3684
+	 * @throws EE_Error
3685
+	 * @throws InvalidDataTypeException
3686
+	 * @throws InvalidInterfaceException
3687
+	 * @throws InvalidArgumentException
3688
+	 * @throws ReflectionException
3689
+	 */
3690
+	protected function _update_global_settings()
3691
+	{
3692
+		/** @var EE_Network_Core_Config $network_config */
3693
+		$network_config  = EE_Registry::instance()->NET_CFG->core;
3694
+		$messages_config = EE_Registry::instance()->CFG->messages;
3695
+		$form            = $this->_generate_global_settings_form();
3696
+		if ($form->was_submitted()) {
3697
+			$form->receive_form_submission();
3698
+			if ($form->is_valid()) {
3699
+				$valid_data = $form->valid_data();
3700
+				foreach ($valid_data as $property => $value) {
3701
+					$setter = 'set_' . $property;
3702
+					if (method_exists($network_config, $setter)) {
3703
+						$network_config->{$setter}($value);
3704
+					} elseif (
3705
+						property_exists($network_config, $property)
3706
+						&& $network_config->{$property} !== $value
3707
+					) {
3708
+						$network_config->{$property} = $value;
3709
+					} elseif (
3710
+						property_exists($messages_config, $property)
3711
+						&& $messages_config->{$property} !== $value
3712
+					) {
3713
+						$messages_config->{$property} = $value;
3714
+					}
3715
+				}
3716
+				// only update if the form submission was valid!
3717
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3718
+				EE_Registry::instance()->CFG->update_espresso_config();
3719
+				EE_Error::overwrite_success();
3720
+				EE_Error::add_success(esc_html__('Global message settings were updated', 'event_espresso'));
3721
+			}
3722
+		}
3723
+		$this->_redirect_after_action(0, '', '', ['action' => 'settings'], true);
3724
+	}
3725
+
3726
+
3727
+	/**
3728
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3729
+	 *
3730
+	 * @param array $tab_array This is an array of message type tab details used to generate the tabs
3731
+	 * @return string html formatted tabs
3732
+	 * @throws DomainException
3733
+	 */
3734
+	protected function _get_mt_tabs($tab_array)
3735
+	{
3736
+		$tab_array = (array) $tab_array;
3737
+		$template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3738
+		$tabs      = '';
3739
+
3740
+		foreach ($tab_array as $tab) {
3741
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3742
+		}
3743
+
3744
+		return $tabs;
3745
+	}
3746
+
3747
+
3748
+	/**
3749
+	 * This prepares the content of the messenger meta box admin settings
3750
+	 *
3751
+	 * @param EE_messenger $messenger The messenger we're setting up content for
3752
+	 * @return string html formatted content
3753
+	 * @throws DomainException
3754
+	 */
3755
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3756
+	{
3757
+
3758
+		$fields                                         = $messenger->get_admin_settings_fields();
3759
+		$settings_template_args['template_form_fields'] = '';
3760
+
3761
+		// is $messenger active?
3762
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3763
+
3764
+
3765
+		if (! empty($fields)) {
3766
+			$existing_settings = $messenger->get_existing_admin_settings();
3767
+
3768
+			foreach ($fields as $fldname => $fldprops) {
3769
+				$field_id                         = $messenger->name . '-' . $fldname;
3770
+				$template_form_field[ $field_id ] = [
3771
+					'name'       => 'messenger_settings[' . $field_id . ']',
3772
+					'label'      => $fldprops['label'],
3773
+					'input'      => $fldprops['field_type'],
3774
+					'type'       => $fldprops['value_type'],
3775
+					'required'   => $fldprops['required'],
3776
+					'validation' => $fldprops['validation'],
3777
+					'value'      => isset($existing_settings[ $field_id ])
3778
+						? $existing_settings[ $field_id ]
3779
+						: $fldprops['default'],
3780
+					'css_class'  => '',
3781
+					'format'     => $fldprops['format'],
3782
+				];
3783
+			}
3784
+
3785
+
3786
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3787
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3788
+				: '';
3789
+		}
3790
+
3791
+		// we also need some hidden fields
3792
+		$settings_template_args['hidden_fields'] = [
3793
+			'messenger_settings[messenger]' . $messenger->name => [
3794
+				'type'  => 'hidden',
3795
+				'value' => $messenger->name,
3796
+			],
3797
+			'type' . $messenger->name                          => [
3798
+				'type'  => 'hidden',
3799
+				'value' => 'messenger',
3800
+			],
3801
+		];
3802
+
3803
+		// make sure any active message types that are existing are included in the hidden fields
3804
+		if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3805
+			foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3806
+				$settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3807
+					'type'  => 'hidden',
3808
+					'value' => $mt,
3809
+				];
3810
+			}
3811
+		}
3812
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3813
+			$settings_template_args['hidden_fields'],
3814
+			'array'
3815
+		);
3816
+		$active                                  =
3817
+			$this->_message_resource_manager->is_messenger_active($messenger->name);
3818
+
3819
+		$settings_template_args['messenger']           = $messenger->name;
3820
+		$settings_template_args['description']         = $messenger->description;
3821
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3822
+
3823
+
3824
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3825
+			$messenger->name
3826
+		)
3827
+			? $settings_template_args['show_hide_edit_form']
3828
+			: ' hidden';
3829
+
3830
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3831
+			? ' hidden'
3832
+			: $settings_template_args['show_hide_edit_form'];
3833
+
3834
+
3835
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3836
+		$settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3837
+		$settings_template_args['on_off_status'] = $active;
3838
+		$template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3839
+		return EEH_Template::display_template(
3840
+			$template,
3841
+			$settings_template_args,
3842
+			true
3843
+		);
3844
+	}
3845
+
3846
+
3847
+	/**
3848
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3849
+	 *
3850
+	 * @throws DomainException
3851
+	 * @throws EE_Error
3852
+	 * @throws InvalidDataTypeException
3853
+	 * @throws InvalidInterfaceException
3854
+	 * @throws InvalidArgumentException
3855
+	 * @throws ReflectionException
3856
+	 */
3857
+	public function activate_messenger_toggle()
3858
+	{
3859
+		$success = true;
3860
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3861
+		// let's check that we have required data
3862
+		if (! isset($this->_req_data['messenger'])) {
3863
+			EE_Error::add_error(
3864
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3865
+				__FILE__,
3866
+				__FUNCTION__,
3867
+				__LINE__
3868
+			);
3869
+			$success = false;
3870
+		}
3871
+
3872
+		// do a nonce check here since we're not arriving via a normal route
3873
+		$nonce     = isset($this->_req_data['activate_nonce'])
3874
+			? sanitize_text_field($this->_req_data['activate_nonce'])
3875
+			: '';
3876
+		$nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3877
+
3878
+		$this->_verify_nonce($nonce, $nonce_ref);
3879
+
3880
+
3881
+		if (! isset($this->_req_data['status'])) {
3882
+			EE_Error::add_error(
3883
+				esc_html__(
3884
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3885
+					'event_espresso'
3886
+				),
3887
+				__FILE__,
3888
+				__FUNCTION__,
3889
+				__LINE__
3890
+			);
3891
+			$success = false;
3892
+		}
3893
+
3894
+		// do check to verify we have a valid status.
3895
+		$status = $this->_req_data['status'];
3896
+
3897
+		if ($status !== 'off' && $status !== 'on') {
3898
+			EE_Error::add_error(
3899
+				sprintf(
3900
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3901
+					$this->_req_data['status']
3902
+				),
3903
+				__FILE__,
3904
+				__FUNCTION__,
3905
+				__LINE__
3906
+			);
3907
+			$success = false;
3908
+		}
3909
+
3910
+		if ($success) {
3911
+			// made it here?  Stop dawdling then!!
3912
+			$success = $status === 'off'
3913
+				? $this->_deactivate_messenger($this->_req_data['messenger'])
3914
+				: $this->_activate_messenger($this->_req_data['messenger']);
3915
+		}
3916
+
3917
+		$this->_template_args['success'] = $success;
3918
+
3919
+		// no special instructions so let's just do the json return (which should automatically do all the special stuff).
3920
+		$this->_return_json();
3921
+	}
3922
+
3923
+
3924
+	/**
3925
+	 * used by ajax from the messages settings page to activate|deactivate a message type
3926
+	 *
3927
+	 * @throws DomainException
3928
+	 * @throws EE_Error
3929
+	 * @throws ReflectionException
3930
+	 * @throws InvalidDataTypeException
3931
+	 * @throws InvalidInterfaceException
3932
+	 * @throws InvalidArgumentException
3933
+	 */
3934
+	public function activate_mt_toggle()
3935
+	{
3936
+		$success = true;
3937
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3938
+
3939
+		// let's make sure we have the necessary data
3940
+		if (! isset($this->_req_data['message_type'])) {
3941
+			EE_Error::add_error(
3942
+				esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3943
+				__FILE__,
3944
+				__FUNCTION__,
3945
+				__LINE__
3946
+			);
3947
+			$success = false;
3948
+		}
3949
+
3950
+		if (! isset($this->_req_data['messenger'])) {
3951
+			EE_Error::add_error(
3952
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3953
+				__FILE__,
3954
+				__FUNCTION__,
3955
+				__LINE__
3956
+			);
3957
+			$success = false;
3958
+		}
3959
+
3960
+		if (! isset($this->_req_data['status'])) {
3961
+			EE_Error::add_error(
3962
+				esc_html__(
3963
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3964
+					'event_espresso'
3965
+				),
3966
+				__FILE__,
3967
+				__FUNCTION__,
3968
+				__LINE__
3969
+			);
3970
+			$success = false;
3971
+		}
3972
+
3973
+
3974
+		// do check to verify we have a valid status.
3975
+		$status = $this->_req_data['status'];
3976
+
3977
+		if ($status !== 'activate' && $status !== 'deactivate') {
3978
+			EE_Error::add_error(
3979
+				sprintf(
3980
+					esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3981
+					$this->_req_data['status']
3982
+				),
3983
+				__FILE__,
3984
+				__FUNCTION__,
3985
+				__LINE__
3986
+			);
3987
+			$success = false;
3988
+		}
3989
+
3990
+
3991
+		// do a nonce check here since we're not arriving via a normal route
3992
+		$nonce     = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3993
+		$nonce_ref = $this->_req_data['message_type'] . '_nonce';
3994
+
3995
+		$this->_verify_nonce($nonce, $nonce_ref);
3996
+
3997
+		if ($success) {
3998
+			// made it here? um, what are you waiting for then?
3999
+			$success = $status === 'deactivate'
4000
+				? $this->_deactivate_message_type_for_messenger(
4001
+					$this->_req_data['messenger'],
4002
+					$this->_req_data['message_type']
4003
+				)
4004
+				: $this->_activate_message_type_for_messenger(
4005
+					$this->_req_data['messenger'],
4006
+					$this->_req_data['message_type']
4007
+				);
4008
+		}
4009
+
4010
+		$this->_template_args['success'] = $success;
4011
+		$this->_return_json();
4012
+	}
4013
+
4014
+
4015
+	/**
4016
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
4017
+	 *
4018
+	 * @param string $messenger_name The name of the messenger being activated
4019
+	 * @return bool
4020
+	 * @throws DomainException
4021
+	 * @throws EE_Error
4022
+	 * @throws InvalidArgumentException
4023
+	 * @throws ReflectionException
4024
+	 * @throws InvalidDataTypeException
4025
+	 * @throws InvalidInterfaceException
4026
+	 */
4027
+	protected function _activate_messenger($messenger_name)
4028
+	{
4029
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4030
+		$active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
4031
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger
4032
+			? $active_messenger->get_default_message_types()
4033
+			: [];
4034
+
4035
+		// ensure is active
4036
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4037
+
4038
+		// set response_data for reload
4039
+		foreach ($message_types_to_activate as $message_type_name) {
4040
+			/** @var EE_message_type $message_type */
4041
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4042
+			if (
4043
+				$this->_message_resource_manager->is_message_type_active_for_messenger(
4044
+					$messenger_name,
4045
+					$message_type_name
4046
+				)
4047
+				&& $message_type instanceof EE_message_type
4048
+			) {
4049
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
4050
+				if ($message_type->get_admin_settings_fields()) {
4051
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
4052
+				}
4053
+			}
4054
+		}
4055
+
4056
+		// add success message for activating messenger
4057
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4058
+	}
4059
+
4060
+
4061
+	/**
4062
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
4063
+	 *
4064
+	 * @param string $messenger_name The name of the messenger being activated
4065
+	 * @return bool
4066
+	 * @throws DomainException
4067
+	 * @throws EE_Error
4068
+	 * @throws InvalidArgumentException
4069
+	 * @throws ReflectionException
4070
+	 * @throws InvalidDataTypeException
4071
+	 * @throws InvalidInterfaceException
4072
+	 */
4073
+	protected function _deactivate_messenger($messenger_name)
4074
+	{
4075
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4076
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4077
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
4078
+
4079
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4080
+	}
4081
+
4082
+
4083
+	/**
4084
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4085
+	 *
4086
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
4087
+	 * @param string $message_type_name The name of the message type being activated for the messenger
4088
+	 * @return bool
4089
+	 * @throws DomainException
4090
+	 * @throws EE_Error
4091
+	 * @throws InvalidArgumentException
4092
+	 * @throws ReflectionException
4093
+	 * @throws InvalidDataTypeException
4094
+	 * @throws InvalidInterfaceException
4095
+	 */
4096
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4097
+	{
4098
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4099
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4100
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4101
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4102
+
4103
+		// ensure is active
4104
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4105
+
4106
+		// set response for load
4107
+		if (
4108
+			$this->_message_resource_manager->is_message_type_active_for_messenger(
4109
+				$messenger_name,
4110
+				$message_type_name
4111
+			)
4112
+		) {
4113
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
4114
+			if ($message_type_to_activate->get_admin_settings_fields()) {
4115
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
4116
+			}
4117
+		}
4118
+
4119
+		return $this->_setup_response_message_for_activating_messenger_with_message_types(
4120
+			$active_messenger,
4121
+			$message_type_to_activate
4122
+		);
4123
+	}
4124
+
4125
+
4126
+	/**
4127
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4128
+	 *
4129
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4130
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
4131
+	 * @return bool
4132
+	 * @throws DomainException
4133
+	 * @throws EE_Error
4134
+	 * @throws InvalidArgumentException
4135
+	 * @throws ReflectionException
4136
+	 * @throws InvalidDataTypeException
4137
+	 * @throws InvalidInterfaceException
4138
+	 */
4139
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4140
+	{
4141
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4142
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4143
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4144
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4145
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4146
+
4147
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4148
+			$active_messenger,
4149
+			$message_type_to_deactivate
4150
+		);
4151
+	}
4152
+
4153
+
4154
+	/**
4155
+	 * This just initializes the defaults for activating messenger and message type responses.
4156
+	 */
4157
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
4158
+	{
4159
+		$this->_template_args['data']['active_mts'] = [];
4160
+		$this->_template_args['data']['mt_reload']  = [];
4161
+	}
4162
+
4163
+
4164
+	/**
4165
+	 * Setup appropriate response for activating a messenger and/or message types
4166
+	 *
4167
+	 * @param EE_messenger         $messenger
4168
+	 * @param EE_message_type|null $message_type
4169
+	 * @return bool
4170
+	 * @throws DomainException
4171
+	 * @throws EE_Error
4172
+	 * @throws InvalidArgumentException
4173
+	 * @throws ReflectionException
4174
+	 * @throws InvalidDataTypeException
4175
+	 * @throws InvalidInterfaceException
4176
+	 */
4177
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
4178
+		$messenger,
4179
+		EE_Message_Type $message_type = null
4180
+	) {
4181
+		// if $messenger isn't a valid messenger object then get out.
4182
+		if (! $messenger instanceof EE_Messenger) {
4183
+			EE_Error::add_error(
4184
+				esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4185
+				__FILE__,
4186
+				__FUNCTION__,
4187
+				__LINE__
4188
+			);
4189
+
4190
+			return false;
4191
+		}
4192
+		// activated
4193
+		if ($this->_template_args['data']['active_mts']) {
4194
+			EE_Error::overwrite_success();
4195
+			// activated a message type with the messenger
4196
+			if ($message_type instanceof EE_message_type) {
4197
+				EE_Error::add_success(
4198
+					sprintf(
4199
+						esc_html__(
4200
+							'%s message type has been successfully activated with the %s messenger',
4201
+							'event_espresso'
4202
+						),
4203
+						ucwords($message_type->label['singular']),
4204
+						ucwords($messenger->label['singular'])
4205
+					)
4206
+				);
4207
+
4208
+				// if message type was invoice then let's make sure we activate the invoice payment method.
4209
+				if ($message_type->name === 'invoice') {
4210
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
4211
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4212
+					if ($pm instanceof EE_Payment_Method) {
4213
+						EE_Error::add_attention(
4214
+							esc_html__(
4215
+								'Activating the invoice message type also automatically activates the invoice payment method.  If you do not wish the invoice payment method to be active, or to change its settings, visit the payment method admin page.',
4216
+								'event_espresso'
4217
+							)
4218
+						);
4219
+					}
4220
+				}
4221
+				// just toggles the entire messenger
4222
+			} else {
4223
+				EE_Error::add_success(
4224
+					sprintf(
4225
+						esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4226
+						ucwords($messenger->label['singular'])
4227
+					)
4228
+				);
4229
+			}
4230
+
4231
+			return true;
4232
+
4233
+			// possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4234
+			// message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4235
+			// in which case we just give a success message for the messenger being successfully activated.
4236
+		} else {
4237
+			if (! $messenger->get_default_message_types()) {
4238
+				// messenger doesn't have any default message types so still a success.
4239
+				EE_Error::add_success(
4240
+					sprintf(
4241
+						esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4242
+						ucwords($messenger->label['singular'])
4243
+					)
4244
+				);
4245
+
4246
+				return true;
4247
+			} else {
4248
+				EE_Error::add_error(
4249
+					$message_type instanceof EE_message_type
4250
+						? sprintf(
4251
+							esc_html__(
4252
+								'%s message type was not successfully activated with the %s messenger',
4253
+								'event_espresso'
4254
+							),
4255
+							ucwords($message_type->label['singular']),
4256
+							ucwords($messenger->label['singular'])
4257
+						)
4258
+						: sprintf(
4259
+							esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4260
+							ucwords($messenger->label['singular'])
4261
+						),
4262
+					__FILE__,
4263
+					__FUNCTION__,
4264
+					__LINE__
4265
+				);
4266
+
4267
+				return false;
4268
+			}
4269
+		}
4270
+	}
4271
+
4272
+
4273
+	/**
4274
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
4275
+	 *
4276
+	 * @param EE_messenger         $messenger
4277
+	 * @param EE_message_type|null $message_type
4278
+	 * @return bool
4279
+	 * @throws DomainException
4280
+	 * @throws EE_Error
4281
+	 * @throws InvalidArgumentException
4282
+	 * @throws ReflectionException
4283
+	 * @throws InvalidDataTypeException
4284
+	 * @throws InvalidInterfaceException
4285
+	 */
4286
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4287
+		$messenger,
4288
+		EE_message_type $message_type = null
4289
+	) {
4290
+		EE_Error::overwrite_success();
4291
+
4292
+		// if $messenger isn't a valid messenger object then get out.
4293
+		if (! $messenger instanceof EE_Messenger) {
4294
+			EE_Error::add_error(
4295
+				esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4296
+				__FILE__,
4297
+				__FUNCTION__,
4298
+				__LINE__
4299
+			);
4300
+
4301
+			return false;
4302
+		}
4303
+
4304
+		if ($message_type instanceof EE_message_type) {
4305
+			$message_type_name = $message_type->name;
4306
+			EE_Error::add_success(
4307
+				sprintf(
4308
+					esc_html__(
4309
+						'%s message type has been successfully deactivated for the %s messenger.',
4310
+						'event_espresso'
4311
+					),
4312
+					ucwords($message_type->label['singular']),
4313
+					ucwords($messenger->label['singular'])
4314
+				)
4315
+			);
4316
+		} else {
4317
+			$message_type_name = '';
4318
+			EE_Error::add_success(
4319
+				sprintf(
4320
+					esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4321
+					ucwords($messenger->label['singular'])
4322
+				)
4323
+			);
4324
+		}
4325
+
4326
+		// if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4327
+		if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4328
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
4329
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4330
+			if ($count_updated > 0) {
4331
+				$msg = $message_type_name === 'invoice'
4332
+					? esc_html__(
4333
+						'Deactivating the invoice message type also automatically deactivates the invoice payment method. In order for invoices to be generated the invoice message type must be active. If you completed this action by mistake, simply reactivate the invoice message type and then visit the payment methods admin page to reactivate the invoice payment method.',
4334
+						'event_espresso'
4335
+					)
4336
+					: esc_html__(
4337
+						'Deactivating the html messenger also automatically deactivates the invoice payment method.  In order for invoices to be generated the html messenger must be be active.  If you completed this action by mistake, simply reactivate the html messenger, then visit the payment methods admin page to reactivate the invoice payment method.',
4338
+						'event_espresso'
4339
+					);
4340
+				EE_Error::add_attention($msg);
4341
+			}
4342
+		}
4343
+
4344
+		return true;
4345
+	}
4346
+
4347
+
4348
+	/**
4349
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4350
+	 *
4351
+	 * @throws DomainException
4352
+	 */
4353
+	public function update_mt_form()
4354
+	{
4355
+		if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4356
+			EE_Error::add_error(
4357
+				esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4358
+				__FILE__,
4359
+				__FUNCTION__,
4360
+				__LINE__
4361
+			);
4362
+			$this->_return_json();
4363
+		}
4364
+
4365
+		$message_types = $this->get_installed_message_types();
4366
+
4367
+		$message_type = $message_types[ $this->_req_data['message_type'] ];
4368
+		$messenger    = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4369
+
4370
+		$content                         = $this->_message_type_settings_content(
4371
+			$message_type,
4372
+			$messenger,
4373
+			true
4374
+		);
4375
+		$this->_template_args['success'] = true;
4376
+		$this->_template_args['content'] = $content;
4377
+		$this->_return_json();
4378
+	}
4379
+
4380
+
4381
+	/**
4382
+	 * this handles saving the settings for a messenger or message type
4383
+	 *
4384
+	 */
4385
+	public function save_settings()
4386
+	{
4387
+		if (! isset($this->_req_data['type'])) {
4388
+			EE_Error::add_error(
4389
+				esc_html__(
4390
+					'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4391
+					'event_espresso'
4392
+				),
4393
+				__FILE__,
4394
+				__FUNCTION__,
4395
+				__LINE__
4396
+			);
4397
+			$this->_template_args['error'] = true;
4398
+			$this->_return_json();
4399
+		}
4400
+
4401
+
4402
+		if ($this->_req_data['type'] === 'messenger') {
4403
+			// this should be an array.
4404
+			$settings  = $this->_req_data['messenger_settings'];
4405
+			$messenger = $settings['messenger'];
4406
+			// let's setup the settings data
4407
+			foreach ($settings as $key => $value) {
4408
+				switch ($key) {
4409
+					case 'messenger':
4410
+						unset($settings['messenger']);
4411
+						break;
4412
+					case 'message_types':
4413
+						unset($settings['message_types']);
4414
+						break;
4415
+					default:
4416
+						$settings[ $key ] = $value;
4417
+						break;
4418
+				}
4419
+			}
4420
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4421
+		} elseif ($this->_req_data['type'] === 'message_type') {
4422
+			$settings     = $this->_req_data['message_type_settings'];
4423
+			$messenger    = $settings['messenger'];
4424
+			$message_type = $settings['message_type'];
4425
+
4426
+			foreach ($settings as $key => $value) {
4427
+				switch ($key) {
4428
+					case 'messenger':
4429
+						unset($settings['messenger']);
4430
+						break;
4431
+					case 'message_type':
4432
+						unset($settings['message_type']);
4433
+						break;
4434
+					default:
4435
+						$settings[ $key ] = $value;
4436
+						break;
4437
+				}
4438
+			}
4439
+
4440
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4441
+		}
4442
+
4443
+		// okay we should have the data all setup.  Now we just update!
4444
+		$success = $this->_message_resource_manager->update_active_messengers_option();
4445
+
4446
+		if ($success) {
4447
+			EE_Error::add_success(esc_html__('Settings updated', 'event_espresso'));
4448
+		} else {
4449
+			EE_Error::add_error(
4450
+				esc_html__(
4451
+					'Settings did not get updated',
4452
+					'event_espresso'
4453
+				),
4454
+				__FILE__,
4455
+				__FUNCTION__,
4456
+				__LINE__
4457
+			);
4458
+		}
4459
+
4460
+		$this->_template_args['success'] = $success;
4461
+		$this->_return_json();
4462
+	}
4463
+
4464
+
4465
+
4466
+
4467
+	/**  EE MESSAGE PROCESSING ACTIONS **/
4468
+
4469
+
4470
+	/**
4471
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4472
+	 * However, this does not send immediately, it just queues for sending.
4473
+	 *
4474
+	 * @throws EE_Error
4475
+	 * @throws InvalidDataTypeException
4476
+	 * @throws InvalidInterfaceException
4477
+	 * @throws InvalidArgumentException
4478
+	 * @throws ReflectionException
4479
+	 * @since 4.9.0
4480
+	 */
4481
+	protected function _generate_now()
4482
+	{
4483
+		EED_Messages::generate_now($this->_get_msg_ids_from_request());
4484
+		$this->_redirect_after_action(false, '', '', [], true);
4485
+	}
4486
+
4487
+
4488
+	/**
4489
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4490
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
4491
+	 *
4492
+	 * @throws EE_Error
4493
+	 * @throws InvalidDataTypeException
4494
+	 * @throws InvalidInterfaceException
4495
+	 * @throws InvalidArgumentException
4496
+	 * @throws ReflectionException
4497
+	 * @since 4.9.0
4498
+	 */
4499
+	protected function _generate_and_send_now()
4500
+	{
4501
+		EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4502
+		$this->_redirect_after_action(false, '', '', [], true);
4503
+	}
4504
+
4505
+
4506
+	/**
4507
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4508
+	 *
4509
+	 * @throws EE_Error
4510
+	 * @throws InvalidDataTypeException
4511
+	 * @throws InvalidInterfaceException
4512
+	 * @throws InvalidArgumentException
4513
+	 * @throws ReflectionException
4514
+	 * @since 4.9.0
4515
+	 */
4516
+	protected function _queue_for_resending()
4517
+	{
4518
+		EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4519
+		$this->_redirect_after_action(false, '', '', [], true);
4520
+	}
4521
+
4522
+
4523
+	/**
4524
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4525
+	 *
4526
+	 * @throws EE_Error
4527
+	 * @throws InvalidDataTypeException
4528
+	 * @throws InvalidInterfaceException
4529
+	 * @throws InvalidArgumentException
4530
+	 * @throws ReflectionException
4531
+	 * @since 4.9.0
4532
+	 */
4533
+	protected function _send_now()
4534
+	{
4535
+		EED_Messages::send_now($this->_get_msg_ids_from_request());
4536
+		$this->_redirect_after_action(false, '', '', [], true);
4537
+	}
4538
+
4539
+
4540
+	/**
4541
+	 * Deletes EE_messages for IDs in the request.
4542
+	 *
4543
+	 * @throws EE_Error
4544
+	 * @throws InvalidDataTypeException
4545
+	 * @throws InvalidInterfaceException
4546
+	 * @throws InvalidArgumentException
4547
+	 * @since 4.9.0
4548
+	 */
4549
+	protected function _delete_ee_messages()
4550
+	{
4551
+		$msg_ids       = $this->_get_msg_ids_from_request();
4552
+		$deleted_count = 0;
4553
+		foreach ($msg_ids as $msg_id) {
4554
+			if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4555
+				$deleted_count++;
4556
+			}
4557
+		}
4558
+		if ($deleted_count) {
4559
+			EE_Error::add_success(
4560
+				esc_html(
4561
+					_n(
4562
+						'Message successfully deleted',
4563
+						'Messages successfully deleted',
4564
+						$deleted_count,
4565
+						'event_espresso'
4566
+					)
4567
+				)
4568
+			);
4569
+			$this->_redirect_after_action(
4570
+				false,
4571
+				'',
4572
+				'',
4573
+				[],
4574
+				true
4575
+			);
4576
+		} else {
4577
+			EE_Error::add_error(
4578
+				_n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4579
+				__FILE__,
4580
+				__FUNCTION__,
4581
+				__LINE__
4582
+			);
4583
+			$this->_redirect_after_action(false, '', '', [], true);
4584
+		}
4585
+	}
4586
+
4587
+
4588
+	/**
4589
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4590
+	 *
4591
+	 * @return array
4592
+	 * @since 4.9.0
4593
+	 */
4594
+	protected function _get_msg_ids_from_request()
4595
+	{
4596
+		if (! isset($this->_req_data['MSG_ID'])) {
4597
+			return [];
4598
+		}
4599
+
4600
+		return is_array($this->_req_data['MSG_ID'])
4601
+			? array_keys($this->_req_data['MSG_ID'])
4602
+			: [$this->_req_data['MSG_ID']];
4603
+	}
4604 4604
 }
Please login to merge, or discard this patch.
Spacing   +240 added lines, -240 removed lines patch added patch discarded remove patch
@@ -149,8 +149,8 @@  discard block
 block discarded – undo
149 149
         $i = 1;
150 150
         foreach ($active_messengers as $active_messenger) {
151 151
             if ($active_messenger instanceof EE_Message) {
152
-                $m_values[ $i ]['id']   = $active_messenger->messenger();
153
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
152
+                $m_values[$i]['id']   = $active_messenger->messenger();
153
+                $m_values[$i]['text'] = ucwords($active_messenger->messenger_label());
154 154
                 $i++;
155 155
             }
156 156
         }
@@ -186,8 +186,8 @@  discard block
 block discarded – undo
186 186
         $i               = 1;
187 187
         foreach ($active_messages as $active_message) {
188 188
             if ($active_message instanceof EE_Message) {
189
-                $mt_values[ $i ]['id']   = $active_message->message_type();
190
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
189
+                $mt_values[$i]['id']   = $active_message->message_type();
190
+                $mt_values[$i]['text'] = ucwords($active_message->message_type_label());
191 191
                 $i++;
192 192
             }
193 193
         }
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
                 if ($message_type instanceof EE_message_type) {
227 227
                     $message_type_contexts = $message_type->get_contexts();
228 228
                     foreach ($message_type_contexts as $context => $context_details) {
229
-                        $contexts[ $context ] = $context_details['label'];
229
+                        $contexts[$context] = $context_details['label'];
230 230
                     }
231 231
                 }
232 232
             }
@@ -259,7 +259,7 @@  discard block
 block discarded – undo
259 259
             ['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
260 260
             $messenger_options
261 261
         );
262
-        $input             = new EE_Select_Input(
262
+        $input = new EE_Select_Input(
263 263
             $messenger_options,
264 264
             [
265 265
                 'html_name'  => 'ee_messenger_filter_by',
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
             ['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
299 299
             $message_type_options
300 300
         );
301
-        $input                = new EE_Select_Input(
301
+        $input = new EE_Select_Input(
302 302
             $message_type_options,
303 303
             [
304 304
                 'html_name'  => 'ee_message_type_filter_by',
@@ -337,7 +337,7 @@  discard block
 block discarded – undo
337 337
             ['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
338 338
             $context_options
339 339
         );
340
-        $input           = new EE_Select_Input(
340
+        $input = new EE_Select_Input(
341 341
             $context_options,
342 342
             [
343 343
                 'html_name'  => 'ee_context_filter_by',
@@ -727,53 +727,53 @@  discard block
 block discarded – undo
727 727
 
728 728
     public function messages_help_tab()
729 729
     {
730
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
730
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_help_tab.template.php');
731 731
     }
732 732
 
733 733
 
734 734
     public function messengers_help_tab()
735 735
     {
736
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
736
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messenger_help_tab.template.php');
737 737
     }
738 738
 
739 739
 
740 740
     public function message_types_help_tab()
741 741
     {
742
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
742
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_type_help_tab.template.php');
743 743
     }
744 744
 
745 745
 
746 746
     public function messages_overview_help_tab()
747 747
     {
748
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
748
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_overview_help_tab.template.php');
749 749
     }
750 750
 
751 751
 
752 752
     public function message_templates_help_tab()
753 753
     {
754
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
754
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_templates_help_tab.template.php');
755 755
     }
756 756
 
757 757
 
758 758
     public function edit_message_template_help_tab()
759 759
     {
760
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
760
+        $args['img1'] = '<img src="'.EE_MSG_ASSETS_URL.'images/editor.png'.'" alt="'
761 761
                         . esc_attr__('Editor Title', 'event_espresso')
762 762
                         . '" />';
763
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
763
+        $args['img2'] = '<img src="'.EE_MSG_ASSETS_URL.'images/switch-context.png'.'" alt="'
764 764
                         . esc_attr__('Context Switcher and Preview', 'event_espresso')
765 765
                         . '" />';
766
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
766
+        $args['img3'] = '<img class="left" src="'.EE_MSG_ASSETS_URL.'images/form-fields.png'.'" alt="'
767 767
                         . esc_attr__('Message Template Form Fields', 'event_espresso')
768 768
                         . '" />';
769
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
769
+        $args['img4'] = '<img class="right" src="'.EE_MSG_ASSETS_URL.'images/shortcodes-metabox.png'.'" alt="'
770 770
                         . esc_attr__('Shortcodes Metabox', 'event_espresso')
771 771
                         . '" />';
772
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
772
+        $args['img5'] = '<img class="right" src="'.EE_MSG_ASSETS_URL.'images/publish-meta-box.png'.'" alt="'
773 773
                         . esc_attr__('Publish Metabox', 'event_espresso')
774 774
                         . '" />';
775 775
         EEH_Template::display_template(
776
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
776
+            EE_MSG_TEMPLATE_PATH.'ee_msg_messages_templates_editor_help_tab.template.php',
777 777
             $args
778 778
         );
779 779
     }
@@ -784,7 +784,7 @@  discard block
 block discarded – undo
784 784
         $this->_set_shortcodes();
785 785
         $args['shortcodes'] = $this->_shortcodes;
786 786
         EEH_Template::display_template(
787
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
787
+            EE_MSG_TEMPLATE_PATH.'ee_msg_messages_shortcodes_help_tab.template.php',
788 788
             $args
789 789
         );
790 790
     }
@@ -792,16 +792,16 @@  discard block
 block discarded – undo
792 792
 
793 793
     public function preview_message_help_tab()
794 794
     {
795
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
795
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_preview_help_tab.template.php');
796 796
     }
797 797
 
798 798
 
799 799
     public function settings_help_tab()
800 800
     {
801
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
802
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
803
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
804
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
801
+        $args['img1'] = '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-active.png'
802
+                        . '" alt="'.esc_attr__('Active Email Tab', 'event_espresso').'" />';
803
+        $args['img2'] = '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-inactive.png'
804
+                        . '" alt="'.esc_attr__('Inactive Email Tab', 'event_espresso').'" />';
805 805
         $args['img3'] = '<div class="switch">'
806 806
                         . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
807 807
                         . ' type="checkbox" checked="checked">'
@@ -812,25 +812,25 @@  discard block
 block discarded – undo
812 812
                         . ' type="checkbox">'
813 813
                         . '<label for="ee-on-off-toggle-on"></label>'
814 814
                         . '</div>';
815
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
815
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_settings_help_tab.template.php', $args);
816 816
     }
817 817
 
818 818
 
819 819
     public function load_scripts_styles()
820 820
     {
821
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
821
+        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL.'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
822 822
         wp_enqueue_style('espresso_ee_msg');
823 823
 
824 824
         wp_register_script(
825 825
             'ee-messages-settings',
826
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
826
+            EE_MSG_ASSETS_URL.'ee-messages-settings.js',
827 827
             ['jquery-ui-droppable', 'ee-serialize-full-array'],
828 828
             EVENT_ESPRESSO_VERSION,
829 829
             true
830 830
         );
831 831
         wp_register_script(
832 832
             'ee-msg-list-table-js',
833
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
833
+            EE_MSG_ASSETS_URL.'ee_message_admin_list_table.js',
834 834
             ['ee-dialog'],
835 835
             EVENT_ESPRESSO_VERSION
836 836
         );
@@ -869,7 +869,7 @@  discard block
 block discarded – undo
869 869
 
870 870
         $this->_set_shortcodes();
871 871
 
872
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
872
+        EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
873 873
             esc_html__(
874 874
                 'Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
875 875
                 'event_espresso'
@@ -881,14 +881,14 @@  discard block
 block discarded – undo
881 881
             'Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
882 882
             'event_espresso'
883 883
         );
884
-        EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
884
+        EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
885 885
             'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
886 886
             'event_espresso'
887 887
         );
888 888
 
889 889
         wp_register_script(
890 890
             'ee_msgs_edit_js',
891
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
891
+            EE_MSG_ASSETS_URL.'ee_message_editor.js',
892 892
             ['jquery'],
893 893
             EVENT_ESPRESSO_VERSION
894 894
         );
@@ -932,7 +932,7 @@  discard block
 block discarded – undo
932 932
     {
933 933
         wp_register_style(
934 934
             'ee-message-settings',
935
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
935
+            EE_MSG_ASSETS_URL.'ee_message_settings.css',
936 936
             [],
937 937
             EVENT_ESPRESSO_VERSION
938 938
         );
@@ -1018,7 +1018,7 @@  discard block
 block discarded – undo
1018 1018
             }
1019 1019
             $status_bulk_actions = $common_bulk_actions;
1020 1020
             // unset bulk actions not applying to status
1021
-            if (! empty($status_bulk_actions)) {
1021
+            if ( ! empty($status_bulk_actions)) {
1022 1022
                 switch ($status) {
1023 1023
                     case EEM_Message::status_idle:
1024 1024
                     case EEM_Message::status_resend:
@@ -1047,7 +1047,7 @@  discard block
 block discarded – undo
1047 1047
                 continue;
1048 1048
             }
1049 1049
 
1050
-            $this->_views[ strtolower($status) ] = [
1050
+            $this->_views[strtolower($status)] = [
1051 1051
                 'slug'        => strtolower($status),
1052 1052
                 'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1053 1053
                 'count'       => 0,
@@ -1086,7 +1086,7 @@  discard block
 block discarded – undo
1086 1086
             if ($action_item === 'see_notifications_for') {
1087 1087
                 continue;
1088 1088
             }
1089
-            $action_items[ $action_item ] = [
1089
+            $action_items[$action_item] = [
1090 1090
                 'class' => $action_details['css_class'],
1091 1091
                 'desc'  => $action_details['label'],
1092 1092
             ];
@@ -1095,37 +1095,37 @@  discard block
 block discarded – undo
1095 1095
         /** @type array $status_items status legend setup */
1096 1096
         $status_items = [
1097 1097
             'sent_status'                => [
1098
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_sent,
1098
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Message::status_sent,
1099 1099
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1100 1100
             ],
1101 1101
             'idle_status'                => [
1102
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_idle,
1102
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Message::status_idle,
1103 1103
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1104 1104
             ],
1105 1105
             'failed_status'              => [
1106
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_failed,
1106
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Message::status_failed,
1107 1107
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1108 1108
             ],
1109 1109
             'messenger_executing_status' => [
1110
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_messenger_executing,
1110
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Message::status_messenger_executing,
1111 1111
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1112 1112
             ],
1113 1113
             'resend_status'              => [
1114
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_resend,
1114
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Message::status_resend,
1115 1115
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1116 1116
             ],
1117 1117
             'incomplete_status'          => [
1118
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_incomplete,
1118
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Message::status_incomplete,
1119 1119
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1120 1120
             ],
1121 1121
             'retry_status'               => [
1122
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_retry,
1122
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Message::status_retry,
1123 1123
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1124 1124
             ],
1125 1125
         ];
1126 1126
         if (EEM_Message::debug()) {
1127 1127
             $status_items['debug_only_status'] = [
1128
-                'class' => 'ee-status-legend ee-status-legend--' . EEM_Message::status_debug_only,
1128
+                'class' => 'ee-status-legend ee-status-legend--'.EEM_Message::status_debug_only,
1129 1129
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1130 1130
             ];
1131 1131
         }
@@ -1137,11 +1137,11 @@  discard block
 block discarded – undo
1137 1137
     protected function _custom_mtps_preview()
1138 1138
     {
1139 1139
         $this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1140
-        $this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1141
-                                                . ' alt="' . esc_attr__(
1140
+        $this->_template_args['preview_img']  = '<img src="'.EE_MSG_ASSETS_URL.'images/custom_mtps_preview.png"'
1141
+                                                . ' alt="'.esc_attr__(
1142 1142
                                                     'Preview Custom Message Templates screenshot',
1143 1143
                                                     'event_espresso'
1144
-                                                ) . '" />';
1144
+                                                ).'" />';
1145 1145
         $this->_template_args['preview_text'] = '<strong>'
1146 1146
                                                 . esc_html__(
1147 1147
                                                     'Custom Message Templates is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
@@ -1221,7 +1221,7 @@  discard block
 block discarded – undo
1221 1221
         $installed               = [];
1222 1222
 
1223 1223
         foreach ($installed_message_types as $message_type) {
1224
-            $installed[ $message_type->name ] = $message_type;
1224
+            $installed[$message_type->name] = $message_type;
1225 1225
         }
1226 1226
 
1227 1227
         return $installed;
@@ -1361,7 +1361,7 @@  discard block
 block discarded – undo
1361 1361
         // we need to assemble the title from Various details
1362 1362
         $context_label = sprintf(
1363 1363
             esc_html__('(%s %s)', 'event_espresso'),
1364
-            $c_config[ $context ]['label'],
1364
+            $c_config[$context]['label'],
1365 1365
             ucwords($c_label['label'])
1366 1366
         );
1367 1367
 
@@ -1383,7 +1383,7 @@  discard block
 block discarded – undo
1383 1383
             $message_template_group->message_type()
1384 1384
         );
1385 1385
 
1386
-        if (! $template_field_structure) {
1386
+        if ( ! $template_field_structure) {
1387 1387
             $template_field_structure = false;
1388 1388
             $template_fields          = esc_html__(
1389 1389
                 'There was an error in assembling the fields for this display (you should see an error message)',
@@ -1397,21 +1397,21 @@  discard block
 block discarded – undo
1397 1397
 
1398 1398
         // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1399 1399
         // will get handled in the "extra" array.
1400
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1401
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1402
-                unset($template_field_structure[ $context ][ $reference_field ]);
1400
+        if (is_array($template_field_structure[$context]) && isset($template_field_structure[$context]['extra'])) {
1401
+            foreach ($template_field_structure[$context]['extra'] as $reference_field => $new_fields) {
1402
+                unset($template_field_structure[$context][$reference_field]);
1403 1403
             }
1404 1404
         }
1405 1405
 
1406 1406
         // let's loop through the template_field_structure and actually assemble the input fields!
1407
-        if (! empty($template_field_structure)) {
1408
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1407
+        if ( ! empty($template_field_structure)) {
1408
+            foreach ($template_field_structure[$context] as $template_field => $field_setup_array) {
1409 1409
                 // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1410 1410
                 // the extra array and reset them.
1411 1411
                 if ($template_field === 'extra') {
1412 1412
                     $this->_template_args['is_extra_fields'] = true;
1413 1413
                     foreach ($field_setup_array as $reference_field => $new_fields_array) {
1414
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1414
+                        $message_template = $message_templates[$context][$reference_field];
1415 1415
                         $content          = $message_template instanceof EE_Message_Template
1416 1416
                             ? $message_template->get('MTP_content')
1417 1417
                             : '';
@@ -1420,7 +1420,7 @@  discard block
 block discarded – undo
1420 1420
                             $continue = false;
1421 1421
                             if (isset($extra_array['shortcodes_required'])) {
1422 1422
                                 foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1423
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1423
+                                    if ( ! array_key_exists($shortcode, $this->_shortcodes)) {
1424 1424
                                         $continue = true;
1425 1425
                                     }
1426 1426
                                 }
@@ -1429,61 +1429,61 @@  discard block
 block discarded – undo
1429 1429
                                 }
1430 1430
                             }
1431 1431
 
1432
-                            $field_id                                  = $reference_field
1432
+                            $field_id = $reference_field
1433 1433
                                                                          . '-'
1434 1434
                                                                          . $extra_field
1435 1435
                                                                          . '-content';
1436
-                            $template_form_fields[ $field_id ]         = $extra_array;
1437
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1436
+                            $template_form_fields[$field_id]         = $extra_array;
1437
+                            $template_form_fields[$field_id]['name'] = 'MTP_template_fields['
1438 1438
                                                                          . $reference_field
1439 1439
                                                                          . '][content]['
1440
-                                                                         . $extra_field . ']';
1441
-                            $css_class                                 = isset($extra_array['css_class'])
1440
+                                                                         . $extra_field.']';
1441
+                            $css_class = isset($extra_array['css_class'])
1442 1442
                                 ? $extra_array['css_class']
1443 1443
                                 : '';
1444 1444
 
1445
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1445
+                            $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1446 1446
                                                                               && in_array($extra_field, $v_fields, true)
1447 1447
                                                                               && (
1448
-                                                                                  is_array($validators[ $extra_field ])
1449
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1448
+                                                                                  is_array($validators[$extra_field])
1449
+                                                                                  && isset($validators[$extra_field]['msg'])
1450 1450
                                                                               )
1451
-                                ? 'validate-error ' . $css_class
1451
+                                ? 'validate-error '.$css_class
1452 1452
                                 : $css_class;
1453 1453
 
1454
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1455
-                                                                          && isset($content[ $extra_field ])
1456
-                                ? $content[ $extra_field ]
1454
+                            $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1455
+                                                                          && isset($content[$extra_field])
1456
+                                ? $content[$extra_field]
1457 1457
                                 : '';
1458 1458
 
1459 1459
                             // do we have a validation error?  if we do then let's use that value instead
1460
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1461
-                                ? $validators[ $extra_field ]['value']
1462
-                                : $template_form_fields[ $field_id ]['value'];
1460
+                            $template_form_fields[$field_id]['value'] = isset($validators[$extra_field])
1461
+                                ? $validators[$extra_field]['value']
1462
+                                : $template_form_fields[$field_id]['value'];
1463 1463
 
1464 1464
 
1465
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1465
+                            $template_form_fields[$field_id]['db-col'] = 'MTP_content';
1466 1466
 
1467 1467
                             // shortcode selector
1468 1468
                             $field_name_to_use                                   = $extra_field === 'main'
1469 1469
                                 ? 'content'
1470 1470
                                 : $extra_field;
1471
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1471
+                            $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1472 1472
                                 $field_name_to_use,
1473 1473
                                 $field_id
1474 1474
                             );
1475 1475
 
1476 1476
                             if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1477 1477
                                 // we want to decode the entities
1478
-                                $template_form_fields[ $field_id ]['value'] =
1479
-                                    $template_form_fields[ $field_id ]['value'];
1478
+                                $template_form_fields[$field_id]['value'] =
1479
+                                    $template_form_fields[$field_id]['value'];
1480 1480
                             }
1481 1481
                         }
1482
-                        $templatefield_MTP_id          = $reference_field . '-MTP_ID';
1483
-                        $templatefield_templatename_id = $reference_field . '-name';
1482
+                        $templatefield_MTP_id          = $reference_field.'-MTP_ID';
1483
+                        $templatefield_templatename_id = $reference_field.'-name';
1484 1484
 
1485
-                        $template_form_fields[ $templatefield_MTP_id ] = [
1486
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1485
+                        $template_form_fields[$templatefield_MTP_id] = [
1486
+                            'name'       => 'MTP_template_fields['.$reference_field.'][MTP_ID]',
1487 1487
                             'label'      => null,
1488 1488
                             'input'      => 'hidden',
1489 1489
                             'type'       => 'int',
@@ -1495,8 +1495,8 @@  discard block
 block discarded – undo
1495 1495
                             'db-col'     => 'MTP_ID',
1496 1496
                         ];
1497 1497
 
1498
-                        $template_form_fields[ $templatefield_templatename_id ] = [
1499
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1498
+                        $template_form_fields[$templatefield_templatename_id] = [
1499
+                            'name'       => 'MTP_template_fields['.$reference_field.'][name]',
1500 1500
                             'label'      => null,
1501 1501
                             'input'      => 'hidden',
1502 1502
                             'type'       => 'string',
@@ -1510,38 +1510,38 @@  discard block
 block discarded – undo
1510 1510
                     }
1511 1511
                     continue; // skip the next stuff, we got the necessary fields here for this dataset.
1512 1512
                 } else {
1513
-                    $field_id                                   = $template_field . '-content';
1514
-                    $template_form_fields[ $field_id ]          = $field_setup_array;
1515
-                    $template_form_fields[ $field_id ]['name']  =
1516
-                        'MTP_template_fields[' . $template_field . '][content]';
1513
+                    $field_id                                   = $template_field.'-content';
1514
+                    $template_form_fields[$field_id]          = $field_setup_array;
1515
+                    $template_form_fields[$field_id]['name']  =
1516
+                        'MTP_template_fields['.$template_field.'][content]';
1517 1517
                     $message_template                           =
1518
-                        isset($message_templates[ $context ][ $template_field ])
1519
-                            ? $message_templates[ $context ][ $template_field ]
1518
+                        isset($message_templates[$context][$template_field])
1519
+                            ? $message_templates[$context][$template_field]
1520 1520
                             : null;
1521
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1522
-                                                                  && is_array($message_templates[ $context ])
1521
+                    $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1522
+                                                                  && is_array($message_templates[$context])
1523 1523
                                                                   && $message_template instanceof EE_Message_Template
1524 1524
                         ? $message_template->get('MTP_content')
1525 1525
                         : '';
1526 1526
 
1527 1527
                     // do we have a validator error for this field?  if we do then we'll use that value instead
1528
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1529
-                        ? $validators[ $template_field ]['value']
1530
-                        : $template_form_fields[ $field_id ]['value'];
1528
+                    $template_form_fields[$field_id]['value'] = isset($validators[$template_field])
1529
+                        ? $validators[$template_field]['value']
1530
+                        : $template_form_fields[$field_id]['value'];
1531 1531
 
1532 1532
 
1533
-                    $template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1533
+                    $template_form_fields[$field_id]['db-col']    = 'MTP_content';
1534 1534
                     $css_class                                      = isset($field_setup_array['css_class'])
1535 1535
                         ? $field_setup_array['css_class']
1536 1536
                         : '';
1537
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1537
+                    $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1538 1538
                                                                       && in_array($template_field, $v_fields, true)
1539
-                                                                      && isset($validators[ $template_field ]['msg'])
1540
-                        ? 'validate-error ' . $css_class
1539
+                                                                      && isset($validators[$template_field]['msg'])
1540
+                        ? 'validate-error '.$css_class
1541 1541
                         : $css_class;
1542 1542
 
1543 1543
                     // shortcode selector
1544
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1544
+                    $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1545 1545
                         $template_field,
1546 1546
                         $field_id
1547 1547
                     );
@@ -1549,12 +1549,12 @@  discard block
 block discarded – undo
1549 1549
 
1550 1550
                 // k took care of content field(s) now let's take care of others.
1551 1551
 
1552
-                $templatefield_MTP_id                = $template_field . '-MTP_ID';
1553
-                $templatefield_field_templatename_id = $template_field . '-name';
1552
+                $templatefield_MTP_id                = $template_field.'-MTP_ID';
1553
+                $templatefield_field_templatename_id = $template_field.'-name';
1554 1554
 
1555 1555
                 // foreach template field there are actually two form fields created
1556
-                $template_form_fields[ $templatefield_MTP_id ] = [
1557
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1556
+                $template_form_fields[$templatefield_MTP_id] = [
1557
+                    'name'       => 'MTP_template_fields['.$template_field.'][MTP_ID]',
1558 1558
                     'label'      => null,
1559 1559
                     'input'      => 'hidden',
1560 1560
                     'type'       => 'int',
@@ -1566,8 +1566,8 @@  discard block
 block discarded – undo
1566 1566
                     'db-col'     => 'MTP_ID',
1567 1567
                 ];
1568 1568
 
1569
-                $template_form_fields[ $templatefield_field_templatename_id ] = [
1570
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1569
+                $template_form_fields[$templatefield_field_templatename_id] = [
1570
+                    'name'       => 'MTP_template_fields['.$template_field.'][name]',
1571 1571
                     'label'      => null,
1572 1572
                     'input'      => 'hidden',
1573 1573
                     'type'       => 'string',
@@ -1684,7 +1684,7 @@  discard block
 block discarded – undo
1684 1684
                 'format'     => '%d',
1685 1685
                 'db-col'     => 'MTP_deleted',
1686 1686
             ];
1687
-            $sidebar_form_fields['ee-msg-author']  = [
1687
+            $sidebar_form_fields['ee-msg-author'] = [
1688 1688
                 'name'       => 'MTP_user_id',
1689 1689
                 'label'      => esc_html__('Author', 'event_espresso'),
1690 1690
                 'input'      => 'hidden',
@@ -1703,17 +1703,17 @@  discard block
 block discarded – undo
1703 1703
                 'value' => $action,
1704 1704
             ];
1705 1705
 
1706
-            $sidebar_form_fields['ee-msg-id']        = [
1706
+            $sidebar_form_fields['ee-msg-id'] = [
1707 1707
                 'name'  => 'id',
1708 1708
                 'input' => 'hidden',
1709 1709
                 'type'  => 'int',
1710 1710
                 'value' => $GRP_ID,
1711 1711
             ];
1712 1712
             $sidebar_form_fields['ee-msg-evt-nonce'] = [
1713
-                'name'  => $action . '_nonce',
1713
+                'name'  => $action.'_nonce',
1714 1714
                 'input' => 'hidden',
1715 1715
                 'type'  => 'string',
1716
-                'value' => wp_create_nonce($action . '_nonce'),
1716
+                'value' => wp_create_nonce($action.'_nonce'),
1717 1717
             ];
1718 1718
 
1719 1719
             if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
@@ -1743,7 +1743,7 @@  discard block
 block discarded – undo
1743 1743
         );
1744 1744
 
1745 1745
         // add preview button
1746
-        $preview_url    = parent::add_query_args_and_nonce(
1746
+        $preview_url = parent::add_query_args_and_nonce(
1747 1747
             [
1748 1748
                 'message_type' => $message_template_group->message_type(),
1749 1749
                 'messenger'    => $message_template_group->messenger(),
@@ -1754,7 +1754,7 @@  discard block
 block discarded – undo
1754 1754
             ],
1755 1755
             $this->_admin_base_url
1756 1756
         );
1757
-        $preview_button = '<a href="' . $preview_url . '" class="button--secondary messages-preview-button">'
1757
+        $preview_button = '<a href="'.$preview_url.'" class="button--secondary messages-preview-button">'
1758 1758
                           . esc_html__('Preview', 'event_espresso')
1759 1759
                           . '</a>';
1760 1760
 
@@ -1790,11 +1790,11 @@  discard block
 block discarded – undo
1790 1790
         $this->_template_args['before_admin_page_content'] .= $this->add_context_switcher();
1791 1791
         $this->_template_args['before_admin_page_content'] .= '</div>';
1792 1792
         $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1793
-        $this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1793
+        $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1794 1794
 
1795 1795
         $this->_template_path = $this->_template_args['GRP_ID']
1796 1796
             ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1797
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1797
+            : EE_MSG_TEMPLATE_PATH.'ee_msg_details_main_add_meta_box.template.php';
1798 1798
 
1799 1799
         // send along EE_Message_Template_Group object for further template use.
1800 1800
         $this->_template_args['MTP'] = $message_template_group;
@@ -1849,7 +1849,7 @@  discard block
 block discarded – undo
1849 1849
     ) {
1850 1850
         $template_args = [
1851 1851
             'context'                   => $context,
1852
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1852
+            'nonce'                     => wp_create_nonce('activate_'.$context.'_toggle_nonce'),
1853 1853
             'is_active'                 => $message_template_group->is_context_active($context),
1854 1854
             'on_off_action'             => $message_template_group->is_context_active($context)
1855 1855
                 ? 'context-off'
@@ -1858,7 +1858,7 @@  discard block
 block discarded – undo
1858 1858
             'message_template_group_id' => $message_template_group->ID(),
1859 1859
         ];
1860 1860
         return EEH_Template::display_template(
1861
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1861
+            EE_MSG_TEMPLATE_PATH.'ee_msg_editor_active_context_element.template.php',
1862 1862
             $template_args,
1863 1863
             true
1864 1864
         );
@@ -1898,7 +1898,7 @@  discard block
 block discarded – undo
1898 1898
         $nonce     = isset($this->_req_data['toggle_context_nonce'])
1899 1899
             ? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1900 1900
             : '';
1901
-        $nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1901
+        $nonce_ref = 'activate_'.$this->_req_data['context'].'_toggle_nonce';
1902 1902
         $this->_verify_nonce($nonce, $nonce_ref);
1903 1903
         $status = $this->_req_data['status'];
1904 1904
         if ($status !== 'off' && $status !== 'on') {
@@ -1916,7 +1916,7 @@  discard block
 block discarded – undo
1916 1916
         $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1917 1917
             $this->_req_data['message_template_group_id']
1918 1918
         );
1919
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1919
+        if ( ! $message_template_group instanceof EE_Message_Template_Group) {
1920 1920
             EE_Error::add_error(
1921 1921
                 sprintf(
1922 1922
                     esc_html__(
@@ -2016,7 +2016,7 @@  discard block
 block discarded – undo
2016 2016
                     )
2017 2017
                 );
2018 2018
                 // generate the redirect url for js.
2019
-                $url                                          = self::add_query_args_and_nonce(
2019
+                $url = self::add_query_args_and_nonce(
2020 2020
                     $query_args,
2021 2021
                     $this->_admin_base_url
2022 2022
                 );
@@ -2046,7 +2046,7 @@  discard block
 block discarded – undo
2046 2046
         $templates = [];
2047 2047
         $GRP_ID    = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2048 2048
         // we need to make sure we've got the info we need.
2049
-        if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2049
+        if ( ! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2050 2050
             EE_Error::add_error(
2051 2051
                 esc_html__(
2052 2052
                     'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
@@ -2088,7 +2088,7 @@  discard block
 block discarded – undo
2088 2088
         }
2089 2089
 
2090 2090
         // any error messages?
2091
-        if (! $success) {
2091
+        if ( ! $success) {
2092 2092
             EE_Error::add_error(
2093 2093
                 esc_html__(
2094 2094
                     'Something went wrong with deleting existing templates. Unable to reset to default',
@@ -2173,7 +2173,7 @@  discard block
 block discarded – undo
2173 2173
             : false;
2174 2174
 
2175 2175
         // let's add a button to go back to the edit view
2176
-        $query_args             = [
2176
+        $query_args = [
2177 2177
             'id'      => $this->_req_data['GRP_ID'],
2178 2178
             'evt_id'  => $EVT_ID,
2179 2179
             'context' => $this->_req_data['context'],
@@ -2194,7 +2194,7 @@  discard block
 block discarded – undo
2194 2194
         $preview_title = sprintf(
2195 2195
             esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2196 2196
             $active_messenger_label,
2197
-            ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2197
+            ucwords($message_types[$this->_req_data['message_type']]->label['singular'])
2198 2198
         );
2199 2199
         if (empty($preview)) {
2200 2200
             $this->noEventsErrorMessage();
@@ -2202,7 +2202,7 @@  discard block
 block discarded – undo
2202 2202
         // setup display of preview.
2203 2203
         $this->_admin_page_title                    = $preview_title;
2204 2204
         $this->_template_args['admin_page_title']   = $preview_title;
2205
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2205
+        $this->_template_args['admin_page_content'] = $preview_button.'<br />'.$preview;
2206 2206
         $this->_template_args['data']['force_json'] = true;
2207 2207
 
2208 2208
         return '';
@@ -2223,7 +2223,7 @@  discard block
 block discarded – undo
2223 2223
             ],
2224 2224
             admin_url('admin.php')
2225 2225
         );
2226
-        $message    = $test_send
2226
+        $message = $test_send
2227 2227
             ? esc_html__(
2228 2228
                 'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2229 2229
                 'event_espresso'
@@ -2316,10 +2316,10 @@  discard block
 block discarded – undo
2316 2316
             // only include template packs that support this messenger and message type!
2317 2317
             $supports = $tp->get_supports();
2318 2318
             if (
2319
-                ! isset($supports[ $this->_message_template_group->messenger() ])
2319
+                ! isset($supports[$this->_message_template_group->messenger()])
2320 2320
                 || ! in_array(
2321 2321
                     $this->_message_template_group->message_type(),
2322
-                    $supports[ $this->_message_template_group->messenger() ],
2322
+                    $supports[$this->_message_template_group->messenger()],
2323 2323
                     true
2324 2324
                 )
2325 2325
             ) {
@@ -2343,7 +2343,7 @@  discard block
 block discarded – undo
2343 2343
         }
2344 2344
 
2345 2345
         // setup variation select values for the currently selected template.
2346
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
2346
+        $variations = $this->_message_template_group->get_template_pack()->get_variations(
2347 2347
             $this->_message_template_group->messenger(),
2348 2348
             $this->_message_template_group->message_type()
2349 2349
         );
@@ -2357,12 +2357,12 @@  discard block
 block discarded – undo
2357 2357
 
2358 2358
         $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2359 2359
 
2360
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2360
+        $template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2361 2361
             'MTP_template_pack',
2362 2362
             $tp_select_values,
2363 2363
             $this->_message_template_group->get_template_pack_name()
2364 2364
         );
2365
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
2365
+        $template_args['variations_selector'] = EEH_Form_Fields::select_input(
2366 2366
             'MTP_template_variation',
2367 2367
             $variations_select_values,
2368 2368
             $this->_message_template_group->get_template_pack_variation()
@@ -2372,7 +2372,7 @@  discard block
 block discarded – undo
2372 2372
         $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2373 2373
         $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2374 2374
 
2375
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2375
+        $template = EE_MSG_TEMPLATE_PATH.'template_pack_and_variations_metabox.template.php';
2376 2376
 
2377 2377
         EEH_Template::display_template($template, $template_args);
2378 2378
     }
@@ -2398,33 +2398,33 @@  discard block
 block discarded – undo
2398 2398
         // first we need to see if there are any fields
2399 2399
         $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2400 2400
 
2401
-        if (! empty($fields)) {
2401
+        if ( ! empty($fields)) {
2402 2402
             // yup there be fields
2403 2403
             foreach ($fields as $field => $config) {
2404
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2404
+                $field_id = $this->_message_template_group->messenger().'_'.$field;
2405 2405
                 $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2406 2406
                 $default  = isset($config['default']) ? $config['default'] : '';
2407 2407
                 $default  = isset($config['value']) ? $config['value'] : $default;
2408 2408
 
2409 2409
                 // if type is hidden and the value is empty
2410 2410
                 // something may have gone wrong so let's correct with the defaults
2411
-                $fix                = $config['input'] === 'hidden'
2412
-                                      && isset($existing[ $field ])
2413
-                                      && empty($existing[ $field ])
2411
+                $fix = $config['input'] === 'hidden'
2412
+                                      && isset($existing[$field])
2413
+                                      && empty($existing[$field])
2414 2414
                     ? $default
2415 2415
                     : '';
2416
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2417
-                    ? $existing[ $field ]
2416
+                $existing[$field] = isset($existing[$field]) && empty($fix)
2417
+                    ? $existing[$field]
2418 2418
                     : $fix;
2419 2419
 
2420
-                $template_form_fields[ $field_id ] = [
2421
-                    'name'       => 'test_settings_fld[' . $field . ']',
2420
+                $template_form_fields[$field_id] = [
2421
+                    'name'       => 'test_settings_fld['.$field.']',
2422 2422
                     'label'      => $config['label'],
2423 2423
                     'input'      => $config['input'],
2424 2424
                     'type'       => $config['type'],
2425 2425
                     'required'   => $config['required'],
2426 2426
                     'validation' => $config['validation'],
2427
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2427
+                    'value'      => isset($existing[$field]) ? $existing[$field] : $default,
2428 2428
                     'css_class'  => $config['css_class'],
2429 2429
                     'options'    => isset($config['options']) ? $config['options'] : [],
2430 2430
                     'default'    => $default,
@@ -2438,7 +2438,7 @@  discard block
 block discarded – undo
2438 2438
             : '';
2439 2439
 
2440 2440
         // print out $test_settings_fields
2441
-        if (! empty($test_settings_html)) {
2441
+        if ( ! empty($test_settings_html)) {
2442 2442
             $test_settings_html .= '<input type="submit" class="button--primary mtp-test-button alignright" ';
2443 2443
             $test_settings_html .= 'name="test_button" value="';
2444 2444
             $test_settings_html .= esc_html__('Test Send', 'event_espresso');
@@ -2484,7 +2484,7 @@  discard block
 block discarded – undo
2484 2484
         ];
2485 2485
 
2486 2486
         return EEH_Template::display_template(
2487
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2487
+            EE_MSG_TEMPLATE_PATH.'shortcode_selector_skeleton.template.php',
2488 2488
             $template_args,
2489 2489
             true
2490 2490
         );
@@ -2510,7 +2510,7 @@  discard block
 block discarded – undo
2510 2510
         // $messenger = $this->_message_template_group->messenger_obj();
2511 2511
         // now let's set the content depending on the status of the shortcodes array
2512 2512
         if (empty($shortcodes)) {
2513
-            echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2513
+            echo '<p>'.esc_html__('There are no valid shortcodes available', 'event_espresso').'</p>';
2514 2514
             return;
2515 2515
         }
2516 2516
         ?>
@@ -2545,7 +2545,7 @@  discard block
 block discarded – undo
2545 2545
     {
2546 2546
 
2547 2547
         // no need to run this if the property is already set
2548
-        if (! empty($this->_shortcodes)) {
2548
+        if ( ! empty($this->_shortcodes)) {
2549 2549
             return;
2550 2550
         }
2551 2551
 
@@ -2599,7 +2599,7 @@  discard block
 block discarded – undo
2599 2599
     protected function _set_message_template_group()
2600 2600
     {
2601 2601
 
2602
-        if (! empty($this->_message_template_group)) {
2602
+        if ( ! empty($this->_message_template_group)) {
2603 2603
             return;
2604 2604
         } //get out if this is already set.
2605 2605
 
@@ -2649,7 +2649,7 @@  discard block
 block discarded – undo
2649 2649
                     <?php
2650 2650
                 }
2651 2651
                 // setup nonce_url
2652
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2652
+                wp_nonce_field($args['action'].'_nonce', $args['action'].'_nonce', false);
2653 2653
                 ?>
2654 2654
                 <select name="context">
2655 2655
                     <?php
@@ -2659,7 +2659,7 @@  discard block
 block discarded – undo
2659 2659
                             $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2660 2660
                             ?>
2661 2661
                             <option value="<?php echo esc_attr($context); ?>" <?php echo esc_attr($checked); ?>>
2662
-                                <?php echo $context_details[ $context ]['label']; // already escaped
2662
+                                <?php echo $context_details[$context]['label']; // already escaped
2663 2663
                                 ?>
2664 2664
                             </option>
2665 2665
                         <?php endforeach;
@@ -2694,22 +2694,22 @@  discard block
 block discarded – undo
2694 2694
      */
2695 2695
     protected function _set_message_template_column_values($index)
2696 2696
     {
2697
-        if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2698
-            foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2699
-                $this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2697
+        if (is_array($this->_req_data['MTP_template_fields'][$index]['content'])) {
2698
+            foreach ($this->_req_data['MTP_template_fields'][$index]['content'] as $field => $value) {
2699
+                $this->_req_data['MTP_template_fields'][$index]['content'][$field] = $value;
2700 2700
             }
2701 2701
         }
2702 2702
 
2703 2703
 
2704 2704
         $set_column_values = [
2705
-            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2705
+            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][$index]['MTP_ID']),
2706 2706
             'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2707 2707
             'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2708 2708
             'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2709 2709
             'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2710
-            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2710
+            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][$index]['name']),
2711 2711
             'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2712
-            'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2712
+            'MTP_content'        => $this->_req_data['MTP_template_fields'][$index]['content'],
2713 2713
             'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2714 2714
                 ? absint($this->_req_data['MTP_is_global'])
2715 2715
                 : 0,
@@ -2753,10 +2753,10 @@  discard block
 block discarded – undo
2753 2753
             : '';
2754 2754
         $context      = ucwords(str_replace('_', ' ', $context_slug));
2755 2755
 
2756
-        $item_desc   = $messenger_label && $message_type_label
2757
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2756
+        $item_desc = $messenger_label && $message_type_label
2757
+            ? $messenger_label.' '.$message_type_label.' '.$context.' '
2758 2758
             : '';
2759
-        $item_desc   .= 'Message Template';
2759
+        $item_desc .= 'Message Template';
2760 2760
         $query_args  = [];
2761 2761
         $edit_array  = [];
2762 2762
         $action_desc = '';
@@ -2785,7 +2785,7 @@  discard block
 block discarded – undo
2785 2785
 
2786 2786
 
2787 2787
             // run update for each template field in displayed context
2788
-            if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2788
+            if ( ! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2789 2789
                 EE_Error::add_error(
2790 2790
                     esc_html__(
2791 2791
                         'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
@@ -2847,10 +2847,10 @@  discard block
 block discarded – undo
2847 2847
                         $set_column_values = $this->_set_message_template_column_values($template_field);
2848 2848
 
2849 2849
                         $where_cols_n_values = [
2850
-                            'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2850
+                            'MTP_ID' => $this->_req_data['MTP_template_fields'][$template_field]['MTP_ID'],
2851 2851
                         ];
2852 2852
                         // if they aren't allowed to use all JS, restrict them to just posty-y tags
2853
-                        if (! current_user_can('unfiltered_html')) {
2853
+                        if ( ! current_user_can('unfiltered_html')) {
2854 2854
                             if (is_array($set_column_values['MTP_content'])) {
2855 2855
                                 foreach ($set_column_values['MTP_content'] as $key => $value) {
2856 2856
                                     // remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
@@ -2858,7 +2858,7 @@  discard block
 block discarded – undo
2858 2858
                                     // appear invalid.) But currently the models expect slashed data, so after wp_kses
2859 2859
                                     // runs we need to re-slash the data. Sheesh. See
2860 2860
                                     // https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2861
-                                    $set_column_values['MTP_content'][ $key ] = addslashes(
2861
+                                    $set_column_values['MTP_content'][$key] = addslashes(
2862 2862
                                         wp_kses(
2863 2863
                                             stripslashes($value),
2864 2864
                                             wp_kses_allowed_html('post')
@@ -2894,14 +2894,14 @@  discard block
 block discarded – undo
2894 2894
                             }
2895 2895
                         } else {
2896 2896
                             // only do this logic if we don't have a MTP_ID for this field
2897
-                            if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2897
+                            if (empty($this->_req_data['MTP_template_fields'][$template_field]['MTP_ID'])) {
2898 2898
                                 // this has already been through the template field validator and sanitized, so it will be
2899 2899
                                 // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2900 2900
                                 // message template field in a messenger/message type and existing users don't have the
2901 2901
                                 // default setup for it.
2902 2902
                                 // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2903 2903
                                 $updated = $MTP->insert($message_template_fields);
2904
-                                if (! $updated || is_wp_error($updated)) {
2904
+                                if ( ! $updated || is_wp_error($updated)) {
2905 2905
                                     EE_Error::add_error(
2906 2906
                                         sprintf(
2907 2907
                                             esc_html__('%s field could not be updated.', 'event_espresso'),
@@ -3135,7 +3135,7 @@  discard block
 block discarded – undo
3135 3135
         // incoming GRP_IDs
3136 3136
         if ($all) {
3137 3137
             // Checkboxes
3138
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3138
+            if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3139 3139
                 // if array has more than one element then success message should be plural.
3140 3140
                 // todo: what about nonce?
3141 3141
                 $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
@@ -3143,16 +3143,16 @@  discard block
 block discarded – undo
3143 3143
                 // cycle through checkboxes
3144 3144
                 while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3145 3145
                     $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3146
-                    if (! $trashed_or_restored) {
3146
+                    if ( ! $trashed_or_restored) {
3147 3147
                         $success = 0;
3148 3148
                     }
3149 3149
                 }
3150 3150
             } else {
3151 3151
                 // grab single GRP_ID and handle
3152 3152
                 $GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3153
-                if (! empty($GRP_ID)) {
3153
+                if ( ! empty($GRP_ID)) {
3154 3154
                     $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3155
-                    if (! $trashed_or_restored) {
3155
+                    if ( ! $trashed_or_restored) {
3156 3156
                         $success = 0;
3157 3157
                     }
3158 3158
                 } else {
@@ -3201,7 +3201,7 @@  discard block
 block discarded – undo
3201 3201
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3202 3202
 
3203 3203
         // checkboxes
3204
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3204
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3205 3205
             // if array has more than one element then success message should be plural
3206 3206
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3207 3207
 
@@ -3285,7 +3285,7 @@  discard block
 block discarded – undo
3285 3285
             : 'email';
3286 3286
 
3287 3287
         // let's setup the messenger tabs
3288
-        $this->_template_args['admin_page_header']         = EEH_Tabbed_Content::tab_text_links(
3288
+        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3289 3289
             $this->_m_mt_settings['messenger_tabs'],
3290 3290
             'messenger_links',
3291 3291
             '|',
@@ -3308,7 +3308,7 @@  discard block
 block discarded – undo
3308 3308
     protected function _set_m_mt_settings()
3309 3309
     {
3310 3310
         // first if this is already set then lets get out no need to regenerate data.
3311
-        if (! empty($this->_m_mt_settings)) {
3311
+        if ( ! empty($this->_m_mt_settings)) {
3312 3312
             return;
3313 3313
         }
3314 3314
 
@@ -3322,7 +3322,7 @@  discard block
 block discarded – undo
3322 3322
         // assemble the array for the _tab_text_links helper
3323 3323
 
3324 3324
         foreach ($messengers as $messenger) {
3325
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
3325
+            $this->_m_mt_settings['messenger_tabs'][$messenger->name] = [
3326 3326
                 'label' => ucwords($messenger->label['singular']),
3327 3327
                 'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3328 3328
                     ? 'messenger-active'
@@ -3339,7 +3339,7 @@  discard block
 block discarded – undo
3339 3339
             foreach ($message_types as $message_type) {
3340 3340
                 // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3341 3341
                 // it shouldn't show in either the inactive OR active metabox.
3342
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3342
+                if ( ! in_array($message_type->name, $message_types_for_messenger, true)) {
3343 3343
                     continue;
3344 3344
                 }
3345 3345
 
@@ -3350,12 +3350,12 @@  discard block
 block discarded – undo
3350 3350
                     ? 'active'
3351 3351
                     : 'inactive';
3352 3352
 
3353
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
3353
+                $this->_m_mt_settings['message_type_tabs'][$messenger->name][$a_or_i][$message_type->name] = [
3354 3354
                     'label'    => ucwords($message_type->label['singular']),
3355
-                    'class'    => 'message-type-' . $a_or_i,
3356
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3357
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3358
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3355
+                    'class'    => 'message-type-'.$a_or_i,
3356
+                    'slug_id'  => $message_type->name.'-messagetype-'.$messenger->name,
3357
+                    'mt_nonce' => wp_create_nonce($message_type->name.'_nonce'),
3358
+                    'href'     => 'espresso_'.$message_type->name.'_message_type_settings',
3359 3359
                     'title'    => $a_or_i === 'active'
3360 3360
                         ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3361 3361
                         : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
@@ -3386,25 +3386,25 @@  discard block
 block discarded – undo
3386 3386
         $fields                                         = $message_type->get_admin_settings_fields();
3387 3387
         $settings_template_args['template_form_fields'] = '';
3388 3388
 
3389
-        if (! empty($fields) && $active) {
3389
+        if ( ! empty($fields) && $active) {
3390 3390
             $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3391 3391
             foreach ($fields as $fldname => $fldprops) {
3392
-                $field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3393
-                $template_form_field[ $field_id ] = [
3394
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3392
+                $field_id                         = $messenger->name.'-'.$message_type->name.'-'.$fldname;
3393
+                $template_form_field[$field_id] = [
3394
+                    'name'       => 'message_type_settings['.$fldname.']',
3395 3395
                     'label'      => $fldprops['label'],
3396 3396
                     'input'      => $fldprops['field_type'],
3397 3397
                     'type'       => $fldprops['value_type'],
3398 3398
                     'required'   => $fldprops['required'],
3399 3399
                     'validation' => $fldprops['validation'],
3400
-                    'value'      => isset($existing_settings[ $fldname ])
3401
-                        ? $existing_settings[ $fldname ]
3400
+                    'value'      => isset($existing_settings[$fldname])
3401
+                        ? $existing_settings[$fldname]
3402 3402
                         : $fldprops['default'],
3403 3403
                     'options'    => isset($fldprops['options'])
3404 3404
                         ? $fldprops['options']
3405 3405
                         : [],
3406
-                    'default'    => isset($existing_settings[ $fldname ])
3407
-                        ? $existing_settings[ $fldname ]
3406
+                    'default'    => isset($existing_settings[$fldname])
3407
+                        ? $existing_settings[$fldname]
3408 3408
                         : $fldprops['default'],
3409 3409
                     'css_class'  => 'no-drag',
3410 3410
                     'format'     => $fldprops['format'],
@@ -3424,15 +3424,15 @@  discard block
 block discarded – undo
3424 3424
         $settings_template_args['description'] = $message_type->description;
3425 3425
         // we also need some hidden fields
3426 3426
         $hidden_fields = [
3427
-            'message_type_settings[messenger]' . $message_type->name   => [
3427
+            'message_type_settings[messenger]'.$message_type->name   => [
3428 3428
                 'type'  => 'hidden',
3429 3429
                 'value' => $messenger->name,
3430 3430
             ],
3431
-            'message_type_settings[message_type]' . $message_type->name => [
3431
+            'message_type_settings[message_type]'.$message_type->name => [
3432 3432
                 'type'  => 'hidden',
3433 3433
                 'value' => $message_type->name,
3434 3434
             ],
3435
-            'type'   . $message_type->name                             => [
3435
+            'type'.$message_type->name                             => [
3436 3436
                 'type'  => 'hidden',
3437 3437
                 'value' => 'message_type',
3438 3438
             ],
@@ -3442,12 +3442,12 @@  discard block
 block discarded – undo
3442 3442
             $hidden_fields,
3443 3443
             'array'
3444 3444
         );
3445
-        $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3445
+        $settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3446 3446
             ? ' hidden'
3447 3447
             : '';
3448 3448
 
3449 3449
 
3450
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3450
+        $template = EE_MSG_TEMPLATE_PATH.'ee_msg_mt_settings_content.template.php';
3451 3451
         $content  = EEH_Template::display_template($template, $settings_template_args, true);
3452 3452
 
3453 3453
         return $content;
@@ -3478,20 +3478,20 @@  discard block
 block discarded – undo
3478 3478
                 // messenger meta boxes
3479 3479
                 $active                                   = $selected_messenger === $messenger;
3480 3480
                 $active_mt_tabs                           = isset(
3481
-                    $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3481
+                    $this->_m_mt_settings['message_type_tabs'][$messenger]['active']
3482 3482
                 )
3483
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3483
+                    ? $this->_m_mt_settings['message_type_tabs'][$messenger]['active']
3484 3484
                     : '';
3485
-                $m_boxes[ $messenger . '_a_box' ]         = sprintf(
3485
+                $m_boxes[$messenger.'_a_box'] = sprintf(
3486 3486
                     esc_html__('%s Settings', 'event_espresso'),
3487 3487
                     $tab_array['label']
3488 3488
                 );
3489
-                $m_template_args[ $messenger . '_a_box' ] = [
3489
+                $m_template_args[$messenger.'_a_box'] = [
3490 3490
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3491 3491
                     'inactive_message_types' => isset(
3492
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3492
+                        $this->_m_mt_settings['message_type_tabs'][$messenger]['inactive']
3493 3493
                     )
3494
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3494
+                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
3495 3495
                         : '',
3496 3496
                     'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3497 3497
                     'hidden'                 => $active ? '' : ' hidden',
@@ -3502,13 +3502,13 @@  discard block
 block discarded – undo
3502 3502
                 // message type meta boxes
3503 3503
                 // (which is really just the inactive container for each messenger
3504 3504
                 // showing inactive message types for that messenger)
3505
-                $mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3506
-                $mt_template_args[ $messenger . '_i_box' ] = [
3505
+                $mt_boxes[$messenger.'_i_box']         = esc_html__('Inactive Message Types', 'event_espresso');
3506
+                $mt_template_args[$messenger.'_i_box'] = [
3507 3507
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3508 3508
                     'inactive_message_types' => isset(
3509
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3509
+                        $this->_m_mt_settings['message_type_tabs'][$messenger]['inactive']
3510 3510
                     )
3511
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3511
+                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
3512 3512
                         : '',
3513 3513
                     'hidden'                 => $active ? '' : ' hidden',
3514 3514
                     'hide_on_message'        => $hide_on_message,
@@ -3521,14 +3521,14 @@  discard block
 block discarded – undo
3521 3521
 
3522 3522
 
3523 3523
         // register messenger metaboxes
3524
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3524
+        $m_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_mt_meta_box.template.php';
3525 3525
         foreach ($m_boxes as $box => $label) {
3526
-            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3526
+            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[$box]];
3527 3527
             $msgr          = str_replace('_a_box', '', $box);
3528 3528
             $this->addMetaBox(
3529
-                'espresso_' . $msgr . '_settings',
3529
+                'espresso_'.$msgr.'_settings',
3530 3530
                 $label,
3531
-                function ($post, $metabox) {
3531
+                function($post, $metabox) {
3532 3532
                     EEH_Template::display_template(
3533 3533
                         $metabox['args']['template_path'],
3534 3534
                         $metabox['args']['template_args']
@@ -3542,17 +3542,17 @@  discard block
 block discarded – undo
3542 3542
         }
3543 3543
 
3544 3544
         // register message type metaboxes
3545
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3545
+        $mt_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_meta_box.template.php';
3546 3546
         foreach ($mt_boxes as $box => $label) {
3547 3547
             $callback_args = [
3548 3548
                 'template_path' => $mt_template_path,
3549
-                'template_args' => $mt_template_args[ $box ],
3549
+                'template_args' => $mt_template_args[$box],
3550 3550
             ];
3551
-            $mt            = str_replace('_i_box', '', $box);
3551
+            $mt = str_replace('_i_box', '', $box);
3552 3552
             $this->addMetaBox(
3553
-                'espresso_' . $mt . '_inactive_mts',
3553
+                'espresso_'.$mt.'_inactive_mts',
3554 3554
                 $label,
3555
-                function ($post, $metabox) {
3555
+                function($post, $metabox) {
3556 3556
                     EEH_Template::display_template(
3557 3557
                         $metabox['args']['template_path'],
3558 3558
                         $metabox['args']['template_args']
@@ -3698,7 +3698,7 @@  discard block
 block discarded – undo
3698 3698
             if ($form->is_valid()) {
3699 3699
                 $valid_data = $form->valid_data();
3700 3700
                 foreach ($valid_data as $property => $value) {
3701
-                    $setter = 'set_' . $property;
3701
+                    $setter = 'set_'.$property;
3702 3702
                     if (method_exists($network_config, $setter)) {
3703 3703
                         $network_config->{$setter}($value);
3704 3704
                     } elseif (
@@ -3734,7 +3734,7 @@  discard block
 block discarded – undo
3734 3734
     protected function _get_mt_tabs($tab_array)
3735 3735
     {
3736 3736
         $tab_array = (array) $tab_array;
3737
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3737
+        $template  = EE_MSG_TEMPLATE_PATH.'ee_msg_details_mt_settings_tab_item.template.php';
3738 3738
         $tabs      = '';
3739 3739
 
3740 3740
         foreach ($tab_array as $tab) {
@@ -3762,20 +3762,20 @@  discard block
 block discarded – undo
3762 3762
         $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3763 3763
 
3764 3764
 
3765
-        if (! empty($fields)) {
3765
+        if ( ! empty($fields)) {
3766 3766
             $existing_settings = $messenger->get_existing_admin_settings();
3767 3767
 
3768 3768
             foreach ($fields as $fldname => $fldprops) {
3769
-                $field_id                         = $messenger->name . '-' . $fldname;
3770
-                $template_form_field[ $field_id ] = [
3771
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3769
+                $field_id                         = $messenger->name.'-'.$fldname;
3770
+                $template_form_field[$field_id] = [
3771
+                    'name'       => 'messenger_settings['.$field_id.']',
3772 3772
                     'label'      => $fldprops['label'],
3773 3773
                     'input'      => $fldprops['field_type'],
3774 3774
                     'type'       => $fldprops['value_type'],
3775 3775
                     'required'   => $fldprops['required'],
3776 3776
                     'validation' => $fldprops['validation'],
3777
-                    'value'      => isset($existing_settings[ $field_id ])
3778
-                        ? $existing_settings[ $field_id ]
3777
+                    'value'      => isset($existing_settings[$field_id])
3778
+                        ? $existing_settings[$field_id]
3779 3779
                         : $fldprops['default'],
3780 3780
                     'css_class'  => '',
3781 3781
                     'format'     => $fldprops['format'],
@@ -3790,20 +3790,20 @@  discard block
 block discarded – undo
3790 3790
 
3791 3791
         // we also need some hidden fields
3792 3792
         $settings_template_args['hidden_fields'] = [
3793
-            'messenger_settings[messenger]' . $messenger->name => [
3793
+            'messenger_settings[messenger]'.$messenger->name => [
3794 3794
                 'type'  => 'hidden',
3795 3795
                 'value' => $messenger->name,
3796 3796
             ],
3797
-            'type' . $messenger->name                          => [
3797
+            'type'.$messenger->name                          => [
3798 3798
                 'type'  => 'hidden',
3799 3799
                 'value' => 'messenger',
3800 3800
             ],
3801 3801
         ];
3802 3802
 
3803 3803
         // make sure any active message types that are existing are included in the hidden fields
3804
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3805
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3806
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3804
+        if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3805
+            foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3806
+                $settings_template_args['hidden_fields']['messenger_settings[message_types]['.$mt.']'] = [
3807 3807
                     'type'  => 'hidden',
3808 3808
                     'value' => $mt,
3809 3809
                 ];
@@ -3813,7 +3813,7 @@  discard block
 block discarded – undo
3813 3813
             $settings_template_args['hidden_fields'],
3814 3814
             'array'
3815 3815
         );
3816
-        $active                                  =
3816
+        $active =
3817 3817
             $this->_message_resource_manager->is_messenger_active($messenger->name);
3818 3818
 
3819 3819
         $settings_template_args['messenger']           = $messenger->name;
@@ -3833,9 +3833,9 @@  discard block
 block discarded – undo
3833 3833
 
3834 3834
 
3835 3835
         $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3836
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3836
+        $settings_template_args['nonce']         = wp_create_nonce('activate_'.$messenger->name.'_toggle_nonce');
3837 3837
         $settings_template_args['on_off_status'] = $active;
3838
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3838
+        $template                                = EE_MSG_TEMPLATE_PATH.'ee_msg_m_settings_content.template.php';
3839 3839
         return EEH_Template::display_template(
3840 3840
             $template,
3841 3841
             $settings_template_args,
@@ -3859,7 +3859,7 @@  discard block
 block discarded – undo
3859 3859
         $success = true;
3860 3860
         $this->_prep_default_response_for_messenger_or_message_type_toggle();
3861 3861
         // let's check that we have required data
3862
-        if (! isset($this->_req_data['messenger'])) {
3862
+        if ( ! isset($this->_req_data['messenger'])) {
3863 3863
             EE_Error::add_error(
3864 3864
                 esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3865 3865
                 __FILE__,
@@ -3873,12 +3873,12 @@  discard block
 block discarded – undo
3873 3873
         $nonce     = isset($this->_req_data['activate_nonce'])
3874 3874
             ? sanitize_text_field($this->_req_data['activate_nonce'])
3875 3875
             : '';
3876
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3876
+        $nonce_ref = 'activate_'.$this->_req_data['messenger'].'_toggle_nonce';
3877 3877
 
3878 3878
         $this->_verify_nonce($nonce, $nonce_ref);
3879 3879
 
3880 3880
 
3881
-        if (! isset($this->_req_data['status'])) {
3881
+        if ( ! isset($this->_req_data['status'])) {
3882 3882
             EE_Error::add_error(
3883 3883
                 esc_html__(
3884 3884
                     'Messenger status needed to know whether activation or deactivation is happening. No status is given',
@@ -3937,7 +3937,7 @@  discard block
 block discarded – undo
3937 3937
         $this->_prep_default_response_for_messenger_or_message_type_toggle();
3938 3938
 
3939 3939
         // let's make sure we have the necessary data
3940
-        if (! isset($this->_req_data['message_type'])) {
3940
+        if ( ! isset($this->_req_data['message_type'])) {
3941 3941
             EE_Error::add_error(
3942 3942
                 esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3943 3943
                 __FILE__,
@@ -3947,7 +3947,7 @@  discard block
 block discarded – undo
3947 3947
             $success = false;
3948 3948
         }
3949 3949
 
3950
-        if (! isset($this->_req_data['messenger'])) {
3950
+        if ( ! isset($this->_req_data['messenger'])) {
3951 3951
             EE_Error::add_error(
3952 3952
                 esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3953 3953
                 __FILE__,
@@ -3957,7 +3957,7 @@  discard block
 block discarded – undo
3957 3957
             $success = false;
3958 3958
         }
3959 3959
 
3960
-        if (! isset($this->_req_data['status'])) {
3960
+        if ( ! isset($this->_req_data['status'])) {
3961 3961
             EE_Error::add_error(
3962 3962
                 esc_html__(
3963 3963
                     'Messenger status needed to know whether activation or deactivation is happening. No status is given',
@@ -3990,7 +3990,7 @@  discard block
 block discarded – undo
3990 3990
 
3991 3991
         // do a nonce check here since we're not arriving via a normal route
3992 3992
         $nonce     = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3993
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3993
+        $nonce_ref = $this->_req_data['message_type'].'_nonce';
3994 3994
 
3995 3995
         $this->_verify_nonce($nonce, $nonce_ref);
3996 3996
 
@@ -4179,7 +4179,7 @@  discard block
 block discarded – undo
4179 4179
         EE_Message_Type $message_type = null
4180 4180
     ) {
4181 4181
         // if $messenger isn't a valid messenger object then get out.
4182
-        if (! $messenger instanceof EE_Messenger) {
4182
+        if ( ! $messenger instanceof EE_Messenger) {
4183 4183
             EE_Error::add_error(
4184 4184
                 esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4185 4185
                 __FILE__,
@@ -4234,7 +4234,7 @@  discard block
 block discarded – undo
4234 4234
             // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4235 4235
             // in which case we just give a success message for the messenger being successfully activated.
4236 4236
         } else {
4237
-            if (! $messenger->get_default_message_types()) {
4237
+            if ( ! $messenger->get_default_message_types()) {
4238 4238
                 // messenger doesn't have any default message types so still a success.
4239 4239
                 EE_Error::add_success(
4240 4240
                     sprintf(
@@ -4290,7 +4290,7 @@  discard block
 block discarded – undo
4290 4290
         EE_Error::overwrite_success();
4291 4291
 
4292 4292
         // if $messenger isn't a valid messenger object then get out.
4293
-        if (! $messenger instanceof EE_Messenger) {
4293
+        if ( ! $messenger instanceof EE_Messenger) {
4294 4294
             EE_Error::add_error(
4295 4295
                 esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4296 4296
                 __FILE__,
@@ -4352,7 +4352,7 @@  discard block
 block discarded – undo
4352 4352
      */
4353 4353
     public function update_mt_form()
4354 4354
     {
4355
-        if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4355
+        if ( ! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4356 4356
             EE_Error::add_error(
4357 4357
                 esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4358 4358
                 __FILE__,
@@ -4364,10 +4364,10 @@  discard block
 block discarded – undo
4364 4364
 
4365 4365
         $message_types = $this->get_installed_message_types();
4366 4366
 
4367
-        $message_type = $message_types[ $this->_req_data['message_type'] ];
4367
+        $message_type = $message_types[$this->_req_data['message_type']];
4368 4368
         $messenger    = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4369 4369
 
4370
-        $content                         = $this->_message_type_settings_content(
4370
+        $content = $this->_message_type_settings_content(
4371 4371
             $message_type,
4372 4372
             $messenger,
4373 4373
             true
@@ -4384,7 +4384,7 @@  discard block
 block discarded – undo
4384 4384
      */
4385 4385
     public function save_settings()
4386 4386
     {
4387
-        if (! isset($this->_req_data['type'])) {
4387
+        if ( ! isset($this->_req_data['type'])) {
4388 4388
             EE_Error::add_error(
4389 4389
                 esc_html__(
4390 4390
                     'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
@@ -4413,7 +4413,7 @@  discard block
 block discarded – undo
4413 4413
                         unset($settings['message_types']);
4414 4414
                         break;
4415 4415
                     default:
4416
-                        $settings[ $key ] = $value;
4416
+                        $settings[$key] = $value;
4417 4417
                         break;
4418 4418
                 }
4419 4419
             }
@@ -4432,7 +4432,7 @@  discard block
 block discarded – undo
4432 4432
                         unset($settings['message_type']);
4433 4433
                         break;
4434 4434
                     default:
4435
-                        $settings[ $key ] = $value;
4435
+                        $settings[$key] = $value;
4436 4436
                         break;
4437 4437
                 }
4438 4438
             }
@@ -4593,7 +4593,7 @@  discard block
 block discarded – undo
4593 4593
      */
4594 4594
     protected function _get_msg_ids_from_request()
4595 4595
     {
4596
-        if (! isset($this->_req_data['MSG_ID'])) {
4596
+        if ( ! isset($this->_req_data['MSG_ID'])) {
4597 4597
             return [];
4598 4598
         }
4599 4599
 
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_CPT.core.php 1 patch
Indentation   +1470 added lines, -1470 removed lines patch added patch discarded remove patch
@@ -28,481 +28,481 @@  discard block
 block discarded – undo
28 28
 {
29 29
 
30 30
 
31
-    /**
32
-     * This gets set in _setup_cpt
33
-     * It will contain the object for the custom post type.
34
-     *
35
-     * @var EE_CPT_Base
36
-     */
37
-    protected $_cpt_object;
38
-
39
-
40
-    /**
41
-     * a boolean flag to set whether the current route is a cpt route or not.
42
-     *
43
-     * @var bool
44
-     */
45
-    protected $_cpt_route = false;
46
-
47
-
48
-    /**
49
-     * This property allows cpt classes to define multiple routes as cpt routes.
50
-     * //in this array we define what the custom post type for this route is.
51
-     * array(
52
-     * 'route_name' => 'custom_post_type_slug'
53
-     * )
54
-     *
55
-     * @var array
56
-     */
57
-    protected $_cpt_routes = [];
58
-
59
-
60
-    /**
61
-     * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
62
-     * in this format:
63
-     * array(
64
-     * 'post_type_slug' => 'edit_route'
65
-     * )
66
-     *
67
-     * @var array
68
-     */
69
-    protected $_cpt_edit_routes = [];
70
-
71
-
72
-    /**
73
-     * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
74
-     * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
75
-     * _cpt_model_names property should be in the following format: array(
76
-     * 'route_defined_by_action_param' => 'Model_Name')
77
-     *
78
-     * @var array $_cpt_model_names
79
-     */
80
-    protected $_cpt_model_names = [];
81
-
82
-
83
-    /**
84
-     * @var EE_CPT_Base
85
-     */
86
-    protected $_cpt_model_obj = false;
87
-
88
-
89
-    /**
90
-     * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
91
-     * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
92
-     * the _register_autosave_containers() method so that we don't override any other containers already registered.
93
-     * Registration of containers should be done before load_page_dependencies() is run.
94
-     *
95
-     * @var array()
96
-     */
97
-    protected $_autosave_containers = [];
98
-
99
-    protected $_autosave_fields     = [];
100
-
101
-    /**
102
-     * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
103
-     * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
104
-     *
105
-     * @var array
106
-     */
107
-    protected $_pagenow_map;
108
-
109
-
110
-
111
-    /**
112
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
113
-     * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
114
-     * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
115
-     * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
116
-     * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
117
-     *
118
-     * @abstract
119
-     * @param string      $post_id The ID of the cpt that was saved (so you can link relationally)
120
-     * @param EE_CPT_Base $post    The post object of the cpt that was saved.
121
-     * @return void
122
-     */
123
-    abstract protected function _insert_update_cpt_item($post_id, $post);
124
-
125
-
126
-    /**
127
-     * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
128
-     *
129
-     * @abstract
130
-     * @param string $post_id The ID of the cpt that was trashed
131
-     * @return void
132
-     */
133
-    abstract public function trash_cpt_item($post_id);
134
-
135
-
136
-    /**
137
-     * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
138
-     *
139
-     * @param string $post_id theID of the cpt that was untrashed
140
-     * @return void
141
-     */
142
-    abstract public function restore_cpt_item($post_id);
143
-
144
-
145
-    /**
146
-     * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
147
-     * from the db
148
-     *
149
-     * @param string $post_id the ID of the cpt that was deleted
150
-     * @return void
151
-     */
152
-    abstract public function delete_cpt_item($post_id);
153
-
154
-
155
-    /**
156
-     * @return LoaderInterface
157
-     * @throws InvalidArgumentException
158
-     * @throws InvalidDataTypeException
159
-     * @throws InvalidInterfaceException
160
-     */
161
-    protected function getLoader()
162
-    {
163
-        if (! $this->loader instanceof LoaderInterface) {
164
-            $this->loader = LoaderFactory::getLoader();
165
-        }
166
-        return $this->loader;
167
-    }
168
-
169
-
170
-    /**
171
-     * Just utilizing the method EE_Admin exposes for doing things before page setup.
172
-     *
173
-     * @return void
174
-     */
175
-    protected function _before_page_setup()
176
-    {
177
-        $this->raw_req_action = $this->request->getRequestParam('action');
178
-        $this->raw_req_page = $this->request->getRequestParam('page');
179
-        $this->_cpt_routes = array_merge(
180
-            [
181
-                'create_new' => $this->page_slug,
182
-                'edit'       => $this->page_slug,
183
-                'trash'      => $this->page_slug,
184
-            ],
185
-            $this->_cpt_routes
186
-        );
187
-        $cpt_route_action  = isset($this->_cpt_routes[ $this->raw_req_action ])
188
-            ? $this->_cpt_routes[ $this->raw_req_action ]
189
-            : null;
190
-        // let's see if the current route has a value for cpt_object_slug. if it does, we use that instead of the page
191
-        $page              = $this->raw_req_page ?: $this->page_slug;
192
-        $page              = $cpt_route_action ?: $page;
193
-        $this->_cpt_object = get_post_type_object($page);
194
-        // tweak pagenow for page loading.
195
-        if (! $this->_pagenow_map) {
196
-            $this->_pagenow_map = [
197
-                'create_new' => 'post-new.php',
198
-                'edit'       => 'post.php',
199
-                'trash'      => 'post.php',
200
-            ];
201
-        }
202
-        add_action('current_screen', [$this, 'modify_pagenow']);
203
-        // TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
204
-        // get current page from autosave
205
-        $current_page        = $this->request->getRequestParam('ee_autosave_data[ee-cpt-hidden-inputs][current_page]');
206
-        $this->_current_page = $this->request->getRequestParam('current_page', $current_page);
207
-    }
208
-
209
-
210
-    /**
211
-     * Simply ensure that we simulate the correct post route for cpt screens
212
-     *
213
-     * @param WP_Screen $current_screen
214
-     * @return void
215
-     */
216
-    public function modify_pagenow($current_screen)
217
-    {
218
-        // possibly reset pagenow.
219
-        if (
220
-            $this->page_slug === $this->raw_req_page
221
-            && isset($this->_pagenow_map[ $this->raw_req_action ])
222
-        ) {
223
-            global $pagenow, $hook_suffix;
224
-            $pagenow     = $this->_pagenow_map[ $this->raw_req_action ];
225
-            $hook_suffix = $pagenow;
226
-        }
227
-    }
228
-
229
-
230
-    /**
231
-     * This method is used to register additional autosave containers to the _autosave_containers property.
232
-     *
233
-     * @param array $ids  an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
234
-     *                    you would send along the id of a metabox container.
235
-     * @return void
236
-     * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
237
-     *                    automatically register the id for the post metabox as a container.
238
-     */
239
-    protected function _register_autosave_containers($ids)
240
-    {
241
-        $this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
242
-    }
243
-
244
-
245
-    /**
246
-     * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
247
-     * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
248
-     */
249
-    protected function _set_autosave_containers()
250
-    {
251
-        global $wp_meta_boxes;
252
-        $containers = [];
253
-        if (empty($wp_meta_boxes)) {
254
-            return;
255
-        }
256
-        $current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : [];
257
-        foreach ($current_metaboxes as $box_context) {
258
-            foreach ($box_context as $box_details) {
259
-                foreach ($box_details as $box) {
260
-                    if (
261
-                        is_array($box) && is_array($box['callback'])
262
-                        && (
263
-                            $box['callback'][0] instanceof EE_Admin_Page
264
-                            || $box['callback'][0] instanceof EE_Admin_Hooks
265
-                        )
266
-                    ) {
267
-                        $containers[] = $box['id'];
268
-                    }
269
-                }
270
-            }
271
-        }
272
-        $this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
273
-        // add hidden inputs container
274
-        $this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
275
-    }
276
-
277
-
278
-    protected function _load_autosave_scripts_styles()
279
-    {
280
-        /*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
31
+	/**
32
+	 * This gets set in _setup_cpt
33
+	 * It will contain the object for the custom post type.
34
+	 *
35
+	 * @var EE_CPT_Base
36
+	 */
37
+	protected $_cpt_object;
38
+
39
+
40
+	/**
41
+	 * a boolean flag to set whether the current route is a cpt route or not.
42
+	 *
43
+	 * @var bool
44
+	 */
45
+	protected $_cpt_route = false;
46
+
47
+
48
+	/**
49
+	 * This property allows cpt classes to define multiple routes as cpt routes.
50
+	 * //in this array we define what the custom post type for this route is.
51
+	 * array(
52
+	 * 'route_name' => 'custom_post_type_slug'
53
+	 * )
54
+	 *
55
+	 * @var array
56
+	 */
57
+	protected $_cpt_routes = [];
58
+
59
+
60
+	/**
61
+	 * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
62
+	 * in this format:
63
+	 * array(
64
+	 * 'post_type_slug' => 'edit_route'
65
+	 * )
66
+	 *
67
+	 * @var array
68
+	 */
69
+	protected $_cpt_edit_routes = [];
70
+
71
+
72
+	/**
73
+	 * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
74
+	 * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
75
+	 * _cpt_model_names property should be in the following format: array(
76
+	 * 'route_defined_by_action_param' => 'Model_Name')
77
+	 *
78
+	 * @var array $_cpt_model_names
79
+	 */
80
+	protected $_cpt_model_names = [];
81
+
82
+
83
+	/**
84
+	 * @var EE_CPT_Base
85
+	 */
86
+	protected $_cpt_model_obj = false;
87
+
88
+
89
+	/**
90
+	 * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
91
+	 * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
92
+	 * the _register_autosave_containers() method so that we don't override any other containers already registered.
93
+	 * Registration of containers should be done before load_page_dependencies() is run.
94
+	 *
95
+	 * @var array()
96
+	 */
97
+	protected $_autosave_containers = [];
98
+
99
+	protected $_autosave_fields     = [];
100
+
101
+	/**
102
+	 * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
103
+	 * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
104
+	 *
105
+	 * @var array
106
+	 */
107
+	protected $_pagenow_map;
108
+
109
+
110
+
111
+	/**
112
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
113
+	 * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
114
+	 * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
115
+	 * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
116
+	 * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
117
+	 *
118
+	 * @abstract
119
+	 * @param string      $post_id The ID of the cpt that was saved (so you can link relationally)
120
+	 * @param EE_CPT_Base $post    The post object of the cpt that was saved.
121
+	 * @return void
122
+	 */
123
+	abstract protected function _insert_update_cpt_item($post_id, $post);
124
+
125
+
126
+	/**
127
+	 * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
128
+	 *
129
+	 * @abstract
130
+	 * @param string $post_id The ID of the cpt that was trashed
131
+	 * @return void
132
+	 */
133
+	abstract public function trash_cpt_item($post_id);
134
+
135
+
136
+	/**
137
+	 * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
138
+	 *
139
+	 * @param string $post_id theID of the cpt that was untrashed
140
+	 * @return void
141
+	 */
142
+	abstract public function restore_cpt_item($post_id);
143
+
144
+
145
+	/**
146
+	 * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
147
+	 * from the db
148
+	 *
149
+	 * @param string $post_id the ID of the cpt that was deleted
150
+	 * @return void
151
+	 */
152
+	abstract public function delete_cpt_item($post_id);
153
+
154
+
155
+	/**
156
+	 * @return LoaderInterface
157
+	 * @throws InvalidArgumentException
158
+	 * @throws InvalidDataTypeException
159
+	 * @throws InvalidInterfaceException
160
+	 */
161
+	protected function getLoader()
162
+	{
163
+		if (! $this->loader instanceof LoaderInterface) {
164
+			$this->loader = LoaderFactory::getLoader();
165
+		}
166
+		return $this->loader;
167
+	}
168
+
169
+
170
+	/**
171
+	 * Just utilizing the method EE_Admin exposes for doing things before page setup.
172
+	 *
173
+	 * @return void
174
+	 */
175
+	protected function _before_page_setup()
176
+	{
177
+		$this->raw_req_action = $this->request->getRequestParam('action');
178
+		$this->raw_req_page = $this->request->getRequestParam('page');
179
+		$this->_cpt_routes = array_merge(
180
+			[
181
+				'create_new' => $this->page_slug,
182
+				'edit'       => $this->page_slug,
183
+				'trash'      => $this->page_slug,
184
+			],
185
+			$this->_cpt_routes
186
+		);
187
+		$cpt_route_action  = isset($this->_cpt_routes[ $this->raw_req_action ])
188
+			? $this->_cpt_routes[ $this->raw_req_action ]
189
+			: null;
190
+		// let's see if the current route has a value for cpt_object_slug. if it does, we use that instead of the page
191
+		$page              = $this->raw_req_page ?: $this->page_slug;
192
+		$page              = $cpt_route_action ?: $page;
193
+		$this->_cpt_object = get_post_type_object($page);
194
+		// tweak pagenow for page loading.
195
+		if (! $this->_pagenow_map) {
196
+			$this->_pagenow_map = [
197
+				'create_new' => 'post-new.php',
198
+				'edit'       => 'post.php',
199
+				'trash'      => 'post.php',
200
+			];
201
+		}
202
+		add_action('current_screen', [$this, 'modify_pagenow']);
203
+		// TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
204
+		// get current page from autosave
205
+		$current_page        = $this->request->getRequestParam('ee_autosave_data[ee-cpt-hidden-inputs][current_page]');
206
+		$this->_current_page = $this->request->getRequestParam('current_page', $current_page);
207
+	}
208
+
209
+
210
+	/**
211
+	 * Simply ensure that we simulate the correct post route for cpt screens
212
+	 *
213
+	 * @param WP_Screen $current_screen
214
+	 * @return void
215
+	 */
216
+	public function modify_pagenow($current_screen)
217
+	{
218
+		// possibly reset pagenow.
219
+		if (
220
+			$this->page_slug === $this->raw_req_page
221
+			&& isset($this->_pagenow_map[ $this->raw_req_action ])
222
+		) {
223
+			global $pagenow, $hook_suffix;
224
+			$pagenow     = $this->_pagenow_map[ $this->raw_req_action ];
225
+			$hook_suffix = $pagenow;
226
+		}
227
+	}
228
+
229
+
230
+	/**
231
+	 * This method is used to register additional autosave containers to the _autosave_containers property.
232
+	 *
233
+	 * @param array $ids  an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
234
+	 *                    you would send along the id of a metabox container.
235
+	 * @return void
236
+	 * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
237
+	 *                    automatically register the id for the post metabox as a container.
238
+	 */
239
+	protected function _register_autosave_containers($ids)
240
+	{
241
+		$this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
242
+	}
243
+
244
+
245
+	/**
246
+	 * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
247
+	 * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
248
+	 */
249
+	protected function _set_autosave_containers()
250
+	{
251
+		global $wp_meta_boxes;
252
+		$containers = [];
253
+		if (empty($wp_meta_boxes)) {
254
+			return;
255
+		}
256
+		$current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : [];
257
+		foreach ($current_metaboxes as $box_context) {
258
+			foreach ($box_context as $box_details) {
259
+				foreach ($box_details as $box) {
260
+					if (
261
+						is_array($box) && is_array($box['callback'])
262
+						&& (
263
+							$box['callback'][0] instanceof EE_Admin_Page
264
+							|| $box['callback'][0] instanceof EE_Admin_Hooks
265
+						)
266
+					) {
267
+						$containers[] = $box['id'];
268
+					}
269
+				}
270
+			}
271
+		}
272
+		$this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
273
+		// add hidden inputs container
274
+		$this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
275
+	}
276
+
277
+
278
+	protected function _load_autosave_scripts_styles()
279
+	{
280
+		/*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
281 281
         wp_enqueue_script('cpt-autosave');/**/ // todo re-enable when we start doing autosave again in 4.2
282 282
 
283
-        // filter _autosave_containers
284
-        $containers = apply_filters(
285
-            'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
286
-            $this->_autosave_containers,
287
-            $this
288
-        );
289
-        $containers = apply_filters(
290
-            'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
291
-            $containers,
292
-            $this
293
-        );
294
-
295
-        wp_localize_script(
296
-            'event_editor_js',
297
-            'EE_AUTOSAVE_IDS',
298
-            $containers
299
-        ); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
300
-
301
-        $unsaved_data_msg = [
302
-            'eventmsg'     => sprintf(
303
-                wp_strip_all_tags(
304
-                    __(
305
-                        "The changes you made to this %s will be lost if you navigate away from this page.",
306
-                        'event_espresso'
307
-                    )
308
-                ),
309
-                $this->_cpt_object->labels->singular_name
310
-            ),
311
-            'inputChanged' => 0,
312
-        ];
313
-        wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
314
-    }
315
-
316
-
317
-    /**
318
-     * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
319
-     *
320
-     * @return void
321
-     * @throws EE_Error
322
-     * @throws ReflectionException
323
-     */
324
-    protected function _load_page_dependencies()
325
-    {
326
-        // we only add stuff if this is a cpt_route!
327
-        if (! $this->_cpt_route) {
328
-            parent::_load_page_dependencies();
329
-            return;
330
-        }
331
-        // now let's do some automatic filters into the wp_system
332
-        // and we'll check to make sure the CHILD class
333
-        // automatically has the required methods in place.
334
-        // the following filters are for setting all the redirects
335
-        // on DEFAULT WP custom post type actions
336
-        // let's add a hidden input to the post-edit form
337
-        // so we know when we have to trigger our custom redirects!
338
-        // Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
339
-        add_action('edit_form_after_title', [$this, 'cpt_post_form_hidden_input']);
340
-        // inject our Admin page nav tabs...
341
-        // let's make sure the nav tabs are set if they aren't already
342
-        // if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
343
-        add_action('post_edit_form_tag', [$this, 'inject_nav_tabs']);
344
-        // modify the post_updated messages array
345
-        add_action('post_updated_messages', [$this, 'post_update_messages'], 10);
346
-        // add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
347
-        // cpts use the same format for shortlinks as posts!
348
-        add_filter('pre_get_shortlink', [$this, 'add_shortlink_button_to_editor'], 10, 4);
349
-        // This basically allows us to change the title of the "publish" metabox area
350
-        // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
351
-        if (! empty($this->_labels['publishbox'])) {
352
-            $box_label = is_array($this->_labels['publishbox'])
353
-                         && isset($this->_labels['publishbox'][ $this->_req_action ])
354
-                ? $this->_labels['publishbox'][ $this->_req_action ]
355
-                : $this->_labels['publishbox'];
356
-            $this->addMetaBox(
357
-                'submitdiv',
358
-                $box_label,
359
-                'post_submit_meta_box',
360
-                $this->_cpt_routes[ $this->_req_action ],
361
-                'side',
362
-                'core'
363
-            );
364
-        }
365
-        // let's add page_templates metabox if this cpt added support for it.
366
-        if ($this->_supports_page_templates($this->_cpt_object->name)) {
367
-            $this->addMetaBox(
368
-                'page_templates',
369
-                esc_html__('Page Template', 'event_espresso'),
370
-                [$this, 'page_template_meta_box'],
371
-                $this->_cpt_routes[ $this->_req_action ],
372
-                'side',
373
-                'default'
374
-            );
375
-        }
376
-        // this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
377
-        if (method_exists($this, 'extra_permalink_field_buttons')) {
378
-            add_filter('get_sample_permalink_html', [$this, 'extra_permalink_field_buttons'], 10, 4);
379
-        }
380
-        // add preview button
381
-        add_filter('get_sample_permalink_html', [$this, 'preview_button_html'], 5, 4);
382
-        // insert our own post_stati dropdown
383
-        add_action('post_submitbox_misc_actions', [$this, 'custom_post_stati_dropdown'], 10);
384
-        // This allows adding additional information to the publish post submitbox on the wp post edit form
385
-        if (method_exists($this, 'extra_misc_actions_publish_box')) {
386
-            add_action('post_submitbox_misc_actions', [$this, 'extra_misc_actions_publish_box'], 10);
387
-        }
388
-        // This allows for adding additional stuff after the title field on the wp post edit form.
389
-        // This is also before the wp_editor for post description field.
390
-        if (method_exists($this, 'edit_form_after_title')) {
391
-            add_action('edit_form_after_title', [$this, 'edit_form_after_title'], 10);
392
-        }
393
-        /**
394
-         * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
395
-         */
396
-        add_filter('clean_url', [$this, 'switch_core_wp_urls_with_ours'], 10, 3);
397
-        parent::_load_page_dependencies();
398
-        // notice we are ALSO going to load the pagenow hook set for this route
399
-        // (see _before_page_setup for the reset of the pagenow global ).
400
-        // This is for any plugins that are doing things properly
401
-        // and hooking into the load page hook for core wp cpt routes.
402
-        global $pagenow;
403
-        add_action('load-' . $pagenow, [$this, 'modify_current_screen'], 20);
404
-        do_action('load-' . $pagenow);
405
-        add_action('admin_enqueue_scripts', [$this, 'setup_autosave_hooks'], 30);
406
-        // we route REALLY early.
407
-        try {
408
-            $this->_route_admin_request();
409
-        } catch (EE_Error $e) {
410
-            $e->get_error();
411
-        }
412
-    }
413
-
414
-
415
-    /**
416
-     * Since we don't want users going to default core wp routes, this will check any wp urls run through the
417
-     * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
418
-     * route instead.
419
-     *
420
-     * @param string $good_protocol_url The escaped url.
421
-     * @param string $original_url      The original url.
422
-     * @param string $_context          The context sent to the esc_url method.
423
-     * @return string possibly a new url for our route.
424
-     */
425
-    public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
426
-    {
427
-        $routes_to_match = [
428
-            0 => [
429
-                'edit.php?post_type=espresso_attendees',
430
-                'admin.php?page=espresso_registrations&action=contact_list',
431
-            ],
432
-            1 => [
433
-                'edit.php?post_type=' . $this->_cpt_object->name,
434
-                'admin.php?page=' . $this->_cpt_object->name,
435
-            ],
436
-        ];
437
-        foreach ($routes_to_match as $route_matches) {
438
-            if (strpos($good_protocol_url, $route_matches[0]) !== false) {
439
-                return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
440
-            }
441
-        }
442
-        return $good_protocol_url;
443
-    }
444
-
445
-
446
-    /**
447
-     * Determine whether the current cpt supports page templates or not.
448
-     *
449
-     * @param string $cpt_name The cpt slug we're checking on.
450
-     * @return bool True supported, false not.
451
-     * @throws InvalidArgumentException
452
-     * @throws InvalidDataTypeException
453
-     * @throws InvalidInterfaceException
454
-     * @since %VER%
455
-     */
456
-    private function _supports_page_templates($cpt_name)
457
-    {
458
-        /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
459
-        $custom_post_types = $this->loader->getShared(
460
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
461
-        );
462
-        $cpt_args          = $custom_post_types->getDefinitions();
463
-        $cpt_args          = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : [];
464
-        $cpt_has_support   = ! empty($cpt_args['page_templates']);
465
-
466
-        // if the installed version of WP is > 4.7 we do some additional checks.
467
-        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
468
-            $post_templates = wp_get_theme()->get_post_templates();
469
-            // if there are $post_templates for this cpt, then we return false for this method because
470
-            // that means we aren't going to load our page template manager and leave that up to the native
471
-            // cpt template manager.
472
-            $cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
473
-        }
474
-
475
-        return $cpt_has_support;
476
-    }
477
-
478
-
479
-    /**
480
-     * Callback for the page_templates metabox selector.
481
-     *
482
-     * @return void
483
-     * @since %VER%
484
-     */
485
-    public function page_template_meta_box()
486
-    {
487
-        global $post;
488
-        $template = '';
489
-
490
-        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
491
-            $page_template_count = count(get_page_templates());
492
-        } else {
493
-            $page_template_count = count(get_page_templates($post));
494
-        }
495
-
496
-        if ($page_template_count) {
497
-            $page_template = get_post_meta($post->ID, '_wp_page_template', true);
498
-            $template      = ! empty($page_template) ? $page_template : '';
499
-        }
500
-        ?>
283
+		// filter _autosave_containers
284
+		$containers = apply_filters(
285
+			'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
286
+			$this->_autosave_containers,
287
+			$this
288
+		);
289
+		$containers = apply_filters(
290
+			'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
291
+			$containers,
292
+			$this
293
+		);
294
+
295
+		wp_localize_script(
296
+			'event_editor_js',
297
+			'EE_AUTOSAVE_IDS',
298
+			$containers
299
+		); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
300
+
301
+		$unsaved_data_msg = [
302
+			'eventmsg'     => sprintf(
303
+				wp_strip_all_tags(
304
+					__(
305
+						"The changes you made to this %s will be lost if you navigate away from this page.",
306
+						'event_espresso'
307
+					)
308
+				),
309
+				$this->_cpt_object->labels->singular_name
310
+			),
311
+			'inputChanged' => 0,
312
+		];
313
+		wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
314
+	}
315
+
316
+
317
+	/**
318
+	 * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
319
+	 *
320
+	 * @return void
321
+	 * @throws EE_Error
322
+	 * @throws ReflectionException
323
+	 */
324
+	protected function _load_page_dependencies()
325
+	{
326
+		// we only add stuff if this is a cpt_route!
327
+		if (! $this->_cpt_route) {
328
+			parent::_load_page_dependencies();
329
+			return;
330
+		}
331
+		// now let's do some automatic filters into the wp_system
332
+		// and we'll check to make sure the CHILD class
333
+		// automatically has the required methods in place.
334
+		// the following filters are for setting all the redirects
335
+		// on DEFAULT WP custom post type actions
336
+		// let's add a hidden input to the post-edit form
337
+		// so we know when we have to trigger our custom redirects!
338
+		// Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
339
+		add_action('edit_form_after_title', [$this, 'cpt_post_form_hidden_input']);
340
+		// inject our Admin page nav tabs...
341
+		// let's make sure the nav tabs are set if they aren't already
342
+		// if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
343
+		add_action('post_edit_form_tag', [$this, 'inject_nav_tabs']);
344
+		// modify the post_updated messages array
345
+		add_action('post_updated_messages', [$this, 'post_update_messages'], 10);
346
+		// add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
347
+		// cpts use the same format for shortlinks as posts!
348
+		add_filter('pre_get_shortlink', [$this, 'add_shortlink_button_to_editor'], 10, 4);
349
+		// This basically allows us to change the title of the "publish" metabox area
350
+		// on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
351
+		if (! empty($this->_labels['publishbox'])) {
352
+			$box_label = is_array($this->_labels['publishbox'])
353
+						 && isset($this->_labels['publishbox'][ $this->_req_action ])
354
+				? $this->_labels['publishbox'][ $this->_req_action ]
355
+				: $this->_labels['publishbox'];
356
+			$this->addMetaBox(
357
+				'submitdiv',
358
+				$box_label,
359
+				'post_submit_meta_box',
360
+				$this->_cpt_routes[ $this->_req_action ],
361
+				'side',
362
+				'core'
363
+			);
364
+		}
365
+		// let's add page_templates metabox if this cpt added support for it.
366
+		if ($this->_supports_page_templates($this->_cpt_object->name)) {
367
+			$this->addMetaBox(
368
+				'page_templates',
369
+				esc_html__('Page Template', 'event_espresso'),
370
+				[$this, 'page_template_meta_box'],
371
+				$this->_cpt_routes[ $this->_req_action ],
372
+				'side',
373
+				'default'
374
+			);
375
+		}
376
+		// this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
377
+		if (method_exists($this, 'extra_permalink_field_buttons')) {
378
+			add_filter('get_sample_permalink_html', [$this, 'extra_permalink_field_buttons'], 10, 4);
379
+		}
380
+		// add preview button
381
+		add_filter('get_sample_permalink_html', [$this, 'preview_button_html'], 5, 4);
382
+		// insert our own post_stati dropdown
383
+		add_action('post_submitbox_misc_actions', [$this, 'custom_post_stati_dropdown'], 10);
384
+		// This allows adding additional information to the publish post submitbox on the wp post edit form
385
+		if (method_exists($this, 'extra_misc_actions_publish_box')) {
386
+			add_action('post_submitbox_misc_actions', [$this, 'extra_misc_actions_publish_box'], 10);
387
+		}
388
+		// This allows for adding additional stuff after the title field on the wp post edit form.
389
+		// This is also before the wp_editor for post description field.
390
+		if (method_exists($this, 'edit_form_after_title')) {
391
+			add_action('edit_form_after_title', [$this, 'edit_form_after_title'], 10);
392
+		}
393
+		/**
394
+		 * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
395
+		 */
396
+		add_filter('clean_url', [$this, 'switch_core_wp_urls_with_ours'], 10, 3);
397
+		parent::_load_page_dependencies();
398
+		// notice we are ALSO going to load the pagenow hook set for this route
399
+		// (see _before_page_setup for the reset of the pagenow global ).
400
+		// This is for any plugins that are doing things properly
401
+		// and hooking into the load page hook for core wp cpt routes.
402
+		global $pagenow;
403
+		add_action('load-' . $pagenow, [$this, 'modify_current_screen'], 20);
404
+		do_action('load-' . $pagenow);
405
+		add_action('admin_enqueue_scripts', [$this, 'setup_autosave_hooks'], 30);
406
+		// we route REALLY early.
407
+		try {
408
+			$this->_route_admin_request();
409
+		} catch (EE_Error $e) {
410
+			$e->get_error();
411
+		}
412
+	}
413
+
414
+
415
+	/**
416
+	 * Since we don't want users going to default core wp routes, this will check any wp urls run through the
417
+	 * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
418
+	 * route instead.
419
+	 *
420
+	 * @param string $good_protocol_url The escaped url.
421
+	 * @param string $original_url      The original url.
422
+	 * @param string $_context          The context sent to the esc_url method.
423
+	 * @return string possibly a new url for our route.
424
+	 */
425
+	public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
426
+	{
427
+		$routes_to_match = [
428
+			0 => [
429
+				'edit.php?post_type=espresso_attendees',
430
+				'admin.php?page=espresso_registrations&action=contact_list',
431
+			],
432
+			1 => [
433
+				'edit.php?post_type=' . $this->_cpt_object->name,
434
+				'admin.php?page=' . $this->_cpt_object->name,
435
+			],
436
+		];
437
+		foreach ($routes_to_match as $route_matches) {
438
+			if (strpos($good_protocol_url, $route_matches[0]) !== false) {
439
+				return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
440
+			}
441
+		}
442
+		return $good_protocol_url;
443
+	}
444
+
445
+
446
+	/**
447
+	 * Determine whether the current cpt supports page templates or not.
448
+	 *
449
+	 * @param string $cpt_name The cpt slug we're checking on.
450
+	 * @return bool True supported, false not.
451
+	 * @throws InvalidArgumentException
452
+	 * @throws InvalidDataTypeException
453
+	 * @throws InvalidInterfaceException
454
+	 * @since %VER%
455
+	 */
456
+	private function _supports_page_templates($cpt_name)
457
+	{
458
+		/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
459
+		$custom_post_types = $this->loader->getShared(
460
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
461
+		);
462
+		$cpt_args          = $custom_post_types->getDefinitions();
463
+		$cpt_args          = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : [];
464
+		$cpt_has_support   = ! empty($cpt_args['page_templates']);
465
+
466
+		// if the installed version of WP is > 4.7 we do some additional checks.
467
+		if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
468
+			$post_templates = wp_get_theme()->get_post_templates();
469
+			// if there are $post_templates for this cpt, then we return false for this method because
470
+			// that means we aren't going to load our page template manager and leave that up to the native
471
+			// cpt template manager.
472
+			$cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
473
+		}
474
+
475
+		return $cpt_has_support;
476
+	}
477
+
478
+
479
+	/**
480
+	 * Callback for the page_templates metabox selector.
481
+	 *
482
+	 * @return void
483
+	 * @since %VER%
484
+	 */
485
+	public function page_template_meta_box()
486
+	{
487
+		global $post;
488
+		$template = '';
489
+
490
+		if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
491
+			$page_template_count = count(get_page_templates());
492
+		} else {
493
+			$page_template_count = count(get_page_templates($post));
494
+		}
495
+
496
+		if ($page_template_count) {
497
+			$page_template = get_post_meta($post->ID, '_wp_page_template', true);
498
+			$template      = ! empty($page_template) ? $page_template : '';
499
+		}
500
+		?>
501 501
         <p><strong><?php esc_html_e('Template', 'event_espresso') ?></strong></p>
502 502
         <label class="screen-reader-text" for="page_template"><?php esc_html_e(
503
-            'Page Template',
504
-            'event_espresso'
505
-        ) ?></label>
503
+			'Page Template',
504
+			'event_espresso'
505
+		) ?></label>
506 506
         <select
507 507
             name="page_template" id="page_template"
508 508
         >
@@ -510,474 +510,474 @@  discard block
 block discarded – undo
510 510
             <?php page_template_dropdown($template); ?>
511 511
         </select>
512 512
         <?php
513
-    }
514
-
515
-
516
-    /**
517
-     * if this post is a draft or scheduled post then we provide a preview button for user to click
518
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
519
-     *
520
-     * @param string $return    the current html
521
-     * @param int    $id        the post id for the page
522
-     * @param string $new_title What the title is
523
-     * @param string $new_slug  what the slug is
524
-     * @return string            The new html string for the permalink area
525
-     */
526
-    public function preview_button_html($return, $id, $new_title, $new_slug)
527
-    {
528
-        $post = get_post($id);
529
-        if ('publish' !== get_post_status($post)) {
530
-            $return .= '<span_id="view-post-btn"><a target="_blank" href="'
531
-                       . get_preview_post_link($id)
532
-                       . '" class="button button--secondary">'
533
-                       . esc_html__('Preview', 'event_espresso')
534
-                       . '</a></span>'
535
-                       . "\n";
536
-        }
537
-        return $return;
538
-    }
539
-
540
-
541
-    /**
542
-     * add our custom post stati dropdown on the wp post page for this cpt
543
-     *
544
-     * @return void
545
-     */
546
-    public function custom_post_stati_dropdown()
547
-    {
548
-
549
-        $statuses         = $this->_cpt_model_obj->get_custom_post_statuses();
550
-        $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
551
-            ? $statuses[ $this->_cpt_model_obj->status() ]
552
-            : '';
553
-        $template_args    = [
554
-            'cur_status'            => $this->_cpt_model_obj->status(),
555
-            'statuses'              => $statuses,
556
-            'cur_status_label'      => $cur_status_label,
557
-            'localized_status_save' => sprintf(esc_html__('Save %s', 'event_espresso'), $cur_status_label),
558
-        ];
559
-        // we'll add a trash post status (WP doesn't add one for some reason)
560
-        if ($this->_cpt_model_obj->status() === 'trash') {
561
-            $template_args['cur_status_label'] = esc_html__('Trashed', 'event_espresso');
562
-            $statuses['trash']                 = esc_html__('Trashed', 'event_espresso');
563
-            $template_args['statuses']         = $statuses;
564
-        }
565
-
566
-        $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
567
-        EEH_Template::display_template($template, $template_args);
568
-    }
569
-
570
-
571
-    public function setup_autosave_hooks()
572
-    {
573
-        $this->_set_autosave_containers();
574
-        $this->_load_autosave_scripts_styles();
575
-    }
576
-
577
-
578
-    /**
579
-     * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a post object (available
580
-     * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
581
-     * for the nonce in here, but then this method looks for two things:
582
-     * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
583
-     * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
584
-     * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
585
-     * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
586
-     * template args.
587
-     *    1. $template_args['error'] = IF there is an error you can add the message in here.
588
-     *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
589
-     *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
590
-     *    $this->_template_args['data']['items'] = array(
591
-     *        'event-datetime-ids' => '1,2,3';
592
-     *    );
593
-     *    Keep in mind the following things:
594
-     *    - "where" index is for the input with the id as that string.
595
-     *    - "what" index is what will be used for the value of that input.
596
-     *
597
-     * @return void
598
-     * @throws EE_Error
599
-     */
600
-    public function do_extra_autosave_stuff()
601
-    {
602
-        // next let's check for the autosave nonce (we'll use _verify_nonce )
603
-        $nonce = $this->request->getRequestParam('autosavenonce');
604
-        $this->_verify_nonce($nonce, 'autosave');
605
-        // make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
606
-        if (! defined('DOING_AUTOSAVE')) {
607
-            define('DOING_AUTOSAVE', true);
608
-        }
609
-        // if we made it here then the nonce checked out.  Let's run our methods and actions
610
-        $autosave = "_ee_autosave_{$this->_current_view}";
611
-        if (method_exists($this, $autosave)) {
612
-            $this->$autosave();
613
-        } else {
614
-            $this->_template_args['success'] = true;
615
-        }
616
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
617
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
618
-        // now let's return json
619
-        $this->_return_json();
620
-    }
621
-
622
-
623
-    /**
624
-     * This takes care of setting up default routes and pages that utilize the core WP admin pages.
625
-     * Child classes can override the defaults (in cases for adding metaboxes etc.)
626
-     * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
627
-     *
628
-     * @return void
629
-     * @throws EE_Error
630
-     * @throws ReflectionException
631
-     */
632
-    protected function _extend_page_config_for_cpt()
633
-    {
634
-        // before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
635
-        if ($this->raw_req_page !== $this->page_slug) {
636
-            return;
637
-        }
638
-        // set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
639
-        if (! empty($this->_cpt_object)) {
640
-            $this->_page_routes = array_merge(
641
-                [
642
-                    'create_new' => '_create_new_cpt_item',
643
-                    'edit'       => '_edit_cpt_item',
644
-                ],
645
-                $this->_page_routes
646
-            );
647
-            $this->_page_config = array_merge(
648
-                [
649
-                    'create_new' => [
650
-                        'nav'           => [
651
-                            'label' => $this->_cpt_object->labels->add_new_item,
652
-                            'order' => 5,
653
-                        ],
654
-                        'require_nonce' => false,
655
-                    ],
656
-                    'edit'       => [
657
-                        'nav'           => [
658
-                            'label'      => $this->_cpt_object->labels->edit_item,
659
-                            'order'      => 5,
660
-                            'persistent' => false,
661
-                            'url'        => '',
662
-                        ],
663
-                        'require_nonce' => false,
664
-                    ],
665
-                ],
666
-                $this->_page_config
667
-            );
668
-        }
669
-        // load the next section only if this is a matching cpt route as set in the cpt routes array.
670
-        if (! isset($this->_cpt_routes[ $this->_req_action ])) {
671
-            return;
672
-        }
673
-        $this->_cpt_route = true;
674
-        // $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]);
675
-        // add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
676
-        if (empty($this->_cpt_object)) {
677
-            $msg = sprintf(
678
-                esc_html__(
679
-                    'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).',
680
-                    'event_espresso'
681
-                ),
682
-                $this->page_slug,
683
-                $this->_req_action,
684
-                get_class($this)
685
-            );
686
-            throw new EE_Error($msg);
687
-        }
688
-        $this->_set_model_object($this->request->getRequestParam('post'));
689
-    }
690
-
691
-
692
-    /**
693
-     * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
694
-     *
695
-     * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
696
-     * @param bool   $ignore_route_check
697
-     * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
698
-     * @throws EE_Error
699
-     * @throws InvalidArgumentException
700
-     * @throws InvalidDataTypeException
701
-     * @throws InvalidInterfaceException
702
-     * @throws ReflectionException
703
-     */
704
-    protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
705
-    {
706
-        $model = null;
707
-        if (
708
-            empty($this->_cpt_model_names)
709
-            || (
710
-                ! $ignore_route_check
711
-                && ! isset($this->_cpt_routes[ $this->_req_action ])
712
-            )
713
-            || (
714
-                $this->_cpt_model_obj instanceof EE_CPT_Base
715
-                && $this->_cpt_model_obj->ID() === $id
716
-            )
717
-        ) {
718
-            // get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
719
-            return;
720
-        }
721
-        // if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
722
-        if ($ignore_route_check) {
723
-            $post_type = get_post_type($id);
724
-            /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
725
-            $custom_post_types = $this->loader->getShared(
726
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
727
-            );
728
-            $model_names       = $custom_post_types->getCustomPostTypeModelNames($post_type);
729
-            if (isset($model_names[ $post_type ])) {
730
-                $model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
731
-            }
732
-        } else {
733
-            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
734
-        }
735
-        if ($model instanceof EEM_Base) {
736
-            $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
737
-        }
738
-        do_action(
739
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
740
-            $this->_cpt_model_obj,
741
-            $req_type
742
-        );
743
-    }
744
-
745
-
746
-    /**
747
-     * admin_init_global
748
-     * This runs all the code that we want executed within the WP admin_init hook.
749
-     * This method executes for ALL EE Admin pages.
750
-     *
751
-     * @return void
752
-     */
753
-    public function admin_init_global()
754
-    {
755
-        $post = $this->request->getRequestParam('post');
756
-        // its possible this is a new save so let's catch that instead
757
-        $post           = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
758
-        $post_type      = $post instanceof WP_Post ? $post->post_type : false;
759
-        $current_route  = isset($this->_req_data['current_route'])
760
-            ? $this->_req_data['current_route']
761
-            : 'shouldneverwork';
762
-        $route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
763
-            ? $this->_cpt_routes[ $current_route ]
764
-            : '';
765
-        add_filter('get_delete_post_link', [$this, 'modify_delete_post_link'], 10, 3);
766
-        add_filter('get_edit_post_link', [$this, 'modify_edit_post_link'], 10, 3);
767
-        if ($post_type === $route_to_check) {
768
-            add_filter('redirect_post_location', [$this, 'cpt_post_location_redirect'], 10, 2);
769
-        }
770
-        // now let's filter redirect if we're on a revision page and the revision is for an event CPT.
771
-        $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
772
-        if (! empty($revision)) {
773
-            $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
774
-            // doing a restore?
775
-            if (! empty($action) && $action === 'restore') {
776
-                // get post for revision
777
-                $rev_post   = get_post($revision);
778
-                $rev_parent = get_post($rev_post->post_parent);
779
-                // only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
780
-                if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
781
-                    add_filter('wp_redirect', [$this, 'revision_redirect'], 10, 2);
782
-                    // restores of revisions
783
-                    add_action('wp_restore_post_revision', [$this, 'restore_revision'], 10, 2);
784
-                }
785
-            }
786
-        }
787
-        // NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
788
-        if ($post_type && $post_type === $route_to_check) {
789
-            // $post_id, $post
790
-            add_action('save_post', [$this, 'insert_update'], 10, 3);
791
-            // $post_id
792
-            add_action('trashed_post', [$this, 'before_trash_cpt_item'], 10);
793
-            add_action('trashed_post', [$this, 'dont_permanently_delete_ee_cpts'], 10);
794
-            add_action('untrashed_post', [$this, 'before_restore_cpt_item'], 10);
795
-            add_action('after_delete_post', [$this, 'before_delete_cpt_item'], 10);
796
-        }
797
-    }
798
-
799
-
800
-    /**
801
-     * Callback for the WordPress trashed_post hook.
802
-     * Execute some basic checks before calling the trash_cpt_item declared in the child class.
803
-     *
804
-     * @param int $post_id
805
-     * @throws EE_Error
806
-     * @throws ReflectionException
807
-     */
808
-    public function before_trash_cpt_item($post_id)
809
-    {
810
-        $this->_set_model_object($post_id, true, 'trash');
811
-        // if our cpt object isn't existent then get out immediately.
812
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
813
-            return;
814
-        }
815
-        $this->trash_cpt_item($post_id);
816
-    }
817
-
818
-
819
-    /**
820
-     * Callback for the WordPress untrashed_post hook.
821
-     * Execute some basic checks before calling the restore_cpt_method in the child class.
822
-     *
823
-     * @param $post_id
824
-     * @throws EE_Error
825
-     * @throws ReflectionException
826
-     */
827
-    public function before_restore_cpt_item($post_id)
828
-    {
829
-        $this->_set_model_object($post_id, true, 'restore');
830
-        // if our cpt object isn't existent then get out immediately.
831
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
832
-            return;
833
-        }
834
-        $this->restore_cpt_item($post_id);
835
-    }
836
-
837
-
838
-    /**
839
-     * Callback for the WordPress after_delete_post hook.
840
-     * Execute some basic checks before calling the delete_cpt_item method in the child class.
841
-     *
842
-     * @param $post_id
843
-     * @throws EE_Error
844
-     * @throws ReflectionException
845
-     */
846
-    public function before_delete_cpt_item($post_id)
847
-    {
848
-        $this->_set_model_object($post_id, true, 'delete');
849
-        // if our cpt object isn't existent then get out immediately.
850
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
851
-            return;
852
-        }
853
-        $this->delete_cpt_item($post_id);
854
-    }
855
-
856
-
857
-    /**
858
-     * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
859
-     * accordingly.
860
-     *
861
-     * @return void
862
-     * @throws EE_Error
863
-     * @throws ReflectionException
864
-     */
865
-    public function verify_cpt_object()
866
-    {
867
-        $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
868
-        // verify event object
869
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
870
-            throw new EE_Error(
871
-                sprintf(
872
-                    esc_html__(
873
-                        'Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
874
-                        'event_espresso'
875
-                    ),
876
-                    $label
877
-                )
878
-            );
879
-        }
880
-        // if auto-draft then throw an error
881
-        if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
882
-            EE_Error::overwrite_errors();
883
-            EE_Error::add_error(
884
-                sprintf(
885
-                    esc_html__(
886
-                        'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.',
887
-                        'event_espresso'
888
-                    ),
889
-                    $label
890
-                ),
891
-                __FILE__,
892
-                __FUNCTION__,
893
-                __LINE__
894
-            );
895
-        }
896
-    }
897
-
898
-
899
-    /**
900
-     * admin_footer_scripts_global
901
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
902
-     * will apply on ALL EE_Admin pages.
903
-     *
904
-     * @return void
905
-     */
906
-    public function admin_footer_scripts_global()
907
-    {
908
-        $this->_add_admin_page_ajax_loading_img();
909
-        $this->_add_admin_page_overlay();
910
-    }
911
-
912
-
913
-    /**
914
-     * add in any global scripts for cpt routes
915
-     *
916
-     * @return void
917
-     * @throws EE_Error
918
-     */
919
-    public function load_global_scripts_styles()
920
-    {
921
-        parent::load_global_scripts_styles();
922
-        if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
923
-            // setup custom post status object for localize script but only if we've got a cpt object
924
-            $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
925
-            if (! empty($statuses)) {
926
-                // get ALL statuses!
927
-                $statuses = $this->_cpt_model_obj->get_all_post_statuses();
928
-                // setup object
929
-                $ee_cpt_statuses = [];
930
-                foreach ($statuses as $status => $label) {
931
-                    $ee_cpt_statuses[ $status ] = [
932
-                        'label'      => $label,
933
-                        'save_label' => sprintf(
934
-                            wp_strip_all_tags(__('Save as %s', 'event_espresso')),
935
-                            $label
936
-                        ),
937
-                    ];
938
-                }
939
-                wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
940
-            }
941
-        }
942
-    }
943
-
944
-
945
-    /**
946
-     * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
947
-     * insert/updates
948
-     *
949
-     * @param int     $post_id ID of post being updated
950
-     * @param WP_Post $post    Post object from WP
951
-     * @param bool    $update  Whether this is an update or a new save.
952
-     * @return void
953
-     * @throws EE_Error
954
-     * @throws ReflectionException
955
-     */
956
-    public function insert_update($post_id, $post, $update)
957
-    {
958
-        // make sure that if this is a revision OR trash action that we don't do any updates!
959
-        if (
960
-            isset($this->_req_data['action'])
961
-            && (
962
-                $this->_req_data['action'] === 'restore'
963
-                || $this->_req_data['action'] === 'trash'
964
-            )
965
-        ) {
966
-            return;
967
-        }
968
-        $this->_set_model_object($post_id, true, 'insert_update');
969
-        // if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
970
-        if (
971
-            $update
972
-            && (
973
-                ! $this->_cpt_model_obj instanceof EE_CPT_Base
974
-                || $this->_cpt_model_obj->ID() !== $post_id
975
-            )
976
-        ) {
977
-            return;
978
-        }
979
-        // check for autosave and update our req_data property accordingly.
980
-        /*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
513
+	}
514
+
515
+
516
+	/**
517
+	 * if this post is a draft or scheduled post then we provide a preview button for user to click
518
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
519
+	 *
520
+	 * @param string $return    the current html
521
+	 * @param int    $id        the post id for the page
522
+	 * @param string $new_title What the title is
523
+	 * @param string $new_slug  what the slug is
524
+	 * @return string            The new html string for the permalink area
525
+	 */
526
+	public function preview_button_html($return, $id, $new_title, $new_slug)
527
+	{
528
+		$post = get_post($id);
529
+		if ('publish' !== get_post_status($post)) {
530
+			$return .= '<span_id="view-post-btn"><a target="_blank" href="'
531
+					   . get_preview_post_link($id)
532
+					   . '" class="button button--secondary">'
533
+					   . esc_html__('Preview', 'event_espresso')
534
+					   . '</a></span>'
535
+					   . "\n";
536
+		}
537
+		return $return;
538
+	}
539
+
540
+
541
+	/**
542
+	 * add our custom post stati dropdown on the wp post page for this cpt
543
+	 *
544
+	 * @return void
545
+	 */
546
+	public function custom_post_stati_dropdown()
547
+	{
548
+
549
+		$statuses         = $this->_cpt_model_obj->get_custom_post_statuses();
550
+		$cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
551
+			? $statuses[ $this->_cpt_model_obj->status() ]
552
+			: '';
553
+		$template_args    = [
554
+			'cur_status'            => $this->_cpt_model_obj->status(),
555
+			'statuses'              => $statuses,
556
+			'cur_status_label'      => $cur_status_label,
557
+			'localized_status_save' => sprintf(esc_html__('Save %s', 'event_espresso'), $cur_status_label),
558
+		];
559
+		// we'll add a trash post status (WP doesn't add one for some reason)
560
+		if ($this->_cpt_model_obj->status() === 'trash') {
561
+			$template_args['cur_status_label'] = esc_html__('Trashed', 'event_espresso');
562
+			$statuses['trash']                 = esc_html__('Trashed', 'event_espresso');
563
+			$template_args['statuses']         = $statuses;
564
+		}
565
+
566
+		$template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
567
+		EEH_Template::display_template($template, $template_args);
568
+	}
569
+
570
+
571
+	public function setup_autosave_hooks()
572
+	{
573
+		$this->_set_autosave_containers();
574
+		$this->_load_autosave_scripts_styles();
575
+	}
576
+
577
+
578
+	/**
579
+	 * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a post object (available
580
+	 * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
581
+	 * for the nonce in here, but then this method looks for two things:
582
+	 * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
583
+	 * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
584
+	 * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
585
+	 * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
586
+	 * template args.
587
+	 *    1. $template_args['error'] = IF there is an error you can add the message in here.
588
+	 *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
589
+	 *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
590
+	 *    $this->_template_args['data']['items'] = array(
591
+	 *        'event-datetime-ids' => '1,2,3';
592
+	 *    );
593
+	 *    Keep in mind the following things:
594
+	 *    - "where" index is for the input with the id as that string.
595
+	 *    - "what" index is what will be used for the value of that input.
596
+	 *
597
+	 * @return void
598
+	 * @throws EE_Error
599
+	 */
600
+	public function do_extra_autosave_stuff()
601
+	{
602
+		// next let's check for the autosave nonce (we'll use _verify_nonce )
603
+		$nonce = $this->request->getRequestParam('autosavenonce');
604
+		$this->_verify_nonce($nonce, 'autosave');
605
+		// make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
606
+		if (! defined('DOING_AUTOSAVE')) {
607
+			define('DOING_AUTOSAVE', true);
608
+		}
609
+		// if we made it here then the nonce checked out.  Let's run our methods and actions
610
+		$autosave = "_ee_autosave_{$this->_current_view}";
611
+		if (method_exists($this, $autosave)) {
612
+			$this->$autosave();
613
+		} else {
614
+			$this->_template_args['success'] = true;
615
+		}
616
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
617
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
618
+		// now let's return json
619
+		$this->_return_json();
620
+	}
621
+
622
+
623
+	/**
624
+	 * This takes care of setting up default routes and pages that utilize the core WP admin pages.
625
+	 * Child classes can override the defaults (in cases for adding metaboxes etc.)
626
+	 * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
627
+	 *
628
+	 * @return void
629
+	 * @throws EE_Error
630
+	 * @throws ReflectionException
631
+	 */
632
+	protected function _extend_page_config_for_cpt()
633
+	{
634
+		// before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
635
+		if ($this->raw_req_page !== $this->page_slug) {
636
+			return;
637
+		}
638
+		// set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
639
+		if (! empty($this->_cpt_object)) {
640
+			$this->_page_routes = array_merge(
641
+				[
642
+					'create_new' => '_create_new_cpt_item',
643
+					'edit'       => '_edit_cpt_item',
644
+				],
645
+				$this->_page_routes
646
+			);
647
+			$this->_page_config = array_merge(
648
+				[
649
+					'create_new' => [
650
+						'nav'           => [
651
+							'label' => $this->_cpt_object->labels->add_new_item,
652
+							'order' => 5,
653
+						],
654
+						'require_nonce' => false,
655
+					],
656
+					'edit'       => [
657
+						'nav'           => [
658
+							'label'      => $this->_cpt_object->labels->edit_item,
659
+							'order'      => 5,
660
+							'persistent' => false,
661
+							'url'        => '',
662
+						],
663
+						'require_nonce' => false,
664
+					],
665
+				],
666
+				$this->_page_config
667
+			);
668
+		}
669
+		// load the next section only if this is a matching cpt route as set in the cpt routes array.
670
+		if (! isset($this->_cpt_routes[ $this->_req_action ])) {
671
+			return;
672
+		}
673
+		$this->_cpt_route = true;
674
+		// $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]);
675
+		// add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
676
+		if (empty($this->_cpt_object)) {
677
+			$msg = sprintf(
678
+				esc_html__(
679
+					'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).',
680
+					'event_espresso'
681
+				),
682
+				$this->page_slug,
683
+				$this->_req_action,
684
+				get_class($this)
685
+			);
686
+			throw new EE_Error($msg);
687
+		}
688
+		$this->_set_model_object($this->request->getRequestParam('post'));
689
+	}
690
+
691
+
692
+	/**
693
+	 * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
694
+	 *
695
+	 * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
696
+	 * @param bool   $ignore_route_check
697
+	 * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
698
+	 * @throws EE_Error
699
+	 * @throws InvalidArgumentException
700
+	 * @throws InvalidDataTypeException
701
+	 * @throws InvalidInterfaceException
702
+	 * @throws ReflectionException
703
+	 */
704
+	protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
705
+	{
706
+		$model = null;
707
+		if (
708
+			empty($this->_cpt_model_names)
709
+			|| (
710
+				! $ignore_route_check
711
+				&& ! isset($this->_cpt_routes[ $this->_req_action ])
712
+			)
713
+			|| (
714
+				$this->_cpt_model_obj instanceof EE_CPT_Base
715
+				&& $this->_cpt_model_obj->ID() === $id
716
+			)
717
+		) {
718
+			// get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
719
+			return;
720
+		}
721
+		// if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
722
+		if ($ignore_route_check) {
723
+			$post_type = get_post_type($id);
724
+			/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
725
+			$custom_post_types = $this->loader->getShared(
726
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
727
+			);
728
+			$model_names       = $custom_post_types->getCustomPostTypeModelNames($post_type);
729
+			if (isset($model_names[ $post_type ])) {
730
+				$model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
731
+			}
732
+		} else {
733
+			$model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
734
+		}
735
+		if ($model instanceof EEM_Base) {
736
+			$this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
737
+		}
738
+		do_action(
739
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
740
+			$this->_cpt_model_obj,
741
+			$req_type
742
+		);
743
+	}
744
+
745
+
746
+	/**
747
+	 * admin_init_global
748
+	 * This runs all the code that we want executed within the WP admin_init hook.
749
+	 * This method executes for ALL EE Admin pages.
750
+	 *
751
+	 * @return void
752
+	 */
753
+	public function admin_init_global()
754
+	{
755
+		$post = $this->request->getRequestParam('post');
756
+		// its possible this is a new save so let's catch that instead
757
+		$post           = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
758
+		$post_type      = $post instanceof WP_Post ? $post->post_type : false;
759
+		$current_route  = isset($this->_req_data['current_route'])
760
+			? $this->_req_data['current_route']
761
+			: 'shouldneverwork';
762
+		$route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
763
+			? $this->_cpt_routes[ $current_route ]
764
+			: '';
765
+		add_filter('get_delete_post_link', [$this, 'modify_delete_post_link'], 10, 3);
766
+		add_filter('get_edit_post_link', [$this, 'modify_edit_post_link'], 10, 3);
767
+		if ($post_type === $route_to_check) {
768
+			add_filter('redirect_post_location', [$this, 'cpt_post_location_redirect'], 10, 2);
769
+		}
770
+		// now let's filter redirect if we're on a revision page and the revision is for an event CPT.
771
+		$revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
772
+		if (! empty($revision)) {
773
+			$action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
774
+			// doing a restore?
775
+			if (! empty($action) && $action === 'restore') {
776
+				// get post for revision
777
+				$rev_post   = get_post($revision);
778
+				$rev_parent = get_post($rev_post->post_parent);
779
+				// only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
780
+				if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
781
+					add_filter('wp_redirect', [$this, 'revision_redirect'], 10, 2);
782
+					// restores of revisions
783
+					add_action('wp_restore_post_revision', [$this, 'restore_revision'], 10, 2);
784
+				}
785
+			}
786
+		}
787
+		// NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
788
+		if ($post_type && $post_type === $route_to_check) {
789
+			// $post_id, $post
790
+			add_action('save_post', [$this, 'insert_update'], 10, 3);
791
+			// $post_id
792
+			add_action('trashed_post', [$this, 'before_trash_cpt_item'], 10);
793
+			add_action('trashed_post', [$this, 'dont_permanently_delete_ee_cpts'], 10);
794
+			add_action('untrashed_post', [$this, 'before_restore_cpt_item'], 10);
795
+			add_action('after_delete_post', [$this, 'before_delete_cpt_item'], 10);
796
+		}
797
+	}
798
+
799
+
800
+	/**
801
+	 * Callback for the WordPress trashed_post hook.
802
+	 * Execute some basic checks before calling the trash_cpt_item declared in the child class.
803
+	 *
804
+	 * @param int $post_id
805
+	 * @throws EE_Error
806
+	 * @throws ReflectionException
807
+	 */
808
+	public function before_trash_cpt_item($post_id)
809
+	{
810
+		$this->_set_model_object($post_id, true, 'trash');
811
+		// if our cpt object isn't existent then get out immediately.
812
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
813
+			return;
814
+		}
815
+		$this->trash_cpt_item($post_id);
816
+	}
817
+
818
+
819
+	/**
820
+	 * Callback for the WordPress untrashed_post hook.
821
+	 * Execute some basic checks before calling the restore_cpt_method in the child class.
822
+	 *
823
+	 * @param $post_id
824
+	 * @throws EE_Error
825
+	 * @throws ReflectionException
826
+	 */
827
+	public function before_restore_cpt_item($post_id)
828
+	{
829
+		$this->_set_model_object($post_id, true, 'restore');
830
+		// if our cpt object isn't existent then get out immediately.
831
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
832
+			return;
833
+		}
834
+		$this->restore_cpt_item($post_id);
835
+	}
836
+
837
+
838
+	/**
839
+	 * Callback for the WordPress after_delete_post hook.
840
+	 * Execute some basic checks before calling the delete_cpt_item method in the child class.
841
+	 *
842
+	 * @param $post_id
843
+	 * @throws EE_Error
844
+	 * @throws ReflectionException
845
+	 */
846
+	public function before_delete_cpt_item($post_id)
847
+	{
848
+		$this->_set_model_object($post_id, true, 'delete');
849
+		// if our cpt object isn't existent then get out immediately.
850
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
851
+			return;
852
+		}
853
+		$this->delete_cpt_item($post_id);
854
+	}
855
+
856
+
857
+	/**
858
+	 * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
859
+	 * accordingly.
860
+	 *
861
+	 * @return void
862
+	 * @throws EE_Error
863
+	 * @throws ReflectionException
864
+	 */
865
+	public function verify_cpt_object()
866
+	{
867
+		$label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
868
+		// verify event object
869
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
870
+			throw new EE_Error(
871
+				sprintf(
872
+					esc_html__(
873
+						'Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
874
+						'event_espresso'
875
+					),
876
+					$label
877
+				)
878
+			);
879
+		}
880
+		// if auto-draft then throw an error
881
+		if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
882
+			EE_Error::overwrite_errors();
883
+			EE_Error::add_error(
884
+				sprintf(
885
+					esc_html__(
886
+						'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.',
887
+						'event_espresso'
888
+					),
889
+					$label
890
+				),
891
+				__FILE__,
892
+				__FUNCTION__,
893
+				__LINE__
894
+			);
895
+		}
896
+	}
897
+
898
+
899
+	/**
900
+	 * admin_footer_scripts_global
901
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
902
+	 * will apply on ALL EE_Admin pages.
903
+	 *
904
+	 * @return void
905
+	 */
906
+	public function admin_footer_scripts_global()
907
+	{
908
+		$this->_add_admin_page_ajax_loading_img();
909
+		$this->_add_admin_page_overlay();
910
+	}
911
+
912
+
913
+	/**
914
+	 * add in any global scripts for cpt routes
915
+	 *
916
+	 * @return void
917
+	 * @throws EE_Error
918
+	 */
919
+	public function load_global_scripts_styles()
920
+	{
921
+		parent::load_global_scripts_styles();
922
+		if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
923
+			// setup custom post status object for localize script but only if we've got a cpt object
924
+			$statuses = $this->_cpt_model_obj->get_custom_post_statuses();
925
+			if (! empty($statuses)) {
926
+				// get ALL statuses!
927
+				$statuses = $this->_cpt_model_obj->get_all_post_statuses();
928
+				// setup object
929
+				$ee_cpt_statuses = [];
930
+				foreach ($statuses as $status => $label) {
931
+					$ee_cpt_statuses[ $status ] = [
932
+						'label'      => $label,
933
+						'save_label' => sprintf(
934
+							wp_strip_all_tags(__('Save as %s', 'event_espresso')),
935
+							$label
936
+						),
937
+					];
938
+				}
939
+				wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
940
+			}
941
+		}
942
+	}
943
+
944
+
945
+	/**
946
+	 * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
947
+	 * insert/updates
948
+	 *
949
+	 * @param int     $post_id ID of post being updated
950
+	 * @param WP_Post $post    Post object from WP
951
+	 * @param bool    $update  Whether this is an update or a new save.
952
+	 * @return void
953
+	 * @throws EE_Error
954
+	 * @throws ReflectionException
955
+	 */
956
+	public function insert_update($post_id, $post, $update)
957
+	{
958
+		// make sure that if this is a revision OR trash action that we don't do any updates!
959
+		if (
960
+			isset($this->_req_data['action'])
961
+			&& (
962
+				$this->_req_data['action'] === 'restore'
963
+				|| $this->_req_data['action'] === 'trash'
964
+			)
965
+		) {
966
+			return;
967
+		}
968
+		$this->_set_model_object($post_id, true, 'insert_update');
969
+		// if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
970
+		if (
971
+			$update
972
+			&& (
973
+				! $this->_cpt_model_obj instanceof EE_CPT_Base
974
+				|| $this->_cpt_model_obj->ID() !== $post_id
975
+			)
976
+		) {
977
+			return;
978
+		}
979
+		// check for autosave and update our req_data property accordingly.
980
+		/*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
981 981
             foreach( (array) $this->_req_data['ee_autosave_data'] as $id => $values ) {
982 982
 
983 983
                 foreach ( (array) $values as $key => $value ) {
@@ -987,548 +987,548 @@  discard block
 block discarded – undo
987 987
 
988 988
         }/**/ // TODO reactivate after autosave is implemented in 4.2
989 989
 
990
-        // take care of updating any selected page_template IF this cpt supports it.
991
-        if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
992
-            // wp version aware.
993
-            if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
994
-                $page_templates = wp_get_theme()->get_page_templates();
995
-            } else {
996
-                $post->page_template = $this->_req_data['page_template'];
997
-                $page_templates      = wp_get_theme()->get_page_templates($post);
998
-            }
999
-            if (
1000
-                'default' != $this->_req_data['page_template']
1001
-                && ! isset($page_templates[ $this->_req_data['page_template'] ])
1002
-            ) {
1003
-                EE_Error::add_error(
1004
-                    esc_html__('Invalid Page Template.', 'event_espresso'),
1005
-                    __FILE__,
1006
-                    __FUNCTION__,
1007
-                    __LINE__
1008
-                );
1009
-            } else {
1010
-                update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
1011
-            }
1012
-        }
1013
-        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
1014
-            return;
1015
-        } //TODO we'll remove this after reimplementing autosave in 4.2
1016
-        $this->_insert_update_cpt_item($post_id, $post);
1017
-    }
1018
-
1019
-
1020
-    /**
1021
-     * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
1022
-     * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
1023
-     * so we don't have to check for our CPT.
1024
-     *
1025
-     * @param int $post_id ID of the post
1026
-     * @return void
1027
-     */
1028
-    public function dont_permanently_delete_ee_cpts($post_id)
1029
-    {
1030
-        // only do this if we're actually processing one of our CPTs
1031
-        // if our cpt object isn't existent then get out immediately.
1032
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1033
-            return;
1034
-        }
1035
-        delete_post_meta($post_id, '_wp_trash_meta_status');
1036
-        delete_post_meta($post_id, '_wp_trash_meta_time');
1037
-        // our cpts may have comments so let's take care of that too
1038
-        delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1039
-    }
1040
-
1041
-
1042
-    /**
1043
-     * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1044
-     * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1045
-     * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1046
-     *
1047
-     * @param int $post_id     ID of cpt item
1048
-     * @param int $revision_id ID of revision being restored
1049
-     * @return void
1050
-     */
1051
-    public function restore_revision($post_id, $revision_id)
1052
-    {
1053
-        $this->_restore_cpt_item($post_id, $revision_id);
1054
-        // global action
1055
-        do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1056
-        // class specific action so you can limit hooking into a specific page.
1057
-        do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1058
-    }
1059
-
1060
-
1061
-    /**
1062
-     * @param int $post_id     ID of cpt item
1063
-     * @param int $revision_id ID of revision for item
1064
-     * @return void
1065
-     * @see restore_revision() for details
1066
-     */
1067
-    abstract protected function _restore_cpt_item($post_id, $revision_id);
1068
-
1069
-
1070
-    /**
1071
-     * Execution of this method is added to the end of the load_page_dependencies method in the parent
1072
-     * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1073
-     * To fix we have to reset the current_screen using the page_slug
1074
-     * (which is identical - or should be - to our registered_post_type id.)
1075
-     * Also, since the core WP file loads the admin_header.php for WP
1076
-     * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1077
-     * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1078
-     *
1079
-     * @return void
1080
-     * @throws EE_Error
1081
-     */
1082
-    public function modify_current_screen()
1083
-    {
1084
-        // ONLY do this if the current page_route IS a cpt route
1085
-        if (! $this->_cpt_route) {
1086
-            return;
1087
-        }
1088
-        // routing things REALLY early b/c this is a cpt admin page
1089
-        set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1090
-        $this->_current_screen       = get_current_screen();
1091
-        $this->_current_screen->base = 'event-espresso';
1092
-        $this->_add_help_tabs(); // we make sure we add any help tabs back in!
1093
-        /*try {
990
+		// take care of updating any selected page_template IF this cpt supports it.
991
+		if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
992
+			// wp version aware.
993
+			if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
994
+				$page_templates = wp_get_theme()->get_page_templates();
995
+			} else {
996
+				$post->page_template = $this->_req_data['page_template'];
997
+				$page_templates      = wp_get_theme()->get_page_templates($post);
998
+			}
999
+			if (
1000
+				'default' != $this->_req_data['page_template']
1001
+				&& ! isset($page_templates[ $this->_req_data['page_template'] ])
1002
+			) {
1003
+				EE_Error::add_error(
1004
+					esc_html__('Invalid Page Template.', 'event_espresso'),
1005
+					__FILE__,
1006
+					__FUNCTION__,
1007
+					__LINE__
1008
+				);
1009
+			} else {
1010
+				update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
1011
+			}
1012
+		}
1013
+		if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
1014
+			return;
1015
+		} //TODO we'll remove this after reimplementing autosave in 4.2
1016
+		$this->_insert_update_cpt_item($post_id, $post);
1017
+	}
1018
+
1019
+
1020
+	/**
1021
+	 * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
1022
+	 * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
1023
+	 * so we don't have to check for our CPT.
1024
+	 *
1025
+	 * @param int $post_id ID of the post
1026
+	 * @return void
1027
+	 */
1028
+	public function dont_permanently_delete_ee_cpts($post_id)
1029
+	{
1030
+		// only do this if we're actually processing one of our CPTs
1031
+		// if our cpt object isn't existent then get out immediately.
1032
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1033
+			return;
1034
+		}
1035
+		delete_post_meta($post_id, '_wp_trash_meta_status');
1036
+		delete_post_meta($post_id, '_wp_trash_meta_time');
1037
+		// our cpts may have comments so let's take care of that too
1038
+		delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1039
+	}
1040
+
1041
+
1042
+	/**
1043
+	 * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1044
+	 * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1045
+	 * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1046
+	 *
1047
+	 * @param int $post_id     ID of cpt item
1048
+	 * @param int $revision_id ID of revision being restored
1049
+	 * @return void
1050
+	 */
1051
+	public function restore_revision($post_id, $revision_id)
1052
+	{
1053
+		$this->_restore_cpt_item($post_id, $revision_id);
1054
+		// global action
1055
+		do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1056
+		// class specific action so you can limit hooking into a specific page.
1057
+		do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1058
+	}
1059
+
1060
+
1061
+	/**
1062
+	 * @param int $post_id     ID of cpt item
1063
+	 * @param int $revision_id ID of revision for item
1064
+	 * @return void
1065
+	 * @see restore_revision() for details
1066
+	 */
1067
+	abstract protected function _restore_cpt_item($post_id, $revision_id);
1068
+
1069
+
1070
+	/**
1071
+	 * Execution of this method is added to the end of the load_page_dependencies method in the parent
1072
+	 * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1073
+	 * To fix we have to reset the current_screen using the page_slug
1074
+	 * (which is identical - or should be - to our registered_post_type id.)
1075
+	 * Also, since the core WP file loads the admin_header.php for WP
1076
+	 * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1077
+	 * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1078
+	 *
1079
+	 * @return void
1080
+	 * @throws EE_Error
1081
+	 */
1082
+	public function modify_current_screen()
1083
+	{
1084
+		// ONLY do this if the current page_route IS a cpt route
1085
+		if (! $this->_cpt_route) {
1086
+			return;
1087
+		}
1088
+		// routing things REALLY early b/c this is a cpt admin page
1089
+		set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1090
+		$this->_current_screen       = get_current_screen();
1091
+		$this->_current_screen->base = 'event-espresso';
1092
+		$this->_add_help_tabs(); // we make sure we add any help tabs back in!
1093
+		/*try {
1094 1094
             $this->_route_admin_request();
1095 1095
         } catch ( EE_Error $e ) {
1096 1096
             $e->get_error();
1097 1097
         }/**/
1098
-    }
1099
-
1100
-
1101
-    /**
1102
-     * This allows child classes to modify the default editor title that appears when people add a new or edit an
1103
-     * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1104
-     * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1105
-     * default to be.
1106
-     *
1107
-     * @param string $title The new title (or existing if there is no editor_title defined)
1108
-     * @return string
1109
-     */
1110
-    public function add_custom_editor_default_title($title)
1111
-    {
1112
-        return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1113
-            ? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1114
-            : $title;
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1120
-     *
1121
-     * @param string $shortlink   The already generated shortlink
1122
-     * @param int    $id          Post ID for this item
1123
-     * @param string $context     The context for the link
1124
-     * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1125
-     * @return string
1126
-     */
1127
-    public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1128
-    {
1129
-        if (! empty($id) && get_option('permalink_structure') !== '') {
1130
-            $post = get_post($id);
1131
-            if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1132
-                $shortlink = home_url('?p=' . $post->ID);
1133
-            }
1134
-        }
1135
-        return $shortlink;
1136
-    }
1137
-
1138
-
1139
-    /**
1140
-     * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1141
-     * already run in modify_current_screen())
1142
-     *
1143
-     * @return void
1144
-     * @throws EE_Error
1145
-     * @throws ReflectionException
1146
-     */
1147
-    public function route_admin_request()
1148
-    {
1149
-        if ($this->_cpt_route) {
1150
-            return;
1151
-        }
1152
-        try {
1153
-            $this->_route_admin_request();
1154
-        } catch (EE_Error $e) {
1155
-            $e->get_error();
1156
-        }
1157
-    }
1158
-
1159
-
1160
-    /**
1161
-     * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1162
-     *
1163
-     * @return void
1164
-     */
1165
-    public function cpt_post_form_hidden_input()
1166
-    {
1167
-        // we're also going to add the route value and the current page so we can direct autosave parsing correctly
1168
-        echo '
1098
+	}
1099
+
1100
+
1101
+	/**
1102
+	 * This allows child classes to modify the default editor title that appears when people add a new or edit an
1103
+	 * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1104
+	 * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1105
+	 * default to be.
1106
+	 *
1107
+	 * @param string $title The new title (or existing if there is no editor_title defined)
1108
+	 * @return string
1109
+	 */
1110
+	public function add_custom_editor_default_title($title)
1111
+	{
1112
+		return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1113
+			? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1114
+			: $title;
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1120
+	 *
1121
+	 * @param string $shortlink   The already generated shortlink
1122
+	 * @param int    $id          Post ID for this item
1123
+	 * @param string $context     The context for the link
1124
+	 * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1125
+	 * @return string
1126
+	 */
1127
+	public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1128
+	{
1129
+		if (! empty($id) && get_option('permalink_structure') !== '') {
1130
+			$post = get_post($id);
1131
+			if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1132
+				$shortlink = home_url('?p=' . $post->ID);
1133
+			}
1134
+		}
1135
+		return $shortlink;
1136
+	}
1137
+
1138
+
1139
+	/**
1140
+	 * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1141
+	 * already run in modify_current_screen())
1142
+	 *
1143
+	 * @return void
1144
+	 * @throws EE_Error
1145
+	 * @throws ReflectionException
1146
+	 */
1147
+	public function route_admin_request()
1148
+	{
1149
+		if ($this->_cpt_route) {
1150
+			return;
1151
+		}
1152
+		try {
1153
+			$this->_route_admin_request();
1154
+		} catch (EE_Error $e) {
1155
+			$e->get_error();
1156
+		}
1157
+	}
1158
+
1159
+
1160
+	/**
1161
+	 * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1162
+	 *
1163
+	 * @return void
1164
+	 */
1165
+	public function cpt_post_form_hidden_input()
1166
+	{
1167
+		// we're also going to add the route value and the current page so we can direct autosave parsing correctly
1168
+		echo '
1169 1169
         <input type="hidden" name="ee_cpt_item_redirect_url" value="' . esc_url_raw($this->_admin_base_url) . '"/>
1170 1170
         <div id="ee-cpt-hidden-inputs">
1171 1171
             <input type="hidden" id="current_route" name="current_route" value="' . esc_attr($this->_current_view) . '"/>
1172 1172
             <input type="hidden" id="current_page" name="current_page" value="' . esc_attr($this->page_slug) . '"/>
1173 1173
         </div>';
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1179
-     *
1180
-     * @param string $location Original location url
1181
-     * @param int    $status   Status for http header
1182
-     * @return string           new (or original) url to redirect to.
1183
-     * @throws EE_Error
1184
-     */
1185
-    public function revision_redirect($location, $status)
1186
-    {
1187
-        // get revision
1188
-        $rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1189
-        // can't do anything without revision so let's get out if not present
1190
-        if (empty($rev_id)) {
1191
-            return $location;
1192
-        }
1193
-        // get rev_post_data
1194
-        $rev        = get_post($rev_id);
1195
-        $admin_url  = $this->_admin_base_url;
1196
-        $query_args = [
1197
-            'action'   => 'edit',
1198
-            'post'     => $rev->post_parent,
1199
-            'revision' => $rev_id,
1200
-            'message'  => 5,
1201
-        ];
1202
-        $this->_process_notices($query_args, true);
1203
-        return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $admin_url);
1204
-    }
1205
-
1206
-
1207
-    /**
1208
-     * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1209
-     *
1210
-     * @param string $link    the original generated link
1211
-     * @param int    $id      post id
1212
-     * @param string $context optional, defaults to display.  How to write the '&'
1213
-     * @return string          the link
1214
-     */
1215
-    public function modify_edit_post_link($link, $id, $context)
1216
-    {
1217
-        $post = get_post($id);
1218
-        if (
1219
-            ! isset($this->_req_data['action'])
1220
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1221
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1222
-        ) {
1223
-            return $link;
1224
-        }
1225
-        $query_args = [
1226
-            'action' => $this->_cpt_edit_routes[ $post->post_type ] ?? 'edit',
1227
-            'post'   => $id,
1228
-        ];
1229
-        return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1230
-    }
1231
-
1232
-
1233
-    /**
1234
-     * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1235
-     * our routes.
1236
-     *
1237
-     * @param string $delete_link  original delete link
1238
-     * @param int    $post_id      id of cpt object
1239
-     * @param bool   $force_delete whether this is forcing a hard delete instead of trash
1240
-     * @return string new delete link
1241
-     * @throws EE_Error
1242
-     * @throws ReflectionException
1243
-     */
1244
-    public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1245
-    {
1246
-        $post = get_post($post_id);
1247
-
1248
-        if (
1249
-            empty($this->_req_data['action'])
1250
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1251
-            || ! $post instanceof WP_Post
1252
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1253
-        ) {
1254
-            return $delete_link;
1255
-        }
1256
-        $this->_set_model_object($post->ID, true);
1257
-
1258
-        // returns something like `trash_event` or `trash_attendee` or `trash_venue`
1259
-        $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1260
-
1261
-        return EE_Admin_Page::add_query_args_and_nonce(
1262
-            [
1263
-                'page'   => $this->_req_data['page'],
1264
-                'action' => $action,
1265
-                $this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1266
-                         => $post->ID,
1267
-            ],
1268
-            admin_url()
1269
-        );
1270
-    }
1271
-
1272
-
1273
-    /**
1274
-     * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1275
-     * so that we can hijack the default redirect locations for wp custom post types
1276
-     * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1277
-     *
1278
-     * @param string $location This is the incoming currently set redirect location
1279
-     * @param string $post_id  This is the 'ID' value of the wp_posts table
1280
-     * @return string           the new location to redirect to
1281
-     * @throws EE_Error
1282
-     */
1283
-    public function cpt_post_location_redirect($location, $post_id)
1284
-    {
1285
-        // we DO have a match so let's setup the url
1286
-        // we have to get the post to determine our route
1287
-        $post       = get_post($post_id);
1288
-        $edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1289
-        // shared query_args
1290
-        $query_args = ['action' => $edit_route, 'post' => $post_id];
1291
-        $admin_url  = $this->_admin_base_url;
1292
-        if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1293
-            $status = get_post_status($post_id);
1294
-            if (isset($this->_req_data['publish'])) {
1295
-                switch ($status) {
1296
-                    case 'pending':
1297
-                        $message = 8;
1298
-                        break;
1299
-                    case 'future':
1300
-                        $message = 9;
1301
-                        break;
1302
-                    default:
1303
-                        $message = 6;
1304
-                }
1305
-            } else {
1306
-                $message = 'draft' === $status ? 10 : 1;
1307
-            }
1308
-        } elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1309
-            $message = 2;
1310
-        } elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1311
-            $message = 3;
1312
-        } elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1313
-            $message = 7;
1314
-        } else {
1315
-            $message = 4;
1316
-        }
1317
-        // change the message if the post type is not viewable on the frontend
1318
-        $this->_cpt_object = get_post_type_object($post->post_type);
1319
-        $message           = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1320
-        $query_args        = array_merge(['message' => $message], $query_args);
1321
-        $this->_process_notices($query_args, true);
1322
-        return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $admin_url);
1323
-    }
1324
-
1325
-
1326
-    /**
1327
-     * This method is called to inject nav tabs on core WP cpt pages
1328
-     *
1329
-     * @return void
1330
-     * @throws EE_Error
1331
-     */
1332
-    public function inject_nav_tabs()
1333
-    {
1334
-        // can we hijack and insert the nav_tabs?
1335
-        $nav_tabs = $this->_get_main_nav_tabs();
1336
-        // first close off existing form tag
1337
-        $html = '>';
1338
-        $html .= $nav_tabs;
1339
-        // now let's handle the remaining tag ( missing ">" is CORRECT )
1340
-        $html .= '<span></span';
1341
-        echo $html;  // already escaped
1342
-    }
1343
-
1344
-
1345
-    /**
1346
-     * This just sets up the post update messages when an update form is loaded
1347
-     *
1348
-     * @param array $messages the original messages array
1349
-     * @return array           the new messages array
1350
-     */
1351
-    public function post_update_messages($messages)
1352
-    {
1353
-        global $post;
1354
-        $id       = $this->request->getRequestParam('post');
1355
-        $id       = empty($id) && is_object($post) ? $post->ID : null;
1356
-        $revision = $this->request->getRequestParam('revision', 0, 'int');
1357
-
1358
-        $messages[ $post->post_type ] = [
1359
-            0  => '', // Unused. Messages start at index 1.
1360
-            1  => sprintf(
1361
-                esc_html__('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1362
-                $this->_cpt_object->labels->singular_name,
1363
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1364
-                '</a>'
1365
-            ),
1366
-            2  => esc_html__('Custom field updated', 'event_espresso'),
1367
-            3  => esc_html__('Custom field deleted.', 'event_espresso'),
1368
-            4  => sprintf(esc_html__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1369
-            5  => $revision
1370
-                ? sprintf(
1371
-                    esc_html__('%s restored to revision from %s', 'event_espresso'),
1372
-                    $this->_cpt_object->labels->singular_name,
1373
-                    wp_post_revision_title($revision, false)
1374
-                )
1375
-                : false,
1376
-            6  => sprintf(
1377
-                esc_html__('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1378
-                $this->_cpt_object->labels->singular_name,
1379
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1380
-                '</a>'
1381
-            ),
1382
-            7  => sprintf(esc_html__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1383
-            8  => sprintf(
1384
-                esc_html__('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1385
-                $this->_cpt_object->labels->singular_name,
1386
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1387
-                '</a>'
1388
-            ),
1389
-            9  => sprintf(
1390
-                esc_html__('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1391
-                $this->_cpt_object->labels->singular_name,
1392
-                '<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1393
-                '<a target="_blank" href="' . esc_url(get_permalink($id)),
1394
-                '</a>'
1395
-            ),
1396
-            10 => sprintf(
1397
-                esc_html__('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1398
-                $this->_cpt_object->labels->singular_name,
1399
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1400
-                '</a>'
1401
-            ),
1402
-        ];
1403
-        return $messages;
1404
-    }
1405
-
1406
-
1407
-    /**
1408
-     * default method for the 'create_new' route for cpt admin pages.
1409
-     * For reference what to include in here, see wp-admin/post-new.php
1410
-     *
1411
-     * @return void
1412
-     */
1413
-    protected function _create_new_cpt_item()
1414
-    {
1415
-        // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1416
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1417
-        $post_type        = $this->_cpt_routes[ $this->_req_action ];
1418
-        $post_type_object = $this->_cpt_object;
1419
-        $title            = $post_type_object->labels->add_new_item;
1420
-        $post             = $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1421
-        add_action('admin_print_styles', [$this, 'add_new_admin_page_global']);
1422
-        // modify the default editor title field with default title.
1423
-        add_filter('enter_title_here', [$this, 'add_custom_editor_default_title'], 10);
1424
-        $this->loadEditorTemplate(true);
1425
-    }
1426
-
1427
-
1428
-    /**
1429
-     * Enqueues auto-save and loads the editor template
1430
-     *
1431
-     * @param bool $creating
1432
-     */
1433
-    private function loadEditorTemplate($creating = true)
1434
-    {
1435
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1436
-        // these vars are used by the template
1437
-        $editing = true;
1438
-        $post_ID = $post->ID;
1439
-        if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1440
-            // only enqueue autosave when creating event (necessary to get permalink/url generated)
1441
-            // otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1442
-            if ($creating) {
1443
-                wp_enqueue_script('autosave');
1444
-            } elseif (
1445
-                isset($this->_cpt_routes[ $this->_req_data['action'] ])
1446
-                && ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1447
-            ) {
1448
-                $create_new_action = apply_filters(
1449
-                    'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1450
-                    'create_new',
1451
-                    $this
1452
-                );
1453
-                $post_new_file = EE_Admin_Page::add_query_args_and_nonce(
1454
-                    array(
1455
-                        'action' => $create_new_action,
1456
-                        'page'   => $this->page_slug,
1457
-                    ),
1458
-                    'admin.php'
1459
-                );
1460
-            }
1461
-            include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1462
-        }
1463
-    }
1464
-
1465
-
1466
-    public function add_new_admin_page_global()
1467
-    {
1468
-        $admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1469
-        ?>
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1179
+	 *
1180
+	 * @param string $location Original location url
1181
+	 * @param int    $status   Status for http header
1182
+	 * @return string           new (or original) url to redirect to.
1183
+	 * @throws EE_Error
1184
+	 */
1185
+	public function revision_redirect($location, $status)
1186
+	{
1187
+		// get revision
1188
+		$rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1189
+		// can't do anything without revision so let's get out if not present
1190
+		if (empty($rev_id)) {
1191
+			return $location;
1192
+		}
1193
+		// get rev_post_data
1194
+		$rev        = get_post($rev_id);
1195
+		$admin_url  = $this->_admin_base_url;
1196
+		$query_args = [
1197
+			'action'   => 'edit',
1198
+			'post'     => $rev->post_parent,
1199
+			'revision' => $rev_id,
1200
+			'message'  => 5,
1201
+		];
1202
+		$this->_process_notices($query_args, true);
1203
+		return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $admin_url);
1204
+	}
1205
+
1206
+
1207
+	/**
1208
+	 * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1209
+	 *
1210
+	 * @param string $link    the original generated link
1211
+	 * @param int    $id      post id
1212
+	 * @param string $context optional, defaults to display.  How to write the '&'
1213
+	 * @return string          the link
1214
+	 */
1215
+	public function modify_edit_post_link($link, $id, $context)
1216
+	{
1217
+		$post = get_post($id);
1218
+		if (
1219
+			! isset($this->_req_data['action'])
1220
+			|| ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1221
+			|| $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1222
+		) {
1223
+			return $link;
1224
+		}
1225
+		$query_args = [
1226
+			'action' => $this->_cpt_edit_routes[ $post->post_type ] ?? 'edit',
1227
+			'post'   => $id,
1228
+		];
1229
+		return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1230
+	}
1231
+
1232
+
1233
+	/**
1234
+	 * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1235
+	 * our routes.
1236
+	 *
1237
+	 * @param string $delete_link  original delete link
1238
+	 * @param int    $post_id      id of cpt object
1239
+	 * @param bool   $force_delete whether this is forcing a hard delete instead of trash
1240
+	 * @return string new delete link
1241
+	 * @throws EE_Error
1242
+	 * @throws ReflectionException
1243
+	 */
1244
+	public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1245
+	{
1246
+		$post = get_post($post_id);
1247
+
1248
+		if (
1249
+			empty($this->_req_data['action'])
1250
+			|| ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1251
+			|| ! $post instanceof WP_Post
1252
+			|| $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1253
+		) {
1254
+			return $delete_link;
1255
+		}
1256
+		$this->_set_model_object($post->ID, true);
1257
+
1258
+		// returns something like `trash_event` or `trash_attendee` or `trash_venue`
1259
+		$action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1260
+
1261
+		return EE_Admin_Page::add_query_args_and_nonce(
1262
+			[
1263
+				'page'   => $this->_req_data['page'],
1264
+				'action' => $action,
1265
+				$this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1266
+						 => $post->ID,
1267
+			],
1268
+			admin_url()
1269
+		);
1270
+	}
1271
+
1272
+
1273
+	/**
1274
+	 * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1275
+	 * so that we can hijack the default redirect locations for wp custom post types
1276
+	 * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1277
+	 *
1278
+	 * @param string $location This is the incoming currently set redirect location
1279
+	 * @param string $post_id  This is the 'ID' value of the wp_posts table
1280
+	 * @return string           the new location to redirect to
1281
+	 * @throws EE_Error
1282
+	 */
1283
+	public function cpt_post_location_redirect($location, $post_id)
1284
+	{
1285
+		// we DO have a match so let's setup the url
1286
+		// we have to get the post to determine our route
1287
+		$post       = get_post($post_id);
1288
+		$edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1289
+		// shared query_args
1290
+		$query_args = ['action' => $edit_route, 'post' => $post_id];
1291
+		$admin_url  = $this->_admin_base_url;
1292
+		if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1293
+			$status = get_post_status($post_id);
1294
+			if (isset($this->_req_data['publish'])) {
1295
+				switch ($status) {
1296
+					case 'pending':
1297
+						$message = 8;
1298
+						break;
1299
+					case 'future':
1300
+						$message = 9;
1301
+						break;
1302
+					default:
1303
+						$message = 6;
1304
+				}
1305
+			} else {
1306
+				$message = 'draft' === $status ? 10 : 1;
1307
+			}
1308
+		} elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1309
+			$message = 2;
1310
+		} elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1311
+			$message = 3;
1312
+		} elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1313
+			$message = 7;
1314
+		} else {
1315
+			$message = 4;
1316
+		}
1317
+		// change the message if the post type is not viewable on the frontend
1318
+		$this->_cpt_object = get_post_type_object($post->post_type);
1319
+		$message           = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1320
+		$query_args        = array_merge(['message' => $message], $query_args);
1321
+		$this->_process_notices($query_args, true);
1322
+		return EE_Admin_Page_CPT::add_query_args_and_nonce($query_args, $admin_url);
1323
+	}
1324
+
1325
+
1326
+	/**
1327
+	 * This method is called to inject nav tabs on core WP cpt pages
1328
+	 *
1329
+	 * @return void
1330
+	 * @throws EE_Error
1331
+	 */
1332
+	public function inject_nav_tabs()
1333
+	{
1334
+		// can we hijack and insert the nav_tabs?
1335
+		$nav_tabs = $this->_get_main_nav_tabs();
1336
+		// first close off existing form tag
1337
+		$html = '>';
1338
+		$html .= $nav_tabs;
1339
+		// now let's handle the remaining tag ( missing ">" is CORRECT )
1340
+		$html .= '<span></span';
1341
+		echo $html;  // already escaped
1342
+	}
1343
+
1344
+
1345
+	/**
1346
+	 * This just sets up the post update messages when an update form is loaded
1347
+	 *
1348
+	 * @param array $messages the original messages array
1349
+	 * @return array           the new messages array
1350
+	 */
1351
+	public function post_update_messages($messages)
1352
+	{
1353
+		global $post;
1354
+		$id       = $this->request->getRequestParam('post');
1355
+		$id       = empty($id) && is_object($post) ? $post->ID : null;
1356
+		$revision = $this->request->getRequestParam('revision', 0, 'int');
1357
+
1358
+		$messages[ $post->post_type ] = [
1359
+			0  => '', // Unused. Messages start at index 1.
1360
+			1  => sprintf(
1361
+				esc_html__('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1362
+				$this->_cpt_object->labels->singular_name,
1363
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1364
+				'</a>'
1365
+			),
1366
+			2  => esc_html__('Custom field updated', 'event_espresso'),
1367
+			3  => esc_html__('Custom field deleted.', 'event_espresso'),
1368
+			4  => sprintf(esc_html__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1369
+			5  => $revision
1370
+				? sprintf(
1371
+					esc_html__('%s restored to revision from %s', 'event_espresso'),
1372
+					$this->_cpt_object->labels->singular_name,
1373
+					wp_post_revision_title($revision, false)
1374
+				)
1375
+				: false,
1376
+			6  => sprintf(
1377
+				esc_html__('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1378
+				$this->_cpt_object->labels->singular_name,
1379
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1380
+				'</a>'
1381
+			),
1382
+			7  => sprintf(esc_html__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1383
+			8  => sprintf(
1384
+				esc_html__('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1385
+				$this->_cpt_object->labels->singular_name,
1386
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1387
+				'</a>'
1388
+			),
1389
+			9  => sprintf(
1390
+				esc_html__('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1391
+				$this->_cpt_object->labels->singular_name,
1392
+				'<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1393
+				'<a target="_blank" href="' . esc_url(get_permalink($id)),
1394
+				'</a>'
1395
+			),
1396
+			10 => sprintf(
1397
+				esc_html__('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1398
+				$this->_cpt_object->labels->singular_name,
1399
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1400
+				'</a>'
1401
+			),
1402
+		];
1403
+		return $messages;
1404
+	}
1405
+
1406
+
1407
+	/**
1408
+	 * default method for the 'create_new' route for cpt admin pages.
1409
+	 * For reference what to include in here, see wp-admin/post-new.php
1410
+	 *
1411
+	 * @return void
1412
+	 */
1413
+	protected function _create_new_cpt_item()
1414
+	{
1415
+		// gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1416
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1417
+		$post_type        = $this->_cpt_routes[ $this->_req_action ];
1418
+		$post_type_object = $this->_cpt_object;
1419
+		$title            = $post_type_object->labels->add_new_item;
1420
+		$post             = $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1421
+		add_action('admin_print_styles', [$this, 'add_new_admin_page_global']);
1422
+		// modify the default editor title field with default title.
1423
+		add_filter('enter_title_here', [$this, 'add_custom_editor_default_title'], 10);
1424
+		$this->loadEditorTemplate(true);
1425
+	}
1426
+
1427
+
1428
+	/**
1429
+	 * Enqueues auto-save and loads the editor template
1430
+	 *
1431
+	 * @param bool $creating
1432
+	 */
1433
+	private function loadEditorTemplate($creating = true)
1434
+	{
1435
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1436
+		// these vars are used by the template
1437
+		$editing = true;
1438
+		$post_ID = $post->ID;
1439
+		if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1440
+			// only enqueue autosave when creating event (necessary to get permalink/url generated)
1441
+			// otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1442
+			if ($creating) {
1443
+				wp_enqueue_script('autosave');
1444
+			} elseif (
1445
+				isset($this->_cpt_routes[ $this->_req_data['action'] ])
1446
+				&& ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1447
+			) {
1448
+				$create_new_action = apply_filters(
1449
+					'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1450
+					'create_new',
1451
+					$this
1452
+				);
1453
+				$post_new_file = EE_Admin_Page::add_query_args_and_nonce(
1454
+					array(
1455
+						'action' => $create_new_action,
1456
+						'page'   => $this->page_slug,
1457
+					),
1458
+					'admin.php'
1459
+				);
1460
+			}
1461
+			include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1462
+		}
1463
+	}
1464
+
1465
+
1466
+	public function add_new_admin_page_global()
1467
+	{
1468
+		$admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1469
+		?>
1470 1470
         <script type="text/javascript">
1471 1471
             adminpage = '<?php echo $admin_page; ?>';
1472 1472
         </script>
1473 1473
         <?php
1474
-    }
1475
-
1476
-
1477
-    /**
1478
-     * default method for the 'edit' route for cpt admin pages
1479
-     * For reference on what to put in here, refer to wp-admin/post.php
1480
-     *
1481
-     * @return string   template for edit cpt form
1482
-     */
1483
-    protected function _edit_cpt_item()
1484
-    {
1485
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1486
-        $post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1487
-        $post    = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1488
-        if (empty($post)) {
1489
-            wp_die(esc_html__(
1490
-                'You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?',
1491
-                'event_espresso'
1492
-            ));
1493
-        }
1494
-
1495
-        $post_lock = $this->request->getRequestParam('get-post-lock');
1496
-        if ($post_lock) {
1497
-            wp_set_post_lock($post_id);
1498
-            wp_redirect(get_edit_post_link($post_id, 'url'));
1499
-            exit();
1500
-        }
1501
-
1502
-        // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1503
-        $post_type        = $this->_cpt_routes[ $this->_req_action ];
1504
-        $post_type_object = $this->_cpt_object;
1505
-
1506
-        if (! wp_check_post_lock($post->ID)) {
1507
-            wp_set_post_lock($post->ID);
1508
-        }
1509
-        add_action('admin_footer', '_admin_notice_post_locked');
1510
-        if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1511
-            wp_enqueue_script('admin-comments');
1512
-            enqueue_comment_hotkeys_js();
1513
-        }
1514
-        add_action('admin_print_styles', [$this, 'add_new_admin_page_global']);
1515
-        // modify the default editor title field with default title.
1516
-        add_filter('enter_title_here', [$this, 'add_custom_editor_default_title'], 10);
1517
-        $this->loadEditorTemplate(false);
1518
-    }
1519
-
1520
-
1521
-
1522
-    /**
1523
-     * some getters
1524
-     */
1525
-    /**
1526
-     * This returns the protected _cpt_model_obj property
1527
-     *
1528
-     * @return EE_CPT_Base
1529
-     */
1530
-    public function get_cpt_model_obj()
1531
-    {
1532
-        return $this->_cpt_model_obj;
1533
-    }
1474
+	}
1475
+
1476
+
1477
+	/**
1478
+	 * default method for the 'edit' route for cpt admin pages
1479
+	 * For reference on what to put in here, refer to wp-admin/post.php
1480
+	 *
1481
+	 * @return string   template for edit cpt form
1482
+	 */
1483
+	protected function _edit_cpt_item()
1484
+	{
1485
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1486
+		$post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1487
+		$post    = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1488
+		if (empty($post)) {
1489
+			wp_die(esc_html__(
1490
+				'You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?',
1491
+				'event_espresso'
1492
+			));
1493
+		}
1494
+
1495
+		$post_lock = $this->request->getRequestParam('get-post-lock');
1496
+		if ($post_lock) {
1497
+			wp_set_post_lock($post_id);
1498
+			wp_redirect(get_edit_post_link($post_id, 'url'));
1499
+			exit();
1500
+		}
1501
+
1502
+		// template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1503
+		$post_type        = $this->_cpt_routes[ $this->_req_action ];
1504
+		$post_type_object = $this->_cpt_object;
1505
+
1506
+		if (! wp_check_post_lock($post->ID)) {
1507
+			wp_set_post_lock($post->ID);
1508
+		}
1509
+		add_action('admin_footer', '_admin_notice_post_locked');
1510
+		if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1511
+			wp_enqueue_script('admin-comments');
1512
+			enqueue_comment_hotkeys_js();
1513
+		}
1514
+		add_action('admin_print_styles', [$this, 'add_new_admin_page_global']);
1515
+		// modify the default editor title field with default title.
1516
+		add_filter('enter_title_here', [$this, 'add_custom_editor_default_title'], 10);
1517
+		$this->loadEditorTemplate(false);
1518
+	}
1519
+
1520
+
1521
+
1522
+	/**
1523
+	 * some getters
1524
+	 */
1525
+	/**
1526
+	 * This returns the protected _cpt_model_obj property
1527
+	 *
1528
+	 * @return EE_CPT_Base
1529
+	 */
1530
+	public function get_cpt_model_obj()
1531
+	{
1532
+		return $this->_cpt_model_obj;
1533
+	}
1534 1534
 }
Please login to merge, or discard this patch.