Completed
Branch decaf-fixes/more-request-fixes (02d799)
by
unknown
07:01 queued 05:08
created
admin_pages/transactions/Transactions_Admin_Page.core.php 1 patch
Indentation   +2577 added lines, -2577 removed lines patch added patch discarded remove patch
@@ -13,2582 +13,2582 @@
 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', array($this, 'apply_payments_or_refunds'));
64
-        add_action('wp_ajax_espresso_apply_refund', array($this, 'apply_payments_or_refunds'));
65
-        add_action('wp_ajax_espresso_delete_payment', array($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 = array(
78
-            'buttons' => array(
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
-
102
-        $txn_id = ! empty($this->_req_data['TXN_ID'])
103
-                  && ! is_array($this->_req_data['TXN_ID'])
104
-            ? $this->_req_data['TXN_ID']
105
-            : 0;
106
-
107
-        $this->_page_routes = array(
108
-
109
-            'default' => array(
110
-                'func'       => '_transactions_overview_list_table',
111
-                'capability' => 'ee_read_transactions',
112
-            ),
113
-
114
-            'view_transaction' => array(
115
-                'func'       => '_transaction_details',
116
-                'capability' => 'ee_read_transaction',
117
-                'obj_id'     => $txn_id,
118
-            ),
119
-
120
-            'send_payment_reminder' => array(
121
-                'func'       => '_send_payment_reminder',
122
-                'noheader'   => true,
123
-                'capability' => 'ee_send_message',
124
-            ),
125
-
126
-            'espresso_apply_payment' => array(
127
-                'func'       => 'apply_payments_or_refunds',
128
-                'noheader'   => true,
129
-                'capability' => 'ee_edit_payments',
130
-            ),
131
-
132
-            'espresso_apply_refund' => array(
133
-                'func'       => 'apply_payments_or_refunds',
134
-                'noheader'   => true,
135
-                'capability' => 'ee_edit_payments',
136
-            ),
137
-
138
-            'espresso_delete_payment' => array(
139
-                'func'       => 'delete_payment',
140
-                'noheader'   => true,
141
-                'capability' => 'ee_delete_payments',
142
-            ),
143
-
144
-            'espresso_recalculate_line_items' => array(
145
-                'func'       => 'recalculateLineItems',
146
-                'noheader'   => true,
147
-                'capability' => 'ee_edit_payments',
148
-            ),
149
-
150
-        );
151
-    }
152
-
153
-
154
-    protected function _set_page_config()
155
-    {
156
-        $this->_page_config = array(
157
-            'default'          => array(
158
-                'nav'           => array(
159
-                    'label' => esc_html__('Overview', 'event_espresso'),
160
-                    'order' => 10,
161
-                ),
162
-                'list_table'    => 'EE_Admin_Transactions_List_Table',
163
-                'help_tabs'     => array(
164
-                    'transactions_overview_help_tab'                       => array(
165
-                        'title'    => esc_html__('Transactions Overview', 'event_espresso'),
166
-                        'filename' => 'transactions_overview',
167
-                    ),
168
-                    'transactions_overview_table_column_headings_help_tab' => array(
169
-                        'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
170
-                        'filename' => 'transactions_overview_table_column_headings',
171
-                    ),
172
-                    'transactions_overview_views_filters_help_tab'         => array(
173
-                        'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
174
-                        'filename' => 'transactions_overview_views_filters_search',
175
-                    ),
176
-                ),
177
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
178
-                // 'help_tour'     => array('Transactions_Overview_Help_Tour'),
179
-                /**
180
-                 * commented out because currently we are not displaying tips for transaction list table status but this
181
-                 * may change in a later iteration so want to keep the code for then.
182
-                 */
183
-                // 'qtips' => array( 'Transactions_List_Table_Tips' ),
184
-                'require_nonce' => false,
185
-            ),
186
-            'view_transaction' => array(
187
-                'nav'       => array(
188
-                    'label'      => esc_html__('View Transaction', 'event_espresso'),
189
-                    'order'      => 5,
190
-                    'url'        => isset($this->_req_data['TXN_ID'])
191
-                        ? add_query_arg(array('TXN_ID' => $this->_req_data['TXN_ID']), $this->_current_page_view_url)
192
-                        : $this->_admin_base_url,
193
-                    'persistent' => false,
194
-                ),
195
-                'help_tabs' => array(
196
-                    'transactions_view_transaction_help_tab'                                              => array(
197
-                        'title'    => esc_html__('View Transaction', 'event_espresso'),
198
-                        'filename' => 'transactions_view_transaction',
199
-                    ),
200
-                    'transactions_view_transaction_transaction_details_table_help_tab'                    => array(
201
-                        'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
202
-                        'filename' => 'transactions_view_transaction_transaction_details_table',
203
-                    ),
204
-                    'transactions_view_transaction_attendees_registered_help_tab'                         => array(
205
-                        'title'    => esc_html__('Attendees Registered', 'event_espresso'),
206
-                        'filename' => 'transactions_view_transaction_attendees_registered',
207
-                    ),
208
-                    'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => array(
209
-                        'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
210
-                        'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
211
-                    ),
212
-                ),
213
-                'qtips'     => array('Transaction_Details_Tips'),
214
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
215
-                // 'help_tour' => array('Transaction_Details_Help_Tour'),
216
-                'metaboxes' => array('_transaction_details_metaboxes'),
217
-
218
-                'require_nonce' => false,
219
-            ),
220
-        );
221
-    }
222
-
223
-
224
-    /**
225
-     * The below methods aren't used by this class currently
226
-     */
227
-    protected function _add_screen_options()
228
-    {
229
-        // noop
230
-    }
231
-
232
-
233
-    protected function _add_feature_pointers()
234
-    {
235
-        // noop
236
-    }
237
-
238
-
239
-    public function admin_init()
240
-    {
241
-        // IF a registration was JUST added via the admin...
242
-        if (
243
-            isset(
244
-                $this->_req_data['redirect_from'],
245
-                $this->_req_data['EVT_ID'],
246
-                $this->_req_data['event_name']
247
-            )
248
-        ) {
249
-            // then set a cookie so that we can block any attempts to use
250
-            // the back button as a way to enter another registration.
251
-            setcookie(
252
-                'ee_registration_added',
253
-                $this->_req_data['EVT_ID'],
254
-                time() + WEEK_IN_SECONDS,
255
-                '/'
256
-            );
257
-            // and update the global
258
-            $_COOKIE['ee_registration_added'] = $this->_req_data['EVT_ID'];
259
-        }
260
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
261
-            '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.',
262
-            'event_espresso'
263
-        );
264
-        EE_Registry::$i18n_js_strings['error_occurred'] = esc_html__(
265
-            'An error occurred! Please refresh the page and try again.',
266
-            'event_espresso'
267
-        );
268
-        EE_Registry::$i18n_js_strings['txn_status_array'] = self::$_txn_status;
269
-        EE_Registry::$i18n_js_strings['pay_status_array'] = self::$_pay_status;
270
-        EE_Registry::$i18n_js_strings['payments_total'] = esc_html__('Payments Total', 'event_espresso');
271
-        EE_Registry::$i18n_js_strings['transaction_overpaid'] = esc_html__(
272
-            'This transaction has been overpaid ! Payments Total',
273
-            'event_espresso'
274
-        );
275
-    }
276
-
277
-
278
-    public function admin_notices()
279
-    {
280
-        // noop
281
-    }
282
-
283
-
284
-    public function admin_footer_scripts()
285
-    {
286
-        // noop
287
-    }
288
-
289
-
290
-    /**
291
-     * _set_transaction_status_array
292
-     * sets list of transaction statuses
293
-     *
294
-     * @access private
295
-     * @return void
296
-     * @throws EE_Error
297
-     * @throws InvalidArgumentException
298
-     * @throws InvalidDataTypeException
299
-     * @throws InvalidInterfaceException
300
-     */
301
-    private function _set_transaction_status_array()
302
-    {
303
-        self::$_txn_status = EEM_Transaction::instance()->status_array(true);
304
-    }
305
-
306
-
307
-    /**
308
-     * get_transaction_status_array
309
-     * return the transaction status array for wp_list_table
310
-     *
311
-     * @access public
312
-     * @return array
313
-     */
314
-    public function get_transaction_status_array()
315
-    {
316
-        return self::$_txn_status;
317
-    }
318
-
319
-
320
-    /**
321
-     *    get list of payment statuses
322
-     *
323
-     * @access private
324
-     * @return void
325
-     * @throws EE_Error
326
-     * @throws InvalidArgumentException
327
-     * @throws InvalidDataTypeException
328
-     * @throws InvalidInterfaceException
329
-     */
330
-    private function _get_payment_status_array()
331
-    {
332
-        self::$_pay_status = EEM_Payment::instance()->status_array(true);
333
-        $this->_template_args['payment_status'] = self::$_pay_status;
334
-    }
335
-
336
-
337
-    /**
338
-     *    _add_screen_options_default
339
-     *
340
-     * @access protected
341
-     * @return void
342
-     * @throws InvalidArgumentException
343
-     * @throws InvalidDataTypeException
344
-     * @throws InvalidInterfaceException
345
-     */
346
-    protected function _add_screen_options_default()
347
-    {
348
-        $this->_per_page_screen_option();
349
-    }
350
-
351
-
352
-    /**
353
-     * load_scripts_styles
354
-     *
355
-     * @access public
356
-     * @return void
357
-     */
358
-    public function load_scripts_styles()
359
-    {
360
-        // enqueue style
361
-        wp_register_style(
362
-            'espresso_txn',
363
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
364
-            array(),
365
-            EVENT_ESPRESSO_VERSION
366
-        );
367
-        wp_enqueue_style('espresso_txn');
368
-        // scripts
369
-        wp_register_script(
370
-            'espresso_txn',
371
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
372
-            array(
373
-                'ee_admin_js',
374
-                'ee-datepicker',
375
-                'jquery-ui-datepicker',
376
-                'jquery-ui-draggable',
377
-                'ee-dialog',
378
-                'ee-accounting',
379
-                'ee-serialize-full-array',
380
-            ),
381
-            EVENT_ESPRESSO_VERSION,
382
-            true
383
-        );
384
-        wp_enqueue_script('espresso_txn');
385
-    }
386
-
387
-
388
-    /**
389
-     *    load_scripts_styles_view_transaction
390
-     *
391
-     * @access public
392
-     * @return void
393
-     */
394
-    public function load_scripts_styles_view_transaction()
395
-    {
396
-        // styles
397
-        wp_enqueue_style('espresso-ui-theme');
398
-    }
399
-
400
-
401
-    /**
402
-     *    load_scripts_styles_default
403
-     *
404
-     * @access public
405
-     * @return void
406
-     */
407
-    public function load_scripts_styles_default()
408
-    {
409
-        // styles
410
-        wp_enqueue_style('espresso-ui-theme');
411
-    }
412
-
413
-
414
-    /**
415
-     *    _set_list_table_views_default
416
-     *
417
-     * @access protected
418
-     * @return void
419
-     */
420
-    protected function _set_list_table_views_default()
421
-    {
422
-        $this->_views = array(
423
-            'all'        => array(
424
-                'slug'  => 'all',
425
-                'label' => esc_html__('View All Transactions', 'event_espresso'),
426
-                'count' => 0,
427
-            ),
428
-            'abandoned'  => array(
429
-                'slug'  => 'abandoned',
430
-                'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
431
-                'count' => 0,
432
-            ),
433
-            'incomplete' => array(
434
-                'slug'  => 'incomplete',
435
-                'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
436
-                'count' => 0,
437
-            ),
438
-        );
439
-        if (
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', array($this, 'apply_payments_or_refunds'));
64
+		add_action('wp_ajax_espresso_apply_refund', array($this, 'apply_payments_or_refunds'));
65
+		add_action('wp_ajax_espresso_delete_payment', array($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 = array(
78
+			'buttons' => array(
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
+
102
+		$txn_id = ! empty($this->_req_data['TXN_ID'])
103
+				  && ! is_array($this->_req_data['TXN_ID'])
104
+			? $this->_req_data['TXN_ID']
105
+			: 0;
106
+
107
+		$this->_page_routes = array(
108
+
109
+			'default' => array(
110
+				'func'       => '_transactions_overview_list_table',
111
+				'capability' => 'ee_read_transactions',
112
+			),
113
+
114
+			'view_transaction' => array(
115
+				'func'       => '_transaction_details',
116
+				'capability' => 'ee_read_transaction',
117
+				'obj_id'     => $txn_id,
118
+			),
119
+
120
+			'send_payment_reminder' => array(
121
+				'func'       => '_send_payment_reminder',
122
+				'noheader'   => true,
123
+				'capability' => 'ee_send_message',
124
+			),
125
+
126
+			'espresso_apply_payment' => array(
127
+				'func'       => 'apply_payments_or_refunds',
128
+				'noheader'   => true,
129
+				'capability' => 'ee_edit_payments',
130
+			),
131
+
132
+			'espresso_apply_refund' => array(
133
+				'func'       => 'apply_payments_or_refunds',
134
+				'noheader'   => true,
135
+				'capability' => 'ee_edit_payments',
136
+			),
137
+
138
+			'espresso_delete_payment' => array(
139
+				'func'       => 'delete_payment',
140
+				'noheader'   => true,
141
+				'capability' => 'ee_delete_payments',
142
+			),
143
+
144
+			'espresso_recalculate_line_items' => array(
145
+				'func'       => 'recalculateLineItems',
146
+				'noheader'   => true,
147
+				'capability' => 'ee_edit_payments',
148
+			),
149
+
150
+		);
151
+	}
152
+
153
+
154
+	protected function _set_page_config()
155
+	{
156
+		$this->_page_config = array(
157
+			'default'          => array(
158
+				'nav'           => array(
159
+					'label' => esc_html__('Overview', 'event_espresso'),
160
+					'order' => 10,
161
+				),
162
+				'list_table'    => 'EE_Admin_Transactions_List_Table',
163
+				'help_tabs'     => array(
164
+					'transactions_overview_help_tab'                       => array(
165
+						'title'    => esc_html__('Transactions Overview', 'event_espresso'),
166
+						'filename' => 'transactions_overview',
167
+					),
168
+					'transactions_overview_table_column_headings_help_tab' => array(
169
+						'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
170
+						'filename' => 'transactions_overview_table_column_headings',
171
+					),
172
+					'transactions_overview_views_filters_help_tab'         => array(
173
+						'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
174
+						'filename' => 'transactions_overview_views_filters_search',
175
+					),
176
+				),
177
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
178
+				// 'help_tour'     => array('Transactions_Overview_Help_Tour'),
179
+				/**
180
+				 * commented out because currently we are not displaying tips for transaction list table status but this
181
+				 * may change in a later iteration so want to keep the code for then.
182
+				 */
183
+				// 'qtips' => array( 'Transactions_List_Table_Tips' ),
184
+				'require_nonce' => false,
185
+			),
186
+			'view_transaction' => array(
187
+				'nav'       => array(
188
+					'label'      => esc_html__('View Transaction', 'event_espresso'),
189
+					'order'      => 5,
190
+					'url'        => isset($this->_req_data['TXN_ID'])
191
+						? add_query_arg(array('TXN_ID' => $this->_req_data['TXN_ID']), $this->_current_page_view_url)
192
+						: $this->_admin_base_url,
193
+					'persistent' => false,
194
+				),
195
+				'help_tabs' => array(
196
+					'transactions_view_transaction_help_tab'                                              => array(
197
+						'title'    => esc_html__('View Transaction', 'event_espresso'),
198
+						'filename' => 'transactions_view_transaction',
199
+					),
200
+					'transactions_view_transaction_transaction_details_table_help_tab'                    => array(
201
+						'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
202
+						'filename' => 'transactions_view_transaction_transaction_details_table',
203
+					),
204
+					'transactions_view_transaction_attendees_registered_help_tab'                         => array(
205
+						'title'    => esc_html__('Attendees Registered', 'event_espresso'),
206
+						'filename' => 'transactions_view_transaction_attendees_registered',
207
+					),
208
+					'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => array(
209
+						'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
210
+						'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
211
+					),
212
+				),
213
+				'qtips'     => array('Transaction_Details_Tips'),
214
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
215
+				// 'help_tour' => array('Transaction_Details_Help_Tour'),
216
+				'metaboxes' => array('_transaction_details_metaboxes'),
217
+
218
+				'require_nonce' => false,
219
+			),
220
+		);
221
+	}
222
+
223
+
224
+	/**
225
+	 * The below methods aren't used by this class currently
226
+	 */
227
+	protected function _add_screen_options()
228
+	{
229
+		// noop
230
+	}
231
+
232
+
233
+	protected function _add_feature_pointers()
234
+	{
235
+		// noop
236
+	}
237
+
238
+
239
+	public function admin_init()
240
+	{
241
+		// IF a registration was JUST added via the admin...
242
+		if (
243
+			isset(
244
+				$this->_req_data['redirect_from'],
245
+				$this->_req_data['EVT_ID'],
246
+				$this->_req_data['event_name']
247
+			)
248
+		) {
249
+			// then set a cookie so that we can block any attempts to use
250
+			// the back button as a way to enter another registration.
251
+			setcookie(
252
+				'ee_registration_added',
253
+				$this->_req_data['EVT_ID'],
254
+				time() + WEEK_IN_SECONDS,
255
+				'/'
256
+			);
257
+			// and update the global
258
+			$_COOKIE['ee_registration_added'] = $this->_req_data['EVT_ID'];
259
+		}
260
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
261
+			'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.',
262
+			'event_espresso'
263
+		);
264
+		EE_Registry::$i18n_js_strings['error_occurred'] = esc_html__(
265
+			'An error occurred! Please refresh the page and try again.',
266
+			'event_espresso'
267
+		);
268
+		EE_Registry::$i18n_js_strings['txn_status_array'] = self::$_txn_status;
269
+		EE_Registry::$i18n_js_strings['pay_status_array'] = self::$_pay_status;
270
+		EE_Registry::$i18n_js_strings['payments_total'] = esc_html__('Payments Total', 'event_espresso');
271
+		EE_Registry::$i18n_js_strings['transaction_overpaid'] = esc_html__(
272
+			'This transaction has been overpaid ! Payments Total',
273
+			'event_espresso'
274
+		);
275
+	}
276
+
277
+
278
+	public function admin_notices()
279
+	{
280
+		// noop
281
+	}
282
+
283
+
284
+	public function admin_footer_scripts()
285
+	{
286
+		// noop
287
+	}
288
+
289
+
290
+	/**
291
+	 * _set_transaction_status_array
292
+	 * sets list of transaction statuses
293
+	 *
294
+	 * @access private
295
+	 * @return void
296
+	 * @throws EE_Error
297
+	 * @throws InvalidArgumentException
298
+	 * @throws InvalidDataTypeException
299
+	 * @throws InvalidInterfaceException
300
+	 */
301
+	private function _set_transaction_status_array()
302
+	{
303
+		self::$_txn_status = EEM_Transaction::instance()->status_array(true);
304
+	}
305
+
306
+
307
+	/**
308
+	 * get_transaction_status_array
309
+	 * return the transaction status array for wp_list_table
310
+	 *
311
+	 * @access public
312
+	 * @return array
313
+	 */
314
+	public function get_transaction_status_array()
315
+	{
316
+		return self::$_txn_status;
317
+	}
318
+
319
+
320
+	/**
321
+	 *    get list of payment statuses
322
+	 *
323
+	 * @access private
324
+	 * @return void
325
+	 * @throws EE_Error
326
+	 * @throws InvalidArgumentException
327
+	 * @throws InvalidDataTypeException
328
+	 * @throws InvalidInterfaceException
329
+	 */
330
+	private function _get_payment_status_array()
331
+	{
332
+		self::$_pay_status = EEM_Payment::instance()->status_array(true);
333
+		$this->_template_args['payment_status'] = self::$_pay_status;
334
+	}
335
+
336
+
337
+	/**
338
+	 *    _add_screen_options_default
339
+	 *
340
+	 * @access protected
341
+	 * @return void
342
+	 * @throws InvalidArgumentException
343
+	 * @throws InvalidDataTypeException
344
+	 * @throws InvalidInterfaceException
345
+	 */
346
+	protected function _add_screen_options_default()
347
+	{
348
+		$this->_per_page_screen_option();
349
+	}
350
+
351
+
352
+	/**
353
+	 * load_scripts_styles
354
+	 *
355
+	 * @access public
356
+	 * @return void
357
+	 */
358
+	public function load_scripts_styles()
359
+	{
360
+		// enqueue style
361
+		wp_register_style(
362
+			'espresso_txn',
363
+			TXN_ASSETS_URL . 'espresso_transactions_admin.css',
364
+			array(),
365
+			EVENT_ESPRESSO_VERSION
366
+		);
367
+		wp_enqueue_style('espresso_txn');
368
+		// scripts
369
+		wp_register_script(
370
+			'espresso_txn',
371
+			TXN_ASSETS_URL . 'espresso_transactions_admin.js',
372
+			array(
373
+				'ee_admin_js',
374
+				'ee-datepicker',
375
+				'jquery-ui-datepicker',
376
+				'jquery-ui-draggable',
377
+				'ee-dialog',
378
+				'ee-accounting',
379
+				'ee-serialize-full-array',
380
+			),
381
+			EVENT_ESPRESSO_VERSION,
382
+			true
383
+		);
384
+		wp_enqueue_script('espresso_txn');
385
+	}
386
+
387
+
388
+	/**
389
+	 *    load_scripts_styles_view_transaction
390
+	 *
391
+	 * @access public
392
+	 * @return void
393
+	 */
394
+	public function load_scripts_styles_view_transaction()
395
+	{
396
+		// styles
397
+		wp_enqueue_style('espresso-ui-theme');
398
+	}
399
+
400
+
401
+	/**
402
+	 *    load_scripts_styles_default
403
+	 *
404
+	 * @access public
405
+	 * @return void
406
+	 */
407
+	public function load_scripts_styles_default()
408
+	{
409
+		// styles
410
+		wp_enqueue_style('espresso-ui-theme');
411
+	}
412
+
413
+
414
+	/**
415
+	 *    _set_list_table_views_default
416
+	 *
417
+	 * @access protected
418
+	 * @return void
419
+	 */
420
+	protected function _set_list_table_views_default()
421
+	{
422
+		$this->_views = array(
423
+			'all'        => array(
424
+				'slug'  => 'all',
425
+				'label' => esc_html__('View All Transactions', 'event_espresso'),
426
+				'count' => 0,
427
+			),
428
+			'abandoned'  => array(
429
+				'slug'  => 'abandoned',
430
+				'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
431
+				'count' => 0,
432
+			),
433
+			'incomplete' => array(
434
+				'slug'  => 'incomplete',
435
+				'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
436
+				'count' => 0,
437
+			),
438
+		);
439
+		if (
440 440
 /**
441
-         * Filters whether a link to the "Failed Transactions" list table
442
-         * appears on the Transactions Admin Page list table.
443
-         * List display can be turned back on via the following:
444
-         * add_filter(
445
-         *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
446
-         *     '__return_true'
447
-         * );
448
-         *
449
-         * @since 4.9.70.p
450
-         * @param boolean                 $display_failed_txns_list
451
-         * @param Transactions_Admin_Page $this
452
-         */
453
-            apply_filters(
454
-                'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
455
-                false,
456
-                $this
457
-            )
458
-        ) {
459
-            $this->_views['failed'] = array(
460
-                'slug'  => 'failed',
461
-                'label' => esc_html__('Failed Transactions', 'event_espresso'),
462
-                'count' => 0,
463
-            );
464
-        }
465
-    }
466
-
467
-
468
-    /**
469
-     * _set_transaction_object
470
-     * This sets the _transaction property for the transaction details screen
471
-     *
472
-     * @access private
473
-     * @return void
474
-     * @throws EE_Error
475
-     * @throws InvalidArgumentException
476
-     * @throws RuntimeException
477
-     * @throws InvalidDataTypeException
478
-     * @throws InvalidInterfaceException
479
-     * @throws ReflectionException
480
-     */
481
-    private function _set_transaction_object()
482
-    {
483
-        if ($this->_transaction instanceof EE_Transaction) {
484
-            return;
485
-        } //get out we've already set the object
486
-
487
-        $TXN_ID = ! empty($this->_req_data['TXN_ID'])
488
-            ? absint($this->_req_data['TXN_ID'])
489
-            : false;
490
-
491
-        // get transaction object
492
-        $this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
493
-        $this->_session = $this->_transaction instanceof EE_Transaction
494
-            ? $this->_transaction->session_data()
495
-            : null;
496
-        if ($this->_transaction instanceof EE_Transaction) {
497
-            $this->_transaction->verify_abandoned_transaction_status();
498
-        }
499
-
500
-        if (! $this->_transaction instanceof EE_Transaction) {
501
-            $error_msg = sprintf(
502
-                esc_html__(
503
-                    'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
504
-                    'event_espresso'
505
-                ),
506
-                $TXN_ID
507
-            );
508
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
509
-        }
510
-    }
511
-
512
-
513
-    /**
514
-     *    _transaction_legend_items
515
-     *
516
-     * @access protected
517
-     * @return array
518
-     * @throws EE_Error
519
-     * @throws InvalidArgumentException
520
-     * @throws ReflectionException
521
-     * @throws InvalidDataTypeException
522
-     * @throws InvalidInterfaceException
523
-     */
524
-    protected function _transaction_legend_items()
525
-    {
526
-        EE_Registry::instance()->load_helper('MSG_Template');
527
-        $items = array();
528
-
529
-        if (
530
-            EE_Registry::instance()->CAP->current_user_can(
531
-                'ee_read_global_messages',
532
-                'view_filtered_messages'
533
-            )
534
-        ) {
535
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
536
-            if (
537
-                is_array($related_for_icon)
538
-                && isset($related_for_icon['css_class'], $related_for_icon['label'])
539
-            ) {
540
-                $items['view_related_messages'] = array(
541
-                    'class' => $related_for_icon['css_class'],
542
-                    'desc'  => $related_for_icon['label'],
543
-                );
544
-            }
545
-        }
546
-
547
-        $items = apply_filters(
548
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
549
-            array_merge(
550
-                $items,
551
-                array(
552
-                    'view_details'          => array(
553
-                        'class' => 'dashicons dashicons-cart',
554
-                        'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
555
-                    ),
556
-                    'view_invoice'          => array(
557
-                        'class' => 'dashicons dashicons-media-spreadsheet',
558
-                        'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
559
-                    ),
560
-                    'view_receipt'          => array(
561
-                        'class' => 'dashicons dashicons-media-default',
562
-                        'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
563
-                    ),
564
-                    'view_registration'     => array(
565
-                        'class' => 'dashicons dashicons-clipboard',
566
-                        'desc'  => esc_html__('View Registration Details', 'event_espresso'),
567
-                    ),
568
-                    'payment_overview_link' => array(
569
-                        'class' => 'dashicons dashicons-money',
570
-                        'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
571
-                    ),
572
-                )
573
-            )
574
-        );
575
-
576
-        if (
577
-            EEH_MSG_Template::is_mt_active('payment_reminder')
578
-            && EE_Registry::instance()->CAP->current_user_can(
579
-                'ee_send_message',
580
-                'espresso_transactions_send_payment_reminder'
581
-            )
582
-        ) {
583
-            $items['send_payment_reminder'] = array(
584
-                'class' => 'dashicons dashicons-email-alt',
585
-                'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
586
-            );
587
-        } else {
588
-            $items['blank*'] = array(
589
-                'class' => '',
590
-                'desc'  => '',
591
-            );
592
-        }
593
-        $more_items = apply_filters(
594
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
595
-            array(
596
-                'overpaid'   => array(
597
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
598
-                    'desc'  => EEH_Template::pretty_status(
599
-                        EEM_Transaction::overpaid_status_code,
600
-                        false,
601
-                        'sentence'
602
-                    ),
603
-                ),
604
-                'complete'   => array(
605
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
606
-                    'desc'  => EEH_Template::pretty_status(
607
-                        EEM_Transaction::complete_status_code,
608
-                        false,
609
-                        'sentence'
610
-                    ),
611
-                ),
612
-                'incomplete' => array(
613
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
614
-                    'desc'  => EEH_Template::pretty_status(
615
-                        EEM_Transaction::incomplete_status_code,
616
-                        false,
617
-                        'sentence'
618
-                    ),
619
-                ),
620
-                'abandoned'  => array(
621
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
622
-                    'desc'  => EEH_Template::pretty_status(
623
-                        EEM_Transaction::abandoned_status_code,
624
-                        false,
625
-                        'sentence'
626
-                    ),
627
-                ),
628
-                'failed'     => array(
629
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
630
-                    'desc'  => EEH_Template::pretty_status(
631
-                        EEM_Transaction::failed_status_code,
632
-                        false,
633
-                        'sentence'
634
-                    ),
635
-                ),
636
-            )
637
-        );
638
-
639
-        return array_merge($items, $more_items);
640
-    }
641
-
642
-
643
-    /**
644
-     *    _transactions_overview_list_table
645
-     *
646
-     * @access protected
647
-     * @return void
648
-     * @throws DomainException
649
-     * @throws EE_Error
650
-     * @throws InvalidArgumentException
651
-     * @throws InvalidDataTypeException
652
-     * @throws InvalidInterfaceException
653
-     * @throws ReflectionException
654
-     */
655
-    protected function _transactions_overview_list_table()
656
-    {
657
-        $this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
658
-        $event = isset($this->_req_data['EVT_ID'])
659
-            ? EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID'])
660
-            : null;
661
-        $this->_template_args['admin_page_header'] = $event instanceof EE_Event
662
-            ? sprintf(
663
-                esc_html__(
664
-                    '%sViewing Transactions for the Event: %s%s',
665
-                    'event_espresso'
666
-                ),
667
-                '<h3>',
668
-                '<a href="'
669
-                . EE_Admin_Page::add_query_args_and_nonce(
670
-                    array('action' => 'edit', 'post' => $event->ID()),
671
-                    EVENTS_ADMIN_URL
672
-                )
673
-                . '" title="'
674
-                . esc_attr__(
675
-                    'Click to Edit event',
676
-                    'event_espresso'
677
-                )
678
-                . '">' . $event->name() . '</a>',
679
-                '</h3>'
680
-            )
681
-            : '';
682
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_transaction_legend_items());
683
-        $this->display_admin_list_table_page_with_no_sidebar();
684
-    }
685
-
686
-
687
-    /**
688
-     *    _transaction_details
689
-     * generates HTML for the View Transaction Details Admin page
690
-     *
691
-     * @access protected
692
-     * @return void
693
-     * @throws DomainException
694
-     * @throws EE_Error
695
-     * @throws InvalidArgumentException
696
-     * @throws InvalidDataTypeException
697
-     * @throws InvalidInterfaceException
698
-     * @throws RuntimeException
699
-     * @throws ReflectionException
700
-     */
701
-    protected function _transaction_details()
702
-    {
703
-        do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
704
-
705
-        $this->_set_transaction_status_array();
706
-
707
-        $this->_template_args = array();
708
-        $this->_template_args['transactions_page'] = $this->_wp_page_slug;
709
-
710
-        $this->_set_transaction_object();
711
-
712
-        if (! $this->_transaction instanceof EE_Transaction) {
713
-            return;
714
-        }
715
-        $primary_registration = $this->_transaction->primary_registration();
716
-        $attendee = $primary_registration instanceof EE_Registration
717
-            ? $primary_registration->attendee()
718
-            : null;
719
-
720
-        $this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
721
-        $this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
722
-
723
-        $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
724
-        $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
725
-
726
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
727
-        $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
728
-        $this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->status_ID();
729
-
730
-        $this->_template_args['grand_total'] = $this->_transaction->total();
731
-        $this->_template_args['total_paid'] = $this->_transaction->paid();
732
-
733
-        $amount_due = $this->_transaction->total() - $this->_transaction->paid();
734
-        $this->_template_args['amount_due'] = EEH_Template::format_currency(
735
-            $amount_due,
736
-            true
737
-        );
738
-        if (EE_Registry::instance()->CFG->currency->sign_b4) {
739
-            $this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign
740
-                                                  . $this->_template_args['amount_due'];
741
-        } else {
742
-            $this->_template_args['amount_due'] .= EE_Registry::instance()->CFG->currency->sign;
743
-        }
744
-        $this->_template_args['amount_due_class'] = '';
745
-
746
-        if ($this->_transaction->paid() === $this->_transaction->total()) {
747
-            // paid in full
748
-            $this->_template_args['amount_due'] = false;
749
-        } elseif ($this->_transaction->paid() > $this->_transaction->total()) {
750
-            // overpaid
751
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
752
-        } elseif ($this->_transaction->total() > (float) 0) {
753
-            if ($this->_transaction->paid() > (float) 0) {
754
-                // monies owing
755
-                $this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
756
-            } elseif ($this->_transaction->paid() === (float) 0) {
757
-                // no payments made yet
758
-                $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
759
-            }
760
-        } elseif ($this->_transaction->total() === (float) 0) {
761
-            // free event
762
-            $this->_template_args['amount_due'] = false;
763
-        }
764
-
765
-        $payment_method = $this->_transaction->payment_method();
766
-
767
-        $this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
768
-            ? $payment_method->admin_name()
769
-            : esc_html__('Unknown', 'event_espresso');
770
-
771
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
772
-        // link back to overview
773
-        $this->_template_args['txn_overview_url'] = $this->request->getServerParam(
774
-            'HTTP_REFERER',
775
-            TXN_ADMIN_URL
776
-        );
777
-
778
-
779
-        // next link
780
-        $next_txn = $this->_transaction->next(
781
-            null,
782
-            array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
783
-            'TXN_ID'
784
-        );
785
-        $this->_template_args['next_transaction'] = $next_txn
786
-            ? $this->_next_link(
787
-                EE_Admin_Page::add_query_args_and_nonce(
788
-                    array('action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']),
789
-                    TXN_ADMIN_URL
790
-                ),
791
-                'dashicons dashicons-arrow-right ee-icon-size-22'
792
-            )
793
-            : '';
794
-        // previous link
795
-        $previous_txn = $this->_transaction->previous(
796
-            null,
797
-            array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
798
-            'TXN_ID'
799
-        );
800
-        $this->_template_args['previous_transaction'] = $previous_txn
801
-            ? $this->_previous_link(
802
-                EE_Admin_Page::add_query_args_and_nonce(
803
-                    array('action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']),
804
-                    TXN_ADMIN_URL
805
-                ),
806
-                'dashicons dashicons-arrow-left ee-icon-size-22'
807
-            )
808
-            : '';
809
-
810
-        // were we just redirected here after adding a new registration ???
811
-        if (
812
-            isset(
813
-                $this->_req_data['redirect_from'],
814
-                $this->_req_data['EVT_ID'],
815
-                $this->_req_data['event_name']
816
-            )
817
-        ) {
818
-            if (
819
-                EE_Registry::instance()->CAP->current_user_can(
820
-                    'ee_edit_registrations',
821
-                    'espresso_registrations_new_registration',
822
-                    $this->_req_data['EVT_ID']
823
-                )
824
-            ) {
825
-                $this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button-primary" href="';
826
-                $this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
827
-                    array(
828
-                        'page'     => 'espresso_registrations',
829
-                        'action'   => 'new_registration',
830
-                        'return'   => 'default',
831
-                        'TXN_ID'   => $this->_transaction->ID(),
832
-                        'event_id' => $this->_req_data['EVT_ID'],
833
-                    ),
834
-                    REG_ADMIN_URL
835
-                );
836
-                $this->_admin_page_title .= '">';
837
-
838
-                $this->_admin_page_title .= sprintf(
839
-                    esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
840
-                    htmlentities(urldecode($this->_req_data['event_name']), ENT_QUOTES, 'UTF-8')
841
-                );
842
-                $this->_admin_page_title .= '</a>';
843
-            }
844
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
845
-        }
846
-        // grab messages at the last second
847
-        $this->_template_args['notices'] = EE_Error::get_notices();
848
-        // path to template
849
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
850
-        $this->_template_args['admin_page_header'] = EEH_Template::display_template(
851
-            $template_path,
852
-            $this->_template_args,
853
-            true
854
-        );
855
-
856
-        // the details template wrapper
857
-        $this->display_admin_page_with_sidebar();
858
-    }
859
-
860
-
861
-    /**
862
-     *        _transaction_details_metaboxes
863
-     *
864
-     * @access protected
865
-     * @return void
866
-     * @throws EE_Error
867
-     * @throws InvalidArgumentException
868
-     * @throws InvalidDataTypeException
869
-     * @throws InvalidInterfaceException
870
-     * @throws RuntimeException
871
-     * @throws ReflectionException
872
-     */
873
-    protected function _transaction_details_metaboxes()
874
-    {
875
-
876
-        $this->_set_transaction_object();
877
-
878
-        if (! $this->_transaction instanceof EE_Transaction) {
879
-            return;
880
-        }
881
-        add_meta_box(
882
-            'edit-txn-details-mbox',
883
-            esc_html__('Transaction Details', 'event_espresso'),
884
-            array($this, 'txn_details_meta_box'),
885
-            $this->_wp_page_slug,
886
-            'normal',
887
-            'high'
888
-        );
889
-        add_meta_box(
890
-            'edit-txn-attendees-mbox',
891
-            esc_html__('Attendees Registered in this Transaction', 'event_espresso'),
892
-            array($this, 'txn_attendees_meta_box'),
893
-            $this->_wp_page_slug,
894
-            'normal',
895
-            'high',
896
-            array('TXN_ID' => $this->_transaction->ID())
897
-        );
898
-        add_meta_box(
899
-            'edit-txn-registrant-mbox',
900
-            esc_html__('Primary Contact', 'event_espresso'),
901
-            array($this, 'txn_registrant_side_meta_box'),
902
-            $this->_wp_page_slug,
903
-            'side',
904
-            'high'
905
-        );
906
-        add_meta_box(
907
-            'edit-txn-billing-info-mbox',
908
-            esc_html__('Billing Information', 'event_espresso'),
909
-            array($this, 'txn_billing_info_side_meta_box'),
910
-            $this->_wp_page_slug,
911
-            'side',
912
-            'high'
913
-        );
914
-    }
915
-
916
-
917
-    /**
918
-     * Callback for transaction actions metabox.
919
-     *
920
-     * @param EE_Transaction|null $transaction
921
-     * @return string
922
-     * @throws DomainException
923
-     * @throws EE_Error
924
-     * @throws InvalidArgumentException
925
-     * @throws InvalidDataTypeException
926
-     * @throws InvalidInterfaceException
927
-     * @throws ReflectionException
928
-     * @throws RuntimeException
929
-     */
930
-    public function getActionButtons(EE_Transaction $transaction = null)
931
-    {
932
-        $content = '';
933
-        $actions = array();
934
-        if (! $transaction instanceof EE_Transaction) {
935
-            return $content;
936
-        }
937
-        /** @var EE_Registration $primary_registration */
938
-        $primary_registration = $transaction->primary_registration();
939
-        $attendee = $primary_registration instanceof EE_Registration
940
-            ? $primary_registration->attendee()
941
-            : null;
942
-
943
-        if (
944
-            $attendee instanceof EE_Attendee
945
-            && EE_Registry::instance()->CAP->current_user_can(
946
-                'ee_send_message',
947
-                'espresso_transactions_send_payment_reminder'
948
-            )
949
-        ) {
950
-            $actions['payment_reminder'] =
951
-                EEH_MSG_Template::is_mt_active('payment_reminder')
952
-                && $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
953
-                && $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
954
-                    ? EEH_Template::get_button_or_link(
955
-                        EE_Admin_Page::add_query_args_and_nonce(
956
-                            array(
957
-                                'action'      => 'send_payment_reminder',
958
-                                'TXN_ID'      => $this->_transaction->ID(),
959
-                                'redirect_to' => 'view_transaction',
960
-                            ),
961
-                            TXN_ADMIN_URL
962
-                        ),
963
-                        esc_html__(' Send Payment Reminder', 'event_espresso'),
964
-                        'button secondary-button',
965
-                        'dashicons dashicons-email-alt'
966
-                    )
967
-                    : '';
968
-        }
969
-
970
-        if (
971
-            EE_Registry::instance()->CAP->current_user_can(
972
-                'ee_edit_payments',
973
-                'espresso_transactions_recalculate_line_items'
974
-            )
975
-        ) {
976
-            $actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
977
-                EE_Admin_Page::add_query_args_and_nonce(
978
-                    array(
979
-                        'action'      => 'espresso_recalculate_line_items',
980
-                        'TXN_ID'      => $this->_transaction->ID(),
981
-                        'redirect_to' => 'view_transaction',
982
-                    ),
983
-                    TXN_ADMIN_URL
984
-                ),
985
-                esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
986
-                'button secondary-button',
987
-                'dashicons dashicons-update'
988
-            );
989
-        }
990
-
991
-        if (
992
-            $primary_registration instanceof EE_Registration
993
-            && EEH_MSG_Template::is_mt_active('receipt')
994
-        ) {
995
-            $actions['receipt'] = EEH_Template::get_button_or_link(
996
-                $primary_registration->receipt_url(),
997
-                esc_html__('View Receipt', 'event_espresso'),
998
-                'button secondary-button',
999
-                'dashicons dashicons-media-default'
1000
-            );
1001
-        }
1002
-
1003
-        if (
1004
-            $primary_registration instanceof EE_Registration
1005
-            && EEH_MSG_Template::is_mt_active('invoice')
1006
-        ) {
1007
-            $actions['invoice'] = EEH_Template::get_button_or_link(
1008
-                $primary_registration->invoice_url(),
1009
-                esc_html__('View Invoice', 'event_espresso'),
1010
-                'button secondary-button',
1011
-                'dashicons dashicons-media-spreadsheet'
1012
-            );
1013
-        }
1014
-        $actions = array_filter(
1015
-            apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
1016
-        );
1017
-        if ($actions) {
1018
-            $content = '<ul>';
1019
-            $content .= '<li>' . implode('</li><li>', $actions) . '</li>';
1020
-            $content .= '</uL>';
1021
-        }
1022
-        return $content;
1023
-    }
1024
-
1025
-
1026
-    /**
1027
-     * txn_details_meta_box
1028
-     * generates HTML for the Transaction main meta box
1029
-     *
1030
-     * @return void
1031
-     * @throws DomainException
1032
-     * @throws EE_Error
1033
-     * @throws InvalidArgumentException
1034
-     * @throws InvalidDataTypeException
1035
-     * @throws InvalidInterfaceException
1036
-     * @throws RuntimeException
1037
-     * @throws ReflectionException
1038
-     */
1039
-    public function txn_details_meta_box()
1040
-    {
1041
-        $this->_set_transaction_object();
1042
-        $this->_template_args['TXN_ID'] = $this->_transaction->ID();
1043
-        $this->_template_args['attendee'] = $this->_transaction->primary_registration() instanceof EE_Registration
1044
-            ? $this->_transaction->primary_registration()->attendee()
1045
-            : null;
1046
-        $this->_template_args['can_edit_payments'] = EE_Registry::instance()->CAP->current_user_can(
1047
-            'ee_edit_payments',
1048
-            'apply_payment_or_refund_from_registration_details'
1049
-        );
1050
-        $this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1051
-            'ee_delete_payments',
1052
-            'delete_payment_from_registration_details'
1053
-        );
1054
-
1055
-        // get line table
1056
-        EEH_Autoloader::register_line_item_display_autoloaders();
1057
-        $Line_Item_Display = new EE_Line_Item_Display(
1058
-            'admin_table',
1059
-            'EE_Admin_Table_Line_Item_Display_Strategy'
1060
-        );
1061
-        $this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1062
-            $this->_transaction->total_line_item()
1063
-        );
1064
-        $this->_template_args['REG_code'] = $this->_transaction->primary_registration() instanceof EE_Registration
1065
-            ? $this->_transaction->primary_registration()->reg_code()
1066
-            : null;
1067
-        // process taxes
1068
-        $taxes = $this->_transaction->line_items(array(array('LIN_type' => EEM_Line_Item::type_tax)));
1069
-        $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1070
-
1071
-        $this->_template_args['grand_total'] = EEH_Template::format_currency(
1072
-            $this->_transaction->total(),
1073
-            false,
1074
-            false
1075
-        );
1076
-        $this->_template_args['grand_raw_total'] = $this->_transaction->total();
1077
-        $this->_template_args['TXN_status'] = $this->_transaction->status_ID();
1078
-
1079
-        // process payment details
1080
-        $payments = $this->_transaction->payments();
1081
-        if (! empty($payments)) {
1082
-            $this->_template_args['payments'] = $payments;
1083
-            $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1084
-        } else {
1085
-            $this->_template_args['payments'] = false;
1086
-            $this->_template_args['existing_reg_payments'] = array();
1087
-        }
1088
-
1089
-        $this->_template_args['edit_payment_url'] = add_query_arg(array('action' => 'edit_payment'), TXN_ADMIN_URL);
1090
-        $this->_template_args['delete_payment_url'] = add_query_arg(
1091
-            array('action' => 'espresso_delete_payment'),
1092
-            TXN_ADMIN_URL
1093
-        );
1094
-
1095
-        if (isset($txn_details['invoice_number'])) {
1096
-            $this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1097
-            $this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1098
-                'Invoice Number',
1099
-                'event_espresso'
1100
-            );
1101
-        }
1102
-
1103
-        $this->_template_args['txn_details']['registration_session']['value']
1104
-            = $this->_transaction->primary_registration() instanceof EE_Registration
1105
-            ? $this->_transaction->primary_registration()->session_ID()
1106
-            : null;
1107
-        $this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1108
-            'Registration Session',
1109
-            'event_espresso'
1110
-        );
1111
-
1112
-        $this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address'])
1113
-            ? $this->_session['ip_address']
1114
-            : '';
1115
-        $this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1116
-            'Transaction placed from IP',
1117
-            'event_espresso'
1118
-        );
1119
-
1120
-        $this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent'])
1121
-            ? $this->_session['user_agent']
1122
-            : '';
1123
-        $this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1124
-            'Registrant User Agent',
1125
-            'event_espresso'
1126
-        );
1127
-
1128
-        $reg_steps = '<ul>';
1129
-        foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1130
-            if ($reg_step_status === true) {
1131
-                $reg_steps .= '<li style="color:#70cc50">'
1132
-                              . sprintf(
1133
-                                  esc_html__('%1$s : Completed', 'event_espresso'),
1134
-                                  ucwords(str_replace('_', ' ', $reg_step))
1135
-                              )
1136
-                              . '</li>';
1137
-            } elseif (is_numeric($reg_step_status) && $reg_step_status !== false) {
1138
-                $reg_steps .= '<li style="color:#2EA2CC">'
1139
-                              . sprintf(
1140
-                                  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1141
-                                  ucwords(str_replace('_', ' ', $reg_step)),
1142
-                                  date(
1143
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1144
-                                      $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1145
-                                  )
1146
-                              )
1147
-                              . '</li>';
1148
-            } else {
1149
-                $reg_steps .= '<li style="color:#E76700">'
1150
-                              . sprintf(
1151
-                                  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1152
-                                  ucwords(str_replace('_', ' ', $reg_step))
1153
-                              )
1154
-                              . '</li>';
1155
-            }
1156
-        }
1157
-        $reg_steps .= '</ul>';
1158
-        $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1159
-        $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1160
-            'Registration Step Progress',
1161
-            'event_espresso'
1162
-        );
1163
-
1164
-
1165
-        $this->_get_registrations_to_apply_payment_to();
1166
-        $this->_get_payment_methods($payments);
1167
-        $this->_get_payment_status_array();
1168
-        $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1169
-
1170
-        $this->_template_args['transaction_form_url'] = add_query_arg(
1171
-            array(
1172
-                'action'  => 'edit_transaction',
1173
-                'process' => 'transaction',
1174
-            ),
1175
-            TXN_ADMIN_URL
1176
-        );
1177
-        $this->_template_args['apply_payment_form_url'] = add_query_arg(
1178
-            array(
1179
-                'page'   => 'espresso_transactions',
1180
-                'action' => 'espresso_apply_payment',
1181
-            ),
1182
-            WP_AJAX_URL
1183
-        );
1184
-        $this->_template_args['delete_payment_form_url'] = add_query_arg(
1185
-            array(
1186
-                'page'   => 'espresso_transactions',
1187
-                'action' => 'espresso_delete_payment',
1188
-            ),
1189
-            WP_AJAX_URL
1190
-        );
1191
-
1192
-        $this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1193
-
1194
-        // 'espresso_delete_payment_nonce'
1195
-
1196
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1197
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1198
-    }
1199
-
1200
-
1201
-    /**
1202
-     * _get_registration_payment_IDs
1203
-     *    generates an array of Payment IDs and their corresponding Registration IDs
1204
-     *
1205
-     * @access protected
1206
-     * @param EE_Payment[] $payments
1207
-     * @return array
1208
-     * @throws EE_Error
1209
-     * @throws InvalidArgumentException
1210
-     * @throws InvalidDataTypeException
1211
-     * @throws InvalidInterfaceException
1212
-     * @throws ReflectionException
1213
-     */
1214
-    protected function _get_registration_payment_IDs($payments = array())
1215
-    {
1216
-        $existing_reg_payments = array();
1217
-        // get all reg payments for these payments
1218
-        $reg_payments = EEM_Registration_Payment::instance()->get_all(
1219
-            array(
1220
-                array(
1221
-                    'PAY_ID' => array(
1222
-                        'IN',
1223
-                        array_keys($payments),
1224
-                    ),
1225
-                ),
1226
-            )
1227
-        );
1228
-        if (! empty($reg_payments)) {
1229
-            foreach ($payments as $payment) {
1230
-                if (! $payment instanceof EE_Payment) {
1231
-                    continue;
1232
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1233
-                    $existing_reg_payments[ $payment->ID() ] = array();
1234
-                }
1235
-                foreach ($reg_payments as $reg_payment) {
1236
-                    if (
1237
-                        $reg_payment instanceof EE_Registration_Payment
1238
-                        && $reg_payment->payment_ID() === $payment->ID()
1239
-                    ) {
1240
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1241
-                    }
1242
-                }
1243
-            }
1244
-        }
1245
-
1246
-        return $existing_reg_payments;
1247
-    }
1248
-
1249
-
1250
-    /**
1251
-     * _get_registrations_to_apply_payment_to
1252
-     *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1253
-     * which allows the admin to only apply the payment to the specific registrations
1254
-     *
1255
-     * @access protected
1256
-     * @return void
1257
-     * @throws EE_Error
1258
-     * @throws InvalidArgumentException
1259
-     * @throws InvalidDataTypeException
1260
-     * @throws InvalidInterfaceException
1261
-     * @throws ReflectionException
1262
-     */
1263
-    protected function _get_registrations_to_apply_payment_to()
1264
-    {
1265
-        // we want any registration with an active status (ie: not deleted or cancelled)
1266
-        $query_params = array(
1267
-            array(
1268
-                'STS_ID' => array(
1269
-                    'IN',
1270
-                    array(
1271
-                        EEM_Registration::status_id_approved,
1272
-                        EEM_Registration::status_id_pending_payment,
1273
-                        EEM_Registration::status_id_not_approved,
1274
-                    ),
1275
-                ),
1276
-            ),
1277
-        );
1278
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1279
-            '',
1280
-            'txn-admin-apply-payment-to-registrations-dv',
1281
-            '',
1282
-            'clear: both; margin: 1.5em 0 0; display: none;'
1283
-        );
1284
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1285
-        $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
1286
-        $registrations_to_apply_payment_to .= EEH_HTML::thead(
1287
-            EEH_HTML::tr(
1288
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1289
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1290
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1291
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1292
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1293
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1294
-                EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1295
-            )
1296
-        );
1297
-        $registrations_to_apply_payment_to .= EEH_HTML::tbody();
1298
-        // get registrations for TXN
1299
-        $registrations = $this->_transaction->registrations($query_params);
1300
-        $existing_reg_payments = $this->_template_args['existing_reg_payments'];
1301
-        foreach ($registrations as $registration) {
1302
-            if ($registration instanceof EE_Registration) {
1303
-                $attendee_name = $registration->attendee() instanceof EE_Attendee
1304
-                    ? $registration->attendee()->full_name()
1305
-                    : esc_html__('Unknown Attendee', 'event_espresso');
1306
-                $owing = $registration->final_price() - $registration->paid();
1307
-                $taxable = $registration->ticket()->taxable()
1308
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1309
-                    : '';
1310
-                $checked = empty($existing_reg_payments)
1311
-                           || in_array($registration->ID(), $existing_reg_payments, true)
1312
-                    ? ' checked="checked"'
1313
-                    : '';
1314
-                $disabled = $registration->final_price() > 0 ? '' : ' disabled';
1315
-                $registrations_to_apply_payment_to .= EEH_HTML::tr(
1316
-                    EEH_HTML::td($registration->ID()) .
1317
-                    EEH_HTML::td($attendee_name) .
1318
-                    EEH_HTML::td(
1319
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1320
-                    ) .
1321
-                    EEH_HTML::td($registration->event_name()) .
1322
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1323
-                    EEH_HTML::td(
1324
-                        EEH_Template::format_currency($owing),
1325
-                        '',
1326
-                        'txn-admin-payment-owing-td jst-cntr'
1327
-                    ) .
1328
-                    EEH_HTML::td(
1329
-                        '<input type="checkbox" value="' . $registration->ID()
1330
-                        . '" name="txn_admin_payment[registrations]"'
1331
-                        . $checked . $disabled . '>',
1332
-                        '',
1333
-                        'jst-cntr'
1334
-                    ),
1335
-                    'apply-payment-registration-row-' . $registration->ID()
1336
-                );
1337
-            }
1338
-        }
1339
-        $registrations_to_apply_payment_to .= EEH_HTML::tbodyx();
1340
-        $registrations_to_apply_payment_to .= EEH_HTML::tablex();
1341
-        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1342
-        $registrations_to_apply_payment_to .= EEH_HTML::p(
1343
-            esc_html__(
1344
-                '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.',
1345
-                'event_espresso'
1346
-            ),
1347
-            '',
1348
-            'clear description'
1349
-        );
1350
-        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1351
-        $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1352
-    }
1353
-
1354
-
1355
-    /**
1356
-     * _get_reg_status_selection
1357
-     *
1358
-     * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1359
-     *         instead of events.
1360
-     * @access protected
1361
-     * @return void
1362
-     * @throws EE_Error
1363
-     */
1364
-    protected function _get_reg_status_selection()
1365
-    {
1366
-        // first get all possible statuses
1367
-        $statuses = EEM_Registration::reg_status_array(array(), true);
1368
-        // let's add a "don't change" option.
1369
-        $status_array['NAN'] = esc_html__('Leave the Same', 'event_espresso');
1370
-        $status_array = array_merge($status_array, $statuses);
1371
-        $this->_template_args['status_change_select'] = EEH_Form_Fields::select_input(
1372
-            'txn_reg_status_change[reg_status]',
1373
-            $status_array,
1374
-            'NAN',
1375
-            'id="txn-admin-payment-reg-status-inp"',
1376
-            'txn-reg-status-change-reg-status'
1377
-        );
1378
-        $this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1379
-            'delete_txn_reg_status_change[reg_status]',
1380
-            $status_array,
1381
-            'NAN',
1382
-            'delete-txn-admin-payment-reg-status-inp',
1383
-            'delete-txn-reg-status-change-reg-status'
1384
-        );
1385
-    }
1386
-
1387
-
1388
-    /**
1389
-     *    _get_payment_methods
1390
-     * Gets all the payment methods available generally, or the ones that are already
1391
-     * selected on these payments (in case their payment methods are no longer active).
1392
-     * Has the side-effect of updating the template args' payment_methods item
1393
-     *
1394
-     * @access private
1395
-     * @param EE_Payment[] to show on this page
1396
-     * @return void
1397
-     * @throws EE_Error
1398
-     * @throws InvalidArgumentException
1399
-     * @throws InvalidDataTypeException
1400
-     * @throws InvalidInterfaceException
1401
-     * @throws ReflectionException
1402
-     */
1403
-    private function _get_payment_methods($payments = array())
1404
-    {
1405
-        $payment_methods_of_payments = array();
1406
-        foreach ($payments as $payment) {
1407
-            if ($payment instanceof EE_Payment) {
1408
-                $payment_methods_of_payments[] = $payment->ID();
1409
-            }
1410
-        }
1411
-        if ($payment_methods_of_payments) {
1412
-            $query_args = array(
1413
-                array(
1414
-                    'OR*payment_method_for_payment' => array(
1415
-                        'PMD_ID'    => array('IN', $payment_methods_of_payments),
1416
-                        'PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%'),
1417
-                    ),
1418
-                ),
1419
-            );
1420
-        } else {
1421
-            $query_args = array(array('PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%')));
1422
-        }
1423
-        $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1424
-    }
1425
-
1426
-
1427
-    /**
1428
-     * txn_attendees_meta_box
1429
-     *    generates HTML for the Attendees Transaction main meta box
1430
-     *
1431
-     * @access public
1432
-     * @param WP_Post $post
1433
-     * @param array   $metabox
1434
-     * @return void
1435
-     * @throws DomainException
1436
-     * @throws EE_Error
1437
-     * @throws InvalidArgumentException
1438
-     * @throws InvalidDataTypeException
1439
-     * @throws InvalidInterfaceException
1440
-     * @throws ReflectionException
1441
-     */
1442
-    public function txn_attendees_meta_box($post, $metabox = array('args' => array()))
1443
-    {
1444
-
1445
-        /** @noinspection NonSecureExtractUsageInspection */
1446
-        extract($metabox['args']);
1447
-        $this->_template_args['post'] = $post;
1448
-        $this->_template_args['event_attendees'] = array();
1449
-        // process items in cart
1450
-        $line_items = $this->_transaction->get_many_related(
1451
-            'Line_Item',
1452
-            array(array('LIN_type' => 'line-item'))
1453
-        );
1454
-        if (! empty($line_items)) {
1455
-            foreach ($line_items as $item) {
1456
-                if ($item instanceof EE_Line_Item) {
1457
-                    switch ($item->OBJ_type()) {
1458
-                        case 'Event':
1459
-                            break;
1460
-                        case 'Ticket':
1461
-                            $ticket = $item->ticket();
1462
-                            // right now we're only handling tickets here.
1463
-                            // Cause its expected that only tickets will have attendees right?
1464
-                            if (! $ticket instanceof EE_Ticket) {
1465
-                                break;
1466
-                            }
1467
-                            try {
1468
-                                $event_name = $ticket->get_event_name();
1469
-                            } catch (Exception $e) {
1470
-                                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1471
-                                $event_name = esc_html__('Unknown Event', 'event_espresso');
1472
-                            }
1473
-                            $event_name .= ' - ' . $item->name();
1474
-                            $ticket_price = EEH_Template::format_currency($item->unit_price());
1475
-                            // now get all of the registrations for this transaction that use this ticket
1476
-                            $registrations = $ticket->registrations(
1477
-                                array(array('TXN_ID' => $this->_transaction->ID()))
1478
-                            );
1479
-                            foreach ($registrations as $registration) {
1480
-                                if (! $registration instanceof EE_Registration) {
1481
-                                    break;
1482
-                                }
1483
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1484
-                                    = $registration->status_ID();
1485
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1486
-                                    = $registration->count();
1487
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1488
-                                    = $event_name;
1489
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1490
-                                    = $ticket_price;
1491
-                                // attendee info
1492
-                                $attendee = $registration->get_first_related('Attendee');
1493
-                                if ($attendee instanceof EE_Attendee) {
1494
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1495
-                                        = $attendee->ID();
1496
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1497
-                                        = $attendee->full_name();
1498
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1499
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1500
-                                          . esc_html__(
1501
-                                              ' Event',
1502
-                                              'event_espresso'
1503
-                                          )
1504
-                                          . '">' . $attendee->email() . '</a>';
1505
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1506
-                                        = EEH_Address::format($attendee, 'inline', false, false);
1507
-                                } else {
1508
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id'] = '';
1509
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1510
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email'] = '';
1511
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address'] = '';
1512
-                                }
1513
-                            }
1514
-                            break;
1515
-                    }
1516
-                }
1517
-            }
1518
-
1519
-            $this->_template_args['transaction_form_url'] = add_query_arg(
1520
-                array(
1521
-                    'action'  => 'edit_transaction',
1522
-                    'process' => 'attendees',
1523
-                ),
1524
-                TXN_ADMIN_URL
1525
-            );
1526
-            echo EEH_Template::display_template(
1527
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1528
-                $this->_template_args,
1529
-                true
1530
-            );
1531
-        } else {
1532
-            echo sprintf(
1533
-                esc_html__(
1534
-                    '%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1535
-                    'event_espresso'
1536
-                ),
1537
-                '<p class="important-notice">',
1538
-                '</p>'
1539
-            );
1540
-        }
1541
-    }
1542
-
1543
-
1544
-    /**
1545
-     * txn_registrant_side_meta_box
1546
-     * generates HTML for the Edit Transaction side meta box
1547
-     *
1548
-     * @access public
1549
-     * @return void
1550
-     * @throws DomainException
1551
-     * @throws EE_Error
1552
-     * @throws InvalidArgumentException
1553
-     * @throws InvalidDataTypeException
1554
-     * @throws InvalidInterfaceException
1555
-     * @throws ReflectionException
1556
-     */
1557
-    public function txn_registrant_side_meta_box()
1558
-    {
1559
-        $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1560
-            ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1561
-            : null;
1562
-        if (! $primary_att instanceof EE_Attendee) {
1563
-            $this->_template_args['no_attendee_message'] = esc_html__(
1564
-                'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1565
-                'event_espresso'
1566
-            );
1567
-            $primary_att = EEM_Attendee::instance()->create_default_object();
1568
-        }
1569
-        $this->_template_args['ATT_ID'] = $primary_att->ID();
1570
-        $this->_template_args['prime_reg_fname'] = $primary_att->fname();
1571
-        $this->_template_args['prime_reg_lname'] = $primary_att->lname();
1572
-        $this->_template_args['prime_reg_email'] = $primary_att->email();
1573
-        $this->_template_args['prime_reg_phone'] = $primary_att->phone();
1574
-        $this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1575
-            array(
1576
-                'action' => 'edit_attendee',
1577
-                'post'   => $primary_att->ID(),
1578
-            ),
1579
-            REG_ADMIN_URL
1580
-        );
1581
-        // get formatted address for registrant
1582
-        $this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1583
-        echo EEH_Template::display_template(
1584
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1585
-            $this->_template_args,
1586
-            true
1587
-        );
1588
-    }
1589
-
1590
-
1591
-    /**
1592
-     * txn_billing_info_side_meta_box
1593
-     *    generates HTML for the Edit Transaction side meta box
1594
-     *
1595
-     * @access public
1596
-     * @return void
1597
-     * @throws DomainException
1598
-     * @throws EE_Error
1599
-     */
1600
-    public function txn_billing_info_side_meta_box()
1601
-    {
1602
-
1603
-        $this->_template_args['billing_form'] = $this->_transaction->billing_info();
1604
-        $this->_template_args['billing_form_url'] = add_query_arg(
1605
-            array('action' => 'edit_transaction', 'process' => 'billing'),
1606
-            TXN_ADMIN_URL
1607
-        );
1608
-
1609
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1610
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1611
-    }
1612
-
1613
-
1614
-    /**
1615
-     * apply_payments_or_refunds
1616
-     *    registers a payment or refund made towards a transaction
1617
-     *
1618
-     * @access public
1619
-     * @return void
1620
-     * @throws EE_Error
1621
-     * @throws InvalidArgumentException
1622
-     * @throws ReflectionException
1623
-     * @throws RuntimeException
1624
-     * @throws InvalidDataTypeException
1625
-     * @throws InvalidInterfaceException
1626
-     */
1627
-    public function apply_payments_or_refunds()
1628
-    {
1629
-        $json_response_data = array('return_data' => false);
1630
-        $valid_data = $this->_validate_payment_request_data();
1631
-        $has_access = EE_Registry::instance()->CAP->current_user_can(
1632
-            'ee_edit_payments',
1633
-            'apply_payment_or_refund_from_registration_details'
1634
-        );
1635
-        if (! empty($valid_data) && $has_access) {
1636
-            $PAY_ID = $valid_data['PAY_ID'];
1637
-            // save  the new payment
1638
-            $payment = $this->_create_payment_from_request_data($valid_data);
1639
-            // get the TXN for this payment
1640
-            $transaction = $payment->transaction();
1641
-            // verify transaction
1642
-            if ($transaction instanceof EE_Transaction) {
1643
-                // calculate_total_payments_and_update_status
1644
-                $this->_process_transaction_payments($transaction);
1645
-                $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1646
-                $this->_remove_existing_registration_payments($payment, $PAY_ID);
1647
-                // apply payment to registrations (if applicable)
1648
-                if (! empty($REG_IDs)) {
1649
-                    $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1650
-                    $this->_maybe_send_notifications();
1651
-                    // now process status changes for the same registrations
1652
-                    $this->_process_registration_status_change($transaction, $REG_IDs);
1653
-                }
1654
-                $this->_maybe_send_notifications($payment);
1655
-                // prepare to render page
1656
-                $json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1657
-                do_action(
1658
-                    'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1659
-                    $transaction,
1660
-                    $payment
1661
-                );
1662
-            } else {
1663
-                EE_Error::add_error(
1664
-                    esc_html__(
1665
-                        'A valid Transaction for this payment could not be retrieved.',
1666
-                        'event_espresso'
1667
-                    ),
1668
-                    __FILE__,
1669
-                    __FUNCTION__,
1670
-                    __LINE__
1671
-                );
1672
-            }
1673
-        } elseif ($has_access) {
1674
-            EE_Error::add_error(
1675
-                esc_html__(
1676
-                    'The payment form data could not be processed. Please try again.',
1677
-                    'event_espresso'
1678
-                ),
1679
-                __FILE__,
1680
-                __FUNCTION__,
1681
-                __LINE__
1682
-            );
1683
-        } else {
1684
-            EE_Error::add_error(
1685
-                esc_html__(
1686
-                    'You do not have access to apply payments or refunds to a registration.',
1687
-                    'event_espresso'
1688
-                ),
1689
-                __FILE__,
1690
-                __FUNCTION__,
1691
-                __LINE__
1692
-            );
1693
-        }
1694
-        $notices = EE_Error::get_notices(
1695
-            false,
1696
-            false,
1697
-            false
1698
-        );
1699
-        $this->_template_args = array(
1700
-            'data'    => $json_response_data,
1701
-            'error'   => $notices['errors'],
1702
-            'success' => $notices['success'],
1703
-        );
1704
-        $this->_return_json();
1705
-    }
1706
-
1707
-
1708
-    /**
1709
-     * _validate_payment_request_data
1710
-     *
1711
-     * @return array
1712
-     * @throws EE_Error
1713
-     * @throws InvalidArgumentException
1714
-     * @throws InvalidDataTypeException
1715
-     * @throws InvalidInterfaceException
1716
-     */
1717
-    protected function _validate_payment_request_data()
1718
-    {
1719
-        if (! isset($this->_req_data['txn_admin_payment'])) {
1720
-            return array();
1721
-        }
1722
-        $payment_form = $this->_generate_payment_form_section();
1723
-        try {
1724
-            if ($payment_form->was_submitted()) {
1725
-                $payment_form->receive_form_submission();
1726
-                if (! $payment_form->is_valid()) {
1727
-                    $submission_error_messages = array();
1728
-                    foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1729
-                        if ($validation_error instanceof EE_Validation_Error) {
1730
-                            $submission_error_messages[] = sprintf(
1731
-                                _x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1732
-                                $validation_error->get_form_section()->html_label_text(),
1733
-                                $validation_error->getMessage()
1734
-                            );
1735
-                        }
1736
-                    }
1737
-                    EE_Error::add_error(
1738
-                        implode('<br />', $submission_error_messages),
1739
-                        __FILE__,
1740
-                        __FUNCTION__,
1741
-                        __LINE__
1742
-                    );
1743
-                    return array();
1744
-                }
1745
-            }
1746
-        } catch (EE_Error $e) {
1747
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1748
-            return array();
1749
-        }
1750
-
1751
-        return $payment_form->valid_data();
1752
-    }
1753
-
1754
-
1755
-    /**
1756
-     * _generate_payment_form_section
1757
-     *
1758
-     * @return EE_Form_Section_Proper
1759
-     * @throws EE_Error
1760
-     */
1761
-    protected function _generate_payment_form_section()
1762
-    {
1763
-        return new EE_Form_Section_Proper(
1764
-            array(
1765
-                'name'        => 'txn_admin_payment',
1766
-                'subsections' => array(
1767
-                    'PAY_ID'          => new EE_Text_Input(
1768
-                        array(
1769
-                            'default'               => 0,
1770
-                            'required'              => false,
1771
-                            'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1772
-                            'validation_strategies' => array(new EE_Int_Normalization()),
1773
-                        )
1774
-                    ),
1775
-                    'TXN_ID'          => new EE_Text_Input(
1776
-                        array(
1777
-                            'default'               => 0,
1778
-                            'required'              => true,
1779
-                            'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1780
-                            'validation_strategies' => array(new EE_Int_Normalization()),
1781
-                        )
1782
-                    ),
1783
-                    'type'            => new EE_Text_Input(
1784
-                        array(
1785
-                            'default'               => 1,
1786
-                            'required'              => true,
1787
-                            'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1788
-                            'validation_strategies' => array(new EE_Int_Normalization()),
1789
-                        )
1790
-                    ),
1791
-                    'amount'          => new EE_Text_Input(
1792
-                        array(
1793
-                            'default'               => 0,
1794
-                            'required'              => true,
1795
-                            'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1796
-                            'validation_strategies' => array(new EE_Float_Normalization()),
1797
-                        )
1798
-                    ),
1799
-                    'status'          => new EE_Text_Input(
1800
-                        array(
1801
-                            'default'         => EEM_Payment::status_id_approved,
1802
-                            'required'        => true,
1803
-                            'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1804
-                        )
1805
-                    ),
1806
-                    'PMD_ID'          => new EE_Text_Input(
1807
-                        array(
1808
-                            'default'               => 2,
1809
-                            'required'              => true,
1810
-                            'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1811
-                            'validation_strategies' => array(new EE_Int_Normalization()),
1812
-                        )
1813
-                    ),
1814
-                    'date'            => new EE_Text_Input(
1815
-                        array(
1816
-                            'default'         => time(),
1817
-                            'required'        => true,
1818
-                            'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1819
-                        )
1820
-                    ),
1821
-                    'txn_id_chq_nmbr' => new EE_Text_Input(
1822
-                        array(
1823
-                            'default'               => '',
1824
-                            'required'              => false,
1825
-                            'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1826
-                            'validation_strategies' => array(
1827
-                                new EE_Max_Length_Validation_Strategy(
1828
-                                    esc_html__('Input too long', 'event_espresso'),
1829
-                                    100
1830
-                                ),
1831
-                            ),
1832
-                        )
1833
-                    ),
1834
-                    'po_number'       => new EE_Text_Input(
1835
-                        array(
1836
-                            'default'               => '',
1837
-                            'required'              => false,
1838
-                            'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1839
-                            'validation_strategies' => array(
1840
-                                new EE_Max_Length_Validation_Strategy(
1841
-                                    esc_html__('Input too long', 'event_espresso'),
1842
-                                    100
1843
-                                ),
1844
-                            ),
1845
-                        )
1846
-                    ),
1847
-                    'accounting'      => new EE_Text_Input(
1848
-                        array(
1849
-                            'default'               => '',
1850
-                            'required'              => false,
1851
-                            'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1852
-                            'validation_strategies' => array(
1853
-                                new EE_Max_Length_Validation_Strategy(
1854
-                                    esc_html__('Input too long', 'event_espresso'),
1855
-                                    100
1856
-                                ),
1857
-                            ),
1858
-                        )
1859
-                    ),
1860
-                ),
1861
-            )
1862
-        );
1863
-    }
1864
-
1865
-
1866
-    /**
1867
-     * _create_payment_from_request_data
1868
-     *
1869
-     * @param array $valid_data
1870
-     * @return EE_Payment
1871
-     * @throws EE_Error
1872
-     * @throws InvalidArgumentException
1873
-     * @throws InvalidDataTypeException
1874
-     * @throws InvalidInterfaceException
1875
-     * @throws ReflectionException
1876
-     */
1877
-    protected function _create_payment_from_request_data($valid_data)
1878
-    {
1879
-        $PAY_ID = $valid_data['PAY_ID'];
1880
-        // get payment amount
1881
-        $amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1882
-        // payments have a type value of 1 and refunds have a type value of -1
1883
-        // so multiplying amount by type will give a positive value for payments, and negative values for refunds
1884
-        $amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1885
-        // for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1886
-        $date = $valid_data['date']
1887
-            ? preg_replace('/\s+/', ' ', $valid_data['date'])
1888
-            : date('Y-m-d g:i a', current_time('timestamp'));
1889
-        $payment = EE_Payment::new_instance(
1890
-            array(
1891
-                'TXN_ID'              => $valid_data['TXN_ID'],
1892
-                'STS_ID'              => $valid_data['status'],
1893
-                'PAY_timestamp'       => $date,
1894
-                'PAY_source'          => EEM_Payment_Method::scope_admin,
1895
-                'PMD_ID'              => $valid_data['PMD_ID'],
1896
-                'PAY_amount'          => $amount,
1897
-                'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1898
-                'PAY_po_number'       => $valid_data['po_number'],
1899
-                'PAY_extra_accntng'   => $valid_data['accounting'],
1900
-                'PAY_details'         => $valid_data,
1901
-                'PAY_ID'              => $PAY_ID,
1902
-            ),
1903
-            '',
1904
-            array('Y-m-d', 'g:i a')
1905
-        );
1906
-
1907
-        if (! $payment->save()) {
1908
-            EE_Error::add_error(
1909
-                sprintf(
1910
-                    esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1911
-                    $payment->ID()
1912
-                ),
1913
-                __FILE__,
1914
-                __FUNCTION__,
1915
-                __LINE__
1916
-            );
1917
-        }
1918
-
1919
-        return $payment;
1920
-    }
1921
-
1922
-
1923
-    /**
1924
-     * _process_transaction_payments
1925
-     *
1926
-     * @param \EE_Transaction $transaction
1927
-     * @return void
1928
-     * @throws EE_Error
1929
-     * @throws InvalidArgumentException
1930
-     * @throws ReflectionException
1931
-     * @throws InvalidDataTypeException
1932
-     * @throws InvalidInterfaceException
1933
-     */
1934
-    protected function _process_transaction_payments(EE_Transaction $transaction)
1935
-    {
1936
-        /** @type EE_Transaction_Payments $transaction_payments */
1937
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1938
-        // update the transaction with this payment
1939
-        if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1940
-            EE_Error::add_success(
1941
-                esc_html__(
1942
-                    'The payment has been processed successfully.',
1943
-                    'event_espresso'
1944
-                ),
1945
-                __FILE__,
1946
-                __FUNCTION__,
1947
-                __LINE__
1948
-            );
1949
-        } else {
1950
-            EE_Error::add_error(
1951
-                esc_html__(
1952
-                    'The payment was processed successfully but the amount paid for the transaction was not updated.',
1953
-                    'event_espresso'
1954
-                ),
1955
-                __FILE__,
1956
-                __FUNCTION__,
1957
-                __LINE__
1958
-            );
1959
-        }
1960
-    }
1961
-
1962
-
1963
-    /**
1964
-     * _get_REG_IDs_to_apply_payment_to
1965
-     * returns a list of registration IDs that the payment will apply to
1966
-     *
1967
-     * @param \EE_Payment $payment
1968
-     * @return array
1969
-     * @throws EE_Error
1970
-     * @throws InvalidArgumentException
1971
-     * @throws InvalidDataTypeException
1972
-     * @throws InvalidInterfaceException
1973
-     * @throws ReflectionException
1974
-     */
1975
-    protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1976
-    {
1977
-        $REG_IDs = array();
1978
-        // grab array of IDs for specific registrations to apply changes to
1979
-        if (isset($this->_req_data['txn_admin_payment']['registrations'])) {
1980
-            $REG_IDs = (array) $this->_req_data['txn_admin_payment']['registrations'];
1981
-        }
1982
-        // nothing specified ? then get all reg IDs
1983
-        if (empty($REG_IDs)) {
1984
-            $registrations = $payment->transaction()->registrations();
1985
-            $REG_IDs = ! empty($registrations)
1986
-                ? array_keys($registrations)
1987
-                : $this->_get_existing_reg_payment_REG_IDs($payment);
1988
-        }
1989
-
1990
-        // ensure that REG_IDs are integers and NOT strings
1991
-        return array_map('intval', $REG_IDs);
1992
-    }
1993
-
1994
-
1995
-    /**
1996
-     * @return array
1997
-     */
1998
-    public function existing_reg_payment_REG_IDs()
1999
-    {
2000
-        return $this->_existing_reg_payment_REG_IDs;
2001
-    }
2002
-
2003
-
2004
-    /**
2005
-     * @param array $existing_reg_payment_REG_IDs
2006
-     */
2007
-    public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
2008
-    {
2009
-        $this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
2010
-    }
2011
-
2012
-
2013
-    /**
2014
-     * _get_existing_reg_payment_REG_IDs
2015
-     * returns a list of registration IDs that the payment is currently related to
2016
-     * as recorded in the database
2017
-     *
2018
-     * @param \EE_Payment $payment
2019
-     * @return array
2020
-     * @throws EE_Error
2021
-     * @throws InvalidArgumentException
2022
-     * @throws InvalidDataTypeException
2023
-     * @throws InvalidInterfaceException
2024
-     * @throws ReflectionException
2025
-     */
2026
-    protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2027
-    {
2028
-        if ($this->existing_reg_payment_REG_IDs() === null) {
2029
-            // let's get any existing reg payment records for this payment
2030
-            $existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2031
-            // but we only want the REG IDs, so grab the array keys
2032
-            $existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2033
-                ? array_keys($existing_reg_payment_REG_IDs)
2034
-                : array();
2035
-            $this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2036
-        }
2037
-
2038
-        return $this->existing_reg_payment_REG_IDs();
2039
-    }
2040
-
2041
-
2042
-    /**
2043
-     * _remove_existing_registration_payments
2044
-     * this calculates the difference between existing relations
2045
-     * to the supplied payment and the new list registration IDs,
2046
-     * removes any related registrations that no longer apply,
2047
-     * and then updates the registration paid fields
2048
-     *
2049
-     * @param \EE_Payment $payment
2050
-     * @param int         $PAY_ID
2051
-     * @return bool;
2052
-     * @throws EE_Error
2053
-     * @throws InvalidArgumentException
2054
-     * @throws ReflectionException
2055
-     * @throws InvalidDataTypeException
2056
-     * @throws InvalidInterfaceException
2057
-     */
2058
-    protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2059
-    {
2060
-        // newly created payments will have nothing recorded for $PAY_ID
2061
-        if (absint($PAY_ID) === 0) {
2062
-            return false;
2063
-        }
2064
-        $existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2065
-        if (empty($existing_reg_payment_REG_IDs)) {
2066
-            return false;
2067
-        }
2068
-        /** @type EE_Transaction_Payments $transaction_payments */
2069
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2070
-
2071
-        return $transaction_payments->delete_registration_payments_and_update_registrations(
2072
-            $payment,
2073
-            array(
2074
-                array(
2075
-                    'PAY_ID' => $payment->ID(),
2076
-                    'REG_ID' => array('IN', $existing_reg_payment_REG_IDs),
2077
-                ),
2078
-            )
2079
-        );
2080
-    }
2081
-
2082
-
2083
-    /**
2084
-     * _update_registration_payments
2085
-     * this applies the payments to the selected registrations
2086
-     * but only if they have not already been paid for
2087
-     *
2088
-     * @param  EE_Transaction $transaction
2089
-     * @param \EE_Payment     $payment
2090
-     * @param array           $REG_IDs
2091
-     * @return void
2092
-     * @throws EE_Error
2093
-     * @throws InvalidArgumentException
2094
-     * @throws ReflectionException
2095
-     * @throws RuntimeException
2096
-     * @throws InvalidDataTypeException
2097
-     * @throws InvalidInterfaceException
2098
-     */
2099
-    protected function _update_registration_payments(
2100
-        EE_Transaction $transaction,
2101
-        EE_Payment $payment,
2102
-        $REG_IDs = array()
2103
-    ) {
2104
-        // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2105
-        // so let's do that using our set of REG_IDs from the form
2106
-        $registration_query_where_params = array(
2107
-            'REG_ID' => array('IN', $REG_IDs),
2108
-        );
2109
-        // but add in some conditions regarding payment,
2110
-        // so that we don't apply payments to registrations that are free or have already been paid for
2111
-        // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2112
-        if (! $payment->is_a_refund()) {
2113
-            $registration_query_where_params['REG_final_price'] = array('!=', 0);
2114
-            $registration_query_where_params['REG_final_price*'] = array('!=', 'REG_paid', true);
2115
-        }
2116
-        $registrations = $transaction->registrations(array($registration_query_where_params));
2117
-        if (! empty($registrations)) {
2118
-            /** @type EE_Payment_Processor $payment_processor */
2119
-            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2120
-            $payment_processor->process_registration_payments($transaction, $payment, $registrations);
2121
-        }
2122
-    }
2123
-
2124
-
2125
-    /**
2126
-     * _process_registration_status_change
2127
-     * This processes requested registration status changes for all the registrations
2128
-     * on a given transaction and (optionally) sends out notifications for the changes.
2129
-     *
2130
-     * @param  EE_Transaction $transaction
2131
-     * @param array           $REG_IDs
2132
-     * @return bool
2133
-     * @throws EE_Error
2134
-     * @throws InvalidArgumentException
2135
-     * @throws ReflectionException
2136
-     * @throws InvalidDataTypeException
2137
-     * @throws InvalidInterfaceException
2138
-     */
2139
-    protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = array())
2140
-    {
2141
-        // first if there is no change in status then we get out.
2142
-        if (
2143
-            ! isset($this->_req_data['txn_reg_status_change']['reg_status'])
2144
-            || $this->_req_data['txn_reg_status_change']['reg_status'] === 'NAN'
2145
-        ) {
2146
-            // no error message, no change requested, just nothing to do man.
2147
-            return false;
2148
-        }
2149
-        /** @type EE_Transaction_Processor $transaction_processor */
2150
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2151
-
2152
-        // made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2153
-        return $transaction_processor->manually_update_registration_statuses(
2154
-            $transaction,
2155
-            sanitize_text_field($this->_req_data['txn_reg_status_change']['reg_status']),
2156
-            array(array('REG_ID' => array('IN', $REG_IDs)))
2157
-        );
2158
-    }
2159
-
2160
-
2161
-    /**
2162
-     * _build_payment_json_response
2163
-     *
2164
-     * @access public
2165
-     * @param \EE_Payment $payment
2166
-     * @param array       $REG_IDs
2167
-     * @param bool | null $delete_txn_reg_status_change
2168
-     * @return array
2169
-     * @throws EE_Error
2170
-     * @throws InvalidArgumentException
2171
-     * @throws InvalidDataTypeException
2172
-     * @throws InvalidInterfaceException
2173
-     * @throws ReflectionException
2174
-     */
2175
-    protected function _build_payment_json_response(
2176
-        EE_Payment $payment,
2177
-        $REG_IDs = array(),
2178
-        $delete_txn_reg_status_change = null
2179
-    ) {
2180
-        // was the payment deleted ?
2181
-        if (is_bool($delete_txn_reg_status_change)) {
2182
-            return array(
2183
-                'PAY_ID'                       => $payment->ID(),
2184
-                'amount'                       => $payment->amount(),
2185
-                'total_paid'                   => $payment->transaction()->paid(),
2186
-                'txn_status'                   => $payment->transaction()->status_ID(),
2187
-                'pay_status'                   => $payment->STS_ID(),
2188
-                'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2189
-                'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2190
-            );
2191
-        } else {
2192
-            $this->_get_payment_status_array();
2193
-
2194
-            return array(
2195
-                'amount'           => $payment->amount(),
2196
-                'total_paid'       => $payment->transaction()->paid(),
2197
-                'txn_status'       => $payment->transaction()->status_ID(),
2198
-                'pay_status'       => $payment->STS_ID(),
2199
-                'PAY_ID'           => $payment->ID(),
2200
-                'STS_ID'           => $payment->STS_ID(),
2201
-                'status'           => self::$_pay_status[ $payment->STS_ID() ],
2202
-                'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2203
-                'method'           => strtoupper($payment->source()),
2204
-                'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2205
-                'gateway'          => $payment->payment_method()
2206
-                    ? $payment->payment_method()->admin_name()
2207
-                    : esc_html__('Unknown', 'event_espresso'),
2208
-                'gateway_response' => $payment->gateway_response(),
2209
-                'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2210
-                'po_number'        => $payment->po_number(),
2211
-                'extra_accntng'    => $payment->extra_accntng(),
2212
-                'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2213
-            );
2214
-        }
2215
-    }
2216
-
2217
-
2218
-    /**
2219
-     * delete_payment
2220
-     *    delete a payment or refund made towards a transaction
2221
-     *
2222
-     * @access public
2223
-     * @return void
2224
-     * @throws EE_Error
2225
-     * @throws InvalidArgumentException
2226
-     * @throws ReflectionException
2227
-     * @throws InvalidDataTypeException
2228
-     * @throws InvalidInterfaceException
2229
-     */
2230
-    public function delete_payment()
2231
-    {
2232
-        $json_response_data = array('return_data' => false);
2233
-        $PAY_ID = isset($this->_req_data['delete_txn_admin_payment']['PAY_ID'])
2234
-            ? absint($this->_req_data['delete_txn_admin_payment']['PAY_ID'])
2235
-            : 0;
2236
-        $can_delete = EE_Registry::instance()->CAP->current_user_can(
2237
-            'ee_delete_payments',
2238
-            'delete_payment_from_registration_details'
2239
-        );
2240
-        if ($PAY_ID && $can_delete) {
2241
-            $delete_txn_reg_status_change = isset($this->_req_data['delete_txn_reg_status_change'])
2242
-                ? $this->_req_data['delete_txn_reg_status_change']
2243
-                : false;
2244
-            $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2245
-            if ($payment instanceof EE_Payment) {
2246
-                $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2247
-                /** @type EE_Transaction_Payments $transaction_payments */
2248
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2249
-                if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2250
-                    $json_response_data['return_data'] = $this->_build_payment_json_response(
2251
-                        $payment,
2252
-                        $REG_IDs,
2253
-                        $delete_txn_reg_status_change
2254
-                    );
2255
-                    if ($delete_txn_reg_status_change) {
2256
-                        $this->_req_data['txn_reg_status_change'] = $delete_txn_reg_status_change;
2257
-                        // MAKE sure we also add the delete_txn_req_status_change to the
2258
-                        // $_REQUEST global because that's how messages will be looking for it.
2259
-                        $this->request->setRequestParam('txn_reg_status_change', $delete_txn_reg_status_change);
2260
-                        $this->_maybe_send_notifications();
2261
-                        $this->_process_registration_status_change($payment->transaction(), $REG_IDs);
2262
-                    }
2263
-                }
2264
-            } else {
2265
-                EE_Error::add_error(
2266
-                    esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2267
-                    __FILE__,
2268
-                    __FUNCTION__,
2269
-                    __LINE__
2270
-                );
2271
-            }
2272
-        } elseif ($can_delete) {
2273
-            EE_Error::add_error(
2274
-                esc_html__(
2275
-                    'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2276
-                    'event_espresso'
2277
-                ),
2278
-                __FILE__,
2279
-                __FUNCTION__,
2280
-                __LINE__
2281
-            );
2282
-        } else {
2283
-            EE_Error::add_error(
2284
-                esc_html__(
2285
-                    'You do not have access to delete a payment.',
2286
-                    'event_espresso'
2287
-                ),
2288
-                __FILE__,
2289
-                __FUNCTION__,
2290
-                __LINE__
2291
-            );
2292
-        }
2293
-        $notices = EE_Error::get_notices(false, false, false);
2294
-        $this->_template_args = array(
2295
-            'data'      => $json_response_data,
2296
-            'success'   => $notices['success'],
2297
-            'error'     => $notices['errors'],
2298
-            'attention' => $notices['attention'],
2299
-        );
2300
-        $this->_return_json();
2301
-    }
2302
-
2303
-
2304
-    /**
2305
-     * _registration_payment_data_array
2306
-     * adds info for 'owing' and 'paid' for each registration to the json response
2307
-     *
2308
-     * @access protected
2309
-     * @param array $REG_IDs
2310
-     * @return array
2311
-     * @throws EE_Error
2312
-     * @throws InvalidArgumentException
2313
-     * @throws InvalidDataTypeException
2314
-     * @throws InvalidInterfaceException
2315
-     * @throws ReflectionException
2316
-     */
2317
-    protected function _registration_payment_data_array($REG_IDs)
2318
-    {
2319
-        $registration_payment_data = array();
2320
-        // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2321
-        if (! empty($REG_IDs)) {
2322
-            $registrations = EEM_Registration::instance()->get_all(array(array('REG_ID' => array('IN', $REG_IDs))));
2323
-            foreach ($registrations as $registration) {
2324
-                if ($registration instanceof EE_Registration) {
2325
-                    $registration_payment_data[ $registration->ID() ] = array(
2326
-                        'paid'  => $registration->pretty_paid(),
2327
-                        'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2328
-                    );
2329
-                }
2330
-            }
2331
-        }
2332
-
2333
-        return $registration_payment_data;
2334
-    }
2335
-
2336
-
2337
-    /**
2338
-     * _maybe_send_notifications
2339
-     * determines whether or not the admin has indicated that notifications should be sent.
2340
-     * If so, will toggle a filter switch for delivering registration notices.
2341
-     * If passed an EE_Payment object, then it will trigger payment notifications instead.
2342
-     *
2343
-     * @access protected
2344
-     * @param \EE_Payment | null $payment
2345
-     */
2346
-    protected function _maybe_send_notifications($payment = null)
2347
-    {
2348
-        switch ($payment instanceof EE_Payment) {
2349
-            // payment notifications
2350
-            case true:
2351
-                if (
2352
-                    isset($this->_req_data['txn_payments']['send_notifications'])
2353
-                    && filter_var(
2354
-                        $this->_req_data['txn_payments']['send_notifications'],
2355
-                        FILTER_VALIDATE_BOOLEAN
2356
-                    )
2357
-                ) {
2358
-                    $this->_process_payment_notification($payment);
2359
-                }
2360
-                break;
2361
-            // registration notifications
2362
-            case false:
2363
-                if (
2364
-                    isset($this->_req_data['txn_reg_status_change']['send_notifications'])
2365
-                    && filter_var(
2366
-                        $this->_req_data['txn_reg_status_change']['send_notifications'],
2367
-                        FILTER_VALIDATE_BOOLEAN
2368
-                    )
2369
-                ) {
2370
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2371
-                }
2372
-                break;
2373
-        }
2374
-    }
2375
-
2376
-
2377
-    /**
2378
-     * _send_payment_reminder
2379
-     *    generates HTML for the View Transaction Details Admin page
2380
-     *
2381
-     * @access protected
2382
-     * @return void
2383
-     * @throws EE_Error
2384
-     * @throws InvalidArgumentException
2385
-     * @throws InvalidDataTypeException
2386
-     * @throws InvalidInterfaceException
2387
-     */
2388
-    protected function _send_payment_reminder()
2389
-    {
2390
-        $TXN_ID = ! empty($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : false;
2391
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2392
-        $query_args = isset($this->_req_data['redirect_to']) ? array(
2393
-            'action' => $this->_req_data['redirect_to'],
2394
-            'TXN_ID' => $this->_req_data['TXN_ID'],
2395
-        ) : array();
2396
-        do_action(
2397
-            'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2398
-            $transaction
2399
-        );
2400
-        $this->_redirect_after_action(
2401
-            false,
2402
-            esc_html__('payment reminder', 'event_espresso'),
2403
-            esc_html__('sent', 'event_espresso'),
2404
-            $query_args,
2405
-            true
2406
-        );
2407
-    }
2408
-
2409
-
2410
-    /**
2411
-     *  get_transactions
2412
-     *    get transactions for given parameters (used by list table)
2413
-     *
2414
-     * @param  int     $perpage how many transactions displayed per page
2415
-     * @param  boolean $count   return the count or objects
2416
-     * @param string   $view
2417
-     * @return mixed int = count || array of transaction objects
2418
-     * @throws EE_Error
2419
-     * @throws InvalidArgumentException
2420
-     * @throws InvalidDataTypeException
2421
-     * @throws InvalidInterfaceException
2422
-     */
2423
-    public function get_transactions($perpage, $count = false, $view = '')
2424
-    {
2425
-
2426
-        $TXN = EEM_Transaction::instance();
2427
-
2428
-        $start_date = isset($this->_req_data['txn-filter-start-date'])
2429
-            ? wp_strip_all_tags($this->_req_data['txn-filter-start-date'])
2430
-            : date(
2431
-                'm/d/Y',
2432
-                strtotime('-10 year')
2433
-            );
2434
-        $end_date = isset($this->_req_data['txn-filter-end-date'])
2435
-            ? wp_strip_all_tags($this->_req_data['txn-filter-end-date'])
2436
-            : date('m/d/Y');
2437
-
2438
-        // make sure our timestamps start and end right at the boundaries for each day
2439
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2440
-        $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2441
-
2442
-
2443
-        // convert to timestamps
2444
-        $start_date = strtotime($start_date);
2445
-        $end_date = strtotime($end_date);
2446
-
2447
-        // makes sure start date is the lowest value and vice versa
2448
-        $start_date = min($start_date, $end_date);
2449
-        $end_date = max($start_date, $end_date);
2450
-
2451
-        // convert to correct format for query
2452
-        $start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2453
-            'TXN_timestamp',
2454
-            date('Y-m-d H:i:s', $start_date),
2455
-            'Y-m-d H:i:s'
2456
-        );
2457
-        $end_date = EEM_Transaction::instance()->convert_datetime_for_query(
2458
-            'TXN_timestamp',
2459
-            date('Y-m-d H:i:s', $end_date),
2460
-            'Y-m-d H:i:s'
2461
-        );
2462
-
2463
-
2464
-        // set orderby
2465
-        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
2466
-
2467
-        switch ($this->_req_data['orderby']) {
2468
-            case 'TXN_ID':
2469
-                $orderby = 'TXN_ID';
2470
-                break;
2471
-            case 'ATT_fname':
2472
-                $orderby = 'Registration.Attendee.ATT_fname';
2473
-                break;
2474
-            case 'event_name':
2475
-                $orderby = 'Registration.Event.EVT_name';
2476
-                break;
2477
-            default: // 'TXN_timestamp'
2478
-                $orderby = 'TXN_timestamp';
2479
-        }
2480
-
2481
-        $sort = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2482
-        $current_page = ! empty($this->_req_data['paged']) ? $this->_req_data['paged'] : 1;
2483
-        $per_page = ! empty($perpage) ? $perpage : 10;
2484
-        $per_page = ! empty($this->_req_data['perpage']) ? $this->_req_data['perpage'] : $per_page;
2485
-
2486
-        $offset = ($current_page - 1) * $per_page;
2487
-        $limit = array($offset, $per_page);
2488
-
2489
-        $_where = array(
2490
-            'TXN_timestamp'          => array('BETWEEN', array($start_date, $end_date)),
2491
-            'Registration.REG_count' => 1,
2492
-        );
2493
-
2494
-        if (isset($this->_req_data['EVT_ID'])) {
2495
-            $_where['Registration.EVT_ID'] = $this->_req_data['EVT_ID'];
2496
-        }
2497
-
2498
-        if (isset($this->_req_data['s'])) {
2499
-            $search_string = '%' . $this->_req_data['s'] . '%';
2500
-            $_where['OR'] = array(
2501
-                'Registration.Event.EVT_name'         => array('LIKE', $search_string),
2502
-                'Registration.Event.EVT_desc'         => array('LIKE', $search_string),
2503
-                'Registration.Event.EVT_short_desc'   => array('LIKE', $search_string),
2504
-                'Registration.Attendee.ATT_full_name' => array('LIKE', $search_string),
2505
-                'Registration.Attendee.ATT_fname'     => array('LIKE', $search_string),
2506
-                'Registration.Attendee.ATT_lname'     => array('LIKE', $search_string),
2507
-                'Registration.Attendee.ATT_short_bio' => array('LIKE', $search_string),
2508
-                'Registration.Attendee.ATT_email'     => array('LIKE', $search_string),
2509
-                'Registration.Attendee.ATT_address'   => array('LIKE', $search_string),
2510
-                'Registration.Attendee.ATT_address2'  => array('LIKE', $search_string),
2511
-                'Registration.Attendee.ATT_city'      => array('LIKE', $search_string),
2512
-                'Registration.REG_final_price'        => array('LIKE', $search_string),
2513
-                'Registration.REG_code'               => array('LIKE', $search_string),
2514
-                'Registration.REG_count'              => array('LIKE', $search_string),
2515
-                'Registration.REG_group_size'         => array('LIKE', $search_string),
2516
-                'Registration.Ticket.TKT_name'        => array('LIKE', $search_string),
2517
-                'Registration.Ticket.TKT_description' => array('LIKE', $search_string),
2518
-                'Payment.PAY_source'                  => array('LIKE', $search_string),
2519
-                'Payment.Payment_Method.PMD_name'     => array('LIKE', $search_string),
2520
-                'TXN_session_data'                    => array('LIKE', $search_string),
2521
-                'Payment.PAY_txn_id_chq_nmbr'         => array('LIKE', $search_string),
2522
-            );
2523
-        }
2524
-
2525
-        // failed transactions
2526
-        $failed = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'failed' && ! $count)
2527
-                  || ($count && $view === 'failed');
2528
-        $abandoned = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'abandoned' && ! $count)
2529
-                     || ($count && $view === 'abandoned');
2530
-        $incomplete = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'incomplete' && ! $count)
2531
-                      || ($count && $view === 'incomplete');
2532
-
2533
-        if ($failed) {
2534
-            $_where['STS_ID'] = EEM_Transaction::failed_status_code;
2535
-        } elseif ($abandoned) {
2536
-            $_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2537
-        } elseif ($incomplete) {
2538
-            $_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2539
-        } else {
2540
-            $_where['STS_ID'] = array('!=', EEM_Transaction::failed_status_code);
2541
-            $_where['STS_ID*'] = array('!=', EEM_Transaction::abandoned_status_code);
2542
-        }
2543
-
2544
-        $query_params = apply_filters(
2545
-            'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2546
-            array(
2547
-                $_where,
2548
-                'order_by'                 => array($orderby => $sort),
2549
-                'limit'                    => $limit,
2550
-                'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2551
-            ),
2552
-            $this->_req_data,
2553
-            $view,
2554
-            $count
2555
-        );
2556
-
2557
-        $transactions = $count
2558
-            ? $TXN->count(array($query_params[0]), 'TXN_ID', true)
2559
-            : $TXN->get_all($query_params);
2560
-
2561
-        return $transactions;
2562
-    }
2563
-
2564
-
2565
-    /**
2566
-     * @since 4.9.79.p
2567
-     * @throws EE_Error
2568
-     * @throws InvalidArgumentException
2569
-     * @throws InvalidDataTypeException
2570
-     * @throws InvalidInterfaceException
2571
-     * @throws ReflectionException
2572
-     * @throws RuntimeException
2573
-     */
2574
-    public function recalculateLineItems()
2575
-    {
2576
-        $TXN_ID = ! empty($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : false;
2577
-        /** @var EE_Transaction $transaction */
2578
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2579
-        $total_line_item = $transaction->total_line_item(false);
2580
-        $success = $transaction->recalculateLineItems();
2581
-        $this->_redirect_after_action(
2582
-            (bool) $success,
2583
-            esc_html__('Transaction taxes and totals', 'event_espresso'),
2584
-            esc_html__('recalculated', 'event_espresso'),
2585
-            isset($this->_req_data['redirect_to'])
2586
-                ? array(
2587
-                'action' => $this->_req_data['redirect_to'],
2588
-                'TXN_ID' => $this->_req_data['TXN_ID'],
2589
-            )
2590
-                : array(),
2591
-            true
2592
-        );
2593
-    }
441
+		 * Filters whether a link to the "Failed Transactions" list table
442
+		 * appears on the Transactions Admin Page list table.
443
+		 * List display can be turned back on via the following:
444
+		 * add_filter(
445
+		 *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
446
+		 *     '__return_true'
447
+		 * );
448
+		 *
449
+		 * @since 4.9.70.p
450
+		 * @param boolean                 $display_failed_txns_list
451
+		 * @param Transactions_Admin_Page $this
452
+		 */
453
+			apply_filters(
454
+				'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
455
+				false,
456
+				$this
457
+			)
458
+		) {
459
+			$this->_views['failed'] = array(
460
+				'slug'  => 'failed',
461
+				'label' => esc_html__('Failed Transactions', 'event_espresso'),
462
+				'count' => 0,
463
+			);
464
+		}
465
+	}
466
+
467
+
468
+	/**
469
+	 * _set_transaction_object
470
+	 * This sets the _transaction property for the transaction details screen
471
+	 *
472
+	 * @access private
473
+	 * @return void
474
+	 * @throws EE_Error
475
+	 * @throws InvalidArgumentException
476
+	 * @throws RuntimeException
477
+	 * @throws InvalidDataTypeException
478
+	 * @throws InvalidInterfaceException
479
+	 * @throws ReflectionException
480
+	 */
481
+	private function _set_transaction_object()
482
+	{
483
+		if ($this->_transaction instanceof EE_Transaction) {
484
+			return;
485
+		} //get out we've already set the object
486
+
487
+		$TXN_ID = ! empty($this->_req_data['TXN_ID'])
488
+			? absint($this->_req_data['TXN_ID'])
489
+			: false;
490
+
491
+		// get transaction object
492
+		$this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
493
+		$this->_session = $this->_transaction instanceof EE_Transaction
494
+			? $this->_transaction->session_data()
495
+			: null;
496
+		if ($this->_transaction instanceof EE_Transaction) {
497
+			$this->_transaction->verify_abandoned_transaction_status();
498
+		}
499
+
500
+		if (! $this->_transaction instanceof EE_Transaction) {
501
+			$error_msg = sprintf(
502
+				esc_html__(
503
+					'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
504
+					'event_espresso'
505
+				),
506
+				$TXN_ID
507
+			);
508
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
509
+		}
510
+	}
511
+
512
+
513
+	/**
514
+	 *    _transaction_legend_items
515
+	 *
516
+	 * @access protected
517
+	 * @return array
518
+	 * @throws EE_Error
519
+	 * @throws InvalidArgumentException
520
+	 * @throws ReflectionException
521
+	 * @throws InvalidDataTypeException
522
+	 * @throws InvalidInterfaceException
523
+	 */
524
+	protected function _transaction_legend_items()
525
+	{
526
+		EE_Registry::instance()->load_helper('MSG_Template');
527
+		$items = array();
528
+
529
+		if (
530
+			EE_Registry::instance()->CAP->current_user_can(
531
+				'ee_read_global_messages',
532
+				'view_filtered_messages'
533
+			)
534
+		) {
535
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
536
+			if (
537
+				is_array($related_for_icon)
538
+				&& isset($related_for_icon['css_class'], $related_for_icon['label'])
539
+			) {
540
+				$items['view_related_messages'] = array(
541
+					'class' => $related_for_icon['css_class'],
542
+					'desc'  => $related_for_icon['label'],
543
+				);
544
+			}
545
+		}
546
+
547
+		$items = apply_filters(
548
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
549
+			array_merge(
550
+				$items,
551
+				array(
552
+					'view_details'          => array(
553
+						'class' => 'dashicons dashicons-cart',
554
+						'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
555
+					),
556
+					'view_invoice'          => array(
557
+						'class' => 'dashicons dashicons-media-spreadsheet',
558
+						'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
559
+					),
560
+					'view_receipt'          => array(
561
+						'class' => 'dashicons dashicons-media-default',
562
+						'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
563
+					),
564
+					'view_registration'     => array(
565
+						'class' => 'dashicons dashicons-clipboard',
566
+						'desc'  => esc_html__('View Registration Details', 'event_espresso'),
567
+					),
568
+					'payment_overview_link' => array(
569
+						'class' => 'dashicons dashicons-money',
570
+						'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
571
+					),
572
+				)
573
+			)
574
+		);
575
+
576
+		if (
577
+			EEH_MSG_Template::is_mt_active('payment_reminder')
578
+			&& EE_Registry::instance()->CAP->current_user_can(
579
+				'ee_send_message',
580
+				'espresso_transactions_send_payment_reminder'
581
+			)
582
+		) {
583
+			$items['send_payment_reminder'] = array(
584
+				'class' => 'dashicons dashicons-email-alt',
585
+				'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
586
+			);
587
+		} else {
588
+			$items['blank*'] = array(
589
+				'class' => '',
590
+				'desc'  => '',
591
+			);
592
+		}
593
+		$more_items = apply_filters(
594
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
595
+			array(
596
+				'overpaid'   => array(
597
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
598
+					'desc'  => EEH_Template::pretty_status(
599
+						EEM_Transaction::overpaid_status_code,
600
+						false,
601
+						'sentence'
602
+					),
603
+				),
604
+				'complete'   => array(
605
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
606
+					'desc'  => EEH_Template::pretty_status(
607
+						EEM_Transaction::complete_status_code,
608
+						false,
609
+						'sentence'
610
+					),
611
+				),
612
+				'incomplete' => array(
613
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
614
+					'desc'  => EEH_Template::pretty_status(
615
+						EEM_Transaction::incomplete_status_code,
616
+						false,
617
+						'sentence'
618
+					),
619
+				),
620
+				'abandoned'  => array(
621
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
622
+					'desc'  => EEH_Template::pretty_status(
623
+						EEM_Transaction::abandoned_status_code,
624
+						false,
625
+						'sentence'
626
+					),
627
+				),
628
+				'failed'     => array(
629
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
630
+					'desc'  => EEH_Template::pretty_status(
631
+						EEM_Transaction::failed_status_code,
632
+						false,
633
+						'sentence'
634
+					),
635
+				),
636
+			)
637
+		);
638
+
639
+		return array_merge($items, $more_items);
640
+	}
641
+
642
+
643
+	/**
644
+	 *    _transactions_overview_list_table
645
+	 *
646
+	 * @access protected
647
+	 * @return void
648
+	 * @throws DomainException
649
+	 * @throws EE_Error
650
+	 * @throws InvalidArgumentException
651
+	 * @throws InvalidDataTypeException
652
+	 * @throws InvalidInterfaceException
653
+	 * @throws ReflectionException
654
+	 */
655
+	protected function _transactions_overview_list_table()
656
+	{
657
+		$this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
658
+		$event = isset($this->_req_data['EVT_ID'])
659
+			? EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID'])
660
+			: null;
661
+		$this->_template_args['admin_page_header'] = $event instanceof EE_Event
662
+			? sprintf(
663
+				esc_html__(
664
+					'%sViewing Transactions for the Event: %s%s',
665
+					'event_espresso'
666
+				),
667
+				'<h3>',
668
+				'<a href="'
669
+				. EE_Admin_Page::add_query_args_and_nonce(
670
+					array('action' => 'edit', 'post' => $event->ID()),
671
+					EVENTS_ADMIN_URL
672
+				)
673
+				. '" title="'
674
+				. esc_attr__(
675
+					'Click to Edit event',
676
+					'event_espresso'
677
+				)
678
+				. '">' . $event->name() . '</a>',
679
+				'</h3>'
680
+			)
681
+			: '';
682
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_transaction_legend_items());
683
+		$this->display_admin_list_table_page_with_no_sidebar();
684
+	}
685
+
686
+
687
+	/**
688
+	 *    _transaction_details
689
+	 * generates HTML for the View Transaction Details Admin page
690
+	 *
691
+	 * @access protected
692
+	 * @return void
693
+	 * @throws DomainException
694
+	 * @throws EE_Error
695
+	 * @throws InvalidArgumentException
696
+	 * @throws InvalidDataTypeException
697
+	 * @throws InvalidInterfaceException
698
+	 * @throws RuntimeException
699
+	 * @throws ReflectionException
700
+	 */
701
+	protected function _transaction_details()
702
+	{
703
+		do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
704
+
705
+		$this->_set_transaction_status_array();
706
+
707
+		$this->_template_args = array();
708
+		$this->_template_args['transactions_page'] = $this->_wp_page_slug;
709
+
710
+		$this->_set_transaction_object();
711
+
712
+		if (! $this->_transaction instanceof EE_Transaction) {
713
+			return;
714
+		}
715
+		$primary_registration = $this->_transaction->primary_registration();
716
+		$attendee = $primary_registration instanceof EE_Registration
717
+			? $primary_registration->attendee()
718
+			: null;
719
+
720
+		$this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
721
+		$this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
722
+
723
+		$this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
724
+		$this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
725
+
726
+		$this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
727
+		$this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
728
+		$this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->status_ID();
729
+
730
+		$this->_template_args['grand_total'] = $this->_transaction->total();
731
+		$this->_template_args['total_paid'] = $this->_transaction->paid();
732
+
733
+		$amount_due = $this->_transaction->total() - $this->_transaction->paid();
734
+		$this->_template_args['amount_due'] = EEH_Template::format_currency(
735
+			$amount_due,
736
+			true
737
+		);
738
+		if (EE_Registry::instance()->CFG->currency->sign_b4) {
739
+			$this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign
740
+												  . $this->_template_args['amount_due'];
741
+		} else {
742
+			$this->_template_args['amount_due'] .= EE_Registry::instance()->CFG->currency->sign;
743
+		}
744
+		$this->_template_args['amount_due_class'] = '';
745
+
746
+		if ($this->_transaction->paid() === $this->_transaction->total()) {
747
+			// paid in full
748
+			$this->_template_args['amount_due'] = false;
749
+		} elseif ($this->_transaction->paid() > $this->_transaction->total()) {
750
+			// overpaid
751
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
752
+		} elseif ($this->_transaction->total() > (float) 0) {
753
+			if ($this->_transaction->paid() > (float) 0) {
754
+				// monies owing
755
+				$this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
756
+			} elseif ($this->_transaction->paid() === (float) 0) {
757
+				// no payments made yet
758
+				$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
759
+			}
760
+		} elseif ($this->_transaction->total() === (float) 0) {
761
+			// free event
762
+			$this->_template_args['amount_due'] = false;
763
+		}
764
+
765
+		$payment_method = $this->_transaction->payment_method();
766
+
767
+		$this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
768
+			? $payment_method->admin_name()
769
+			: esc_html__('Unknown', 'event_espresso');
770
+
771
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
772
+		// link back to overview
773
+		$this->_template_args['txn_overview_url'] = $this->request->getServerParam(
774
+			'HTTP_REFERER',
775
+			TXN_ADMIN_URL
776
+		);
777
+
778
+
779
+		// next link
780
+		$next_txn = $this->_transaction->next(
781
+			null,
782
+			array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
783
+			'TXN_ID'
784
+		);
785
+		$this->_template_args['next_transaction'] = $next_txn
786
+			? $this->_next_link(
787
+				EE_Admin_Page::add_query_args_and_nonce(
788
+					array('action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']),
789
+					TXN_ADMIN_URL
790
+				),
791
+				'dashicons dashicons-arrow-right ee-icon-size-22'
792
+			)
793
+			: '';
794
+		// previous link
795
+		$previous_txn = $this->_transaction->previous(
796
+			null,
797
+			array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
798
+			'TXN_ID'
799
+		);
800
+		$this->_template_args['previous_transaction'] = $previous_txn
801
+			? $this->_previous_link(
802
+				EE_Admin_Page::add_query_args_and_nonce(
803
+					array('action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']),
804
+					TXN_ADMIN_URL
805
+				),
806
+				'dashicons dashicons-arrow-left ee-icon-size-22'
807
+			)
808
+			: '';
809
+
810
+		// were we just redirected here after adding a new registration ???
811
+		if (
812
+			isset(
813
+				$this->_req_data['redirect_from'],
814
+				$this->_req_data['EVT_ID'],
815
+				$this->_req_data['event_name']
816
+			)
817
+		) {
818
+			if (
819
+				EE_Registry::instance()->CAP->current_user_can(
820
+					'ee_edit_registrations',
821
+					'espresso_registrations_new_registration',
822
+					$this->_req_data['EVT_ID']
823
+				)
824
+			) {
825
+				$this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button-primary" href="';
826
+				$this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
827
+					array(
828
+						'page'     => 'espresso_registrations',
829
+						'action'   => 'new_registration',
830
+						'return'   => 'default',
831
+						'TXN_ID'   => $this->_transaction->ID(),
832
+						'event_id' => $this->_req_data['EVT_ID'],
833
+					),
834
+					REG_ADMIN_URL
835
+				);
836
+				$this->_admin_page_title .= '">';
837
+
838
+				$this->_admin_page_title .= sprintf(
839
+					esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
840
+					htmlentities(urldecode($this->_req_data['event_name']), ENT_QUOTES, 'UTF-8')
841
+				);
842
+				$this->_admin_page_title .= '</a>';
843
+			}
844
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
845
+		}
846
+		// grab messages at the last second
847
+		$this->_template_args['notices'] = EE_Error::get_notices();
848
+		// path to template
849
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
850
+		$this->_template_args['admin_page_header'] = EEH_Template::display_template(
851
+			$template_path,
852
+			$this->_template_args,
853
+			true
854
+		);
855
+
856
+		// the details template wrapper
857
+		$this->display_admin_page_with_sidebar();
858
+	}
859
+
860
+
861
+	/**
862
+	 *        _transaction_details_metaboxes
863
+	 *
864
+	 * @access protected
865
+	 * @return void
866
+	 * @throws EE_Error
867
+	 * @throws InvalidArgumentException
868
+	 * @throws InvalidDataTypeException
869
+	 * @throws InvalidInterfaceException
870
+	 * @throws RuntimeException
871
+	 * @throws ReflectionException
872
+	 */
873
+	protected function _transaction_details_metaboxes()
874
+	{
875
+
876
+		$this->_set_transaction_object();
877
+
878
+		if (! $this->_transaction instanceof EE_Transaction) {
879
+			return;
880
+		}
881
+		add_meta_box(
882
+			'edit-txn-details-mbox',
883
+			esc_html__('Transaction Details', 'event_espresso'),
884
+			array($this, 'txn_details_meta_box'),
885
+			$this->_wp_page_slug,
886
+			'normal',
887
+			'high'
888
+		);
889
+		add_meta_box(
890
+			'edit-txn-attendees-mbox',
891
+			esc_html__('Attendees Registered in this Transaction', 'event_espresso'),
892
+			array($this, 'txn_attendees_meta_box'),
893
+			$this->_wp_page_slug,
894
+			'normal',
895
+			'high',
896
+			array('TXN_ID' => $this->_transaction->ID())
897
+		);
898
+		add_meta_box(
899
+			'edit-txn-registrant-mbox',
900
+			esc_html__('Primary Contact', 'event_espresso'),
901
+			array($this, 'txn_registrant_side_meta_box'),
902
+			$this->_wp_page_slug,
903
+			'side',
904
+			'high'
905
+		);
906
+		add_meta_box(
907
+			'edit-txn-billing-info-mbox',
908
+			esc_html__('Billing Information', 'event_espresso'),
909
+			array($this, 'txn_billing_info_side_meta_box'),
910
+			$this->_wp_page_slug,
911
+			'side',
912
+			'high'
913
+		);
914
+	}
915
+
916
+
917
+	/**
918
+	 * Callback for transaction actions metabox.
919
+	 *
920
+	 * @param EE_Transaction|null $transaction
921
+	 * @return string
922
+	 * @throws DomainException
923
+	 * @throws EE_Error
924
+	 * @throws InvalidArgumentException
925
+	 * @throws InvalidDataTypeException
926
+	 * @throws InvalidInterfaceException
927
+	 * @throws ReflectionException
928
+	 * @throws RuntimeException
929
+	 */
930
+	public function getActionButtons(EE_Transaction $transaction = null)
931
+	{
932
+		$content = '';
933
+		$actions = array();
934
+		if (! $transaction instanceof EE_Transaction) {
935
+			return $content;
936
+		}
937
+		/** @var EE_Registration $primary_registration */
938
+		$primary_registration = $transaction->primary_registration();
939
+		$attendee = $primary_registration instanceof EE_Registration
940
+			? $primary_registration->attendee()
941
+			: null;
942
+
943
+		if (
944
+			$attendee instanceof EE_Attendee
945
+			&& EE_Registry::instance()->CAP->current_user_can(
946
+				'ee_send_message',
947
+				'espresso_transactions_send_payment_reminder'
948
+			)
949
+		) {
950
+			$actions['payment_reminder'] =
951
+				EEH_MSG_Template::is_mt_active('payment_reminder')
952
+				&& $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
953
+				&& $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
954
+					? EEH_Template::get_button_or_link(
955
+						EE_Admin_Page::add_query_args_and_nonce(
956
+							array(
957
+								'action'      => 'send_payment_reminder',
958
+								'TXN_ID'      => $this->_transaction->ID(),
959
+								'redirect_to' => 'view_transaction',
960
+							),
961
+							TXN_ADMIN_URL
962
+						),
963
+						esc_html__(' Send Payment Reminder', 'event_espresso'),
964
+						'button secondary-button',
965
+						'dashicons dashicons-email-alt'
966
+					)
967
+					: '';
968
+		}
969
+
970
+		if (
971
+			EE_Registry::instance()->CAP->current_user_can(
972
+				'ee_edit_payments',
973
+				'espresso_transactions_recalculate_line_items'
974
+			)
975
+		) {
976
+			$actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
977
+				EE_Admin_Page::add_query_args_and_nonce(
978
+					array(
979
+						'action'      => 'espresso_recalculate_line_items',
980
+						'TXN_ID'      => $this->_transaction->ID(),
981
+						'redirect_to' => 'view_transaction',
982
+					),
983
+					TXN_ADMIN_URL
984
+				),
985
+				esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
986
+				'button secondary-button',
987
+				'dashicons dashicons-update'
988
+			);
989
+		}
990
+
991
+		if (
992
+			$primary_registration instanceof EE_Registration
993
+			&& EEH_MSG_Template::is_mt_active('receipt')
994
+		) {
995
+			$actions['receipt'] = EEH_Template::get_button_or_link(
996
+				$primary_registration->receipt_url(),
997
+				esc_html__('View Receipt', 'event_espresso'),
998
+				'button secondary-button',
999
+				'dashicons dashicons-media-default'
1000
+			);
1001
+		}
1002
+
1003
+		if (
1004
+			$primary_registration instanceof EE_Registration
1005
+			&& EEH_MSG_Template::is_mt_active('invoice')
1006
+		) {
1007
+			$actions['invoice'] = EEH_Template::get_button_or_link(
1008
+				$primary_registration->invoice_url(),
1009
+				esc_html__('View Invoice', 'event_espresso'),
1010
+				'button secondary-button',
1011
+				'dashicons dashicons-media-spreadsheet'
1012
+			);
1013
+		}
1014
+		$actions = array_filter(
1015
+			apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
1016
+		);
1017
+		if ($actions) {
1018
+			$content = '<ul>';
1019
+			$content .= '<li>' . implode('</li><li>', $actions) . '</li>';
1020
+			$content .= '</uL>';
1021
+		}
1022
+		return $content;
1023
+	}
1024
+
1025
+
1026
+	/**
1027
+	 * txn_details_meta_box
1028
+	 * generates HTML for the Transaction main meta box
1029
+	 *
1030
+	 * @return void
1031
+	 * @throws DomainException
1032
+	 * @throws EE_Error
1033
+	 * @throws InvalidArgumentException
1034
+	 * @throws InvalidDataTypeException
1035
+	 * @throws InvalidInterfaceException
1036
+	 * @throws RuntimeException
1037
+	 * @throws ReflectionException
1038
+	 */
1039
+	public function txn_details_meta_box()
1040
+	{
1041
+		$this->_set_transaction_object();
1042
+		$this->_template_args['TXN_ID'] = $this->_transaction->ID();
1043
+		$this->_template_args['attendee'] = $this->_transaction->primary_registration() instanceof EE_Registration
1044
+			? $this->_transaction->primary_registration()->attendee()
1045
+			: null;
1046
+		$this->_template_args['can_edit_payments'] = EE_Registry::instance()->CAP->current_user_can(
1047
+			'ee_edit_payments',
1048
+			'apply_payment_or_refund_from_registration_details'
1049
+		);
1050
+		$this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1051
+			'ee_delete_payments',
1052
+			'delete_payment_from_registration_details'
1053
+		);
1054
+
1055
+		// get line table
1056
+		EEH_Autoloader::register_line_item_display_autoloaders();
1057
+		$Line_Item_Display = new EE_Line_Item_Display(
1058
+			'admin_table',
1059
+			'EE_Admin_Table_Line_Item_Display_Strategy'
1060
+		);
1061
+		$this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1062
+			$this->_transaction->total_line_item()
1063
+		);
1064
+		$this->_template_args['REG_code'] = $this->_transaction->primary_registration() instanceof EE_Registration
1065
+			? $this->_transaction->primary_registration()->reg_code()
1066
+			: null;
1067
+		// process taxes
1068
+		$taxes = $this->_transaction->line_items(array(array('LIN_type' => EEM_Line_Item::type_tax)));
1069
+		$this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1070
+
1071
+		$this->_template_args['grand_total'] = EEH_Template::format_currency(
1072
+			$this->_transaction->total(),
1073
+			false,
1074
+			false
1075
+		);
1076
+		$this->_template_args['grand_raw_total'] = $this->_transaction->total();
1077
+		$this->_template_args['TXN_status'] = $this->_transaction->status_ID();
1078
+
1079
+		// process payment details
1080
+		$payments = $this->_transaction->payments();
1081
+		if (! empty($payments)) {
1082
+			$this->_template_args['payments'] = $payments;
1083
+			$this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1084
+		} else {
1085
+			$this->_template_args['payments'] = false;
1086
+			$this->_template_args['existing_reg_payments'] = array();
1087
+		}
1088
+
1089
+		$this->_template_args['edit_payment_url'] = add_query_arg(array('action' => 'edit_payment'), TXN_ADMIN_URL);
1090
+		$this->_template_args['delete_payment_url'] = add_query_arg(
1091
+			array('action' => 'espresso_delete_payment'),
1092
+			TXN_ADMIN_URL
1093
+		);
1094
+
1095
+		if (isset($txn_details['invoice_number'])) {
1096
+			$this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1097
+			$this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1098
+				'Invoice Number',
1099
+				'event_espresso'
1100
+			);
1101
+		}
1102
+
1103
+		$this->_template_args['txn_details']['registration_session']['value']
1104
+			= $this->_transaction->primary_registration() instanceof EE_Registration
1105
+			? $this->_transaction->primary_registration()->session_ID()
1106
+			: null;
1107
+		$this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1108
+			'Registration Session',
1109
+			'event_espresso'
1110
+		);
1111
+
1112
+		$this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address'])
1113
+			? $this->_session['ip_address']
1114
+			: '';
1115
+		$this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1116
+			'Transaction placed from IP',
1117
+			'event_espresso'
1118
+		);
1119
+
1120
+		$this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent'])
1121
+			? $this->_session['user_agent']
1122
+			: '';
1123
+		$this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1124
+			'Registrant User Agent',
1125
+			'event_espresso'
1126
+		);
1127
+
1128
+		$reg_steps = '<ul>';
1129
+		foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1130
+			if ($reg_step_status === true) {
1131
+				$reg_steps .= '<li style="color:#70cc50">'
1132
+							  . sprintf(
1133
+								  esc_html__('%1$s : Completed', 'event_espresso'),
1134
+								  ucwords(str_replace('_', ' ', $reg_step))
1135
+							  )
1136
+							  . '</li>';
1137
+			} elseif (is_numeric($reg_step_status) && $reg_step_status !== false) {
1138
+				$reg_steps .= '<li style="color:#2EA2CC">'
1139
+							  . sprintf(
1140
+								  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1141
+								  ucwords(str_replace('_', ' ', $reg_step)),
1142
+								  date(
1143
+									  get_option('date_format') . ' ' . get_option('time_format'),
1144
+									  $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1145
+								  )
1146
+							  )
1147
+							  . '</li>';
1148
+			} else {
1149
+				$reg_steps .= '<li style="color:#E76700">'
1150
+							  . sprintf(
1151
+								  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1152
+								  ucwords(str_replace('_', ' ', $reg_step))
1153
+							  )
1154
+							  . '</li>';
1155
+			}
1156
+		}
1157
+		$reg_steps .= '</ul>';
1158
+		$this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1159
+		$this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1160
+			'Registration Step Progress',
1161
+			'event_espresso'
1162
+		);
1163
+
1164
+
1165
+		$this->_get_registrations_to_apply_payment_to();
1166
+		$this->_get_payment_methods($payments);
1167
+		$this->_get_payment_status_array();
1168
+		$this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1169
+
1170
+		$this->_template_args['transaction_form_url'] = add_query_arg(
1171
+			array(
1172
+				'action'  => 'edit_transaction',
1173
+				'process' => 'transaction',
1174
+			),
1175
+			TXN_ADMIN_URL
1176
+		);
1177
+		$this->_template_args['apply_payment_form_url'] = add_query_arg(
1178
+			array(
1179
+				'page'   => 'espresso_transactions',
1180
+				'action' => 'espresso_apply_payment',
1181
+			),
1182
+			WP_AJAX_URL
1183
+		);
1184
+		$this->_template_args['delete_payment_form_url'] = add_query_arg(
1185
+			array(
1186
+				'page'   => 'espresso_transactions',
1187
+				'action' => 'espresso_delete_payment',
1188
+			),
1189
+			WP_AJAX_URL
1190
+		);
1191
+
1192
+		$this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1193
+
1194
+		// 'espresso_delete_payment_nonce'
1195
+
1196
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1197
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1198
+	}
1199
+
1200
+
1201
+	/**
1202
+	 * _get_registration_payment_IDs
1203
+	 *    generates an array of Payment IDs and their corresponding Registration IDs
1204
+	 *
1205
+	 * @access protected
1206
+	 * @param EE_Payment[] $payments
1207
+	 * @return array
1208
+	 * @throws EE_Error
1209
+	 * @throws InvalidArgumentException
1210
+	 * @throws InvalidDataTypeException
1211
+	 * @throws InvalidInterfaceException
1212
+	 * @throws ReflectionException
1213
+	 */
1214
+	protected function _get_registration_payment_IDs($payments = array())
1215
+	{
1216
+		$existing_reg_payments = array();
1217
+		// get all reg payments for these payments
1218
+		$reg_payments = EEM_Registration_Payment::instance()->get_all(
1219
+			array(
1220
+				array(
1221
+					'PAY_ID' => array(
1222
+						'IN',
1223
+						array_keys($payments),
1224
+					),
1225
+				),
1226
+			)
1227
+		);
1228
+		if (! empty($reg_payments)) {
1229
+			foreach ($payments as $payment) {
1230
+				if (! $payment instanceof EE_Payment) {
1231
+					continue;
1232
+				} elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1233
+					$existing_reg_payments[ $payment->ID() ] = array();
1234
+				}
1235
+				foreach ($reg_payments as $reg_payment) {
1236
+					if (
1237
+						$reg_payment instanceof EE_Registration_Payment
1238
+						&& $reg_payment->payment_ID() === $payment->ID()
1239
+					) {
1240
+						$existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1241
+					}
1242
+				}
1243
+			}
1244
+		}
1245
+
1246
+		return $existing_reg_payments;
1247
+	}
1248
+
1249
+
1250
+	/**
1251
+	 * _get_registrations_to_apply_payment_to
1252
+	 *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1253
+	 * which allows the admin to only apply the payment to the specific registrations
1254
+	 *
1255
+	 * @access protected
1256
+	 * @return void
1257
+	 * @throws EE_Error
1258
+	 * @throws InvalidArgumentException
1259
+	 * @throws InvalidDataTypeException
1260
+	 * @throws InvalidInterfaceException
1261
+	 * @throws ReflectionException
1262
+	 */
1263
+	protected function _get_registrations_to_apply_payment_to()
1264
+	{
1265
+		// we want any registration with an active status (ie: not deleted or cancelled)
1266
+		$query_params = array(
1267
+			array(
1268
+				'STS_ID' => array(
1269
+					'IN',
1270
+					array(
1271
+						EEM_Registration::status_id_approved,
1272
+						EEM_Registration::status_id_pending_payment,
1273
+						EEM_Registration::status_id_not_approved,
1274
+					),
1275
+				),
1276
+			),
1277
+		);
1278
+		$registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1279
+			'',
1280
+			'txn-admin-apply-payment-to-registrations-dv',
1281
+			'',
1282
+			'clear: both; margin: 1.5em 0 0; display: none;'
1283
+		);
1284
+		$registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1285
+		$registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
1286
+		$registrations_to_apply_payment_to .= EEH_HTML::thead(
1287
+			EEH_HTML::tr(
1288
+				EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1289
+				EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1290
+				EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1291
+				EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1292
+				EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1293
+				EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1294
+				EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1295
+			)
1296
+		);
1297
+		$registrations_to_apply_payment_to .= EEH_HTML::tbody();
1298
+		// get registrations for TXN
1299
+		$registrations = $this->_transaction->registrations($query_params);
1300
+		$existing_reg_payments = $this->_template_args['existing_reg_payments'];
1301
+		foreach ($registrations as $registration) {
1302
+			if ($registration instanceof EE_Registration) {
1303
+				$attendee_name = $registration->attendee() instanceof EE_Attendee
1304
+					? $registration->attendee()->full_name()
1305
+					: esc_html__('Unknown Attendee', 'event_espresso');
1306
+				$owing = $registration->final_price() - $registration->paid();
1307
+				$taxable = $registration->ticket()->taxable()
1308
+					? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1309
+					: '';
1310
+				$checked = empty($existing_reg_payments)
1311
+						   || in_array($registration->ID(), $existing_reg_payments, true)
1312
+					? ' checked="checked"'
1313
+					: '';
1314
+				$disabled = $registration->final_price() > 0 ? '' : ' disabled';
1315
+				$registrations_to_apply_payment_to .= EEH_HTML::tr(
1316
+					EEH_HTML::td($registration->ID()) .
1317
+					EEH_HTML::td($attendee_name) .
1318
+					EEH_HTML::td(
1319
+						$registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1320
+					) .
1321
+					EEH_HTML::td($registration->event_name()) .
1322
+					EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1323
+					EEH_HTML::td(
1324
+						EEH_Template::format_currency($owing),
1325
+						'',
1326
+						'txn-admin-payment-owing-td jst-cntr'
1327
+					) .
1328
+					EEH_HTML::td(
1329
+						'<input type="checkbox" value="' . $registration->ID()
1330
+						. '" name="txn_admin_payment[registrations]"'
1331
+						. $checked . $disabled . '>',
1332
+						'',
1333
+						'jst-cntr'
1334
+					),
1335
+					'apply-payment-registration-row-' . $registration->ID()
1336
+				);
1337
+			}
1338
+		}
1339
+		$registrations_to_apply_payment_to .= EEH_HTML::tbodyx();
1340
+		$registrations_to_apply_payment_to .= EEH_HTML::tablex();
1341
+		$registrations_to_apply_payment_to .= EEH_HTML::divx();
1342
+		$registrations_to_apply_payment_to .= EEH_HTML::p(
1343
+			esc_html__(
1344
+				'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.',
1345
+				'event_espresso'
1346
+			),
1347
+			'',
1348
+			'clear description'
1349
+		);
1350
+		$registrations_to_apply_payment_to .= EEH_HTML::divx();
1351
+		$this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1352
+	}
1353
+
1354
+
1355
+	/**
1356
+	 * _get_reg_status_selection
1357
+	 *
1358
+	 * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1359
+	 *         instead of events.
1360
+	 * @access protected
1361
+	 * @return void
1362
+	 * @throws EE_Error
1363
+	 */
1364
+	protected function _get_reg_status_selection()
1365
+	{
1366
+		// first get all possible statuses
1367
+		$statuses = EEM_Registration::reg_status_array(array(), true);
1368
+		// let's add a "don't change" option.
1369
+		$status_array['NAN'] = esc_html__('Leave the Same', 'event_espresso');
1370
+		$status_array = array_merge($status_array, $statuses);
1371
+		$this->_template_args['status_change_select'] = EEH_Form_Fields::select_input(
1372
+			'txn_reg_status_change[reg_status]',
1373
+			$status_array,
1374
+			'NAN',
1375
+			'id="txn-admin-payment-reg-status-inp"',
1376
+			'txn-reg-status-change-reg-status'
1377
+		);
1378
+		$this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1379
+			'delete_txn_reg_status_change[reg_status]',
1380
+			$status_array,
1381
+			'NAN',
1382
+			'delete-txn-admin-payment-reg-status-inp',
1383
+			'delete-txn-reg-status-change-reg-status'
1384
+		);
1385
+	}
1386
+
1387
+
1388
+	/**
1389
+	 *    _get_payment_methods
1390
+	 * Gets all the payment methods available generally, or the ones that are already
1391
+	 * selected on these payments (in case their payment methods are no longer active).
1392
+	 * Has the side-effect of updating the template args' payment_methods item
1393
+	 *
1394
+	 * @access private
1395
+	 * @param EE_Payment[] to show on this page
1396
+	 * @return void
1397
+	 * @throws EE_Error
1398
+	 * @throws InvalidArgumentException
1399
+	 * @throws InvalidDataTypeException
1400
+	 * @throws InvalidInterfaceException
1401
+	 * @throws ReflectionException
1402
+	 */
1403
+	private function _get_payment_methods($payments = array())
1404
+	{
1405
+		$payment_methods_of_payments = array();
1406
+		foreach ($payments as $payment) {
1407
+			if ($payment instanceof EE_Payment) {
1408
+				$payment_methods_of_payments[] = $payment->ID();
1409
+			}
1410
+		}
1411
+		if ($payment_methods_of_payments) {
1412
+			$query_args = array(
1413
+				array(
1414
+					'OR*payment_method_for_payment' => array(
1415
+						'PMD_ID'    => array('IN', $payment_methods_of_payments),
1416
+						'PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%'),
1417
+					),
1418
+				),
1419
+			);
1420
+		} else {
1421
+			$query_args = array(array('PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%')));
1422
+		}
1423
+		$this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1424
+	}
1425
+
1426
+
1427
+	/**
1428
+	 * txn_attendees_meta_box
1429
+	 *    generates HTML for the Attendees Transaction main meta box
1430
+	 *
1431
+	 * @access public
1432
+	 * @param WP_Post $post
1433
+	 * @param array   $metabox
1434
+	 * @return void
1435
+	 * @throws DomainException
1436
+	 * @throws EE_Error
1437
+	 * @throws InvalidArgumentException
1438
+	 * @throws InvalidDataTypeException
1439
+	 * @throws InvalidInterfaceException
1440
+	 * @throws ReflectionException
1441
+	 */
1442
+	public function txn_attendees_meta_box($post, $metabox = array('args' => array()))
1443
+	{
1444
+
1445
+		/** @noinspection NonSecureExtractUsageInspection */
1446
+		extract($metabox['args']);
1447
+		$this->_template_args['post'] = $post;
1448
+		$this->_template_args['event_attendees'] = array();
1449
+		// process items in cart
1450
+		$line_items = $this->_transaction->get_many_related(
1451
+			'Line_Item',
1452
+			array(array('LIN_type' => 'line-item'))
1453
+		);
1454
+		if (! empty($line_items)) {
1455
+			foreach ($line_items as $item) {
1456
+				if ($item instanceof EE_Line_Item) {
1457
+					switch ($item->OBJ_type()) {
1458
+						case 'Event':
1459
+							break;
1460
+						case 'Ticket':
1461
+							$ticket = $item->ticket();
1462
+							// right now we're only handling tickets here.
1463
+							// Cause its expected that only tickets will have attendees right?
1464
+							if (! $ticket instanceof EE_Ticket) {
1465
+								break;
1466
+							}
1467
+							try {
1468
+								$event_name = $ticket->get_event_name();
1469
+							} catch (Exception $e) {
1470
+								EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1471
+								$event_name = esc_html__('Unknown Event', 'event_espresso');
1472
+							}
1473
+							$event_name .= ' - ' . $item->name();
1474
+							$ticket_price = EEH_Template::format_currency($item->unit_price());
1475
+							// now get all of the registrations for this transaction that use this ticket
1476
+							$registrations = $ticket->registrations(
1477
+								array(array('TXN_ID' => $this->_transaction->ID()))
1478
+							);
1479
+							foreach ($registrations as $registration) {
1480
+								if (! $registration instanceof EE_Registration) {
1481
+									break;
1482
+								}
1483
+								$this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1484
+									= $registration->status_ID();
1485
+								$this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1486
+									= $registration->count();
1487
+								$this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1488
+									= $event_name;
1489
+								$this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1490
+									= $ticket_price;
1491
+								// attendee info
1492
+								$attendee = $registration->get_first_related('Attendee');
1493
+								if ($attendee instanceof EE_Attendee) {
1494
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1495
+										= $attendee->ID();
1496
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1497
+										= $attendee->full_name();
1498
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']
1499
+										= '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1500
+										  . esc_html__(
1501
+											  ' Event',
1502
+											  'event_espresso'
1503
+										  )
1504
+										  . '">' . $attendee->email() . '</a>';
1505
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']
1506
+										= EEH_Address::format($attendee, 'inline', false, false);
1507
+								} else {
1508
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id'] = '';
1509
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1510
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email'] = '';
1511
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address'] = '';
1512
+								}
1513
+							}
1514
+							break;
1515
+					}
1516
+				}
1517
+			}
1518
+
1519
+			$this->_template_args['transaction_form_url'] = add_query_arg(
1520
+				array(
1521
+					'action'  => 'edit_transaction',
1522
+					'process' => 'attendees',
1523
+				),
1524
+				TXN_ADMIN_URL
1525
+			);
1526
+			echo EEH_Template::display_template(
1527
+				TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1528
+				$this->_template_args,
1529
+				true
1530
+			);
1531
+		} else {
1532
+			echo sprintf(
1533
+				esc_html__(
1534
+					'%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1535
+					'event_espresso'
1536
+				),
1537
+				'<p class="important-notice">',
1538
+				'</p>'
1539
+			);
1540
+		}
1541
+	}
1542
+
1543
+
1544
+	/**
1545
+	 * txn_registrant_side_meta_box
1546
+	 * generates HTML for the Edit Transaction side meta box
1547
+	 *
1548
+	 * @access public
1549
+	 * @return void
1550
+	 * @throws DomainException
1551
+	 * @throws EE_Error
1552
+	 * @throws InvalidArgumentException
1553
+	 * @throws InvalidDataTypeException
1554
+	 * @throws InvalidInterfaceException
1555
+	 * @throws ReflectionException
1556
+	 */
1557
+	public function txn_registrant_side_meta_box()
1558
+	{
1559
+		$primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1560
+			? $this->_transaction->primary_registration()->get_first_related('Attendee')
1561
+			: null;
1562
+		if (! $primary_att instanceof EE_Attendee) {
1563
+			$this->_template_args['no_attendee_message'] = esc_html__(
1564
+				'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1565
+				'event_espresso'
1566
+			);
1567
+			$primary_att = EEM_Attendee::instance()->create_default_object();
1568
+		}
1569
+		$this->_template_args['ATT_ID'] = $primary_att->ID();
1570
+		$this->_template_args['prime_reg_fname'] = $primary_att->fname();
1571
+		$this->_template_args['prime_reg_lname'] = $primary_att->lname();
1572
+		$this->_template_args['prime_reg_email'] = $primary_att->email();
1573
+		$this->_template_args['prime_reg_phone'] = $primary_att->phone();
1574
+		$this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1575
+			array(
1576
+				'action' => 'edit_attendee',
1577
+				'post'   => $primary_att->ID(),
1578
+			),
1579
+			REG_ADMIN_URL
1580
+		);
1581
+		// get formatted address for registrant
1582
+		$this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1583
+		echo EEH_Template::display_template(
1584
+			TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1585
+			$this->_template_args,
1586
+			true
1587
+		);
1588
+	}
1589
+
1590
+
1591
+	/**
1592
+	 * txn_billing_info_side_meta_box
1593
+	 *    generates HTML for the Edit Transaction side meta box
1594
+	 *
1595
+	 * @access public
1596
+	 * @return void
1597
+	 * @throws DomainException
1598
+	 * @throws EE_Error
1599
+	 */
1600
+	public function txn_billing_info_side_meta_box()
1601
+	{
1602
+
1603
+		$this->_template_args['billing_form'] = $this->_transaction->billing_info();
1604
+		$this->_template_args['billing_form_url'] = add_query_arg(
1605
+			array('action' => 'edit_transaction', 'process' => 'billing'),
1606
+			TXN_ADMIN_URL
1607
+		);
1608
+
1609
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1610
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1611
+	}
1612
+
1613
+
1614
+	/**
1615
+	 * apply_payments_or_refunds
1616
+	 *    registers a payment or refund made towards a transaction
1617
+	 *
1618
+	 * @access public
1619
+	 * @return void
1620
+	 * @throws EE_Error
1621
+	 * @throws InvalidArgumentException
1622
+	 * @throws ReflectionException
1623
+	 * @throws RuntimeException
1624
+	 * @throws InvalidDataTypeException
1625
+	 * @throws InvalidInterfaceException
1626
+	 */
1627
+	public function apply_payments_or_refunds()
1628
+	{
1629
+		$json_response_data = array('return_data' => false);
1630
+		$valid_data = $this->_validate_payment_request_data();
1631
+		$has_access = EE_Registry::instance()->CAP->current_user_can(
1632
+			'ee_edit_payments',
1633
+			'apply_payment_or_refund_from_registration_details'
1634
+		);
1635
+		if (! empty($valid_data) && $has_access) {
1636
+			$PAY_ID = $valid_data['PAY_ID'];
1637
+			// save  the new payment
1638
+			$payment = $this->_create_payment_from_request_data($valid_data);
1639
+			// get the TXN for this payment
1640
+			$transaction = $payment->transaction();
1641
+			// verify transaction
1642
+			if ($transaction instanceof EE_Transaction) {
1643
+				// calculate_total_payments_and_update_status
1644
+				$this->_process_transaction_payments($transaction);
1645
+				$REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1646
+				$this->_remove_existing_registration_payments($payment, $PAY_ID);
1647
+				// apply payment to registrations (if applicable)
1648
+				if (! empty($REG_IDs)) {
1649
+					$this->_update_registration_payments($transaction, $payment, $REG_IDs);
1650
+					$this->_maybe_send_notifications();
1651
+					// now process status changes for the same registrations
1652
+					$this->_process_registration_status_change($transaction, $REG_IDs);
1653
+				}
1654
+				$this->_maybe_send_notifications($payment);
1655
+				// prepare to render page
1656
+				$json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1657
+				do_action(
1658
+					'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1659
+					$transaction,
1660
+					$payment
1661
+				);
1662
+			} else {
1663
+				EE_Error::add_error(
1664
+					esc_html__(
1665
+						'A valid Transaction for this payment could not be retrieved.',
1666
+						'event_espresso'
1667
+					),
1668
+					__FILE__,
1669
+					__FUNCTION__,
1670
+					__LINE__
1671
+				);
1672
+			}
1673
+		} elseif ($has_access) {
1674
+			EE_Error::add_error(
1675
+				esc_html__(
1676
+					'The payment form data could not be processed. Please try again.',
1677
+					'event_espresso'
1678
+				),
1679
+				__FILE__,
1680
+				__FUNCTION__,
1681
+				__LINE__
1682
+			);
1683
+		} else {
1684
+			EE_Error::add_error(
1685
+				esc_html__(
1686
+					'You do not have access to apply payments or refunds to a registration.',
1687
+					'event_espresso'
1688
+				),
1689
+				__FILE__,
1690
+				__FUNCTION__,
1691
+				__LINE__
1692
+			);
1693
+		}
1694
+		$notices = EE_Error::get_notices(
1695
+			false,
1696
+			false,
1697
+			false
1698
+		);
1699
+		$this->_template_args = array(
1700
+			'data'    => $json_response_data,
1701
+			'error'   => $notices['errors'],
1702
+			'success' => $notices['success'],
1703
+		);
1704
+		$this->_return_json();
1705
+	}
1706
+
1707
+
1708
+	/**
1709
+	 * _validate_payment_request_data
1710
+	 *
1711
+	 * @return array
1712
+	 * @throws EE_Error
1713
+	 * @throws InvalidArgumentException
1714
+	 * @throws InvalidDataTypeException
1715
+	 * @throws InvalidInterfaceException
1716
+	 */
1717
+	protected function _validate_payment_request_data()
1718
+	{
1719
+		if (! isset($this->_req_data['txn_admin_payment'])) {
1720
+			return array();
1721
+		}
1722
+		$payment_form = $this->_generate_payment_form_section();
1723
+		try {
1724
+			if ($payment_form->was_submitted()) {
1725
+				$payment_form->receive_form_submission();
1726
+				if (! $payment_form->is_valid()) {
1727
+					$submission_error_messages = array();
1728
+					foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1729
+						if ($validation_error instanceof EE_Validation_Error) {
1730
+							$submission_error_messages[] = sprintf(
1731
+								_x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1732
+								$validation_error->get_form_section()->html_label_text(),
1733
+								$validation_error->getMessage()
1734
+							);
1735
+						}
1736
+					}
1737
+					EE_Error::add_error(
1738
+						implode('<br />', $submission_error_messages),
1739
+						__FILE__,
1740
+						__FUNCTION__,
1741
+						__LINE__
1742
+					);
1743
+					return array();
1744
+				}
1745
+			}
1746
+		} catch (EE_Error $e) {
1747
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1748
+			return array();
1749
+		}
1750
+
1751
+		return $payment_form->valid_data();
1752
+	}
1753
+
1754
+
1755
+	/**
1756
+	 * _generate_payment_form_section
1757
+	 *
1758
+	 * @return EE_Form_Section_Proper
1759
+	 * @throws EE_Error
1760
+	 */
1761
+	protected function _generate_payment_form_section()
1762
+	{
1763
+		return new EE_Form_Section_Proper(
1764
+			array(
1765
+				'name'        => 'txn_admin_payment',
1766
+				'subsections' => array(
1767
+					'PAY_ID'          => new EE_Text_Input(
1768
+						array(
1769
+							'default'               => 0,
1770
+							'required'              => false,
1771
+							'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1772
+							'validation_strategies' => array(new EE_Int_Normalization()),
1773
+						)
1774
+					),
1775
+					'TXN_ID'          => new EE_Text_Input(
1776
+						array(
1777
+							'default'               => 0,
1778
+							'required'              => true,
1779
+							'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1780
+							'validation_strategies' => array(new EE_Int_Normalization()),
1781
+						)
1782
+					),
1783
+					'type'            => new EE_Text_Input(
1784
+						array(
1785
+							'default'               => 1,
1786
+							'required'              => true,
1787
+							'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1788
+							'validation_strategies' => array(new EE_Int_Normalization()),
1789
+						)
1790
+					),
1791
+					'amount'          => new EE_Text_Input(
1792
+						array(
1793
+							'default'               => 0,
1794
+							'required'              => true,
1795
+							'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1796
+							'validation_strategies' => array(new EE_Float_Normalization()),
1797
+						)
1798
+					),
1799
+					'status'          => new EE_Text_Input(
1800
+						array(
1801
+							'default'         => EEM_Payment::status_id_approved,
1802
+							'required'        => true,
1803
+							'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1804
+						)
1805
+					),
1806
+					'PMD_ID'          => new EE_Text_Input(
1807
+						array(
1808
+							'default'               => 2,
1809
+							'required'              => true,
1810
+							'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1811
+							'validation_strategies' => array(new EE_Int_Normalization()),
1812
+						)
1813
+					),
1814
+					'date'            => new EE_Text_Input(
1815
+						array(
1816
+							'default'         => time(),
1817
+							'required'        => true,
1818
+							'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1819
+						)
1820
+					),
1821
+					'txn_id_chq_nmbr' => new EE_Text_Input(
1822
+						array(
1823
+							'default'               => '',
1824
+							'required'              => false,
1825
+							'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1826
+							'validation_strategies' => array(
1827
+								new EE_Max_Length_Validation_Strategy(
1828
+									esc_html__('Input too long', 'event_espresso'),
1829
+									100
1830
+								),
1831
+							),
1832
+						)
1833
+					),
1834
+					'po_number'       => new EE_Text_Input(
1835
+						array(
1836
+							'default'               => '',
1837
+							'required'              => false,
1838
+							'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1839
+							'validation_strategies' => array(
1840
+								new EE_Max_Length_Validation_Strategy(
1841
+									esc_html__('Input too long', 'event_espresso'),
1842
+									100
1843
+								),
1844
+							),
1845
+						)
1846
+					),
1847
+					'accounting'      => new EE_Text_Input(
1848
+						array(
1849
+							'default'               => '',
1850
+							'required'              => false,
1851
+							'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1852
+							'validation_strategies' => array(
1853
+								new EE_Max_Length_Validation_Strategy(
1854
+									esc_html__('Input too long', 'event_espresso'),
1855
+									100
1856
+								),
1857
+							),
1858
+						)
1859
+					),
1860
+				),
1861
+			)
1862
+		);
1863
+	}
1864
+
1865
+
1866
+	/**
1867
+	 * _create_payment_from_request_data
1868
+	 *
1869
+	 * @param array $valid_data
1870
+	 * @return EE_Payment
1871
+	 * @throws EE_Error
1872
+	 * @throws InvalidArgumentException
1873
+	 * @throws InvalidDataTypeException
1874
+	 * @throws InvalidInterfaceException
1875
+	 * @throws ReflectionException
1876
+	 */
1877
+	protected function _create_payment_from_request_data($valid_data)
1878
+	{
1879
+		$PAY_ID = $valid_data['PAY_ID'];
1880
+		// get payment amount
1881
+		$amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1882
+		// payments have a type value of 1 and refunds have a type value of -1
1883
+		// so multiplying amount by type will give a positive value for payments, and negative values for refunds
1884
+		$amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1885
+		// for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1886
+		$date = $valid_data['date']
1887
+			? preg_replace('/\s+/', ' ', $valid_data['date'])
1888
+			: date('Y-m-d g:i a', current_time('timestamp'));
1889
+		$payment = EE_Payment::new_instance(
1890
+			array(
1891
+				'TXN_ID'              => $valid_data['TXN_ID'],
1892
+				'STS_ID'              => $valid_data['status'],
1893
+				'PAY_timestamp'       => $date,
1894
+				'PAY_source'          => EEM_Payment_Method::scope_admin,
1895
+				'PMD_ID'              => $valid_data['PMD_ID'],
1896
+				'PAY_amount'          => $amount,
1897
+				'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1898
+				'PAY_po_number'       => $valid_data['po_number'],
1899
+				'PAY_extra_accntng'   => $valid_data['accounting'],
1900
+				'PAY_details'         => $valid_data,
1901
+				'PAY_ID'              => $PAY_ID,
1902
+			),
1903
+			'',
1904
+			array('Y-m-d', 'g:i a')
1905
+		);
1906
+
1907
+		if (! $payment->save()) {
1908
+			EE_Error::add_error(
1909
+				sprintf(
1910
+					esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1911
+					$payment->ID()
1912
+				),
1913
+				__FILE__,
1914
+				__FUNCTION__,
1915
+				__LINE__
1916
+			);
1917
+		}
1918
+
1919
+		return $payment;
1920
+	}
1921
+
1922
+
1923
+	/**
1924
+	 * _process_transaction_payments
1925
+	 *
1926
+	 * @param \EE_Transaction $transaction
1927
+	 * @return void
1928
+	 * @throws EE_Error
1929
+	 * @throws InvalidArgumentException
1930
+	 * @throws ReflectionException
1931
+	 * @throws InvalidDataTypeException
1932
+	 * @throws InvalidInterfaceException
1933
+	 */
1934
+	protected function _process_transaction_payments(EE_Transaction $transaction)
1935
+	{
1936
+		/** @type EE_Transaction_Payments $transaction_payments */
1937
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1938
+		// update the transaction with this payment
1939
+		if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1940
+			EE_Error::add_success(
1941
+				esc_html__(
1942
+					'The payment has been processed successfully.',
1943
+					'event_espresso'
1944
+				),
1945
+				__FILE__,
1946
+				__FUNCTION__,
1947
+				__LINE__
1948
+			);
1949
+		} else {
1950
+			EE_Error::add_error(
1951
+				esc_html__(
1952
+					'The payment was processed successfully but the amount paid for the transaction was not updated.',
1953
+					'event_espresso'
1954
+				),
1955
+				__FILE__,
1956
+				__FUNCTION__,
1957
+				__LINE__
1958
+			);
1959
+		}
1960
+	}
1961
+
1962
+
1963
+	/**
1964
+	 * _get_REG_IDs_to_apply_payment_to
1965
+	 * returns a list of registration IDs that the payment will apply to
1966
+	 *
1967
+	 * @param \EE_Payment $payment
1968
+	 * @return array
1969
+	 * @throws EE_Error
1970
+	 * @throws InvalidArgumentException
1971
+	 * @throws InvalidDataTypeException
1972
+	 * @throws InvalidInterfaceException
1973
+	 * @throws ReflectionException
1974
+	 */
1975
+	protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1976
+	{
1977
+		$REG_IDs = array();
1978
+		// grab array of IDs for specific registrations to apply changes to
1979
+		if (isset($this->_req_data['txn_admin_payment']['registrations'])) {
1980
+			$REG_IDs = (array) $this->_req_data['txn_admin_payment']['registrations'];
1981
+		}
1982
+		// nothing specified ? then get all reg IDs
1983
+		if (empty($REG_IDs)) {
1984
+			$registrations = $payment->transaction()->registrations();
1985
+			$REG_IDs = ! empty($registrations)
1986
+				? array_keys($registrations)
1987
+				: $this->_get_existing_reg_payment_REG_IDs($payment);
1988
+		}
1989
+
1990
+		// ensure that REG_IDs are integers and NOT strings
1991
+		return array_map('intval', $REG_IDs);
1992
+	}
1993
+
1994
+
1995
+	/**
1996
+	 * @return array
1997
+	 */
1998
+	public function existing_reg_payment_REG_IDs()
1999
+	{
2000
+		return $this->_existing_reg_payment_REG_IDs;
2001
+	}
2002
+
2003
+
2004
+	/**
2005
+	 * @param array $existing_reg_payment_REG_IDs
2006
+	 */
2007
+	public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
2008
+	{
2009
+		$this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
2010
+	}
2011
+
2012
+
2013
+	/**
2014
+	 * _get_existing_reg_payment_REG_IDs
2015
+	 * returns a list of registration IDs that the payment is currently related to
2016
+	 * as recorded in the database
2017
+	 *
2018
+	 * @param \EE_Payment $payment
2019
+	 * @return array
2020
+	 * @throws EE_Error
2021
+	 * @throws InvalidArgumentException
2022
+	 * @throws InvalidDataTypeException
2023
+	 * @throws InvalidInterfaceException
2024
+	 * @throws ReflectionException
2025
+	 */
2026
+	protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2027
+	{
2028
+		if ($this->existing_reg_payment_REG_IDs() === null) {
2029
+			// let's get any existing reg payment records for this payment
2030
+			$existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2031
+			// but we only want the REG IDs, so grab the array keys
2032
+			$existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2033
+				? array_keys($existing_reg_payment_REG_IDs)
2034
+				: array();
2035
+			$this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2036
+		}
2037
+
2038
+		return $this->existing_reg_payment_REG_IDs();
2039
+	}
2040
+
2041
+
2042
+	/**
2043
+	 * _remove_existing_registration_payments
2044
+	 * this calculates the difference between existing relations
2045
+	 * to the supplied payment and the new list registration IDs,
2046
+	 * removes any related registrations that no longer apply,
2047
+	 * and then updates the registration paid fields
2048
+	 *
2049
+	 * @param \EE_Payment $payment
2050
+	 * @param int         $PAY_ID
2051
+	 * @return bool;
2052
+	 * @throws EE_Error
2053
+	 * @throws InvalidArgumentException
2054
+	 * @throws ReflectionException
2055
+	 * @throws InvalidDataTypeException
2056
+	 * @throws InvalidInterfaceException
2057
+	 */
2058
+	protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2059
+	{
2060
+		// newly created payments will have nothing recorded for $PAY_ID
2061
+		if (absint($PAY_ID) === 0) {
2062
+			return false;
2063
+		}
2064
+		$existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2065
+		if (empty($existing_reg_payment_REG_IDs)) {
2066
+			return false;
2067
+		}
2068
+		/** @type EE_Transaction_Payments $transaction_payments */
2069
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2070
+
2071
+		return $transaction_payments->delete_registration_payments_and_update_registrations(
2072
+			$payment,
2073
+			array(
2074
+				array(
2075
+					'PAY_ID' => $payment->ID(),
2076
+					'REG_ID' => array('IN', $existing_reg_payment_REG_IDs),
2077
+				),
2078
+			)
2079
+		);
2080
+	}
2081
+
2082
+
2083
+	/**
2084
+	 * _update_registration_payments
2085
+	 * this applies the payments to the selected registrations
2086
+	 * but only if they have not already been paid for
2087
+	 *
2088
+	 * @param  EE_Transaction $transaction
2089
+	 * @param \EE_Payment     $payment
2090
+	 * @param array           $REG_IDs
2091
+	 * @return void
2092
+	 * @throws EE_Error
2093
+	 * @throws InvalidArgumentException
2094
+	 * @throws ReflectionException
2095
+	 * @throws RuntimeException
2096
+	 * @throws InvalidDataTypeException
2097
+	 * @throws InvalidInterfaceException
2098
+	 */
2099
+	protected function _update_registration_payments(
2100
+		EE_Transaction $transaction,
2101
+		EE_Payment $payment,
2102
+		$REG_IDs = array()
2103
+	) {
2104
+		// we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2105
+		// so let's do that using our set of REG_IDs from the form
2106
+		$registration_query_where_params = array(
2107
+			'REG_ID' => array('IN', $REG_IDs),
2108
+		);
2109
+		// but add in some conditions regarding payment,
2110
+		// so that we don't apply payments to registrations that are free or have already been paid for
2111
+		// but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2112
+		if (! $payment->is_a_refund()) {
2113
+			$registration_query_where_params['REG_final_price'] = array('!=', 0);
2114
+			$registration_query_where_params['REG_final_price*'] = array('!=', 'REG_paid', true);
2115
+		}
2116
+		$registrations = $transaction->registrations(array($registration_query_where_params));
2117
+		if (! empty($registrations)) {
2118
+			/** @type EE_Payment_Processor $payment_processor */
2119
+			$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2120
+			$payment_processor->process_registration_payments($transaction, $payment, $registrations);
2121
+		}
2122
+	}
2123
+
2124
+
2125
+	/**
2126
+	 * _process_registration_status_change
2127
+	 * This processes requested registration status changes for all the registrations
2128
+	 * on a given transaction and (optionally) sends out notifications for the changes.
2129
+	 *
2130
+	 * @param  EE_Transaction $transaction
2131
+	 * @param array           $REG_IDs
2132
+	 * @return bool
2133
+	 * @throws EE_Error
2134
+	 * @throws InvalidArgumentException
2135
+	 * @throws ReflectionException
2136
+	 * @throws InvalidDataTypeException
2137
+	 * @throws InvalidInterfaceException
2138
+	 */
2139
+	protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = array())
2140
+	{
2141
+		// first if there is no change in status then we get out.
2142
+		if (
2143
+			! isset($this->_req_data['txn_reg_status_change']['reg_status'])
2144
+			|| $this->_req_data['txn_reg_status_change']['reg_status'] === 'NAN'
2145
+		) {
2146
+			// no error message, no change requested, just nothing to do man.
2147
+			return false;
2148
+		}
2149
+		/** @type EE_Transaction_Processor $transaction_processor */
2150
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2151
+
2152
+		// made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2153
+		return $transaction_processor->manually_update_registration_statuses(
2154
+			$transaction,
2155
+			sanitize_text_field($this->_req_data['txn_reg_status_change']['reg_status']),
2156
+			array(array('REG_ID' => array('IN', $REG_IDs)))
2157
+		);
2158
+	}
2159
+
2160
+
2161
+	/**
2162
+	 * _build_payment_json_response
2163
+	 *
2164
+	 * @access public
2165
+	 * @param \EE_Payment $payment
2166
+	 * @param array       $REG_IDs
2167
+	 * @param bool | null $delete_txn_reg_status_change
2168
+	 * @return array
2169
+	 * @throws EE_Error
2170
+	 * @throws InvalidArgumentException
2171
+	 * @throws InvalidDataTypeException
2172
+	 * @throws InvalidInterfaceException
2173
+	 * @throws ReflectionException
2174
+	 */
2175
+	protected function _build_payment_json_response(
2176
+		EE_Payment $payment,
2177
+		$REG_IDs = array(),
2178
+		$delete_txn_reg_status_change = null
2179
+	) {
2180
+		// was the payment deleted ?
2181
+		if (is_bool($delete_txn_reg_status_change)) {
2182
+			return array(
2183
+				'PAY_ID'                       => $payment->ID(),
2184
+				'amount'                       => $payment->amount(),
2185
+				'total_paid'                   => $payment->transaction()->paid(),
2186
+				'txn_status'                   => $payment->transaction()->status_ID(),
2187
+				'pay_status'                   => $payment->STS_ID(),
2188
+				'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2189
+				'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2190
+			);
2191
+		} else {
2192
+			$this->_get_payment_status_array();
2193
+
2194
+			return array(
2195
+				'amount'           => $payment->amount(),
2196
+				'total_paid'       => $payment->transaction()->paid(),
2197
+				'txn_status'       => $payment->transaction()->status_ID(),
2198
+				'pay_status'       => $payment->STS_ID(),
2199
+				'PAY_ID'           => $payment->ID(),
2200
+				'STS_ID'           => $payment->STS_ID(),
2201
+				'status'           => self::$_pay_status[ $payment->STS_ID() ],
2202
+				'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2203
+				'method'           => strtoupper($payment->source()),
2204
+				'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2205
+				'gateway'          => $payment->payment_method()
2206
+					? $payment->payment_method()->admin_name()
2207
+					: esc_html__('Unknown', 'event_espresso'),
2208
+				'gateway_response' => $payment->gateway_response(),
2209
+				'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2210
+				'po_number'        => $payment->po_number(),
2211
+				'extra_accntng'    => $payment->extra_accntng(),
2212
+				'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2213
+			);
2214
+		}
2215
+	}
2216
+
2217
+
2218
+	/**
2219
+	 * delete_payment
2220
+	 *    delete a payment or refund made towards a transaction
2221
+	 *
2222
+	 * @access public
2223
+	 * @return void
2224
+	 * @throws EE_Error
2225
+	 * @throws InvalidArgumentException
2226
+	 * @throws ReflectionException
2227
+	 * @throws InvalidDataTypeException
2228
+	 * @throws InvalidInterfaceException
2229
+	 */
2230
+	public function delete_payment()
2231
+	{
2232
+		$json_response_data = array('return_data' => false);
2233
+		$PAY_ID = isset($this->_req_data['delete_txn_admin_payment']['PAY_ID'])
2234
+			? absint($this->_req_data['delete_txn_admin_payment']['PAY_ID'])
2235
+			: 0;
2236
+		$can_delete = EE_Registry::instance()->CAP->current_user_can(
2237
+			'ee_delete_payments',
2238
+			'delete_payment_from_registration_details'
2239
+		);
2240
+		if ($PAY_ID && $can_delete) {
2241
+			$delete_txn_reg_status_change = isset($this->_req_data['delete_txn_reg_status_change'])
2242
+				? $this->_req_data['delete_txn_reg_status_change']
2243
+				: false;
2244
+			$payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2245
+			if ($payment instanceof EE_Payment) {
2246
+				$REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2247
+				/** @type EE_Transaction_Payments $transaction_payments */
2248
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2249
+				if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2250
+					$json_response_data['return_data'] = $this->_build_payment_json_response(
2251
+						$payment,
2252
+						$REG_IDs,
2253
+						$delete_txn_reg_status_change
2254
+					);
2255
+					if ($delete_txn_reg_status_change) {
2256
+						$this->_req_data['txn_reg_status_change'] = $delete_txn_reg_status_change;
2257
+						// MAKE sure we also add the delete_txn_req_status_change to the
2258
+						// $_REQUEST global because that's how messages will be looking for it.
2259
+						$this->request->setRequestParam('txn_reg_status_change', $delete_txn_reg_status_change);
2260
+						$this->_maybe_send_notifications();
2261
+						$this->_process_registration_status_change($payment->transaction(), $REG_IDs);
2262
+					}
2263
+				}
2264
+			} else {
2265
+				EE_Error::add_error(
2266
+					esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2267
+					__FILE__,
2268
+					__FUNCTION__,
2269
+					__LINE__
2270
+				);
2271
+			}
2272
+		} elseif ($can_delete) {
2273
+			EE_Error::add_error(
2274
+				esc_html__(
2275
+					'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2276
+					'event_espresso'
2277
+				),
2278
+				__FILE__,
2279
+				__FUNCTION__,
2280
+				__LINE__
2281
+			);
2282
+		} else {
2283
+			EE_Error::add_error(
2284
+				esc_html__(
2285
+					'You do not have access to delete a payment.',
2286
+					'event_espresso'
2287
+				),
2288
+				__FILE__,
2289
+				__FUNCTION__,
2290
+				__LINE__
2291
+			);
2292
+		}
2293
+		$notices = EE_Error::get_notices(false, false, false);
2294
+		$this->_template_args = array(
2295
+			'data'      => $json_response_data,
2296
+			'success'   => $notices['success'],
2297
+			'error'     => $notices['errors'],
2298
+			'attention' => $notices['attention'],
2299
+		);
2300
+		$this->_return_json();
2301
+	}
2302
+
2303
+
2304
+	/**
2305
+	 * _registration_payment_data_array
2306
+	 * adds info for 'owing' and 'paid' for each registration to the json response
2307
+	 *
2308
+	 * @access protected
2309
+	 * @param array $REG_IDs
2310
+	 * @return array
2311
+	 * @throws EE_Error
2312
+	 * @throws InvalidArgumentException
2313
+	 * @throws InvalidDataTypeException
2314
+	 * @throws InvalidInterfaceException
2315
+	 * @throws ReflectionException
2316
+	 */
2317
+	protected function _registration_payment_data_array($REG_IDs)
2318
+	{
2319
+		$registration_payment_data = array();
2320
+		// if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2321
+		if (! empty($REG_IDs)) {
2322
+			$registrations = EEM_Registration::instance()->get_all(array(array('REG_ID' => array('IN', $REG_IDs))));
2323
+			foreach ($registrations as $registration) {
2324
+				if ($registration instanceof EE_Registration) {
2325
+					$registration_payment_data[ $registration->ID() ] = array(
2326
+						'paid'  => $registration->pretty_paid(),
2327
+						'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2328
+					);
2329
+				}
2330
+			}
2331
+		}
2332
+
2333
+		return $registration_payment_data;
2334
+	}
2335
+
2336
+
2337
+	/**
2338
+	 * _maybe_send_notifications
2339
+	 * determines whether or not the admin has indicated that notifications should be sent.
2340
+	 * If so, will toggle a filter switch for delivering registration notices.
2341
+	 * If passed an EE_Payment object, then it will trigger payment notifications instead.
2342
+	 *
2343
+	 * @access protected
2344
+	 * @param \EE_Payment | null $payment
2345
+	 */
2346
+	protected function _maybe_send_notifications($payment = null)
2347
+	{
2348
+		switch ($payment instanceof EE_Payment) {
2349
+			// payment notifications
2350
+			case true:
2351
+				if (
2352
+					isset($this->_req_data['txn_payments']['send_notifications'])
2353
+					&& filter_var(
2354
+						$this->_req_data['txn_payments']['send_notifications'],
2355
+						FILTER_VALIDATE_BOOLEAN
2356
+					)
2357
+				) {
2358
+					$this->_process_payment_notification($payment);
2359
+				}
2360
+				break;
2361
+			// registration notifications
2362
+			case false:
2363
+				if (
2364
+					isset($this->_req_data['txn_reg_status_change']['send_notifications'])
2365
+					&& filter_var(
2366
+						$this->_req_data['txn_reg_status_change']['send_notifications'],
2367
+						FILTER_VALIDATE_BOOLEAN
2368
+					)
2369
+				) {
2370
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2371
+				}
2372
+				break;
2373
+		}
2374
+	}
2375
+
2376
+
2377
+	/**
2378
+	 * _send_payment_reminder
2379
+	 *    generates HTML for the View Transaction Details Admin page
2380
+	 *
2381
+	 * @access protected
2382
+	 * @return void
2383
+	 * @throws EE_Error
2384
+	 * @throws InvalidArgumentException
2385
+	 * @throws InvalidDataTypeException
2386
+	 * @throws InvalidInterfaceException
2387
+	 */
2388
+	protected function _send_payment_reminder()
2389
+	{
2390
+		$TXN_ID = ! empty($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : false;
2391
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2392
+		$query_args = isset($this->_req_data['redirect_to']) ? array(
2393
+			'action' => $this->_req_data['redirect_to'],
2394
+			'TXN_ID' => $this->_req_data['TXN_ID'],
2395
+		) : array();
2396
+		do_action(
2397
+			'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2398
+			$transaction
2399
+		);
2400
+		$this->_redirect_after_action(
2401
+			false,
2402
+			esc_html__('payment reminder', 'event_espresso'),
2403
+			esc_html__('sent', 'event_espresso'),
2404
+			$query_args,
2405
+			true
2406
+		);
2407
+	}
2408
+
2409
+
2410
+	/**
2411
+	 *  get_transactions
2412
+	 *    get transactions for given parameters (used by list table)
2413
+	 *
2414
+	 * @param  int     $perpage how many transactions displayed per page
2415
+	 * @param  boolean $count   return the count or objects
2416
+	 * @param string   $view
2417
+	 * @return mixed int = count || array of transaction objects
2418
+	 * @throws EE_Error
2419
+	 * @throws InvalidArgumentException
2420
+	 * @throws InvalidDataTypeException
2421
+	 * @throws InvalidInterfaceException
2422
+	 */
2423
+	public function get_transactions($perpage, $count = false, $view = '')
2424
+	{
2425
+
2426
+		$TXN = EEM_Transaction::instance();
2427
+
2428
+		$start_date = isset($this->_req_data['txn-filter-start-date'])
2429
+			? wp_strip_all_tags($this->_req_data['txn-filter-start-date'])
2430
+			: date(
2431
+				'm/d/Y',
2432
+				strtotime('-10 year')
2433
+			);
2434
+		$end_date = isset($this->_req_data['txn-filter-end-date'])
2435
+			? wp_strip_all_tags($this->_req_data['txn-filter-end-date'])
2436
+			: date('m/d/Y');
2437
+
2438
+		// make sure our timestamps start and end right at the boundaries for each day
2439
+		$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2440
+		$end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2441
+
2442
+
2443
+		// convert to timestamps
2444
+		$start_date = strtotime($start_date);
2445
+		$end_date = strtotime($end_date);
2446
+
2447
+		// makes sure start date is the lowest value and vice versa
2448
+		$start_date = min($start_date, $end_date);
2449
+		$end_date = max($start_date, $end_date);
2450
+
2451
+		// convert to correct format for query
2452
+		$start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2453
+			'TXN_timestamp',
2454
+			date('Y-m-d H:i:s', $start_date),
2455
+			'Y-m-d H:i:s'
2456
+		);
2457
+		$end_date = EEM_Transaction::instance()->convert_datetime_for_query(
2458
+			'TXN_timestamp',
2459
+			date('Y-m-d H:i:s', $end_date),
2460
+			'Y-m-d H:i:s'
2461
+		);
2462
+
2463
+
2464
+		// set orderby
2465
+		$this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
2466
+
2467
+		switch ($this->_req_data['orderby']) {
2468
+			case 'TXN_ID':
2469
+				$orderby = 'TXN_ID';
2470
+				break;
2471
+			case 'ATT_fname':
2472
+				$orderby = 'Registration.Attendee.ATT_fname';
2473
+				break;
2474
+			case 'event_name':
2475
+				$orderby = 'Registration.Event.EVT_name';
2476
+				break;
2477
+			default: // 'TXN_timestamp'
2478
+				$orderby = 'TXN_timestamp';
2479
+		}
2480
+
2481
+		$sort = ! empty($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2482
+		$current_page = ! empty($this->_req_data['paged']) ? $this->_req_data['paged'] : 1;
2483
+		$per_page = ! empty($perpage) ? $perpage : 10;
2484
+		$per_page = ! empty($this->_req_data['perpage']) ? $this->_req_data['perpage'] : $per_page;
2485
+
2486
+		$offset = ($current_page - 1) * $per_page;
2487
+		$limit = array($offset, $per_page);
2488
+
2489
+		$_where = array(
2490
+			'TXN_timestamp'          => array('BETWEEN', array($start_date, $end_date)),
2491
+			'Registration.REG_count' => 1,
2492
+		);
2493
+
2494
+		if (isset($this->_req_data['EVT_ID'])) {
2495
+			$_where['Registration.EVT_ID'] = $this->_req_data['EVT_ID'];
2496
+		}
2497
+
2498
+		if (isset($this->_req_data['s'])) {
2499
+			$search_string = '%' . $this->_req_data['s'] . '%';
2500
+			$_where['OR'] = array(
2501
+				'Registration.Event.EVT_name'         => array('LIKE', $search_string),
2502
+				'Registration.Event.EVT_desc'         => array('LIKE', $search_string),
2503
+				'Registration.Event.EVT_short_desc'   => array('LIKE', $search_string),
2504
+				'Registration.Attendee.ATT_full_name' => array('LIKE', $search_string),
2505
+				'Registration.Attendee.ATT_fname'     => array('LIKE', $search_string),
2506
+				'Registration.Attendee.ATT_lname'     => array('LIKE', $search_string),
2507
+				'Registration.Attendee.ATT_short_bio' => array('LIKE', $search_string),
2508
+				'Registration.Attendee.ATT_email'     => array('LIKE', $search_string),
2509
+				'Registration.Attendee.ATT_address'   => array('LIKE', $search_string),
2510
+				'Registration.Attendee.ATT_address2'  => array('LIKE', $search_string),
2511
+				'Registration.Attendee.ATT_city'      => array('LIKE', $search_string),
2512
+				'Registration.REG_final_price'        => array('LIKE', $search_string),
2513
+				'Registration.REG_code'               => array('LIKE', $search_string),
2514
+				'Registration.REG_count'              => array('LIKE', $search_string),
2515
+				'Registration.REG_group_size'         => array('LIKE', $search_string),
2516
+				'Registration.Ticket.TKT_name'        => array('LIKE', $search_string),
2517
+				'Registration.Ticket.TKT_description' => array('LIKE', $search_string),
2518
+				'Payment.PAY_source'                  => array('LIKE', $search_string),
2519
+				'Payment.Payment_Method.PMD_name'     => array('LIKE', $search_string),
2520
+				'TXN_session_data'                    => array('LIKE', $search_string),
2521
+				'Payment.PAY_txn_id_chq_nmbr'         => array('LIKE', $search_string),
2522
+			);
2523
+		}
2524
+
2525
+		// failed transactions
2526
+		$failed = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'failed' && ! $count)
2527
+				  || ($count && $view === 'failed');
2528
+		$abandoned = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'abandoned' && ! $count)
2529
+					 || ($count && $view === 'abandoned');
2530
+		$incomplete = (! empty($this->_req_data['status']) && $this->_req_data['status'] === 'incomplete' && ! $count)
2531
+					  || ($count && $view === 'incomplete');
2532
+
2533
+		if ($failed) {
2534
+			$_where['STS_ID'] = EEM_Transaction::failed_status_code;
2535
+		} elseif ($abandoned) {
2536
+			$_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2537
+		} elseif ($incomplete) {
2538
+			$_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2539
+		} else {
2540
+			$_where['STS_ID'] = array('!=', EEM_Transaction::failed_status_code);
2541
+			$_where['STS_ID*'] = array('!=', EEM_Transaction::abandoned_status_code);
2542
+		}
2543
+
2544
+		$query_params = apply_filters(
2545
+			'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2546
+			array(
2547
+				$_where,
2548
+				'order_by'                 => array($orderby => $sort),
2549
+				'limit'                    => $limit,
2550
+				'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2551
+			),
2552
+			$this->_req_data,
2553
+			$view,
2554
+			$count
2555
+		);
2556
+
2557
+		$transactions = $count
2558
+			? $TXN->count(array($query_params[0]), 'TXN_ID', true)
2559
+			: $TXN->get_all($query_params);
2560
+
2561
+		return $transactions;
2562
+	}
2563
+
2564
+
2565
+	/**
2566
+	 * @since 4.9.79.p
2567
+	 * @throws EE_Error
2568
+	 * @throws InvalidArgumentException
2569
+	 * @throws InvalidDataTypeException
2570
+	 * @throws InvalidInterfaceException
2571
+	 * @throws ReflectionException
2572
+	 * @throws RuntimeException
2573
+	 */
2574
+	public function recalculateLineItems()
2575
+	{
2576
+		$TXN_ID = ! empty($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : false;
2577
+		/** @var EE_Transaction $transaction */
2578
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2579
+		$total_line_item = $transaction->total_line_item(false);
2580
+		$success = $transaction->recalculateLineItems();
2581
+		$this->_redirect_after_action(
2582
+			(bool) $success,
2583
+			esc_html__('Transaction taxes and totals', 'event_espresso'),
2584
+			esc_html__('recalculated', 'event_espresso'),
2585
+			isset($this->_req_data['redirect_to'])
2586
+				? array(
2587
+				'action' => $this->_req_data['redirect_to'],
2588
+				'TXN_ID' => $this->_req_data['TXN_ID'],
2589
+			)
2590
+				: array(),
2591
+			true
2592
+		);
2593
+	}
2594 2594
 }
Please login to merge, or discard this patch.
registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php 2 patches
Indentation   +180 added lines, -180 removed lines patch added patch discarded remove patch
@@ -20,198 +20,198 @@
 block discarded – undo
20 20
  */
21 21
 class EE_Registration_Custom_Questions_Form extends EE_Form_Section_Proper
22 22
 {
23
-    /**
24
-     *
25
-     * @var EE_Registration
26
-     */
27
-    protected $_registration = null;
23
+	/**
24
+	 *
25
+	 * @var EE_Registration
26
+	 */
27
+	protected $_registration = null;
28 28
 
29 29
 
30
-    /**
31
-     *
32
-     * @param EE_Registration $reg
33
-     * @param array           $options
34
-     * @throws EE_Error
35
-     * @throws ReflectionException
36
-     */
37
-    public function __construct(EE_Registration $reg, $options = array())
38
-    {
39
-        $this->_registration = $reg;
40
-        if (! isset($options['layout_strategy'])) {
41
-            $options['layout_strategy'] = new EE_Admin_Two_Column_Layout();
42
-        }
43
-        if (! isset($options['html_id'])) {
44
-            $options['html_id'] = 'reg-admin-attendee-questions-frm';
45
-        }
46
-        $this->build_form_from_registration();
47
-        parent::__construct($options);
48
-    }
30
+	/**
31
+	 *
32
+	 * @param EE_Registration $reg
33
+	 * @param array           $options
34
+	 * @throws EE_Error
35
+	 * @throws ReflectionException
36
+	 */
37
+	public function __construct(EE_Registration $reg, $options = array())
38
+	{
39
+		$this->_registration = $reg;
40
+		if (! isset($options['layout_strategy'])) {
41
+			$options['layout_strategy'] = new EE_Admin_Two_Column_Layout();
42
+		}
43
+		if (! isset($options['html_id'])) {
44
+			$options['html_id'] = 'reg-admin-attendee-questions-frm';
45
+		}
46
+		$this->build_form_from_registration();
47
+		parent::__construct($options);
48
+	}
49 49
 
50 50
 
51
-    /**
52
-     * Gets the registration object this form is about
53
-     * @return EE_Registration
54
-     */
55
-    public function get_registration()
56
-    {
57
-        return $this->_registration;
58
-    }
51
+	/**
52
+	 * Gets the registration object this form is about
53
+	 * @return EE_Registration
54
+	 */
55
+	public function get_registration()
56
+	{
57
+		return $this->_registration;
58
+	}
59 59
 
60
-    /**
61
-     * @since 4.10.0.p
62
-     * @throws EE_Error
63
-     * @throws InvalidArgumentException
64
-     * @throws ReflectionException
65
-     * @throws InvalidDataTypeException
66
-     * @throws InvalidInterfaceException
67
-     */
68
-    public function build_form_from_registration()
69
-    {
70
-        $reg = $this->get_registration();
71
-        if (! $reg instanceof EE_Registration) {
72
-            throw new EE_Error(esc_html__('We cannot build the registration custom questions form because there is no registration set on it yet', 'event_espresso'));
73
-        }
74
-        // we want to get all their question groups
75
-        $question_groups = EEM_Question_Group::instance()->get_all(
76
-            [
77
-                [
78
-                    'Event_Question_Group.EVT_ID' => $reg->event_ID(),
79
-                    'OR' => [
80
-                        'Question.QST_system*blank' =>  '',
81
-                        'Question.QST_system*null' => ['IS_NULL']
82
-                    ],
83
-                    'Event_Question_Group.'
84
-                    . EEM_Event_Question_Group::instance()->fieldNameForContext(
85
-                        $reg->is_primary_registrant()
86
-                    ) => true
87
-                ],
88
-                'order_by' => ['QSG_order' => 'ASC']
89
-            ]
90
-        );
91
-        // get each question groups questions
92
-        foreach ($question_groups as $question_group) {
93
-            if ($question_group instanceof EE_Question_Group) {
94
-                $this->_subsections[ $question_group->ID() ] = $this->build_subform_from_question_group(
95
-                    $question_group,
96
-                    $reg
97
-                );
98
-            }
99
-        }
100
-    }
60
+	/**
61
+	 * @since 4.10.0.p
62
+	 * @throws EE_Error
63
+	 * @throws InvalidArgumentException
64
+	 * @throws ReflectionException
65
+	 * @throws InvalidDataTypeException
66
+	 * @throws InvalidInterfaceException
67
+	 */
68
+	public function build_form_from_registration()
69
+	{
70
+		$reg = $this->get_registration();
71
+		if (! $reg instanceof EE_Registration) {
72
+			throw new EE_Error(esc_html__('We cannot build the registration custom questions form because there is no registration set on it yet', 'event_espresso'));
73
+		}
74
+		// we want to get all their question groups
75
+		$question_groups = EEM_Question_Group::instance()->get_all(
76
+			[
77
+				[
78
+					'Event_Question_Group.EVT_ID' => $reg->event_ID(),
79
+					'OR' => [
80
+						'Question.QST_system*blank' =>  '',
81
+						'Question.QST_system*null' => ['IS_NULL']
82
+					],
83
+					'Event_Question_Group.'
84
+					. EEM_Event_Question_Group::instance()->fieldNameForContext(
85
+						$reg->is_primary_registrant()
86
+					) => true
87
+				],
88
+				'order_by' => ['QSG_order' => 'ASC']
89
+			]
90
+		);
91
+		// get each question groups questions
92
+		foreach ($question_groups as $question_group) {
93
+			if ($question_group instanceof EE_Question_Group) {
94
+				$this->_subsections[ $question_group->ID() ] = $this->build_subform_from_question_group(
95
+					$question_group,
96
+					$reg
97
+				);
98
+			}
99
+		}
100
+	}
101 101
 
102 102
 
103
-    /**
104
-     *
105
-     * @param EE_Question_Group $question_group
106
-     * @param EE_Registration   $registration
107
-     * @return EE_Form_Section_Proper
108
-     * @throws EE_Error
109
-     * @throws ReflectionException
110
-     */
111
-    public function build_subform_from_question_group($question_group, $registration)
112
-    {
113
-        if (
114
-            ! $question_group instanceof EE_Question_Group ||
115
-            ! $registration instanceof EE_Registration
116
-        ) {
117
-            throw new EE_Error(esc_html__('A valid question group and registration must be passed to EE_Registration_Custom_Question_Form', 'event_espresso'));
118
-        }
119
-        $parts_of_subsection = array(
120
-            'title' => new EE_Form_Section_HTML(
121
-                EEH_HTML::h5(
122
-                    $question_group->name(),
123
-                    $question_group->identifier(),
124
-                    'espresso-question-group-title-h5 section-title'
125
-                )
126
-            )
127
-        );
128
-        $questions = $question_group->questions(
129
-            array(
130
-                array(
131
-                    'OR' => array(
132
-                        'QST_system*blank' => '',
133
-                        'QST_system*null' => array( 'IS_NULL' )
134
-                    )
135
-                )
136
-            )
137
-        );
138
-        foreach ($questions as $question) {
139
-            $parts_of_subsection[ $question->ID() ] = $question->generate_form_input($registration);
140
-        }
141
-        if (
142
-            EE_Registry::instance()->CAP->current_user_can(
143
-                'ee_edit_registration',
144
-                'edit-reg-questions-mbox',
145
-                $this->_registration->ID()
146
-            )
147
-        ) {
148
-            $parts_of_subsection['edit_link'] = new EE_Form_Section_HTML(
149
-                EEH_HTML::table(
150
-                    EEH_HTML::tr(
151
-                        '<th/><td class="reg-admin-edit-attendee-question-td"><a class="reg-admin-edit-attendee-question-lnk" href="#" aria-label="' . esc_attr__('click to edit question', 'event_espresso') . '">
103
+	/**
104
+	 *
105
+	 * @param EE_Question_Group $question_group
106
+	 * @param EE_Registration   $registration
107
+	 * @return EE_Form_Section_Proper
108
+	 * @throws EE_Error
109
+	 * @throws ReflectionException
110
+	 */
111
+	public function build_subform_from_question_group($question_group, $registration)
112
+	{
113
+		if (
114
+			! $question_group instanceof EE_Question_Group ||
115
+			! $registration instanceof EE_Registration
116
+		) {
117
+			throw new EE_Error(esc_html__('A valid question group and registration must be passed to EE_Registration_Custom_Question_Form', 'event_espresso'));
118
+		}
119
+		$parts_of_subsection = array(
120
+			'title' => new EE_Form_Section_HTML(
121
+				EEH_HTML::h5(
122
+					$question_group->name(),
123
+					$question_group->identifier(),
124
+					'espresso-question-group-title-h5 section-title'
125
+				)
126
+			)
127
+		);
128
+		$questions = $question_group->questions(
129
+			array(
130
+				array(
131
+					'OR' => array(
132
+						'QST_system*blank' => '',
133
+						'QST_system*null' => array( 'IS_NULL' )
134
+					)
135
+				)
136
+			)
137
+		);
138
+		foreach ($questions as $question) {
139
+			$parts_of_subsection[ $question->ID() ] = $question->generate_form_input($registration);
140
+		}
141
+		if (
142
+			EE_Registry::instance()->CAP->current_user_can(
143
+				'ee_edit_registration',
144
+				'edit-reg-questions-mbox',
145
+				$this->_registration->ID()
146
+			)
147
+		) {
148
+			$parts_of_subsection['edit_link'] = new EE_Form_Section_HTML(
149
+				EEH_HTML::table(
150
+					EEH_HTML::tr(
151
+						'<th/><td class="reg-admin-edit-attendee-question-td"><a class="reg-admin-edit-attendee-question-lnk" href="#" aria-label="' . esc_attr__('click to edit question', 'event_espresso') . '">
152 152
 		  			<span class="reg-admin-edit-question-group-spn">' . esc_html__('edit the above question group', 'event_espresso') . '</span>
153 153
 		  			<div class="dashicons dashicons-edit"></div>
154 154
 		  		</a></td>'
155
-                    ) .
156
-                    EEH_HTML::no_row()
157
-                )
158
-            );
159
-        }
160
-        return new EE_Form_Section_Proper(
161
-            array(
162
-                'subsections' => $parts_of_subsection,
163
-                'html_class' => 'question-group-questions',
164
-            )
165
-        );
166
-    }
155
+					) .
156
+					EEH_HTML::no_row()
157
+				)
158
+			);
159
+		}
160
+		return new EE_Form_Section_Proper(
161
+			array(
162
+				'subsections' => $parts_of_subsection,
163
+				'html_class' => 'question-group-questions',
164
+			)
165
+		);
166
+	}
167 167
 
168 168
 
169
-    /**
170
-     * Overrides parent so if inputs were disabled, we leave those with their defaults
171
-     * from the answers in the DB
172
-     *
173
-     * @param array $req_data like $_POST
174
-     * @return void
175
-     * @throws EE_Error
176
-     */
177
-    protected function _normalize($req_data)
178
-    {
179
-        $this->_received_submission = true;
180
-        $this->_validation_errors = array();
181
-        foreach ($this->get_validatable_subsections() as $subsection) {
182
-            if ($subsection->form_data_present_in($req_data)) {
183
-                try {
184
-                    $subsection->_normalize($req_data);
185
-                } catch (EE_Validation_Error $e) {
186
-                    $subsection->add_validation_error($e);
187
-                }
188
-            }
189
-        }
190
-    }
169
+	/**
170
+	 * Overrides parent so if inputs were disabled, we leave those with their defaults
171
+	 * from the answers in the DB
172
+	 *
173
+	 * @param array $req_data like $_POST
174
+	 * @return void
175
+	 * @throws EE_Error
176
+	 */
177
+	protected function _normalize($req_data)
178
+	{
179
+		$this->_received_submission = true;
180
+		$this->_validation_errors = array();
181
+		foreach ($this->get_validatable_subsections() as $subsection) {
182
+			if ($subsection->form_data_present_in($req_data)) {
183
+				try {
184
+					$subsection->_normalize($req_data);
185
+				} catch (EE_Validation_Error $e) {
186
+					$subsection->add_validation_error($e);
187
+				}
188
+			}
189
+		}
190
+	}
191 191
 
192 192
 
193
-    /**
194
-     * Performs validation on this form section and its subsections. For each subsection,
195
-     * calls _validate_{subsection_name} on THIS form (if the function exists) and passes it the subsection, then calls
196
-     * _validate on that subsection. If you need to perform validation on the form as a whole (considering multiple)
197
-     * you would be best to override this _validate method, calling parent::_validate() first.
198
-     *
199
-     * @throws EE_Error
200
-     */
201
-    protected function _validate()
202
-    {
203
-        /** @var RequestInterface $request */
204
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
205
-        $form_data = $request->requestParams();
206
-        foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
207
-            if ($subsection->form_data_present_in($form_data)) {
208
-                if (method_exists($this, '_validate_' . $subsection_name)) {
209
-                    call_user_func_array(array($this,'_validate_' . $subsection_name), array($subsection));
210
-                }
211
-                $subsection->_validate();
212
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
213
-                $subsection->_received_submission = true;
214
-            }
215
-        }
216
-    }
193
+	/**
194
+	 * Performs validation on this form section and its subsections. For each subsection,
195
+	 * calls _validate_{subsection_name} on THIS form (if the function exists) and passes it the subsection, then calls
196
+	 * _validate on that subsection. If you need to perform validation on the form as a whole (considering multiple)
197
+	 * you would be best to override this _validate method, calling parent::_validate() first.
198
+	 *
199
+	 * @throws EE_Error
200
+	 */
201
+	protected function _validate()
202
+	{
203
+		/** @var RequestInterface $request */
204
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
205
+		$form_data = $request->requestParams();
206
+		foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
207
+			if ($subsection->form_data_present_in($form_data)) {
208
+				if (method_exists($this, '_validate_' . $subsection_name)) {
209
+					call_user_func_array(array($this,'_validate_' . $subsection_name), array($subsection));
210
+				}
211
+				$subsection->_validate();
212
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
213
+				$subsection->_received_submission = true;
214
+			}
215
+		}
216
+	}
217 217
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -37,10 +37,10 @@  discard block
 block discarded – undo
37 37
     public function __construct(EE_Registration $reg, $options = array())
38 38
     {
39 39
         $this->_registration = $reg;
40
-        if (! isset($options['layout_strategy'])) {
40
+        if ( ! isset($options['layout_strategy'])) {
41 41
             $options['layout_strategy'] = new EE_Admin_Two_Column_Layout();
42 42
         }
43
-        if (! isset($options['html_id'])) {
43
+        if ( ! isset($options['html_id'])) {
44 44
             $options['html_id'] = 'reg-admin-attendee-questions-frm';
45 45
         }
46 46
         $this->build_form_from_registration();
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
     public function build_form_from_registration()
69 69
     {
70 70
         $reg = $this->get_registration();
71
-        if (! $reg instanceof EE_Registration) {
71
+        if ( ! $reg instanceof EE_Registration) {
72 72
             throw new EE_Error(esc_html__('We cannot build the registration custom questions form because there is no registration set on it yet', 'event_espresso'));
73 73
         }
74 74
         // we want to get all their question groups
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
         // get each question groups questions
92 92
         foreach ($question_groups as $question_group) {
93 93
             if ($question_group instanceof EE_Question_Group) {
94
-                $this->_subsections[ $question_group->ID() ] = $this->build_subform_from_question_group(
94
+                $this->_subsections[$question_group->ID()] = $this->build_subform_from_question_group(
95 95
                     $question_group,
96 96
                     $reg
97 97
                 );
@@ -130,13 +130,13 @@  discard block
 block discarded – undo
130 130
                 array(
131 131
                     'OR' => array(
132 132
                         'QST_system*blank' => '',
133
-                        'QST_system*null' => array( 'IS_NULL' )
133
+                        'QST_system*null' => array('IS_NULL')
134 134
                     )
135 135
                 )
136 136
             )
137 137
         );
138 138
         foreach ($questions as $question) {
139
-            $parts_of_subsection[ $question->ID() ] = $question->generate_form_input($registration);
139
+            $parts_of_subsection[$question->ID()] = $question->generate_form_input($registration);
140 140
         }
141 141
         if (
142 142
             EE_Registry::instance()->CAP->current_user_can(
@@ -148,11 +148,11 @@  discard block
 block discarded – undo
148 148
             $parts_of_subsection['edit_link'] = new EE_Form_Section_HTML(
149 149
                 EEH_HTML::table(
150 150
                     EEH_HTML::tr(
151
-                        '<th/><td class="reg-admin-edit-attendee-question-td"><a class="reg-admin-edit-attendee-question-lnk" href="#" aria-label="' . esc_attr__('click to edit question', 'event_espresso') . '">
152
-		  			<span class="reg-admin-edit-question-group-spn">' . esc_html__('edit the above question group', 'event_espresso') . '</span>
151
+                        '<th/><td class="reg-admin-edit-attendee-question-td"><a class="reg-admin-edit-attendee-question-lnk" href="#" aria-label="'.esc_attr__('click to edit question', 'event_espresso').'">
152
+		  			<span class="reg-admin-edit-question-group-spn">' . esc_html__('edit the above question group', 'event_espresso').'</span>
153 153
 		  			<div class="dashicons dashicons-edit"></div>
154 154
 		  		</a></td>'
155
-                    ) .
155
+                    ).
156 156
                     EEH_HTML::no_row()
157 157
                 )
158 158
             );
@@ -205,8 +205,8 @@  discard block
 block discarded – undo
205 205
         $form_data = $request->requestParams();
206 206
         foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
207 207
             if ($subsection->form_data_present_in($form_data)) {
208
-                if (method_exists($this, '_validate_' . $subsection_name)) {
209
-                    call_user_func_array(array($this,'_validate_' . $subsection_name), array($subsection));
208
+                if (method_exists($this, '_validate_'.$subsection_name)) {
209
+                    call_user_func_array(array($this, '_validate_'.$subsection_name), array($subsection));
210 210
                 }
211 211
                 $subsection->_validate();
212 212
             } elseif ($subsection instanceof EE_Form_Section_Proper) {
Please login to merge, or discard this patch.
admin_pages/registrations/EE_Registrations_List_Table.class.php 2 patches
Indentation   +978 added lines, -978 removed lines patch added patch discarded remove patch
@@ -15,1058 +15,1058 @@
 block discarded – undo
15 15
 {
16 16
 
17 17
 
18
-    /**
19
-     * @var Registrations_Admin_Page
20
-     */
21
-    protected $_admin_page;
18
+	/**
19
+	 * @var Registrations_Admin_Page
20
+	 */
21
+	protected $_admin_page;
22 22
 
23
-    /**
24
-     * @var array
25
-     */
26
-    private $_status;
23
+	/**
24
+	 * @var array
25
+	 */
26
+	private $_status;
27 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 = [];
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 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 = [];
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 43
 
44 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
-    }
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 61
 
62 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
-    }
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 72
 
73 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
-        $ID_column_name      = esc_html__('ID', 'event_espresso');
87
-        $ID_column_name      .= ' : <span class="show-on-mobile-view-only" style="float:none">';
88
-        $ID_column_name      .= esc_html__('Registrant Name', 'event_espresso');
89
-        $ID_column_name      .= '</span> ';
90
-        $req_data = $this->_admin_page->get_request_data();
91
-        if (isset($req_data['event_id'])) {
92
-            $this->_columns        = [
93
-                'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
94
-                '_REG_ID'          => $ID_column_name,
95
-                'ATT_fname'        => esc_html__('Name', 'event_espresso'),
96
-                'ATT_email'        => esc_html__('Email', 'event_espresso'),
97
-                '_REG_date'        => esc_html__('Reg Date', 'event_espresso'),
98
-                'PRC_amount'       => esc_html__('TKT Price', 'event_espresso'),
99
-                '_REG_final_price' => esc_html__('Final Price', 'event_espresso'),
100
-                'TXN_total'        => esc_html__('Total Txn', 'event_espresso'),
101
-                'TXN_paid'         => esc_html__('Paid', 'event_espresso'),
102
-                'actions'          => esc_html__('Actions', 'event_espresso'),
103
-            ];
104
-            $this->_bottom_buttons = [
105
-                'report' => [
106
-                    'route'         => 'registrations_report',
107
-                    'extra_request' => [
108
-                        'EVT_ID'     => isset($this->_req_data['event_id'])
109
-                            ? $this->_req_data['event_id']
110
-                            : null,
111
-                        'return_url' => $return_url,
112
-                    ],
113
-                ],
114
-            ];
115
-        } else {
116
-            $this->_columns        = [
117
-                'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
118
-                '_REG_ID'          => $ID_column_name,
119
-                'ATT_fname'        => esc_html__('Name', 'event_espresso'),
120
-                '_REG_date'        => esc_html__('TXN Date', 'event_espresso'),
121
-                'event_name'       => esc_html__('Event', 'event_espresso'),
122
-                'DTT_EVT_start'    => esc_html__('Event Date', 'event_espresso'),
123
-                '_REG_final_price' => esc_html__('Price', 'event_espresso'),
124
-                '_REG_paid'        => esc_html__('Paid', 'event_espresso'),
125
-                'actions'          => esc_html__('Actions', 'event_espresso'),
126
-            ];
127
-            $this->_bottom_buttons = [
128
-                'report_all' => [
129
-                    'route'         => 'registrations_report',
130
-                    'extra_request' => [
131
-                        'return_url' => $return_url,
132
-                    ],
133
-                ],
134
-            ];
135
-        }
136
-        $this->_bottom_buttons['report_filtered'] = [
137
-            'route'         => 'registrations_report',
138
-            'extra_request' => [
139
-                'use_filters' => true,
140
-                'return_url'  => $return_url,
141
-            ],
142
-        ];
143
-        $filters                                  = array_diff_key(
144
-            $this->_req_data,
145
-            array_flip(
146
-                [
147
-                    'page',
148
-                    'action',
149
-                    'default_nonce',
150
-                ]
151
-            )
152
-        );
153
-        if (! empty($filters)) {
154
-            $this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters;
155
-        }
156
-        $this->_primary_column   = '_REG_ID';
157
-        $this->_sortable_columns = [
158
-            '_REG_date'     => ['_REG_date' => true],   // true means its already sorted
159
-            /**
160
-             * Allows users to change the default sort if they wish.
161
-             * Returning a falsey on this filter will result in the default sort to be by firstname rather than last
162
-             * name.
163
-             */
164
-            'ATT_fname'     => [
165
-                'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
166
-                true,
167
-                $this,
168
-            ]
169
-                ? ['ATT_lname' => false]
170
-                : ['ATT_fname' => false],
171
-            'event_name'    => ['event_name' => false],
172
-            'DTT_EVT_start' => ['DTT_EVT_start' => false],
173
-            '_REG_ID'       => ['_REG_ID' => false],
174
-        ];
175
-        $this->_hidden_columns   = [];
176
-    }
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
+		$ID_column_name      = esc_html__('ID', 'event_espresso');
87
+		$ID_column_name      .= ' : <span class="show-on-mobile-view-only" style="float:none">';
88
+		$ID_column_name      .= esc_html__('Registrant Name', 'event_espresso');
89
+		$ID_column_name      .= '</span> ';
90
+		$req_data = $this->_admin_page->get_request_data();
91
+		if (isset($req_data['event_id'])) {
92
+			$this->_columns        = [
93
+				'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
94
+				'_REG_ID'          => $ID_column_name,
95
+				'ATT_fname'        => esc_html__('Name', 'event_espresso'),
96
+				'ATT_email'        => esc_html__('Email', 'event_espresso'),
97
+				'_REG_date'        => esc_html__('Reg Date', 'event_espresso'),
98
+				'PRC_amount'       => esc_html__('TKT Price', 'event_espresso'),
99
+				'_REG_final_price' => esc_html__('Final Price', 'event_espresso'),
100
+				'TXN_total'        => esc_html__('Total Txn', 'event_espresso'),
101
+				'TXN_paid'         => esc_html__('Paid', 'event_espresso'),
102
+				'actions'          => esc_html__('Actions', 'event_espresso'),
103
+			];
104
+			$this->_bottom_buttons = [
105
+				'report' => [
106
+					'route'         => 'registrations_report',
107
+					'extra_request' => [
108
+						'EVT_ID'     => isset($this->_req_data['event_id'])
109
+							? $this->_req_data['event_id']
110
+							: null,
111
+						'return_url' => $return_url,
112
+					],
113
+				],
114
+			];
115
+		} else {
116
+			$this->_columns        = [
117
+				'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
118
+				'_REG_ID'          => $ID_column_name,
119
+				'ATT_fname'        => esc_html__('Name', 'event_espresso'),
120
+				'_REG_date'        => esc_html__('TXN Date', 'event_espresso'),
121
+				'event_name'       => esc_html__('Event', 'event_espresso'),
122
+				'DTT_EVT_start'    => esc_html__('Event Date', 'event_espresso'),
123
+				'_REG_final_price' => esc_html__('Price', 'event_espresso'),
124
+				'_REG_paid'        => esc_html__('Paid', 'event_espresso'),
125
+				'actions'          => esc_html__('Actions', 'event_espresso'),
126
+			];
127
+			$this->_bottom_buttons = [
128
+				'report_all' => [
129
+					'route'         => 'registrations_report',
130
+					'extra_request' => [
131
+						'return_url' => $return_url,
132
+					],
133
+				],
134
+			];
135
+		}
136
+		$this->_bottom_buttons['report_filtered'] = [
137
+			'route'         => 'registrations_report',
138
+			'extra_request' => [
139
+				'use_filters' => true,
140
+				'return_url'  => $return_url,
141
+			],
142
+		];
143
+		$filters                                  = array_diff_key(
144
+			$this->_req_data,
145
+			array_flip(
146
+				[
147
+					'page',
148
+					'action',
149
+					'default_nonce',
150
+				]
151
+			)
152
+		);
153
+		if (! empty($filters)) {
154
+			$this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters;
155
+		}
156
+		$this->_primary_column   = '_REG_ID';
157
+		$this->_sortable_columns = [
158
+			'_REG_date'     => ['_REG_date' => true],   // true means its already sorted
159
+			/**
160
+			 * Allows users to change the default sort if they wish.
161
+			 * Returning a falsey on this filter will result in the default sort to be by firstname rather than last
162
+			 * name.
163
+			 */
164
+			'ATT_fname'     => [
165
+				'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
166
+				true,
167
+				$this,
168
+			]
169
+				? ['ATT_lname' => false]
170
+				: ['ATT_fname' => false],
171
+			'event_name'    => ['event_name' => false],
172
+			'DTT_EVT_start' => ['DTT_EVT_start' => false],
173
+			'_REG_ID'       => ['_REG_ID' => false],
174
+		];
175
+		$this->_hidden_columns   = [];
176
+	}
177 177
 
178 178
 
179
-    /**
180
-     * This simply sets up the row class for the table rows.
181
-     * Allows for easier overriding of child methods for setting up sorting.
182
-     *
183
-     * @param EE_Registration $item the current item
184
-     * @return string
185
-     */
186
-    protected function _get_row_class($item)
187
-    {
188
-        $class = parent::_get_row_class($item);
189
-        // add status class
190
-        $class .= ' ee-status-strip reg-status-' . $item->status_ID();
191
-        if ($this->_has_checkbox_column) {
192
-            $class .= ' has-checkbox-column';
193
-        }
194
-        return $class;
195
-    }
179
+	/**
180
+	 * This simply sets up the row class for the table rows.
181
+	 * Allows for easier overriding of child methods for setting up sorting.
182
+	 *
183
+	 * @param EE_Registration $item the current item
184
+	 * @return string
185
+	 */
186
+	protected function _get_row_class($item)
187
+	{
188
+		$class = parent::_get_row_class($item);
189
+		// add status class
190
+		$class .= ' ee-status-strip reg-status-' . $item->status_ID();
191
+		if ($this->_has_checkbox_column) {
192
+			$class .= ' has-checkbox-column';
193
+		}
194
+		return $class;
195
+	}
196 196
 
197 197
 
198
-    /**
199
-     * Set the $_transaction_details property if not set yet.
200
-     *
201
-     * @param EE_Registration $registration
202
-     * @throws EE_Error
203
-     * @throws InvalidArgumentException
204
-     * @throws ReflectionException
205
-     * @throws InvalidDataTypeException
206
-     * @throws InvalidInterfaceException
207
-     */
208
-    protected function _set_related_details(EE_Registration $registration)
209
-    {
210
-        $transaction                = $registration->get_first_related('Transaction');
211
-        $status                     = $transaction instanceof EE_Transaction
212
-            ? $transaction->status_ID()
213
-            : EEM_Transaction::failed_status_code;
214
-        $this->_transaction_details = [
215
-            'transaction' => $transaction,
216
-            'status'      => $status,
217
-            'id'          => $transaction instanceof EE_Transaction
218
-                ? $transaction->ID()
219
-                : 0,
220
-            'title_attr'  => sprintf(
221
-                esc_html__('View Transaction Details (%s)', 'event_espresso'),
222
-                EEH_Template::pretty_status($status, false, 'sentence')
223
-            ),
224
-        ];
225
-        try {
226
-            $event = $registration->event();
227
-        } catch (EntityNotFoundException $e) {
228
-            $event = null;
229
-        }
230
-        $status               = $event instanceof EE_Event
231
-            ? $event->get_active_status()
232
-            : EE_Datetime::inactive;
233
-        $this->_event_details = [
234
-            'event'      => $event,
235
-            'status'     => $status,
236
-            'id'         => $event instanceof EE_Event
237
-                ? $event->ID()
238
-                : 0,
239
-            'title_attr' => sprintf(
240
-                esc_html__('Edit Event (%s)', 'event_espresso'),
241
-                EEH_Template::pretty_status($status, false, 'sentence')
242
-            ),
243
-        ];
244
-    }
198
+	/**
199
+	 * Set the $_transaction_details property if not set yet.
200
+	 *
201
+	 * @param EE_Registration $registration
202
+	 * @throws EE_Error
203
+	 * @throws InvalidArgumentException
204
+	 * @throws ReflectionException
205
+	 * @throws InvalidDataTypeException
206
+	 * @throws InvalidInterfaceException
207
+	 */
208
+	protected function _set_related_details(EE_Registration $registration)
209
+	{
210
+		$transaction                = $registration->get_first_related('Transaction');
211
+		$status                     = $transaction instanceof EE_Transaction
212
+			? $transaction->status_ID()
213
+			: EEM_Transaction::failed_status_code;
214
+		$this->_transaction_details = [
215
+			'transaction' => $transaction,
216
+			'status'      => $status,
217
+			'id'          => $transaction instanceof EE_Transaction
218
+				? $transaction->ID()
219
+				: 0,
220
+			'title_attr'  => sprintf(
221
+				esc_html__('View Transaction Details (%s)', 'event_espresso'),
222
+				EEH_Template::pretty_status($status, false, 'sentence')
223
+			),
224
+		];
225
+		try {
226
+			$event = $registration->event();
227
+		} catch (EntityNotFoundException $e) {
228
+			$event = null;
229
+		}
230
+		$status               = $event instanceof EE_Event
231
+			? $event->get_active_status()
232
+			: EE_Datetime::inactive;
233
+		$this->_event_details = [
234
+			'event'      => $event,
235
+			'status'     => $status,
236
+			'id'         => $event instanceof EE_Event
237
+				? $event->ID()
238
+				: 0,
239
+			'title_attr' => sprintf(
240
+				esc_html__('Edit Event (%s)', 'event_espresso'),
241
+				EEH_Template::pretty_status($status, false, 'sentence')
242
+			),
243
+		];
244
+	}
245 245
 
246 246
 
247
-    /**
248
-     *    _get_table_filters
249
-     *
250
-     * @return array
251
-     */
252
-    protected function _get_table_filters()
253
-    {
254
-        $filters = [];
255
-        // todo we're currently using old functions here. We need to move things into the Events_Admin_Page() class as
256
-        // methods.
257
-        $cur_date     = isset($this->_req_data['month_range'])
258
-            ? $this->_req_data['month_range']
259
-            : '';
260
-        $cur_category = isset($this->_req_data['EVT_CAT'])
261
-            ? $this->_req_data['EVT_CAT']
262
-            : -1;
263
-        $reg_status   = isset($this->_req_data['_reg_status'])
264
-            ? $this->_req_data['_reg_status']
265
-            : '';
266
-        $filters[]    = EEH_Form_Fields::generate_registration_months_dropdown($cur_date, $reg_status, $cur_category);
267
-        $filters[]    = EEH_Form_Fields::generate_event_category_dropdown($cur_category);
268
-        $status       = [];
269
-        $status[]     = ['id' => 0, 'text' => esc_html__('Select Status', 'event_espresso')];
270
-        foreach ($this->_status as $key => $value) {
271
-            $status[] = ['id' => $key, 'text' => $value];
272
-        }
273
-        if ($this->_view !== 'incomplete') {
274
-            $filters[] = EEH_Form_Fields::select_input(
275
-                '_reg_status',
276
-                $status,
277
-                isset($this->_req_data['_reg_status'])
278
-                    ? strtoupper(sanitize_key($this->_req_data['_reg_status']))
279
-                    : ''
280
-            );
281
-        }
282
-        if (isset($this->_req_data['event_id'])) {
283
-            $filters[] = EEH_Form_Fields::hidden_input('event_id', $this->_req_data['event_id'], 'reg_event_id');
284
-        }
285
-        return $filters;
286
-    }
247
+	/**
248
+	 *    _get_table_filters
249
+	 *
250
+	 * @return array
251
+	 */
252
+	protected function _get_table_filters()
253
+	{
254
+		$filters = [];
255
+		// todo we're currently using old functions here. We need to move things into the Events_Admin_Page() class as
256
+		// methods.
257
+		$cur_date     = isset($this->_req_data['month_range'])
258
+			? $this->_req_data['month_range']
259
+			: '';
260
+		$cur_category = isset($this->_req_data['EVT_CAT'])
261
+			? $this->_req_data['EVT_CAT']
262
+			: -1;
263
+		$reg_status   = isset($this->_req_data['_reg_status'])
264
+			? $this->_req_data['_reg_status']
265
+			: '';
266
+		$filters[]    = EEH_Form_Fields::generate_registration_months_dropdown($cur_date, $reg_status, $cur_category);
267
+		$filters[]    = EEH_Form_Fields::generate_event_category_dropdown($cur_category);
268
+		$status       = [];
269
+		$status[]     = ['id' => 0, 'text' => esc_html__('Select Status', 'event_espresso')];
270
+		foreach ($this->_status as $key => $value) {
271
+			$status[] = ['id' => $key, 'text' => $value];
272
+		}
273
+		if ($this->_view !== 'incomplete') {
274
+			$filters[] = EEH_Form_Fields::select_input(
275
+				'_reg_status',
276
+				$status,
277
+				isset($this->_req_data['_reg_status'])
278
+					? strtoupper(sanitize_key($this->_req_data['_reg_status']))
279
+					: ''
280
+			);
281
+		}
282
+		if (isset($this->_req_data['event_id'])) {
283
+			$filters[] = EEH_Form_Fields::hidden_input('event_id', $this->_req_data['event_id'], 'reg_event_id');
284
+		}
285
+		return $filters;
286
+	}
287 287
 
288 288
 
289
-    /**
290
-     * @return void
291
-     * @throws EE_Error
292
-     * @throws InvalidArgumentException
293
-     * @throws InvalidDataTypeException
294
-     * @throws InvalidInterfaceException
295
-     */
296
-    protected function _add_view_counts()
297
-    {
298
-        $this->_views['all']['count']   = $this->_total_registrations();
299
-        $this->_views['month']['count'] = $this->_total_registrations_this_month();
300
-        $this->_views['today']['count'] = $this->_total_registrations_today();
301
-        if (
302
-            EE_Registry::instance()->CAP->current_user_can(
303
-                'ee_delete_registrations',
304
-                'espresso_registrations_trash_registrations'
305
-            )
306
-        ) {
307
-            $this->_views['incomplete']['count'] = $this->_total_registrations('incomplete');
308
-            $this->_views['trash']['count']      = $this->_total_registrations('trash');
309
-        }
310
-    }
289
+	/**
290
+	 * @return void
291
+	 * @throws EE_Error
292
+	 * @throws InvalidArgumentException
293
+	 * @throws InvalidDataTypeException
294
+	 * @throws InvalidInterfaceException
295
+	 */
296
+	protected function _add_view_counts()
297
+	{
298
+		$this->_views['all']['count']   = $this->_total_registrations();
299
+		$this->_views['month']['count'] = $this->_total_registrations_this_month();
300
+		$this->_views['today']['count'] = $this->_total_registrations_today();
301
+		if (
302
+			EE_Registry::instance()->CAP->current_user_can(
303
+				'ee_delete_registrations',
304
+				'espresso_registrations_trash_registrations'
305
+			)
306
+		) {
307
+			$this->_views['incomplete']['count'] = $this->_total_registrations('incomplete');
308
+			$this->_views['trash']['count']      = $this->_total_registrations('trash');
309
+		}
310
+	}
311 311
 
312 312
 
313
-    /**
314
-     * @param string $view
315
-     * @return int
316
-     * @throws EE_Error
317
-     * @throws InvalidArgumentException
318
-     * @throws InvalidDataTypeException
319
-     * @throws InvalidInterfaceException
320
-     */
321
-    protected function _total_registrations($view = '')
322
-    {
323
-        $_where = [];
324
-        $EVT_ID = isset($this->_req_data['event_id'])
325
-            ? absint($this->_req_data['event_id'])
326
-            : false;
327
-        if ($EVT_ID) {
328
-            $_where['EVT_ID'] = $EVT_ID;
329
-        }
330
-        switch ($view) {
331
-            case 'trash':
332
-                return EEM_Registration::instance()->count_deleted([$_where]);
333
-            case 'incomplete':
334
-                $_where['STS_ID'] = EEM_Registration::status_id_incomplete;
335
-                break;
336
-            default:
337
-                $_where['STS_ID'] = ['!=', EEM_Registration::status_id_incomplete];
338
-        }
339
-        return EEM_Registration::instance()->count([$_where]);
340
-    }
313
+	/**
314
+	 * @param string $view
315
+	 * @return int
316
+	 * @throws EE_Error
317
+	 * @throws InvalidArgumentException
318
+	 * @throws InvalidDataTypeException
319
+	 * @throws InvalidInterfaceException
320
+	 */
321
+	protected function _total_registrations($view = '')
322
+	{
323
+		$_where = [];
324
+		$EVT_ID = isset($this->_req_data['event_id'])
325
+			? absint($this->_req_data['event_id'])
326
+			: false;
327
+		if ($EVT_ID) {
328
+			$_where['EVT_ID'] = $EVT_ID;
329
+		}
330
+		switch ($view) {
331
+			case 'trash':
332
+				return EEM_Registration::instance()->count_deleted([$_where]);
333
+			case 'incomplete':
334
+				$_where['STS_ID'] = EEM_Registration::status_id_incomplete;
335
+				break;
336
+			default:
337
+				$_where['STS_ID'] = ['!=', EEM_Registration::status_id_incomplete];
338
+		}
339
+		return EEM_Registration::instance()->count([$_where]);
340
+	}
341 341
 
342 342
 
343
-    /**
344
-     * @return int
345
-     * @throws EE_Error
346
-     * @throws InvalidArgumentException
347
-     * @throws InvalidDataTypeException
348
-     * @throws InvalidInterfaceException
349
-     */
350
-    protected function _total_registrations_this_month()
351
-    {
352
-        $EVT_ID          = isset($this->_req_data['event_id'])
353
-            ? absint($this->_req_data['event_id'])
354
-            : false;
355
-        $_where          = $EVT_ID
356
-            ? ['EVT_ID' => $EVT_ID]
357
-            : [];
358
-        $this_year_r     = date('Y', current_time('timestamp'));
359
-        $time_start      = ' 00:00:00';
360
-        $time_end        = ' 23:59:59';
361
-        $this_month_r    = date('m', current_time('timestamp'));
362
-        $days_this_month = date('t', current_time('timestamp'));
363
-        // setup date query.
364
-        $beginning_string   = EEM_Registration::instance()->convert_datetime_for_query(
365
-            'REG_date',
366
-            $this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start,
367
-            'Y-m-d H:i:s'
368
-        );
369
-        $end_string         = EEM_Registration::instance()->convert_datetime_for_query(
370
-            'REG_date',
371
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end,
372
-            'Y-m-d H:i:s'
373
-        );
374
-        $_where['REG_date'] = [
375
-            'BETWEEN',
376
-            [
377
-                $beginning_string,
378
-                $end_string,
379
-            ],
380
-        ];
381
-        $_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
382
-        return EEM_Registration::instance()->count([$_where]);
383
-    }
343
+	/**
344
+	 * @return int
345
+	 * @throws EE_Error
346
+	 * @throws InvalidArgumentException
347
+	 * @throws InvalidDataTypeException
348
+	 * @throws InvalidInterfaceException
349
+	 */
350
+	protected function _total_registrations_this_month()
351
+	{
352
+		$EVT_ID          = isset($this->_req_data['event_id'])
353
+			? absint($this->_req_data['event_id'])
354
+			: false;
355
+		$_where          = $EVT_ID
356
+			? ['EVT_ID' => $EVT_ID]
357
+			: [];
358
+		$this_year_r     = date('Y', current_time('timestamp'));
359
+		$time_start      = ' 00:00:00';
360
+		$time_end        = ' 23:59:59';
361
+		$this_month_r    = date('m', current_time('timestamp'));
362
+		$days_this_month = date('t', current_time('timestamp'));
363
+		// setup date query.
364
+		$beginning_string   = EEM_Registration::instance()->convert_datetime_for_query(
365
+			'REG_date',
366
+			$this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start,
367
+			'Y-m-d H:i:s'
368
+		);
369
+		$end_string         = EEM_Registration::instance()->convert_datetime_for_query(
370
+			'REG_date',
371
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end,
372
+			'Y-m-d H:i:s'
373
+		);
374
+		$_where['REG_date'] = [
375
+			'BETWEEN',
376
+			[
377
+				$beginning_string,
378
+				$end_string,
379
+			],
380
+		];
381
+		$_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
382
+		return EEM_Registration::instance()->count([$_where]);
383
+	}
384 384
 
385 385
 
386
-    /**
387
-     * @return int
388
-     * @throws EE_Error
389
-     * @throws InvalidArgumentException
390
-     * @throws InvalidDataTypeException
391
-     * @throws InvalidInterfaceException
392
-     */
393
-    protected function _total_registrations_today()
394
-    {
395
-        $EVT_ID             = isset($this->_req_data['event_id'])
396
-            ? absint($this->_req_data['event_id'])
397
-            : false;
398
-        $_where             = $EVT_ID
399
-            ? ['EVT_ID' => $EVT_ID]
400
-            : [];
401
-        $current_date       = date('Y-m-d', current_time('timestamp'));
402
-        $time_start         = ' 00:00:00';
403
-        $time_end           = ' 23:59:59';
404
-        $_where['REG_date'] = [
405
-            'BETWEEN',
406
-            [
407
-                EEM_Registration::instance()->convert_datetime_for_query(
408
-                    'REG_date',
409
-                    $current_date . $time_start,
410
-                    'Y-m-d H:i:s'
411
-                ),
412
-                EEM_Registration::instance()->convert_datetime_for_query(
413
-                    'REG_date',
414
-                    $current_date . $time_end,
415
-                    'Y-m-d H:i:s'
416
-                ),
417
-            ],
418
-        ];
419
-        $_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
420
-        return EEM_Registration::instance()->count([$_where]);
421
-    }
386
+	/**
387
+	 * @return int
388
+	 * @throws EE_Error
389
+	 * @throws InvalidArgumentException
390
+	 * @throws InvalidDataTypeException
391
+	 * @throws InvalidInterfaceException
392
+	 */
393
+	protected function _total_registrations_today()
394
+	{
395
+		$EVT_ID             = isset($this->_req_data['event_id'])
396
+			? absint($this->_req_data['event_id'])
397
+			: false;
398
+		$_where             = $EVT_ID
399
+			? ['EVT_ID' => $EVT_ID]
400
+			: [];
401
+		$current_date       = date('Y-m-d', current_time('timestamp'));
402
+		$time_start         = ' 00:00:00';
403
+		$time_end           = ' 23:59:59';
404
+		$_where['REG_date'] = [
405
+			'BETWEEN',
406
+			[
407
+				EEM_Registration::instance()->convert_datetime_for_query(
408
+					'REG_date',
409
+					$current_date . $time_start,
410
+					'Y-m-d H:i:s'
411
+				),
412
+				EEM_Registration::instance()->convert_datetime_for_query(
413
+					'REG_date',
414
+					$current_date . $time_end,
415
+					'Y-m-d H:i:s'
416
+				),
417
+			],
418
+		];
419
+		$_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
420
+		return EEM_Registration::instance()->count([$_where]);
421
+	}
422 422
 
423 423
 
424
-    /**
425
-     * @param EE_Registration $item
426
-     * @return string
427
-     * @throws EE_Error
428
-     * @throws InvalidArgumentException
429
-     * @throws InvalidDataTypeException
430
-     * @throws InvalidInterfaceException
431
-     * @throws ReflectionException
432
-     */
433
-    public function column_cb($item)
434
-    {
435
-        /** checkbox/lock **/
436
-        $transaction   = $item->get_first_related('Transaction');
437
-        $payment_count = $transaction instanceof EE_Transaction
438
-            ? $transaction->count_related('Payment')
439
-            : 0;
440
-        return $payment_count > 0
441
-               || ! EE_Registry::instance()->CAP->current_user_can(
442
-            'ee_edit_registration',
443
-            'registration_list_table_checkbox_input',
444
-            $item->ID()
445
-        )
446
-            ? sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID())
447
-              . '<span class="ee-lock-icon"></span>'
448
-            : sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID());
449
-    }
424
+	/**
425
+	 * @param EE_Registration $item
426
+	 * @return string
427
+	 * @throws EE_Error
428
+	 * @throws InvalidArgumentException
429
+	 * @throws InvalidDataTypeException
430
+	 * @throws InvalidInterfaceException
431
+	 * @throws ReflectionException
432
+	 */
433
+	public function column_cb($item)
434
+	{
435
+		/** checkbox/lock **/
436
+		$transaction   = $item->get_first_related('Transaction');
437
+		$payment_count = $transaction instanceof EE_Transaction
438
+			? $transaction->count_related('Payment')
439
+			: 0;
440
+		return $payment_count > 0
441
+			   || ! EE_Registry::instance()->CAP->current_user_can(
442
+			'ee_edit_registration',
443
+			'registration_list_table_checkbox_input',
444
+			$item->ID()
445
+		)
446
+			? sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID())
447
+			  . '<span class="ee-lock-icon"></span>'
448
+			: sprintf('<input type="checkbox" name="_REG_ID[]" value="%1$d" />', $item->ID());
449
+	}
450 450
 
451 451
 
452
-    /**
453
-     * @param EE_Registration $item
454
-     * @return string
455
-     * @throws EE_Error
456
-     * @throws InvalidArgumentException
457
-     * @throws InvalidDataTypeException
458
-     * @throws InvalidInterfaceException
459
-     * @throws ReflectionException
460
-     */
461
-    public function column__REG_ID(EE_Registration $item)
462
-    {
463
-        $attendee = $item->attendee();
464
-        $content  = $item->ID();
465
-        $content  .= '<div class="show-on-mobile-view-only">';
466
-        $content  .= '<br>';
467
-        $content  .= $attendee instanceof EE_Attendee
468
-            ? $attendee->full_name()
469
-            : '';
470
-        $content  .= '&nbsp;';
471
-        $content  .= sprintf(
472
-            esc_html__('(%1$s / %2$s)', 'event_espresso'),
473
-            $item->count(),
474
-            $item->group_size()
475
-        );
476
-        $content  .= '<br>';
477
-        $content  .= sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
478
-        $content  .= '</div>';
479
-        return $content;
480
-    }
452
+	/**
453
+	 * @param EE_Registration $item
454
+	 * @return string
455
+	 * @throws EE_Error
456
+	 * @throws InvalidArgumentException
457
+	 * @throws InvalidDataTypeException
458
+	 * @throws InvalidInterfaceException
459
+	 * @throws ReflectionException
460
+	 */
461
+	public function column__REG_ID(EE_Registration $item)
462
+	{
463
+		$attendee = $item->attendee();
464
+		$content  = $item->ID();
465
+		$content  .= '<div class="show-on-mobile-view-only">';
466
+		$content  .= '<br>';
467
+		$content  .= $attendee instanceof EE_Attendee
468
+			? $attendee->full_name()
469
+			: '';
470
+		$content  .= '&nbsp;';
471
+		$content  .= sprintf(
472
+			esc_html__('(%1$s / %2$s)', 'event_espresso'),
473
+			$item->count(),
474
+			$item->group_size()
475
+		);
476
+		$content  .= '<br>';
477
+		$content  .= sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
478
+		$content  .= '</div>';
479
+		return $content;
480
+	}
481 481
 
482 482
 
483
-    /**
484
-     * @param EE_Registration $item
485
-     * @return string
486
-     * @throws EE_Error
487
-     * @throws InvalidArgumentException
488
-     * @throws InvalidDataTypeException
489
-     * @throws InvalidInterfaceException
490
-     * @throws ReflectionException
491
-     */
492
-    public function column__REG_date(EE_Registration $item)
493
-    {
494
-        $this->_set_related_details($item);
495
-        // Build row actions
496
-        $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
497
-            [
498
-                'action' => 'view_transaction',
499
-                'TXN_ID' => $this->_transaction_details['id'],
500
-            ],
501
-            TXN_ADMIN_URL
502
-        );
503
-        $view_link    = EE_Registry::instance()->CAP->current_user_can(
504
-            'ee_read_transaction',
505
-            'espresso_transactions_view_transaction'
506
-        )
507
-            ? '<a class="ee-status-color-'
508
-              . $this->_transaction_details['status']
509
-              . '" href="'
510
-              . $view_lnk_url
511
-              . '" title="'
512
-              . esc_attr($this->_transaction_details['title_attr'])
513
-              . '">'
514
-              . $item->get_i18n_datetime('REG_date')
515
-              . '</a>'
516
-            : $item->get_i18n_datetime('REG_date');
517
-        $view_link    .= '<br><span class="ee-status-text-small">'
518
-                         . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence')
519
-                         . '</span>';
520
-        return $view_link;
521
-    }
483
+	/**
484
+	 * @param EE_Registration $item
485
+	 * @return string
486
+	 * @throws EE_Error
487
+	 * @throws InvalidArgumentException
488
+	 * @throws InvalidDataTypeException
489
+	 * @throws InvalidInterfaceException
490
+	 * @throws ReflectionException
491
+	 */
492
+	public function column__REG_date(EE_Registration $item)
493
+	{
494
+		$this->_set_related_details($item);
495
+		// Build row actions
496
+		$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
497
+			[
498
+				'action' => 'view_transaction',
499
+				'TXN_ID' => $this->_transaction_details['id'],
500
+			],
501
+			TXN_ADMIN_URL
502
+		);
503
+		$view_link    = EE_Registry::instance()->CAP->current_user_can(
504
+			'ee_read_transaction',
505
+			'espresso_transactions_view_transaction'
506
+		)
507
+			? '<a class="ee-status-color-'
508
+			  . $this->_transaction_details['status']
509
+			  . '" href="'
510
+			  . $view_lnk_url
511
+			  . '" title="'
512
+			  . esc_attr($this->_transaction_details['title_attr'])
513
+			  . '">'
514
+			  . $item->get_i18n_datetime('REG_date')
515
+			  . '</a>'
516
+			: $item->get_i18n_datetime('REG_date');
517
+		$view_link    .= '<br><span class="ee-status-text-small">'
518
+						 . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence')
519
+						 . '</span>';
520
+		return $view_link;
521
+	}
522 522
 
523 523
 
524
-    /**
525
-     * @param EE_Registration $item
526
-     * @return string
527
-     * @throws EE_Error
528
-     * @throws InvalidArgumentException
529
-     * @throws InvalidDataTypeException
530
-     * @throws InvalidInterfaceException
531
-     * @throws ReflectionException
532
-     */
533
-    public function column_event_name(EE_Registration $item)
534
-    {
535
-        $this->_set_related_details($item);
536
-        // page=espresso_events&action=edit_event&EVT_ID=2&edit_event_nonce=cf3a7e5b62
537
-        $EVT_ID     = $item->event_ID();
538
-        $event_name = $item->event_name();
539
-        $event_name = $event_name ?: esc_html__("No Associated Event", 'event_espresso');
540
-        $event_name = wp_trim_words($event_name, 30, '...');
541
-        if ($EVT_ID) {
542
-            $edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(
543
-                ['action' => 'edit', 'post' => $EVT_ID],
544
-                EVENTS_ADMIN_URL
545
-            );
546
-            $edit_event              =
547
-                EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID)
548
-                    ? '<a class="ee-status-color-'
549
-                      . $this->_event_details['status']
550
-                      . '" href="'
551
-                      . $edit_event_url
552
-                      . '" title="'
553
-                      . esc_attr($this->_event_details['title_attr'])
554
-                      . '">'
555
-                      . $event_name
556
-                      . '</a>'
557
-                    : $event_name;
558
-            $edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(['event_id' => $EVT_ID], REG_ADMIN_URL);
559
-            $actions['event_filter'] = '<a href="' . $edit_event_url . '" title="';
560
-            $actions['event_filter'] .= sprintf(
561
-                esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'),
562
-                $event_name
563
-            );
564
-            $actions['event_filter'] .= '">' . esc_html__('View Registrations', 'event_espresso') . '</a>';
565
-        } else {
566
-            $edit_event              = $event_name;
567
-            $actions['event_filter'] = '';
568
-        }
569
-        return sprintf('%1$s %2$s', $edit_event, $this->row_actions($actions));
570
-    }
524
+	/**
525
+	 * @param EE_Registration $item
526
+	 * @return string
527
+	 * @throws EE_Error
528
+	 * @throws InvalidArgumentException
529
+	 * @throws InvalidDataTypeException
530
+	 * @throws InvalidInterfaceException
531
+	 * @throws ReflectionException
532
+	 */
533
+	public function column_event_name(EE_Registration $item)
534
+	{
535
+		$this->_set_related_details($item);
536
+		// page=espresso_events&action=edit_event&EVT_ID=2&edit_event_nonce=cf3a7e5b62
537
+		$EVT_ID     = $item->event_ID();
538
+		$event_name = $item->event_name();
539
+		$event_name = $event_name ?: esc_html__("No Associated Event", 'event_espresso');
540
+		$event_name = wp_trim_words($event_name, 30, '...');
541
+		if ($EVT_ID) {
542
+			$edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(
543
+				['action' => 'edit', 'post' => $EVT_ID],
544
+				EVENTS_ADMIN_URL
545
+			);
546
+			$edit_event              =
547
+				EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID)
548
+					? '<a class="ee-status-color-'
549
+					  . $this->_event_details['status']
550
+					  . '" href="'
551
+					  . $edit_event_url
552
+					  . '" title="'
553
+					  . esc_attr($this->_event_details['title_attr'])
554
+					  . '">'
555
+					  . $event_name
556
+					  . '</a>'
557
+					: $event_name;
558
+			$edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(['event_id' => $EVT_ID], REG_ADMIN_URL);
559
+			$actions['event_filter'] = '<a href="' . $edit_event_url . '" title="';
560
+			$actions['event_filter'] .= sprintf(
561
+				esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'),
562
+				$event_name
563
+			);
564
+			$actions['event_filter'] .= '">' . esc_html__('View Registrations', 'event_espresso') . '</a>';
565
+		} else {
566
+			$edit_event              = $event_name;
567
+			$actions['event_filter'] = '';
568
+		}
569
+		return sprintf('%1$s %2$s', $edit_event, $this->row_actions($actions));
570
+	}
571 571
 
572 572
 
573
-    /**
574
-     * @param EE_Registration $item
575
-     * @return string
576
-     * @throws EE_Error
577
-     * @throws InvalidArgumentException
578
-     * @throws InvalidDataTypeException
579
-     * @throws InvalidInterfaceException
580
-     * @throws ReflectionException
581
-     */
582
-    public function column_DTT_EVT_start(EE_Registration $item)
583
-    {
584
-        $datetime_strings = [];
585
-        $ticket           = $item->ticket();
586
-        if ($ticket instanceof EE_Ticket) {
587
-            $remove_defaults = ['default_where_conditions' => 'none'];
588
-            $datetimes       = $ticket->datetimes($remove_defaults);
589
-            foreach ($datetimes as $datetime) {
590
-                $datetime_strings[] = $datetime->get_i18n_datetime('DTT_EVT_start');
591
-            }
592
-            return $this->generateDisplayForDatetimes($datetime_strings);
593
-        }
594
-        return esc_html__('There is no ticket on this registration', 'event_espresso');
595
-    }
573
+	/**
574
+	 * @param EE_Registration $item
575
+	 * @return string
576
+	 * @throws EE_Error
577
+	 * @throws InvalidArgumentException
578
+	 * @throws InvalidDataTypeException
579
+	 * @throws InvalidInterfaceException
580
+	 * @throws ReflectionException
581
+	 */
582
+	public function column_DTT_EVT_start(EE_Registration $item)
583
+	{
584
+		$datetime_strings = [];
585
+		$ticket           = $item->ticket();
586
+		if ($ticket instanceof EE_Ticket) {
587
+			$remove_defaults = ['default_where_conditions' => 'none'];
588
+			$datetimes       = $ticket->datetimes($remove_defaults);
589
+			foreach ($datetimes as $datetime) {
590
+				$datetime_strings[] = $datetime->get_i18n_datetime('DTT_EVT_start');
591
+			}
592
+			return $this->generateDisplayForDatetimes($datetime_strings);
593
+		}
594
+		return esc_html__('There is no ticket on this registration', 'event_espresso');
595
+	}
596 596
 
597 597
 
598
-    /**
599
-     * Receives an array of datetime strings to display and converts them to the html container for the column.
600
-     *
601
-     * @param array $datetime_strings
602
-     * @return string
603
-     */
604
-    public function generateDisplayForDateTimes(array $datetime_strings)
605
-    {
606
-        $content       = '<div class="ee-registration-event-datetimes-container">';
607
-        $expand_toggle = count($datetime_strings) > 1
608
-            ? ' <span title="' . esc_attr__('Click to view all dates', 'event_espresso')
609
-              . '" class="ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>'
610
-            : '';
611
-        // get first item for initial visibility
612
-        $content .= '<div class="left">' . array_shift($datetime_strings) . '</div>';
613
-        $content .= $expand_toggle;
614
-        if ($datetime_strings) {
615
-            $content .= '<div style="clear:both"></div>';
616
-            $content .= '<div class="ee-registration-event-datetimes-container more-items hidden">';
617
-            $content .= implode("<br />", $datetime_strings);
618
-            $content .= '</div>';
619
-        }
620
-        $content .= '</div>';
621
-        return $content;
622
-    }
598
+	/**
599
+	 * Receives an array of datetime strings to display and converts them to the html container for the column.
600
+	 *
601
+	 * @param array $datetime_strings
602
+	 * @return string
603
+	 */
604
+	public function generateDisplayForDateTimes(array $datetime_strings)
605
+	{
606
+		$content       = '<div class="ee-registration-event-datetimes-container">';
607
+		$expand_toggle = count($datetime_strings) > 1
608
+			? ' <span title="' . esc_attr__('Click to view all dates', 'event_espresso')
609
+			  . '" class="ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>'
610
+			: '';
611
+		// get first item for initial visibility
612
+		$content .= '<div class="left">' . array_shift($datetime_strings) . '</div>';
613
+		$content .= $expand_toggle;
614
+		if ($datetime_strings) {
615
+			$content .= '<div style="clear:both"></div>';
616
+			$content .= '<div class="ee-registration-event-datetimes-container more-items hidden">';
617
+			$content .= implode("<br />", $datetime_strings);
618
+			$content .= '</div>';
619
+		}
620
+		$content .= '</div>';
621
+		return $content;
622
+	}
623 623
 
624 624
 
625
-    /**
626
-     * @param EE_Registration $item
627
-     * @return string
628
-     * @throws EE_Error
629
-     * @throws InvalidArgumentException
630
-     * @throws InvalidDataTypeException
631
-     * @throws InvalidInterfaceException
632
-     * @throws ReflectionException
633
-     */
634
-    public function column_ATT_fname(EE_Registration $item)
635
-    {
636
-        $attendee      = $item->attendee();
637
-        $edit_lnk_url  = EE_Admin_Page::add_query_args_and_nonce(
638
-            [
639
-                'action'  => 'view_registration',
640
-                '_REG_ID' => $item->ID(),
641
-            ],
642
-            REG_ADMIN_URL
643
-        );
644
-        $attendee_name = $attendee instanceof EE_Attendee
645
-            ? $attendee->full_name()
646
-            : '';
647
-        $link          = EE_Registry::instance()->CAP->current_user_can(
648
-            'ee_read_registration',
649
-            'espresso_registrations_view_registration',
650
-            $item->ID()
651
-        )
652
-            ? '<a href="'
653
-              . $edit_lnk_url
654
-              . '" title="'
655
-              . esc_attr__('View Registration Details', 'event_espresso')
656
-              . '">'
657
-              . $attendee_name
658
-              . '</a>'
659
-            : $attendee_name;
660
-        $link          .= $item->count() === 1
661
-            ? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>'
662
-            : '';
663
-        $t             = $item->get_first_related('Transaction');
664
-        $payment_count = $t instanceof EE_Transaction
665
-            ? $t->count_related('Payment')
666
-            : 0;
667
-        // append group count to name
668
-        $link .= '&nbsp;' . sprintf(esc_html__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
669
-        // append reg_code
670
-        $link .= '<br>' . sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
671
-        // reg status text for accessibility
672
-        $link   .= '<br><span class="ee-status-text-small">'
673
-                   . EEH_Template::pretty_status($item->status_ID(), false, 'sentence')
674
-                   . '</span>';
675
-        $action = ['_REG_ID' => $item->ID()];
676
-        if (isset($this->_req_data['event_id'])) {
677
-            $action['event_id'] = $item->event_ID();
678
-        }
679
-        // trash/restore/delete actions
680
-        $actions = [];
681
-        if (
682
-            $this->_view !== 'trash'
683
-            && $payment_count === 0
684
-            && EE_Registry::instance()->CAP->current_user_can(
685
-                'ee_delete_registration',
686
-                'espresso_registrations_trash_registrations',
687
-                $item->ID()
688
-            )
689
-        ) {
690
-            $action['action'] = 'trash_registrations';
691
-            $trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
692
-                $action,
693
-                REG_ADMIN_URL
694
-            );
695
-            $actions['trash'] = '<a href="'
696
-                                . $trash_lnk_url
697
-                                . '" title="'
698
-                                . esc_attr__('Trash Registration', 'event_espresso')
699
-                                . '">' . esc_html__('Trash', 'event_espresso') . '</a>';
700
-        } elseif ($this->_view === 'trash') {
701
-            // restore registration link
702
-            if (
703
-            EE_Registry::instance()->CAP->current_user_can(
704
-                'ee_delete_registration',
705
-                'espresso_registrations_restore_registrations',
706
-                $item->ID()
707
-            )
708
-            ) {
709
-                $action['action']   = 'restore_registrations';
710
-                $restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
711
-                    $action,
712
-                    REG_ADMIN_URL
713
-                );
714
-                $actions['restore'] = '<a href="'
715
-                                      . $restore_lnk_url
716
-                                      . '" title="'
717
-                                      . esc_attr__('Restore Registration', 'event_espresso') . '">'
718
-                                      . esc_html__('Restore', 'event_espresso') . '</a>';
719
-            }
720
-            if (
721
-            EE_Registry::instance()->CAP->current_user_can(
722
-                'ee_delete_registration',
723
-                'espresso_registrations_ee_delete_registrations',
724
-                $item->ID()
725
-            )
726
-            ) {
727
-                $action['action']  = 'delete_registrations';
728
-                $delete_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
729
-                    $action,
730
-                    REG_ADMIN_URL
731
-                );
732
-                $actions['delete'] = '<a href="'
733
-                                     . $delete_lnk_url
734
-                                     . '" title="'
735
-                                     . esc_attr__('Delete Registration Permanently', 'event_espresso')
736
-                                     . '">'
737
-                                     . esc_html__('Delete', 'event_espresso')
738
-                                     . '</a>';
739
-            }
740
-        }
741
-        return sprintf('%1$s %2$s', $link, $this->row_actions($actions));
742
-    }
625
+	/**
626
+	 * @param EE_Registration $item
627
+	 * @return string
628
+	 * @throws EE_Error
629
+	 * @throws InvalidArgumentException
630
+	 * @throws InvalidDataTypeException
631
+	 * @throws InvalidInterfaceException
632
+	 * @throws ReflectionException
633
+	 */
634
+	public function column_ATT_fname(EE_Registration $item)
635
+	{
636
+		$attendee      = $item->attendee();
637
+		$edit_lnk_url  = EE_Admin_Page::add_query_args_and_nonce(
638
+			[
639
+				'action'  => 'view_registration',
640
+				'_REG_ID' => $item->ID(),
641
+			],
642
+			REG_ADMIN_URL
643
+		);
644
+		$attendee_name = $attendee instanceof EE_Attendee
645
+			? $attendee->full_name()
646
+			: '';
647
+		$link          = EE_Registry::instance()->CAP->current_user_can(
648
+			'ee_read_registration',
649
+			'espresso_registrations_view_registration',
650
+			$item->ID()
651
+		)
652
+			? '<a href="'
653
+			  . $edit_lnk_url
654
+			  . '" title="'
655
+			  . esc_attr__('View Registration Details', 'event_espresso')
656
+			  . '">'
657
+			  . $attendee_name
658
+			  . '</a>'
659
+			: $attendee_name;
660
+		$link          .= $item->count() === 1
661
+			? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>'
662
+			: '';
663
+		$t             = $item->get_first_related('Transaction');
664
+		$payment_count = $t instanceof EE_Transaction
665
+			? $t->count_related('Payment')
666
+			: 0;
667
+		// append group count to name
668
+		$link .= '&nbsp;' . sprintf(esc_html__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
669
+		// append reg_code
670
+		$link .= '<br>' . sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
671
+		// reg status text for accessibility
672
+		$link   .= '<br><span class="ee-status-text-small">'
673
+				   . EEH_Template::pretty_status($item->status_ID(), false, 'sentence')
674
+				   . '</span>';
675
+		$action = ['_REG_ID' => $item->ID()];
676
+		if (isset($this->_req_data['event_id'])) {
677
+			$action['event_id'] = $item->event_ID();
678
+		}
679
+		// trash/restore/delete actions
680
+		$actions = [];
681
+		if (
682
+			$this->_view !== 'trash'
683
+			&& $payment_count === 0
684
+			&& EE_Registry::instance()->CAP->current_user_can(
685
+				'ee_delete_registration',
686
+				'espresso_registrations_trash_registrations',
687
+				$item->ID()
688
+			)
689
+		) {
690
+			$action['action'] = 'trash_registrations';
691
+			$trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
692
+				$action,
693
+				REG_ADMIN_URL
694
+			);
695
+			$actions['trash'] = '<a href="'
696
+								. $trash_lnk_url
697
+								. '" title="'
698
+								. esc_attr__('Trash Registration', 'event_espresso')
699
+								. '">' . esc_html__('Trash', 'event_espresso') . '</a>';
700
+		} elseif ($this->_view === 'trash') {
701
+			// restore registration link
702
+			if (
703
+			EE_Registry::instance()->CAP->current_user_can(
704
+				'ee_delete_registration',
705
+				'espresso_registrations_restore_registrations',
706
+				$item->ID()
707
+			)
708
+			) {
709
+				$action['action']   = 'restore_registrations';
710
+				$restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
711
+					$action,
712
+					REG_ADMIN_URL
713
+				);
714
+				$actions['restore'] = '<a href="'
715
+									  . $restore_lnk_url
716
+									  . '" title="'
717
+									  . esc_attr__('Restore Registration', 'event_espresso') . '">'
718
+									  . esc_html__('Restore', 'event_espresso') . '</a>';
719
+			}
720
+			if (
721
+			EE_Registry::instance()->CAP->current_user_can(
722
+				'ee_delete_registration',
723
+				'espresso_registrations_ee_delete_registrations',
724
+				$item->ID()
725
+			)
726
+			) {
727
+				$action['action']  = 'delete_registrations';
728
+				$delete_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
729
+					$action,
730
+					REG_ADMIN_URL
731
+				);
732
+				$actions['delete'] = '<a href="'
733
+									 . $delete_lnk_url
734
+									 . '" title="'
735
+									 . esc_attr__('Delete Registration Permanently', 'event_espresso')
736
+									 . '">'
737
+									 . esc_html__('Delete', 'event_espresso')
738
+									 . '</a>';
739
+			}
740
+		}
741
+		return sprintf('%1$s %2$s', $link, $this->row_actions($actions));
742
+	}
743 743
 
744 744
 
745
-    /**
746
-     * @param EE_Registration $item
747
-     * @return string
748
-     * @throws EE_Error
749
-     * @throws InvalidArgumentException
750
-     * @throws InvalidDataTypeException
751
-     * @throws InvalidInterfaceException
752
-     * @throws ReflectionException
753
-     */
754
-    public function column_ATT_email(EE_Registration $item)
755
-    {
756
-        $attendee = $item->get_first_related('Attendee');
757
-        return ! $attendee instanceof EE_Attendee
758
-            ? esc_html__('No attached contact record.', 'event_espresso')
759
-            : $attendee->email();
760
-    }
745
+	/**
746
+	 * @param EE_Registration $item
747
+	 * @return string
748
+	 * @throws EE_Error
749
+	 * @throws InvalidArgumentException
750
+	 * @throws InvalidDataTypeException
751
+	 * @throws InvalidInterfaceException
752
+	 * @throws ReflectionException
753
+	 */
754
+	public function column_ATT_email(EE_Registration $item)
755
+	{
756
+		$attendee = $item->get_first_related('Attendee');
757
+		return ! $attendee instanceof EE_Attendee
758
+			? esc_html__('No attached contact record.', 'event_espresso')
759
+			: $attendee->email();
760
+	}
761 761
 
762 762
 
763
-    /**
764
-     * @param EE_Registration $item
765
-     * @return string
766
-     */
767
-    public function column__REG_count(EE_Registration $item)
768
-    {
769
-        return sprintf(esc_html__('%1$s / %2$s', 'event_espresso'), $item->count(), $item->group_size());
770
-    }
763
+	/**
764
+	 * @param EE_Registration $item
765
+	 * @return string
766
+	 */
767
+	public function column__REG_count(EE_Registration $item)
768
+	{
769
+		return sprintf(esc_html__('%1$s / %2$s', 'event_espresso'), $item->count(), $item->group_size());
770
+	}
771 771
 
772 772
 
773
-    /**
774
-     * @param EE_Registration $item
775
-     * @return string
776
-     * @throws EE_Error
777
-     * @throws ReflectionException
778
-     */
779
-    public function column_PRC_amount(EE_Registration $item)
780
-    {
781
-        $ticket  = $item->ticket();
782
-        $req_data = $this->_admin_page->get_request_data();
783
-        $content = isset($req_data['event_id']) && $ticket instanceof EE_Ticket
784
-            ? '<span class="TKT_name">' . $ticket->name() . '</span><br />'
785
-            : '';
786
-        if ($item->final_price() > 0) {
787
-            $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
788
-        } else {
789
-            // free event
790
-            $content .= '<span class="reg-overview-free-event-spn reg-pad-rght">'
791
-                        . esc_html__('free', 'event_espresso')
792
-                        . '</span>';
793
-        }
794
-        return $content;
795
-    }
773
+	/**
774
+	 * @param EE_Registration $item
775
+	 * @return string
776
+	 * @throws EE_Error
777
+	 * @throws ReflectionException
778
+	 */
779
+	public function column_PRC_amount(EE_Registration $item)
780
+	{
781
+		$ticket  = $item->ticket();
782
+		$req_data = $this->_admin_page->get_request_data();
783
+		$content = isset($req_data['event_id']) && $ticket instanceof EE_Ticket
784
+			? '<span class="TKT_name">' . $ticket->name() . '</span><br />'
785
+			: '';
786
+		if ($item->final_price() > 0) {
787
+			$content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
788
+		} else {
789
+			// free event
790
+			$content .= '<span class="reg-overview-free-event-spn reg-pad-rght">'
791
+						. esc_html__('free', 'event_espresso')
792
+						. '</span>';
793
+		}
794
+		return $content;
795
+	}
796 796
 
797 797
 
798
-    /**
799
-     * @param EE_Registration $item
800
-     * @return string
801
-     * @throws EE_Error
802
-     * @throws ReflectionException
803
-     */
804
-    public function column__REG_final_price(EE_Registration $item)
805
-    {
806
-        $ticket  = $item->ticket();
807
-        $req_data = $this->_admin_page->get_request_data();
808
-        $content = isset($req_data['event_id']) || ! $ticket instanceof EE_Ticket
809
-            ? ''
810
-            : '<span class="TKT_name">' . $ticket->name() . '</span><br />';
811
-        $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
812
-        return $content;
813
-    }
798
+	/**
799
+	 * @param EE_Registration $item
800
+	 * @return string
801
+	 * @throws EE_Error
802
+	 * @throws ReflectionException
803
+	 */
804
+	public function column__REG_final_price(EE_Registration $item)
805
+	{
806
+		$ticket  = $item->ticket();
807
+		$req_data = $this->_admin_page->get_request_data();
808
+		$content = isset($req_data['event_id']) || ! $ticket instanceof EE_Ticket
809
+			? ''
810
+			: '<span class="TKT_name">' . $ticket->name() . '</span><br />';
811
+		$content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
812
+		return $content;
813
+	}
814 814
 
815 815
 
816
-    /**
817
-     * @param EE_Registration $item
818
-     * @return string
819
-     * @throws EE_Error
820
-     */
821
-    public function column__REG_paid(EE_Registration $item)
822
-    {
823
-        $payment_method      = $item->payment_method();
824
-        $payment_method_name = $payment_method instanceof EE_Payment_Method
825
-            ? $payment_method->admin_name()
826
-            : esc_html__('Unknown', 'event_espresso');
827
-        $content             = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span>';
828
-        if ($item->paid() > 0) {
829
-            $content .= '<br><span class="ee-status-text-small">'
830
-                        . sprintf(
831
-                            esc_html__('...via %s', 'event_espresso'),
832
-                            $payment_method_name
833
-                        )
834
-                        . '</span>';
835
-        }
836
-        return $content;
837
-    }
816
+	/**
817
+	 * @param EE_Registration $item
818
+	 * @return string
819
+	 * @throws EE_Error
820
+	 */
821
+	public function column__REG_paid(EE_Registration $item)
822
+	{
823
+		$payment_method      = $item->payment_method();
824
+		$payment_method_name = $payment_method instanceof EE_Payment_Method
825
+			? $payment_method->admin_name()
826
+			: esc_html__('Unknown', 'event_espresso');
827
+		$content             = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span>';
828
+		if ($item->paid() > 0) {
829
+			$content .= '<br><span class="ee-status-text-small">'
830
+						. sprintf(
831
+							esc_html__('...via %s', 'event_espresso'),
832
+							$payment_method_name
833
+						)
834
+						. '</span>';
835
+		}
836
+		return $content;
837
+	}
838 838
 
839 839
 
840
-    /**
841
-     * @param EE_Registration $item
842
-     * @return string
843
-     * @throws EE_Error
844
-     * @throws EntityNotFoundException
845
-     * @throws InvalidArgumentException
846
-     * @throws InvalidDataTypeException
847
-     * @throws InvalidInterfaceException
848
-     * @throws ReflectionException
849
-     */
850
-    public function column_TXN_total(EE_Registration $item)
851
-    {
852
-        if ($item->transaction()) {
853
-            $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
854
-                [
855
-                    'action' => 'view_transaction',
856
-                    'TXN_ID' => $item->transaction_ID(),
857
-                ],
858
-                TXN_ADMIN_URL
859
-            );
860
-            return EE_Registry::instance()->CAP->current_user_can(
861
-                'ee_read_transaction',
862
-                'espresso_transactions_view_transaction',
863
-                $item->transaction_ID()
864
-            )
865
-                ? '<span class="reg-pad-rght"><a class="status-'
866
-                  . $item->transaction()->status_ID()
867
-                  . '" href="'
868
-                  . $view_txn_lnk_url
869
-                  . '"  title="'
870
-                  . esc_attr__('View Transaction', 'event_espresso')
871
-                  . '">'
872
-                  . $item->transaction()->pretty_total()
873
-                  . '</a></span>'
874
-                : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>';
875
-        } else {
876
-            return esc_html__("None", "event_espresso");
877
-        }
878
-    }
840
+	/**
841
+	 * @param EE_Registration $item
842
+	 * @return string
843
+	 * @throws EE_Error
844
+	 * @throws EntityNotFoundException
845
+	 * @throws InvalidArgumentException
846
+	 * @throws InvalidDataTypeException
847
+	 * @throws InvalidInterfaceException
848
+	 * @throws ReflectionException
849
+	 */
850
+	public function column_TXN_total(EE_Registration $item)
851
+	{
852
+		if ($item->transaction()) {
853
+			$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
854
+				[
855
+					'action' => 'view_transaction',
856
+					'TXN_ID' => $item->transaction_ID(),
857
+				],
858
+				TXN_ADMIN_URL
859
+			);
860
+			return EE_Registry::instance()->CAP->current_user_can(
861
+				'ee_read_transaction',
862
+				'espresso_transactions_view_transaction',
863
+				$item->transaction_ID()
864
+			)
865
+				? '<span class="reg-pad-rght"><a class="status-'
866
+				  . $item->transaction()->status_ID()
867
+				  . '" href="'
868
+				  . $view_txn_lnk_url
869
+				  . '"  title="'
870
+				  . esc_attr__('View Transaction', 'event_espresso')
871
+				  . '">'
872
+				  . $item->transaction()->pretty_total()
873
+				  . '</a></span>'
874
+				: '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>';
875
+		} else {
876
+			return esc_html__("None", "event_espresso");
877
+		}
878
+	}
879 879
 
880 880
 
881
-    /**
882
-     * @param EE_Registration $item
883
-     * @return string
884
-     * @throws EE_Error
885
-     * @throws EntityNotFoundException
886
-     * @throws InvalidArgumentException
887
-     * @throws InvalidDataTypeException
888
-     * @throws InvalidInterfaceException
889
-     * @throws ReflectionException
890
-     */
891
-    public function column_TXN_paid(EE_Registration $item)
892
-    {
893
-        if ($item->count() === 1) {
894
-            $transaction = $item->transaction()
895
-                ? $item->transaction()
896
-                : EE_Transaction::new_instance();
897
-            if ($transaction->paid() >= $transaction->total()) {
898
-                return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>';
899
-            } else {
900
-                $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
901
-                    [
902
-                        'action' => 'view_transaction',
903
-                        'TXN_ID' => $item->transaction_ID(),
904
-                    ],
905
-                    TXN_ADMIN_URL
906
-                );
907
-                return EE_Registry::instance()->CAP->current_user_can(
908
-                    'ee_read_transaction',
909
-                    'espresso_transactions_view_transaction',
910
-                    $item->transaction_ID()
911
-                )
912
-                    ? '<span class="reg-pad-rght"><a class="status-'
913
-                      . $transaction->status_ID()
914
-                      . '" href="'
915
-                      . $view_txn_lnk_url
916
-                      . '"  title="'
917
-                      . esc_attr__('View Transaction', 'event_espresso')
918
-                      . '">'
919
-                      . $item->transaction()->pretty_paid()
920
-                      . '</a><span>'
921
-                    : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
922
-            }
923
-        }
924
-        return '&nbsp;';
925
-    }
881
+	/**
882
+	 * @param EE_Registration $item
883
+	 * @return string
884
+	 * @throws EE_Error
885
+	 * @throws EntityNotFoundException
886
+	 * @throws InvalidArgumentException
887
+	 * @throws InvalidDataTypeException
888
+	 * @throws InvalidInterfaceException
889
+	 * @throws ReflectionException
890
+	 */
891
+	public function column_TXN_paid(EE_Registration $item)
892
+	{
893
+		if ($item->count() === 1) {
894
+			$transaction = $item->transaction()
895
+				? $item->transaction()
896
+				: EE_Transaction::new_instance();
897
+			if ($transaction->paid() >= $transaction->total()) {
898
+				return '<span class="reg-pad-rght"><div class="dashicons dashicons-yes green-icon"></div></span>';
899
+			} else {
900
+				$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
901
+					[
902
+						'action' => 'view_transaction',
903
+						'TXN_ID' => $item->transaction_ID(),
904
+					],
905
+					TXN_ADMIN_URL
906
+				);
907
+				return EE_Registry::instance()->CAP->current_user_can(
908
+					'ee_read_transaction',
909
+					'espresso_transactions_view_transaction',
910
+					$item->transaction_ID()
911
+				)
912
+					? '<span class="reg-pad-rght"><a class="status-'
913
+					  . $transaction->status_ID()
914
+					  . '" href="'
915
+					  . $view_txn_lnk_url
916
+					  . '"  title="'
917
+					  . esc_attr__('View Transaction', 'event_espresso')
918
+					  . '">'
919
+					  . $item->transaction()->pretty_paid()
920
+					  . '</a><span>'
921
+					: '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
922
+			}
923
+		}
924
+		return '&nbsp;';
925
+	}
926 926
 
927 927
 
928
-    /**
929
-     * column_actions
930
-     *
931
-     * @param EE_Registration $item
932
-     * @return string
933
-     * @throws EE_Error
934
-     * @throws InvalidArgumentException
935
-     * @throws InvalidDataTypeException
936
-     * @throws InvalidInterfaceException
937
-     * @throws ReflectionException
938
-     */
939
-    public function column_actions(EE_Registration $item)
940
-    {
941
-        $actions  = [];
942
-        $attendee = $item->attendee();
943
-        $this->_set_related_details($item);
944
-        // Build row actions
945
-        $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
946
-            [
947
-                'action'  => 'view_registration',
948
-                '_REG_ID' => $item->ID(),
949
-            ],
950
-            REG_ADMIN_URL
951
-        );
952
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
953
-            [
954
-                'action' => 'edit_attendee',
955
-                'post'   => $item->attendee_ID(),
956
-            ],
957
-            REG_ADMIN_URL
958
-        );
959
-        // page=attendees&event_admin_reports=resend_email&registration_id=43653465634&event_id=2&form_action=resend_email
960
-        // $resend_reg_lnk_url_params = array( 'action'=>'resend_registration', '_REG_ID'=>$item->REG_ID );
961
-        $resend_reg_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
962
-            [
963
-                'action'  => 'resend_registration',
964
-                '_REG_ID' => $item->ID(),
965
-            ],
966
-            REG_ADMIN_URL,
967
-            true
968
-        );
969
-        // Build row actions
970
-        $actions['view_lnk']       = EE_Registry::instance()->CAP->current_user_can(
971
-            'ee_read_registration',
972
-            'espresso_registrations_view_registration',
973
-            $item->ID()
974
-        )
975
-            ? '<li><a href="'
976
-              . $view_lnk_url
977
-              . '" title="'
978
-              . esc_attr__('View Registration Details', 'event_espresso')
979
-              . '" class="tiny-text">
928
+	/**
929
+	 * column_actions
930
+	 *
931
+	 * @param EE_Registration $item
932
+	 * @return string
933
+	 * @throws EE_Error
934
+	 * @throws InvalidArgumentException
935
+	 * @throws InvalidDataTypeException
936
+	 * @throws InvalidInterfaceException
937
+	 * @throws ReflectionException
938
+	 */
939
+	public function column_actions(EE_Registration $item)
940
+	{
941
+		$actions  = [];
942
+		$attendee = $item->attendee();
943
+		$this->_set_related_details($item);
944
+		// Build row actions
945
+		$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
946
+			[
947
+				'action'  => 'view_registration',
948
+				'_REG_ID' => $item->ID(),
949
+			],
950
+			REG_ADMIN_URL
951
+		);
952
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
953
+			[
954
+				'action' => 'edit_attendee',
955
+				'post'   => $item->attendee_ID(),
956
+			],
957
+			REG_ADMIN_URL
958
+		);
959
+		// page=attendees&event_admin_reports=resend_email&registration_id=43653465634&event_id=2&form_action=resend_email
960
+		// $resend_reg_lnk_url_params = array( 'action'=>'resend_registration', '_REG_ID'=>$item->REG_ID );
961
+		$resend_reg_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
962
+			[
963
+				'action'  => 'resend_registration',
964
+				'_REG_ID' => $item->ID(),
965
+			],
966
+			REG_ADMIN_URL,
967
+			true
968
+		);
969
+		// Build row actions
970
+		$actions['view_lnk']       = EE_Registry::instance()->CAP->current_user_can(
971
+			'ee_read_registration',
972
+			'espresso_registrations_view_registration',
973
+			$item->ID()
974
+		)
975
+			? '<li><a href="'
976
+			  . $view_lnk_url
977
+			  . '" title="'
978
+			  . esc_attr__('View Registration Details', 'event_espresso')
979
+			  . '" class="tiny-text">
980 980
 				<div class="dashicons dashicons-clipboard"></div>
981 981
 			</a>
982 982
 			</li>'
983
-            : '';
984
-        $actions['edit_lnk']       = EE_Registry::instance()->CAP->current_user_can(
985
-            'ee_edit_contacts',
986
-            'espresso_registrations_edit_attendee'
987
-        )
988
-                                     && $attendee instanceof EE_Attendee
989
-            ? '
983
+			: '';
984
+		$actions['edit_lnk']       = EE_Registry::instance()->CAP->current_user_can(
985
+			'ee_edit_contacts',
986
+			'espresso_registrations_edit_attendee'
987
+		)
988
+									 && $attendee instanceof EE_Attendee
989
+			? '
990 990
 			<li>
991 991
 			<a href="' . $edit_lnk_url . '" title="'
992
-              . esc_attr__('Edit Contact Details', 'event_espresso') . '" class="tiny-text">
992
+			  . esc_attr__('Edit Contact Details', 'event_espresso') . '" class="tiny-text">
993 993
 				<div class="ee-icon ee-icon-user-edit ee-icon-size-16"></div>
994 994
 			</a>
995 995
 			</li>'
996
-            : '';
997
-        $actions['resend_reg_lnk'] = $attendee instanceof EE_Attendee
998
-                                     && EE_Registry::instance()->CAP->current_user_can(
999
-            'ee_send_message',
1000
-            'espresso_registrations_resend_registration',
1001
-            $item->ID()
1002
-        )
1003
-            ? '
996
+			: '';
997
+		$actions['resend_reg_lnk'] = $attendee instanceof EE_Attendee
998
+									 && EE_Registry::instance()->CAP->current_user_can(
999
+			'ee_send_message',
1000
+			'espresso_registrations_resend_registration',
1001
+			$item->ID()
1002
+		)
1003
+			? '
1004 1004
 			<li>
1005 1005
 			<a href="'
1006
-              . $resend_reg_lnk_url
1007
-              . '" title="'
1008
-              . esc_attr__('Resend Registration Details', 'event_espresso')
1009
-              . '" class="tiny-text">
1006
+			  . $resend_reg_lnk_url
1007
+			  . '" title="'
1008
+			  . esc_attr__('Resend Registration Details', 'event_espresso')
1009
+			  . '" class="tiny-text">
1010 1010
 				<div class="dashicons dashicons-email-alt"></div>
1011 1011
 			</a>
1012 1012
 			</li>'
1013
-            : '';
1014
-        // page=transactions&action=view_transaction&txn=256&_wpnonce=6414da4dbb
1015
-        $view_txn_lnk_url        = EE_Admin_Page::add_query_args_and_nonce(
1016
-            [
1017
-                'action' => 'view_transaction',
1018
-                'TXN_ID' => $this->_transaction_details['id'],
1019
-            ],
1020
-            TXN_ADMIN_URL
1021
-        );
1022
-        $actions['view_txn_lnk'] = EE_Registry::instance()->CAP->current_user_can(
1023
-            'ee_read_transaction',
1024
-            'espresso_transactions_view_transaction',
1025
-            $this->_transaction_details['id']
1026
-        )
1027
-            ? '
1013
+			: '';
1014
+		// page=transactions&action=view_transaction&txn=256&_wpnonce=6414da4dbb
1015
+		$view_txn_lnk_url        = EE_Admin_Page::add_query_args_and_nonce(
1016
+			[
1017
+				'action' => 'view_transaction',
1018
+				'TXN_ID' => $this->_transaction_details['id'],
1019
+			],
1020
+			TXN_ADMIN_URL
1021
+		);
1022
+		$actions['view_txn_lnk'] = EE_Registry::instance()->CAP->current_user_can(
1023
+			'ee_read_transaction',
1024
+			'espresso_transactions_view_transaction',
1025
+			$this->_transaction_details['id']
1026
+		)
1027
+			? '
1028 1028
 			<li>
1029 1029
 			<a class="ee-status-color-'
1030
-              . $this->_transaction_details['status']
1031
-              . ' tiny-text" href="'
1032
-              . $view_txn_lnk_url
1033
-              . '"  title="'
1034
-              . $this->_transaction_details['title_attr']
1035
-              . '">
1030
+			  . $this->_transaction_details['status']
1031
+			  . ' tiny-text" href="'
1032
+			  . $view_txn_lnk_url
1033
+			  . '"  title="'
1034
+			  . $this->_transaction_details['title_attr']
1035
+			  . '">
1036 1036
 				<div class="dashicons dashicons-cart"></div>
1037 1037
 			</a>
1038 1038
 			</li>'
1039
-            : '';
1040
-        // invoice link
1041
-        $actions['dl_invoice_lnk'] = '';
1042
-        $dl_invoice_lnk_url        = $item->invoice_url();
1043
-        // only show invoice link if message type is active.
1044
-        if (
1045
-            $attendee instanceof EE_Attendee
1046
-            && $item->is_primary_registrant()
1047
-            && EEH_MSG_Template::is_mt_active('invoice')
1048
-        ) {
1049
-            $actions['dl_invoice_lnk'] = '
1039
+			: '';
1040
+		// invoice link
1041
+		$actions['dl_invoice_lnk'] = '';
1042
+		$dl_invoice_lnk_url        = $item->invoice_url();
1043
+		// only show invoice link if message type is active.
1044
+		if (
1045
+			$attendee instanceof EE_Attendee
1046
+			&& $item->is_primary_registrant()
1047
+			&& EEH_MSG_Template::is_mt_active('invoice')
1048
+		) {
1049
+			$actions['dl_invoice_lnk'] = '
1050 1050
 		<li>
1051 1051
 			<a title="' . esc_attr__('View Transaction Invoice', 'event_espresso')
1052
-                 . '" target="_blank" href="'
1053
-                 . $dl_invoice_lnk_url
1054
-                 . '" class="tiny-text">
1052
+				 . '" target="_blank" href="'
1053
+				 . $dl_invoice_lnk_url
1054
+				 . '" class="tiny-text">
1055 1055
 				<span class="dashicons dashicons-media-spreadsheet ee-icon-size-18"></span>
1056 1056
 			</a>
1057 1057
 		</li>';
1058
-        }
1059
-        $actions['filtered_messages_link'] = '';
1060
-        // message list table link (filtered by REG_ID
1061
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
1062
-            $actions['filtered_messages_link'] = '<li>'
1063
-                                                 . EEH_MSG_Template::get_message_action_link(
1064
-                    'see_notifications_for',
1065
-                    null,
1066
-                    ['_REG_ID' => $item->ID()]
1067
-                ) . '</li>';
1068
-        }
1069
-        $actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this);
1070
-        return $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul');
1071
-    }
1058
+		}
1059
+		$actions['filtered_messages_link'] = '';
1060
+		// message list table link (filtered by REG_ID
1061
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
1062
+			$actions['filtered_messages_link'] = '<li>'
1063
+												 . EEH_MSG_Template::get_message_action_link(
1064
+					'see_notifications_for',
1065
+					null,
1066
+					['_REG_ID' => $item->ID()]
1067
+				) . '</li>';
1068
+		}
1069
+		$actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this);
1070
+		return $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul');
1071
+	}
1072 1072
 }
Please login to merge, or discard this patch.
Spacing   +46 added lines, -46 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,13 +83,13 @@  discard block
 block discarded – undo
83 83
             'ajax'     => true,
84 84
             'screen'   => $this->_admin_page->get_current_screen()->id,
85 85
         ];
86
-        $ID_column_name      = esc_html__('ID', 'event_espresso');
86
+        $ID_column_name = esc_html__('ID', 'event_espresso');
87 87
         $ID_column_name      .= ' : <span class="show-on-mobile-view-only" style="float:none">';
88 88
         $ID_column_name      .= esc_html__('Registrant Name', 'event_espresso');
89 89
         $ID_column_name      .= '</span> ';
90 90
         $req_data = $this->_admin_page->get_request_data();
91 91
         if (isset($req_data['event_id'])) {
92
-            $this->_columns        = [
92
+            $this->_columns = [
93 93
                 'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
94 94
                 '_REG_ID'          => $ID_column_name,
95 95
                 'ATT_fname'        => esc_html__('Name', 'event_espresso'),
@@ -113,7 +113,7 @@  discard block
 block discarded – undo
113 113
                 ],
114 114
             ];
115 115
         } else {
116
-            $this->_columns        = [
116
+            $this->_columns = [
117 117
                 'cb'               => '<input type="checkbox" />', // Render a checkbox instead of text
118 118
                 '_REG_ID'          => $ID_column_name,
119 119
                 'ATT_fname'        => esc_html__('Name', 'event_espresso'),
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
                 'return_url'  => $return_url,
141 141
             ],
142 142
         ];
143
-        $filters                                  = array_diff_key(
143
+        $filters = array_diff_key(
144 144
             $this->_req_data,
145 145
             array_flip(
146 146
                 [
@@ -150,12 +150,12 @@  discard block
 block discarded – undo
150 150
                 ]
151 151
             )
152 152
         );
153
-        if (! empty($filters)) {
153
+        if ( ! empty($filters)) {
154 154
             $this->_bottom_buttons['report_filtered']['extra_request']['filters'] = $filters;
155 155
         }
156 156
         $this->_primary_column   = '_REG_ID';
157 157
         $this->_sortable_columns = [
158
-            '_REG_date'     => ['_REG_date' => true],   // true means its already sorted
158
+            '_REG_date'     => ['_REG_date' => true], // true means its already sorted
159 159
             /**
160 160
              * Allows users to change the default sort if they wish.
161 161
              * Returning a falsey on this filter will result in the default sort to be by firstname rather than last
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
             'DTT_EVT_start' => ['DTT_EVT_start' => false],
173 173
             '_REG_ID'       => ['_REG_ID' => false],
174 174
         ];
175
-        $this->_hidden_columns   = [];
175
+        $this->_hidden_columns = [];
176 176
     }
177 177
 
178 178
 
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
     {
188 188
         $class = parent::_get_row_class($item);
189 189
         // add status class
190
-        $class .= ' ee-status-strip reg-status-' . $item->status_ID();
190
+        $class .= ' ee-status-strip reg-status-'.$item->status_ID();
191 191
         if ($this->_has_checkbox_column) {
192 192
             $class .= ' has-checkbox-column';
193 193
         }
@@ -361,14 +361,14 @@  discard block
 block discarded – undo
361 361
         $this_month_r    = date('m', current_time('timestamp'));
362 362
         $days_this_month = date('t', current_time('timestamp'));
363 363
         // setup date query.
364
-        $beginning_string   = EEM_Registration::instance()->convert_datetime_for_query(
364
+        $beginning_string = EEM_Registration::instance()->convert_datetime_for_query(
365 365
             'REG_date',
366
-            $this_year_r . '-' . $this_month_r . '-01' . ' ' . $time_start,
366
+            $this_year_r.'-'.$this_month_r.'-01'.' '.$time_start,
367 367
             'Y-m-d H:i:s'
368 368
         );
369
-        $end_string         = EEM_Registration::instance()->convert_datetime_for_query(
369
+        $end_string = EEM_Registration::instance()->convert_datetime_for_query(
370 370
             'REG_date',
371
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' ' . $time_end,
371
+            $this_year_r.'-'.$this_month_r.'-'.$days_this_month.' '.$time_end,
372 372
             'Y-m-d H:i:s'
373 373
         );
374 374
         $_where['REG_date'] = [
@@ -378,7 +378,7 @@  discard block
 block discarded – undo
378 378
                 $end_string,
379 379
             ],
380 380
         ];
381
-        $_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
381
+        $_where['STS_ID'] = ['!=', EEM_Registration::status_id_incomplete];
382 382
         return EEM_Registration::instance()->count([$_where]);
383 383
     }
384 384
 
@@ -406,17 +406,17 @@  discard block
 block discarded – undo
406 406
             [
407 407
                 EEM_Registration::instance()->convert_datetime_for_query(
408 408
                     'REG_date',
409
-                    $current_date . $time_start,
409
+                    $current_date.$time_start,
410 410
                     'Y-m-d H:i:s'
411 411
                 ),
412 412
                 EEM_Registration::instance()->convert_datetime_for_query(
413 413
                     'REG_date',
414
-                    $current_date . $time_end,
414
+                    $current_date.$time_end,
415 415
                     'Y-m-d H:i:s'
416 416
                 ),
417 417
             ],
418 418
         ];
419
-        $_where['STS_ID']   = ['!=', EEM_Registration::status_id_incomplete];
419
+        $_where['STS_ID'] = ['!=', EEM_Registration::status_id_incomplete];
420 420
         return EEM_Registration::instance()->count([$_where]);
421 421
     }
422 422
 
@@ -500,7 +500,7 @@  discard block
 block discarded – undo
500 500
             ],
501 501
             TXN_ADMIN_URL
502 502
         );
503
-        $view_link    = EE_Registry::instance()->CAP->current_user_can(
503
+        $view_link = EE_Registry::instance()->CAP->current_user_can(
504 504
             'ee_read_transaction',
505 505
             'espresso_transactions_view_transaction'
506 506
         )
@@ -514,7 +514,7 @@  discard block
 block discarded – undo
514 514
               . $item->get_i18n_datetime('REG_date')
515 515
               . '</a>'
516 516
             : $item->get_i18n_datetime('REG_date');
517
-        $view_link    .= '<br><span class="ee-status-text-small">'
517
+        $view_link .= '<br><span class="ee-status-text-small">'
518 518
                          . EEH_Template::pretty_status($this->_transaction_details['status'], false, 'sentence')
519 519
                          . '</span>';
520 520
         return $view_link;
@@ -539,11 +539,11 @@  discard block
 block discarded – undo
539 539
         $event_name = $event_name ?: esc_html__("No Associated Event", 'event_espresso');
540 540
         $event_name = wp_trim_words($event_name, 30, '...');
541 541
         if ($EVT_ID) {
542
-            $edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(
542
+            $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(
543 543
                 ['action' => 'edit', 'post' => $EVT_ID],
544 544
                 EVENTS_ADMIN_URL
545 545
             );
546
-            $edit_event              =
546
+            $edit_event =
547 547
                 EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'edit_event', $EVT_ID)
548 548
                     ? '<a class="ee-status-color-'
549 549
                       . $this->_event_details['status']
@@ -556,12 +556,12 @@  discard block
 block discarded – undo
556 556
                       . '</a>'
557 557
                     : $event_name;
558 558
             $edit_event_url          = EE_Admin_Page::add_query_args_and_nonce(['event_id' => $EVT_ID], REG_ADMIN_URL);
559
-            $actions['event_filter'] = '<a href="' . $edit_event_url . '" title="';
559
+            $actions['event_filter'] = '<a href="'.$edit_event_url.'" title="';
560 560
             $actions['event_filter'] .= sprintf(
561 561
                 esc_attr__('Filter this list to only show registrations for %s', 'event_espresso'),
562 562
                 $event_name
563 563
             );
564
-            $actions['event_filter'] .= '">' . esc_html__('View Registrations', 'event_espresso') . '</a>';
564
+            $actions['event_filter'] .= '">'.esc_html__('View Registrations', 'event_espresso').'</a>';
565 565
         } else {
566 566
             $edit_event              = $event_name;
567 567
             $actions['event_filter'] = '';
@@ -605,11 +605,11 @@  discard block
 block discarded – undo
605 605
     {
606 606
         $content       = '<div class="ee-registration-event-datetimes-container">';
607 607
         $expand_toggle = count($datetime_strings) > 1
608
-            ? ' <span title="' . esc_attr__('Click to view all dates', 'event_espresso')
608
+            ? ' <span title="'.esc_attr__('Click to view all dates', 'event_espresso')
609 609
               . '" class="ee-js ee-more-datetimes-toggle dashicons dashicons-plus"></span>'
610 610
             : '';
611 611
         // get first item for initial visibility
612
-        $content .= '<div class="left">' . array_shift($datetime_strings) . '</div>';
612
+        $content .= '<div class="left">'.array_shift($datetime_strings).'</div>';
613 613
         $content .= $expand_toggle;
614 614
         if ($datetime_strings) {
615 615
             $content .= '<div style="clear:both"></div>';
@@ -657,7 +657,7 @@  discard block
 block discarded – undo
657 657
               . $attendee_name
658 658
               . '</a>'
659 659
             : $attendee_name;
660
-        $link          .= $item->count() === 1
660
+        $link .= $item->count() === 1
661 661
             ? '&nbsp;<sup><div class="dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8"></div></sup>'
662 662
             : '';
663 663
         $t             = $item->get_first_related('Transaction');
@@ -665,11 +665,11 @@  discard block
 block discarded – undo
665 665
             ? $t->count_related('Payment')
666 666
             : 0;
667 667
         // append group count to name
668
-        $link .= '&nbsp;' . sprintf(esc_html__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
668
+        $link .= '&nbsp;'.sprintf(esc_html__('(%1$s / %2$s)', 'event_espresso'), $item->count(), $item->group_size());
669 669
         // append reg_code
670
-        $link .= '<br>' . sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
670
+        $link .= '<br>'.sprintf(esc_html__('Reg Code: %s', 'event_espresso'), $item->get('REG_code'));
671 671
         // reg status text for accessibility
672
-        $link   .= '<br><span class="ee-status-text-small">'
672
+        $link .= '<br><span class="ee-status-text-small">'
673 673
                    . EEH_Template::pretty_status($item->status_ID(), false, 'sentence')
674 674
                    . '</span>';
675 675
         $action = ['_REG_ID' => $item->ID()];
@@ -696,7 +696,7 @@  discard block
 block discarded – undo
696 696
                                 . $trash_lnk_url
697 697
                                 . '" title="'
698 698
                                 . esc_attr__('Trash Registration', 'event_espresso')
699
-                                . '">' . esc_html__('Trash', 'event_espresso') . '</a>';
699
+                                . '">'.esc_html__('Trash', 'event_espresso').'</a>';
700 700
         } elseif ($this->_view === 'trash') {
701 701
             // restore registration link
702 702
             if (
@@ -714,8 +714,8 @@  discard block
 block discarded – undo
714 714
                 $actions['restore'] = '<a href="'
715 715
                                       . $restore_lnk_url
716 716
                                       . '" title="'
717
-                                      . esc_attr__('Restore Registration', 'event_espresso') . '">'
718
-                                      . esc_html__('Restore', 'event_espresso') . '</a>';
717
+                                      . esc_attr__('Restore Registration', 'event_espresso').'">'
718
+                                      . esc_html__('Restore', 'event_espresso').'</a>';
719 719
             }
720 720
             if (
721 721
             EE_Registry::instance()->CAP->current_user_can(
@@ -781,10 +781,10 @@  discard block
 block discarded – undo
781 781
         $ticket  = $item->ticket();
782 782
         $req_data = $this->_admin_page->get_request_data();
783 783
         $content = isset($req_data['event_id']) && $ticket instanceof EE_Ticket
784
-            ? '<span class="TKT_name">' . $ticket->name() . '</span><br />'
784
+            ? '<span class="TKT_name">'.$ticket->name().'</span><br />'
785 785
             : '';
786 786
         if ($item->final_price() > 0) {
787
-            $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
787
+            $content .= '<span class="reg-pad-rght">'.$item->pretty_final_price().'</span>';
788 788
         } else {
789 789
             // free event
790 790
             $content .= '<span class="reg-overview-free-event-spn reg-pad-rght">'
@@ -807,8 +807,8 @@  discard block
 block discarded – undo
807 807
         $req_data = $this->_admin_page->get_request_data();
808 808
         $content = isset($req_data['event_id']) || ! $ticket instanceof EE_Ticket
809 809
             ? ''
810
-            : '<span class="TKT_name">' . $ticket->name() . '</span><br />';
811
-        $content .= '<span class="reg-pad-rght">' . $item->pretty_final_price() . '</span>';
810
+            : '<span class="TKT_name">'.$ticket->name().'</span><br />';
811
+        $content .= '<span class="reg-pad-rght">'.$item->pretty_final_price().'</span>';
812 812
         return $content;
813 813
     }
814 814
 
@@ -824,7 +824,7 @@  discard block
 block discarded – undo
824 824
         $payment_method_name = $payment_method instanceof EE_Payment_Method
825 825
             ? $payment_method->admin_name()
826 826
             : esc_html__('Unknown', 'event_espresso');
827
-        $content             = '<span class="reg-pad-rght">' . $item->pretty_paid() . '</span>';
827
+        $content             = '<span class="reg-pad-rght">'.$item->pretty_paid().'</span>';
828 828
         if ($item->paid() > 0) {
829 829
             $content .= '<br><span class="ee-status-text-small">'
830 830
                         . sprintf(
@@ -871,7 +871,7 @@  discard block
 block discarded – undo
871 871
                   . '">'
872 872
                   . $item->transaction()->pretty_total()
873 873
                   . '</a></span>'
874
-                : '<span class="reg-pad-rght">' . $item->transaction()->pretty_total() . '</span>';
874
+                : '<span class="reg-pad-rght">'.$item->transaction()->pretty_total().'</span>';
875 875
         } else {
876 876
             return esc_html__("None", "event_espresso");
877 877
         }
@@ -918,7 +918,7 @@  discard block
 block discarded – undo
918 918
                       . '">'
919 919
                       . $item->transaction()->pretty_paid()
920 920
                       . '</a><span>'
921
-                    : '<span class="reg-pad-rght">' . $item->transaction()->pretty_paid() . '</span>';
921
+                    : '<span class="reg-pad-rght">'.$item->transaction()->pretty_paid().'</span>';
922 922
             }
923 923
         }
924 924
         return '&nbsp;';
@@ -967,7 +967,7 @@  discard block
 block discarded – undo
967 967
             true
968 968
         );
969 969
         // Build row actions
970
-        $actions['view_lnk']       = EE_Registry::instance()->CAP->current_user_can(
970
+        $actions['view_lnk'] = EE_Registry::instance()->CAP->current_user_can(
971 971
             'ee_read_registration',
972 972
             'espresso_registrations_view_registration',
973 973
             $item->ID()
@@ -981,15 +981,15 @@  discard block
 block discarded – undo
981 981
 			</a>
982 982
 			</li>'
983 983
             : '';
984
-        $actions['edit_lnk']       = EE_Registry::instance()->CAP->current_user_can(
984
+        $actions['edit_lnk'] = EE_Registry::instance()->CAP->current_user_can(
985 985
             'ee_edit_contacts',
986 986
             'espresso_registrations_edit_attendee'
987 987
         )
988 988
                                      && $attendee instanceof EE_Attendee
989 989
             ? '
990 990
 			<li>
991
-			<a href="' . $edit_lnk_url . '" title="'
992
-              . esc_attr__('Edit Contact Details', 'event_espresso') . '" class="tiny-text">
991
+			<a href="' . $edit_lnk_url.'" title="'
992
+              . esc_attr__('Edit Contact Details', 'event_espresso').'" class="tiny-text">
993 993
 				<div class="ee-icon ee-icon-user-edit ee-icon-size-16"></div>
994 994
 			</a>
995 995
 			</li>'
@@ -1012,7 +1012,7 @@  discard block
 block discarded – undo
1012 1012
 			</li>'
1013 1013
             : '';
1014 1014
         // page=transactions&action=view_transaction&txn=256&_wpnonce=6414da4dbb
1015
-        $view_txn_lnk_url        = EE_Admin_Page::add_query_args_and_nonce(
1015
+        $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
1016 1016
             [
1017 1017
                 'action' => 'view_transaction',
1018 1018
                 'TXN_ID' => $this->_transaction_details['id'],
@@ -1064,7 +1064,7 @@  discard block
 block discarded – undo
1064 1064
                     'see_notifications_for',
1065 1065
                     null,
1066 1066
                     ['_REG_ID' => $item->ID()]
1067
-                ) . '</li>';
1067
+                ).'</li>';
1068 1068
         }
1069 1069
         $actions = apply_filters('FHEE__EE_Registrations_List_Table__column_actions__actions', $actions, $item, $this);
1070 1070
         return $this->_action_string(implode('', $actions), $item, 'ul', 'reg-overview-actions-ul');
Please login to merge, or discard this patch.
admin_pages/general_settings/General_Settings_Admin_Page.core.php 1 patch
Indentation   +1399 added lines, -1399 removed lines patch added patch discarded remove patch
@@ -19,1414 +19,1414 @@
 block discarded – undo
19 19
 class General_Settings_Admin_Page extends EE_Admin_Page
20 20
 {
21 21
 
22
-    /**
23
-     * _question_group
24
-     * holds the specific question group object for the question group details screen
25
-     *
26
-     * @var object
27
-     */
28
-    protected $_question_group;
29
-
30
-
31
-    /**
32
-     * Initialize basic properties.
33
-     */
34
-    protected function _init_page_props()
35
-    {
36
-        $this->page_slug = GEN_SET_PG_SLUG;
37
-        $this->page_label = GEN_SET_LABEL;
38
-        $this->_admin_base_url = GEN_SET_ADMIN_URL;
39
-        $this->_admin_base_path = GEN_SET_ADMIN;
40
-    }
41
-
42
-
43
-    /**
44
-     * Set ajax hooks
45
-     */
46
-    protected function _ajax_hooks()
47
-    {
48
-        add_action('wp_ajax_espresso_display_country_settings', array($this, 'display_country_settings'));
49
-        add_action('wp_ajax_espresso_display_country_states', array($this, 'display_country_states'));
50
-        add_action('wp_ajax_espresso_delete_state', array($this, 'delete_state'), 10, 3);
51
-        add_action('wp_ajax_espresso_add_new_state', array($this, 'add_new_state'));
52
-    }
53
-
54
-
55
-    /**
56
-     * More page properties initialization.
57
-     */
58
-    protected function _define_page_props()
59
-    {
60
-        $this->_admin_page_title = GEN_SET_LABEL;
61
-        $this->_labels = array(
62
-            'publishbox' => esc_html__('Update Settings', 'event_espresso'),
63
-        );
64
-    }
65
-
66
-
67
-    /**
68
-     * Set page routes property.
69
-     */
70
-    protected function _set_page_routes()
71
-    {
72
-        $this->_page_routes = array(
73
-
74
-            'critical_pages'                => array(
75
-                'func'       => '_espresso_page_settings',
76
-                'capability' => 'manage_options',
77
-            ),
78
-            'update_espresso_page_settings' => array(
79
-                'func'       => '_update_espresso_page_settings',
80
-                'capability' => 'manage_options',
81
-                'noheader'   => true,
82
-            ),
83
-            'default'                       => array(
84
-                'func'       => '_your_organization_settings',
85
-                'capability' => 'manage_options',
86
-            ),
87
-
88
-            'update_your_organization_settings' => array(
89
-                'func'       => '_update_your_organization_settings',
90
-                'capability' => 'manage_options',
91
-                'noheader'   => true,
92
-            ),
93
-
94
-            'admin_option_settings' => array(
95
-                'func'       => '_admin_option_settings',
96
-                'capability' => 'manage_options',
97
-            ),
98
-
99
-            'update_admin_option_settings' => array(
100
-                'func'       => '_update_admin_option_settings',
101
-                'capability' => 'manage_options',
102
-                'noheader'   => true,
103
-            ),
104
-
105
-            'country_settings' => array(
106
-                'func'       => '_country_settings',
107
-                'capability' => 'manage_options',
108
-            ),
109
-
110
-            'update_country_settings' => array(
111
-                'func'       => '_update_country_settings',
112
-                'capability' => 'manage_options',
113
-                'noheader'   => true,
114
-            ),
115
-
116
-            'display_country_settings' => array(
117
-                'func'       => 'display_country_settings',
118
-                'capability' => 'manage_options',
119
-                'noheader'   => true,
120
-            ),
121
-
122
-            'add_new_state' => array(
123
-                'func'       => 'add_new_state',
124
-                'capability' => 'manage_options',
125
-                'noheader'   => true,
126
-            ),
127
-
128
-            'delete_state'            => array(
129
-                'func'       => 'delete_state',
130
-                'capability' => 'manage_options',
131
-                'noheader'   => true,
132
-            ),
133
-            'privacy_settings'        => array(
134
-                'func'       => 'privacySettings',
135
-                'capability' => 'manage_options',
136
-            ),
137
-            'update_privacy_settings' => array(
138
-                'func'               => 'updatePrivacySettings',
139
-                'capability'         => 'manage_options',
140
-                'noheader'           => true,
141
-                'headers_sent_route' => 'privacy_settings',
142
-            ),
143
-        );
144
-    }
145
-
146
-
147
-    /**
148
-     * Set page configuration property
149
-     */
150
-    protected function _set_page_config()
151
-    {
152
-        $this->_page_config = array(
153
-            'critical_pages'        => array(
154
-                'nav'           => array(
155
-                    'label' => esc_html__('Critical Pages', 'event_espresso'),
156
-                    'order' => 50,
157
-                ),
158
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
159
-                'help_tabs'     => array(
160
-                    'general_settings_critical_pages_help_tab' => array(
161
-                        'title'    => esc_html__('Critical Pages', 'event_espresso'),
162
-                        'filename' => 'general_settings_critical_pages',
163
-                    ),
164
-                ),
165
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
166
-                // 'help_tour'     => array('Critical_Pages_Help_Tour'),
167
-                'require_nonce' => false,
168
-            ),
169
-            'default'               => array(
170
-                'nav'           => array(
171
-                    'label' => esc_html__('Your Organization', 'event_espresso'),
172
-                    'order' => 20,
173
-                ),
174
-                'help_tabs'     => array(
175
-                    'general_settings_your_organization_help_tab' => array(
176
-                        'title'    => esc_html__('Your Organization', 'event_espresso'),
177
-                        'filename' => 'general_settings_your_organization',
178
-                    ),
179
-                ),
180
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
181
-                // 'help_tour'     => array('Your_Organization_Help_Tour'),
182
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
183
-                'require_nonce' => false,
184
-            ),
185
-            'admin_option_settings' => array(
186
-                'nav'           => array(
187
-                    'label' => esc_html__('Admin Options', 'event_espresso'),
188
-                    'order' => 60,
189
-                ),
190
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
191
-                'help_tabs'     => array(
192
-                    'general_settings_admin_options_help_tab' => array(
193
-                        'title'    => esc_html__('Admin Options', 'event_espresso'),
194
-                        'filename' => 'general_settings_admin_options',
195
-                    ),
196
-                ),
197
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
198
-                // 'help_tour'     => array('Admin_Options_Help_Tour'),
199
-                'require_nonce' => false,
200
-            ),
201
-            'country_settings'      => array(
202
-                'nav'           => array(
203
-                    'label' => esc_html__('Countries', 'event_espresso'),
204
-                    'order' => 70,
205
-                ),
206
-                'help_tabs'     => array(
207
-                    'general_settings_countries_help_tab' => array(
208
-                        'title'    => esc_html__('Countries', 'event_espresso'),
209
-                        'filename' => 'general_settings_countries',
210
-                    ),
211
-                ),
212
-                // disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
213
-                // 'help_tour'     => array('Countries_Help_Tour'),
214
-                'require_nonce' => false,
215
-            ),
216
-            'privacy_settings'      => array(
217
-                'nav'           => array(
218
-                    'label' => esc_html__('Privacy', 'event_espresso'),
219
-                    'order' => 80,
220
-                ),
221
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
222
-                'require_nonce' => false,
223
-            ),
224
-        );
225
-    }
226
-
227
-
228
-    protected function _add_screen_options()
229
-    {
230
-    }
231
-
232
-
233
-    protected function _add_feature_pointers()
234
-    {
235
-    }
236
-
237
-
238
-    /**
239
-     * Enqueue global scripts and styles for all routes in the General Settings Admin Pages.
240
-     */
241
-    public function load_scripts_styles()
242
-    {
243
-        // styles
244
-        wp_enqueue_style('espresso-ui-theme');
245
-        // scripts
246
-        wp_enqueue_script('ee_admin_js');
247
-    }
248
-
249
-
250
-    /**
251
-     * Execute logic running on `admin_init`
252
-     */
253
-    public function admin_init()
254
-    {
255
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = wp_strip_all_tags(__(
256
-            '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.',
257
-            'event_espresso'
258
-        ));
259
-        EE_Registry::$i18n_js_strings['error_occurred'] = wp_strip_all_tags(__(
260
-            'An error occurred! Please refresh the page and try again.',
261
-            'event_espresso'
262
-        ));
263
-        EE_Registry::$i18n_js_strings['confirm_delete_state'] = wp_strip_all_tags(__(
264
-            'Are you sure you want to delete this State / Province?',
265
-            'event_espresso'
266
-        ));
267
-        $protocol = is_ssl() ? 'https://' : 'http://';
268
-        EE_Registry::$i18n_js_strings['ajax_url'] = admin_url(
269
-            'admin-ajax.php?page=espresso_general_settings',
270
-            $protocol
271
-        );
272
-    }
273
-
274
-
275
-    public function admin_notices()
276
-    {
277
-    }
278
-
279
-
280
-    public function admin_footer_scripts()
281
-    {
282
-    }
283
-
284
-
285
-    /**
286
-     * Enqueue scripts and styles for the default route.
287
-     */
288
-    public function load_scripts_styles_default()
289
-    {
290
-        // styles
291
-        wp_enqueue_style('thickbox');
292
-        // scripts
293
-        wp_enqueue_script('media-upload');
294
-        wp_enqueue_script('thickbox');
295
-        wp_register_script(
296
-            'organization_settings',
297
-            GEN_SET_ASSETS_URL . 'your_organization_settings.js',
298
-            array('jquery', 'media-upload', 'thickbox'),
299
-            EVENT_ESPRESSO_VERSION,
300
-            true
301
-        );
302
-        wp_register_style('organization-css', GEN_SET_ASSETS_URL . 'organization.css', array(), EVENT_ESPRESSO_VERSION);
303
-        wp_enqueue_script('organization_settings');
304
-        wp_enqueue_style('organization-css');
305
-        $confirm_image_delete = array(
306
-            'text' => wp_strip_all_tags(
307
-                __(
308
-                    'Do you really want to delete this image? Please remember to save your settings to complete the removal.',
309
-                    'event_espresso'
310
-                )
311
-            ),
312
-        );
313
-        wp_localize_script('organization_settings', 'confirm_image_delete', $confirm_image_delete);
314
-    }
315
-
316
-
317
-    /**
318
-     * Enqueue scripts and styles for the country settings route.
319
-     */
320
-    public function load_scripts_styles_country_settings()
321
-    {
322
-        // scripts
323
-        wp_register_script(
324
-            'gen_settings_countries',
325
-            GEN_SET_ASSETS_URL . 'gen_settings_countries.js',
326
-            array('ee_admin_js'),
327
-            EVENT_ESPRESSO_VERSION,
328
-            true
329
-        );
330
-        wp_register_style('organization-css', GEN_SET_ASSETS_URL . 'organization.css', array(), EVENT_ESPRESSO_VERSION);
331
-        wp_enqueue_script('gen_settings_countries');
332
-        wp_enqueue_style('organization-css');
333
-    }
334
-
335
-
336
-    /*************        Espresso Pages        *************/
337
-    /**
338
-     * _espresso_page_settings
339
-     *
340
-     * @throws \EE_Error
341
-     * @throws DomainException
342
-     * @throws DomainException
343
-     * @throws InvalidDataTypeException
344
-     * @throws InvalidArgumentException
345
-     */
346
-    protected function _espresso_page_settings()
347
-    {
348
-        // Check to make sure all of the main pages are setup properly,
349
-        // if not create the default pages and display an admin notice
350
-        EEH_Activation::verify_default_pages_exist();
351
-        $this->_transient_garbage_collection();
352
-        $this->_template_args['values'] = $this->_yes_no_values;
353
-        $this->_template_args['reg_page_id'] = isset(EE_Registry::instance()->CFG->core->reg_page_id)
354
-            ? EE_Registry::instance()->CFG->core->reg_page_id
355
-            : null;
356
-        $this->_template_args['reg_page_obj'] = isset(EE_Registry::instance()->CFG->core->reg_page_id)
357
-            ? get_page(EE_Registry::instance()->CFG->core->reg_page_id)
358
-            : false;
359
-        $this->_template_args['txn_page_id'] = isset(EE_Registry::instance()->CFG->core->txn_page_id)
360
-            ? EE_Registry::instance()->CFG->core->txn_page_id
361
-            : null;
362
-        $this->_template_args['txn_page_obj'] = isset(EE_Registry::instance()->CFG->core->txn_page_id)
363
-            ? get_page(EE_Registry::instance()->CFG->core->txn_page_id)
364
-            : false;
365
-        $this->_template_args['thank_you_page_id'] = isset(EE_Registry::instance()->CFG->core->thank_you_page_id)
366
-            ? EE_Registry::instance()->CFG->core->thank_you_page_id
367
-            : null;
368
-        $this->_template_args['thank_you_page_obj'] = isset(EE_Registry::instance()->CFG->core->thank_you_page_id)
369
-            ? get_page(EE_Registry::instance()->CFG->core->thank_you_page_id)
370
-            : false;
371
-        $this->_template_args['cancel_page_id'] = isset(EE_Registry::instance()->CFG->core->cancel_page_id)
372
-            ? EE_Registry::instance()->CFG->core->cancel_page_id
373
-            : null;
374
-        $this->_template_args['cancel_page_obj'] = isset(EE_Registry::instance()->CFG->core->cancel_page_id)
375
-            ? get_page(EE_Registry::instance()->CFG->core->cancel_page_id)
376
-            : false;
377
-        $this->_set_add_edit_form_tags('update_espresso_page_settings');
378
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
379
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
380
-            GEN_SET_TEMPLATE_PATH . 'espresso_page_settings.template.php',
381
-            $this->_template_args,
382
-            true
383
-        );
384
-        $this->display_admin_page_with_sidebar();
385
-    }
386
-
387
-
388
-    /**
389
-     * Handler for updating espresso page settings.
390
-     *
391
-     * @throws EE_Error
392
-     */
393
-    protected function _update_espresso_page_settings()
394
-    {
395
-        // capture incoming request data && set page IDs
396
-        EE_Registry::instance()->CFG->core->reg_page_id = isset($this->_req_data['reg_page_id'])
397
-            ? absint($this->_req_data['reg_page_id'])
398
-            : EE_Registry::instance()->CFG->core->reg_page_id;
399
-        EE_Registry::instance()->CFG->core->txn_page_id = isset($this->_req_data['txn_page_id'])
400
-            ? absint($this->_req_data['txn_page_id'])
401
-            : EE_Registry::instance()->CFG->core->txn_page_id;
402
-        EE_Registry::instance()->CFG->core->thank_you_page_id = isset($this->_req_data['thank_you_page_id'])
403
-            ? absint($this->_req_data['thank_you_page_id'])
404
-            : EE_Registry::instance()->CFG->core->thank_you_page_id;
405
-        EE_Registry::instance()->CFG->core->cancel_page_id = isset($this->_req_data['cancel_page_id'])
406
-            ? absint($this->_req_data['cancel_page_id'])
407
-            : EE_Registry::instance()->CFG->core->cancel_page_id;
408
-
409
-        EE_Registry::instance()->CFG->core = apply_filters(
410
-            'FHEE__General_Settings_Admin_Page___update_espresso_page_settings__CFG_core',
411
-            EE_Registry::instance()->CFG->core,
412
-            $this->_req_data
413
-        );
414
-        $what = esc_html__('Critical Pages & Shortcodes', 'event_espresso');
415
-        $this->_redirect_after_action(
416
-            $this->_update_espresso_configuration(
417
-                $what,
418
-                EE_Registry::instance()->CFG->core,
419
-                __FILE__,
420
-                __FUNCTION__,
421
-                __LINE__
422
-            ),
423
-            $what,
424
-            '',
425
-            array(
426
-                'action' => 'critical_pages',
427
-            ),
428
-            true
429
-        );
430
-    }
431
-
432
-
433
-    /*************        Your Organization        *************/
434
-
435
-
436
-    /**
437
-     * @throws DomainException
438
-     * @throws EE_Error
439
-     * @throws InvalidArgumentException
440
-     * @throws InvalidDataTypeException
441
-     * @throws InvalidInterfaceException
442
-     */
443
-    protected function _your_organization_settings()
444
-    {
445
-        $this->_template_args['admin_page_content'] = '';
446
-        try {
447
-            /** @var EventEspresso\admin_pages\general_settings\OrganizationSettings $organization_settings_form */
448
-            $organization_settings_form = $this->loader->getShared(
449
-                'EventEspresso\admin_pages\general_settings\OrganizationSettings'
450
-            );
451
-            $this->_template_args['admin_page_content'] = $organization_settings_form->display();
452
-        } catch (Exception $e) {
453
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
454
-        }
455
-        $this->_set_add_edit_form_tags('update_your_organization_settings');
456
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
457
-        $this->display_admin_page_with_sidebar();
458
-    }
459
-
460
-
461
-    /**
462
-     * Handler for updating organization settings.
463
-     *
464
-     * @throws EE_Error
465
-     */
466
-    protected function _update_your_organization_settings()
467
-    {
468
-        try {
469
-            /** @var EventEspresso\admin_pages\general_settings\OrganizationSettings $organization_settings_form */
470
-            $organization_settings_form = $this->loader->getShared(
471
-                'EventEspresso\admin_pages\general_settings\OrganizationSettings'
472
-            );
473
-            $success = $organization_settings_form->process($this->_req_data);
474
-            EE_Registry::instance()->CFG = apply_filters(
475
-                'FHEE__General_Settings_Admin_Page___update_your_organization_settings__CFG',
476
-                EE_Registry::instance()->CFG
477
-            );
478
-        } catch (Exception $e) {
479
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
480
-            $success = false;
481
-        }
482
-
483
-        if ($success) {
484
-            $success = $this->_update_espresso_configuration(
485
-                esc_html__('Your Organization Settings', 'event_espresso'),
486
-                EE_Registry::instance()->CFG,
487
-                __FILE__,
488
-                __FUNCTION__,
489
-                __LINE__
490
-            );
491
-        }
492
-
493
-        $this->_redirect_after_action($success, '', '', array('action' => 'default'), true);
494
-    }
495
-
496
-
497
-
498
-    /*************        Admin Options        *************/
499
-
500
-
501
-    /**
502
-     * _admin_option_settings
503
-     *
504
-     * @throws \EE_Error
505
-     * @throws \LogicException
506
-     */
507
-    protected function _admin_option_settings()
508
-    {
509
-        $this->_template_args['admin_page_content'] = '';
510
-        try {
511
-            $admin_options_settings_form = new AdminOptionsSettings(EE_Registry::instance());
512
-            // still need this for the old school form in Extend_General_Settings_Admin_Page
513
-            $this->_template_args['values'] = $this->_yes_no_values;
514
-            // also need to account for the do_action that was in the old template
515
-            $admin_options_settings_form->setTemplateArgs($this->_template_args);
516
-            $this->_template_args['admin_page_content'] = $admin_options_settings_form->display();
517
-        } catch (Exception $e) {
518
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
519
-        }
520
-        $this->_set_add_edit_form_tags('update_admin_option_settings');
521
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
522
-        $this->display_admin_page_with_sidebar();
523
-    }
524
-
525
-
526
-    /**
527
-     * _update_admin_option_settings
528
-     *
529
-     * @throws \EE_Error
530
-     * @throws InvalidDataTypeException
531
-     * @throws \EventEspresso\core\exceptions\InvalidFormSubmissionException
532
-     * @throws \InvalidArgumentException
533
-     * @throws \LogicException
534
-     */
535
-    protected function _update_admin_option_settings()
536
-    {
537
-        try {
538
-            $admin_options_settings_form = new AdminOptionsSettings(EE_Registry::instance());
539
-            $admin_options_settings_form->process($this->_req_data[ $admin_options_settings_form->slug() ]);
540
-            EE_Registry::instance()->CFG->admin = apply_filters(
541
-                'FHEE__General_Settings_Admin_Page___update_admin_option_settings__CFG_admin',
542
-                EE_Registry::instance()->CFG->admin
543
-            );
544
-        } catch (Exception $e) {
545
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
546
-        }
547
-        $this->_redirect_after_action(
548
-            apply_filters(
549
-                'FHEE__General_Settings_Admin_Page___update_admin_option_settings__success',
550
-                $this->_update_espresso_configuration(
551
-                    'Admin Options',
552
-                    EE_Registry::instance()->CFG->admin,
553
-                    __FILE__,
554
-                    __FUNCTION__,
555
-                    __LINE__
556
-                )
557
-            ),
558
-            'Admin Options',
559
-            'updated',
560
-            array('action' => 'admin_option_settings')
561
-        );
562
-    }
563
-
564
-
565
-    /*************        Countries        *************/
566
-
567
-
568
-    /**
569
-     * @return string
570
-     */
571
-    protected function getCountryIsoForSite()
572
-    {
573
-        return ! empty(EE_Registry::instance()->CFG->organization->CNT_ISO)
574
-            ? EE_Registry::instance()->CFG->organization->CNT_ISO
575
-            : 'US';
576
-    }
577
-
578
-
579
-    /**
580
-     * @param string          $CNT_ISO
581
-     * @param EE_Country|null $country
582
-     * @return EE_Base_Class|EE_Country
583
-     * @throws EE_Error
584
-     * @throws InvalidArgumentException
585
-     * @throws InvalidDataTypeException
586
-     * @throws InvalidInterfaceException
587
-     * @throws ReflectionException
588
-     */
589
-    protected function verifyOrGetCountryFromIso($CNT_ISO, EE_Country $country = null)
590
-    {
591
-        /** @var EE_Country $country */
592
-        return $country instanceof EE_Country && $country->ID() === $CNT_ISO
593
-            ? $country
594
-            : EEM_Country::instance()->get_one_by_ID($CNT_ISO);
595
-    }
596
-
597
-
598
-    /**
599
-     * Output Country Settings view.
600
-     *
601
-     * @throws DomainException
602
-     * @throws EE_Error
603
-     * @throws InvalidArgumentException
604
-     * @throws InvalidDataTypeException
605
-     * @throws InvalidInterfaceException
606
-     * @throws ReflectionException
607
-     */
608
-    protected function _country_settings()
609
-    {
610
-        $CNT_ISO_for_site = $this->getCountryIsoForSite();
611
-        $CNT_ISO = isset($this->_req_data['country'])
612
-            ? strtoupper(sanitize_text_field($this->_req_data['country']))
613
-            : $CNT_ISO_for_site;
614
-
615
-        // load field generator helper
616
-
617
-        $this->_template_args['values'] = $this->_yes_no_values;
618
-
619
-        $this->_template_args['countries'] = new EE_Question_Form_Input(
620
-            EE_Question::new_instance(
621
-                array(
622
-                    'QST_ID'           => 0,
623
-                    'QST_display_text' => esc_html__('Select Country', 'event_espresso'),
624
-                    'QST_system'       => 'admin-country',
625
-                )
626
-            ),
627
-            EE_Answer::new_instance(
628
-                array(
629
-                    'ANS_ID'    => 0,
630
-                    'ANS_value' => $CNT_ISO,
631
-                )
632
-            ),
633
-            array(
634
-                'input_id'       => 'country',
635
-                'input_name'     => 'country',
636
-                'input_prefix'   => '',
637
-                'append_qstn_id' => false,
638
-            )
639
-        );
640
-        $country = $this->verifyOrGetCountryFromIso($CNT_ISO_for_site);
641
-        add_filter('FHEE__EEH_Form_Fields__label_html', array($this, 'country_form_field_label_wrap'), 10, 2);
642
-        add_filter('FHEE__EEH_Form_Fields__input_html', array($this, 'country_form_field_input__wrap'), 10, 2);
643
-        $this->_template_args['country_details_settings'] = $this->display_country_settings(
644
-            $country->ID(),
645
-            $country
646
-        );
647
-        $this->_template_args['country_states_settings'] = $this->display_country_states(
648
-            $country->ID(),
649
-            $country
650
-        );
651
-        $this->_template_args['CNT_name_for_site'] = $country->name();
652
-
653
-        $this->_set_add_edit_form_tags('update_country_settings');
654
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
655
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
656
-            GEN_SET_TEMPLATE_PATH . 'countries_settings.template.php',
657
-            $this->_template_args,
658
-            true
659
-        );
660
-        $this->display_admin_page_with_no_sidebar();
661
-    }
662
-
663
-
664
-    /**
665
-     *        display_country_settings
666
-     *
667
-     * @param string          $CNT_ISO
668
-     * @param EE_Country|null $country
669
-     * @return mixed string | array$country
670
-     * @throws DomainException
671
-     * @throws EE_Error
672
-     * @throws InvalidArgumentException
673
-     * @throws InvalidDataTypeException
674
-     * @throws InvalidInterfaceException
675
-     * @throws ReflectionException
676
-     */
677
-    public function display_country_settings($CNT_ISO = '', EE_Country $country = null)
678
-    {
679
-        $CNT_ISO_for_site = $this->getCountryIsoForSite();
680
-
681
-        $CNT_ISO = isset($this->_req_data['country'])
682
-            ? strtoupper(sanitize_text_field($this->_req_data['country']))
683
-            : $CNT_ISO;
684
-        if (! $CNT_ISO) {
685
-            return '';
686
-        }
687
-
688
-        // for ajax
689
-        remove_all_filters('FHEE__EEH_Form_Fields__label_html');
690
-        remove_all_filters('FHEE__EEH_Form_Fields__input_html');
691
-        add_filter('FHEE__EEH_Form_Fields__label_html', array($this, 'country_form_field_label_wrap'), 10, 2);
692
-        add_filter('FHEE__EEH_Form_Fields__input_html', array($this, 'country_form_field_input__wrap'), 10, 2);
693
-        $country = $this->verifyOrGetCountryFromIso($CNT_ISO, $country);
694
-        $CNT_cur_disabled = $CNT_ISO !== $CNT_ISO_for_site;
695
-        $this->_template_args['CNT_cur_disabled'] = $CNT_cur_disabled;
696
-
697
-        $country_input_types = array(
698
-            'CNT_active'      => array(
699
-                'type'             => 'RADIO_BTN',
700
-                'input_name'       => 'cntry[' . $CNT_ISO . ']',
701
-                'class'            => '',
702
-                'options'          => $this->_yes_no_values,
703
-                'use_desc_4_label' => true,
704
-            ),
705
-            'CNT_ISO'         => array(
706
-                'type'       => 'TEXT',
707
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
708
-                'class'      => 'small-text',
709
-            ),
710
-            'CNT_ISO3'        => array(
711
-                'type'       => 'TEXT',
712
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
713
-                'class'      => 'small-text',
714
-            ),
715
-            'RGN_ID'          => array(
716
-                'type'       => 'TEXT',
717
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
718
-                'class'      => 'small-text',
719
-            ),
720
-            'CNT_name'        => array(
721
-                'type'       => 'TEXT',
722
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
723
-                'class'      => 'regular-text',
724
-            ),
725
-            'CNT_cur_code'    => array(
726
-                'type'       => 'TEXT',
727
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
728
-                'class'      => 'small-text',
729
-                'disabled'   => $CNT_cur_disabled,
730
-            ),
731
-            'CNT_cur_single'  => array(
732
-                'type'       => 'TEXT',
733
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
734
-                'class'      => 'medium-text',
735
-                'disabled'   => $CNT_cur_disabled,
736
-            ),
737
-            'CNT_cur_plural'  => array(
738
-                'type'       => 'TEXT',
739
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
740
-                'class'      => 'medium-text',
741
-                'disabled'   => $CNT_cur_disabled,
742
-            ),
743
-            'CNT_cur_sign'    => array(
744
-                'type'         => 'TEXT',
745
-                'input_name'   => 'cntry[' . $CNT_ISO . ']',
746
-                'class'        => 'small-text',
747
-                'htmlentities' => false,
748
-                'disabled'     => $CNT_cur_disabled,
749
-            ),
750
-            'CNT_cur_sign_b4' => array(
751
-                'type'             => 'RADIO_BTN',
752
-                'input_name'       => 'cntry[' . $CNT_ISO . ']',
753
-                'class'            => '',
754
-                'options'          => $this->_yes_no_values,
755
-                'use_desc_4_label' => true,
756
-                'disabled'         => $CNT_cur_disabled,
757
-            ),
758
-            'CNT_cur_dec_plc' => array(
759
-                'type'       => 'RADIO_BTN',
760
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
761
-                'class'      => '',
762
-                'options'    => array(
763
-                    array('id' => 0, 'text' => ''),
764
-                    array('id' => 1, 'text' => ''),
765
-                    array('id' => 2, 'text' => ''),
766
-                    array('id' => 3, 'text' => ''),
767
-                ),
768
-                'disabled'   => $CNT_cur_disabled,
769
-            ),
770
-            'CNT_cur_dec_mrk' => array(
771
-                'type'             => 'RADIO_BTN',
772
-                'input_name'       => 'cntry[' . $CNT_ISO . ']',
773
-                'class'            => '',
774
-                'options'          => array(
775
-                    array(
776
-                        'id'   => ',',
777
-                        'text' => esc_html__(', (comma)', 'event_espresso'),
778
-                    ),
779
-                    array('id' => '.', 'text' => esc_html__('. (decimal)', 'event_espresso')),
780
-                ),
781
-                'use_desc_4_label' => true,
782
-                'disabled'         => $CNT_cur_disabled,
783
-            ),
784
-            'CNT_cur_thsnds'  => array(
785
-                'type'             => 'RADIO_BTN',
786
-                'input_name'       => 'cntry[' . $CNT_ISO . ']',
787
-                'class'            => '',
788
-                'options'          => array(
789
-                    array(
790
-                        'id'   => ',',
791
-                        'text' => esc_html__(', (comma)', 'event_espresso'),
792
-                    ),
793
-                    array(
794
-                        'id' => '.',
795
-                        'text' => esc_html__('. (decimal)', 'event_espresso')
796
-                    ),
797
-                    array(
798
-                        'id' => '&nbsp;',
799
-                        'text' => esc_html__('(space)', 'event_espresso')
800
-                    )
801
-                ),
802
-                'use_desc_4_label' => true,
803
-                'disabled'         => $CNT_cur_disabled,
804
-            ),
805
-            'CNT_tel_code'    => array(
806
-                'type'       => 'TEXT',
807
-                'input_name' => 'cntry[' . $CNT_ISO . ']',
808
-                'class'      => 'small-text',
809
-            ),
810
-            'CNT_is_EU'       => array(
811
-                'type'             => 'RADIO_BTN',
812
-                'input_name'       => 'cntry[' . $CNT_ISO . ']',
813
-                'class'            => '',
814
-                'options'          => $this->_yes_no_values,
815
-                'use_desc_4_label' => true,
816
-            ),
817
-        );
818
-        $this->_template_args['inputs'] = EE_Question_Form_Input::generate_question_form_inputs_for_object(
819
-            $country,
820
-            $country_input_types
821
-        );
822
-        $country_details_settings = EEH_Template::display_template(
823
-            GEN_SET_TEMPLATE_PATH . 'country_details_settings.template.php',
824
-            $this->_template_args,
825
-            true
826
-        );
827
-
828
-        if (defined('DOING_AJAX')) {
829
-            $notices = EE_Error::get_notices(false, false, false);
830
-            echo wp_json_encode(
831
-                array(
832
-                    'return_data' => $country_details_settings,
833
-                    'success'     => $notices['success'],
834
-                    'errors'      => $notices['errors'],
835
-                )
836
-            );
837
-            die();
838
-        } else {
839
-            return $country_details_settings;
840
-        }
841
-    }
842
-
843
-
844
-    /**
845
-     * @param string          $CNT_ISO
846
-     * @param EE_Country|null $country
847
-     * @return string
848
-     * @throws DomainException
849
-     * @throws EE_Error
850
-     * @throws InvalidArgumentException
851
-     * @throws InvalidDataTypeException
852
-     * @throws InvalidInterfaceException
853
-     * @throws ReflectionException
854
-     */
855
-    public function display_country_states($CNT_ISO = '', EE_Country $country = null)
856
-    {
857
-
858
-        $CNT_ISO = isset($this->_req_data['country'])
859
-            ? sanitize_text_field($this->_req_data['country'])
860
-            : $CNT_ISO;
861
-        if (! $CNT_ISO) {
862
-            return '';
863
-        }
864
-        // for ajax
865
-        remove_all_filters('FHEE__EEH_Form_Fields__label_html');
866
-        remove_all_filters('FHEE__EEH_Form_Fields__input_html');
867
-        add_filter('FHEE__EEH_Form_Fields__label_html', array($this, 'state_form_field_label_wrap'), 10, 2);
868
-        add_filter('FHEE__EEH_Form_Fields__input_html', array($this, 'state_form_field_input__wrap'), 10, 2);
869
-        $states = EEM_State::instance()->get_all_states_for_these_countries(array($CNT_ISO => $CNT_ISO));
870
-        if (empty($states)) {
871
-            /** @var EventEspresso\core\services\address\CountrySubRegionDao $countrySubRegionDao */
872
-            $countrySubRegionDao = $this->loader->getShared(
873
-                'EventEspresso\core\services\address\CountrySubRegionDao'
874
-            );
875
-            if ($countrySubRegionDao instanceof EventEspresso\core\services\address\CountrySubRegionDao) {
876
-                $country = $this->verifyOrGetCountryFromIso($CNT_ISO, $country);
877
-                if ($countrySubRegionDao->saveCountrySubRegions($country)) {
878
-                    $states = EEM_State::instance()->get_all_states_for_these_countries(
879
-                        array($CNT_ISO => $CNT_ISO)
880
-                    );
881
-                }
882
-            }
883
-        }
884
-        if (is_array($states)) {
885
-            foreach ($states as $STA_ID => $state) {
886
-                if ($state instanceof EE_State) {
887
-                    // STA_abbrev    STA_name    STA_active
888
-                    $state_input_types = array(
889
-                        'STA_abbrev' => array(
890
-                            'type'       => 'TEXT',
891
-                            'input_name' => 'states[' . $STA_ID . ']',
892
-                            'class'      => 'mid-text',
893
-                        ),
894
-                        'STA_name'   => array(
895
-                            'type'       => 'TEXT',
896
-                            'input_name' => 'states[' . $STA_ID . ']',
897
-                            'class'      => 'regular-text',
898
-                        ),
899
-                        'STA_active' => array(
900
-                            'type'             => 'RADIO_BTN',
901
-                            'input_name'       => 'states[' . $STA_ID . ']',
902
-                            'options'          => $this->_yes_no_values,
903
-                            'use_desc_4_label' => true,
904
-                        ),
905
-                    );
906
-                    $this->_template_args['states'][ $STA_ID ]['inputs'] =
907
-                        EE_Question_Form_Input::generate_question_form_inputs_for_object(
908
-                            $state,
909
-                            $state_input_types
910
-                        );
911
-                    $query_args = array(
912
-                        'action'     => 'delete_state',
913
-                        'STA_ID'     => $STA_ID,
914
-                        'CNT_ISO'    => $CNT_ISO,
915
-                        'STA_abbrev' => $state->abbrev(),
916
-                    );
917
-                    $this->_template_args['states'][ $STA_ID ]['delete_state_url'] =
918
-                        EE_Admin_Page::add_query_args_and_nonce(
919
-                            $query_args,
920
-                            GEN_SET_ADMIN_URL
921
-                        );
922
-                }
923
-            }
924
-        } else {
925
-            $this->_template_args['states'] = false;
926
-        }
927
-
928
-        $this->_template_args['add_new_state_url'] = EE_Admin_Page::add_query_args_and_nonce(
929
-            array('action' => 'add_new_state'),
930
-            GEN_SET_ADMIN_URL
931
-        );
932
-
933
-        $state_details_settings = EEH_Template::display_template(
934
-            GEN_SET_TEMPLATE_PATH . 'state_details_settings.template.php',
935
-            $this->_template_args,
936
-            true
937
-        );
938
-
939
-        if (defined('DOING_AJAX')) {
940
-            $notices = EE_Error::get_notices(false, false, false);
941
-            echo wp_json_encode(
942
-                array(
943
-                    'return_data' => $state_details_settings,
944
-                    'success'     => $notices['success'],
945
-                    'errors'      => $notices['errors'],
946
-                )
947
-            );
948
-            die();
949
-        } else {
950
-            return $state_details_settings;
951
-        }
952
-    }
953
-
954
-
955
-    /**
956
-     *        add_new_state
957
-     *
958
-     * @access    public
959
-     * @return void
960
-     * @throws EE_Error
961
-     * @throws InvalidArgumentException
962
-     * @throws InvalidDataTypeException
963
-     * @throws InvalidInterfaceException
964
-     */
965
-    public function add_new_state()
966
-    {
967
-
968
-        $success = true;
969
-
970
-        $CNT_ISO = isset($this->_req_data['CNT_ISO'])
971
-            ? strtoupper(sanitize_text_field($this->_req_data['CNT_ISO']))
972
-            : false;
973
-        if (! $CNT_ISO) {
974
-            EE_Error::add_error(
975
-                esc_html__('No Country ISO code or an invalid Country ISO code was received.', 'event_espresso'),
976
-                __FILE__,
977
-                __FUNCTION__,
978
-                __LINE__
979
-            );
980
-            $success = false;
981
-        }
982
-        $STA_abbrev = isset($this->_req_data['STA_abbrev'])
983
-            ? sanitize_text_field($this->_req_data['STA_abbrev'])
984
-            : false;
985
-        if (! $STA_abbrev) {
986
-            EE_Error::add_error(
987
-                esc_html__('No State ISO code or an invalid State ISO code was received.', 'event_espresso'),
988
-                __FILE__,
989
-                __FUNCTION__,
990
-                __LINE__
991
-            );
992
-            $success = false;
993
-        }
994
-        $STA_name = isset($this->_req_data['STA_name'])
995
-            ? sanitize_text_field($this->_req_data['STA_name'])
996
-            : false;
997
-        if (! $STA_name) {
998
-            EE_Error::add_error(
999
-                esc_html__('No State name or an invalid State name was received.', 'event_espresso'),
1000
-                __FILE__,
1001
-                __FUNCTION__,
1002
-                __LINE__
1003
-            );
1004
-            $success = false;
1005
-        }
1006
-
1007
-        if ($success) {
1008
-            $cols_n_values = array(
1009
-                'CNT_ISO'    => $CNT_ISO,
1010
-                'STA_abbrev' => $STA_abbrev,
1011
-                'STA_name'   => $STA_name,
1012
-                'STA_active' => true,
1013
-            );
1014
-            $success = EEM_State::instance()->insert($cols_n_values);
1015
-            EE_Error::add_success(esc_html__('The State was added successfully.', 'event_espresso'));
1016
-        }
1017
-
1018
-        if (defined('DOING_AJAX')) {
1019
-            $notices = EE_Error::get_notices(false, false, false);
1020
-            echo wp_json_encode(array_merge($notices, array('return_data' => $CNT_ISO)));
1021
-            die();
1022
-        } else {
1023
-            $this->_redirect_after_action($success, 'State', 'added', array('action' => 'country_settings'));
1024
-        }
1025
-    }
1026
-
1027
-
1028
-    /**
1029
-     *        delete_state
1030
-     *
1031
-     * @access    public
1032
-     * @return        boolean
1033
-     * @throws EE_Error
1034
-     * @throws InvalidArgumentException
1035
-     * @throws InvalidDataTypeException
1036
-     * @throws InvalidInterfaceException
1037
-     */
1038
-    public function delete_state()
1039
-    {
1040
-        $CNT_ISO = isset($this->_req_data['CNT_ISO'])
1041
-            ? strtoupper(sanitize_text_field($this->_req_data['CNT_ISO']))
1042
-            : false;
1043
-        $STA_ID = isset($this->_req_data['STA_ID'])
1044
-            ? sanitize_text_field($this->_req_data['STA_ID'])
1045
-            : false;
1046
-        $STA_abbrev = isset($this->_req_data['STA_abbrev'])
1047
-            ? sanitize_text_field($this->_req_data['STA_abbrev'])
1048
-            : false;
1049
-        if (! $STA_ID) {
1050
-            EE_Error::add_error(
1051
-                esc_html__('No State ID or an invalid State ID was received.', 'event_espresso'),
1052
-                __FILE__,
1053
-                __FUNCTION__,
1054
-                __LINE__
1055
-            );
1056
-            return false;
1057
-        }
1058
-
1059
-        $success = EEM_State::instance()->delete_by_ID($STA_ID);
1060
-        if ($success !== false) {
1061
-            do_action(
1062
-                'AHEE__General_Settings_Admin_Page__delete_state__state_deleted',
1063
-                $CNT_ISO,
1064
-                $STA_ID,
1065
-                array('STA_abbrev' => $STA_abbrev)
1066
-            );
1067
-            EE_Error::add_success(esc_html__('The State was deleted successfully.', 'event_espresso'));
1068
-        }
1069
-        if (defined('DOING_AJAX')) {
1070
-            $notices = EE_Error::get_notices(false, false);
1071
-            $notices['return_data'] = true;
1072
-            echo wp_json_encode($notices);
1073
-            die();
1074
-        } else {
1075
-            $this->_redirect_after_action(
1076
-                $success,
1077
-                'State',
1078
-                'deleted',
1079
-                array('action' => 'country_settings')
1080
-            );
1081
-        }
1082
-    }
1083
-
1084
-
1085
-    /**
1086
-     *        _update_country_settings
1087
-     *
1088
-     * @access    protected
1089
-     * @return void
1090
-     * @throws EE_Error
1091
-     * @throws InvalidArgumentException
1092
-     * @throws InvalidDataTypeException
1093
-     * @throws InvalidInterfaceException
1094
-     */
1095
-    protected function _update_country_settings()
1096
-    {
1097
-        // grab the country ISO code
1098
-        $CNT_ISO = isset($this->_req_data['country'])
1099
-            ? strtoupper(sanitize_text_field($this->_req_data['country']))
1100
-            : false;
1101
-        if (! $CNT_ISO) {
1102
-            EE_Error::add_error(
1103
-                esc_html__('No Country ISO code or an invalid Country ISO code was received.', 'event_espresso'),
1104
-                __FILE__,
1105
-                __FUNCTION__,
1106
-                __LINE__
1107
-            );
1108
-
1109
-            return;
1110
-        }
1111
-        $cols_n_values = array();
1112
-        $cols_n_values['CNT_ISO3'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_ISO3'])
1113
-            ? strtoupper(sanitize_text_field($this->_req_data['cntry'][ $CNT_ISO ]['CNT_ISO3']))
1114
-            : false;
1115
-        $cols_n_values['RGN_ID'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['RGN_ID'])
1116
-            ? absint($this->_req_data['cntry'][ $CNT_ISO ]['RGN_ID'])
1117
-            : null;
1118
-        $cols_n_values['CNT_name'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_name'])
1119
-            ? sanitize_text_field($this->_req_data['cntry'][ $CNT_ISO ]['CNT_name'])
1120
-            : null;
1121
-        if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_code'])) {
1122
-            $cols_n_values['CNT_cur_code'] = strtoupper(
1123
-                sanitize_text_field($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_code'])
1124
-            );
1125
-        }
1126
-        if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_single'])) {
1127
-            $cols_n_values['CNT_cur_single'] = sanitize_text_field(
1128
-                $this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_single']
1129
-            );
1130
-        }
1131
-        if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_plural'])) {
1132
-            $cols_n_values['CNT_cur_plural'] = sanitize_text_field(
1133
-                $this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_plural']
1134
-            );
1135
-        }
1136
-        if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_sign'])) {
1137
-            $cols_n_values['CNT_cur_sign'] = sanitize_text_field(
1138
-                $this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_sign']
1139
-            );
1140
-        }
1141
-        if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_sign_b4'])) {
1142
-            $cols_n_values['CNT_cur_sign_b4'] = absint(
1143
-                $this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_sign_b4']
1144
-            );
1145
-        }
1146
-        if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_dec_plc'])) {
1147
-            $cols_n_values['CNT_cur_dec_plc'] = absint(
1148
-                $this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_dec_plc']
1149
-            );
1150
-        }
1151
-        if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_dec_mrk'])) {
1152
-            $cols_n_values['CNT_cur_dec_mrk'] = sanitize_text_field(
1153
-                $this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_dec_mrk']
1154
-            );
1155
-        }
1156
-        if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_thsnds'])) {
1157
-            $cols_n_values['CNT_cur_thsnds'] = sanitize_text_field(
1158
-                $this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_thsnds']
1159
-            );
1160
-        }
1161
-        $cols_n_values['CNT_tel_code'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_tel_code'])
1162
-            ? sanitize_text_field($this->_req_data['cntry'][ $CNT_ISO ]['CNT_tel_code'])
1163
-            : null;
1164
-        $cols_n_values['CNT_is_EU'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_is_EU'])
1165
-            ? absint($this->_req_data['cntry'][ $CNT_ISO ]['CNT_is_EU'])
1166
-            : false;
1167
-        $cols_n_values['CNT_active'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_active'])
1168
-            ? absint($this->_req_data['cntry'][ $CNT_ISO ]['CNT_active'])
1169
-            : false;
1170
-        // allow filtering of country data
1171
-        $cols_n_values = apply_filters(
1172
-            'FHEE__General_Settings_Admin_Page___update_country_settings__cols_n_values',
1173
-            $cols_n_values
1174
-        );
1175
-
1176
-        // where values
1177
-        $where_cols_n_values = array(array('CNT_ISO' => $CNT_ISO));
1178
-        // run the update
1179
-        $success = EEM_Country::instance()->update($cols_n_values, $where_cols_n_values);
1180
-
1181
-        if (isset($this->_req_data['states']) && is_array($this->_req_data['states']) && $success !== false) {
1182
-            // allow filtering of states data
1183
-            $states = apply_filters(
1184
-                'FHEE__General_Settings_Admin_Page___update_country_settings__states',
1185
-                $this->_req_data['states']
1186
-            );
1187
-
1188
-            // loop thru state data ( looks like : states[75][STA_name] )
1189
-            foreach ($states as $STA_ID => $state) {
1190
-                $cols_n_values = array(
1191
-                    'CNT_ISO'    => $CNT_ISO,
1192
-                    'STA_abbrev' => sanitize_text_field($state['STA_abbrev']),
1193
-                    'STA_name'   => sanitize_text_field($state['STA_name']),
1194
-                    'STA_active' => (bool) absint($state['STA_active']),
1195
-                );
1196
-                // where values
1197
-                $where_cols_n_values = array(array('STA_ID' => $STA_ID));
1198
-                // run the update
1199
-                $success = EEM_State::instance()->update($cols_n_values, $where_cols_n_values);
1200
-                if ($success !== false) {
1201
-                    do_action(
1202
-                        'AHEE__General_Settings_Admin_Page__update_country_settings__state_saved',
1203
-                        $CNT_ISO,
1204
-                        $STA_ID,
1205
-                        $cols_n_values
1206
-                    );
1207
-                }
1208
-            }
1209
-        }
1210
-        // check if country being edited matches org option country, and if so, then  update EE_Config with new settings
1211
-        if (
1212
-            isset(EE_Registry::instance()->CFG->organization->CNT_ISO)
1213
-            && $CNT_ISO == EE_Registry::instance()->CFG->organization->CNT_ISO
1214
-        ) {
1215
-            EE_Registry::instance()->CFG->currency = new EE_Currency_Config($CNT_ISO);
1216
-            EE_Registry::instance()->CFG->update_espresso_config();
1217
-        }
1218
-
1219
-        if ($success !== false) {
1220
-            EE_Error::add_success(
1221
-                esc_html__('Country Settings updated successfully.', 'event_espresso')
1222
-            );
1223
-        }
1224
-        $this->_redirect_after_action(
1225
-            $success,
1226
-            '',
1227
-            '',
1228
-            array('action' => 'country_settings', 'country' => $CNT_ISO),
1229
-            true
1230
-        );
1231
-    }
1232
-
1233
-
1234
-    /**
1235
-     *        form_form_field_label_wrap
1236
-     *
1237
-     * @access        public
1238
-     * @param        string $label
1239
-     * @return        string
1240
-     */
1241
-    public function country_form_field_label_wrap($label, $required_text)
1242
-    {
1243
-        return '
22
+	/**
23
+	 * _question_group
24
+	 * holds the specific question group object for the question group details screen
25
+	 *
26
+	 * @var object
27
+	 */
28
+	protected $_question_group;
29
+
30
+
31
+	/**
32
+	 * Initialize basic properties.
33
+	 */
34
+	protected function _init_page_props()
35
+	{
36
+		$this->page_slug = GEN_SET_PG_SLUG;
37
+		$this->page_label = GEN_SET_LABEL;
38
+		$this->_admin_base_url = GEN_SET_ADMIN_URL;
39
+		$this->_admin_base_path = GEN_SET_ADMIN;
40
+	}
41
+
42
+
43
+	/**
44
+	 * Set ajax hooks
45
+	 */
46
+	protected function _ajax_hooks()
47
+	{
48
+		add_action('wp_ajax_espresso_display_country_settings', array($this, 'display_country_settings'));
49
+		add_action('wp_ajax_espresso_display_country_states', array($this, 'display_country_states'));
50
+		add_action('wp_ajax_espresso_delete_state', array($this, 'delete_state'), 10, 3);
51
+		add_action('wp_ajax_espresso_add_new_state', array($this, 'add_new_state'));
52
+	}
53
+
54
+
55
+	/**
56
+	 * More page properties initialization.
57
+	 */
58
+	protected function _define_page_props()
59
+	{
60
+		$this->_admin_page_title = GEN_SET_LABEL;
61
+		$this->_labels = array(
62
+			'publishbox' => esc_html__('Update Settings', 'event_espresso'),
63
+		);
64
+	}
65
+
66
+
67
+	/**
68
+	 * Set page routes property.
69
+	 */
70
+	protected function _set_page_routes()
71
+	{
72
+		$this->_page_routes = array(
73
+
74
+			'critical_pages'                => array(
75
+				'func'       => '_espresso_page_settings',
76
+				'capability' => 'manage_options',
77
+			),
78
+			'update_espresso_page_settings' => array(
79
+				'func'       => '_update_espresso_page_settings',
80
+				'capability' => 'manage_options',
81
+				'noheader'   => true,
82
+			),
83
+			'default'                       => array(
84
+				'func'       => '_your_organization_settings',
85
+				'capability' => 'manage_options',
86
+			),
87
+
88
+			'update_your_organization_settings' => array(
89
+				'func'       => '_update_your_organization_settings',
90
+				'capability' => 'manage_options',
91
+				'noheader'   => true,
92
+			),
93
+
94
+			'admin_option_settings' => array(
95
+				'func'       => '_admin_option_settings',
96
+				'capability' => 'manage_options',
97
+			),
98
+
99
+			'update_admin_option_settings' => array(
100
+				'func'       => '_update_admin_option_settings',
101
+				'capability' => 'manage_options',
102
+				'noheader'   => true,
103
+			),
104
+
105
+			'country_settings' => array(
106
+				'func'       => '_country_settings',
107
+				'capability' => 'manage_options',
108
+			),
109
+
110
+			'update_country_settings' => array(
111
+				'func'       => '_update_country_settings',
112
+				'capability' => 'manage_options',
113
+				'noheader'   => true,
114
+			),
115
+
116
+			'display_country_settings' => array(
117
+				'func'       => 'display_country_settings',
118
+				'capability' => 'manage_options',
119
+				'noheader'   => true,
120
+			),
121
+
122
+			'add_new_state' => array(
123
+				'func'       => 'add_new_state',
124
+				'capability' => 'manage_options',
125
+				'noheader'   => true,
126
+			),
127
+
128
+			'delete_state'            => array(
129
+				'func'       => 'delete_state',
130
+				'capability' => 'manage_options',
131
+				'noheader'   => true,
132
+			),
133
+			'privacy_settings'        => array(
134
+				'func'       => 'privacySettings',
135
+				'capability' => 'manage_options',
136
+			),
137
+			'update_privacy_settings' => array(
138
+				'func'               => 'updatePrivacySettings',
139
+				'capability'         => 'manage_options',
140
+				'noheader'           => true,
141
+				'headers_sent_route' => 'privacy_settings',
142
+			),
143
+		);
144
+	}
145
+
146
+
147
+	/**
148
+	 * Set page configuration property
149
+	 */
150
+	protected function _set_page_config()
151
+	{
152
+		$this->_page_config = array(
153
+			'critical_pages'        => array(
154
+				'nav'           => array(
155
+					'label' => esc_html__('Critical Pages', 'event_espresso'),
156
+					'order' => 50,
157
+				),
158
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
159
+				'help_tabs'     => array(
160
+					'general_settings_critical_pages_help_tab' => array(
161
+						'title'    => esc_html__('Critical Pages', 'event_espresso'),
162
+						'filename' => 'general_settings_critical_pages',
163
+					),
164
+				),
165
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
166
+				// 'help_tour'     => array('Critical_Pages_Help_Tour'),
167
+				'require_nonce' => false,
168
+			),
169
+			'default'               => array(
170
+				'nav'           => array(
171
+					'label' => esc_html__('Your Organization', 'event_espresso'),
172
+					'order' => 20,
173
+				),
174
+				'help_tabs'     => array(
175
+					'general_settings_your_organization_help_tab' => array(
176
+						'title'    => esc_html__('Your Organization', 'event_espresso'),
177
+						'filename' => 'general_settings_your_organization',
178
+					),
179
+				),
180
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
181
+				// 'help_tour'     => array('Your_Organization_Help_Tour'),
182
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
183
+				'require_nonce' => false,
184
+			),
185
+			'admin_option_settings' => array(
186
+				'nav'           => array(
187
+					'label' => esc_html__('Admin Options', 'event_espresso'),
188
+					'order' => 60,
189
+				),
190
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
191
+				'help_tabs'     => array(
192
+					'general_settings_admin_options_help_tab' => array(
193
+						'title'    => esc_html__('Admin Options', 'event_espresso'),
194
+						'filename' => 'general_settings_admin_options',
195
+					),
196
+				),
197
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
198
+				// 'help_tour'     => array('Admin_Options_Help_Tour'),
199
+				'require_nonce' => false,
200
+			),
201
+			'country_settings'      => array(
202
+				'nav'           => array(
203
+					'label' => esc_html__('Countries', 'event_espresso'),
204
+					'order' => 70,
205
+				),
206
+				'help_tabs'     => array(
207
+					'general_settings_countries_help_tab' => array(
208
+						'title'    => esc_html__('Countries', 'event_espresso'),
209
+						'filename' => 'general_settings_countries',
210
+					),
211
+				),
212
+				// disabled temporarily. see: https://github.com/eventespresso/eventsmart.com-website/issues/836
213
+				// 'help_tour'     => array('Countries_Help_Tour'),
214
+				'require_nonce' => false,
215
+			),
216
+			'privacy_settings'      => array(
217
+				'nav'           => array(
218
+					'label' => esc_html__('Privacy', 'event_espresso'),
219
+					'order' => 80,
220
+				),
221
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
222
+				'require_nonce' => false,
223
+			),
224
+		);
225
+	}
226
+
227
+
228
+	protected function _add_screen_options()
229
+	{
230
+	}
231
+
232
+
233
+	protected function _add_feature_pointers()
234
+	{
235
+	}
236
+
237
+
238
+	/**
239
+	 * Enqueue global scripts and styles for all routes in the General Settings Admin Pages.
240
+	 */
241
+	public function load_scripts_styles()
242
+	{
243
+		// styles
244
+		wp_enqueue_style('espresso-ui-theme');
245
+		// scripts
246
+		wp_enqueue_script('ee_admin_js');
247
+	}
248
+
249
+
250
+	/**
251
+	 * Execute logic running on `admin_init`
252
+	 */
253
+	public function admin_init()
254
+	{
255
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = wp_strip_all_tags(__(
256
+			'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.',
257
+			'event_espresso'
258
+		));
259
+		EE_Registry::$i18n_js_strings['error_occurred'] = wp_strip_all_tags(__(
260
+			'An error occurred! Please refresh the page and try again.',
261
+			'event_espresso'
262
+		));
263
+		EE_Registry::$i18n_js_strings['confirm_delete_state'] = wp_strip_all_tags(__(
264
+			'Are you sure you want to delete this State / Province?',
265
+			'event_espresso'
266
+		));
267
+		$protocol = is_ssl() ? 'https://' : 'http://';
268
+		EE_Registry::$i18n_js_strings['ajax_url'] = admin_url(
269
+			'admin-ajax.php?page=espresso_general_settings',
270
+			$protocol
271
+		);
272
+	}
273
+
274
+
275
+	public function admin_notices()
276
+	{
277
+	}
278
+
279
+
280
+	public function admin_footer_scripts()
281
+	{
282
+	}
283
+
284
+
285
+	/**
286
+	 * Enqueue scripts and styles for the default route.
287
+	 */
288
+	public function load_scripts_styles_default()
289
+	{
290
+		// styles
291
+		wp_enqueue_style('thickbox');
292
+		// scripts
293
+		wp_enqueue_script('media-upload');
294
+		wp_enqueue_script('thickbox');
295
+		wp_register_script(
296
+			'organization_settings',
297
+			GEN_SET_ASSETS_URL . 'your_organization_settings.js',
298
+			array('jquery', 'media-upload', 'thickbox'),
299
+			EVENT_ESPRESSO_VERSION,
300
+			true
301
+		);
302
+		wp_register_style('organization-css', GEN_SET_ASSETS_URL . 'organization.css', array(), EVENT_ESPRESSO_VERSION);
303
+		wp_enqueue_script('organization_settings');
304
+		wp_enqueue_style('organization-css');
305
+		$confirm_image_delete = array(
306
+			'text' => wp_strip_all_tags(
307
+				__(
308
+					'Do you really want to delete this image? Please remember to save your settings to complete the removal.',
309
+					'event_espresso'
310
+				)
311
+			),
312
+		);
313
+		wp_localize_script('organization_settings', 'confirm_image_delete', $confirm_image_delete);
314
+	}
315
+
316
+
317
+	/**
318
+	 * Enqueue scripts and styles for the country settings route.
319
+	 */
320
+	public function load_scripts_styles_country_settings()
321
+	{
322
+		// scripts
323
+		wp_register_script(
324
+			'gen_settings_countries',
325
+			GEN_SET_ASSETS_URL . 'gen_settings_countries.js',
326
+			array('ee_admin_js'),
327
+			EVENT_ESPRESSO_VERSION,
328
+			true
329
+		);
330
+		wp_register_style('organization-css', GEN_SET_ASSETS_URL . 'organization.css', array(), EVENT_ESPRESSO_VERSION);
331
+		wp_enqueue_script('gen_settings_countries');
332
+		wp_enqueue_style('organization-css');
333
+	}
334
+
335
+
336
+	/*************        Espresso Pages        *************/
337
+	/**
338
+	 * _espresso_page_settings
339
+	 *
340
+	 * @throws \EE_Error
341
+	 * @throws DomainException
342
+	 * @throws DomainException
343
+	 * @throws InvalidDataTypeException
344
+	 * @throws InvalidArgumentException
345
+	 */
346
+	protected function _espresso_page_settings()
347
+	{
348
+		// Check to make sure all of the main pages are setup properly,
349
+		// if not create the default pages and display an admin notice
350
+		EEH_Activation::verify_default_pages_exist();
351
+		$this->_transient_garbage_collection();
352
+		$this->_template_args['values'] = $this->_yes_no_values;
353
+		$this->_template_args['reg_page_id'] = isset(EE_Registry::instance()->CFG->core->reg_page_id)
354
+			? EE_Registry::instance()->CFG->core->reg_page_id
355
+			: null;
356
+		$this->_template_args['reg_page_obj'] = isset(EE_Registry::instance()->CFG->core->reg_page_id)
357
+			? get_page(EE_Registry::instance()->CFG->core->reg_page_id)
358
+			: false;
359
+		$this->_template_args['txn_page_id'] = isset(EE_Registry::instance()->CFG->core->txn_page_id)
360
+			? EE_Registry::instance()->CFG->core->txn_page_id
361
+			: null;
362
+		$this->_template_args['txn_page_obj'] = isset(EE_Registry::instance()->CFG->core->txn_page_id)
363
+			? get_page(EE_Registry::instance()->CFG->core->txn_page_id)
364
+			: false;
365
+		$this->_template_args['thank_you_page_id'] = isset(EE_Registry::instance()->CFG->core->thank_you_page_id)
366
+			? EE_Registry::instance()->CFG->core->thank_you_page_id
367
+			: null;
368
+		$this->_template_args['thank_you_page_obj'] = isset(EE_Registry::instance()->CFG->core->thank_you_page_id)
369
+			? get_page(EE_Registry::instance()->CFG->core->thank_you_page_id)
370
+			: false;
371
+		$this->_template_args['cancel_page_id'] = isset(EE_Registry::instance()->CFG->core->cancel_page_id)
372
+			? EE_Registry::instance()->CFG->core->cancel_page_id
373
+			: null;
374
+		$this->_template_args['cancel_page_obj'] = isset(EE_Registry::instance()->CFG->core->cancel_page_id)
375
+			? get_page(EE_Registry::instance()->CFG->core->cancel_page_id)
376
+			: false;
377
+		$this->_set_add_edit_form_tags('update_espresso_page_settings');
378
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
379
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
380
+			GEN_SET_TEMPLATE_PATH . 'espresso_page_settings.template.php',
381
+			$this->_template_args,
382
+			true
383
+		);
384
+		$this->display_admin_page_with_sidebar();
385
+	}
386
+
387
+
388
+	/**
389
+	 * Handler for updating espresso page settings.
390
+	 *
391
+	 * @throws EE_Error
392
+	 */
393
+	protected function _update_espresso_page_settings()
394
+	{
395
+		// capture incoming request data && set page IDs
396
+		EE_Registry::instance()->CFG->core->reg_page_id = isset($this->_req_data['reg_page_id'])
397
+			? absint($this->_req_data['reg_page_id'])
398
+			: EE_Registry::instance()->CFG->core->reg_page_id;
399
+		EE_Registry::instance()->CFG->core->txn_page_id = isset($this->_req_data['txn_page_id'])
400
+			? absint($this->_req_data['txn_page_id'])
401
+			: EE_Registry::instance()->CFG->core->txn_page_id;
402
+		EE_Registry::instance()->CFG->core->thank_you_page_id = isset($this->_req_data['thank_you_page_id'])
403
+			? absint($this->_req_data['thank_you_page_id'])
404
+			: EE_Registry::instance()->CFG->core->thank_you_page_id;
405
+		EE_Registry::instance()->CFG->core->cancel_page_id = isset($this->_req_data['cancel_page_id'])
406
+			? absint($this->_req_data['cancel_page_id'])
407
+			: EE_Registry::instance()->CFG->core->cancel_page_id;
408
+
409
+		EE_Registry::instance()->CFG->core = apply_filters(
410
+			'FHEE__General_Settings_Admin_Page___update_espresso_page_settings__CFG_core',
411
+			EE_Registry::instance()->CFG->core,
412
+			$this->_req_data
413
+		);
414
+		$what = esc_html__('Critical Pages & Shortcodes', 'event_espresso');
415
+		$this->_redirect_after_action(
416
+			$this->_update_espresso_configuration(
417
+				$what,
418
+				EE_Registry::instance()->CFG->core,
419
+				__FILE__,
420
+				__FUNCTION__,
421
+				__LINE__
422
+			),
423
+			$what,
424
+			'',
425
+			array(
426
+				'action' => 'critical_pages',
427
+			),
428
+			true
429
+		);
430
+	}
431
+
432
+
433
+	/*************        Your Organization        *************/
434
+
435
+
436
+	/**
437
+	 * @throws DomainException
438
+	 * @throws EE_Error
439
+	 * @throws InvalidArgumentException
440
+	 * @throws InvalidDataTypeException
441
+	 * @throws InvalidInterfaceException
442
+	 */
443
+	protected function _your_organization_settings()
444
+	{
445
+		$this->_template_args['admin_page_content'] = '';
446
+		try {
447
+			/** @var EventEspresso\admin_pages\general_settings\OrganizationSettings $organization_settings_form */
448
+			$organization_settings_form = $this->loader->getShared(
449
+				'EventEspresso\admin_pages\general_settings\OrganizationSettings'
450
+			);
451
+			$this->_template_args['admin_page_content'] = $organization_settings_form->display();
452
+		} catch (Exception $e) {
453
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
454
+		}
455
+		$this->_set_add_edit_form_tags('update_your_organization_settings');
456
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
457
+		$this->display_admin_page_with_sidebar();
458
+	}
459
+
460
+
461
+	/**
462
+	 * Handler for updating organization settings.
463
+	 *
464
+	 * @throws EE_Error
465
+	 */
466
+	protected function _update_your_organization_settings()
467
+	{
468
+		try {
469
+			/** @var EventEspresso\admin_pages\general_settings\OrganizationSettings $organization_settings_form */
470
+			$organization_settings_form = $this->loader->getShared(
471
+				'EventEspresso\admin_pages\general_settings\OrganizationSettings'
472
+			);
473
+			$success = $organization_settings_form->process($this->_req_data);
474
+			EE_Registry::instance()->CFG = apply_filters(
475
+				'FHEE__General_Settings_Admin_Page___update_your_organization_settings__CFG',
476
+				EE_Registry::instance()->CFG
477
+			);
478
+		} catch (Exception $e) {
479
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
480
+			$success = false;
481
+		}
482
+
483
+		if ($success) {
484
+			$success = $this->_update_espresso_configuration(
485
+				esc_html__('Your Organization Settings', 'event_espresso'),
486
+				EE_Registry::instance()->CFG,
487
+				__FILE__,
488
+				__FUNCTION__,
489
+				__LINE__
490
+			);
491
+		}
492
+
493
+		$this->_redirect_after_action($success, '', '', array('action' => 'default'), true);
494
+	}
495
+
496
+
497
+
498
+	/*************        Admin Options        *************/
499
+
500
+
501
+	/**
502
+	 * _admin_option_settings
503
+	 *
504
+	 * @throws \EE_Error
505
+	 * @throws \LogicException
506
+	 */
507
+	protected function _admin_option_settings()
508
+	{
509
+		$this->_template_args['admin_page_content'] = '';
510
+		try {
511
+			$admin_options_settings_form = new AdminOptionsSettings(EE_Registry::instance());
512
+			// still need this for the old school form in Extend_General_Settings_Admin_Page
513
+			$this->_template_args['values'] = $this->_yes_no_values;
514
+			// also need to account for the do_action that was in the old template
515
+			$admin_options_settings_form->setTemplateArgs($this->_template_args);
516
+			$this->_template_args['admin_page_content'] = $admin_options_settings_form->display();
517
+		} catch (Exception $e) {
518
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
519
+		}
520
+		$this->_set_add_edit_form_tags('update_admin_option_settings');
521
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
522
+		$this->display_admin_page_with_sidebar();
523
+	}
524
+
525
+
526
+	/**
527
+	 * _update_admin_option_settings
528
+	 *
529
+	 * @throws \EE_Error
530
+	 * @throws InvalidDataTypeException
531
+	 * @throws \EventEspresso\core\exceptions\InvalidFormSubmissionException
532
+	 * @throws \InvalidArgumentException
533
+	 * @throws \LogicException
534
+	 */
535
+	protected function _update_admin_option_settings()
536
+	{
537
+		try {
538
+			$admin_options_settings_form = new AdminOptionsSettings(EE_Registry::instance());
539
+			$admin_options_settings_form->process($this->_req_data[ $admin_options_settings_form->slug() ]);
540
+			EE_Registry::instance()->CFG->admin = apply_filters(
541
+				'FHEE__General_Settings_Admin_Page___update_admin_option_settings__CFG_admin',
542
+				EE_Registry::instance()->CFG->admin
543
+			);
544
+		} catch (Exception $e) {
545
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
546
+		}
547
+		$this->_redirect_after_action(
548
+			apply_filters(
549
+				'FHEE__General_Settings_Admin_Page___update_admin_option_settings__success',
550
+				$this->_update_espresso_configuration(
551
+					'Admin Options',
552
+					EE_Registry::instance()->CFG->admin,
553
+					__FILE__,
554
+					__FUNCTION__,
555
+					__LINE__
556
+				)
557
+			),
558
+			'Admin Options',
559
+			'updated',
560
+			array('action' => 'admin_option_settings')
561
+		);
562
+	}
563
+
564
+
565
+	/*************        Countries        *************/
566
+
567
+
568
+	/**
569
+	 * @return string
570
+	 */
571
+	protected function getCountryIsoForSite()
572
+	{
573
+		return ! empty(EE_Registry::instance()->CFG->organization->CNT_ISO)
574
+			? EE_Registry::instance()->CFG->organization->CNT_ISO
575
+			: 'US';
576
+	}
577
+
578
+
579
+	/**
580
+	 * @param string          $CNT_ISO
581
+	 * @param EE_Country|null $country
582
+	 * @return EE_Base_Class|EE_Country
583
+	 * @throws EE_Error
584
+	 * @throws InvalidArgumentException
585
+	 * @throws InvalidDataTypeException
586
+	 * @throws InvalidInterfaceException
587
+	 * @throws ReflectionException
588
+	 */
589
+	protected function verifyOrGetCountryFromIso($CNT_ISO, EE_Country $country = null)
590
+	{
591
+		/** @var EE_Country $country */
592
+		return $country instanceof EE_Country && $country->ID() === $CNT_ISO
593
+			? $country
594
+			: EEM_Country::instance()->get_one_by_ID($CNT_ISO);
595
+	}
596
+
597
+
598
+	/**
599
+	 * Output Country Settings view.
600
+	 *
601
+	 * @throws DomainException
602
+	 * @throws EE_Error
603
+	 * @throws InvalidArgumentException
604
+	 * @throws InvalidDataTypeException
605
+	 * @throws InvalidInterfaceException
606
+	 * @throws ReflectionException
607
+	 */
608
+	protected function _country_settings()
609
+	{
610
+		$CNT_ISO_for_site = $this->getCountryIsoForSite();
611
+		$CNT_ISO = isset($this->_req_data['country'])
612
+			? strtoupper(sanitize_text_field($this->_req_data['country']))
613
+			: $CNT_ISO_for_site;
614
+
615
+		// load field generator helper
616
+
617
+		$this->_template_args['values'] = $this->_yes_no_values;
618
+
619
+		$this->_template_args['countries'] = new EE_Question_Form_Input(
620
+			EE_Question::new_instance(
621
+				array(
622
+					'QST_ID'           => 0,
623
+					'QST_display_text' => esc_html__('Select Country', 'event_espresso'),
624
+					'QST_system'       => 'admin-country',
625
+				)
626
+			),
627
+			EE_Answer::new_instance(
628
+				array(
629
+					'ANS_ID'    => 0,
630
+					'ANS_value' => $CNT_ISO,
631
+				)
632
+			),
633
+			array(
634
+				'input_id'       => 'country',
635
+				'input_name'     => 'country',
636
+				'input_prefix'   => '',
637
+				'append_qstn_id' => false,
638
+			)
639
+		);
640
+		$country = $this->verifyOrGetCountryFromIso($CNT_ISO_for_site);
641
+		add_filter('FHEE__EEH_Form_Fields__label_html', array($this, 'country_form_field_label_wrap'), 10, 2);
642
+		add_filter('FHEE__EEH_Form_Fields__input_html', array($this, 'country_form_field_input__wrap'), 10, 2);
643
+		$this->_template_args['country_details_settings'] = $this->display_country_settings(
644
+			$country->ID(),
645
+			$country
646
+		);
647
+		$this->_template_args['country_states_settings'] = $this->display_country_states(
648
+			$country->ID(),
649
+			$country
650
+		);
651
+		$this->_template_args['CNT_name_for_site'] = $country->name();
652
+
653
+		$this->_set_add_edit_form_tags('update_country_settings');
654
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
655
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
656
+			GEN_SET_TEMPLATE_PATH . 'countries_settings.template.php',
657
+			$this->_template_args,
658
+			true
659
+		);
660
+		$this->display_admin_page_with_no_sidebar();
661
+	}
662
+
663
+
664
+	/**
665
+	 *        display_country_settings
666
+	 *
667
+	 * @param string          $CNT_ISO
668
+	 * @param EE_Country|null $country
669
+	 * @return mixed string | array$country
670
+	 * @throws DomainException
671
+	 * @throws EE_Error
672
+	 * @throws InvalidArgumentException
673
+	 * @throws InvalidDataTypeException
674
+	 * @throws InvalidInterfaceException
675
+	 * @throws ReflectionException
676
+	 */
677
+	public function display_country_settings($CNT_ISO = '', EE_Country $country = null)
678
+	{
679
+		$CNT_ISO_for_site = $this->getCountryIsoForSite();
680
+
681
+		$CNT_ISO = isset($this->_req_data['country'])
682
+			? strtoupper(sanitize_text_field($this->_req_data['country']))
683
+			: $CNT_ISO;
684
+		if (! $CNT_ISO) {
685
+			return '';
686
+		}
687
+
688
+		// for ajax
689
+		remove_all_filters('FHEE__EEH_Form_Fields__label_html');
690
+		remove_all_filters('FHEE__EEH_Form_Fields__input_html');
691
+		add_filter('FHEE__EEH_Form_Fields__label_html', array($this, 'country_form_field_label_wrap'), 10, 2);
692
+		add_filter('FHEE__EEH_Form_Fields__input_html', array($this, 'country_form_field_input__wrap'), 10, 2);
693
+		$country = $this->verifyOrGetCountryFromIso($CNT_ISO, $country);
694
+		$CNT_cur_disabled = $CNT_ISO !== $CNT_ISO_for_site;
695
+		$this->_template_args['CNT_cur_disabled'] = $CNT_cur_disabled;
696
+
697
+		$country_input_types = array(
698
+			'CNT_active'      => array(
699
+				'type'             => 'RADIO_BTN',
700
+				'input_name'       => 'cntry[' . $CNT_ISO . ']',
701
+				'class'            => '',
702
+				'options'          => $this->_yes_no_values,
703
+				'use_desc_4_label' => true,
704
+			),
705
+			'CNT_ISO'         => array(
706
+				'type'       => 'TEXT',
707
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
708
+				'class'      => 'small-text',
709
+			),
710
+			'CNT_ISO3'        => array(
711
+				'type'       => 'TEXT',
712
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
713
+				'class'      => 'small-text',
714
+			),
715
+			'RGN_ID'          => array(
716
+				'type'       => 'TEXT',
717
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
718
+				'class'      => 'small-text',
719
+			),
720
+			'CNT_name'        => array(
721
+				'type'       => 'TEXT',
722
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
723
+				'class'      => 'regular-text',
724
+			),
725
+			'CNT_cur_code'    => array(
726
+				'type'       => 'TEXT',
727
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
728
+				'class'      => 'small-text',
729
+				'disabled'   => $CNT_cur_disabled,
730
+			),
731
+			'CNT_cur_single'  => array(
732
+				'type'       => 'TEXT',
733
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
734
+				'class'      => 'medium-text',
735
+				'disabled'   => $CNT_cur_disabled,
736
+			),
737
+			'CNT_cur_plural'  => array(
738
+				'type'       => 'TEXT',
739
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
740
+				'class'      => 'medium-text',
741
+				'disabled'   => $CNT_cur_disabled,
742
+			),
743
+			'CNT_cur_sign'    => array(
744
+				'type'         => 'TEXT',
745
+				'input_name'   => 'cntry[' . $CNT_ISO . ']',
746
+				'class'        => 'small-text',
747
+				'htmlentities' => false,
748
+				'disabled'     => $CNT_cur_disabled,
749
+			),
750
+			'CNT_cur_sign_b4' => array(
751
+				'type'             => 'RADIO_BTN',
752
+				'input_name'       => 'cntry[' . $CNT_ISO . ']',
753
+				'class'            => '',
754
+				'options'          => $this->_yes_no_values,
755
+				'use_desc_4_label' => true,
756
+				'disabled'         => $CNT_cur_disabled,
757
+			),
758
+			'CNT_cur_dec_plc' => array(
759
+				'type'       => 'RADIO_BTN',
760
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
761
+				'class'      => '',
762
+				'options'    => array(
763
+					array('id' => 0, 'text' => ''),
764
+					array('id' => 1, 'text' => ''),
765
+					array('id' => 2, 'text' => ''),
766
+					array('id' => 3, 'text' => ''),
767
+				),
768
+				'disabled'   => $CNT_cur_disabled,
769
+			),
770
+			'CNT_cur_dec_mrk' => array(
771
+				'type'             => 'RADIO_BTN',
772
+				'input_name'       => 'cntry[' . $CNT_ISO . ']',
773
+				'class'            => '',
774
+				'options'          => array(
775
+					array(
776
+						'id'   => ',',
777
+						'text' => esc_html__(', (comma)', 'event_espresso'),
778
+					),
779
+					array('id' => '.', 'text' => esc_html__('. (decimal)', 'event_espresso')),
780
+				),
781
+				'use_desc_4_label' => true,
782
+				'disabled'         => $CNT_cur_disabled,
783
+			),
784
+			'CNT_cur_thsnds'  => array(
785
+				'type'             => 'RADIO_BTN',
786
+				'input_name'       => 'cntry[' . $CNT_ISO . ']',
787
+				'class'            => '',
788
+				'options'          => array(
789
+					array(
790
+						'id'   => ',',
791
+						'text' => esc_html__(', (comma)', 'event_espresso'),
792
+					),
793
+					array(
794
+						'id' => '.',
795
+						'text' => esc_html__('. (decimal)', 'event_espresso')
796
+					),
797
+					array(
798
+						'id' => '&nbsp;',
799
+						'text' => esc_html__('(space)', 'event_espresso')
800
+					)
801
+				),
802
+				'use_desc_4_label' => true,
803
+				'disabled'         => $CNT_cur_disabled,
804
+			),
805
+			'CNT_tel_code'    => array(
806
+				'type'       => 'TEXT',
807
+				'input_name' => 'cntry[' . $CNT_ISO . ']',
808
+				'class'      => 'small-text',
809
+			),
810
+			'CNT_is_EU'       => array(
811
+				'type'             => 'RADIO_BTN',
812
+				'input_name'       => 'cntry[' . $CNT_ISO . ']',
813
+				'class'            => '',
814
+				'options'          => $this->_yes_no_values,
815
+				'use_desc_4_label' => true,
816
+			),
817
+		);
818
+		$this->_template_args['inputs'] = EE_Question_Form_Input::generate_question_form_inputs_for_object(
819
+			$country,
820
+			$country_input_types
821
+		);
822
+		$country_details_settings = EEH_Template::display_template(
823
+			GEN_SET_TEMPLATE_PATH . 'country_details_settings.template.php',
824
+			$this->_template_args,
825
+			true
826
+		);
827
+
828
+		if (defined('DOING_AJAX')) {
829
+			$notices = EE_Error::get_notices(false, false, false);
830
+			echo wp_json_encode(
831
+				array(
832
+					'return_data' => $country_details_settings,
833
+					'success'     => $notices['success'],
834
+					'errors'      => $notices['errors'],
835
+				)
836
+			);
837
+			die();
838
+		} else {
839
+			return $country_details_settings;
840
+		}
841
+	}
842
+
843
+
844
+	/**
845
+	 * @param string          $CNT_ISO
846
+	 * @param EE_Country|null $country
847
+	 * @return string
848
+	 * @throws DomainException
849
+	 * @throws EE_Error
850
+	 * @throws InvalidArgumentException
851
+	 * @throws InvalidDataTypeException
852
+	 * @throws InvalidInterfaceException
853
+	 * @throws ReflectionException
854
+	 */
855
+	public function display_country_states($CNT_ISO = '', EE_Country $country = null)
856
+	{
857
+
858
+		$CNT_ISO = isset($this->_req_data['country'])
859
+			? sanitize_text_field($this->_req_data['country'])
860
+			: $CNT_ISO;
861
+		if (! $CNT_ISO) {
862
+			return '';
863
+		}
864
+		// for ajax
865
+		remove_all_filters('FHEE__EEH_Form_Fields__label_html');
866
+		remove_all_filters('FHEE__EEH_Form_Fields__input_html');
867
+		add_filter('FHEE__EEH_Form_Fields__label_html', array($this, 'state_form_field_label_wrap'), 10, 2);
868
+		add_filter('FHEE__EEH_Form_Fields__input_html', array($this, 'state_form_field_input__wrap'), 10, 2);
869
+		$states = EEM_State::instance()->get_all_states_for_these_countries(array($CNT_ISO => $CNT_ISO));
870
+		if (empty($states)) {
871
+			/** @var EventEspresso\core\services\address\CountrySubRegionDao $countrySubRegionDao */
872
+			$countrySubRegionDao = $this->loader->getShared(
873
+				'EventEspresso\core\services\address\CountrySubRegionDao'
874
+			);
875
+			if ($countrySubRegionDao instanceof EventEspresso\core\services\address\CountrySubRegionDao) {
876
+				$country = $this->verifyOrGetCountryFromIso($CNT_ISO, $country);
877
+				if ($countrySubRegionDao->saveCountrySubRegions($country)) {
878
+					$states = EEM_State::instance()->get_all_states_for_these_countries(
879
+						array($CNT_ISO => $CNT_ISO)
880
+					);
881
+				}
882
+			}
883
+		}
884
+		if (is_array($states)) {
885
+			foreach ($states as $STA_ID => $state) {
886
+				if ($state instanceof EE_State) {
887
+					// STA_abbrev    STA_name    STA_active
888
+					$state_input_types = array(
889
+						'STA_abbrev' => array(
890
+							'type'       => 'TEXT',
891
+							'input_name' => 'states[' . $STA_ID . ']',
892
+							'class'      => 'mid-text',
893
+						),
894
+						'STA_name'   => array(
895
+							'type'       => 'TEXT',
896
+							'input_name' => 'states[' . $STA_ID . ']',
897
+							'class'      => 'regular-text',
898
+						),
899
+						'STA_active' => array(
900
+							'type'             => 'RADIO_BTN',
901
+							'input_name'       => 'states[' . $STA_ID . ']',
902
+							'options'          => $this->_yes_no_values,
903
+							'use_desc_4_label' => true,
904
+						),
905
+					);
906
+					$this->_template_args['states'][ $STA_ID ]['inputs'] =
907
+						EE_Question_Form_Input::generate_question_form_inputs_for_object(
908
+							$state,
909
+							$state_input_types
910
+						);
911
+					$query_args = array(
912
+						'action'     => 'delete_state',
913
+						'STA_ID'     => $STA_ID,
914
+						'CNT_ISO'    => $CNT_ISO,
915
+						'STA_abbrev' => $state->abbrev(),
916
+					);
917
+					$this->_template_args['states'][ $STA_ID ]['delete_state_url'] =
918
+						EE_Admin_Page::add_query_args_and_nonce(
919
+							$query_args,
920
+							GEN_SET_ADMIN_URL
921
+						);
922
+				}
923
+			}
924
+		} else {
925
+			$this->_template_args['states'] = false;
926
+		}
927
+
928
+		$this->_template_args['add_new_state_url'] = EE_Admin_Page::add_query_args_and_nonce(
929
+			array('action' => 'add_new_state'),
930
+			GEN_SET_ADMIN_URL
931
+		);
932
+
933
+		$state_details_settings = EEH_Template::display_template(
934
+			GEN_SET_TEMPLATE_PATH . 'state_details_settings.template.php',
935
+			$this->_template_args,
936
+			true
937
+		);
938
+
939
+		if (defined('DOING_AJAX')) {
940
+			$notices = EE_Error::get_notices(false, false, false);
941
+			echo wp_json_encode(
942
+				array(
943
+					'return_data' => $state_details_settings,
944
+					'success'     => $notices['success'],
945
+					'errors'      => $notices['errors'],
946
+				)
947
+			);
948
+			die();
949
+		} else {
950
+			return $state_details_settings;
951
+		}
952
+	}
953
+
954
+
955
+	/**
956
+	 *        add_new_state
957
+	 *
958
+	 * @access    public
959
+	 * @return void
960
+	 * @throws EE_Error
961
+	 * @throws InvalidArgumentException
962
+	 * @throws InvalidDataTypeException
963
+	 * @throws InvalidInterfaceException
964
+	 */
965
+	public function add_new_state()
966
+	{
967
+
968
+		$success = true;
969
+
970
+		$CNT_ISO = isset($this->_req_data['CNT_ISO'])
971
+			? strtoupper(sanitize_text_field($this->_req_data['CNT_ISO']))
972
+			: false;
973
+		if (! $CNT_ISO) {
974
+			EE_Error::add_error(
975
+				esc_html__('No Country ISO code or an invalid Country ISO code was received.', 'event_espresso'),
976
+				__FILE__,
977
+				__FUNCTION__,
978
+				__LINE__
979
+			);
980
+			$success = false;
981
+		}
982
+		$STA_abbrev = isset($this->_req_data['STA_abbrev'])
983
+			? sanitize_text_field($this->_req_data['STA_abbrev'])
984
+			: false;
985
+		if (! $STA_abbrev) {
986
+			EE_Error::add_error(
987
+				esc_html__('No State ISO code or an invalid State ISO code was received.', 'event_espresso'),
988
+				__FILE__,
989
+				__FUNCTION__,
990
+				__LINE__
991
+			);
992
+			$success = false;
993
+		}
994
+		$STA_name = isset($this->_req_data['STA_name'])
995
+			? sanitize_text_field($this->_req_data['STA_name'])
996
+			: false;
997
+		if (! $STA_name) {
998
+			EE_Error::add_error(
999
+				esc_html__('No State name or an invalid State name was received.', 'event_espresso'),
1000
+				__FILE__,
1001
+				__FUNCTION__,
1002
+				__LINE__
1003
+			);
1004
+			$success = false;
1005
+		}
1006
+
1007
+		if ($success) {
1008
+			$cols_n_values = array(
1009
+				'CNT_ISO'    => $CNT_ISO,
1010
+				'STA_abbrev' => $STA_abbrev,
1011
+				'STA_name'   => $STA_name,
1012
+				'STA_active' => true,
1013
+			);
1014
+			$success = EEM_State::instance()->insert($cols_n_values);
1015
+			EE_Error::add_success(esc_html__('The State was added successfully.', 'event_espresso'));
1016
+		}
1017
+
1018
+		if (defined('DOING_AJAX')) {
1019
+			$notices = EE_Error::get_notices(false, false, false);
1020
+			echo wp_json_encode(array_merge($notices, array('return_data' => $CNT_ISO)));
1021
+			die();
1022
+		} else {
1023
+			$this->_redirect_after_action($success, 'State', 'added', array('action' => 'country_settings'));
1024
+		}
1025
+	}
1026
+
1027
+
1028
+	/**
1029
+	 *        delete_state
1030
+	 *
1031
+	 * @access    public
1032
+	 * @return        boolean
1033
+	 * @throws EE_Error
1034
+	 * @throws InvalidArgumentException
1035
+	 * @throws InvalidDataTypeException
1036
+	 * @throws InvalidInterfaceException
1037
+	 */
1038
+	public function delete_state()
1039
+	{
1040
+		$CNT_ISO = isset($this->_req_data['CNT_ISO'])
1041
+			? strtoupper(sanitize_text_field($this->_req_data['CNT_ISO']))
1042
+			: false;
1043
+		$STA_ID = isset($this->_req_data['STA_ID'])
1044
+			? sanitize_text_field($this->_req_data['STA_ID'])
1045
+			: false;
1046
+		$STA_abbrev = isset($this->_req_data['STA_abbrev'])
1047
+			? sanitize_text_field($this->_req_data['STA_abbrev'])
1048
+			: false;
1049
+		if (! $STA_ID) {
1050
+			EE_Error::add_error(
1051
+				esc_html__('No State ID or an invalid State ID was received.', 'event_espresso'),
1052
+				__FILE__,
1053
+				__FUNCTION__,
1054
+				__LINE__
1055
+			);
1056
+			return false;
1057
+		}
1058
+
1059
+		$success = EEM_State::instance()->delete_by_ID($STA_ID);
1060
+		if ($success !== false) {
1061
+			do_action(
1062
+				'AHEE__General_Settings_Admin_Page__delete_state__state_deleted',
1063
+				$CNT_ISO,
1064
+				$STA_ID,
1065
+				array('STA_abbrev' => $STA_abbrev)
1066
+			);
1067
+			EE_Error::add_success(esc_html__('The State was deleted successfully.', 'event_espresso'));
1068
+		}
1069
+		if (defined('DOING_AJAX')) {
1070
+			$notices = EE_Error::get_notices(false, false);
1071
+			$notices['return_data'] = true;
1072
+			echo wp_json_encode($notices);
1073
+			die();
1074
+		} else {
1075
+			$this->_redirect_after_action(
1076
+				$success,
1077
+				'State',
1078
+				'deleted',
1079
+				array('action' => 'country_settings')
1080
+			);
1081
+		}
1082
+	}
1083
+
1084
+
1085
+	/**
1086
+	 *        _update_country_settings
1087
+	 *
1088
+	 * @access    protected
1089
+	 * @return void
1090
+	 * @throws EE_Error
1091
+	 * @throws InvalidArgumentException
1092
+	 * @throws InvalidDataTypeException
1093
+	 * @throws InvalidInterfaceException
1094
+	 */
1095
+	protected function _update_country_settings()
1096
+	{
1097
+		// grab the country ISO code
1098
+		$CNT_ISO = isset($this->_req_data['country'])
1099
+			? strtoupper(sanitize_text_field($this->_req_data['country']))
1100
+			: false;
1101
+		if (! $CNT_ISO) {
1102
+			EE_Error::add_error(
1103
+				esc_html__('No Country ISO code or an invalid Country ISO code was received.', 'event_espresso'),
1104
+				__FILE__,
1105
+				__FUNCTION__,
1106
+				__LINE__
1107
+			);
1108
+
1109
+			return;
1110
+		}
1111
+		$cols_n_values = array();
1112
+		$cols_n_values['CNT_ISO3'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_ISO3'])
1113
+			? strtoupper(sanitize_text_field($this->_req_data['cntry'][ $CNT_ISO ]['CNT_ISO3']))
1114
+			: false;
1115
+		$cols_n_values['RGN_ID'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['RGN_ID'])
1116
+			? absint($this->_req_data['cntry'][ $CNT_ISO ]['RGN_ID'])
1117
+			: null;
1118
+		$cols_n_values['CNT_name'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_name'])
1119
+			? sanitize_text_field($this->_req_data['cntry'][ $CNT_ISO ]['CNT_name'])
1120
+			: null;
1121
+		if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_code'])) {
1122
+			$cols_n_values['CNT_cur_code'] = strtoupper(
1123
+				sanitize_text_field($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_code'])
1124
+			);
1125
+		}
1126
+		if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_single'])) {
1127
+			$cols_n_values['CNT_cur_single'] = sanitize_text_field(
1128
+				$this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_single']
1129
+			);
1130
+		}
1131
+		if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_plural'])) {
1132
+			$cols_n_values['CNT_cur_plural'] = sanitize_text_field(
1133
+				$this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_plural']
1134
+			);
1135
+		}
1136
+		if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_sign'])) {
1137
+			$cols_n_values['CNT_cur_sign'] = sanitize_text_field(
1138
+				$this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_sign']
1139
+			);
1140
+		}
1141
+		if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_sign_b4'])) {
1142
+			$cols_n_values['CNT_cur_sign_b4'] = absint(
1143
+				$this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_sign_b4']
1144
+			);
1145
+		}
1146
+		if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_dec_plc'])) {
1147
+			$cols_n_values['CNT_cur_dec_plc'] = absint(
1148
+				$this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_dec_plc']
1149
+			);
1150
+		}
1151
+		if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_dec_mrk'])) {
1152
+			$cols_n_values['CNT_cur_dec_mrk'] = sanitize_text_field(
1153
+				$this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_dec_mrk']
1154
+			);
1155
+		}
1156
+		if (isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_thsnds'])) {
1157
+			$cols_n_values['CNT_cur_thsnds'] = sanitize_text_field(
1158
+				$this->_req_data['cntry'][ $CNT_ISO ]['CNT_cur_thsnds']
1159
+			);
1160
+		}
1161
+		$cols_n_values['CNT_tel_code'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_tel_code'])
1162
+			? sanitize_text_field($this->_req_data['cntry'][ $CNT_ISO ]['CNT_tel_code'])
1163
+			: null;
1164
+		$cols_n_values['CNT_is_EU'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_is_EU'])
1165
+			? absint($this->_req_data['cntry'][ $CNT_ISO ]['CNT_is_EU'])
1166
+			: false;
1167
+		$cols_n_values['CNT_active'] = isset($this->_req_data['cntry'][ $CNT_ISO ]['CNT_active'])
1168
+			? absint($this->_req_data['cntry'][ $CNT_ISO ]['CNT_active'])
1169
+			: false;
1170
+		// allow filtering of country data
1171
+		$cols_n_values = apply_filters(
1172
+			'FHEE__General_Settings_Admin_Page___update_country_settings__cols_n_values',
1173
+			$cols_n_values
1174
+		);
1175
+
1176
+		// where values
1177
+		$where_cols_n_values = array(array('CNT_ISO' => $CNT_ISO));
1178
+		// run the update
1179
+		$success = EEM_Country::instance()->update($cols_n_values, $where_cols_n_values);
1180
+
1181
+		if (isset($this->_req_data['states']) && is_array($this->_req_data['states']) && $success !== false) {
1182
+			// allow filtering of states data
1183
+			$states = apply_filters(
1184
+				'FHEE__General_Settings_Admin_Page___update_country_settings__states',
1185
+				$this->_req_data['states']
1186
+			);
1187
+
1188
+			// loop thru state data ( looks like : states[75][STA_name] )
1189
+			foreach ($states as $STA_ID => $state) {
1190
+				$cols_n_values = array(
1191
+					'CNT_ISO'    => $CNT_ISO,
1192
+					'STA_abbrev' => sanitize_text_field($state['STA_abbrev']),
1193
+					'STA_name'   => sanitize_text_field($state['STA_name']),
1194
+					'STA_active' => (bool) absint($state['STA_active']),
1195
+				);
1196
+				// where values
1197
+				$where_cols_n_values = array(array('STA_ID' => $STA_ID));
1198
+				// run the update
1199
+				$success = EEM_State::instance()->update($cols_n_values, $where_cols_n_values);
1200
+				if ($success !== false) {
1201
+					do_action(
1202
+						'AHEE__General_Settings_Admin_Page__update_country_settings__state_saved',
1203
+						$CNT_ISO,
1204
+						$STA_ID,
1205
+						$cols_n_values
1206
+					);
1207
+				}
1208
+			}
1209
+		}
1210
+		// check if country being edited matches org option country, and if so, then  update EE_Config with new settings
1211
+		if (
1212
+			isset(EE_Registry::instance()->CFG->organization->CNT_ISO)
1213
+			&& $CNT_ISO == EE_Registry::instance()->CFG->organization->CNT_ISO
1214
+		) {
1215
+			EE_Registry::instance()->CFG->currency = new EE_Currency_Config($CNT_ISO);
1216
+			EE_Registry::instance()->CFG->update_espresso_config();
1217
+		}
1218
+
1219
+		if ($success !== false) {
1220
+			EE_Error::add_success(
1221
+				esc_html__('Country Settings updated successfully.', 'event_espresso')
1222
+			);
1223
+		}
1224
+		$this->_redirect_after_action(
1225
+			$success,
1226
+			'',
1227
+			'',
1228
+			array('action' => 'country_settings', 'country' => $CNT_ISO),
1229
+			true
1230
+		);
1231
+	}
1232
+
1233
+
1234
+	/**
1235
+	 *        form_form_field_label_wrap
1236
+	 *
1237
+	 * @access        public
1238
+	 * @param        string $label
1239
+	 * @return        string
1240
+	 */
1241
+	public function country_form_field_label_wrap($label, $required_text)
1242
+	{
1243
+		return '
1244 1244
 			<tr>
1245 1245
 				<th>
1246 1246
 					' . $label . '
1247 1247
 				</th>';
1248
-    }
1249
-
1250
-
1251
-    /**
1252
-     *        form_form_field_input__wrap
1253
-     *
1254
-     * @access        public
1255
-     * @param        string $label
1256
-     * @return        string
1257
-     */
1258
-    public function country_form_field_input__wrap($input, $label)
1259
-    {
1260
-        return '
1248
+	}
1249
+
1250
+
1251
+	/**
1252
+	 *        form_form_field_input__wrap
1253
+	 *
1254
+	 * @access        public
1255
+	 * @param        string $label
1256
+	 * @return        string
1257
+	 */
1258
+	public function country_form_field_input__wrap($input, $label)
1259
+	{
1260
+		return '
1261 1261
 				<td class="general-settings-country-input-td">
1262 1262
 					' . $input . '
1263 1263
 				</td>
1264 1264
 			</tr>';
1265
-    }
1266
-
1267
-
1268
-    /**
1269
-     *        form_form_field_label_wrap
1270
-     *
1271
-     * @access        public
1272
-     * @param        string $label
1273
-     * @param        string $required_text
1274
-     * @return        string
1275
-     */
1276
-    public function state_form_field_label_wrap($label, $required_text)
1277
-    {
1278
-        return $required_text;
1279
-    }
1280
-
1281
-
1282
-    /**
1283
-     *        form_form_field_input__wrap
1284
-     *
1285
-     * @access        public
1286
-     * @param        string $label
1287
-     * @return        string
1288
-     */
1289
-    public function state_form_field_input__wrap($input, $label)
1290
-    {
1291
-        return '
1265
+	}
1266
+
1267
+
1268
+	/**
1269
+	 *        form_form_field_label_wrap
1270
+	 *
1271
+	 * @access        public
1272
+	 * @param        string $label
1273
+	 * @param        string $required_text
1274
+	 * @return        string
1275
+	 */
1276
+	public function state_form_field_label_wrap($label, $required_text)
1277
+	{
1278
+		return $required_text;
1279
+	}
1280
+
1281
+
1282
+	/**
1283
+	 *        form_form_field_input__wrap
1284
+	 *
1285
+	 * @access        public
1286
+	 * @param        string $label
1287
+	 * @return        string
1288
+	 */
1289
+	public function state_form_field_input__wrap($input, $label)
1290
+	{
1291
+		return '
1292 1292
 				<td class="general-settings-country-state-input-td">
1293 1293
 					' . $input . '
1294 1294
 				</td>';
1295
-    }
1296
-
1297
-
1298
-    /***********/
1299
-
1300
-
1301
-    /**
1302
-     * displays edit and view links for critical EE pages
1303
-     *
1304
-     * @access public
1305
-     * @param int $ee_page_id
1306
-     * @return string
1307
-     */
1308
-    public static function edit_view_links($ee_page_id)
1309
-    {
1310
-        $links = '<a href="'
1311
-                 . add_query_arg(
1312
-                     array('post' => $ee_page_id, 'action' => 'edit'),
1313
-                     admin_url('post.php')
1314
-                 )
1315
-                 . '" >'
1316
-                 . esc_html__('Edit', 'event_espresso')
1317
-                 . '</a>';
1318
-        $links .= ' &nbsp;|&nbsp; ';
1319
-        $links .= '<a href="' . get_permalink($ee_page_id) . '" >' . esc_html__('View', 'event_espresso') . '</a>';
1320
-
1321
-        return $links;
1322
-    }
1323
-
1324
-
1325
-    /**
1326
-     * displays page and shortcode status for critical EE pages
1327
-     *
1328
-     * @param WP page object $ee_page
1329
-     * @return string
1330
-     */
1331
-    public static function page_and_shortcode_status($ee_page, $shortcode)
1332
-    {
1333
-
1334
-        // page status
1335
-        if (isset($ee_page->post_status) && $ee_page->post_status == 'publish') {
1336
-            $pg_colour = 'green';
1337
-            $pg_status = sprintf(esc_html__('Page%sStatus%sOK', 'event_espresso'), '&nbsp;', '&nbsp;');
1338
-        } else {
1339
-            $pg_colour = 'red';
1340
-            $pg_status = sprintf(esc_html__('Page%sVisibility%sProblem', 'event_espresso'), '&nbsp;', '&nbsp;');
1341
-        }
1342
-
1343
-        // shortcode status
1344
-        if (isset($ee_page->post_content) && strpos($ee_page->post_content, $shortcode) !== false) {
1345
-            $sc_colour = 'green';
1346
-            $sc_status = sprintf(esc_html__('Shortcode%sOK', 'event_espresso'), '&nbsp;');
1347
-        } else {
1348
-            $sc_colour = 'red';
1349
-            $sc_status = sprintf(esc_html__('Shortcode%sProblem', 'event_espresso'), '&nbsp;');
1350
-        }
1351
-
1352
-        return '<span style="color:' . $pg_colour . '; margin-right:2em;"><strong>'
1353
-               . $pg_status
1354
-               . '</strong></span><span style="color:' . $sc_colour . '"><strong>' . $sc_status . '</strong></span>';
1355
-    }
1356
-
1357
-
1358
-    /**
1359
-     * generates a dropdown of all parent pages - copied from WP core
1360
-     *
1361
-     * @param int $default
1362
-     * @param int $parent
1363
-     * @param int $level
1364
-     */
1365
-    public static function page_settings_dropdown($default = 0, $parent = 0, $level = 0)
1366
-    {
1367
-        global $wpdb;
1368
-        $items = $wpdb->get_results(
1369
-            $wpdb->prepare(
1370
-                "SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' AND post_status != 'trash' ORDER BY menu_order",
1371
-                $parent
1372
-            )
1373
-        );
1374
-
1375
-        if ($items) {
1376
-            foreach ($items as $item) {
1377
-                $pad = str_repeat('&nbsp;', $level * 3);
1378
-                if ($item->ID == $default) {
1379
-                    $current = ' selected="selected"';
1380
-                } else {
1381
-                    $current = '';
1382
-                }
1383
-
1384
-                echo "\n\t<option class='level-$level' value='$item->ID'$current>$pad "
1385
-                     . esc_html($item->post_title)
1386
-                     . "</option>";
1387
-                parent_dropdown($default, $item->ID, $level + 1);
1388
-            }
1389
-        }
1390
-    }
1391
-
1392
-
1393
-    /**
1394
-     * Loads the scripts for the privacy settings form
1395
-     */
1396
-    public function load_scripts_styles_privacy_settings()
1397
-    {
1398
-        $form_handler = $this->loader->getShared('EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler');
1399
-        $form_handler->enqueueStylesAndScripts();
1400
-    }
1401
-
1402
-
1403
-    /**
1404
-     * display the privacy settings form
1405
-     */
1406
-    public function privacySettings()
1407
-    {
1408
-        $this->_set_add_edit_form_tags('update_privacy_settings');
1409
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
1410
-        $form_handler = $this->loader->getShared('EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler');
1411
-        $this->_template_args['admin_page_content'] = $form_handler->display();
1412
-        $this->display_admin_page_with_sidebar();
1413
-    }
1414
-
1415
-
1416
-    /**
1417
-     * Update the privacy settings from form data
1418
-     *
1419
-     * @throws EE_Error
1420
-     */
1421
-    public function updatePrivacySettings()
1422
-    {
1423
-        $form_handler = $this->loader->getShared('EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler');
1424
-        $success = $form_handler->process($this->get_request_data());
1425
-        $this->_redirect_after_action(
1426
-            $success,
1427
-            esc_html__('Registration Form Options', 'event_espresso'),
1428
-            'updated',
1429
-            array('action' => 'privacy_settings')
1430
-        );
1431
-    }
1295
+	}
1296
+
1297
+
1298
+	/***********/
1299
+
1300
+
1301
+	/**
1302
+	 * displays edit and view links for critical EE pages
1303
+	 *
1304
+	 * @access public
1305
+	 * @param int $ee_page_id
1306
+	 * @return string
1307
+	 */
1308
+	public static function edit_view_links($ee_page_id)
1309
+	{
1310
+		$links = '<a href="'
1311
+				 . add_query_arg(
1312
+					 array('post' => $ee_page_id, 'action' => 'edit'),
1313
+					 admin_url('post.php')
1314
+				 )
1315
+				 . '" >'
1316
+				 . esc_html__('Edit', 'event_espresso')
1317
+				 . '</a>';
1318
+		$links .= ' &nbsp;|&nbsp; ';
1319
+		$links .= '<a href="' . get_permalink($ee_page_id) . '" >' . esc_html__('View', 'event_espresso') . '</a>';
1320
+
1321
+		return $links;
1322
+	}
1323
+
1324
+
1325
+	/**
1326
+	 * displays page and shortcode status for critical EE pages
1327
+	 *
1328
+	 * @param WP page object $ee_page
1329
+	 * @return string
1330
+	 */
1331
+	public static function page_and_shortcode_status($ee_page, $shortcode)
1332
+	{
1333
+
1334
+		// page status
1335
+		if (isset($ee_page->post_status) && $ee_page->post_status == 'publish') {
1336
+			$pg_colour = 'green';
1337
+			$pg_status = sprintf(esc_html__('Page%sStatus%sOK', 'event_espresso'), '&nbsp;', '&nbsp;');
1338
+		} else {
1339
+			$pg_colour = 'red';
1340
+			$pg_status = sprintf(esc_html__('Page%sVisibility%sProblem', 'event_espresso'), '&nbsp;', '&nbsp;');
1341
+		}
1342
+
1343
+		// shortcode status
1344
+		if (isset($ee_page->post_content) && strpos($ee_page->post_content, $shortcode) !== false) {
1345
+			$sc_colour = 'green';
1346
+			$sc_status = sprintf(esc_html__('Shortcode%sOK', 'event_espresso'), '&nbsp;');
1347
+		} else {
1348
+			$sc_colour = 'red';
1349
+			$sc_status = sprintf(esc_html__('Shortcode%sProblem', 'event_espresso'), '&nbsp;');
1350
+		}
1351
+
1352
+		return '<span style="color:' . $pg_colour . '; margin-right:2em;"><strong>'
1353
+			   . $pg_status
1354
+			   . '</strong></span><span style="color:' . $sc_colour . '"><strong>' . $sc_status . '</strong></span>';
1355
+	}
1356
+
1357
+
1358
+	/**
1359
+	 * generates a dropdown of all parent pages - copied from WP core
1360
+	 *
1361
+	 * @param int $default
1362
+	 * @param int $parent
1363
+	 * @param int $level
1364
+	 */
1365
+	public static function page_settings_dropdown($default = 0, $parent = 0, $level = 0)
1366
+	{
1367
+		global $wpdb;
1368
+		$items = $wpdb->get_results(
1369
+			$wpdb->prepare(
1370
+				"SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' AND post_status != 'trash' ORDER BY menu_order",
1371
+				$parent
1372
+			)
1373
+		);
1374
+
1375
+		if ($items) {
1376
+			foreach ($items as $item) {
1377
+				$pad = str_repeat('&nbsp;', $level * 3);
1378
+				if ($item->ID == $default) {
1379
+					$current = ' selected="selected"';
1380
+				} else {
1381
+					$current = '';
1382
+				}
1383
+
1384
+				echo "\n\t<option class='level-$level' value='$item->ID'$current>$pad "
1385
+					 . esc_html($item->post_title)
1386
+					 . "</option>";
1387
+				parent_dropdown($default, $item->ID, $level + 1);
1388
+			}
1389
+		}
1390
+	}
1391
+
1392
+
1393
+	/**
1394
+	 * Loads the scripts for the privacy settings form
1395
+	 */
1396
+	public function load_scripts_styles_privacy_settings()
1397
+	{
1398
+		$form_handler = $this->loader->getShared('EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler');
1399
+		$form_handler->enqueueStylesAndScripts();
1400
+	}
1401
+
1402
+
1403
+	/**
1404
+	 * display the privacy settings form
1405
+	 */
1406
+	public function privacySettings()
1407
+	{
1408
+		$this->_set_add_edit_form_tags('update_privacy_settings');
1409
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
1410
+		$form_handler = $this->loader->getShared('EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler');
1411
+		$this->_template_args['admin_page_content'] = $form_handler->display();
1412
+		$this->display_admin_page_with_sidebar();
1413
+	}
1414
+
1415
+
1416
+	/**
1417
+	 * Update the privacy settings from form data
1418
+	 *
1419
+	 * @throws EE_Error
1420
+	 */
1421
+	public function updatePrivacySettings()
1422
+	{
1423
+		$form_handler = $this->loader->getShared('EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler');
1424
+		$success = $form_handler->process($this->get_request_data());
1425
+		$this->_redirect_after_action(
1426
+			$success,
1427
+			esc_html__('Registration Form Options', 'event_espresso'),
1428
+			'updated',
1429
+			array('action' => 'privacy_settings')
1430
+		);
1431
+	}
1432 1432
 }
Please login to merge, or discard this patch.
payment_methods/Paypal_Standard/EE_PMT_Paypal_Standard.pm.php 2 patches
Indentation   +89 added lines, -89 removed lines patch added patch discarded remove patch
@@ -16,105 +16,105 @@
 block discarded – undo
16 16
 class EE_PMT_Paypal_Standard extends EE_PMT_Base
17 17
 {
18 18
 
19
-    const shipping_info_none     = 1;
19
+	const shipping_info_none     = 1;
20 20
 
21
-    const shipping_info_optional = 0;
21
+	const shipping_info_optional = 0;
22 22
 
23
-    const shipping_info_required = 2;
23
+	const shipping_info_required = 2;
24 24
 
25 25
 
26
-    /**
27
-     * @param null $pm_instance
28
-     * @throws EE_Error
29
-     */
30
-    public function __construct($pm_instance = null)
31
-    {
32
-        require_once($this->file_folder() . 'EEG_Paypal_Standard.gateway.php');
33
-        $this->_gateway             = new EEG_Paypal_Standard();
34
-        $this->_pretty_name         = esc_html__("PayPal Standard", 'event_espresso');
35
-        $this->_default_description = sprintf(
36
-            esc_html__(
37
-                'Upon submitting this form, you will be forwarded to PayPal to make your payment. %1$sMake sure you return to this site in order to properly finalize your registration.%2$s',
38
-                'event_espresso'
39
-            ),
40
-            '<strong>',
41
-            '</strong>'
42
-        );
43
-        parent::__construct($pm_instance);
44
-        $this->_default_button_url = $this->file_url() . 'lib/paypal-logo.png';
45
-    }
26
+	/**
27
+	 * @param null $pm_instance
28
+	 * @throws EE_Error
29
+	 */
30
+	public function __construct($pm_instance = null)
31
+	{
32
+		require_once($this->file_folder() . 'EEG_Paypal_Standard.gateway.php');
33
+		$this->_gateway             = new EEG_Paypal_Standard();
34
+		$this->_pretty_name         = esc_html__("PayPal Standard", 'event_espresso');
35
+		$this->_default_description = sprintf(
36
+			esc_html__(
37
+				'Upon submitting this form, you will be forwarded to PayPal to make your payment. %1$sMake sure you return to this site in order to properly finalize your registration.%2$s',
38
+				'event_espresso'
39
+			),
40
+			'<strong>',
41
+			'</strong>'
42
+		);
43
+		parent::__construct($pm_instance);
44
+		$this->_default_button_url = $this->file_url() . 'lib/paypal-logo.png';
45
+	}
46 46
 
47 47
 
48
-    /**
49
-     * Creates the billing form for this payment method type
50
-     *
51
-     * @param EE_Transaction $transaction
52
-     * @return NULL
53
-     */
54
-    public function generate_new_billing_form(EE_Transaction $transaction = null)
55
-    {
56
-        return null;
57
-    }
48
+	/**
49
+	 * Creates the billing form for this payment method type
50
+	 *
51
+	 * @param EE_Transaction $transaction
52
+	 * @return NULL
53
+	 */
54
+	public function generate_new_billing_form(EE_Transaction $transaction = null)
55
+	{
56
+		return null;
57
+	}
58 58
 
59 59
 
60
-    /**
61
-     * Gets the form for all the settings related to this payment method type
62
-     *
63
-     * @return EE_Payment_Method_Form
64
-     * @throws EE_Error
65
-     */
66
-    public function generate_new_settings_form()
67
-    {
68
-        require_once($this->file_folder() . 'EE_Paypal_Standard_Form.form.php');
69
-        $form = new EE_Paypal_Standard_Form($this);
70
-        $form->get_input('PMD_debug_mode')->set_html_label_text(
71
-            sprintf(esc_html__("Use PayPal Sandbox %s", 'event_espresso'), $this->get_help_tab_link())
72
-        );
73
-        $form->get_input('shipping_details')->set_html_label_text(
74
-            sprintf(esc_html__("Shipping Address Options %s", "event_espresso"), $this->get_help_tab_link())
75
-        );
76
-        return $form;
77
-    }
60
+	/**
61
+	 * Gets the form for all the settings related to this payment method type
62
+	 *
63
+	 * @return EE_Payment_Method_Form
64
+	 * @throws EE_Error
65
+	 */
66
+	public function generate_new_settings_form()
67
+	{
68
+		require_once($this->file_folder() . 'EE_Paypal_Standard_Form.form.php');
69
+		$form = new EE_Paypal_Standard_Form($this);
70
+		$form->get_input('PMD_debug_mode')->set_html_label_text(
71
+			sprintf(esc_html__("Use PayPal Sandbox %s", 'event_espresso'), $this->get_help_tab_link())
72
+		);
73
+		$form->get_input('shipping_details')->set_html_label_text(
74
+			sprintf(esc_html__("Shipping Address Options %s", "event_espresso"), $this->get_help_tab_link())
75
+		);
76
+		return $form;
77
+	}
78 78
 
79 79
 
80
-    /**
81
-     * Adds the help tab
82
-     *
83
-     * @return array
84
-     * @see EE_PMT_Base::help_tabs_config()
85
-     */
86
-    public function help_tabs_config()
87
-    {
88
-        return [
89
-            $this->get_help_tab_name() => [
90
-                'title'    => esc_html__("PayPal Standard Settings", 'event_espresso'),
91
-                'filename' => 'payment_methods_overview_paypalstandard',
92
-            ],
93
-        ];
94
-    }
80
+	/**
81
+	 * Adds the help tab
82
+	 *
83
+	 * @return array
84
+	 * @see EE_PMT_Base::help_tabs_config()
85
+	 */
86
+	public function help_tabs_config()
87
+	{
88
+		return [
89
+			$this->get_help_tab_name() => [
90
+				'title'    => esc_html__("PayPal Standard Settings", 'event_espresso'),
91
+				'filename' => 'payment_methods_overview_paypalstandard',
92
+			],
93
+		];
94
+	}
95 95
 
96 96
 
97
-    /**
98
-     * Logic to be accomplished when the payment attempt is complete.
99
-     * Most payment methods don't need to do anything at this point; but some, like Mijireh, do.
100
-     * (Mijireh was an offsite gateway which doesn't send an IPN. So when the user returns to EE from
101
-     * Mijireh, this method needs to be called so the Mijireh PM can ping Mijireh to know the status
102
-     * of the payment). Fed a transaction because it's always assumed to be the last payment that
103
-     *
104
-     * @param EE_Transaction $transaction
105
-     * @return EE_Payment
106
-     * @throws EE_Error
107
-     */
108
-    public function finalize_payment_for($transaction)
109
-    {
110
-        /** @var RequestInterface $request */
111
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
112
-        // PayPal standard actually sends the IPN info along with the user when they return to our site
113
-        // so in case the IPN is arriving later, let's try to process an IPN!
114
-        if ($request->getServerParam('REQUEST_METHOD') === 'POST') {
115
-            return $this->handle_ipn($request->postParams(), $transaction);
116
-        } else {
117
-            return parent::finalize_payment_for($transaction);
118
-        }
119
-    }
97
+	/**
98
+	 * Logic to be accomplished when the payment attempt is complete.
99
+	 * Most payment methods don't need to do anything at this point; but some, like Mijireh, do.
100
+	 * (Mijireh was an offsite gateway which doesn't send an IPN. So when the user returns to EE from
101
+	 * Mijireh, this method needs to be called so the Mijireh PM can ping Mijireh to know the status
102
+	 * of the payment). Fed a transaction because it's always assumed to be the last payment that
103
+	 *
104
+	 * @param EE_Transaction $transaction
105
+	 * @return EE_Payment
106
+	 * @throws EE_Error
107
+	 */
108
+	public function finalize_payment_for($transaction)
109
+	{
110
+		/** @var RequestInterface $request */
111
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
112
+		// PayPal standard actually sends the IPN info along with the user when they return to our site
113
+		// so in case the IPN is arriving later, let's try to process an IPN!
114
+		if ($request->getServerParam('REQUEST_METHOD') === 'POST') {
115
+			return $this->handle_ipn($request->postParams(), $transaction);
116
+		} else {
117
+			return parent::finalize_payment_for($transaction);
118
+		}
119
+	}
120 120
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@  discard block
 block discarded – undo
29 29
      */
30 30
     public function __construct($pm_instance = null)
31 31
     {
32
-        require_once($this->file_folder() . 'EEG_Paypal_Standard.gateway.php');
32
+        require_once($this->file_folder().'EEG_Paypal_Standard.gateway.php');
33 33
         $this->_gateway             = new EEG_Paypal_Standard();
34 34
         $this->_pretty_name         = esc_html__("PayPal Standard", 'event_espresso');
35 35
         $this->_default_description = sprintf(
@@ -41,7 +41,7 @@  discard block
 block discarded – undo
41 41
             '</strong>'
42 42
         );
43 43
         parent::__construct($pm_instance);
44
-        $this->_default_button_url = $this->file_url() . 'lib/paypal-logo.png';
44
+        $this->_default_button_url = $this->file_url().'lib/paypal-logo.png';
45 45
     }
46 46
 
47 47
 
@@ -65,7 +65,7 @@  discard block
 block discarded – undo
65 65
      */
66 66
     public function generate_new_settings_form()
67 67
     {
68
-        require_once($this->file_folder() . 'EE_Paypal_Standard_Form.form.php');
68
+        require_once($this->file_folder().'EE_Paypal_Standard_Form.form.php');
69 69
         $form = new EE_Paypal_Standard_Form($this);
70 70
         $form->get_input('PMD_debug_mode')->set_html_label_text(
71 71
             sprintf(esc_html__("Use PayPal Sandbox %s", 'event_espresso'), $this->get_help_tab_link())
Please login to merge, or discard this patch.
modules/bot_trap/EED_Bot_Trap.module.php 1 patch
Indentation   +277 added lines, -277 removed lines patch added patch discarded remove patch
@@ -17,306 +17,306 @@
 block discarded – undo
17 17
 class EED_Bot_Trap extends EED_Module
18 18
 {
19 19
 
20
-    /**
21
-     * @return EED_Module|EED_Bot_Trap
22
-     * @throws EE_Error
23
-     * @throws ReflectionException
24
-     */
25
-    public static function instance()
26
-    {
27
-        return parent::get_instance(__CLASS__);
28
-    }
20
+	/**
21
+	 * @return EED_Module|EED_Bot_Trap
22
+	 * @throws EE_Error
23
+	 * @throws ReflectionException
24
+	 */
25
+	public static function instance()
26
+	{
27
+		return parent::get_instance(__CLASS__);
28
+	}
29 29
 
30 30
 
31
-    /**
32
-     * set_hooks - for hooking into EE Core, other modules, etc
33
-     *
34
-     * @return void
35
-     */
36
-    public static function set_hooks()
37
-    {
38
-        if (
39
-            apply_filters('FHEE__EED_Bot_Trap__set_hooks__use_bot_trap', true) &&
40
-            EE_Registry::instance()->CFG->registration->use_bot_trap
41
-        ) {
42
-            EED_Bot_Trap::set_trap();
43
-            // redirect bots to bogus success page
44
-            EE_Config::register_route(
45
-                'ticket_selection_received',
46
-                'EED_Bot_Trap',
47
-                'display_bot_trap_success'
48
-            );
49
-        }
50
-    }
31
+	/**
32
+	 * set_hooks - for hooking into EE Core, other modules, etc
33
+	 *
34
+	 * @return void
35
+	 */
36
+	public static function set_hooks()
37
+	{
38
+		if (
39
+			apply_filters('FHEE__EED_Bot_Trap__set_hooks__use_bot_trap', true) &&
40
+			EE_Registry::instance()->CFG->registration->use_bot_trap
41
+		) {
42
+			EED_Bot_Trap::set_trap();
43
+			// redirect bots to bogus success page
44
+			EE_Config::register_route(
45
+				'ticket_selection_received',
46
+				'EED_Bot_Trap',
47
+				'display_bot_trap_success'
48
+			);
49
+		}
50
+	}
51 51
 
52 52
 
53
-    /**
54
-     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
55
-     *
56
-     * @return void
57
-     */
58
-    public static function set_trap()
59
-    {
60
-        define('EE_BOT_TRAP_BASE_URL', plugin_dir_url(__FILE__) . '/');
61
-        add_action(
62
-            'AHEE__ticket_selector_chart__template__after_ticket_selector',
63
-            array('EED_Bot_Trap', 'generate_bot_trap'),
64
-            10,
65
-            2
66
-        );
67
-        add_action(
68
-            'EED_Ticket_Selector__process_ticket_selections__before',
69
-            array('EED_Bot_Trap', 'process_bot_trap'),
70
-            1,
71
-            2
72
-        );
73
-    }
53
+	/**
54
+	 * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
55
+	 *
56
+	 * @return void
57
+	 */
58
+	public static function set_trap()
59
+	{
60
+		define('EE_BOT_TRAP_BASE_URL', plugin_dir_url(__FILE__) . '/');
61
+		add_action(
62
+			'AHEE__ticket_selector_chart__template__after_ticket_selector',
63
+			array('EED_Bot_Trap', 'generate_bot_trap'),
64
+			10,
65
+			2
66
+		);
67
+		add_action(
68
+			'EED_Ticket_Selector__process_ticket_selections__before',
69
+			array('EED_Bot_Trap', 'process_bot_trap'),
70
+			1,
71
+			2
72
+		);
73
+	}
74 74
 
75 75
 
76
-    /**
77
-     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
78
-     *
79
-     * @return void
80
-     */
81
-    public static function set_hooks_admin()
82
-    {
83
-        if (
84
-            EED_Bot_Trap::getRequest()->isAjax()
85
-            && apply_filters('FHEE__EED_Bot_Trap__set_hooks__use_bot_trap', true)
86
-            && EE_Registry::instance()->CFG->registration->use_bot_trap
87
-        ) {
88
-            EED_Bot_Trap::set_trap();
89
-        }
90
-        add_action(
91
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
92
-            array('EED_Bot_Trap', 'bot_trap_settings_form'),
93
-            5
94
-        );
95
-        add_filter(
96
-            'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
97
-            array('EED_Bot_Trap', 'update_bot_trap_settings_form'),
98
-            10,
99
-            1
100
-        );
101
-    }
76
+	/**
77
+	 * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
78
+	 *
79
+	 * @return void
80
+	 */
81
+	public static function set_hooks_admin()
82
+	{
83
+		if (
84
+			EED_Bot_Trap::getRequest()->isAjax()
85
+			&& apply_filters('FHEE__EED_Bot_Trap__set_hooks__use_bot_trap', true)
86
+			&& EE_Registry::instance()->CFG->registration->use_bot_trap
87
+		) {
88
+			EED_Bot_Trap::set_trap();
89
+		}
90
+		add_action(
91
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
92
+			array('EED_Bot_Trap', 'bot_trap_settings_form'),
93
+			5
94
+		);
95
+		add_filter(
96
+			'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
97
+			array('EED_Bot_Trap', 'update_bot_trap_settings_form'),
98
+			10,
99
+			1
100
+		);
101
+	}
102 102
 
103 103
 
104
-    /**
105
-     * run - initial module setup
106
-     *
107
-     * @param WP $WP
108
-     * @return void
109
-     */
110
-    public function run($WP)
111
-    {
112
-    }
104
+	/**
105
+	 * run - initial module setup
106
+	 *
107
+	 * @param WP $WP
108
+	 * @return void
109
+	 */
110
+	public function run($WP)
111
+	{
112
+	}
113 113
 
114 114
 
115
-    /**
116
-     * generate_bot_trap
117
-     *
118
-     * @return void
119
-     * @throws RuntimeException
120
-     */
121
-    public static function generate_bot_trap()
122
-    {
123
-        $do_not_enter = esc_html__('please do not enter anything in this input', 'event_espresso');
124
-        $time = microtime(true);
125
-        $html = '<div class="tkt-slctr-request-processor-dv" style="float:left; margin:0 0 0 -999em; height: 0;">';
126
-        $html .= '<label for="tkt-slctr-request-processor-email-' . $time . '">' . $do_not_enter . '</label>';
127
-        $html .= '<input type="email" id="tkt-slctr-request-processor-email-';
128
-        $html .= $time . '" name="tkt-slctr-request-processor-email" value=""/>';
129
-        $html .= '</div><!-- .tkt-slctr-request-processor-dv -->';
130
-        echo $html;
131
-    }
115
+	/**
116
+	 * generate_bot_trap
117
+	 *
118
+	 * @return void
119
+	 * @throws RuntimeException
120
+	 */
121
+	public static function generate_bot_trap()
122
+	{
123
+		$do_not_enter = esc_html__('please do not enter anything in this input', 'event_espresso');
124
+		$time = microtime(true);
125
+		$html = '<div class="tkt-slctr-request-processor-dv" style="float:left; margin:0 0 0 -999em; height: 0;">';
126
+		$html .= '<label for="tkt-slctr-request-processor-email-' . $time . '">' . $do_not_enter . '</label>';
127
+		$html .= '<input type="email" id="tkt-slctr-request-processor-email-';
128
+		$html .= $time . '" name="tkt-slctr-request-processor-email" value=""/>';
129
+		$html .= '</div><!-- .tkt-slctr-request-processor-dv -->';
130
+		echo $html;
131
+	}
132 132
 
133 133
 
134
-    /**
135
-     * process_bot_trap
136
-     *
137
-     * @param array|string $triggered_trap_callback Callback that will be executed for handling the
138
-     *                                              response if the bot trap is triggered.
139
-     *                                              It should receive one argument: a boolean indicating
140
-     *                                              whether the trap was triggered by suspicious timing or not.
141
-     * @throws RuntimeException
142
-     */
143
-    public static function process_bot_trap($triggered_trap_callback = array())
144
-    {
145
-        // what's your email address Mr. Bot ?
146
-        $empty_trap = EED_Bot_Trap::getRequest()->getRequestParam('tkt-slctr-request-processor-email') === '';
147
-        // are we human ?
148
-        if ($empty_trap) {
149
-            do_action('AHEE__EED_Bot_Trap__process_bot_trap__trap_not_triggered');
150
-            return;
151
-        }
152
-        // check the given callback is valid first before executing
153
-        if (! is_callable($triggered_trap_callback)) {
154
-            // invalid callback so lets just sub in our default.
155
-            $triggered_trap_callback = array('EED_Bot_Trap', 'triggered_trap_response');
156
-        }
157
-        call_user_func($triggered_trap_callback);
158
-    }
134
+	/**
135
+	 * process_bot_trap
136
+	 *
137
+	 * @param array|string $triggered_trap_callback Callback that will be executed for handling the
138
+	 *                                              response if the bot trap is triggered.
139
+	 *                                              It should receive one argument: a boolean indicating
140
+	 *                                              whether the trap was triggered by suspicious timing or not.
141
+	 * @throws RuntimeException
142
+	 */
143
+	public static function process_bot_trap($triggered_trap_callback = array())
144
+	{
145
+		// what's your email address Mr. Bot ?
146
+		$empty_trap = EED_Bot_Trap::getRequest()->getRequestParam('tkt-slctr-request-processor-email') === '';
147
+		// are we human ?
148
+		if ($empty_trap) {
149
+			do_action('AHEE__EED_Bot_Trap__process_bot_trap__trap_not_triggered');
150
+			return;
151
+		}
152
+		// check the given callback is valid first before executing
153
+		if (! is_callable($triggered_trap_callback)) {
154
+			// invalid callback so lets just sub in our default.
155
+			$triggered_trap_callback = array('EED_Bot_Trap', 'triggered_trap_response');
156
+		}
157
+		call_user_func($triggered_trap_callback);
158
+	}
159 159
 
160 160
 
161
-    /**
162
-     * This is the default callback executed by EED_Bot_Trap::process_bot_trap that handles the response.
163
-     *
164
-     * @throws InvalidArgumentException
165
-     * @throws InvalidDataTypeException
166
-     * @throws InvalidInterfaceException
167
-     */
168
-    public static function triggered_trap_response()
169
-    {
170
-        // UH OH...
171
-        $redirect_url = apply_filters(
172
-            'FHEE__EED_Bot_Trap__process_bot_trap__redirect_url',
173
-            add_query_arg(
174
-                array('ee' => 'ticket_selection_received'),
175
-                EE_Registry::instance()->CFG->core->reg_page_url()
176
-            )
177
-        );
178
-        // if AJAX, return the redirect URL
179
-        if (EED_Bot_Trap::getRequest()->isAjax()) {
180
-            echo wp_json_encode(
181
-                array_merge(
182
-                    EE_Error::get_notices(false),
183
-                    array(
184
-                        'redirect_url' => $redirect_url,
185
-                    )
186
-                )
187
-            );
188
-            exit();
189
-        }
190
-        wp_safe_redirect($redirect_url);
191
-        exit();
192
-    }
161
+	/**
162
+	 * This is the default callback executed by EED_Bot_Trap::process_bot_trap that handles the response.
163
+	 *
164
+	 * @throws InvalidArgumentException
165
+	 * @throws InvalidDataTypeException
166
+	 * @throws InvalidInterfaceException
167
+	 */
168
+	public static function triggered_trap_response()
169
+	{
170
+		// UH OH...
171
+		$redirect_url = apply_filters(
172
+			'FHEE__EED_Bot_Trap__process_bot_trap__redirect_url',
173
+			add_query_arg(
174
+				array('ee' => 'ticket_selection_received'),
175
+				EE_Registry::instance()->CFG->core->reg_page_url()
176
+			)
177
+		);
178
+		// if AJAX, return the redirect URL
179
+		if (EED_Bot_Trap::getRequest()->isAjax()) {
180
+			echo wp_json_encode(
181
+				array_merge(
182
+					EE_Error::get_notices(false),
183
+					array(
184
+						'redirect_url' => $redirect_url,
185
+					)
186
+				)
187
+			);
188
+			exit();
189
+		}
190
+		wp_safe_redirect($redirect_url);
191
+		exit();
192
+	}
193 193
 
194 194
 
195
-    /**
196
-     * display_bot_trap_success
197
-     * shows a "success" screen to bots so that they (ie: the ppl managing them)
198
-     * think the form was submitted successfully
199
-     *
200
-     * @return void
201
-     */
202
-    public static function display_bot_trap_success()
203
-    {
204
-        add_filter('FHEE__EED_Single_Page_Checkout__run', '__return_false');
205
-        $bot_notice = EED_Bot_Trap::getRequest()->getRequestParam(
206
-            'ee-notice',
207
-            esc_html__(
208
-                'Thank you so much. Your ticket selections have been received for consideration.',
209
-                'event_espresso'
210
-            )
211
-        );
212
-        EED_Bot_Trap::getResponse()->addOutput(EEH_HTML::div($bot_notice, '', 'ee-attention'));
213
-    }
195
+	/**
196
+	 * display_bot_trap_success
197
+	 * shows a "success" screen to bots so that they (ie: the ppl managing them)
198
+	 * think the form was submitted successfully
199
+	 *
200
+	 * @return void
201
+	 */
202
+	public static function display_bot_trap_success()
203
+	{
204
+		add_filter('FHEE__EED_Single_Page_Checkout__run', '__return_false');
205
+		$bot_notice = EED_Bot_Trap::getRequest()->getRequestParam(
206
+			'ee-notice',
207
+			esc_html__(
208
+				'Thank you so much. Your ticket selections have been received for consideration.',
209
+				'event_espresso'
210
+			)
211
+		);
212
+		EED_Bot_Trap::getResponse()->addOutput(EEH_HTML::div($bot_notice, '', 'ee-attention'));
213
+	}
214 214
 
215 215
 
216 216
 
217
-    /***********************************    ADMIN    **********************************/
217
+	/***********************************    ADMIN    **********************************/
218 218
 
219 219
 
220
-    /**
221
-     * bot_trap_settings_form
222
-     *
223
-     * @return void
224
-     * @throws EE_Error
225
-     * @throws InvalidArgumentException
226
-     * @throws InvalidDataTypeException
227
-     * @throws InvalidInterfaceException
228
-     */
229
-    public static function bot_trap_settings_form()
230
-    {
231
-        EED_Bot_Trap::_bot_trap_settings_form()->enqueue_js();
232
-        echo EED_Bot_Trap::_bot_trap_settings_form()->get_html();
233
-    }
220
+	/**
221
+	 * bot_trap_settings_form
222
+	 *
223
+	 * @return void
224
+	 * @throws EE_Error
225
+	 * @throws InvalidArgumentException
226
+	 * @throws InvalidDataTypeException
227
+	 * @throws InvalidInterfaceException
228
+	 */
229
+	public static function bot_trap_settings_form()
230
+	{
231
+		EED_Bot_Trap::_bot_trap_settings_form()->enqueue_js();
232
+		echo EED_Bot_Trap::_bot_trap_settings_form()->get_html();
233
+	}
234 234
 
235 235
 
236
-    /**
237
-     * _bot_trap_settings_form
238
-     *
239
-     * @return EE_Form_Section_Proper
240
-     * @throws EE_Error
241
-     */
242
-    protected static function _bot_trap_settings_form()
243
-    {
244
-        return new EE_Form_Section_Proper(
245
-            array(
246
-                'name'            => 'bot_trap_settings',
247
-                'html_id'         => 'bot_trap_settings',
248
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
249
-                'subsections'     => array(
250
-                    'bot_trap_hdr' => new EE_Form_Section_HTML(
251
-                        EEH_HTML::h2(esc_html__('Bot Trap Settings', 'event_espresso'))
252
-                    ),
253
-                    'use_bot_trap' => new EE_Yes_No_Input(
254
-                        array(
255
-                            'html_label_text' => esc_html__('Enable Bot Trap', 'event_espresso'),
256
-                            'html_help_text'  => esc_html__(
257
-                                'The Event Espresso Bot Trap will insert a fake input into your Ticket Selector forms that is hidden from regular site visitors, but visible to spam bots. Because the input asks for an email address, it is irresistible to spam bots who will of course enter text into it. Since regular site visitors can not see this input, any value detected during form submission means a bot has been detected, which will then be blocked from submitting the form.',
258
-                                'event_espresso'
259
-                            ),
260
-                            'default'         => EE_Registry::instance()->CFG->registration->use_bot_trap !== null
261
-                                ? EE_Registry::instance()->CFG->registration->use_bot_trap
262
-                                : true,
263
-                            'required'        => false,
264
-                        )
265
-                    ),
266
-                ),
267
-            )
268
-        );
269
-    }
236
+	/**
237
+	 * _bot_trap_settings_form
238
+	 *
239
+	 * @return EE_Form_Section_Proper
240
+	 * @throws EE_Error
241
+	 */
242
+	protected static function _bot_trap_settings_form()
243
+	{
244
+		return new EE_Form_Section_Proper(
245
+			array(
246
+				'name'            => 'bot_trap_settings',
247
+				'html_id'         => 'bot_trap_settings',
248
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
249
+				'subsections'     => array(
250
+					'bot_trap_hdr' => new EE_Form_Section_HTML(
251
+						EEH_HTML::h2(esc_html__('Bot Trap Settings', 'event_espresso'))
252
+					),
253
+					'use_bot_trap' => new EE_Yes_No_Input(
254
+						array(
255
+							'html_label_text' => esc_html__('Enable Bot Trap', 'event_espresso'),
256
+							'html_help_text'  => esc_html__(
257
+								'The Event Espresso Bot Trap will insert a fake input into your Ticket Selector forms that is hidden from regular site visitors, but visible to spam bots. Because the input asks for an email address, it is irresistible to spam bots who will of course enter text into it. Since regular site visitors can not see this input, any value detected during form submission means a bot has been detected, which will then be blocked from submitting the form.',
258
+								'event_espresso'
259
+							),
260
+							'default'         => EE_Registry::instance()->CFG->registration->use_bot_trap !== null
261
+								? EE_Registry::instance()->CFG->registration->use_bot_trap
262
+								: true,
263
+							'required'        => false,
264
+						)
265
+					),
266
+				),
267
+			)
268
+		);
269
+	}
270 270
 
271 271
 
272
-    /**
273
-     * update_bot_trap_settings_form
274
-     *
275
-     * @param EE_Registration_Config $EE_Registration_Config
276
-     * @return EE_Registration_Config
277
-     * @throws EE_Error
278
-     * @throws InvalidArgumentException
279
-     * @throws ReflectionException
280
-     * @throws InvalidDataTypeException
281
-     * @throws InvalidInterfaceException
282
-     */
283
-    public static function update_bot_trap_settings_form(EE_Registration_Config $EE_Registration_Config)
284
-    {
285
-        try {
286
-            $bot_trap_settings_form = EED_Bot_Trap::_bot_trap_settings_form();
287
-            // if not displaying a form, then check for form submission
288
-            if ($bot_trap_settings_form->was_submitted()) {
289
-                // capture form data
290
-                $bot_trap_settings_form->receive_form_submission();
291
-                // validate form data
292
-                if ($bot_trap_settings_form->is_valid()) {
293
-                    // grab validated data from form
294
-                    $valid_data = $bot_trap_settings_form->valid_data();
295
-                    if (isset($valid_data['use_bot_trap'])) {
296
-                        $EE_Registration_Config->use_bot_trap = $valid_data['use_bot_trap'];
297
-                    } else {
298
-                        EE_Error::add_error(
299
-                            esc_html__(
300
-                                'Invalid or missing Bot Trap settings. Please refresh the form and try again.',
301
-                                'event_espresso'
302
-                            ),
303
-                            __FILE__,
304
-                            __FUNCTION__,
305
-                            __LINE__
306
-                        );
307
-                    }
308
-                } elseif ($bot_trap_settings_form->submission_error_message() !== '') {
309
-                    EE_Error::add_error(
310
-                        $bot_trap_settings_form->submission_error_message(),
311
-                        __FILE__,
312
-                        __FUNCTION__,
313
-                        __LINE__
314
-                    );
315
-                }
316
-            }
317
-        } catch (EE_Error $e) {
318
-            $e->get_error();
319
-        }
320
-        return $EE_Registration_Config;
321
-    }
272
+	/**
273
+	 * update_bot_trap_settings_form
274
+	 *
275
+	 * @param EE_Registration_Config $EE_Registration_Config
276
+	 * @return EE_Registration_Config
277
+	 * @throws EE_Error
278
+	 * @throws InvalidArgumentException
279
+	 * @throws ReflectionException
280
+	 * @throws InvalidDataTypeException
281
+	 * @throws InvalidInterfaceException
282
+	 */
283
+	public static function update_bot_trap_settings_form(EE_Registration_Config $EE_Registration_Config)
284
+	{
285
+		try {
286
+			$bot_trap_settings_form = EED_Bot_Trap::_bot_trap_settings_form();
287
+			// if not displaying a form, then check for form submission
288
+			if ($bot_trap_settings_form->was_submitted()) {
289
+				// capture form data
290
+				$bot_trap_settings_form->receive_form_submission();
291
+				// validate form data
292
+				if ($bot_trap_settings_form->is_valid()) {
293
+					// grab validated data from form
294
+					$valid_data = $bot_trap_settings_form->valid_data();
295
+					if (isset($valid_data['use_bot_trap'])) {
296
+						$EE_Registration_Config->use_bot_trap = $valid_data['use_bot_trap'];
297
+					} else {
298
+						EE_Error::add_error(
299
+							esc_html__(
300
+								'Invalid or missing Bot Trap settings. Please refresh the form and try again.',
301
+								'event_espresso'
302
+							),
303
+							__FILE__,
304
+							__FUNCTION__,
305
+							__LINE__
306
+						);
307
+					}
308
+				} elseif ($bot_trap_settings_form->submission_error_message() !== '') {
309
+					EE_Error::add_error(
310
+						$bot_trap_settings_form->submission_error_message(),
311
+						__FILE__,
312
+						__FUNCTION__,
313
+						__LINE__
314
+					);
315
+				}
316
+			}
317
+		} catch (EE_Error $e) {
318
+			$e->get_error();
319
+		}
320
+		return $EE_Registration_Config;
321
+	}
322 322
 }
Please login to merge, or discard this patch.
modules/core_rest_api/EED_Core_Rest_Api.module.php 1 patch
Indentation   +1348 added lines, -1348 removed lines patch added patch discarded remove patch
@@ -23,1352 +23,1352 @@
 block discarded – undo
23 23
 class EED_Core_Rest_Api extends \EED_Module
24 24
 {
25 25
 
26
-    const ee_api_namespace = Domain::API_NAMESPACE;
27
-
28
-    const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/';
29
-
30
-    const saved_routes_option_names = 'ee_core_routes';
31
-
32
-    /**
33
-     * string used in _links response bodies to make them globally unique.
34
-     *
35
-     * @see http://v2.wp-api.org/extending/linking/
36
-     */
37
-    const ee_api_link_namespace = 'https://api.eventespresso.com/';
38
-
39
-    /**
40
-     * @var CalculatedModelFields
41
-     */
42
-    protected static $_field_calculator;
43
-
44
-
45
-    /**
46
-     * @return EED_Core_Rest_Api|EED_Module
47
-     */
48
-    public static function instance()
49
-    {
50
-        self::$_field_calculator = LoaderFactory::getLoader()->load('EventEspresso\core\libraries\rest_api\CalculatedModelFields');
51
-        return parent::get_instance(__CLASS__);
52
-    }
53
-
54
-
55
-    /**
56
-     *    set_hooks - for hooking into EE Core, other modules, etc
57
-     *
58
-     * @access    public
59
-     * @return    void
60
-     */
61
-    public static function set_hooks()
62
-    {
63
-        self::set_hooks_both();
64
-    }
65
-
66
-
67
-    /**
68
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
69
-     *
70
-     * @access    public
71
-     * @return    void
72
-     */
73
-    public static function set_hooks_admin()
74
-    {
75
-        self::set_hooks_both();
76
-    }
77
-
78
-
79
-    public static function set_hooks_both()
80
-    {
81
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
82
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
83
-        add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
84
-        add_filter(
85
-            'rest_index',
86
-            array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex')
87
-        );
88
-        EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
89
-    }
90
-
91
-
92
-    /**
93
-     * sets up hooks which only need to be included as part of REST API requests;
94
-     * other requests like to the frontend or admin etc don't need them
95
-     *
96
-     * @throws \EE_Error
97
-     */
98
-    public static function set_hooks_rest_api()
99
-    {
100
-        // set hooks which account for changes made to the API
101
-        EED_Core_Rest_Api::_set_hooks_for_changes();
102
-    }
103
-
104
-
105
-    /**
106
-     * public wrapper of _set_hooks_for_changes.
107
-     * Loads all the hooks which make requests to old versions of the API
108
-     * appear the same as they always did
109
-     *
110
-     * @throws EE_Error
111
-     */
112
-    public static function set_hooks_for_changes()
113
-    {
114
-        self::_set_hooks_for_changes();
115
-    }
116
-
117
-
118
-    /**
119
-     * Loads all the hooks which make requests to old versions of the API
120
-     * appear the same as they always did
121
-     *
122
-     * @throws EE_Error
123
-     */
124
-    protected static function _set_hooks_for_changes()
125
-    {
126
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api/changes'), false);
127
-        foreach ($folder_contents as $classname_in_namespace => $filepath) {
128
-            // ignore the base parent class
129
-            // and legacy named classes
130
-            if (
131
-                $classname_in_namespace === 'ChangesInBase'
132
-                || strpos($classname_in_namespace, 'Changes_In_') === 0
133
-            ) {
134
-                continue;
135
-            }
136
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
137
-            if (class_exists($full_classname)) {
138
-                $instance_of_class = new $full_classname();
139
-                if ($instance_of_class instanceof ChangesInBase) {
140
-                    $instance_of_class->setHooks();
141
-                }
142
-            }
143
-        }
144
-    }
145
-
146
-
147
-    /**
148
-     * Filters the WP routes to add our EE-related ones. This takes a bit of time
149
-     * so we actually prefer to only do it when an EE plugin is activated or upgraded
150
-     *
151
-     * @throws \EE_Error
152
-     */
153
-    public static function register_routes()
154
-    {
155
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
156
-            foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
157
-                /**
158
-                 * @var array     $data_for_multiple_endpoints numerically indexed array
159
-                 *                                         but can also contain route options like {
160
-                 * @type array    $schema                      {
161
-                 * @type callable $schema_callback
162
-                 * @type array    $callback_args               arguments that will be passed to the callback, after the
163
-                 * WP_REST_Request of course
164
-                 * }
165
-                 * }
166
-                 */
167
-                // when registering routes, register all the endpoints' data at the same time
168
-                $multiple_endpoint_args = array();
169
-                foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
170
-                    /**
171
-                     * @var array     $data_for_single_endpoint {
172
-                     * @type callable $callback
173
-                     * @type string methods
174
-                     * @type array args
175
-                     * @type array _links
176
-                     * @type array    $callback_args            arguments that will be passed to the callback, after the
177
-                     * WP_REST_Request of course
178
-                     * }
179
-                     */
180
-                    // skip route options
181
-                    if (! is_numeric($endpoint_key)) {
182
-                        continue;
183
-                    }
184
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
185
-                        throw new EE_Error(
186
-                            esc_html__(
187
-                            // @codingStandardsIgnoreStart
188
-                                'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
189
-                                // @codingStandardsIgnoreEnd
190
-                                'event_espresso'
191
-                            )
192
-                        );
193
-                    }
194
-                    $callback = $data_for_single_endpoint['callback'];
195
-                    $single_endpoint_args = array(
196
-                        'methods' => $data_for_single_endpoint['methods'],
197
-                        'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
198
-                            : array(),
199
-                    );
200
-                    if (isset($data_for_single_endpoint['_links'])) {
201
-                        $single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
202
-                    }
203
-                    if (isset($data_for_single_endpoint['callback_args'])) {
204
-                        $callback_args = $data_for_single_endpoint['callback_args'];
205
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
206
-                            $callback,
207
-                            $callback_args
208
-                        ) {
209
-                            array_unshift($callback_args, $request);
210
-                            return call_user_func_array(
211
-                                $callback,
212
-                                $callback_args
213
-                            );
214
-                        };
215
-                    } else {
216
-                        $single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
217
-                    }
218
-                    // As of WordPress 5.5, if a permission_callback is not provided,
219
-                    // the REST API will issue a _doing_it_wrong notice.
220
-                    // Since the EE REST API defers capabilities to the db model system,
221
-                    // we will just use the generic WP callback for public endpoints
222
-                    if (! isset($single_endpoint_args['permission_callback'])) {
223
-                        $single_endpoint_args['permission_callback'] = '__return_true';
224
-                    }
225
-                    $multiple_endpoint_args[] = $single_endpoint_args;
226
-                }
227
-                if (isset($data_for_multiple_endpoints['schema'])) {
228
-                    $schema_route_data = $data_for_multiple_endpoints['schema'];
229
-                    $schema_callback = $schema_route_data['schema_callback'];
230
-                    $callback_args = $schema_route_data['callback_args'];
231
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
232
-                        return call_user_func_array(
233
-                            $schema_callback,
234
-                            $callback_args
235
-                        );
236
-                    };
237
-                }
238
-                register_rest_route(
239
-                    $namespace,
240
-                    $relative_route,
241
-                    $multiple_endpoint_args
242
-                );
243
-            }
244
-        }
245
-    }
246
-
247
-
248
-    /**
249
-     * Checks if there was a version change or something that merits invalidating the cached
250
-     * route data. If so, invalidates the cached route data so that it gets refreshed
251
-     * next time the WP API is used
252
-     */
253
-    public static function invalidate_cached_route_data_on_version_change()
254
-    {
255
-        if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
256
-            EED_Core_Rest_Api::invalidate_cached_route_data();
257
-        }
258
-        foreach (EE_Registry::instance()->addons as $addon) {
259
-            if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
260
-                EED_Core_Rest_Api::invalidate_cached_route_data();
261
-            }
262
-        }
263
-    }
264
-
265
-
266
-    /**
267
-     * Removes the cached route data so it will get refreshed next time the WP API is used
268
-     */
269
-    public static function invalidate_cached_route_data()
270
-    {
271
-        // delete the saved EE REST API routes
272
-        foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
273
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
274
-        }
275
-    }
276
-
277
-
278
-    /**
279
-     * Gets the EE route data
280
-     *
281
-     * @return array top-level key is the namespace, next-level key is the route and its value is array{
282
-     * @throws \EE_Error
283
-     * @type string|array $callback
284
-     * @type string       $methods
285
-     * @type boolean      $hidden_endpoint
286
-     * }
287
-     */
288
-    public static function get_ee_route_data()
289
-    {
290
-        $ee_routes = array();
291
-        foreach (self::versions_served() as $version => $hidden_endpoints) {
292
-            $ee_routes[ self::ee_api_namespace . $version ] = self::_get_ee_route_data_for_version(
293
-                $version,
294
-                $hidden_endpoints
295
-            );
296
-        }
297
-        return $ee_routes;
298
-    }
299
-
300
-
301
-    /**
302
-     * Gets the EE route data from the wp options if it exists already,
303
-     * otherwise re-generates it and saves it to the option
304
-     *
305
-     * @param string  $version
306
-     * @param boolean $hidden_endpoints
307
-     * @return array
308
-     * @throws \EE_Error
309
-     */
310
-    protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
311
-    {
312
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
313
-        if (! $ee_routes || EED_Core_Rest_Api::debugMode()) {
314
-            $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
315
-        }
316
-        return $ee_routes;
317
-    }
318
-
319
-
320
-    /**
321
-     * Saves the EE REST API route data to a wp option and returns it
322
-     *
323
-     * @param string  $version
324
-     * @param boolean $hidden_endpoints
325
-     * @return mixed|null
326
-     * @throws \EE_Error
327
-     */
328
-    protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
329
-    {
330
-        $instance = self::instance();
331
-        $routes = apply_filters(
332
-            'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
333
-            array_replace_recursive(
334
-                $instance->_get_config_route_data_for_version($version, $hidden_endpoints),
335
-                $instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
336
-                $instance->_get_model_route_data_for_version($version, $hidden_endpoints),
337
-                $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
338
-            )
339
-        );
340
-        $option_name = self::saved_routes_option_names . $version;
341
-        if (get_option($option_name)) {
342
-            update_option($option_name, $routes, true);
343
-        } else {
344
-            add_option($option_name, $routes, null, 'no');
345
-        }
346
-        return $routes;
347
-    }
348
-
349
-
350
-    /**
351
-     * Calculates all the EE routes and saves it to a WordPress option so we don't
352
-     * need to calculate it on every request
353
-     *
354
-     * @deprecated since version 4.9.1
355
-     * @return void
356
-     */
357
-    public static function save_ee_routes()
358
-    {
359
-        if (EE_Maintenance_Mode::instance()->models_can_query()) {
360
-            $instance = self::instance();
361
-            $routes = apply_filters(
362
-                'EED_Core_Rest_Api__save_ee_routes__routes',
363
-                array_replace_recursive(
364
-                    $instance->_register_config_routes(),
365
-                    $instance->_register_meta_routes(),
366
-                    $instance->_register_model_routes(),
367
-                    $instance->_register_rpc_routes()
368
-                )
369
-            );
370
-            update_option(self::saved_routes_option_names, $routes, true);
371
-        }
372
-    }
373
-
374
-
375
-    /**
376
-     * Gets all the route information relating to EE models
377
-     *
378
-     * @return array @see get_ee_route_data
379
-     * @deprecated since version 4.9.1
380
-     */
381
-    protected function _register_model_routes()
382
-    {
383
-        $model_routes = array();
384
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
385
-            $model_routes[ EED_Core_Rest_Api::ee_api_namespace
386
-                           . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
387
-        }
388
-        return $model_routes;
389
-    }
390
-
391
-
392
-    /**
393
-     * Decides whether or not to add write endpoints for this model.
394
-     *
395
-     * Currently, this defaults to exclude all global tables and models
396
-     * which would allow inserting WP core data (we don't want to duplicate
397
-     * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
398
-     *
399
-     * @param EEM_Base $model
400
-     * @return bool
401
-     */
402
-    public static function should_have_write_endpoints(EEM_Base $model)
403
-    {
404
-        if ($model->is_wp_core_model()) {
405
-            return false;
406
-        }
407
-        foreach ($model->get_tables() as $table) {
408
-            if ($table->is_global()) {
409
-                return false;
410
-            }
411
-        }
412
-        return true;
413
-    }
414
-
415
-
416
-    /**
417
-     * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
418
-     * in this versioned namespace of EE4
419
-     *
420
-     * @param $version
421
-     * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
422
-     */
423
-    public static function model_names_with_plural_routes($version)
424
-    {
425
-        $model_version_info = new ModelVersionInfo($version);
426
-        $models_to_register = $model_version_info->modelsForRequestedVersion();
427
-        // let's not bother having endpoints for extra metas
428
-        unset(
429
-            $models_to_register['Extra_Meta'],
430
-            $models_to_register['Extra_Join'],
431
-            $models_to_register['Post_Meta']
432
-        );
433
-        return apply_filters(
434
-            'FHEE__EED_Core_REST_API___register_model_routes',
435
-            $models_to_register
436
-        );
437
-    }
438
-
439
-
440
-    /**
441
-     * Gets the route data for EE models in the specified version
442
-     *
443
-     * @param string  $version
444
-     * @param boolean $hidden_endpoint
445
-     * @return array
446
-     * @throws EE_Error
447
-     */
448
-    protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
449
-    {
450
-        $model_routes = array();
451
-        $model_version_info = new ModelVersionInfo($version);
452
-        foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
453
-            $model = \EE_Registry::instance()->load_model($model_name);
454
-            // if this isn't a valid model then let's skip iterate to the next item in the loop.
455
-            if (! $model instanceof EEM_Base) {
456
-                continue;
457
-            }
458
-            // yes we could just register one route for ALL models, but then they wouldn't show up in the index
459
-            $plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
460
-            $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
461
-            $model_routes[ $plural_model_route ] = array(
462
-                array(
463
-                    'callback'        => array(
464
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
465
-                        'handleRequestGetAll',
466
-                    ),
467
-                    'callback_args'   => array($version, $model_name),
468
-                    'methods'         => WP_REST_Server::READABLE,
469
-                    'hidden_endpoint' => $hidden_endpoint,
470
-                    'args'            => $this->_get_read_query_params($model, $version),
471
-                    '_links'          => array(
472
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
473
-                    ),
474
-                ),
475
-                'schema' => array(
476
-                    'schema_callback' => array(
477
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
478
-                        'handleSchemaRequest',
479
-                    ),
480
-                    'callback_args'   => array($version, $model_name),
481
-                ),
482
-            );
483
-            $model_routes[ $singular_model_route ] = array(
484
-                array(
485
-                    'callback'        => array(
486
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
487
-                        'handleRequestGetOne',
488
-                    ),
489
-                    'callback_args'   => array($version, $model_name),
490
-                    'methods'         => WP_REST_Server::READABLE,
491
-                    'hidden_endpoint' => $hidden_endpoint,
492
-                    'args'            => $this->_get_response_selection_query_params($model, $version, true),
493
-                ),
494
-            );
495
-            if (
496
-                apply_filters(
497
-                    'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
498
-                    EED_Core_Rest_Api::should_have_write_endpoints($model),
499
-                    $model
500
-                )
501
-            ) {
502
-                $model_routes[ $plural_model_route ][] = array(
503
-                    'callback'        => array(
504
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Write',
505
-                        'handleRequestInsert',
506
-                    ),
507
-                    'callback_args'   => array($version, $model_name),
508
-                    'methods'         => WP_REST_Server::CREATABLE,
509
-                    'hidden_endpoint' => $hidden_endpoint,
510
-                    'args'            => $this->_get_write_params($model_name, $model_version_info, true),
511
-                );
512
-                $model_routes[ $singular_model_route ] = array_merge(
513
-                    $model_routes[ $singular_model_route ],
514
-                    array(
515
-                        array(
516
-                            'callback'        => array(
517
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
518
-                                'handleRequestUpdate',
519
-                            ),
520
-                            'callback_args'   => array($version, $model_name),
521
-                            'methods'         => WP_REST_Server::EDITABLE,
522
-                            'hidden_endpoint' => $hidden_endpoint,
523
-                            'args'            => $this->_get_write_params($model_name, $model_version_info),
524
-                        ),
525
-                        array(
526
-                            'callback'        => array(
527
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
528
-                                'handleRequestDelete',
529
-                            ),
530
-                            'callback_args'   => array($version, $model_name),
531
-                            'methods'         => WP_REST_Server::DELETABLE,
532
-                            'hidden_endpoint' => $hidden_endpoint,
533
-                            'args'            => $this->_get_delete_query_params($model, $version),
534
-                        ),
535
-                    )
536
-                );
537
-            }
538
-            foreach ($model->relation_settings() as $relation_name => $relation_obj) {
539
-                $related_route = EED_Core_Rest_Api::get_relation_route_via(
540
-                    $model,
541
-                    '(?P<id>[^\/]+)',
542
-                    $relation_obj
543
-                );
544
-                $model_routes[ $related_route ] = array(
545
-                    array(
546
-                        'callback'        => array(
547
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Read',
548
-                            'handleRequestGetRelated',
549
-                        ),
550
-                        'callback_args'   => array($version, $model_name, $relation_name),
551
-                        'methods'         => WP_REST_Server::READABLE,
552
-                        'hidden_endpoint' => $hidden_endpoint,
553
-                        'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
554
-                    ),
555
-                );
556
-
557
-                $related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)';
558
-                $model_routes[ $related_write_route ] = array(
559
-                    array(
560
-                        'callback'        => array(
561
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Write',
562
-                            'handleRequestAddRelation',
563
-                        ),
564
-                        'callback_args'   => array($version, $model_name, $relation_name),
565
-                        'methods'         => WP_REST_Server::EDITABLE,
566
-                        'hidden_endpoint' => $hidden_endpoint,
567
-                        'args'            => $this->_get_add_relation_query_params($model, $relation_obj->get_other_model(), $version)
568
-                    ),
569
-                    array(
570
-                        'callback'        => array(
571
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Write',
572
-                            'handleRequestRemoveRelation',
573
-                        ),
574
-                        'callback_args'   => array($version, $model_name, $relation_name),
575
-                        'methods'         => WP_REST_Server::DELETABLE,
576
-                        'hidden_endpoint' => $hidden_endpoint,
577
-                        'args'            => array()
578
-                    ),
579
-                );
580
-            }
581
-        }
582
-        return $model_routes;
583
-    }
584
-
585
-
586
-    /**
587
-     * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
588
-     * excluding the preceding slash.
589
-     * Eg you pass get_plural_route_to('Event') = 'events'
590
-     *
591
-     * @param EEM_Base $model
592
-     * @return string
593
-     */
594
-    public static function get_collection_route(EEM_Base $model)
595
-    {
596
-        return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
597
-    }
598
-
599
-
600
-    /**
601
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
602
-     * excluding the preceding slash.
603
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
604
-     *
605
-     * @param EEM_Base $model eg Event or Venue
606
-     * @param string   $id
607
-     * @return string
608
-     */
609
-    public static function get_entity_route($model, $id)
610
-    {
611
-        return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id;
612
-    }
613
-
614
-
615
-    /**
616
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
617
-     * excluding the preceding slash.
618
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
619
-     *
620
-     * @param EEM_Base               $model eg Event or Venue
621
-     * @param string                 $id
622
-     * @param EE_Model_Relation_Base $relation_obj
623
-     * @return string
624
-     */
625
-    public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
626
-    {
627
-        $related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
628
-            $relation_obj->get_other_model()->get_this_model_name(),
629
-            $relation_obj
630
-        );
631
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
632
-    }
633
-
634
-
635
-    /**
636
-     * Adds onto the $relative_route the EE4 REST API versioned namespace.
637
-     * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
638
-     *
639
-     * @param string $relative_route
640
-     * @param string $version
641
-     * @return string
642
-     */
643
-    public static function get_versioned_route_to($relative_route, $version = '4.8.36')
644
-    {
645
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
646
-    }
647
-
648
-
649
-    /**
650
-     * Adds all the RPC-style routes (remote procedure call-like routes, ie
651
-     * routes that don't conform to the traditional REST CRUD-style).
652
-     *
653
-     * @deprecated since 4.9.1
654
-     */
655
-    protected function _register_rpc_routes()
656
-    {
657
-        $routes = array();
658
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
659
-            $routes[ self::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version(
660
-                $version,
661
-                $hidden_endpoint
662
-            );
663
-        }
664
-        return $routes;
665
-    }
666
-
667
-
668
-    /**
669
-     * @param string  $version
670
-     * @param boolean $hidden_endpoint
671
-     * @return array
672
-     */
673
-    protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
674
-    {
675
-        $this_versions_routes = array();
676
-        // checkin endpoint
677
-        $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
678
-            array(
679
-                'callback'        => array(
680
-                    'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
681
-                    'handleRequestToggleCheckin',
682
-                ),
683
-                'methods'         => WP_REST_Server::CREATABLE,
684
-                'hidden_endpoint' => $hidden_endpoint,
685
-                'args'            => array(
686
-                    'force' => array(
687
-                        'required'    => false,
688
-                        'default'     => false,
689
-                        'description' => esc_html__(
690
-                        // @codingStandardsIgnoreStart
691
-                            'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
692
-                            // @codingStandardsIgnoreEnd
693
-                            'event_espresso'
694
-                        ),
695
-                    ),
696
-                ),
697
-                'callback_args'   => array($version),
698
-            ),
699
-        );
700
-        return apply_filters(
701
-            'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
702
-            $this_versions_routes,
703
-            $version,
704
-            $hidden_endpoint
705
-        );
706
-    }
707
-
708
-
709
-    /**
710
-     * Gets the query params that can be used when request one or many
711
-     *
712
-     * @param EEM_Base $model
713
-     * @param string   $version
714
-     * @return array
715
-     */
716
-    protected function _get_response_selection_query_params(\EEM_Base $model, $version, $single_only = false)
717
-    {
718
-        $query_params = array(
719
-            'include'   => array(
720
-                'required' => false,
721
-                'default'  => '*',
722
-                'type'     => 'string',
723
-            ),
724
-            'calculate' => array(
725
-                'required'          => false,
726
-                'default'           => '',
727
-                'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
728
-                'type'              => 'string',
729
-                // because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
730
-                // freaks out. We'll just validate this argument while handling the request
731
-                'validate_callback' => null,
732
-                'sanitize_callback' => null,
733
-            ),
734
-            'password' => array(
735
-                'required' => false,
736
-                'default' => '',
737
-                'type' => 'string'
738
-            )
739
-        );
740
-        return apply_filters(
741
-            'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
742
-            $query_params,
743
-            $model,
744
-            $version
745
-        );
746
-    }
747
-
748
-
749
-    /**
750
-     * Gets the parameters acceptable for delete requests
751
-     *
752
-     * @param \EEM_Base $model
753
-     * @param string    $version
754
-     * @return array
755
-     */
756
-    protected function _get_delete_query_params(\EEM_Base $model, $version)
757
-    {
758
-        $params_for_delete = array(
759
-            'allow_blocking' => array(
760
-                'required' => false,
761
-                'default'  => true,
762
-                'type'     => 'boolean',
763
-            ),
764
-        );
765
-        $params_for_delete['force'] = array(
766
-            'required' => false,
767
-            'default'  => false,
768
-            'type'     => 'boolean',
769
-        );
770
-        return apply_filters(
771
-            'FHEE__EED_Core_Rest_Api___get_delete_query_params',
772
-            $params_for_delete,
773
-            $model,
774
-            $version
775
-        );
776
-    }
777
-
778
-    protected function _get_add_relation_query_params(\EEM_Base $source_model, \EEM_Base $related_model, $version)
779
-    {
780
-        // if they're related through a HABTM relation, check for any non-FKs
781
-        $all_relation_settings = $source_model->relation_settings();
782
-        $relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ];
783
-        $params = array();
784
-        if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) {
785
-            foreach ($relation_settings->getNonKeyFields() as $field) {
786
-                /* @var $field EE_Model_Field_Base */
787
-                $params[ $field->get_name() ] = array(
788
-                    'required' => ! $field->is_nullable(),
789
-                    'default' => ModelDataTranslator::prepareFieldValueForJson($field, $field->get_default_value(), $version),
790
-                    'type' => $field->getSchemaType(),
791
-                    'validate_callbaack' => null,
792
-                    'sanitize_callback' => null
793
-                );
794
-            }
795
-        }
796
-        return $params;
797
-    }
798
-
799
-
800
-    /**
801
-     * Gets info about reading query params that are acceptable
802
-     *
803
-     * @param \EEM_Base $model eg 'Event' or 'Venue'
804
-     * @param  string   $version
805
-     * @return array    describing the args acceptable when querying this model
806
-     * @throws EE_Error
807
-     */
808
-    protected function _get_read_query_params(\EEM_Base $model, $version)
809
-    {
810
-        $default_orderby = array();
811
-        foreach ($model->get_combined_primary_key_fields() as $key_field) {
812
-            $default_orderby[ $key_field->get_name() ] = 'ASC';
813
-        }
814
-        return array_merge(
815
-            $this->_get_response_selection_query_params($model, $version),
816
-            array(
817
-                'where'    => array(
818
-                    'required'          => false,
819
-                    'default'           => array(),
820
-                    'type'              => 'object',
821
-                    // because we accept an almost infinite list of possible where conditions, WP
822
-                    // core validation and sanitization freaks out. We'll just validate this argument
823
-                    // while handling the request
824
-                    'validate_callback' => null,
825
-                    'sanitize_callback' => null,
826
-                ),
827
-                'limit'    => array(
828
-                    'required'          => false,
829
-                    'default'           => EED_Core_Rest_Api::get_default_query_limit(),
830
-                    'type'              => array(
831
-                        'array',
832
-                        'string',
833
-                        'integer',
834
-                    ),
835
-                    // because we accept a variety of types, WP core validation and sanitization
836
-                    // freaks out. We'll just validate this argument while handling the request
837
-                    'validate_callback' => null,
838
-                    'sanitize_callback' => null,
839
-                ),
840
-                'order_by' => array(
841
-                    'required'          => false,
842
-                    'default'           => $default_orderby,
843
-                    'type'              => array(
844
-                        'object',
845
-                        'string',
846
-                    ),// because we accept a variety of types, WP core validation and sanitization
847
-                    // freaks out. We'll just validate this argument while handling the request
848
-                    'validate_callback' => null,
849
-                    'sanitize_callback' => null,
850
-                ),
851
-                'group_by' => array(
852
-                    'required'          => false,
853
-                    'default'           => null,
854
-                    'type'              => array(
855
-                        'object',
856
-                        'string',
857
-                    ),
858
-                    // because we accept  an almost infinite list of possible groupings,
859
-                    // WP core validation and sanitization
860
-                    // freaks out. We'll just validate this argument while handling the request
861
-                    'validate_callback' => null,
862
-                    'sanitize_callback' => null,
863
-                ),
864
-                'having'   => array(
865
-                    'required'          => false,
866
-                    'default'           => null,
867
-                    'type'              => 'object',
868
-                    // because we accept an almost infinite list of possible where conditions, WP
869
-                    // core validation and sanitization freaks out. We'll just validate this argument
870
-                    // while handling the request
871
-                    'validate_callback' => null,
872
-                    'sanitize_callback' => null,
873
-                ),
874
-                'caps'     => array(
875
-                    'required' => false,
876
-                    'default'  => EEM_Base::caps_read,
877
-                    'type'     => 'string',
878
-                    'enum'     => array(
879
-                        EEM_Base::caps_read,
880
-                        EEM_Base::caps_read_admin,
881
-                        EEM_Base::caps_edit,
882
-                        EEM_Base::caps_delete,
883
-                    ),
884
-                ),
885
-            )
886
-        );
887
-    }
888
-
889
-
890
-    /**
891
-     * Gets parameter information for a model regarding writing data
892
-     *
893
-     * @param string           $model_name
894
-     * @param ModelVersionInfo $model_version_info
895
-     * @param boolean          $create                                       whether this is for request to create (in
896
-     *                                                                       which case we need all required params) or
897
-     *                                                                       just to update (in which case we don't
898
-     *                                                                       need those on every request)
899
-     * @return array
900
-     */
901
-    protected function _get_write_params(
902
-        $model_name,
903
-        ModelVersionInfo $model_version_info,
904
-        $create = false
905
-    ) {
906
-        $model = EE_Registry::instance()->load_model($model_name);
907
-        $fields = $model_version_info->fieldsOnModelInThisVersion($model);
908
-        $args_info = array();
909
-        foreach ($fields as $field_name => $field_obj) {
910
-            if ($field_obj->is_auto_increment()) {
911
-                // totally ignore auto increment IDs
912
-                continue;
913
-            }
914
-            $arg_info = $field_obj->getSchema();
915
-            $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
916
-            $arg_info['required'] = $required;
917
-            // remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
918
-            unset($arg_info['readonly']);
919
-            $schema_properties = $field_obj->getSchemaProperties();
920
-            if (
921
-                isset($schema_properties['raw'])
922
-                && $field_obj->getSchemaType() === 'object'
923
-            ) {
924
-                // if there's a "raw" form of this argument, use those properties instead
925
-                $arg_info = array_replace(
926
-                    $arg_info,
927
-                    $schema_properties['raw']
928
-                );
929
-            }
930
-            $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
931
-                $field_obj,
932
-                $field_obj->get_default_value(),
933
-                $model_version_info->requestedVersion()
934
-            );
935
-            // we do our own validation and sanitization within the controller
936
-            if (function_exists('rest_validate_value_from_schema')) {
937
-                $sanitize_callback = array(
938
-                    'EED_Core_Rest_Api',
939
-                    'default_sanitize_callback',
940
-                );
941
-            } else {
942
-                $sanitize_callback = null;
943
-            }
944
-            $arg_info['sanitize_callback'] = $sanitize_callback;
945
-            $args_info[ $field_name ] = $arg_info;
946
-            if ($field_obj instanceof EE_Datetime_Field) {
947
-                $gmt_arg_info = $arg_info;
948
-                $gmt_arg_info['description'] = sprintf(
949
-                    esc_html__(
950
-                        '%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
951
-                        'event_espresso'
952
-                    ),
953
-                    $field_obj->get_nicename(),
954
-                    $field_name
955
-                );
956
-                $args_info[ $field_name . '_gmt' ] = $gmt_arg_info;
957
-            }
958
-        }
959
-        return $args_info;
960
-    }
961
-
962
-
963
-    /**
964
-     * Replacement for WP API's 'rest_parse_request_arg'.
965
-     * If the value is blank but not required, don't bother validating it.
966
-     * Also, it uses our email validation instead of WP API's default.
967
-     *
968
-     * @param                 $value
969
-     * @param WP_REST_Request $request
970
-     * @param                 $param
971
-     * @return bool|true|WP_Error
972
-     * @throws InvalidArgumentException
973
-     * @throws InvalidInterfaceException
974
-     * @throws InvalidDataTypeException
975
-     */
976
-    public static function default_sanitize_callback($value, WP_REST_Request $request, $param)
977
-    {
978
-        $attributes = $request->get_attributes();
979
-        if (
980
-            ! isset($attributes['args'][ $param ])
981
-            || ! is_array($attributes['args'][ $param ])
982
-        ) {
983
-            $validation_result = true;
984
-        } else {
985
-            $args = $attributes['args'][ $param ];
986
-            if (
987
-                (
988
-                    $value === ''
989
-                    || $value === null
990
-                )
991
-                && (! isset($args['required'])
992
-                    || $args['required'] === false
993
-                )
994
-            ) {
995
-                // not required and not provided? that's cool
996
-                $validation_result = true;
997
-            } elseif (
998
-                isset($args['format'])
999
-                      && $args['format'] === 'email'
1000
-            ) {
1001
-                $validation_result = true;
1002
-                if (! self::_validate_email($value)) {
1003
-                    $validation_result = new WP_Error(
1004
-                        'rest_invalid_param',
1005
-                        esc_html__(
1006
-                            'The email address is not valid or does not exist.',
1007
-                            'event_espresso'
1008
-                        )
1009
-                    );
1010
-                }
1011
-            } else {
1012
-                $validation_result = rest_validate_value_from_schema($value, $args, $param);
1013
-            }
1014
-        }
1015
-        if (is_wp_error($validation_result)) {
1016
-            return $validation_result;
1017
-        }
1018
-        return rest_sanitize_request_arg($value, $request, $param);
1019
-    }
1020
-
1021
-
1022
-    /**
1023
-     * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
1024
-     *
1025
-     * @param $email
1026
-     * @return bool
1027
-     * @throws InvalidArgumentException
1028
-     * @throws InvalidInterfaceException
1029
-     * @throws InvalidDataTypeException
1030
-     */
1031
-    protected static function _validate_email($email)
1032
-    {
1033
-        try {
1034
-            EmailAddressFactory::create($email);
1035
-            return true;
1036
-        } catch (EmailValidationException $e) {
1037
-            return false;
1038
-        }
1039
-    }
1040
-
1041
-
1042
-    /**
1043
-     * Gets routes for the config
1044
-     *
1045
-     * @return array @see _register_model_routes
1046
-     * @deprecated since version 4.9.1
1047
-     */
1048
-    protected function _register_config_routes()
1049
-    {
1050
-        $config_routes = array();
1051
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
1052
-            $config_routes[ self::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version(
1053
-                $version,
1054
-                $hidden_endpoint
1055
-            );
1056
-        }
1057
-        return $config_routes;
1058
-    }
1059
-
1060
-
1061
-    /**
1062
-     * Gets routes for the config for the specified version
1063
-     *
1064
-     * @param string  $version
1065
-     * @param boolean $hidden_endpoint
1066
-     * @return array
1067
-     */
1068
-    protected function _get_config_route_data_for_version($version, $hidden_endpoint)
1069
-    {
1070
-        return array(
1071
-            'config'    => array(
1072
-                array(
1073
-                    'callback'        => array(
1074
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1075
-                        'handleRequest',
1076
-                    ),
1077
-                    'methods'         => WP_REST_Server::READABLE,
1078
-                    'hidden_endpoint' => $hidden_endpoint,
1079
-                    'callback_args'   => array($version),
1080
-                ),
1081
-            ),
1082
-            'site_info' => array(
1083
-                array(
1084
-                    'callback'        => array(
1085
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1086
-                        'handleRequestSiteInfo',
1087
-                    ),
1088
-                    'methods'         => WP_REST_Server::READABLE,
1089
-                    'hidden_endpoint' => $hidden_endpoint,
1090
-                    'callback_args'   => array($version),
1091
-                ),
1092
-            ),
1093
-        );
1094
-    }
1095
-
1096
-
1097
-    /**
1098
-     * Gets the meta info routes
1099
-     *
1100
-     * @return array @see _register_model_routes
1101
-     * @deprecated since version 4.9.1
1102
-     */
1103
-    protected function _register_meta_routes()
1104
-    {
1105
-        $meta_routes = array();
1106
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
1107
-            $meta_routes[ self::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version(
1108
-                $version,
1109
-                $hidden_endpoint
1110
-            );
1111
-        }
1112
-        return $meta_routes;
1113
-    }
1114
-
1115
-
1116
-    /**
1117
-     * @param string  $version
1118
-     * @param boolean $hidden_endpoint
1119
-     * @return array
1120
-     */
1121
-    protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1122
-    {
1123
-        return array(
1124
-            'resources' => array(
1125
-                array(
1126
-                    'callback'        => array(
1127
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1128
-                        'handleRequestModelsMeta',
1129
-                    ),
1130
-                    'methods'         => WP_REST_Server::READABLE,
1131
-                    'hidden_endpoint' => $hidden_endpoint,
1132
-                    'callback_args'   => array($version),
1133
-                ),
1134
-            ),
1135
-        );
1136
-    }
1137
-
1138
-
1139
-    /**
1140
-     * Tries to hide old 4.6 endpoints from the
1141
-     *
1142
-     * @param array $route_data
1143
-     * @return array
1144
-     * @throws \EE_Error
1145
-     */
1146
-    public static function hide_old_endpoints($route_data)
1147
-    {
1148
-        // allow API clients to override which endpoints get hidden, in case
1149
-        // they want to discover particular endpoints
1150
-        // also, we don't have access to the request so we have to just grab it from the superglobal
1151
-        $force_show_ee_namespace = ltrim(
1152
-            EED_Core_Rest_Api::getRequest()->getRequestParam('force_show_ee_namespace'),
1153
-            '/'
1154
-        );
1155
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1156
-            foreach ($relative_urls as $resource_name => $endpoints) {
1157
-                foreach ($endpoints as $key => $endpoint) {
1158
-                    // skip schema and other route options
1159
-                    if (! is_numeric($key)) {
1160
-                        continue;
1161
-                    }
1162
-                    // by default, hide "hidden_endpoint"s, unless the request indicates
1163
-                    // to $force_show_ee_namespace, in which case only show that one
1164
-                    // namespace's endpoints (and hide all others)
1165
-                    if (
1166
-                        ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1167
-                        || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1168
-                    ) {
1169
-                        $full_route = '/' . ltrim($namespace, '/');
1170
-                        $full_route .= '/' . ltrim($resource_name, '/');
1171
-                        unset($route_data[ $full_route ]);
1172
-                    }
1173
-                }
1174
-            }
1175
-        }
1176
-        return $route_data;
1177
-    }
1178
-
1179
-
1180
-    /**
1181
-     * Returns an array describing which versions of core support serving requests for.
1182
-     * Keys are core versions' major and minor version, and values are the
1183
-     * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1184
-     * data by just removing a few models and fields from the responses. However, 4.15 might remove
1185
-     * the answers table entirely, in which case it would be very difficult for
1186
-     * it to serve 4.6-style responses.
1187
-     * Versions of core that are missing from this array are unknowns.
1188
-     * previous ver
1189
-     *
1190
-     * @return array
1191
-     */
1192
-    public static function version_compatibilities()
1193
-    {
1194
-        return apply_filters(
1195
-            'FHEE__EED_Core_REST_API__version_compatibilities',
1196
-            array(
1197
-                '4.8.29' => '4.8.29',
1198
-                '4.8.33' => '4.8.29',
1199
-                '4.8.34' => '4.8.29',
1200
-                '4.8.36' => '4.8.29',
1201
-            )
1202
-        );
1203
-    }
1204
-
1205
-
1206
-    /**
1207
-     * Gets the latest API version served. Eg if there
1208
-     * are two versions served of the API, 4.8.29 and 4.8.32, and
1209
-     * we are on core version 4.8.34, it will return the string "4.8.32"
1210
-     *
1211
-     * @return string
1212
-     */
1213
-    public static function latest_rest_api_version()
1214
-    {
1215
-        $versions_served = \EED_Core_Rest_Api::versions_served();
1216
-        $versions_served_keys = array_keys($versions_served);
1217
-        return end($versions_served_keys);
1218
-    }
1219
-
1220
-
1221
-    /**
1222
-     * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1223
-     * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1224
-     * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1225
-     * We also indicate whether or not this version should be put in the index or not
1226
-     *
1227
-     * @return array keys are API version numbers (just major and minor numbers), and values
1228
-     * are whether or not they should be hidden
1229
-     */
1230
-    public static function versions_served()
1231
-    {
1232
-        $versions_served = array();
1233
-        $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1234
-        $lowest_compatible_version = end($possibly_served_versions);
1235
-        reset($possibly_served_versions);
1236
-        $versions_served_historically = array_keys($possibly_served_versions);
1237
-        $latest_version = end($versions_served_historically);
1238
-        reset($versions_served_historically);
1239
-        // for each version of core we have ever served:
1240
-        foreach ($versions_served_historically as $key_versioned_endpoint) {
1241
-            // if it's not above the current core version, and it's compatible with the current version of core
1242
-
1243
-            if ($key_versioned_endpoint === $latest_version) {
1244
-                // don't hide the latest version in the index
1245
-                $versions_served[ $key_versioned_endpoint ] = false;
1246
-            } elseif (
1247
-                version_compare($key_versioned_endpoint, $lowest_compatible_version, '>=')
1248
-                && version_compare($key_versioned_endpoint, EED_Core_Rest_Api::core_version(), '<')
1249
-            ) {
1250
-                // include, but hide, previous versions which are still supported
1251
-                $versions_served[ $key_versioned_endpoint ] = true;
1252
-            } elseif (
1253
-                apply_filters(
1254
-                    'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1255
-                    false,
1256
-                    $possibly_served_versions
1257
-                )
1258
-            ) {
1259
-                // if a version is no longer supported, don't include it in index or list of versions served
1260
-                $versions_served[ $key_versioned_endpoint ] = true;
1261
-            }
1262
-        }
1263
-        return $versions_served;
1264
-    }
1265
-
1266
-
1267
-    /**
1268
-     * Gets the major and minor version of EE core's version string
1269
-     *
1270
-     * @return string
1271
-     */
1272
-    public static function core_version()
1273
-    {
1274
-        return apply_filters(
1275
-            'FHEE__EED_Core_REST_API__core_version',
1276
-            implode(
1277
-                '.',
1278
-                array_slice(
1279
-                    explode(
1280
-                        '.',
1281
-                        espresso_version()
1282
-                    ),
1283
-                    0,
1284
-                    3
1285
-                )
1286
-            )
1287
-        );
1288
-    }
1289
-
1290
-
1291
-    /**
1292
-     * Gets the default limit that should be used when querying for resources
1293
-     *
1294
-     * @return int
1295
-     */
1296
-    public static function get_default_query_limit()
1297
-    {
1298
-        // we actually don't use a const because we want folks to always use
1299
-        // this method, not the const directly
1300
-        return apply_filters(
1301
-            'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1302
-            50
1303
-        );
1304
-    }
1305
-
1306
-
1307
-    /**
1308
-     *
1309
-     * @param string $version api version string (i.e. '4.8.36')
1310
-     * @return array
1311
-     */
1312
-    public static function getCollectionRoutesIndexedByModelName($version = '')
1313
-    {
1314
-        $version = empty($version) ? self::latest_rest_api_version() : $version;
1315
-        $model_names = self::model_names_with_plural_routes($version);
1316
-        $collection_routes = array();
1317
-        foreach ($model_names as $model_name => $model_class_name) {
1318
-            $collection_routes[ strtolower($model_name) ] = '/' . self::ee_api_namespace . $version . '/'
1319
-                                                            . EEH_Inflector::pluralize_and_lower($model_name);
1320
-        }
1321
-        return $collection_routes;
1322
-    }
1323
-
1324
-
1325
-    /**
1326
-     * Returns an array of primary key names indexed by model names.
1327
-     * @param string $version
1328
-     * @return array
1329
-     */
1330
-    public static function getPrimaryKeyNamesIndexedByModelName($version = '')
1331
-    {
1332
-        $version = empty($version) ? self::latest_rest_api_version() : $version;
1333
-        $model_names = self::model_names_with_plural_routes($version);
1334
-        $primary_key_items = array();
1335
-        foreach ($model_names as $model_name => $model_class_name) {
1336
-            $primary_keys = $model_class_name::instance()->get_combined_primary_key_fields();
1337
-            foreach ($primary_keys as $primary_key_name => $primary_key_field) {
1338
-                if (count($primary_keys) > 1) {
1339
-                    $primary_key_items[ strtolower($model_name) ][] = $primary_key_name;
1340
-                } else {
1341
-                    $primary_key_items[ strtolower($model_name) ] = $primary_key_name;
1342
-                }
1343
-            }
1344
-        }
1345
-        return $primary_key_items;
1346
-    }
1347
-
1348
-    /**
1349
-     * Determines the EE REST API debug mode is activated, or not.
1350
-     * @since 4.9.76.p
1351
-     * @return bool
1352
-     */
1353
-    public static function debugMode()
1354
-    {
1355
-        static $debug_mode = null; // could be class prop
1356
-        if ($debug_mode === null) {
1357
-            $debug_mode = defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE;
1358
-        }
1359
-        return $debug_mode;
1360
-    }
1361
-
1362
-
1363
-
1364
-    /**
1365
-     *    run - initial module setup
1366
-     *
1367
-     * @access    public
1368
-     * @param  WP $WP
1369
-     * @return    void
1370
-     */
1371
-    public function run($WP)
1372
-    {
1373
-    }
26
+	const ee_api_namespace = Domain::API_NAMESPACE;
27
+
28
+	const ee_api_namespace_for_regex = 'ee\/v([^/]*)\/';
29
+
30
+	const saved_routes_option_names = 'ee_core_routes';
31
+
32
+	/**
33
+	 * string used in _links response bodies to make them globally unique.
34
+	 *
35
+	 * @see http://v2.wp-api.org/extending/linking/
36
+	 */
37
+	const ee_api_link_namespace = 'https://api.eventespresso.com/';
38
+
39
+	/**
40
+	 * @var CalculatedModelFields
41
+	 */
42
+	protected static $_field_calculator;
43
+
44
+
45
+	/**
46
+	 * @return EED_Core_Rest_Api|EED_Module
47
+	 */
48
+	public static function instance()
49
+	{
50
+		self::$_field_calculator = LoaderFactory::getLoader()->load('EventEspresso\core\libraries\rest_api\CalculatedModelFields');
51
+		return parent::get_instance(__CLASS__);
52
+	}
53
+
54
+
55
+	/**
56
+	 *    set_hooks - for hooking into EE Core, other modules, etc
57
+	 *
58
+	 * @access    public
59
+	 * @return    void
60
+	 */
61
+	public static function set_hooks()
62
+	{
63
+		self::set_hooks_both();
64
+	}
65
+
66
+
67
+	/**
68
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
69
+	 *
70
+	 * @access    public
71
+	 * @return    void
72
+	 */
73
+	public static function set_hooks_admin()
74
+	{
75
+		self::set_hooks_both();
76
+	}
77
+
78
+
79
+	public static function set_hooks_both()
80
+	{
81
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
82
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
83
+		add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
84
+		add_filter(
85
+			'rest_index',
86
+			array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex')
87
+		);
88
+		EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
89
+	}
90
+
91
+
92
+	/**
93
+	 * sets up hooks which only need to be included as part of REST API requests;
94
+	 * other requests like to the frontend or admin etc don't need them
95
+	 *
96
+	 * @throws \EE_Error
97
+	 */
98
+	public static function set_hooks_rest_api()
99
+	{
100
+		// set hooks which account for changes made to the API
101
+		EED_Core_Rest_Api::_set_hooks_for_changes();
102
+	}
103
+
104
+
105
+	/**
106
+	 * public wrapper of _set_hooks_for_changes.
107
+	 * Loads all the hooks which make requests to old versions of the API
108
+	 * appear the same as they always did
109
+	 *
110
+	 * @throws EE_Error
111
+	 */
112
+	public static function set_hooks_for_changes()
113
+	{
114
+		self::_set_hooks_for_changes();
115
+	}
116
+
117
+
118
+	/**
119
+	 * Loads all the hooks which make requests to old versions of the API
120
+	 * appear the same as they always did
121
+	 *
122
+	 * @throws EE_Error
123
+	 */
124
+	protected static function _set_hooks_for_changes()
125
+	{
126
+		$folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api/changes'), false);
127
+		foreach ($folder_contents as $classname_in_namespace => $filepath) {
128
+			// ignore the base parent class
129
+			// and legacy named classes
130
+			if (
131
+				$classname_in_namespace === 'ChangesInBase'
132
+				|| strpos($classname_in_namespace, 'Changes_In_') === 0
133
+			) {
134
+				continue;
135
+			}
136
+			$full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
137
+			if (class_exists($full_classname)) {
138
+				$instance_of_class = new $full_classname();
139
+				if ($instance_of_class instanceof ChangesInBase) {
140
+					$instance_of_class->setHooks();
141
+				}
142
+			}
143
+		}
144
+	}
145
+
146
+
147
+	/**
148
+	 * Filters the WP routes to add our EE-related ones. This takes a bit of time
149
+	 * so we actually prefer to only do it when an EE plugin is activated or upgraded
150
+	 *
151
+	 * @throws \EE_Error
152
+	 */
153
+	public static function register_routes()
154
+	{
155
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
156
+			foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
157
+				/**
158
+				 * @var array     $data_for_multiple_endpoints numerically indexed array
159
+				 *                                         but can also contain route options like {
160
+				 * @type array    $schema                      {
161
+				 * @type callable $schema_callback
162
+				 * @type array    $callback_args               arguments that will be passed to the callback, after the
163
+				 * WP_REST_Request of course
164
+				 * }
165
+				 * }
166
+				 */
167
+				// when registering routes, register all the endpoints' data at the same time
168
+				$multiple_endpoint_args = array();
169
+				foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
170
+					/**
171
+					 * @var array     $data_for_single_endpoint {
172
+					 * @type callable $callback
173
+					 * @type string methods
174
+					 * @type array args
175
+					 * @type array _links
176
+					 * @type array    $callback_args            arguments that will be passed to the callback, after the
177
+					 * WP_REST_Request of course
178
+					 * }
179
+					 */
180
+					// skip route options
181
+					if (! is_numeric($endpoint_key)) {
182
+						continue;
183
+					}
184
+					if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
185
+						throw new EE_Error(
186
+							esc_html__(
187
+							// @codingStandardsIgnoreStart
188
+								'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
189
+								// @codingStandardsIgnoreEnd
190
+								'event_espresso'
191
+							)
192
+						);
193
+					}
194
+					$callback = $data_for_single_endpoint['callback'];
195
+					$single_endpoint_args = array(
196
+						'methods' => $data_for_single_endpoint['methods'],
197
+						'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
198
+							: array(),
199
+					);
200
+					if (isset($data_for_single_endpoint['_links'])) {
201
+						$single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
202
+					}
203
+					if (isset($data_for_single_endpoint['callback_args'])) {
204
+						$callback_args = $data_for_single_endpoint['callback_args'];
205
+						$single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
206
+							$callback,
207
+							$callback_args
208
+						) {
209
+							array_unshift($callback_args, $request);
210
+							return call_user_func_array(
211
+								$callback,
212
+								$callback_args
213
+							);
214
+						};
215
+					} else {
216
+						$single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
217
+					}
218
+					// As of WordPress 5.5, if a permission_callback is not provided,
219
+					// the REST API will issue a _doing_it_wrong notice.
220
+					// Since the EE REST API defers capabilities to the db model system,
221
+					// we will just use the generic WP callback for public endpoints
222
+					if (! isset($single_endpoint_args['permission_callback'])) {
223
+						$single_endpoint_args['permission_callback'] = '__return_true';
224
+					}
225
+					$multiple_endpoint_args[] = $single_endpoint_args;
226
+				}
227
+				if (isset($data_for_multiple_endpoints['schema'])) {
228
+					$schema_route_data = $data_for_multiple_endpoints['schema'];
229
+					$schema_callback = $schema_route_data['schema_callback'];
230
+					$callback_args = $schema_route_data['callback_args'];
231
+					$multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
232
+						return call_user_func_array(
233
+							$schema_callback,
234
+							$callback_args
235
+						);
236
+					};
237
+				}
238
+				register_rest_route(
239
+					$namespace,
240
+					$relative_route,
241
+					$multiple_endpoint_args
242
+				);
243
+			}
244
+		}
245
+	}
246
+
247
+
248
+	/**
249
+	 * Checks if there was a version change or something that merits invalidating the cached
250
+	 * route data. If so, invalidates the cached route data so that it gets refreshed
251
+	 * next time the WP API is used
252
+	 */
253
+	public static function invalidate_cached_route_data_on_version_change()
254
+	{
255
+		if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
256
+			EED_Core_Rest_Api::invalidate_cached_route_data();
257
+		}
258
+		foreach (EE_Registry::instance()->addons as $addon) {
259
+			if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
260
+				EED_Core_Rest_Api::invalidate_cached_route_data();
261
+			}
262
+		}
263
+	}
264
+
265
+
266
+	/**
267
+	 * Removes the cached route data so it will get refreshed next time the WP API is used
268
+	 */
269
+	public static function invalidate_cached_route_data()
270
+	{
271
+		// delete the saved EE REST API routes
272
+		foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
273
+			delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
274
+		}
275
+	}
276
+
277
+
278
+	/**
279
+	 * Gets the EE route data
280
+	 *
281
+	 * @return array top-level key is the namespace, next-level key is the route and its value is array{
282
+	 * @throws \EE_Error
283
+	 * @type string|array $callback
284
+	 * @type string       $methods
285
+	 * @type boolean      $hidden_endpoint
286
+	 * }
287
+	 */
288
+	public static function get_ee_route_data()
289
+	{
290
+		$ee_routes = array();
291
+		foreach (self::versions_served() as $version => $hidden_endpoints) {
292
+			$ee_routes[ self::ee_api_namespace . $version ] = self::_get_ee_route_data_for_version(
293
+				$version,
294
+				$hidden_endpoints
295
+			);
296
+		}
297
+		return $ee_routes;
298
+	}
299
+
300
+
301
+	/**
302
+	 * Gets the EE route data from the wp options if it exists already,
303
+	 * otherwise re-generates it and saves it to the option
304
+	 *
305
+	 * @param string  $version
306
+	 * @param boolean $hidden_endpoints
307
+	 * @return array
308
+	 * @throws \EE_Error
309
+	 */
310
+	protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
311
+	{
312
+		$ee_routes = get_option(self::saved_routes_option_names . $version, null);
313
+		if (! $ee_routes || EED_Core_Rest_Api::debugMode()) {
314
+			$ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
315
+		}
316
+		return $ee_routes;
317
+	}
318
+
319
+
320
+	/**
321
+	 * Saves the EE REST API route data to a wp option and returns it
322
+	 *
323
+	 * @param string  $version
324
+	 * @param boolean $hidden_endpoints
325
+	 * @return mixed|null
326
+	 * @throws \EE_Error
327
+	 */
328
+	protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
329
+	{
330
+		$instance = self::instance();
331
+		$routes = apply_filters(
332
+			'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
333
+			array_replace_recursive(
334
+				$instance->_get_config_route_data_for_version($version, $hidden_endpoints),
335
+				$instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
336
+				$instance->_get_model_route_data_for_version($version, $hidden_endpoints),
337
+				$instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
338
+			)
339
+		);
340
+		$option_name = self::saved_routes_option_names . $version;
341
+		if (get_option($option_name)) {
342
+			update_option($option_name, $routes, true);
343
+		} else {
344
+			add_option($option_name, $routes, null, 'no');
345
+		}
346
+		return $routes;
347
+	}
348
+
349
+
350
+	/**
351
+	 * Calculates all the EE routes and saves it to a WordPress option so we don't
352
+	 * need to calculate it on every request
353
+	 *
354
+	 * @deprecated since version 4.9.1
355
+	 * @return void
356
+	 */
357
+	public static function save_ee_routes()
358
+	{
359
+		if (EE_Maintenance_Mode::instance()->models_can_query()) {
360
+			$instance = self::instance();
361
+			$routes = apply_filters(
362
+				'EED_Core_Rest_Api__save_ee_routes__routes',
363
+				array_replace_recursive(
364
+					$instance->_register_config_routes(),
365
+					$instance->_register_meta_routes(),
366
+					$instance->_register_model_routes(),
367
+					$instance->_register_rpc_routes()
368
+				)
369
+			);
370
+			update_option(self::saved_routes_option_names, $routes, true);
371
+		}
372
+	}
373
+
374
+
375
+	/**
376
+	 * Gets all the route information relating to EE models
377
+	 *
378
+	 * @return array @see get_ee_route_data
379
+	 * @deprecated since version 4.9.1
380
+	 */
381
+	protected function _register_model_routes()
382
+	{
383
+		$model_routes = array();
384
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
385
+			$model_routes[ EED_Core_Rest_Api::ee_api_namespace
386
+						   . $version ] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
387
+		}
388
+		return $model_routes;
389
+	}
390
+
391
+
392
+	/**
393
+	 * Decides whether or not to add write endpoints for this model.
394
+	 *
395
+	 * Currently, this defaults to exclude all global tables and models
396
+	 * which would allow inserting WP core data (we don't want to duplicate
397
+	 * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
398
+	 *
399
+	 * @param EEM_Base $model
400
+	 * @return bool
401
+	 */
402
+	public static function should_have_write_endpoints(EEM_Base $model)
403
+	{
404
+		if ($model->is_wp_core_model()) {
405
+			return false;
406
+		}
407
+		foreach ($model->get_tables() as $table) {
408
+			if ($table->is_global()) {
409
+				return false;
410
+			}
411
+		}
412
+		return true;
413
+	}
414
+
415
+
416
+	/**
417
+	 * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
418
+	 * in this versioned namespace of EE4
419
+	 *
420
+	 * @param $version
421
+	 * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
422
+	 */
423
+	public static function model_names_with_plural_routes($version)
424
+	{
425
+		$model_version_info = new ModelVersionInfo($version);
426
+		$models_to_register = $model_version_info->modelsForRequestedVersion();
427
+		// let's not bother having endpoints for extra metas
428
+		unset(
429
+			$models_to_register['Extra_Meta'],
430
+			$models_to_register['Extra_Join'],
431
+			$models_to_register['Post_Meta']
432
+		);
433
+		return apply_filters(
434
+			'FHEE__EED_Core_REST_API___register_model_routes',
435
+			$models_to_register
436
+		);
437
+	}
438
+
439
+
440
+	/**
441
+	 * Gets the route data for EE models in the specified version
442
+	 *
443
+	 * @param string  $version
444
+	 * @param boolean $hidden_endpoint
445
+	 * @return array
446
+	 * @throws EE_Error
447
+	 */
448
+	protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
449
+	{
450
+		$model_routes = array();
451
+		$model_version_info = new ModelVersionInfo($version);
452
+		foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
453
+			$model = \EE_Registry::instance()->load_model($model_name);
454
+			// if this isn't a valid model then let's skip iterate to the next item in the loop.
455
+			if (! $model instanceof EEM_Base) {
456
+				continue;
457
+			}
458
+			// yes we could just register one route for ALL models, but then they wouldn't show up in the index
459
+			$plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
460
+			$singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
461
+			$model_routes[ $plural_model_route ] = array(
462
+				array(
463
+					'callback'        => array(
464
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
465
+						'handleRequestGetAll',
466
+					),
467
+					'callback_args'   => array($version, $model_name),
468
+					'methods'         => WP_REST_Server::READABLE,
469
+					'hidden_endpoint' => $hidden_endpoint,
470
+					'args'            => $this->_get_read_query_params($model, $version),
471
+					'_links'          => array(
472
+						'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
473
+					),
474
+				),
475
+				'schema' => array(
476
+					'schema_callback' => array(
477
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
478
+						'handleSchemaRequest',
479
+					),
480
+					'callback_args'   => array($version, $model_name),
481
+				),
482
+			);
483
+			$model_routes[ $singular_model_route ] = array(
484
+				array(
485
+					'callback'        => array(
486
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
487
+						'handleRequestGetOne',
488
+					),
489
+					'callback_args'   => array($version, $model_name),
490
+					'methods'         => WP_REST_Server::READABLE,
491
+					'hidden_endpoint' => $hidden_endpoint,
492
+					'args'            => $this->_get_response_selection_query_params($model, $version, true),
493
+				),
494
+			);
495
+			if (
496
+				apply_filters(
497
+					'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
498
+					EED_Core_Rest_Api::should_have_write_endpoints($model),
499
+					$model
500
+				)
501
+			) {
502
+				$model_routes[ $plural_model_route ][] = array(
503
+					'callback'        => array(
504
+						'EventEspresso\core\libraries\rest_api\controllers\model\Write',
505
+						'handleRequestInsert',
506
+					),
507
+					'callback_args'   => array($version, $model_name),
508
+					'methods'         => WP_REST_Server::CREATABLE,
509
+					'hidden_endpoint' => $hidden_endpoint,
510
+					'args'            => $this->_get_write_params($model_name, $model_version_info, true),
511
+				);
512
+				$model_routes[ $singular_model_route ] = array_merge(
513
+					$model_routes[ $singular_model_route ],
514
+					array(
515
+						array(
516
+							'callback'        => array(
517
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
518
+								'handleRequestUpdate',
519
+							),
520
+							'callback_args'   => array($version, $model_name),
521
+							'methods'         => WP_REST_Server::EDITABLE,
522
+							'hidden_endpoint' => $hidden_endpoint,
523
+							'args'            => $this->_get_write_params($model_name, $model_version_info),
524
+						),
525
+						array(
526
+							'callback'        => array(
527
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
528
+								'handleRequestDelete',
529
+							),
530
+							'callback_args'   => array($version, $model_name),
531
+							'methods'         => WP_REST_Server::DELETABLE,
532
+							'hidden_endpoint' => $hidden_endpoint,
533
+							'args'            => $this->_get_delete_query_params($model, $version),
534
+						),
535
+					)
536
+				);
537
+			}
538
+			foreach ($model->relation_settings() as $relation_name => $relation_obj) {
539
+				$related_route = EED_Core_Rest_Api::get_relation_route_via(
540
+					$model,
541
+					'(?P<id>[^\/]+)',
542
+					$relation_obj
543
+				);
544
+				$model_routes[ $related_route ] = array(
545
+					array(
546
+						'callback'        => array(
547
+							'EventEspresso\core\libraries\rest_api\controllers\model\Read',
548
+							'handleRequestGetRelated',
549
+						),
550
+						'callback_args'   => array($version, $model_name, $relation_name),
551
+						'methods'         => WP_REST_Server::READABLE,
552
+						'hidden_endpoint' => $hidden_endpoint,
553
+						'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
554
+					),
555
+				);
556
+
557
+				$related_write_route = $related_route . '/' . '(?P<related_id>[^\/]+)';
558
+				$model_routes[ $related_write_route ] = array(
559
+					array(
560
+						'callback'        => array(
561
+							'EventEspresso\core\libraries\rest_api\controllers\model\Write',
562
+							'handleRequestAddRelation',
563
+						),
564
+						'callback_args'   => array($version, $model_name, $relation_name),
565
+						'methods'         => WP_REST_Server::EDITABLE,
566
+						'hidden_endpoint' => $hidden_endpoint,
567
+						'args'            => $this->_get_add_relation_query_params($model, $relation_obj->get_other_model(), $version)
568
+					),
569
+					array(
570
+						'callback'        => array(
571
+							'EventEspresso\core\libraries\rest_api\controllers\model\Write',
572
+							'handleRequestRemoveRelation',
573
+						),
574
+						'callback_args'   => array($version, $model_name, $relation_name),
575
+						'methods'         => WP_REST_Server::DELETABLE,
576
+						'hidden_endpoint' => $hidden_endpoint,
577
+						'args'            => array()
578
+					),
579
+				);
580
+			}
581
+		}
582
+		return $model_routes;
583
+	}
584
+
585
+
586
+	/**
587
+	 * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
588
+	 * excluding the preceding slash.
589
+	 * Eg you pass get_plural_route_to('Event') = 'events'
590
+	 *
591
+	 * @param EEM_Base $model
592
+	 * @return string
593
+	 */
594
+	public static function get_collection_route(EEM_Base $model)
595
+	{
596
+		return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
597
+	}
598
+
599
+
600
+	/**
601
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
602
+	 * excluding the preceding slash.
603
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
604
+	 *
605
+	 * @param EEM_Base $model eg Event or Venue
606
+	 * @param string   $id
607
+	 * @return string
608
+	 */
609
+	public static function get_entity_route($model, $id)
610
+	{
611
+		return EED_Core_Rest_Api::get_collection_route($model) . '/' . $id;
612
+	}
613
+
614
+
615
+	/**
616
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
617
+	 * excluding the preceding slash.
618
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
619
+	 *
620
+	 * @param EEM_Base               $model eg Event or Venue
621
+	 * @param string                 $id
622
+	 * @param EE_Model_Relation_Base $relation_obj
623
+	 * @return string
624
+	 */
625
+	public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
626
+	{
627
+		$related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
628
+			$relation_obj->get_other_model()->get_this_model_name(),
629
+			$relation_obj
630
+		);
631
+		return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
632
+	}
633
+
634
+
635
+	/**
636
+	 * Adds onto the $relative_route the EE4 REST API versioned namespace.
637
+	 * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
638
+	 *
639
+	 * @param string $relative_route
640
+	 * @param string $version
641
+	 * @return string
642
+	 */
643
+	public static function get_versioned_route_to($relative_route, $version = '4.8.36')
644
+	{
645
+		return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
646
+	}
647
+
648
+
649
+	/**
650
+	 * Adds all the RPC-style routes (remote procedure call-like routes, ie
651
+	 * routes that don't conform to the traditional REST CRUD-style).
652
+	 *
653
+	 * @deprecated since 4.9.1
654
+	 */
655
+	protected function _register_rpc_routes()
656
+	{
657
+		$routes = array();
658
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
659
+			$routes[ self::ee_api_namespace . $version ] = $this->_get_rpc_route_data_for_version(
660
+				$version,
661
+				$hidden_endpoint
662
+			);
663
+		}
664
+		return $routes;
665
+	}
666
+
667
+
668
+	/**
669
+	 * @param string  $version
670
+	 * @param boolean $hidden_endpoint
671
+	 * @return array
672
+	 */
673
+	protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
674
+	{
675
+		$this_versions_routes = array();
676
+		// checkin endpoint
677
+		$this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
678
+			array(
679
+				'callback'        => array(
680
+					'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
681
+					'handleRequestToggleCheckin',
682
+				),
683
+				'methods'         => WP_REST_Server::CREATABLE,
684
+				'hidden_endpoint' => $hidden_endpoint,
685
+				'args'            => array(
686
+					'force' => array(
687
+						'required'    => false,
688
+						'default'     => false,
689
+						'description' => esc_html__(
690
+						// @codingStandardsIgnoreStart
691
+							'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
692
+							// @codingStandardsIgnoreEnd
693
+							'event_espresso'
694
+						),
695
+					),
696
+				),
697
+				'callback_args'   => array($version),
698
+			),
699
+		);
700
+		return apply_filters(
701
+			'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
702
+			$this_versions_routes,
703
+			$version,
704
+			$hidden_endpoint
705
+		);
706
+	}
707
+
708
+
709
+	/**
710
+	 * Gets the query params that can be used when request one or many
711
+	 *
712
+	 * @param EEM_Base $model
713
+	 * @param string   $version
714
+	 * @return array
715
+	 */
716
+	protected function _get_response_selection_query_params(\EEM_Base $model, $version, $single_only = false)
717
+	{
718
+		$query_params = array(
719
+			'include'   => array(
720
+				'required' => false,
721
+				'default'  => '*',
722
+				'type'     => 'string',
723
+			),
724
+			'calculate' => array(
725
+				'required'          => false,
726
+				'default'           => '',
727
+				'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
728
+				'type'              => 'string',
729
+				// because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
730
+				// freaks out. We'll just validate this argument while handling the request
731
+				'validate_callback' => null,
732
+				'sanitize_callback' => null,
733
+			),
734
+			'password' => array(
735
+				'required' => false,
736
+				'default' => '',
737
+				'type' => 'string'
738
+			)
739
+		);
740
+		return apply_filters(
741
+			'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
742
+			$query_params,
743
+			$model,
744
+			$version
745
+		);
746
+	}
747
+
748
+
749
+	/**
750
+	 * Gets the parameters acceptable for delete requests
751
+	 *
752
+	 * @param \EEM_Base $model
753
+	 * @param string    $version
754
+	 * @return array
755
+	 */
756
+	protected function _get_delete_query_params(\EEM_Base $model, $version)
757
+	{
758
+		$params_for_delete = array(
759
+			'allow_blocking' => array(
760
+				'required' => false,
761
+				'default'  => true,
762
+				'type'     => 'boolean',
763
+			),
764
+		);
765
+		$params_for_delete['force'] = array(
766
+			'required' => false,
767
+			'default'  => false,
768
+			'type'     => 'boolean',
769
+		);
770
+		return apply_filters(
771
+			'FHEE__EED_Core_Rest_Api___get_delete_query_params',
772
+			$params_for_delete,
773
+			$model,
774
+			$version
775
+		);
776
+	}
777
+
778
+	protected function _get_add_relation_query_params(\EEM_Base $source_model, \EEM_Base $related_model, $version)
779
+	{
780
+		// if they're related through a HABTM relation, check for any non-FKs
781
+		$all_relation_settings = $source_model->relation_settings();
782
+		$relation_settings = $all_relation_settings[ $related_model->get_this_model_name() ];
783
+		$params = array();
784
+		if ($relation_settings instanceof EE_HABTM_Relation && $relation_settings->hasNonKeyFields()) {
785
+			foreach ($relation_settings->getNonKeyFields() as $field) {
786
+				/* @var $field EE_Model_Field_Base */
787
+				$params[ $field->get_name() ] = array(
788
+					'required' => ! $field->is_nullable(),
789
+					'default' => ModelDataTranslator::prepareFieldValueForJson($field, $field->get_default_value(), $version),
790
+					'type' => $field->getSchemaType(),
791
+					'validate_callbaack' => null,
792
+					'sanitize_callback' => null
793
+				);
794
+			}
795
+		}
796
+		return $params;
797
+	}
798
+
799
+
800
+	/**
801
+	 * Gets info about reading query params that are acceptable
802
+	 *
803
+	 * @param \EEM_Base $model eg 'Event' or 'Venue'
804
+	 * @param  string   $version
805
+	 * @return array    describing the args acceptable when querying this model
806
+	 * @throws EE_Error
807
+	 */
808
+	protected function _get_read_query_params(\EEM_Base $model, $version)
809
+	{
810
+		$default_orderby = array();
811
+		foreach ($model->get_combined_primary_key_fields() as $key_field) {
812
+			$default_orderby[ $key_field->get_name() ] = 'ASC';
813
+		}
814
+		return array_merge(
815
+			$this->_get_response_selection_query_params($model, $version),
816
+			array(
817
+				'where'    => array(
818
+					'required'          => false,
819
+					'default'           => array(),
820
+					'type'              => 'object',
821
+					// because we accept an almost infinite list of possible where conditions, WP
822
+					// core validation and sanitization freaks out. We'll just validate this argument
823
+					// while handling the request
824
+					'validate_callback' => null,
825
+					'sanitize_callback' => null,
826
+				),
827
+				'limit'    => array(
828
+					'required'          => false,
829
+					'default'           => EED_Core_Rest_Api::get_default_query_limit(),
830
+					'type'              => array(
831
+						'array',
832
+						'string',
833
+						'integer',
834
+					),
835
+					// because we accept a variety of types, WP core validation and sanitization
836
+					// freaks out. We'll just validate this argument while handling the request
837
+					'validate_callback' => null,
838
+					'sanitize_callback' => null,
839
+				),
840
+				'order_by' => array(
841
+					'required'          => false,
842
+					'default'           => $default_orderby,
843
+					'type'              => array(
844
+						'object',
845
+						'string',
846
+					),// because we accept a variety of types, WP core validation and sanitization
847
+					// freaks out. We'll just validate this argument while handling the request
848
+					'validate_callback' => null,
849
+					'sanitize_callback' => null,
850
+				),
851
+				'group_by' => array(
852
+					'required'          => false,
853
+					'default'           => null,
854
+					'type'              => array(
855
+						'object',
856
+						'string',
857
+					),
858
+					// because we accept  an almost infinite list of possible groupings,
859
+					// WP core validation and sanitization
860
+					// freaks out. We'll just validate this argument while handling the request
861
+					'validate_callback' => null,
862
+					'sanitize_callback' => null,
863
+				),
864
+				'having'   => array(
865
+					'required'          => false,
866
+					'default'           => null,
867
+					'type'              => 'object',
868
+					// because we accept an almost infinite list of possible where conditions, WP
869
+					// core validation and sanitization freaks out. We'll just validate this argument
870
+					// while handling the request
871
+					'validate_callback' => null,
872
+					'sanitize_callback' => null,
873
+				),
874
+				'caps'     => array(
875
+					'required' => false,
876
+					'default'  => EEM_Base::caps_read,
877
+					'type'     => 'string',
878
+					'enum'     => array(
879
+						EEM_Base::caps_read,
880
+						EEM_Base::caps_read_admin,
881
+						EEM_Base::caps_edit,
882
+						EEM_Base::caps_delete,
883
+					),
884
+				),
885
+			)
886
+		);
887
+	}
888
+
889
+
890
+	/**
891
+	 * Gets parameter information for a model regarding writing data
892
+	 *
893
+	 * @param string           $model_name
894
+	 * @param ModelVersionInfo $model_version_info
895
+	 * @param boolean          $create                                       whether this is for request to create (in
896
+	 *                                                                       which case we need all required params) or
897
+	 *                                                                       just to update (in which case we don't
898
+	 *                                                                       need those on every request)
899
+	 * @return array
900
+	 */
901
+	protected function _get_write_params(
902
+		$model_name,
903
+		ModelVersionInfo $model_version_info,
904
+		$create = false
905
+	) {
906
+		$model = EE_Registry::instance()->load_model($model_name);
907
+		$fields = $model_version_info->fieldsOnModelInThisVersion($model);
908
+		$args_info = array();
909
+		foreach ($fields as $field_name => $field_obj) {
910
+			if ($field_obj->is_auto_increment()) {
911
+				// totally ignore auto increment IDs
912
+				continue;
913
+			}
914
+			$arg_info = $field_obj->getSchema();
915
+			$required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
916
+			$arg_info['required'] = $required;
917
+			// remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
918
+			unset($arg_info['readonly']);
919
+			$schema_properties = $field_obj->getSchemaProperties();
920
+			if (
921
+				isset($schema_properties['raw'])
922
+				&& $field_obj->getSchemaType() === 'object'
923
+			) {
924
+				// if there's a "raw" form of this argument, use those properties instead
925
+				$arg_info = array_replace(
926
+					$arg_info,
927
+					$schema_properties['raw']
928
+				);
929
+			}
930
+			$arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
931
+				$field_obj,
932
+				$field_obj->get_default_value(),
933
+				$model_version_info->requestedVersion()
934
+			);
935
+			// we do our own validation and sanitization within the controller
936
+			if (function_exists('rest_validate_value_from_schema')) {
937
+				$sanitize_callback = array(
938
+					'EED_Core_Rest_Api',
939
+					'default_sanitize_callback',
940
+				);
941
+			} else {
942
+				$sanitize_callback = null;
943
+			}
944
+			$arg_info['sanitize_callback'] = $sanitize_callback;
945
+			$args_info[ $field_name ] = $arg_info;
946
+			if ($field_obj instanceof EE_Datetime_Field) {
947
+				$gmt_arg_info = $arg_info;
948
+				$gmt_arg_info['description'] = sprintf(
949
+					esc_html__(
950
+						'%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
951
+						'event_espresso'
952
+					),
953
+					$field_obj->get_nicename(),
954
+					$field_name
955
+				);
956
+				$args_info[ $field_name . '_gmt' ] = $gmt_arg_info;
957
+			}
958
+		}
959
+		return $args_info;
960
+	}
961
+
962
+
963
+	/**
964
+	 * Replacement for WP API's 'rest_parse_request_arg'.
965
+	 * If the value is blank but not required, don't bother validating it.
966
+	 * Also, it uses our email validation instead of WP API's default.
967
+	 *
968
+	 * @param                 $value
969
+	 * @param WP_REST_Request $request
970
+	 * @param                 $param
971
+	 * @return bool|true|WP_Error
972
+	 * @throws InvalidArgumentException
973
+	 * @throws InvalidInterfaceException
974
+	 * @throws InvalidDataTypeException
975
+	 */
976
+	public static function default_sanitize_callback($value, WP_REST_Request $request, $param)
977
+	{
978
+		$attributes = $request->get_attributes();
979
+		if (
980
+			! isset($attributes['args'][ $param ])
981
+			|| ! is_array($attributes['args'][ $param ])
982
+		) {
983
+			$validation_result = true;
984
+		} else {
985
+			$args = $attributes['args'][ $param ];
986
+			if (
987
+				(
988
+					$value === ''
989
+					|| $value === null
990
+				)
991
+				&& (! isset($args['required'])
992
+					|| $args['required'] === false
993
+				)
994
+			) {
995
+				// not required and not provided? that's cool
996
+				$validation_result = true;
997
+			} elseif (
998
+				isset($args['format'])
999
+					  && $args['format'] === 'email'
1000
+			) {
1001
+				$validation_result = true;
1002
+				if (! self::_validate_email($value)) {
1003
+					$validation_result = new WP_Error(
1004
+						'rest_invalid_param',
1005
+						esc_html__(
1006
+							'The email address is not valid or does not exist.',
1007
+							'event_espresso'
1008
+						)
1009
+					);
1010
+				}
1011
+			} else {
1012
+				$validation_result = rest_validate_value_from_schema($value, $args, $param);
1013
+			}
1014
+		}
1015
+		if (is_wp_error($validation_result)) {
1016
+			return $validation_result;
1017
+		}
1018
+		return rest_sanitize_request_arg($value, $request, $param);
1019
+	}
1020
+
1021
+
1022
+	/**
1023
+	 * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
1024
+	 *
1025
+	 * @param $email
1026
+	 * @return bool
1027
+	 * @throws InvalidArgumentException
1028
+	 * @throws InvalidInterfaceException
1029
+	 * @throws InvalidDataTypeException
1030
+	 */
1031
+	protected static function _validate_email($email)
1032
+	{
1033
+		try {
1034
+			EmailAddressFactory::create($email);
1035
+			return true;
1036
+		} catch (EmailValidationException $e) {
1037
+			return false;
1038
+		}
1039
+	}
1040
+
1041
+
1042
+	/**
1043
+	 * Gets routes for the config
1044
+	 *
1045
+	 * @return array @see _register_model_routes
1046
+	 * @deprecated since version 4.9.1
1047
+	 */
1048
+	protected function _register_config_routes()
1049
+	{
1050
+		$config_routes = array();
1051
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
1052
+			$config_routes[ self::ee_api_namespace . $version ] = $this->_get_config_route_data_for_version(
1053
+				$version,
1054
+				$hidden_endpoint
1055
+			);
1056
+		}
1057
+		return $config_routes;
1058
+	}
1059
+
1060
+
1061
+	/**
1062
+	 * Gets routes for the config for the specified version
1063
+	 *
1064
+	 * @param string  $version
1065
+	 * @param boolean $hidden_endpoint
1066
+	 * @return array
1067
+	 */
1068
+	protected function _get_config_route_data_for_version($version, $hidden_endpoint)
1069
+	{
1070
+		return array(
1071
+			'config'    => array(
1072
+				array(
1073
+					'callback'        => array(
1074
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1075
+						'handleRequest',
1076
+					),
1077
+					'methods'         => WP_REST_Server::READABLE,
1078
+					'hidden_endpoint' => $hidden_endpoint,
1079
+					'callback_args'   => array($version),
1080
+				),
1081
+			),
1082
+			'site_info' => array(
1083
+				array(
1084
+					'callback'        => array(
1085
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1086
+						'handleRequestSiteInfo',
1087
+					),
1088
+					'methods'         => WP_REST_Server::READABLE,
1089
+					'hidden_endpoint' => $hidden_endpoint,
1090
+					'callback_args'   => array($version),
1091
+				),
1092
+			),
1093
+		);
1094
+	}
1095
+
1096
+
1097
+	/**
1098
+	 * Gets the meta info routes
1099
+	 *
1100
+	 * @return array @see _register_model_routes
1101
+	 * @deprecated since version 4.9.1
1102
+	 */
1103
+	protected function _register_meta_routes()
1104
+	{
1105
+		$meta_routes = array();
1106
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
1107
+			$meta_routes[ self::ee_api_namespace . $version ] = $this->_get_meta_route_data_for_version(
1108
+				$version,
1109
+				$hidden_endpoint
1110
+			);
1111
+		}
1112
+		return $meta_routes;
1113
+	}
1114
+
1115
+
1116
+	/**
1117
+	 * @param string  $version
1118
+	 * @param boolean $hidden_endpoint
1119
+	 * @return array
1120
+	 */
1121
+	protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1122
+	{
1123
+		return array(
1124
+			'resources' => array(
1125
+				array(
1126
+					'callback'        => array(
1127
+						'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1128
+						'handleRequestModelsMeta',
1129
+					),
1130
+					'methods'         => WP_REST_Server::READABLE,
1131
+					'hidden_endpoint' => $hidden_endpoint,
1132
+					'callback_args'   => array($version),
1133
+				),
1134
+			),
1135
+		);
1136
+	}
1137
+
1138
+
1139
+	/**
1140
+	 * Tries to hide old 4.6 endpoints from the
1141
+	 *
1142
+	 * @param array $route_data
1143
+	 * @return array
1144
+	 * @throws \EE_Error
1145
+	 */
1146
+	public static function hide_old_endpoints($route_data)
1147
+	{
1148
+		// allow API clients to override which endpoints get hidden, in case
1149
+		// they want to discover particular endpoints
1150
+		// also, we don't have access to the request so we have to just grab it from the superglobal
1151
+		$force_show_ee_namespace = ltrim(
1152
+			EED_Core_Rest_Api::getRequest()->getRequestParam('force_show_ee_namespace'),
1153
+			'/'
1154
+		);
1155
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1156
+			foreach ($relative_urls as $resource_name => $endpoints) {
1157
+				foreach ($endpoints as $key => $endpoint) {
1158
+					// skip schema and other route options
1159
+					if (! is_numeric($key)) {
1160
+						continue;
1161
+					}
1162
+					// by default, hide "hidden_endpoint"s, unless the request indicates
1163
+					// to $force_show_ee_namespace, in which case only show that one
1164
+					// namespace's endpoints (and hide all others)
1165
+					if (
1166
+						($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1167
+						|| ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1168
+					) {
1169
+						$full_route = '/' . ltrim($namespace, '/');
1170
+						$full_route .= '/' . ltrim($resource_name, '/');
1171
+						unset($route_data[ $full_route ]);
1172
+					}
1173
+				}
1174
+			}
1175
+		}
1176
+		return $route_data;
1177
+	}
1178
+
1179
+
1180
+	/**
1181
+	 * Returns an array describing which versions of core support serving requests for.
1182
+	 * Keys are core versions' major and minor version, and values are the
1183
+	 * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1184
+	 * data by just removing a few models and fields from the responses. However, 4.15 might remove
1185
+	 * the answers table entirely, in which case it would be very difficult for
1186
+	 * it to serve 4.6-style responses.
1187
+	 * Versions of core that are missing from this array are unknowns.
1188
+	 * previous ver
1189
+	 *
1190
+	 * @return array
1191
+	 */
1192
+	public static function version_compatibilities()
1193
+	{
1194
+		return apply_filters(
1195
+			'FHEE__EED_Core_REST_API__version_compatibilities',
1196
+			array(
1197
+				'4.8.29' => '4.8.29',
1198
+				'4.8.33' => '4.8.29',
1199
+				'4.8.34' => '4.8.29',
1200
+				'4.8.36' => '4.8.29',
1201
+			)
1202
+		);
1203
+	}
1204
+
1205
+
1206
+	/**
1207
+	 * Gets the latest API version served. Eg if there
1208
+	 * are two versions served of the API, 4.8.29 and 4.8.32, and
1209
+	 * we are on core version 4.8.34, it will return the string "4.8.32"
1210
+	 *
1211
+	 * @return string
1212
+	 */
1213
+	public static function latest_rest_api_version()
1214
+	{
1215
+		$versions_served = \EED_Core_Rest_Api::versions_served();
1216
+		$versions_served_keys = array_keys($versions_served);
1217
+		return end($versions_served_keys);
1218
+	}
1219
+
1220
+
1221
+	/**
1222
+	 * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1223
+	 * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1224
+	 * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1225
+	 * We also indicate whether or not this version should be put in the index or not
1226
+	 *
1227
+	 * @return array keys are API version numbers (just major and minor numbers), and values
1228
+	 * are whether or not they should be hidden
1229
+	 */
1230
+	public static function versions_served()
1231
+	{
1232
+		$versions_served = array();
1233
+		$possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1234
+		$lowest_compatible_version = end($possibly_served_versions);
1235
+		reset($possibly_served_versions);
1236
+		$versions_served_historically = array_keys($possibly_served_versions);
1237
+		$latest_version = end($versions_served_historically);
1238
+		reset($versions_served_historically);
1239
+		// for each version of core we have ever served:
1240
+		foreach ($versions_served_historically as $key_versioned_endpoint) {
1241
+			// if it's not above the current core version, and it's compatible with the current version of core
1242
+
1243
+			if ($key_versioned_endpoint === $latest_version) {
1244
+				// don't hide the latest version in the index
1245
+				$versions_served[ $key_versioned_endpoint ] = false;
1246
+			} elseif (
1247
+				version_compare($key_versioned_endpoint, $lowest_compatible_version, '>=')
1248
+				&& version_compare($key_versioned_endpoint, EED_Core_Rest_Api::core_version(), '<')
1249
+			) {
1250
+				// include, but hide, previous versions which are still supported
1251
+				$versions_served[ $key_versioned_endpoint ] = true;
1252
+			} elseif (
1253
+				apply_filters(
1254
+					'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1255
+					false,
1256
+					$possibly_served_versions
1257
+				)
1258
+			) {
1259
+				// if a version is no longer supported, don't include it in index or list of versions served
1260
+				$versions_served[ $key_versioned_endpoint ] = true;
1261
+			}
1262
+		}
1263
+		return $versions_served;
1264
+	}
1265
+
1266
+
1267
+	/**
1268
+	 * Gets the major and minor version of EE core's version string
1269
+	 *
1270
+	 * @return string
1271
+	 */
1272
+	public static function core_version()
1273
+	{
1274
+		return apply_filters(
1275
+			'FHEE__EED_Core_REST_API__core_version',
1276
+			implode(
1277
+				'.',
1278
+				array_slice(
1279
+					explode(
1280
+						'.',
1281
+						espresso_version()
1282
+					),
1283
+					0,
1284
+					3
1285
+				)
1286
+			)
1287
+		);
1288
+	}
1289
+
1290
+
1291
+	/**
1292
+	 * Gets the default limit that should be used when querying for resources
1293
+	 *
1294
+	 * @return int
1295
+	 */
1296
+	public static function get_default_query_limit()
1297
+	{
1298
+		// we actually don't use a const because we want folks to always use
1299
+		// this method, not the const directly
1300
+		return apply_filters(
1301
+			'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1302
+			50
1303
+		);
1304
+	}
1305
+
1306
+
1307
+	/**
1308
+	 *
1309
+	 * @param string $version api version string (i.e. '4.8.36')
1310
+	 * @return array
1311
+	 */
1312
+	public static function getCollectionRoutesIndexedByModelName($version = '')
1313
+	{
1314
+		$version = empty($version) ? self::latest_rest_api_version() : $version;
1315
+		$model_names = self::model_names_with_plural_routes($version);
1316
+		$collection_routes = array();
1317
+		foreach ($model_names as $model_name => $model_class_name) {
1318
+			$collection_routes[ strtolower($model_name) ] = '/' . self::ee_api_namespace . $version . '/'
1319
+															. EEH_Inflector::pluralize_and_lower($model_name);
1320
+		}
1321
+		return $collection_routes;
1322
+	}
1323
+
1324
+
1325
+	/**
1326
+	 * Returns an array of primary key names indexed by model names.
1327
+	 * @param string $version
1328
+	 * @return array
1329
+	 */
1330
+	public static function getPrimaryKeyNamesIndexedByModelName($version = '')
1331
+	{
1332
+		$version = empty($version) ? self::latest_rest_api_version() : $version;
1333
+		$model_names = self::model_names_with_plural_routes($version);
1334
+		$primary_key_items = array();
1335
+		foreach ($model_names as $model_name => $model_class_name) {
1336
+			$primary_keys = $model_class_name::instance()->get_combined_primary_key_fields();
1337
+			foreach ($primary_keys as $primary_key_name => $primary_key_field) {
1338
+				if (count($primary_keys) > 1) {
1339
+					$primary_key_items[ strtolower($model_name) ][] = $primary_key_name;
1340
+				} else {
1341
+					$primary_key_items[ strtolower($model_name) ] = $primary_key_name;
1342
+				}
1343
+			}
1344
+		}
1345
+		return $primary_key_items;
1346
+	}
1347
+
1348
+	/**
1349
+	 * Determines the EE REST API debug mode is activated, or not.
1350
+	 * @since 4.9.76.p
1351
+	 * @return bool
1352
+	 */
1353
+	public static function debugMode()
1354
+	{
1355
+		static $debug_mode = null; // could be class prop
1356
+		if ($debug_mode === null) {
1357
+			$debug_mode = defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE;
1358
+		}
1359
+		return $debug_mode;
1360
+	}
1361
+
1362
+
1363
+
1364
+	/**
1365
+	 *    run - initial module setup
1366
+	 *
1367
+	 * @access    public
1368
+	 * @param  WP $WP
1369
+	 * @return    void
1370
+	 */
1371
+	public function run($WP)
1372
+	{
1373
+	}
1374 1374
 }
Please login to merge, or discard this patch.
modules/invoice/EED_Invoice.module.php 1 patch
Indentation   +77 added lines, -77 removed lines patch added patch discarded remove patch
@@ -12,91 +12,91 @@
 block discarded – undo
12 12
 {
13 13
 
14 14
 
15
-    /**
16
-     * @return EED_Invoice|EED_Module
17
-     * @throws EE_Error
18
-     * @throws ReflectionException
19
-     */
20
-    public static function instance()
21
-    {
22
-        return parent::get_instance(__CLASS__);
23
-    }
15
+	/**
16
+	 * @return EED_Invoice|EED_Module
17
+	 * @throws EE_Error
18
+	 * @throws ReflectionException
19
+	 */
20
+	public static function instance()
21
+	{
22
+		return parent::get_instance(__CLASS__);
23
+	}
24 24
 
25 25
 
26
-    /**
27
-     *    set_hooks - for hooking into EE Core, other modules, etc
28
-     *
29
-     * @access    public
30
-     * @return    void
31
-     */
32
-    public static function set_hooks()
33
-    {
34
-        EE_Config::register_route('download_invoice', 'EED_Invoice', 'download_invoice');
35
-        EE_Config::register_route('launch_invoice', 'EED_Invoice', 'launch_invoice');
36
-    }
26
+	/**
27
+	 *    set_hooks - for hooking into EE Core, other modules, etc
28
+	 *
29
+	 * @access    public
30
+	 * @return    void
31
+	 */
32
+	public static function set_hooks()
33
+	{
34
+		EE_Config::register_route('download_invoice', 'EED_Invoice', 'download_invoice');
35
+		EE_Config::register_route('launch_invoice', 'EED_Invoice', 'launch_invoice');
36
+	}
37 37
 
38 38
 
39
-    /**
40
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
41
-     *
42
-     * @access    public
43
-     * @return    void
44
-     */
45
-    public static function set_hooks_admin()
46
-    {
47
-    }
39
+	/**
40
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
41
+	 *
42
+	 * @access    public
43
+	 * @return    void
44
+	 */
45
+	public static function set_hooks_admin()
46
+	{
47
+	}
48 48
 
49 49
 
50
-    /**
51
-     *    run - initial module setup
52
-     *
53
-     * @access    public
54
-     * @return    void
55
-     */
56
-    public function run($WP)
57
-    {
58
-        if (is_readable(EE_MODULES . 'gateways/Invoice/lib/Invoice.class.php')) {
59
-            require_once(EE_MODULES . 'gateways/Invoice/lib/Invoice.class.php');
60
-        } else {
61
-            $msg = esc_html__('The Invoice.class.php file could not be loaded.', 'event_espresso');
62
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
63
-        }
64
-    }
50
+	/**
51
+	 *    run - initial module setup
52
+	 *
53
+	 * @access    public
54
+	 * @return    void
55
+	 */
56
+	public function run($WP)
57
+	{
58
+		if (is_readable(EE_MODULES . 'gateways/Invoice/lib/Invoice.class.php')) {
59
+			require_once(EE_MODULES . 'gateways/Invoice/lib/Invoice.class.php');
60
+		} else {
61
+			$msg = esc_html__('The Invoice.class.php file could not be loaded.', 'event_espresso');
62
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
63
+		}
64
+	}
65 65
 
66 66
 
67
-    /**
68
-     *    invoice_launch
69
-     *
70
-     * @access    public
71
-     * @return    void
72
-     */
73
-    public function launch_invoice()
74
-    {
75
-        $this->run(null);
76
-        $request = self::getRequest();
77
-        if ($request->requestParamIsSet('id')) {
78
-            $id = $request->getRequestParam('id', '', 'key');
79
-            $invoice = new Invoice($id);
80
-            $invoice->send_invoice();
81
-        }
82
-    }
67
+	/**
68
+	 *    invoice_launch
69
+	 *
70
+	 * @access    public
71
+	 * @return    void
72
+	 */
73
+	public function launch_invoice()
74
+	{
75
+		$this->run(null);
76
+		$request = self::getRequest();
77
+		if ($request->requestParamIsSet('id')) {
78
+			$id = $request->getRequestParam('id', '', 'key');
79
+			$invoice = new Invoice($id);
80
+			$invoice->send_invoice();
81
+		}
82
+	}
83 83
 
84 84
 
85
-    /**
86
-     *    download_invoice
87
-     *
88
-     * @access    public
89
-     * @return    void
90
-     */
91
-    public function download_invoice()
92
-    {
93
-        $this->run(null);
94
-        $request = self::getRequest();
95
-        if ($request->requestParamIsSet('id')) {
96
-            $id = $request->getRequestParam('id', '', 'key');
97
-            $invoice = new Invoice($id);
98
-            // send invoice but force download
99
-            $invoice->send_invoice(true);
100
-        }
101
-    }
85
+	/**
86
+	 *    download_invoice
87
+	 *
88
+	 * @access    public
89
+	 * @return    void
90
+	 */
91
+	public function download_invoice()
92
+	{
93
+		$this->run(null);
94
+		$request = self::getRequest();
95
+		if ($request->requestParamIsSet('id')) {
96
+			$id = $request->getRequestParam('id', '', 'key');
97
+			$invoice = new Invoice($id);
98
+			// send invoice but force download
99
+			$invoice->send_invoice(true);
100
+		}
101
+	}
102 102
 }
Please login to merge, or discard this patch.
modules/invalid_checkout_access/InvalidCheckoutAccess.php 2 patches
Indentation   +171 added lines, -171 removed lines patch added patch discarded remove patch
@@ -27,181 +27,181 @@
 block discarded – undo
27 27
 class InvalidCheckoutAccess
28 28
 {
29 29
 
30
-    /**
31
-     * key used for saving invalid checkout access data to the wp_options table
32
-     */
33
-    const OPTION_KEY = 'ee_invalid_checkout_access';
30
+	/**
31
+	 * key used for saving invalid checkout access data to the wp_options table
32
+	 */
33
+	const OPTION_KEY = 'ee_invalid_checkout_access';
34 34
 
35 35
 
36
-    /**
37
-     * _block_bots
38
-     * checks that the incoming request has either of the following set:
39
-     *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
40
-     *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
41
-     * so if you're not coming from the Ticket Selector nor returning for a valid IP...
42
-     * then where you coming from man?
43
-     *
44
-     * @param EE_Checkout $checkout
45
-     * @return bool true if access to registration checkout appears to be invalid
46
-     */
47
-    public function checkoutAccessIsInvalid(EE_Checkout $checkout)
48
-    {
49
-        if (
50
-            ! ($checkout->uts || $checkout->reg_url_link)
51
-            && ! (defined('DOING_AJAX') && DOING_AJAX)
52
-            && EE_Config::instance()->registration->track_invalid_checkout_access()
53
-        ) {
54
-            /** @var RequestInterface $request */
55
-            $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
56
-            $ip_address = $request->ipAddress();
57
-            $ee_bot_checkout = get_option(InvalidCheckoutAccess::OPTION_KEY);
58
-            if ($ee_bot_checkout === false) {
59
-                $ee_bot_checkout = array();
60
-                add_option(InvalidCheckoutAccess::OPTION_KEY, $ee_bot_checkout, '', false);
61
-            }
62
-            if (! isset($ee_bot_checkout[ $ip_address ])) {
63
-                $ee_bot_checkout[ $ip_address ] = array();
64
-            }
65
-            $http_referer = esc_attr($request->getServerParam('HTTP_REFERER', 0));
66
-            if (! isset($ee_bot_checkout[ $ip_address ][ $http_referer ])) {
67
-                $ee_bot_checkout[ $ip_address ][ $http_referer ] = 0;
68
-            }
69
-            $ee_bot_checkout[ $ip_address ][ $http_referer ]++;
70
-            update_option(InvalidCheckoutAccess::OPTION_KEY, $ee_bot_checkout);
71
-            if (WP_DEBUG) {
72
-                EE_Error::add_error(
73
-                    esc_html__('Direct access to the registration checkout page is not allowed.', 'event_espresso'),
74
-                    __FILE__,
75
-                    __FUNCTION__,
76
-                    __LINE__
77
-                );
78
-            }
79
-            return true;
80
-        }
81
-        return false;
82
-    }
36
+	/**
37
+	 * _block_bots
38
+	 * checks that the incoming request has either of the following set:
39
+	 *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
40
+	 *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
41
+	 * so if you're not coming from the Ticket Selector nor returning for a valid IP...
42
+	 * then where you coming from man?
43
+	 *
44
+	 * @param EE_Checkout $checkout
45
+	 * @return bool true if access to registration checkout appears to be invalid
46
+	 */
47
+	public function checkoutAccessIsInvalid(EE_Checkout $checkout)
48
+	{
49
+		if (
50
+			! ($checkout->uts || $checkout->reg_url_link)
51
+			&& ! (defined('DOING_AJAX') && DOING_AJAX)
52
+			&& EE_Config::instance()->registration->track_invalid_checkout_access()
53
+		) {
54
+			/** @var RequestInterface $request */
55
+			$request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
56
+			$ip_address = $request->ipAddress();
57
+			$ee_bot_checkout = get_option(InvalidCheckoutAccess::OPTION_KEY);
58
+			if ($ee_bot_checkout === false) {
59
+				$ee_bot_checkout = array();
60
+				add_option(InvalidCheckoutAccess::OPTION_KEY, $ee_bot_checkout, '', false);
61
+			}
62
+			if (! isset($ee_bot_checkout[ $ip_address ])) {
63
+				$ee_bot_checkout[ $ip_address ] = array();
64
+			}
65
+			$http_referer = esc_attr($request->getServerParam('HTTP_REFERER', 0));
66
+			if (! isset($ee_bot_checkout[ $ip_address ][ $http_referer ])) {
67
+				$ee_bot_checkout[ $ip_address ][ $http_referer ] = 0;
68
+			}
69
+			$ee_bot_checkout[ $ip_address ][ $http_referer ]++;
70
+			update_option(InvalidCheckoutAccess::OPTION_KEY, $ee_bot_checkout);
71
+			if (WP_DEBUG) {
72
+				EE_Error::add_error(
73
+					esc_html__('Direct access to the registration checkout page is not allowed.', 'event_espresso'),
74
+					__FILE__,
75
+					__FUNCTION__,
76
+					__LINE__
77
+				);
78
+			}
79
+			return true;
80
+		}
81
+		return false;
82
+	}
83 83
 
84 84
 
85
-    /**
86
-     * _invalid_checkout_access_form
87
-     *
88
-     * @return EE_Form_Section_Proper
89
-     * @throws EE_Error
90
-     */
91
-    public function getForm()
92
-    {
93
-        return new EE_Form_Section_Proper(
94
-            array(
95
-                'name'            => 'invalid_checkout_access',
96
-                'html_id'         => 'invalid_checkout_access',
97
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
98
-                'subsections'     => array(
99
-                    'invalid_checkout_access_hdr'   => new EE_Form_Section_HTML(
100
-                        EEH_HTML::h2(esc_html__('Invalid Checkout Access', 'event_espresso'))
101
-                    ),
102
-                    'ee_bot_checkout_data'          => new EE_Text_Area_Input(
103
-                        array(
104
-                            'html_label_text' => esc_html__('Invalid Checkout Data', 'event_espresso'),
105
-                            'default'         => var_export(
106
-                                get_option(InvalidCheckoutAccess::OPTION_KEY, array()),
107
-                                true
108
-                            ),
109
-                            'required'        => false,
110
-                            'html_help_text'  => esc_html__(
111
-                                'Event Espresso blocks any attempt to directly access the registration checkout page, that is NOT from a Ticket Selector or for a return visit for a valid transaction. These are not valid requests accessing your checkout page, so we track the IP addresses, what web page they just came from, and the number of times that they have attempted to access your registration page. This information may help you with protecting your site by other means, such as firewalls, etc, but please note that IP addresses are almost guaranteed to be spoofed by malicious agents.',
112
-                                'event_espresso'
113
-                            ),
114
-                        )
115
-                    ),
116
-                    'track_invalid_checkout_access' => new EE_Yes_No_Input(
117
-                        array(
118
-                            'html_label_text'         => esc_html__('Track Invalid Checkout Access?', 'event_espresso'),
119
-                            'html_help_text'          => esc_html__(
120
-                                'Controls whether or not invalid attempts to directly access the registration checkout page should be tracked. Setting this to "No" means that the above data will no longer be collected.',
121
-                                'event_espresso'
122
-                            ),
123
-                            'default'                 => EE_Config::instance()
124
-                                ->registration
125
-                                ->track_invalid_checkout_access(),
126
-                            'display_html_label_text' => false,
127
-                        )
128
-                    ),
129
-                    'delete_invalid_checkout_data'  => new EE_Yes_No_Input(
130
-                        array(
131
-                            'html_label_text'         => esc_html__('Reset Invalid Checkout Data', 'event_espresso'),
132
-                            'html_help_text'          => esc_html__(
133
-                                'Setting this to "Yes" will delete all existing invalid checkout access data.',
134
-                                'event_espresso'
135
-                            ),
136
-                            'default'                 => false,
137
-                            'display_html_label_text' => false,
138
-                        )
139
-                    ),
140
-                ),
141
-            )
142
-        );
143
-    }
85
+	/**
86
+	 * _invalid_checkout_access_form
87
+	 *
88
+	 * @return EE_Form_Section_Proper
89
+	 * @throws EE_Error
90
+	 */
91
+	public function getForm()
92
+	{
93
+		return new EE_Form_Section_Proper(
94
+			array(
95
+				'name'            => 'invalid_checkout_access',
96
+				'html_id'         => 'invalid_checkout_access',
97
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
98
+				'subsections'     => array(
99
+					'invalid_checkout_access_hdr'   => new EE_Form_Section_HTML(
100
+						EEH_HTML::h2(esc_html__('Invalid Checkout Access', 'event_espresso'))
101
+					),
102
+					'ee_bot_checkout_data'          => new EE_Text_Area_Input(
103
+						array(
104
+							'html_label_text' => esc_html__('Invalid Checkout Data', 'event_espresso'),
105
+							'default'         => var_export(
106
+								get_option(InvalidCheckoutAccess::OPTION_KEY, array()),
107
+								true
108
+							),
109
+							'required'        => false,
110
+							'html_help_text'  => esc_html__(
111
+								'Event Espresso blocks any attempt to directly access the registration checkout page, that is NOT from a Ticket Selector or for a return visit for a valid transaction. These are not valid requests accessing your checkout page, so we track the IP addresses, what web page they just came from, and the number of times that they have attempted to access your registration page. This information may help you with protecting your site by other means, such as firewalls, etc, but please note that IP addresses are almost guaranteed to be spoofed by malicious agents.',
112
+								'event_espresso'
113
+							),
114
+						)
115
+					),
116
+					'track_invalid_checkout_access' => new EE_Yes_No_Input(
117
+						array(
118
+							'html_label_text'         => esc_html__('Track Invalid Checkout Access?', 'event_espresso'),
119
+							'html_help_text'          => esc_html__(
120
+								'Controls whether or not invalid attempts to directly access the registration checkout page should be tracked. Setting this to "No" means that the above data will no longer be collected.',
121
+								'event_espresso'
122
+							),
123
+							'default'                 => EE_Config::instance()
124
+								->registration
125
+								->track_invalid_checkout_access(),
126
+							'display_html_label_text' => false,
127
+						)
128
+					),
129
+					'delete_invalid_checkout_data'  => new EE_Yes_No_Input(
130
+						array(
131
+							'html_label_text'         => esc_html__('Reset Invalid Checkout Data', 'event_espresso'),
132
+							'html_help_text'          => esc_html__(
133
+								'Setting this to "Yes" will delete all existing invalid checkout access data.',
134
+								'event_espresso'
135
+							),
136
+							'default'                 => false,
137
+							'display_html_label_text' => false,
138
+						)
139
+					),
140
+				),
141
+			)
142
+		);
143
+	}
144 144
 
145 145
 
146
-    /**
147
-     * update_invalid_checkout_access_form
148
-     *
149
-     * @param EE_Registration_Config $EE_Registration_Config
150
-     * @return EE_Registration_Config
151
-     * @throws EE_Error
152
-     * @throws ReflectionException
153
-     */
154
-    public function processForm(EE_Registration_Config $EE_Registration_Config)
155
-    {
156
-        try {
157
-            $invalid_checkout_access_form = $this->getForm();
158
-            // if not displaying a form, then check for form submission
159
-            if ($invalid_checkout_access_form->was_submitted()) {
160
-                // capture form data
161
-                $invalid_checkout_access_form->receive_form_submission();
162
-                // validate form data
163
-                if ($invalid_checkout_access_form->is_valid()) {
164
-                    // grab validated data from form
165
-                    $valid_data = $invalid_checkout_access_form->valid_data();
166
-                    // ensure form inputs we want are set
167
-                    if (
168
-                        isset(
169
-                            $valid_data['track_invalid_checkout_access'],
170
-                            $valid_data['delete_invalid_checkout_data']
171
-                        )
172
-                    ) {
173
-                        $EE_Registration_Config->set_track_invalid_checkout_access(
174
-                            $valid_data['track_invalid_checkout_access']
175
-                        );
176
-                        // if deleting, then update option with empty array
177
-                        if (filter_var($valid_data['delete_invalid_checkout_data'], FILTER_VALIDATE_BOOLEAN)) {
178
-                            update_option(InvalidCheckoutAccess::OPTION_KEY, array());
179
-                        }
180
-                    } else {
181
-                        EE_Error::add_error(
182
-                            esc_html__(
183
-                                'Invalid or missing Invalid Checkout Access form data. Please refresh the form and try again.',
184
-                                'event_espresso'
185
-                            ),
186
-                            __FILE__,
187
-                            __FUNCTION__,
188
-                            __LINE__
189
-                        );
190
-                    }
191
-                } else {
192
-                    if ($invalid_checkout_access_form->submission_error_message() !== '') {
193
-                        EE_Error::add_error(
194
-                            $invalid_checkout_access_form->submission_error_message(),
195
-                            __FILE__,
196
-                            __FUNCTION__,
197
-                            __LINE__
198
-                        );
199
-                    }
200
-                }
201
-            }
202
-        } catch (EE_Error $e) {
203
-            $e->get_error();
204
-        }
205
-        return $EE_Registration_Config;
206
-    }
146
+	/**
147
+	 * update_invalid_checkout_access_form
148
+	 *
149
+	 * @param EE_Registration_Config $EE_Registration_Config
150
+	 * @return EE_Registration_Config
151
+	 * @throws EE_Error
152
+	 * @throws ReflectionException
153
+	 */
154
+	public function processForm(EE_Registration_Config $EE_Registration_Config)
155
+	{
156
+		try {
157
+			$invalid_checkout_access_form = $this->getForm();
158
+			// if not displaying a form, then check for form submission
159
+			if ($invalid_checkout_access_form->was_submitted()) {
160
+				// capture form data
161
+				$invalid_checkout_access_form->receive_form_submission();
162
+				// validate form data
163
+				if ($invalid_checkout_access_form->is_valid()) {
164
+					// grab validated data from form
165
+					$valid_data = $invalid_checkout_access_form->valid_data();
166
+					// ensure form inputs we want are set
167
+					if (
168
+						isset(
169
+							$valid_data['track_invalid_checkout_access'],
170
+							$valid_data['delete_invalid_checkout_data']
171
+						)
172
+					) {
173
+						$EE_Registration_Config->set_track_invalid_checkout_access(
174
+							$valid_data['track_invalid_checkout_access']
175
+						);
176
+						// if deleting, then update option with empty array
177
+						if (filter_var($valid_data['delete_invalid_checkout_data'], FILTER_VALIDATE_BOOLEAN)) {
178
+							update_option(InvalidCheckoutAccess::OPTION_KEY, array());
179
+						}
180
+					} else {
181
+						EE_Error::add_error(
182
+							esc_html__(
183
+								'Invalid or missing Invalid Checkout Access form data. Please refresh the form and try again.',
184
+								'event_espresso'
185
+							),
186
+							__FILE__,
187
+							__FUNCTION__,
188
+							__LINE__
189
+						);
190
+					}
191
+				} else {
192
+					if ($invalid_checkout_access_form->submission_error_message() !== '') {
193
+						EE_Error::add_error(
194
+							$invalid_checkout_access_form->submission_error_message(),
195
+							__FILE__,
196
+							__FUNCTION__,
197
+							__LINE__
198
+						);
199
+					}
200
+				}
201
+			}
202
+		} catch (EE_Error $e) {
203
+			$e->get_error();
204
+		}
205
+		return $EE_Registration_Config;
206
+	}
207 207
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -59,14 +59,14 @@
 block discarded – undo
59 59
                 $ee_bot_checkout = array();
60 60
                 add_option(InvalidCheckoutAccess::OPTION_KEY, $ee_bot_checkout, '', false);
61 61
             }
62
-            if (! isset($ee_bot_checkout[ $ip_address ])) {
63
-                $ee_bot_checkout[ $ip_address ] = array();
62
+            if ( ! isset($ee_bot_checkout[$ip_address])) {
63
+                $ee_bot_checkout[$ip_address] = array();
64 64
             }
65 65
             $http_referer = esc_attr($request->getServerParam('HTTP_REFERER', 0));
66
-            if (! isset($ee_bot_checkout[ $ip_address ][ $http_referer ])) {
67
-                $ee_bot_checkout[ $ip_address ][ $http_referer ] = 0;
66
+            if ( ! isset($ee_bot_checkout[$ip_address][$http_referer])) {
67
+                $ee_bot_checkout[$ip_address][$http_referer] = 0;
68 68
             }
69
-            $ee_bot_checkout[ $ip_address ][ $http_referer ]++;
69
+            $ee_bot_checkout[$ip_address][$http_referer]++;
70 70
             update_option(InvalidCheckoutAccess::OPTION_KEY, $ee_bot_checkout);
71 71
             if (WP_DEBUG) {
72 72
                 EE_Error::add_error(
Please login to merge, or discard this patch.