Completed
Branch BUG-10738-inconsistency-in-ses... (cda363)
by
unknown
13:38 queued 12s
created
core/exceptions/InvalidEntityException.php 2 patches
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -3,7 +3,7 @@  discard block
 block discarded – undo
3 3
 namespace EventEspresso\core\exceptions;
4 4
 
5 5
 if (! defined('EVENT_ESPRESSO_VERSION')) {
6
-    exit('No direct script access allowed');
6
+	exit('No direct script access allowed');
7 7
 }
8 8
 
9 9
 
@@ -18,32 +18,32 @@  discard block
 block discarded – undo
18 18
 class InvalidEntityException extends \InvalidArgumentException
19 19
 {
20 20
 
21
-    /**
22
-     * InvalidInterfaceException constructor.
23
-     *
24
-     * @param string     $actual   classname of what we got
25
-     * @param string     $expected classname of the entity we wanted
26
-     * @param string     $message
27
-     * @param int        $code
28
-     * @param \Exception $previous
29
-     */
30
-    public function __construct($actual, $expected, $message = '', $code = 0, \Exception $previous = null)
31
-    {
32
-        if (empty($message)) {
33
-            $message = sprintf(
34
-                __(
35
-                    'The supplied entity is an instance of "%1$s", but an instance of "%2$s" was expected. Object: %3$s',
36
-                    'event_espresso'
37
-                ),
38
-                is_object($actual)
39
-                    ? get_class($actual)
40
-                    : gettype($actual),
41
-                $expected,
42
-                var_export($actual, true)
43
-            );
44
-        }
45
-        parent::__construct($message, $code, $previous);
46
-    }
21
+	/**
22
+	 * InvalidInterfaceException constructor.
23
+	 *
24
+	 * @param string     $actual   classname of what we got
25
+	 * @param string     $expected classname of the entity we wanted
26
+	 * @param string     $message
27
+	 * @param int        $code
28
+	 * @param \Exception $previous
29
+	 */
30
+	public function __construct($actual, $expected, $message = '', $code = 0, \Exception $previous = null)
31
+	{
32
+		if (empty($message)) {
33
+			$message = sprintf(
34
+				__(
35
+					'The supplied entity is an instance of "%1$s", but an instance of "%2$s" was expected. Object: %3$s',
36
+					'event_espresso'
37
+				),
38
+				is_object($actual)
39
+					? get_class($actual)
40
+					: gettype($actual),
41
+				$expected,
42
+				var_export($actual, true)
43
+			);
44
+		}
45
+		parent::__construct($message, $code, $previous);
46
+	}
47 47
 
48 48
 }
49 49
 // End of file InvalidEntityException.php
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@
 block discarded – undo
2 2
 
3 3
 namespace EventEspresso\core\exceptions;
4 4
 
5
-if (! defined('EVENT_ESPRESSO_VERSION')) {
5
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
6 6
     exit('No direct script access allowed');
7 7
 }
8 8
 
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_Email_Input.input.php 1 patch
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -6,22 +6,22 @@
 block discarded – undo
6 6
  * @subpackage
7 7
  * @author				Mike Nelson
8 8
  */
9
-class EE_Email_Input extends EE_Form_Input_Base{
9
+class EE_Email_Input extends EE_Form_Input_Base {
10 10
 
11 11
 	/**
12 12
 	 * @param array $input_settings
13 13
 	 */
14
-	public function __construct( $input_settings = array() ){
15
-		$this->_set_display_strategy( new EE_Text_Input_Display_Strategy('email') );
16
-		$this->_set_normalization_strategy( new EE_Text_Normalization() );
14
+	public function __construct($input_settings = array()) {
15
+		$this->_set_display_strategy(new EE_Text_Input_Display_Strategy('email'));
16
+		$this->_set_normalization_strategy(new EE_Text_Normalization());
17 17
 		$this->_add_validation_strategy(
18 18
 			new EE_Email_Validation_Strategy(
19
-				isset( $input_settings[ 'validation_error_message' ] )
20
-					? $input_settings[ 'validation_error_message' ]
19
+				isset($input_settings['validation_error_message'])
20
+					? $input_settings['validation_error_message']
21 21
 					: NULL
22 22
 			)
23 23
 		);
24
-		parent::__construct( $input_settings );
25
-		$this->set_html_class( $this->html_class() . ' email' );
24
+		parent::__construct($input_settings);
25
+		$this->set_html_class($this->html_class().' email');
26 26
 	}
27 27
 }
Please login to merge, or discard this patch.
admin_pages/transactions/EE_Admin_Transactions_List_Table.class.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
      *
103 103
      * @abstract
104 104
      * @access protected
105
-     * @return array
105
+     * @return string[]
106 106
      */
107 107
     protected function _get_table_filters()
108 108
     {
@@ -265,7 +265,7 @@  discard block
 block discarded – undo
265 265
      *    column_TXN_paid
266 266
      *
267 267
      * @param \EE_Transaction $transaction
268
-     * @return mixed|string
268
+     * @return string
269 269
      * @throws \EE_Error
270 270
      */
271 271
     public function column_TXN_paid(EE_Transaction $transaction)
Please login to merge, or discard this patch.
Indentation   +606 added lines, -606 removed lines patch added patch discarded remove patch
@@ -13,114 +13,114 @@  discard block
 block discarded – undo
13 13
 class EE_Admin_Transactions_List_Table extends EE_Admin_List_Table
14 14
 {
15 15
 
16
-    private $_status;
17
-
18
-
19
-    /**
20
-     * @param \Transactions_Admin_Page $admin_page
21
-     */
22
-    public function __construct(\Transactions_Admin_Page $admin_page)
23
-    {
24
-        parent::__construct($admin_page);
25
-        $this->_status = $this->_admin_page->get_transaction_status_array();
26
-    }
27
-
28
-
29
-    /**
30
-     *_setup_data
31
-     */
32
-    protected function _setup_data()
33
-    {
34
-        $this->_data           = $this->_admin_page->get_transactions($this->_per_page);
35
-        $status                = ! empty($this->_req_data['status']) ? $this->_req_data['status'] : 'all';
36
-        $this->_all_data_count = $this->_admin_page->get_transactions($this->_per_page, true, $status);
37
-    }
38
-
39
-
40
-    /**
41
-     *_set_properties
42
-     */
43
-    protected function _set_properties()
44
-    {
45
-        $this->_wp_list_args = array(
46
-            'singular' => __('transaction', 'event_espresso'),
47
-            'plural'   => __('transactions', 'event_espresso'),
48
-            'ajax'     => true,
49
-            'screen'   => $this->_admin_page->get_current_screen()->id,
50
-        );
51
-        $ID_column_name      = __('ID', 'event_espresso');
52
-        $ID_column_name      .= ' : <span class="show-on-mobile-view-only" style="float:none">';
53
-        $ID_column_name      .= __('Transaction Date', 'event_espresso');
54
-        $ID_column_name      .= '</span> ';
55
-        $this->_columns      = array(
56
-            'TXN_ID'        => $ID_column_name,
57
-            'TXN_timestamp' => __('Transaction Date', 'event_espresso'),
58
-            'TXN_total'     => __('Total', 'event_espresso'),
59
-            'TXN_paid'      => __('Paid', 'event_espresso'),
60
-            'ATT_fname'     => __('Primary Registrant', 'event_espresso'),
61
-            'event_name'    => __('Event', 'event_espresso'),
62
-            'actions'       => __('Actions', 'event_espresso'),
63
-        );
64
-
65
-        $this->_sortable_columns = array(
66
-            'TXN_ID'        => array('TXN_ID' => false),
67
-            'event_name'    => array('event_name' => false),
68
-            'ATT_fname'     => array('ATT_fname' => false),
69
-            'TXN_timestamp' => array('TXN_timestamp' => true) //true means its already sorted
70
-        );
71
-
72
-        $this->_primary_column = 'TXN_ID';
73
-
74
-        $this->_hidden_columns = array();
75
-    }
76
-
77
-
78
-    /**
79
-     * This simply sets up the row class for the table rows.
80
-     * Allows for easier overriding of child methods for setting up sorting.
81
-     *
82
-     * @param  EE_Transaction $transaction the current item
83
-     * @return string
84
-     * @throws \EE_Error
85
-     */
86
-    protected function _get_row_class($transaction)
87
-    {
88
-        $class = parent::_get_row_class($transaction);
89
-        //add status class
90
-        $class .= ' ee-status-strip txn-status-' . $transaction->status_ID();
91
-        if ($this->_has_checkbox_column) {
92
-            $class .= ' has-checkbox-column';
93
-        }
94
-        return $class;
95
-    }
96
-
97
-
98
-    /**
99
-     * _get_table_filters
100
-     * We use this to assemble and return any filters that are associated with this table that help further refine what
101
-     * get's shown in the table.
102
-     *
103
-     * @abstract
104
-     * @access protected
105
-     * @return array
106
-     */
107
-    protected function _get_table_filters()
108
-    {
109
-        $filters    = array();
110
-        $start_date = isset($this->_req_data['txn-filter-start-date'])
111
-            ? wp_strip_all_tags($this->_req_data['txn-filter-start-date'])
112
-            : date(
113
-                'm/d/Y',
114
-                strtotime('-10 year')
115
-            );
116
-        $end_date   = isset($this->_req_data['txn-filter-end-date'])
117
-            ? wp_strip_all_tags($this->_req_data['txn-filter-end-date'])
118
-            : date(
119
-                'm/d/Y',
120
-                current_time('timestamp')
121
-            );
122
-        ob_start();
123
-        ?>
16
+	private $_status;
17
+
18
+
19
+	/**
20
+	 * @param \Transactions_Admin_Page $admin_page
21
+	 */
22
+	public function __construct(\Transactions_Admin_Page $admin_page)
23
+	{
24
+		parent::__construct($admin_page);
25
+		$this->_status = $this->_admin_page->get_transaction_status_array();
26
+	}
27
+
28
+
29
+	/**
30
+	 *_setup_data
31
+	 */
32
+	protected function _setup_data()
33
+	{
34
+		$this->_data           = $this->_admin_page->get_transactions($this->_per_page);
35
+		$status                = ! empty($this->_req_data['status']) ? $this->_req_data['status'] : 'all';
36
+		$this->_all_data_count = $this->_admin_page->get_transactions($this->_per_page, true, $status);
37
+	}
38
+
39
+
40
+	/**
41
+	 *_set_properties
42
+	 */
43
+	protected function _set_properties()
44
+	{
45
+		$this->_wp_list_args = array(
46
+			'singular' => __('transaction', 'event_espresso'),
47
+			'plural'   => __('transactions', 'event_espresso'),
48
+			'ajax'     => true,
49
+			'screen'   => $this->_admin_page->get_current_screen()->id,
50
+		);
51
+		$ID_column_name      = __('ID', 'event_espresso');
52
+		$ID_column_name      .= ' : <span class="show-on-mobile-view-only" style="float:none">';
53
+		$ID_column_name      .= __('Transaction Date', 'event_espresso');
54
+		$ID_column_name      .= '</span> ';
55
+		$this->_columns      = array(
56
+			'TXN_ID'        => $ID_column_name,
57
+			'TXN_timestamp' => __('Transaction Date', 'event_espresso'),
58
+			'TXN_total'     => __('Total', 'event_espresso'),
59
+			'TXN_paid'      => __('Paid', 'event_espresso'),
60
+			'ATT_fname'     => __('Primary Registrant', 'event_espresso'),
61
+			'event_name'    => __('Event', 'event_espresso'),
62
+			'actions'       => __('Actions', 'event_espresso'),
63
+		);
64
+
65
+		$this->_sortable_columns = array(
66
+			'TXN_ID'        => array('TXN_ID' => false),
67
+			'event_name'    => array('event_name' => false),
68
+			'ATT_fname'     => array('ATT_fname' => false),
69
+			'TXN_timestamp' => array('TXN_timestamp' => true) //true means its already sorted
70
+		);
71
+
72
+		$this->_primary_column = 'TXN_ID';
73
+
74
+		$this->_hidden_columns = array();
75
+	}
76
+
77
+
78
+	/**
79
+	 * This simply sets up the row class for the table rows.
80
+	 * Allows for easier overriding of child methods for setting up sorting.
81
+	 *
82
+	 * @param  EE_Transaction $transaction the current item
83
+	 * @return string
84
+	 * @throws \EE_Error
85
+	 */
86
+	protected function _get_row_class($transaction)
87
+	{
88
+		$class = parent::_get_row_class($transaction);
89
+		//add status class
90
+		$class .= ' ee-status-strip txn-status-' . $transaction->status_ID();
91
+		if ($this->_has_checkbox_column) {
92
+			$class .= ' has-checkbox-column';
93
+		}
94
+		return $class;
95
+	}
96
+
97
+
98
+	/**
99
+	 * _get_table_filters
100
+	 * We use this to assemble and return any filters that are associated with this table that help further refine what
101
+	 * get's shown in the table.
102
+	 *
103
+	 * @abstract
104
+	 * @access protected
105
+	 * @return array
106
+	 */
107
+	protected function _get_table_filters()
108
+	{
109
+		$filters    = array();
110
+		$start_date = isset($this->_req_data['txn-filter-start-date'])
111
+			? wp_strip_all_tags($this->_req_data['txn-filter-start-date'])
112
+			: date(
113
+				'm/d/Y',
114
+				strtotime('-10 year')
115
+			);
116
+		$end_date   = isset($this->_req_data['txn-filter-end-date'])
117
+			? wp_strip_all_tags($this->_req_data['txn-filter-end-date'])
118
+			: date(
119
+				'm/d/Y',
120
+				current_time('timestamp')
121
+			);
122
+		ob_start();
123
+		?>
124 124
         <label for="txn-filter-start-date">Display Transactions from </label>
125 125
         <input id="txn-filter-start-date" class="datepicker" type="text" value="<?php echo $start_date; ?>"
126 126
                name="txn-filter-start-date" size="15"/>
@@ -128,534 +128,534 @@  discard block
 block discarded – undo
128 128
         <input id="txn-filter-end-date" class="datepicker" type="text" value="<?php echo $end_date; ?>"
129 129
                name="txn-filter-end-date" size="15"/>
130 130
         <?php
131
-        $filters[] = ob_get_contents();
132
-        ob_end_clean();
133
-        return $filters;
134
-    }
135
-
136
-
137
-    /**
138
-     *_add_view_counts
139
-     */
140
-    protected function _add_view_counts()
141
-    {
142
-        $this->_views['all']['count']       = $this->_admin_page->get_transactions($this->_per_page, true, 'all');
143
-        $this->_views['abandoned']['count'] = $this->_admin_page->get_transactions($this->_per_page, true, 'abandoned');
144
-        $this->_views['failed']['count']    = $this->_admin_page->get_transactions($this->_per_page, true, 'failed');
145
-    }
146
-
147
-
148
-    /**
149
-     *    column TXN_ID
150
-     *
151
-     * @param \EE_Transaction $transaction
152
-     * @return string
153
-     * @throws \EE_Error
154
-     */
155
-    public function column_TXN_ID(EE_Transaction $transaction)
156
-    {
157
-        $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
158
-            'action' => 'view_transaction',
159
-            'TXN_ID' => $transaction->ID(),
160
-        ), TXN_ADMIN_URL);
161
-        $content      = '<a href="' . $view_lnk_url . '"'
162
-                        . ' title="' . esc_attr__('Go to Transaction Details', 'event_espresso') . '">'
163
-                        . $transaction->ID()
164
-                        . '</a>';
165
-
166
-        //txn timestamp
167
-        $content .= '  <span class="show-on-mobile-view-only">' . $this->_get_txn_timestamp($transaction) . '</span>';
168
-        return $content;
169
-    }
170
-
171
-
172
-    /**
173
-     * @param \EE_Transaction $transaction
174
-     * @return string
175
-     * @throws \EE_Error
176
-     */
177
-    protected function _get_txn_timestamp(EE_Transaction $transaction)
178
-    {
179
-        //txn timestamp
180
-        // is TXN less than 2 hours old ?
181
-        if (($transaction->failed() || $transaction->is_abandoned())
182
-            && (
183
-                (time() - EE_Registry::instance()->SSN->lifespan()) < $transaction->datetime(false, true)
184
-            )
185
-        ) {
186
-            $timestamp = esc_html__('TXN in progress...', 'event_espresso');
187
-        } else {
188
-            $timestamp = $transaction->get_i18n_datetime('TXN_timestamp');
189
-        }
190
-        return $timestamp;
191
-    }
192
-
193
-
194
-    /**
195
-     *    column_cb
196
-     *
197
-     * @param \EE_Transaction $transaction
198
-     * @return string
199
-     * @throws \EE_Error
200
-     */
201
-    public function column_cb($transaction)
202
-    {
203
-        return sprintf(
204
-            '<input type="checkbox" name="%1$s[]" value="%2$s" />',
205
-            $this->_wp_list_args['singular'],
206
-            $transaction->ID()
207
-        );
208
-    }
209
-
210
-
211
-    /**
212
-     *    column_TXN_timestamp
213
-     *
214
-     * @param \EE_Transaction $transaction
215
-     * @return string
216
-     * @throws \EE_Error
217
-     */
218
-    public function column_TXN_timestamp(EE_Transaction $transaction)
219
-    {
220
-        $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
221
-            'action' => 'view_transaction',
222
-            'TXN_ID' => $transaction->ID(),
223
-        ), TXN_ADMIN_URL);
224
-        $txn_date     = '<a href="' . $view_lnk_url . '"'
225
-                        . ' title="'
226
-                        . esc_attr__('View Transaction Details for TXN #', 'event_espresso') . $transaction->ID() . '">'
227
-                        . $this->_get_txn_timestamp($transaction)
228
-                        . '</a>';
229
-        //status
230
-        $txn_date .= '<br><span class="ee-status-text-small">'
231
-                     . EEH_Template::pretty_status(
232
-                         $transaction->status_ID(),
233
-                         false,
234
-                         'sentence'
235
-                     )
236
-                     . '</span>';
237
-        return $txn_date;
238
-    }
239
-
240
-
241
-    /**
242
-     *    column_TXN_total
243
-     *
244
-     * @param \EE_Transaction $transaction
245
-     * @return string
246
-     * @throws \EE_Error
247
-     */
248
-    public function column_TXN_total(EE_Transaction $transaction)
249
-    {
250
-        if ($transaction->get('TXN_total') > 0) {
251
-            return '<span class="txn-pad-rght">'
252
-                   . apply_filters(
253
-                       'FHEE__EE_Admin_Transactions_List_Table__column_TXN_total__TXN_total',
254
-                       $transaction->get_pretty('TXN_total'),
255
-                       $transaction
256
-                   )
257
-                   . '</span>';
258
-        } else {
259
-            return '<span class="txn-overview-free-event-spn">' . esc_html__('free', 'event_espresso') . '</span>';
260
-        }
261
-    }
262
-
263
-
264
-    /**
265
-     *    column_TXN_paid
266
-     *
267
-     * @param \EE_Transaction $transaction
268
-     * @return mixed|string
269
-     * @throws \EE_Error
270
-     */
271
-    public function column_TXN_paid(EE_Transaction $transaction)
272
-    {
273
-        $transaction_total = $transaction->get('TXN_total');
274
-        $transaction_paid  = $transaction->get('TXN_paid');
275
-
276
-        if (\EEH_Money::compare_floats($transaction_total, 0, '>')) {
277
-            // monies owing
278
-            $span_class = 'txn-overview-part-payment-spn';
279
-            if (\EEH_Money::compare_floats($transaction_paid, $transaction_total, '>=')) {
280
-                // paid in full
281
-                $span_class = 'txn-overview-full-payment-spn';
282
-            } elseif (\EEH_Money::compare_floats($transaction_paid, 0, '==')) {
283
-                // no payments made
284
-                $span_class = 'txn-overview-no-payment-spn';
285
-            }
286
-        } else {
287
-            $span_class       = 'txn-overview-free-event-spn';
288
-            $transaction_paid = 0;
289
-        }
290
-
291
-        $payment_method      = $transaction->payment_method();
292
-        $payment_method_name = $payment_method instanceof EE_Payment_Method
293
-            ? $payment_method->admin_name()
294
-            : esc_html__('Unknown', 'event_espresso');
295
-        $transaction_paid_content = $transaction_paid !== 0 ? $transaction->get_pretty('TXN_paid') : $transaction_paid;
296
-
297
-        $content = '<span class="' . $span_class . ' txn-pad-rght">'
298
-                   . $transaction_paid_content
299
-                   . '</span>';
300
-        if ($transaction_paid > 0) {
301
-            $content .= '<br><span class="ee-status-text-small">'
302
-                        . sprintf(
303
-                            esc_html__('...via %s', 'event_espresso'),
304
-                            $payment_method_name
305
-                        )
306
-                        . '</span>';
307
-        }
308
-        return $content;
309
-    }
310
-
311
-
312
-    /**
313
-     *    column_ATT_fname
314
-     *
315
-     * @param \EE_Transaction $transaction
316
-     * @return string
317
-     * @throws \EE_Error
318
-     */
319
-    public function column_ATT_fname(EE_Transaction $transaction)
320
-    {
321
-        $primary_reg = $transaction->primary_registration();
322
-        $attendee    = $primary_reg->get_first_related('Attendee');
323
-        if ($attendee instanceof EE_Attendee) {
324
-            $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
325
-                'action'  => 'view_registration',
326
-                '_REG_ID' => $primary_reg->ID(),
327
-            ), REG_ADMIN_URL);
328
-            $content      = EE_Registry::instance()->CAP->current_user_can(
329
-                'ee_read_registration',
330
-                'espresso_registrations_view_registration',
331
-                $primary_reg->ID()
332
-            )
333
-                ? '<a href="' . $edit_lnk_url . '"'
334
-                    . ' title="' . esc_attr__('View Registration Details', 'event_espresso') . '">'
335
-                    . $attendee->full_name()
336
-                    . '</a>'
337
-                : $attendee->full_name();
338
-            $content      .= '<br>' . $attendee->email();
339
-            return $content;
340
-        }
341
-        return $transaction->failed() || $transaction->is_abandoned()
342
-            ? esc_html__('no contact record.', 'event_espresso')
343
-            : esc_html__(
344
-                'No contact record, because the transaction was abandoned or the registration process failed.',
345
-                'event_espresso'
346
-            );
347
-    }
348
-
349
-
350
-    /**
351
-     *    column_ATT_email
352
-     *
353
-     * @param \EE_Transaction $transaction
354
-     * @return string
355
-     * @throws \EE_Error
356
-     */
357
-    public function column_ATT_email(EE_Transaction $transaction)
358
-    {
359
-        $attendee = $transaction->primary_registration()->get_first_related('Attendee');
360
-        if (! empty($attendee)) {
361
-            return '<a href="mailto:' . $attendee->get('ATT_email') . '">'
362
-                   . $attendee->get('ATT_email')
363
-                   . '</a>';
364
-        } else {
365
-            return $transaction->failed() || $transaction->is_abandoned()
366
-                ? esc_html__('no contact record.', 'event_espresso')
367
-                : esc_html__(
368
-                    'No contact record, because the transaction was abandoned or the registration process failed.',
369
-                    'event_espresso'
370
-                );
371
-        }
372
-    }
373
-
374
-
375
-    /**
376
-     *    column_event_name
377
-     *
378
-     * @param \EE_Transaction $transaction
379
-     * @return string
380
-     * @throws \EE_Error
381
-     */
382
-    public function column_event_name(EE_Transaction $transaction)
383
-    {
384
-        $actions = array();
385
-        $event   = $transaction->primary_registration()->get_first_related('Event');
386
-        if (! empty($event)) {
387
-            $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(
388
-                array('action' => 'edit', 'post' => $event->ID()),
389
-                EVENTS_ADMIN_URL
390
-            );
391
-            $event_name     = $event->get('EVT_name');
392
-
393
-            //filter this view by transactions for this event
394
-            $txn_by_event_lnk = EE_Admin_Page::add_query_args_and_nonce(array(
395
-                'action' => 'default',
396
-                'EVT_ID' => $event->ID(),
397
-            ));
398
-            if (EE_Registry::instance()->CAP->current_user_can(
399
-                'ee_edit_event',
400
-                'espresso_events_edit',
401
-                $event->ID()
402
-            )) {
403
-                $actions['filter_by_event'] = '<a href="' . $txn_by_event_lnk . '"'
404
-                        . ' title="' . esc_attr__('Filter transactions by this event', 'event_espresso') . '">'
405
-                        . esc_html__('View Transactions for this event', 'event_espresso')
406
-                        . '</a>';
407
-            }
408
-
409
-            return sprintf(
410
-                '%1$s %2$s',
411
-                EE_Registry::instance()->CAP->current_user_can(
412
-                    'ee_edit_event',
413
-                    'espresso_events_edit',
414
-                    $event->ID()
415
-                )
416
-                    ? '<a href="' . $edit_event_url . '"'
417
-                        . ' title="'
418
-                        . sprintf(
419
-                            esc_attr__('Edit Event: %s', 'event_espresso'),
420
-                            $event->get('EVT_name')
421
-                        )
422
-                        . '">'
423
-                        . wp_trim_words(
424
-                            $event_name,
425
-                            30,
426
-                            '...'
427
-                        )
428
-                        . '</a>'
429
-                        : wp_trim_words($event_name, 30, '...'),
430
-                $this->row_actions($actions)
431
-            );
432
-        } else {
433
-            return esc_html__(
434
-                'The event associated with this transaction via the primary registration cannot be retrieved.',
435
-                'event_espresso'
436
-            );
437
-        }
438
-    }
439
-
440
-
441
-    /**
442
-     *    column_actions
443
-     *
444
-     * @param \EE_Transaction $transaction
445
-     * @return string
446
-     * @throws \EE_Error
447
-     */
448
-    public function column_actions(EE_Transaction $transaction)
449
-    {
450
-        return $this->_action_string(
451
-            $this->get_transaction_details_link($transaction)
452
-            . $this->get_invoice_link($transaction)
453
-            . $this->get_receipt_link($transaction)
454
-            . $this->get_primary_registration_details_link($transaction)
455
-            . $this->get_send_payment_reminder_trigger_link($transaction)
456
-            . $this->get_payment_overview_link($transaction)
457
-            . $this->get_related_messages_link($transaction),
458
-            $transaction,
459
-            'ul',
460
-            'txn-overview-actions-ul'
461
-        );
462
-    }
463
-
464
-
465
-    /**
466
-     * Get the transaction details link.
467
-     * @param EE_Transaction $transaction
468
-     * @return string
469
-     * @throws EE_Error
470
-     */
471
-    protected function get_transaction_details_link(EE_Transaction $transaction)
472
-    {
473
-        $url          = EE_Admin_Page::add_query_args_and_nonce(array(
474
-            'action' => 'view_transaction',
475
-            'TXN_ID' => $transaction->ID(),
476
-        ), TXN_ADMIN_URL);
477
-        return '
131
+		$filters[] = ob_get_contents();
132
+		ob_end_clean();
133
+		return $filters;
134
+	}
135
+
136
+
137
+	/**
138
+	 *_add_view_counts
139
+	 */
140
+	protected function _add_view_counts()
141
+	{
142
+		$this->_views['all']['count']       = $this->_admin_page->get_transactions($this->_per_page, true, 'all');
143
+		$this->_views['abandoned']['count'] = $this->_admin_page->get_transactions($this->_per_page, true, 'abandoned');
144
+		$this->_views['failed']['count']    = $this->_admin_page->get_transactions($this->_per_page, true, 'failed');
145
+	}
146
+
147
+
148
+	/**
149
+	 *    column TXN_ID
150
+	 *
151
+	 * @param \EE_Transaction $transaction
152
+	 * @return string
153
+	 * @throws \EE_Error
154
+	 */
155
+	public function column_TXN_ID(EE_Transaction $transaction)
156
+	{
157
+		$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
158
+			'action' => 'view_transaction',
159
+			'TXN_ID' => $transaction->ID(),
160
+		), TXN_ADMIN_URL);
161
+		$content      = '<a href="' . $view_lnk_url . '"'
162
+						. ' title="' . esc_attr__('Go to Transaction Details', 'event_espresso') . '">'
163
+						. $transaction->ID()
164
+						. '</a>';
165
+
166
+		//txn timestamp
167
+		$content .= '  <span class="show-on-mobile-view-only">' . $this->_get_txn_timestamp($transaction) . '</span>';
168
+		return $content;
169
+	}
170
+
171
+
172
+	/**
173
+	 * @param \EE_Transaction $transaction
174
+	 * @return string
175
+	 * @throws \EE_Error
176
+	 */
177
+	protected function _get_txn_timestamp(EE_Transaction $transaction)
178
+	{
179
+		//txn timestamp
180
+		// is TXN less than 2 hours old ?
181
+		if (($transaction->failed() || $transaction->is_abandoned())
182
+			&& (
183
+				(time() - EE_Registry::instance()->SSN->lifespan()) < $transaction->datetime(false, true)
184
+			)
185
+		) {
186
+			$timestamp = esc_html__('TXN in progress...', 'event_espresso');
187
+		} else {
188
+			$timestamp = $transaction->get_i18n_datetime('TXN_timestamp');
189
+		}
190
+		return $timestamp;
191
+	}
192
+
193
+
194
+	/**
195
+	 *    column_cb
196
+	 *
197
+	 * @param \EE_Transaction $transaction
198
+	 * @return string
199
+	 * @throws \EE_Error
200
+	 */
201
+	public function column_cb($transaction)
202
+	{
203
+		return sprintf(
204
+			'<input type="checkbox" name="%1$s[]" value="%2$s" />',
205
+			$this->_wp_list_args['singular'],
206
+			$transaction->ID()
207
+		);
208
+	}
209
+
210
+
211
+	/**
212
+	 *    column_TXN_timestamp
213
+	 *
214
+	 * @param \EE_Transaction $transaction
215
+	 * @return string
216
+	 * @throws \EE_Error
217
+	 */
218
+	public function column_TXN_timestamp(EE_Transaction $transaction)
219
+	{
220
+		$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
221
+			'action' => 'view_transaction',
222
+			'TXN_ID' => $transaction->ID(),
223
+		), TXN_ADMIN_URL);
224
+		$txn_date     = '<a href="' . $view_lnk_url . '"'
225
+						. ' title="'
226
+						. esc_attr__('View Transaction Details for TXN #', 'event_espresso') . $transaction->ID() . '">'
227
+						. $this->_get_txn_timestamp($transaction)
228
+						. '</a>';
229
+		//status
230
+		$txn_date .= '<br><span class="ee-status-text-small">'
231
+					 . EEH_Template::pretty_status(
232
+						 $transaction->status_ID(),
233
+						 false,
234
+						 'sentence'
235
+					 )
236
+					 . '</span>';
237
+		return $txn_date;
238
+	}
239
+
240
+
241
+	/**
242
+	 *    column_TXN_total
243
+	 *
244
+	 * @param \EE_Transaction $transaction
245
+	 * @return string
246
+	 * @throws \EE_Error
247
+	 */
248
+	public function column_TXN_total(EE_Transaction $transaction)
249
+	{
250
+		if ($transaction->get('TXN_total') > 0) {
251
+			return '<span class="txn-pad-rght">'
252
+				   . apply_filters(
253
+					   'FHEE__EE_Admin_Transactions_List_Table__column_TXN_total__TXN_total',
254
+					   $transaction->get_pretty('TXN_total'),
255
+					   $transaction
256
+				   )
257
+				   . '</span>';
258
+		} else {
259
+			return '<span class="txn-overview-free-event-spn">' . esc_html__('free', 'event_espresso') . '</span>';
260
+		}
261
+	}
262
+
263
+
264
+	/**
265
+	 *    column_TXN_paid
266
+	 *
267
+	 * @param \EE_Transaction $transaction
268
+	 * @return mixed|string
269
+	 * @throws \EE_Error
270
+	 */
271
+	public function column_TXN_paid(EE_Transaction $transaction)
272
+	{
273
+		$transaction_total = $transaction->get('TXN_total');
274
+		$transaction_paid  = $transaction->get('TXN_paid');
275
+
276
+		if (\EEH_Money::compare_floats($transaction_total, 0, '>')) {
277
+			// monies owing
278
+			$span_class = 'txn-overview-part-payment-spn';
279
+			if (\EEH_Money::compare_floats($transaction_paid, $transaction_total, '>=')) {
280
+				// paid in full
281
+				$span_class = 'txn-overview-full-payment-spn';
282
+			} elseif (\EEH_Money::compare_floats($transaction_paid, 0, '==')) {
283
+				// no payments made
284
+				$span_class = 'txn-overview-no-payment-spn';
285
+			}
286
+		} else {
287
+			$span_class       = 'txn-overview-free-event-spn';
288
+			$transaction_paid = 0;
289
+		}
290
+
291
+		$payment_method      = $transaction->payment_method();
292
+		$payment_method_name = $payment_method instanceof EE_Payment_Method
293
+			? $payment_method->admin_name()
294
+			: esc_html__('Unknown', 'event_espresso');
295
+		$transaction_paid_content = $transaction_paid !== 0 ? $transaction->get_pretty('TXN_paid') : $transaction_paid;
296
+
297
+		$content = '<span class="' . $span_class . ' txn-pad-rght">'
298
+				   . $transaction_paid_content
299
+				   . '</span>';
300
+		if ($transaction_paid > 0) {
301
+			$content .= '<br><span class="ee-status-text-small">'
302
+						. sprintf(
303
+							esc_html__('...via %s', 'event_espresso'),
304
+							$payment_method_name
305
+						)
306
+						. '</span>';
307
+		}
308
+		return $content;
309
+	}
310
+
311
+
312
+	/**
313
+	 *    column_ATT_fname
314
+	 *
315
+	 * @param \EE_Transaction $transaction
316
+	 * @return string
317
+	 * @throws \EE_Error
318
+	 */
319
+	public function column_ATT_fname(EE_Transaction $transaction)
320
+	{
321
+		$primary_reg = $transaction->primary_registration();
322
+		$attendee    = $primary_reg->get_first_related('Attendee');
323
+		if ($attendee instanceof EE_Attendee) {
324
+			$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
325
+				'action'  => 'view_registration',
326
+				'_REG_ID' => $primary_reg->ID(),
327
+			), REG_ADMIN_URL);
328
+			$content      = EE_Registry::instance()->CAP->current_user_can(
329
+				'ee_read_registration',
330
+				'espresso_registrations_view_registration',
331
+				$primary_reg->ID()
332
+			)
333
+				? '<a href="' . $edit_lnk_url . '"'
334
+					. ' title="' . esc_attr__('View Registration Details', 'event_espresso') . '">'
335
+					. $attendee->full_name()
336
+					. '</a>'
337
+				: $attendee->full_name();
338
+			$content      .= '<br>' . $attendee->email();
339
+			return $content;
340
+		}
341
+		return $transaction->failed() || $transaction->is_abandoned()
342
+			? esc_html__('no contact record.', 'event_espresso')
343
+			: esc_html__(
344
+				'No contact record, because the transaction was abandoned or the registration process failed.',
345
+				'event_espresso'
346
+			);
347
+	}
348
+
349
+
350
+	/**
351
+	 *    column_ATT_email
352
+	 *
353
+	 * @param \EE_Transaction $transaction
354
+	 * @return string
355
+	 * @throws \EE_Error
356
+	 */
357
+	public function column_ATT_email(EE_Transaction $transaction)
358
+	{
359
+		$attendee = $transaction->primary_registration()->get_first_related('Attendee');
360
+		if (! empty($attendee)) {
361
+			return '<a href="mailto:' . $attendee->get('ATT_email') . '">'
362
+				   . $attendee->get('ATT_email')
363
+				   . '</a>';
364
+		} else {
365
+			return $transaction->failed() || $transaction->is_abandoned()
366
+				? esc_html__('no contact record.', 'event_espresso')
367
+				: esc_html__(
368
+					'No contact record, because the transaction was abandoned or the registration process failed.',
369
+					'event_espresso'
370
+				);
371
+		}
372
+	}
373
+
374
+
375
+	/**
376
+	 *    column_event_name
377
+	 *
378
+	 * @param \EE_Transaction $transaction
379
+	 * @return string
380
+	 * @throws \EE_Error
381
+	 */
382
+	public function column_event_name(EE_Transaction $transaction)
383
+	{
384
+		$actions = array();
385
+		$event   = $transaction->primary_registration()->get_first_related('Event');
386
+		if (! empty($event)) {
387
+			$edit_event_url = EE_Admin_Page::add_query_args_and_nonce(
388
+				array('action' => 'edit', 'post' => $event->ID()),
389
+				EVENTS_ADMIN_URL
390
+			);
391
+			$event_name     = $event->get('EVT_name');
392
+
393
+			//filter this view by transactions for this event
394
+			$txn_by_event_lnk = EE_Admin_Page::add_query_args_and_nonce(array(
395
+				'action' => 'default',
396
+				'EVT_ID' => $event->ID(),
397
+			));
398
+			if (EE_Registry::instance()->CAP->current_user_can(
399
+				'ee_edit_event',
400
+				'espresso_events_edit',
401
+				$event->ID()
402
+			)) {
403
+				$actions['filter_by_event'] = '<a href="' . $txn_by_event_lnk . '"'
404
+						. ' title="' . esc_attr__('Filter transactions by this event', 'event_espresso') . '">'
405
+						. esc_html__('View Transactions for this event', 'event_espresso')
406
+						. '</a>';
407
+			}
408
+
409
+			return sprintf(
410
+				'%1$s %2$s',
411
+				EE_Registry::instance()->CAP->current_user_can(
412
+					'ee_edit_event',
413
+					'espresso_events_edit',
414
+					$event->ID()
415
+				)
416
+					? '<a href="' . $edit_event_url . '"'
417
+						. ' title="'
418
+						. sprintf(
419
+							esc_attr__('Edit Event: %s', 'event_espresso'),
420
+							$event->get('EVT_name')
421
+						)
422
+						. '">'
423
+						. wp_trim_words(
424
+							$event_name,
425
+							30,
426
+							'...'
427
+						)
428
+						. '</a>'
429
+						: wp_trim_words($event_name, 30, '...'),
430
+				$this->row_actions($actions)
431
+			);
432
+		} else {
433
+			return esc_html__(
434
+				'The event associated with this transaction via the primary registration cannot be retrieved.',
435
+				'event_espresso'
436
+			);
437
+		}
438
+	}
439
+
440
+
441
+	/**
442
+	 *    column_actions
443
+	 *
444
+	 * @param \EE_Transaction $transaction
445
+	 * @return string
446
+	 * @throws \EE_Error
447
+	 */
448
+	public function column_actions(EE_Transaction $transaction)
449
+	{
450
+		return $this->_action_string(
451
+			$this->get_transaction_details_link($transaction)
452
+			. $this->get_invoice_link($transaction)
453
+			. $this->get_receipt_link($transaction)
454
+			. $this->get_primary_registration_details_link($transaction)
455
+			. $this->get_send_payment_reminder_trigger_link($transaction)
456
+			. $this->get_payment_overview_link($transaction)
457
+			. $this->get_related_messages_link($transaction),
458
+			$transaction,
459
+			'ul',
460
+			'txn-overview-actions-ul'
461
+		);
462
+	}
463
+
464
+
465
+	/**
466
+	 * Get the transaction details link.
467
+	 * @param EE_Transaction $transaction
468
+	 * @return string
469
+	 * @throws EE_Error
470
+	 */
471
+	protected function get_transaction_details_link(EE_Transaction $transaction)
472
+	{
473
+		$url          = EE_Admin_Page::add_query_args_and_nonce(array(
474
+			'action' => 'view_transaction',
475
+			'TXN_ID' => $transaction->ID(),
476
+		), TXN_ADMIN_URL);
477
+		return '
478 478
 			<li>
479 479
 				<a href="' . $url . '"'
480
-                    . ' title="' . esc_attr__('View Transaction Details', 'event_espresso') . '" class="tiny-text">
480
+					. ' title="' . esc_attr__('View Transaction Details', 'event_espresso') . '" class="tiny-text">
481 481
 					<span class="dashicons dashicons-cart"></span>
482 482
 				</a>
483 483
 			</li>';
484
-    }
485
-
486
-
487
-    /**
488
-     * Get the invoice link for the given registration.
489
-     * @param EE_Transaction $transaction
490
-     * @return string
491
-     * @throws EE_Error
492
-     */
493
-    protected function get_invoice_link(EE_Transaction $transaction)
494
-    {
495
-        $registration = $transaction->primary_registration();
496
-        if ($registration instanceof EE_Registration) {
497
-            $url = $registration->invoice_url();
498
-            //only show invoice link if message type is active.
499
-            if ($registration->attendee() instanceof EE_Attendee
500
-                && EEH_MSG_Template::is_mt_active('invoice')
501
-            ) {
502
-                return '
484
+	}
485
+
486
+
487
+	/**
488
+	 * Get the invoice link for the given registration.
489
+	 * @param EE_Transaction $transaction
490
+	 * @return string
491
+	 * @throws EE_Error
492
+	 */
493
+	protected function get_invoice_link(EE_Transaction $transaction)
494
+	{
495
+		$registration = $transaction->primary_registration();
496
+		if ($registration instanceof EE_Registration) {
497
+			$url = $registration->invoice_url();
498
+			//only show invoice link if message type is active.
499
+			if ($registration->attendee() instanceof EE_Attendee
500
+				&& EEH_MSG_Template::is_mt_active('invoice')
501
+			) {
502
+				return '
503 503
                 <li>
504 504
                     <a title="' . esc_attr__('View Transaction Invoice', 'event_espresso') . '"'
505
-                       . ' target="_blank" href="' . $url . '" class="tiny-text">
505
+					   . ' target="_blank" href="' . $url . '" class="tiny-text">
506 506
                         <span class="dashicons dashicons-media-spreadsheet ee-icon-size-18"></span>
507 507
                     </a>
508 508
                 </li>';
509
-            }
510
-        }
511
-        return '';
512
-    }
513
-
514
-
515
-    /**
516
-     * Get the receipt link for the transaction.
517
-     * @param EE_Transaction $transaction
518
-     * @return string
519
-     * @throws EE_Error
520
-     */
521
-    protected function get_receipt_link(EE_Transaction $transaction)
522
-    {
523
-        $registration = $transaction->primary_registration();
524
-        if ($registration instanceof EE_Registration) {
525
-            $url = $registration->receipt_url();
526
-            //only show receipt link if message type is active.
527
-            if ($registration->attendee() instanceof EE_Attendee
528
-                && EEH_MSG_Template::is_mt_active('receipt')) {
529
-                return '
509
+			}
510
+		}
511
+		return '';
512
+	}
513
+
514
+
515
+	/**
516
+	 * Get the receipt link for the transaction.
517
+	 * @param EE_Transaction $transaction
518
+	 * @return string
519
+	 * @throws EE_Error
520
+	 */
521
+	protected function get_receipt_link(EE_Transaction $transaction)
522
+	{
523
+		$registration = $transaction->primary_registration();
524
+		if ($registration instanceof EE_Registration) {
525
+			$url = $registration->receipt_url();
526
+			//only show receipt link if message type is active.
527
+			if ($registration->attendee() instanceof EE_Attendee
528
+				&& EEH_MSG_Template::is_mt_active('receipt')) {
529
+				return '
530 530
 			<li>
531 531
 				<a title="' . esc_attr__('View Transaction Receipt', 'event_espresso') . '"'
532
-                                  . ' target="_blank" href="' . $url . '" class="tiny-text">
532
+								  . ' target="_blank" href="' . $url . '" class="tiny-text">
533 533
 					<span class="dashicons dashicons-media-default ee-icon-size-18"></span>
534 534
 				</a>
535 535
 			</li>';
536
-            }
537
-        }
538
-        return '';
539
-    }
540
-
541
-
542
-    /**
543
-     * Get the link to view the details for the primary registration.
544
-     * @param EE_Transaction $transaction
545
-     * @return string
546
-     * @throws EE_Error
547
-     */
548
-    protected function get_primary_registration_details_link(EE_Transaction $transaction)
549
-    {
550
-        $registration = $transaction->primary_registration();
551
-        if ($registration instanceof EE_Registration) {
552
-            $url      = EE_Admin_Page::add_query_args_and_nonce(array(
553
-                'action'  => 'view_registration',
554
-                '_REG_ID' => $registration->ID(),
555
-            ), REG_ADMIN_URL);
556
-            return EE_Registry::instance()->CAP->current_user_can(
557
-                'ee_read_registration',
558
-                'espresso_registrations_view_registration',
559
-                $registration->ID()
560
-            )
561
-                ? '
536
+			}
537
+		}
538
+		return '';
539
+	}
540
+
541
+
542
+	/**
543
+	 * Get the link to view the details for the primary registration.
544
+	 * @param EE_Transaction $transaction
545
+	 * @return string
546
+	 * @throws EE_Error
547
+	 */
548
+	protected function get_primary_registration_details_link(EE_Transaction $transaction)
549
+	{
550
+		$registration = $transaction->primary_registration();
551
+		if ($registration instanceof EE_Registration) {
552
+			$url      = EE_Admin_Page::add_query_args_and_nonce(array(
553
+				'action'  => 'view_registration',
554
+				'_REG_ID' => $registration->ID(),
555
+			), REG_ADMIN_URL);
556
+			return EE_Registry::instance()->CAP->current_user_can(
557
+				'ee_read_registration',
558
+				'espresso_registrations_view_registration',
559
+				$registration->ID()
560
+			)
561
+				? '
562 562
 				<li>
563 563
 					<a href="' . $url . '"'
564
-                  . ' title="' . esc_attr__('View Registration Details', 'event_espresso') . '" class="tiny-text">
564
+				  . ' title="' . esc_attr__('View Registration Details', 'event_espresso') . '" class="tiny-text">
565 565
 						<span class="dashicons dashicons-clipboard"></span>
566 566
 					</a>
567 567
 				</li>'
568
-                : '';
569
-        }
570
-        return '';
571
-    }
572
-
573
-
574
-    /**
575
-     * Get send payment reminder trigger link
576
-     * @param EE_Transaction $transaction
577
-     * @return string
578
-     * @throws EE_Error
579
-     */
580
-    protected function get_send_payment_reminder_trigger_link(EE_Transaction $transaction)
581
-    {
582
-        $registration = $transaction->primary_registration();
583
-        if ($registration instanceof EE_Registration
584
-            && $registration->attendee() instanceof EE_Attendee
585
-            && EEH_MSG_Template::is_mt_active('payment_reminder')
586
-            && ! in_array(
587
-                $transaction->status_ID(),
588
-                array(EEM_Transaction::complete_status_code, EEM_Transaction::overpaid_status_code),
589
-                true
590
-            )
591
-            && EE_Registry::instance()->CAP->current_user_can(
592
-                'ee_send_message',
593
-                'espresso_transactions_send_payment_reminder'
594
-            )
595
-        ) {
596
-            $url = EE_Admin_Page::add_query_args_and_nonce(array(
597
-                'action' => 'send_payment_reminder',
598
-                'TXN_ID' => $transaction->ID(),
599
-            ), TXN_ADMIN_URL);
600
-            return  '
568
+				: '';
569
+		}
570
+		return '';
571
+	}
572
+
573
+
574
+	/**
575
+	 * Get send payment reminder trigger link
576
+	 * @param EE_Transaction $transaction
577
+	 * @return string
578
+	 * @throws EE_Error
579
+	 */
580
+	protected function get_send_payment_reminder_trigger_link(EE_Transaction $transaction)
581
+	{
582
+		$registration = $transaction->primary_registration();
583
+		if ($registration instanceof EE_Registration
584
+			&& $registration->attendee() instanceof EE_Attendee
585
+			&& EEH_MSG_Template::is_mt_active('payment_reminder')
586
+			&& ! in_array(
587
+				$transaction->status_ID(),
588
+				array(EEM_Transaction::complete_status_code, EEM_Transaction::overpaid_status_code),
589
+				true
590
+			)
591
+			&& EE_Registry::instance()->CAP->current_user_can(
592
+				'ee_send_message',
593
+				'espresso_transactions_send_payment_reminder'
594
+			)
595
+		) {
596
+			$url = EE_Admin_Page::add_query_args_and_nonce(array(
597
+				'action' => 'send_payment_reminder',
598
+				'TXN_ID' => $transaction->ID(),
599
+			), TXN_ADMIN_URL);
600
+			return  '
601 601
             <li>
602 602
                 <a href="' . $url . '"'
603
-                  . ' title="' . esc_attr__('Send Payment Reminder', 'event_espresso') . '" class="tiny-text">
603
+				  . ' title="' . esc_attr__('Send Payment Reminder', 'event_espresso') . '" class="tiny-text">
604 604
                     <span class="dashicons dashicons-email-alt"></span>
605 605
                 </a>
606 606
             </li>';
607
-        }
608
-        return '';
609
-    }
610
-
611
-
612
-
613
-    /**
614
-     * Get link to filtered view in the message activity list table of messages for this transaction.
615
-     * @param EE_Transaction $transaction
616
-     * @return string
617
-     * @throws EE_Error
618
-     */
619
-    protected function get_related_messages_link(EE_Transaction $transaction)
620
-    {
621
-        $url = EEH_MSG_Template::get_message_action_link(
622
-            'see_notifications_for',
623
-            null,
624
-            array('TXN_ID' => $transaction->ID())
625
-        );
626
-        return EE_Registry::instance()->CAP->current_user_can(
627
-            'ee_read_global_messages',
628
-            'view_filtered_messages'
629
-        )
630
-            ? '<li>' . $url . '</li>'
631
-            : '';
632
-    }
633
-
634
-
635
-    /**
636
-     * Return the link to make a payment on the frontend
637
-     * @param EE_Transaction $transaction
638
-     * @return string
639
-     * @throws EE_Error
640
-     */
641
-    protected function get_payment_overview_link(EE_Transaction $transaction)
642
-    {
643
-        $registration = $transaction->primary_registration();
644
-        if ($registration instanceof EE_Registration
645
-            && $transaction->status_ID() !== EEM_Transaction::complete_status_code
646
-            && $registration->owes_monies_and_can_pay()
647
-        ) {
648
-            return '
607
+		}
608
+		return '';
609
+	}
610
+
611
+
612
+
613
+	/**
614
+	 * Get link to filtered view in the message activity list table of messages for this transaction.
615
+	 * @param EE_Transaction $transaction
616
+	 * @return string
617
+	 * @throws EE_Error
618
+	 */
619
+	protected function get_related_messages_link(EE_Transaction $transaction)
620
+	{
621
+		$url = EEH_MSG_Template::get_message_action_link(
622
+			'see_notifications_for',
623
+			null,
624
+			array('TXN_ID' => $transaction->ID())
625
+		);
626
+		return EE_Registry::instance()->CAP->current_user_can(
627
+			'ee_read_global_messages',
628
+			'view_filtered_messages'
629
+		)
630
+			? '<li>' . $url . '</li>'
631
+			: '';
632
+	}
633
+
634
+
635
+	/**
636
+	 * Return the link to make a payment on the frontend
637
+	 * @param EE_Transaction $transaction
638
+	 * @return string
639
+	 * @throws EE_Error
640
+	 */
641
+	protected function get_payment_overview_link(EE_Transaction $transaction)
642
+	{
643
+		$registration = $transaction->primary_registration();
644
+		if ($registration instanceof EE_Registration
645
+			&& $transaction->status_ID() !== EEM_Transaction::complete_status_code
646
+			&& $registration->owes_monies_and_can_pay()
647
+		) {
648
+			return '
649 649
             <li>
650 650
                 <a title="' . esc_attr__('Make Payment from the Frontend.', 'event_espresso') . '"'
651
-                    . ' target="_blank" href="' . $registration->payment_overview_url(true) . '"'
652
-                    . ' class="tiny-text">
651
+					. ' target="_blank" href="' . $registration->payment_overview_url(true) . '"'
652
+					. ' class="tiny-text">
653 653
                     <span class="dashicons dashicons-money ee-icon-size-18"></span>
654 654
                 </a>
655 655
             </li>
656 656
             ';
657 657
 
658
-        }
659
-        return '';
660
-    }
658
+		}
659
+		return '';
660
+	}
661 661
 }
Please login to merge, or discard this patch.
Spacing   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -48,11 +48,11 @@  discard block
 block discarded – undo
48 48
             'ajax'     => true,
49 49
             'screen'   => $this->_admin_page->get_current_screen()->id,
50 50
         );
51
-        $ID_column_name      = __('ID', 'event_espresso');
51
+        $ID_column_name = __('ID', 'event_espresso');
52 52
         $ID_column_name      .= ' : <span class="show-on-mobile-view-only" style="float:none">';
53 53
         $ID_column_name      .= __('Transaction Date', 'event_espresso');
54 54
         $ID_column_name      .= '</span> ';
55
-        $this->_columns      = array(
55
+        $this->_columns = array(
56 56
             'TXN_ID'        => $ID_column_name,
57 57
             'TXN_timestamp' => __('Transaction Date', 'event_espresso'),
58 58
             'TXN_total'     => __('Total', 'event_espresso'),
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
     {
88 88
         $class = parent::_get_row_class($transaction);
89 89
         //add status class
90
-        $class .= ' ee-status-strip txn-status-' . $transaction->status_ID();
90
+        $class .= ' ee-status-strip txn-status-'.$transaction->status_ID();
91 91
         if ($this->_has_checkbox_column) {
92 92
             $class .= ' has-checkbox-column';
93 93
         }
@@ -113,7 +113,7 @@  discard block
 block discarded – undo
113 113
                 'm/d/Y',
114 114
                 strtotime('-10 year')
115 115
             );
116
-        $end_date   = isset($this->_req_data['txn-filter-end-date'])
116
+        $end_date = isset($this->_req_data['txn-filter-end-date'])
117 117
             ? wp_strip_all_tags($this->_req_data['txn-filter-end-date'])
118 118
             : date(
119 119
                 'm/d/Y',
@@ -158,13 +158,13 @@  discard block
 block discarded – undo
158 158
             'action' => 'view_transaction',
159 159
             'TXN_ID' => $transaction->ID(),
160 160
         ), TXN_ADMIN_URL);
161
-        $content      = '<a href="' . $view_lnk_url . '"'
162
-                        . ' title="' . esc_attr__('Go to Transaction Details', 'event_espresso') . '">'
161
+        $content = '<a href="'.$view_lnk_url.'"'
162
+                        . ' title="'.esc_attr__('Go to Transaction Details', 'event_espresso').'">'
163 163
                         . $transaction->ID()
164 164
                         . '</a>';
165 165
 
166 166
         //txn timestamp
167
-        $content .= '  <span class="show-on-mobile-view-only">' . $this->_get_txn_timestamp($transaction) . '</span>';
167
+        $content .= '  <span class="show-on-mobile-view-only">'.$this->_get_txn_timestamp($transaction).'</span>';
168 168
         return $content;
169 169
     }
170 170
 
@@ -221,9 +221,9 @@  discard block
 block discarded – undo
221 221
             'action' => 'view_transaction',
222 222
             'TXN_ID' => $transaction->ID(),
223 223
         ), TXN_ADMIN_URL);
224
-        $txn_date     = '<a href="' . $view_lnk_url . '"'
224
+        $txn_date = '<a href="'.$view_lnk_url.'"'
225 225
                         . ' title="'
226
-                        . esc_attr__('View Transaction Details for TXN #', 'event_espresso') . $transaction->ID() . '">'
226
+                        . esc_attr__('View Transaction Details for TXN #', 'event_espresso').$transaction->ID().'">'
227 227
                         . $this->_get_txn_timestamp($transaction)
228 228
                         . '</a>';
229 229
         //status
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
                    )
257 257
                    . '</span>';
258 258
         } else {
259
-            return '<span class="txn-overview-free-event-spn">' . esc_html__('free', 'event_espresso') . '</span>';
259
+            return '<span class="txn-overview-free-event-spn">'.esc_html__('free', 'event_espresso').'</span>';
260 260
         }
261 261
     }
262 262
 
@@ -294,7 +294,7 @@  discard block
 block discarded – undo
294 294
             : esc_html__('Unknown', 'event_espresso');
295 295
         $transaction_paid_content = $transaction_paid !== 0 ? $transaction->get_pretty('TXN_paid') : $transaction_paid;
296 296
 
297
-        $content = '<span class="' . $span_class . ' txn-pad-rght">'
297
+        $content = '<span class="'.$span_class.' txn-pad-rght">'
298 298
                    . $transaction_paid_content
299 299
                    . '</span>';
300 300
         if ($transaction_paid > 0) {
@@ -325,17 +325,17 @@  discard block
 block discarded – undo
325 325
                 'action'  => 'view_registration',
326 326
                 '_REG_ID' => $primary_reg->ID(),
327 327
             ), REG_ADMIN_URL);
328
-            $content      = EE_Registry::instance()->CAP->current_user_can(
328
+            $content = EE_Registry::instance()->CAP->current_user_can(
329 329
                 'ee_read_registration',
330 330
                 'espresso_registrations_view_registration',
331 331
                 $primary_reg->ID()
332 332
             )
333
-                ? '<a href="' . $edit_lnk_url . '"'
334
-                    . ' title="' . esc_attr__('View Registration Details', 'event_espresso') . '">'
333
+                ? '<a href="'.$edit_lnk_url.'"'
334
+                    . ' title="'.esc_attr__('View Registration Details', 'event_espresso').'">'
335 335
                     . $attendee->full_name()
336 336
                     . '</a>'
337 337
                 : $attendee->full_name();
338
-            $content      .= '<br>' . $attendee->email();
338
+            $content .= '<br>'.$attendee->email();
339 339
             return $content;
340 340
         }
341 341
         return $transaction->failed() || $transaction->is_abandoned()
@@ -357,8 +357,8 @@  discard block
 block discarded – undo
357 357
     public function column_ATT_email(EE_Transaction $transaction)
358 358
     {
359 359
         $attendee = $transaction->primary_registration()->get_first_related('Attendee');
360
-        if (! empty($attendee)) {
361
-            return '<a href="mailto:' . $attendee->get('ATT_email') . '">'
360
+        if ( ! empty($attendee)) {
361
+            return '<a href="mailto:'.$attendee->get('ATT_email').'">'
362 362
                    . $attendee->get('ATT_email')
363 363
                    . '</a>';
364 364
         } else {
@@ -383,12 +383,12 @@  discard block
 block discarded – undo
383 383
     {
384 384
         $actions = array();
385 385
         $event   = $transaction->primary_registration()->get_first_related('Event');
386
-        if (! empty($event)) {
386
+        if ( ! empty($event)) {
387 387
             $edit_event_url = EE_Admin_Page::add_query_args_and_nonce(
388 388
                 array('action' => 'edit', 'post' => $event->ID()),
389 389
                 EVENTS_ADMIN_URL
390 390
             );
391
-            $event_name     = $event->get('EVT_name');
391
+            $event_name = $event->get('EVT_name');
392 392
 
393 393
             //filter this view by transactions for this event
394 394
             $txn_by_event_lnk = EE_Admin_Page::add_query_args_and_nonce(array(
@@ -400,8 +400,8 @@  discard block
 block discarded – undo
400 400
                 'espresso_events_edit',
401 401
                 $event->ID()
402 402
             )) {
403
-                $actions['filter_by_event'] = '<a href="' . $txn_by_event_lnk . '"'
404
-                        . ' title="' . esc_attr__('Filter transactions by this event', 'event_espresso') . '">'
403
+                $actions['filter_by_event'] = '<a href="'.$txn_by_event_lnk.'"'
404
+                        . ' title="'.esc_attr__('Filter transactions by this event', 'event_espresso').'">'
405 405
                         . esc_html__('View Transactions for this event', 'event_espresso')
406 406
                         . '</a>';
407 407
             }
@@ -413,7 +413,7 @@  discard block
 block discarded – undo
413 413
                     'espresso_events_edit',
414 414
                     $event->ID()
415 415
                 )
416
-                    ? '<a href="' . $edit_event_url . '"'
416
+                    ? '<a href="'.$edit_event_url.'"'
417 417
                         . ' title="'
418 418
                         . sprintf(
419 419
                             esc_attr__('Edit Event: %s', 'event_espresso'),
@@ -470,14 +470,14 @@  discard block
 block discarded – undo
470 470
      */
471 471
     protected function get_transaction_details_link(EE_Transaction $transaction)
472 472
     {
473
-        $url          = EE_Admin_Page::add_query_args_and_nonce(array(
473
+        $url = EE_Admin_Page::add_query_args_and_nonce(array(
474 474
             'action' => 'view_transaction',
475 475
             'TXN_ID' => $transaction->ID(),
476 476
         ), TXN_ADMIN_URL);
477 477
         return '
478 478
 			<li>
479
-				<a href="' . $url . '"'
480
-                    . ' title="' . esc_attr__('View Transaction Details', 'event_espresso') . '" class="tiny-text">
479
+				<a href="' . $url.'"'
480
+                    . ' title="'.esc_attr__('View Transaction Details', 'event_espresso').'" class="tiny-text">
481 481
 					<span class="dashicons dashicons-cart"></span>
482 482
 				</a>
483 483
 			</li>';
@@ -501,8 +501,8 @@  discard block
 block discarded – undo
501 501
             ) {
502 502
                 return '
503 503
                 <li>
504
-                    <a title="' . esc_attr__('View Transaction Invoice', 'event_espresso') . '"'
505
-                       . ' target="_blank" href="' . $url . '" class="tiny-text">
504
+                    <a title="' . esc_attr__('View Transaction Invoice', 'event_espresso').'"'
505
+                       . ' target="_blank" href="'.$url.'" class="tiny-text">
506 506
                         <span class="dashicons dashicons-media-spreadsheet ee-icon-size-18"></span>
507 507
                     </a>
508 508
                 </li>';
@@ -528,8 +528,8 @@  discard block
 block discarded – undo
528 528
                 && EEH_MSG_Template::is_mt_active('receipt')) {
529 529
                 return '
530 530
 			<li>
531
-				<a title="' . esc_attr__('View Transaction Receipt', 'event_espresso') . '"'
532
-                                  . ' target="_blank" href="' . $url . '" class="tiny-text">
531
+				<a title="' . esc_attr__('View Transaction Receipt', 'event_espresso').'"'
532
+                                  . ' target="_blank" href="'.$url.'" class="tiny-text">
533 533
 					<span class="dashicons dashicons-media-default ee-icon-size-18"></span>
534 534
 				</a>
535 535
 			</li>';
@@ -560,8 +560,8 @@  discard block
 block discarded – undo
560 560
             )
561 561
                 ? '
562 562
 				<li>
563
-					<a href="' . $url . '"'
564
-                  . ' title="' . esc_attr__('View Registration Details', 'event_espresso') . '" class="tiny-text">
563
+					<a href="' . $url.'"'
564
+                  . ' title="'.esc_attr__('View Registration Details', 'event_espresso').'" class="tiny-text">
565 565
 						<span class="dashicons dashicons-clipboard"></span>
566 566
 					</a>
567 567
 				</li>'
@@ -599,8 +599,8 @@  discard block
 block discarded – undo
599 599
             ), TXN_ADMIN_URL);
600 600
             return  '
601 601
             <li>
602
-                <a href="' . $url . '"'
603
-                  . ' title="' . esc_attr__('Send Payment Reminder', 'event_espresso') . '" class="tiny-text">
602
+                <a href="' . $url.'"'
603
+                  . ' title="'.esc_attr__('Send Payment Reminder', 'event_espresso').'" class="tiny-text">
604 604
                     <span class="dashicons dashicons-email-alt"></span>
605 605
                 </a>
606 606
             </li>';
@@ -627,7 +627,7 @@  discard block
 block discarded – undo
627 627
             'ee_read_global_messages',
628 628
             'view_filtered_messages'
629 629
         )
630
-            ? '<li>' . $url . '</li>'
630
+            ? '<li>'.$url.'</li>'
631 631
             : '';
632 632
     }
633 633
 
@@ -647,8 +647,8 @@  discard block
 block discarded – undo
647 647
         ) {
648 648
             return '
649 649
             <li>
650
-                <a title="' . esc_attr__('Make Payment from the Frontend.', 'event_espresso') . '"'
651
-                    . ' target="_blank" href="' . $registration->payment_overview_url(true) . '"'
650
+                <a title="' . esc_attr__('Make Payment from the Frontend.', 'event_espresso').'"'
651
+                    . ' target="_blank" href="'.$registration->payment_overview_url(true).'"'
652 652
                     . ' class="tiny-text">
653 653
                     <span class="dashicons dashicons-money ee-icon-size-18"></span>
654 654
                 </a>
Please login to merge, or discard this patch.
core/db_classes/EE_Registration.class.php 3 patches
Doc Comments   +4 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1159,7 +1159,7 @@  discard block
 block discarded – undo
1159 1159
      * Sets deleted
1160 1160
      *
1161 1161
      * @param boolean $deleted
1162
-     * @return bool
1162
+     * @return boolean|null
1163 1163
      * @throws EE_Error
1164 1164
      * @throws RuntimeException
1165 1165
      */
@@ -1217,6 +1217,7 @@  discard block
 block discarded – undo
1217 1217
      * @param int | EE_Datetime $DTT_OR_ID      The datetime the registration is being checked against
1218 1218
      * @param bool              $check_approved This is used to indicate whether the caller wants can_checkin to also
1219 1219
      *                                          consider registration status as well as datetime access.
1220
+     * @param integer $DTT_OR_ID
1220 1221
      * @return bool
1221 1222
      * @throws EE_Error
1222 1223
      */
@@ -1387,7 +1388,7 @@  discard block
 block discarded – undo
1387 1388
      * Returns the latest datetime related to this registration (via the ticket attached to the registration).
1388 1389
      * "Latest" is defined by the `DTT_EVT_start` column.
1389 1390
      *
1390
-     * @return EE_Datetime|null
1391
+     * @return null|EE_Base_Class
1391 1392
      * @throws \EE_Error
1392 1393
      */
1393 1394
     public function get_latest_related_datetime()
@@ -1680,7 +1681,7 @@  discard block
 block discarded – undo
1680 1681
      * This grabs the payment method corresponding to the last payment made for the amount owing on the registration.
1681 1682
      * Note: if there are no payments on the registration there will be no payment method returned.
1682 1683
      *
1683
-     * @return EE_Payment_Method|null
1684
+     * @return null|EE_Base_Class
1684 1685
      */
1685 1686
     public function payment_method()
1686 1687
     {
Please login to merge, or discard this patch.
Indentation   +1934 added lines, -1934 removed lines patch added patch discarded remove patch
@@ -18,1940 +18,1940 @@
 block discarded – undo
18 18
 {
19 19
 
20 20
 
21
-    /**
22
-     * Used to reference when a registration has never been checked in.
23
-     *
24
-     * @deprecated use \EE_Checkin::status_checked_never instead
25
-     * @type int
26
-     */
27
-    const checkin_status_never = 2;
28
-
29
-    /**
30
-     * Used to reference when a registration has been checked in.
31
-     *
32
-     * @deprecated use \EE_Checkin::status_checked_in instead
33
-     * @type int
34
-     */
35
-    const checkin_status_in = 1;
36
-
37
-
38
-    /**
39
-     * Used to reference when a registration has been checked out.
40
-     *
41
-     * @deprecated use \EE_Checkin::status_checked_out instead
42
-     * @type int
43
-     */
44
-    const checkin_status_out = 0;
45
-
46
-
47
-    /**
48
-     * extra meta key for tracking reg status os trashed registrations
49
-     *
50
-     * @type string
51
-     */
52
-    const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status';
53
-
54
-
55
-    /**
56
-     * extra meta key for tracking if registration has reserved ticket
57
-     *
58
-     * @type string
59
-     */
60
-    const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket';
61
-
62
-
63
-    /**
64
-     * @param array  $props_n_values          incoming values
65
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
66
-     *                                        used.)
67
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
68
-     *                                        date_format and the second value is the time format
69
-     * @return EE_Registration
70
-     * @throws EE_Error
71
-     */
72
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
73
-    {
74
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
75
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
76
-    }
77
-
78
-
79
-    /**
80
-     * @param array  $props_n_values  incoming values from the database
81
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
82
-     *                                the website will be used.
83
-     * @return EE_Registration
84
-     */
85
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
86
-    {
87
-        return new self($props_n_values, true, $timezone);
88
-    }
89
-
90
-
91
-    /**
92
-     *        Set Event ID
93
-     *
94
-     * @param        int $EVT_ID Event ID
95
-     * @throws EE_Error
96
-     * @throws RuntimeException
97
-     */
98
-    public function set_event($EVT_ID = 0)
99
-    {
100
-        $this->set('EVT_ID', $EVT_ID);
101
-    }
102
-
103
-
104
-    /**
105
-     * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can
106
-     * be routed to internal methods
107
-     *
108
-     * @param string $field_name
109
-     * @param mixed  $field_value
110
-     * @param bool   $use_default
111
-     * @throws EE_Error
112
-     * @throws EntityNotFoundException
113
-     * @throws InvalidArgumentException
114
-     * @throws InvalidDataTypeException
115
-     * @throws InvalidInterfaceException
116
-     * @throws ReflectionException
117
-     * @throws RuntimeException
118
-     */
119
-    public function set($field_name, $field_value, $use_default = false)
120
-    {
121
-        switch ($field_name) {
122
-            case 'REG_code':
123
-                if (! empty($field_value) && $this->reg_code() === null) {
124
-                    $this->set_reg_code($field_value, $use_default);
125
-                }
126
-                break;
127
-            case 'STS_ID':
128
-                $this->set_status($field_value, $use_default);
129
-                break;
130
-            default:
131
-                parent::set($field_name, $field_value, $use_default);
132
-        }
133
-    }
134
-
135
-
136
-    /**
137
-     * Set Status ID
138
-     * updates the registration status and ALSO...
139
-     * calls reserve_registration_space() if the reg status changes TO approved from any other reg status
140
-     * calls release_registration_space() if the reg status changes FROM approved to any other reg status
141
-     *
142
-     * @param string       $new_STS_ID
143
-     * @param boolean      $use_default
144
-     * @param Context|null $context
145
-     * @return bool
146
-     * @throws EE_Error
147
-     * @throws EntityNotFoundException
148
-     * @throws InvalidArgumentException
149
-     * @throws ReflectionException
150
-     * @throws RuntimeException
151
-     * @throws InvalidDataTypeException
152
-     * @throws InvalidInterfaceException
153
-     */
154
-    public function set_status($new_STS_ID = null, $use_default = false, Context $context = null)
155
-    {
156
-        // get current REG_Status
157
-        $old_STS_ID = $this->status_ID();
158
-        // if status has changed
159
-        if ($old_STS_ID !== $new_STS_ID // and that status has actually changed
160
-            && ! empty($old_STS_ID) // and that old status is actually set
161
-            && ! empty($new_STS_ID) // as well as the new status
162
-            && $this->ID() // ensure registration is in the db
163
-        ) {
164
-            // TO approved
165
-            if ($new_STS_ID === EEM_Registration::status_id_approved) {
166
-                // reserve a space by incrementing ticket and datetime sold values
167
-                $this->_reserve_registration_space();
168
-                do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context);
169
-                // OR FROM  approved
170
-            } elseif ($old_STS_ID === EEM_Registration::status_id_approved) {
171
-                // release a space by decrementing ticket and datetime sold values
172
-                $this->_release_registration_space();
173
-                do_action(
174
-                    'AHEE__EE_Registration__set_status__from_approved',
175
-                    $this,
176
-                    $old_STS_ID,
177
-                    $new_STS_ID,
178
-                    $context
179
-                );
180
-            }
181
-            // update status
182
-            parent::set('STS_ID', $new_STS_ID, $use_default);
183
-            $this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, $context);
184
-            if($this->statusChangeUpdatesTransaction($context)) {
185
-                $this->updateTransactionAfterStatusChange();
186
-            }
187
-            do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context);
188
-            return true;
189
-        }
190
-        //even though the old value matches the new value, it's still good to
191
-        //allow the parent set method to have a say
192
-        parent::set('STS_ID', $new_STS_ID, $use_default);
193
-        return true;
194
-    }
195
-
196
-
197
-    /**
198
-     * update REGs and TXN when cancelled or declined registrations involved
199
-     *
200
-     * @param string       $new_STS_ID
201
-     * @param string       $old_STS_ID
202
-     * @param Context|null $context
203
-     * @throws EE_Error
204
-     * @throws InvalidArgumentException
205
-     * @throws InvalidDataTypeException
206
-     * @throws InvalidInterfaceException
207
-     * @throws ReflectionException
208
-     */
209
-    private function _update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, Context $context = null)
210
-    {
211
-        // these reg statuses should not be considered in any calculations involving monies owing
212
-        $closed_reg_statuses = EEM_Registration::closed_reg_statuses();
213
-        // true if registration has been cancelled or declined
214
-        $this->updateIfCanceled(
215
-            $closed_reg_statuses,
216
-            $new_STS_ID,
217
-            $old_STS_ID,
218
-            $context
219
-        );
220
-        $this->updateIfDeclined(
221
-            $closed_reg_statuses,
222
-            $new_STS_ID,
223
-            $old_STS_ID,
224
-            $context
225
-        );
226
-    }
227
-
228
-
229
-    /**
230
-     * update REGs and TXN when cancelled or declined registrations involved
231
-     *
232
-     * @param array        $closed_reg_statuses
233
-     * @param string       $new_STS_ID
234
-     * @param string       $old_STS_ID
235
-     * @param Context|null $context
236
-     * @throws EE_Error
237
-     * @throws InvalidArgumentException
238
-     * @throws InvalidDataTypeException
239
-     * @throws InvalidInterfaceException
240
-     * @throws ReflectionException
241
-     */
242
-    private function updateIfCanceled(array $closed_reg_statuses, $new_STS_ID, $old_STS_ID, Context $context = null)
243
-    {
244
-        // true if registration has been cancelled or declined
245
-        if (in_array($new_STS_ID, $closed_reg_statuses, true)
246
-            && ! in_array($old_STS_ID, $closed_reg_statuses, true)
247
-        ) {
248
-            /** @type EE_Registration_Processor $registration_processor */
249
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
250
-            /** @type EE_Transaction_Processor $transaction_processor */
251
-            $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
252
-            // cancelled or declined registration
253
-            $registration_processor->update_registration_after_being_canceled_or_declined(
254
-                $this,
255
-                $closed_reg_statuses
256
-            );
257
-            $transaction_processor->update_transaction_after_canceled_or_declined_registration(
258
-                $this,
259
-                $closed_reg_statuses,
260
-                false
261
-            );
262
-            do_action(
263
-                'AHEE__EE_Registration__set_status__canceled_or_declined',
264
-                $this,
265
-                $old_STS_ID,
266
-                $new_STS_ID,
267
-                $context
268
-            );
269
-            return;
270
-        }
271
-    }
272
-
273
-
274
-    /**
275
-     * update REGs and TXN when cancelled or declined registrations involved
276
-     *
277
-     * @param array        $closed_reg_statuses
278
-     * @param string       $new_STS_ID
279
-     * @param string       $old_STS_ID
280
-     * @param Context|null $context
281
-     * @throws EE_Error
282
-     * @throws InvalidArgumentException
283
-     * @throws InvalidDataTypeException
284
-     * @throws InvalidInterfaceException
285
-     * @throws ReflectionException
286
-     */
287
-    private function updateIfDeclined(array $closed_reg_statuses, $new_STS_ID, $old_STS_ID, Context $context = null)
288
-    {
289
-        // true if reinstating cancelled or declined registration
290
-        if (in_array($old_STS_ID, $closed_reg_statuses, true)
291
-            && ! in_array($new_STS_ID, $closed_reg_statuses, true)
292
-        ) {
293
-            /** @type EE_Registration_Processor $registration_processor */
294
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
295
-            /** @type EE_Transaction_Processor $transaction_processor */
296
-            $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
297
-            // reinstating cancelled or declined registration
298
-            $registration_processor->update_canceled_or_declined_registration_after_being_reinstated(
299
-                $this,
300
-                $closed_reg_statuses
301
-            );
302
-            $transaction_processor->update_transaction_after_reinstating_canceled_registration(
303
-                $this,
304
-                $closed_reg_statuses,
305
-                false
306
-            );
307
-            do_action(
308
-                'AHEE__EE_Registration__set_status__after_reinstated',
309
-                $this,
310
-                $old_STS_ID,
311
-                $new_STS_ID,
312
-                $context
313
-            );
314
-        }
315
-    }
316
-
317
-
318
-    /**
319
-     * @param Context|null $context
320
-     * @return bool
321
-     */
322
-    private function statusChangeUpdatesTransaction(Context $context = null)
323
-    {
324
-        $contexts_that_do_not_update_transaction = (array) apply_filters(
325
-            'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction',
326
-            array('spco_reg_step_attendee_information_process_registrations'),
327
-            $context,
328
-            $this
329
-        );
330
-        return ! (
331
-            $context instanceof Context
332
-            && in_array($context->slug(), $contexts_that_do_not_update_transaction, true)
333
-        );
334
-    }
335
-
336
-
337
-    /**
338
-     * @throws EE_Error
339
-     * @throws EntityNotFoundException
340
-     * @throws InvalidArgumentException
341
-     * @throws InvalidDataTypeException
342
-     * @throws InvalidInterfaceException
343
-     * @throws ReflectionException
344
-     * @throws RuntimeException
345
-     */
346
-    private function updateTransactionAfterStatusChange()
347
-    {
348
-        /** @type EE_Transaction_Payments $transaction_payments */
349
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
350
-        $transaction_payments->recalculate_transaction_total($this->transaction(), false);
351
-        $this->transaction()->update_status_based_on_total_paid(true);
352
-    }
353
-
354
-
355
-    /**
356
-     *        get Status ID
357
-     */
358
-    public function status_ID()
359
-    {
360
-        return $this->get('STS_ID');
361
-    }
362
-
363
-
364
-    /**
365
-     * increments this registration's related ticket sold and corresponding datetime sold values
366
-     *
367
-     * @return void
368
-     * @throws EE_Error
369
-     * @throws EntityNotFoundException
370
-     */
371
-    private function _reserve_registration_space()
372
-    {
373
-        // reserved ticket and datetime counts will be decremented as sold counts are incremented
374
-        // so stop tracking that this reg has a ticket reserved
375
-        $this->release_reserved_ticket();
376
-        $ticket = $this->ticket();
377
-        $ticket->increase_sold();
378
-        $ticket->save();
379
-        // possibly set event status to sold out
380
-        $this->event()->perform_sold_out_status_check();
381
-    }
382
-
383
-
384
-    /**
385
-     * Gets the ticket this registration is for
386
-     *
387
-     * @param boolean $include_archived whether to include archived tickets or not.
388
-     * @return EE_Ticket|EE_Base_Class
389
-     * @throws \EE_Error
390
-     */
391
-    public function ticket($include_archived = true)
392
-    {
393
-        $query_params = array();
394
-        if ($include_archived) {
395
-            $query_params['default_where_conditions'] = 'none';
396
-        }
397
-        return $this->get_first_related('Ticket', $query_params);
398
-    }
399
-
400
-
401
-    /**
402
-     * Gets the event this registration is for
403
-     *
404
-     * @return EE_Event
405
-     * @throws EE_Error
406
-     * @throws EntityNotFoundException
407
-     */
408
-    public function event()
409
-    {
410
-        $event = $this->get_first_related('Event');
411
-        if (! $event instanceof \EE_Event) {
412
-            throw new EntityNotFoundException('Event ID', $this->event_ID());
413
-        }
414
-        return $event;
415
-    }
416
-
417
-
418
-    /**
419
-     * Gets the "author" of the registration.  Note that for the purposes of registrations, the author will correspond
420
-     * with the author of the event this registration is for.
421
-     *
422
-     * @since 4.5.0
423
-     * @return int
424
-     * @throws EE_Error
425
-     * @throws EntityNotFoundException
426
-     */
427
-    public function wp_user()
428
-    {
429
-        $event = $this->event();
430
-        if ($event instanceof EE_Event) {
431
-            return $event->wp_user();
432
-        }
433
-        return 0;
434
-    }
435
-
436
-
437
-    /**
438
-     * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values
439
-     *
440
-     * @return void
441
-     * @throws \EE_Error
442
-     */
443
-    private function _release_registration_space()
444
-    {
445
-        $ticket = $this->ticket();
446
-        $ticket->decrease_sold();
447
-        $ticket->save();
448
-    }
449
-
450
-
451
-    /**
452
-     * tracks this registration's ticket reservation in extra meta
453
-     * and can increment related ticket reserved and corresponding datetime reserved values
454
-     *
455
-     * @param bool $update_ticket if true, will increment ticket and datetime reserved count
456
-     * @return void
457
-     * @throws \EE_Error
458
-     */
459
-    public function reserve_ticket($update_ticket = false)
460
-    {
461
-        if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) === false) {
462
-            // PLZ NOTE: although checking $update_ticket first would be more efficient,
463
-            // we NEED to ALWAYS call update_extra_meta(), which is why that is done first
464
-            if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) && $update_ticket) {
465
-                $ticket = $this->ticket();
466
-                $ticket->increase_reserved();
467
-                $ticket->save();
468
-            }
469
-        }
470
-    }
471
-
472
-
473
-    /**
474
-     * stops tracking this registration's ticket reservation in extra meta
475
-     * decrements (subtracts) related ticket reserved and corresponding datetime reserved values
476
-     *
477
-     * @param bool $update_ticket if true, will decrement ticket and datetime reserved count
478
-     * @return void
479
-     * @throws \EE_Error
480
-     */
481
-    public function release_reserved_ticket($update_ticket = false)
482
-    {
483
-        if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) !== false) {
484
-            // PLZ NOTE: although checking $update_ticket first would be more efficient,
485
-            // we NEED to ALWAYS call delete_extra_meta(), which is why that is done first
486
-            if ($this->delete_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY) && $update_ticket) {
487
-                $ticket = $this->ticket();
488
-                $ticket->decrease_reserved();
489
-                $ticket->save();
490
-            }
491
-        }
492
-    }
493
-
494
-
495
-    /**
496
-     * Set Attendee ID
497
-     *
498
-     * @param        int $ATT_ID Attendee ID
499
-     * @throws EE_Error
500
-     * @throws RuntimeException
501
-     */
502
-    public function set_attendee_id($ATT_ID = 0)
503
-    {
504
-        $this->set('ATT_ID', $ATT_ID);
505
-    }
506
-
507
-
508
-    /**
509
-     *        Set Transaction ID
510
-     *
511
-     * @param        int $TXN_ID Transaction ID
512
-     * @throws EE_Error
513
-     * @throws RuntimeException
514
-     */
515
-    public function set_transaction_id($TXN_ID = 0)
516
-    {
517
-        $this->set('TXN_ID', $TXN_ID);
518
-    }
519
-
520
-
521
-    /**
522
-     *        Set Session
523
-     *
524
-     * @param    string $REG_session PHP Session ID
525
-     * @throws EE_Error
526
-     * @throws RuntimeException
527
-     */
528
-    public function set_session($REG_session = '')
529
-    {
530
-        $this->set('REG_session', $REG_session);
531
-    }
532
-
533
-
534
-    /**
535
-     *        Set Registration URL Link
536
-     *
537
-     * @param    string $REG_url_link Registration URL Link
538
-     * @throws EE_Error
539
-     * @throws RuntimeException
540
-     */
541
-    public function set_reg_url_link($REG_url_link = '')
542
-    {
543
-        $this->set('REG_url_link', $REG_url_link);
544
-    }
545
-
546
-
547
-    /**
548
-     *        Set Attendee Counter
549
-     *
550
-     * @param        int $REG_count Primary Attendee
551
-     * @throws EE_Error
552
-     * @throws RuntimeException
553
-     */
554
-    public function set_count($REG_count = 1)
555
-    {
556
-        $this->set('REG_count', $REG_count);
557
-    }
558
-
559
-
560
-    /**
561
-     *        Set Group Size
562
-     *
563
-     * @param        boolean $REG_group_size Group Registration
564
-     * @throws EE_Error
565
-     * @throws RuntimeException
566
-     */
567
-    public function set_group_size($REG_group_size = false)
568
-    {
569
-        $this->set('REG_group_size', $REG_group_size);
570
-    }
571
-
572
-
573
-    /**
574
-     *    is_not_approved -  convenience method that returns TRUE if REG status ID ==
575
-     *    EEM_Registration::status_id_not_approved
576
-     *
577
-     * @return        boolean
578
-     */
579
-    public function is_not_approved()
580
-    {
581
-        return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false;
582
-    }
583
-
584
-
585
-    /**
586
-     *    is_pending_payment -  convenience method that returns TRUE if REG status ID ==
587
-     *    EEM_Registration::status_id_pending_payment
588
-     *
589
-     * @return        boolean
590
-     */
591
-    public function is_pending_payment()
592
-    {
593
-        return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false;
594
-    }
595
-
596
-
597
-    /**
598
-     *    is_approved -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved
599
-     *
600
-     * @return        boolean
601
-     */
602
-    public function is_approved()
603
-    {
604
-        return $this->status_ID() == EEM_Registration::status_id_approved ? true : false;
605
-    }
606
-
607
-
608
-    /**
609
-     *    is_cancelled -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled
610
-     *
611
-     * @return        boolean
612
-     */
613
-    public function is_cancelled()
614
-    {
615
-        return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false;
616
-    }
617
-
618
-
619
-    /**
620
-     *    is_declined -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined
621
-     *
622
-     * @return        boolean
623
-     */
624
-    public function is_declined()
625
-    {
626
-        return $this->status_ID() == EEM_Registration::status_id_declined ? true : false;
627
-    }
628
-
629
-
630
-    /**
631
-     *    is_incomplete -  convenience method that returns TRUE if REG status ID ==
632
-     *    EEM_Registration::status_id_incomplete
633
-     *
634
-     * @return        boolean
635
-     */
636
-    public function is_incomplete()
637
-    {
638
-        return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false;
639
-    }
640
-
641
-
642
-    /**
643
-     *        Set Registration Date
644
-     *
645
-     * @param        mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of
646
-     *                                                 Date
647
-     * @throws EE_Error
648
-     * @throws RuntimeException
649
-     */
650
-    public function set_reg_date($REG_date = false)
651
-    {
652
-        $this->set('REG_date', $REG_date);
653
-    }
654
-
655
-
656
-    /**
657
-     *    Set final price owing for this registration after all ticket/price modifications
658
-     *
659
-     * @access    public
660
-     * @param    float $REG_final_price
661
-     * @throws EE_Error
662
-     * @throws RuntimeException
663
-     */
664
-    public function set_final_price($REG_final_price = 0.00)
665
-    {
666
-        $this->set('REG_final_price', $REG_final_price);
667
-    }
668
-
669
-
670
-    /**
671
-     *    Set amount paid towards this registration's final price
672
-     *
673
-     * @access    public
674
-     * @param    float $REG_paid
675
-     * @throws EE_Error
676
-     * @throws RuntimeException
677
-     */
678
-    public function set_paid($REG_paid = 0.00)
679
-    {
680
-        $this->set('REG_paid', $REG_paid);
681
-    }
682
-
683
-
684
-    /**
685
-     *        Attendee Is Going
686
-     *
687
-     * @param        boolean $REG_att_is_going Attendee Is Going
688
-     * @throws EE_Error
689
-     * @throws RuntimeException
690
-     */
691
-    public function set_att_is_going($REG_att_is_going = false)
692
-    {
693
-        $this->set('REG_att_is_going', $REG_att_is_going);
694
-    }
695
-
696
-
697
-    /**
698
-     * Gets the related attendee
699
-     *
700
-     * @return EE_Attendee
701
-     * @throws EE_Error
702
-     */
703
-    public function attendee()
704
-    {
705
-        return $this->get_first_related('Attendee');
706
-    }
707
-
708
-
709
-    /**
710
-     *        get Event ID
711
-     */
712
-    public function event_ID()
713
-    {
714
-        return $this->get('EVT_ID');
715
-    }
716
-
717
-
718
-    /**
719
-     *        get Event ID
720
-     */
721
-    public function event_name()
722
-    {
723
-        $event = $this->event_obj();
724
-        if ($event) {
725
-            return $event->name();
726
-        } else {
727
-            return null;
728
-        }
729
-    }
730
-
731
-
732
-    /**
733
-     * Fetches the event this registration is for
734
-     *
735
-     * @return EE_Event
736
-     * @throws EE_Error
737
-     */
738
-    public function event_obj()
739
-    {
740
-        return $this->get_first_related('Event');
741
-    }
742
-
743
-
744
-    /**
745
-     *        get Attendee ID
746
-     */
747
-    public function attendee_ID()
748
-    {
749
-        return $this->get('ATT_ID');
750
-    }
751
-
752
-
753
-    /**
754
-     *        get PHP Session ID
755
-     */
756
-    public function session_ID()
757
-    {
758
-        return $this->get('REG_session');
759
-    }
760
-
761
-
762
-    /**
763
-     * Gets the string which represents the URL trigger for the receipt template in the message template system.
764
-     *
765
-     * @param string $messenger 'pdf' or 'html'.  Default 'html'.
766
-     * @return string
767
-     */
768
-    public function receipt_url($messenger = 'html')
769
-    {
770
-
771
-        /**
772
-         * The below will be deprecated one version after this.  We check first if there is a custom receipt template
773
-         * already in use on old system.  If there is then we just return the standard url for it.
774
-         *
775
-         * @since 4.5.0
776
-         */
777
-        $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php';
778
-        $has_custom             = EEH_Template::locate_template(
779
-            $template_relative_path,
780
-            array(),
781
-            true,
782
-            true,
783
-            true
784
-        );
785
-
786
-        if ($has_custom) {
787
-            return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch'));
788
-        }
789
-        return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt');
790
-    }
791
-
792
-
793
-    /**
794
-     * Gets the string which represents the URL trigger for the invoice template in the message template system.
795
-     *
796
-     * @param string $messenger 'pdf' or 'html'.  Default 'html'.
797
-     * @return string
798
-     * @throws EE_Error
799
-     */
800
-    public function invoice_url($messenger = 'html')
801
-    {
802
-        /**
803
-         * The below will be deprecated one version after this.  We check first if there is a custom invoice template
804
-         * already in use on old system.  If there is then we just return the standard url for it.
805
-         *
806
-         * @since 4.5.0
807
-         */
808
-        $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php';
809
-        $has_custom             = EEH_Template::locate_template(
810
-            $template_relative_path,
811
-            array(),
812
-            true,
813
-            true,
814
-            true
815
-        );
816
-
817
-        if ($has_custom) {
818
-            if ($messenger == 'html') {
819
-                return $this->invoice_url('launch');
820
-            }
821
-            $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice';
822
-
823
-            $query_args = array('ee' => $route, 'id' => $this->reg_url_link());
824
-            if ($messenger == 'html') {
825
-                $query_args['html'] = true;
826
-            }
827
-            return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id));
828
-        }
829
-        return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice');
830
-    }
831
-
832
-
833
-    /**
834
-     * get Registration URL Link
835
-     *
836
-     * @access public
837
-     * @return string
838
-     * @throws \EE_Error
839
-     */
840
-    public function reg_url_link()
841
-    {
842
-        return (string) $this->get('REG_url_link');
843
-    }
844
-
845
-
846
-    /**
847
-     * Echoes out invoice_url()
848
-     *
849
-     * @param string $type 'download','launch', or 'html' (default is 'launch')
850
-     * @return void
851
-     * @throws EE_Error
852
-     */
853
-    public function e_invoice_url($type = 'launch')
854
-    {
855
-        echo $this->invoice_url($type);
856
-    }
857
-
858
-
859
-    /**
860
-     * Echoes out payment_overview_url
861
-     */
862
-    public function e_payment_overview_url()
863
-    {
864
-        echo $this->payment_overview_url();
865
-    }
866
-
867
-
868
-    /**
869
-     * Gets the URL of the thank you page with this registration REG_url_link added as
870
-     * a query parameter
871
-     *
872
-     * @param bool $clear_session Set to true when you want to clear the session on revisiting the
873
-     *                            payment overview url.
874
-     * @return string
875
-     * @throws EE_Error
876
-     */
877
-    public function payment_overview_url($clear_session = false)
878
-    {
879
-        return add_query_arg(array(
880
-            'e_reg_url_link' => $this->reg_url_link(),
881
-            'step'           => 'payment_options',
882
-            'revisit'        => true,
883
-            'clear_session' => (bool) $clear_session
884
-        ), EE_Registry::instance()->CFG->core->reg_page_url());
885
-    }
886
-
887
-
888
-    /**
889
-     * Gets the URL of the thank you page with this registration REG_url_link added as
890
-     * a query parameter
891
-     *
892
-     * @return string
893
-     * @throws EE_Error
894
-     */
895
-    public function edit_attendee_information_url()
896
-    {
897
-        return add_query_arg(array(
898
-            'e_reg_url_link' => $this->reg_url_link(),
899
-            'step'           => 'attendee_information',
900
-            'revisit'        => true,
901
-        ), EE_Registry::instance()->CFG->core->reg_page_url());
902
-    }
903
-
904
-
905
-    /**
906
-     * Simply generates and returns the appropriate admin_url link to edit this registration
907
-     *
908
-     * @return string
909
-     * @throws EE_Error
910
-     */
911
-    public function get_admin_edit_url()
912
-    {
913
-        return EEH_URL::add_query_args_and_nonce(array(
914
-            'page'    => 'espresso_registrations',
915
-            'action'  => 'view_registration',
916
-            '_REG_ID' => $this->ID(),
917
-        ), admin_url('admin.php'));
918
-    }
919
-
920
-
921
-    /**
922
-     *    is_primary_registrant?
923
-     */
924
-    public function is_primary_registrant()
925
-    {
926
-        return $this->get('REG_count') == 1 ? true : false;
927
-    }
928
-
929
-
930
-    /**
931
-     * This returns the primary registration object for this registration group (which may be this object).
932
-     *
933
-     * @return EE_Registration
934
-     * @throws EE_Error
935
-     */
936
-    public function get_primary_registration()
937
-    {
938
-        if ($this->is_primary_registrant()) {
939
-            return $this;
940
-        }
941
-
942
-        //k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1
943
-        /** @var EE_Registration $primary_registrant */
944
-        $primary_registrant = EEM_Registration::instance()->get_one(array(
945
-            array(
946
-                'TXN_ID'    => $this->transaction_ID(),
947
-                'REG_count' => 1,
948
-            ),
949
-        ));
950
-        return $primary_registrant;
951
-    }
952
-
953
-
954
-    /**
955
-     *        get  Attendee Number
956
-     *
957
-     * @access        public
958
-     */
959
-    public function count()
960
-    {
961
-        return $this->get('REG_count');
962
-    }
963
-
964
-
965
-    /**
966
-     *        get Group Size
967
-     */
968
-    public function group_size()
969
-    {
970
-        return $this->get('REG_group_size');
971
-    }
972
-
973
-
974
-    /**
975
-     *        get Registration Date
976
-     */
977
-    public function date()
978
-    {
979
-        return $this->get('REG_date');
980
-    }
981
-
982
-
983
-    /**
984
-     * gets a pretty date
985
-     *
986
-     * @param string $date_format
987
-     * @param string $time_format
988
-     * @return string
989
-     * @throws EE_Error
990
-     */
991
-    public function pretty_date($date_format = null, $time_format = null)
992
-    {
993
-        return $this->get_datetime('REG_date', $date_format, $time_format);
994
-    }
995
-
996
-
997
-    /**
998
-     * final_price
999
-     * the registration's share of the transaction total, so that the
1000
-     * sum of all the transaction's REG_final_prices equal the transaction's total
1001
-     *
1002
-     * @return float
1003
-     * @throws EE_Error
1004
-     */
1005
-    public function final_price()
1006
-    {
1007
-        return $this->get('REG_final_price');
1008
-    }
1009
-
1010
-
1011
-    /**
1012
-     * pretty_final_price
1013
-     *  final price as formatted string, with correct decimal places and currency symbol
1014
-     *
1015
-     * @return string
1016
-     * @throws EE_Error
1017
-     */
1018
-    public function pretty_final_price()
1019
-    {
1020
-        return $this->get_pretty('REG_final_price');
1021
-    }
1022
-
1023
-
1024
-    /**
1025
-     * get paid (yeah)
1026
-     *
1027
-     * @return float
1028
-     * @throws EE_Error
1029
-     */
1030
-    public function paid()
1031
-    {
1032
-        return $this->get('REG_paid');
1033
-    }
1034
-
1035
-
1036
-    /**
1037
-     * pretty_paid
1038
-     *
1039
-     * @return float
1040
-     * @throws EE_Error
1041
-     */
1042
-    public function pretty_paid()
1043
-    {
1044
-        return $this->get_pretty('REG_paid');
1045
-    }
1046
-
1047
-
1048
-    /**
1049
-     * owes_monies_and_can_pay
1050
-     * whether or not this registration has monies owing and it's' status allows payment
1051
-     *
1052
-     * @param array $requires_payment
1053
-     * @return bool
1054
-     * @throws EE_Error
1055
-     */
1056
-    public function owes_monies_and_can_pay($requires_payment = array())
1057
-    {
1058
-        // these reg statuses require payment (if event is not free)
1059
-        $requires_payment = ! empty($requires_payment)
1060
-            ? $requires_payment
1061
-            : EEM_Registration::reg_statuses_that_allow_payment();
1062
-        if (in_array($this->status_ID(), $requires_payment) &&
1063
-            $this->final_price() != 0 &&
1064
-            $this->final_price() != $this->paid()
1065
-        ) {
1066
-            return true;
1067
-        } else {
1068
-            return false;
1069
-        }
1070
-    }
1071
-
1072
-
1073
-    /**
1074
-     * Prints out the return value of $this->pretty_status()
1075
-     *
1076
-     * @param bool $show_icons
1077
-     * @return void
1078
-     * @throws EE_Error
1079
-     */
1080
-    public function e_pretty_status($show_icons = false)
1081
-    {
1082
-        echo $this->pretty_status($show_icons);
1083
-    }
1084
-
1085
-
1086
-    /**
1087
-     * Returns a nice version of the status for displaying to customers
1088
-     *
1089
-     * @param bool $show_icons
1090
-     * @return string
1091
-     * @throws EE_Error
1092
-     */
1093
-    public function pretty_status($show_icons = false)
1094
-    {
1095
-        $status = EEM_Status::instance()->localized_status(
1096
-            array($this->status_ID() => esc_html__('unknown', 'event_espresso')),
1097
-            false,
1098
-            'sentence'
1099
-        );
1100
-        $icon   = '';
1101
-        switch ($this->status_ID()) {
1102
-            case EEM_Registration::status_id_approved:
1103
-                $icon = $show_icons
1104
-                    ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>'
1105
-                    : '';
1106
-                break;
1107
-            case EEM_Registration::status_id_pending_payment:
1108
-                $icon = $show_icons
1109
-                    ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>'
1110
-                    : '';
1111
-                break;
1112
-            case EEM_Registration::status_id_not_approved:
1113
-                $icon = $show_icons
1114
-                    ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>'
1115
-                    : '';
1116
-                break;
1117
-            case EEM_Registration::status_id_cancelled:
1118
-                $icon = $show_icons
1119
-                    ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>'
1120
-                    : '';
1121
-                break;
1122
-            case EEM_Registration::status_id_incomplete:
1123
-                $icon = $show_icons
1124
-                    ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>'
1125
-                    : '';
1126
-                break;
1127
-            case EEM_Registration::status_id_declined:
1128
-                $icon = $show_icons
1129
-                    ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>'
1130
-                    : '';
1131
-                break;
1132
-            case EEM_Registration::status_id_wait_list:
1133
-                $icon = $show_icons
1134
-                    ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>'
1135
-                    : '';
1136
-                break;
1137
-        }
1138
-        return $icon . $status[$this->status_ID()];
1139
-    }
1140
-
1141
-
1142
-    /**
1143
-     *        get Attendee Is Going
1144
-     */
1145
-    public function att_is_going()
1146
-    {
1147
-        return $this->get('REG_att_is_going');
1148
-    }
1149
-
1150
-
1151
-    /**
1152
-     * Gets related answers
1153
-     *
1154
-     * @param array $query_params like EEM_Base::get_all
1155
-     * @return EE_Answer[]
1156
-     * @throws EE_Error
1157
-     */
1158
-    public function answers($query_params = null)
1159
-    {
1160
-        return $this->get_many_related('Answer', $query_params);
1161
-    }
1162
-
1163
-
1164
-    /**
1165
-     * Gets the registration's answer value to the specified question
1166
-     * (either the question's ID or a question object)
1167
-     *
1168
-     * @param EE_Question|int $question
1169
-     * @param bool            $pretty_value
1170
-     * @return array|string if pretty_value= true, the result will always be a string
1171
-     * (because the answer might be an array of answer values, so passing pretty_value=true
1172
-     * will convert it into some kind of string)
1173
-     * @throws EE_Error
1174
-     */
1175
-    public function answer_value_to_question($question, $pretty_value = true)
1176
-    {
1177
-        $question_id = EEM_Question::instance()->ensure_is_ID($question);
1178
-        return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value);
1179
-    }
1180
-
1181
-
1182
-    /**
1183
-     * question_groups
1184
-     * returns an array of EE_Question_Group objects for this registration
1185
-     *
1186
-     * @return EE_Question_Group[]
1187
-     * @throws EE_Error
1188
-     * @throws EntityNotFoundException
1189
-     */
1190
-    public function question_groups()
1191
-    {
1192
-        $question_groups = array();
1193
-        if ($this->event() instanceof EE_Event) {
1194
-            $question_groups = $this->event()->question_groups(
1195
-                array(
1196
-                    array(
1197
-                        'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false,
1198
-                    ),
1199
-                    'order_by' => array('QSG_order' => 'ASC'),
1200
-                )
1201
-            );
1202
-        }
1203
-        return $question_groups;
1204
-    }
1205
-
1206
-
1207
-    /**
1208
-     * count_question_groups
1209
-     * returns a count of the number of EE_Question_Group objects for this registration
1210
-     *
1211
-     * @return int
1212
-     * @throws EE_Error
1213
-     * @throws EntityNotFoundException
1214
-     */
1215
-    public function count_question_groups()
1216
-    {
1217
-        $qg_count = 0;
1218
-        if ($this->event() instanceof EE_Event) {
1219
-            $qg_count = $this->event()->count_related(
1220
-                'Question_Group',
1221
-                array(
1222
-                    array(
1223
-                        'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false,
1224
-                    ),
1225
-                )
1226
-            );
1227
-        }
1228
-        return $qg_count;
1229
-    }
1230
-
1231
-
1232
-    /**
1233
-     * Returns the registration date in the 'standard' string format
1234
-     * (function may be improved in the future to allow for different formats and timezones)
1235
-     *
1236
-     * @return string
1237
-     * @throws EE_Error
1238
-     */
1239
-    public function reg_date()
1240
-    {
1241
-        return $this->get_datetime('REG_date');
1242
-    }
1243
-
1244
-
1245
-    /**
1246
-     * Gets the datetime-ticket for this registration (ie, it can be used to isolate
1247
-     * the ticket this registration purchased, or the datetime they have registered
1248
-     * to attend)
1249
-     *
1250
-     * @return EE_Datetime_Ticket
1251
-     * @throws EE_Error
1252
-     */
1253
-    public function datetime_ticket()
1254
-    {
1255
-        return $this->get_first_related('Datetime_Ticket');
1256
-    }
1257
-
1258
-
1259
-    /**
1260
-     * Sets the registration's datetime_ticket.
1261
-     *
1262
-     * @param EE_Datetime_Ticket $datetime_ticket
1263
-     * @return EE_Datetime_Ticket
1264
-     * @throws EE_Error
1265
-     */
1266
-    public function set_datetime_ticket($datetime_ticket)
1267
-    {
1268
-        return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket');
1269
-    }
1270
-
1271
-    /**
1272
-     * Gets deleted
1273
-     *
1274
-     * @return bool
1275
-     * @throws EE_Error
1276
-     */
1277
-    public function deleted()
1278
-    {
1279
-        return $this->get('REG_deleted');
1280
-    }
1281
-
1282
-    /**
1283
-     * Sets deleted
1284
-     *
1285
-     * @param boolean $deleted
1286
-     * @return bool
1287
-     * @throws EE_Error
1288
-     * @throws RuntimeException
1289
-     */
1290
-    public function set_deleted($deleted)
1291
-    {
1292
-        if ($deleted) {
1293
-            $this->delete();
1294
-        } else {
1295
-            $this->restore();
1296
-        }
1297
-    }
1298
-
1299
-
1300
-    /**
1301
-     * Get the status object of this object
1302
-     *
1303
-     * @return EE_Status
1304
-     * @throws EE_Error
1305
-     */
1306
-    public function status_obj()
1307
-    {
1308
-        return $this->get_first_related('Status');
1309
-    }
1310
-
1311
-
1312
-    /**
1313
-     * Returns the number of times this registration has checked into any of the datetimes
1314
-     * its available for
1315
-     *
1316
-     * @return int
1317
-     * @throws EE_Error
1318
-     */
1319
-    public function count_checkins()
1320
-    {
1321
-        return $this->get_model()->count_related($this, 'Checkin');
1322
-    }
1323
-
1324
-
1325
-    /**
1326
-     * Returns the number of current Check-ins this registration is checked into for any of the datetimes the
1327
-     * registration is for.  Note, this is ONLY checked in (does not include checkedout)
1328
-     *
1329
-     * @return int
1330
-     * @throws EE_Error
1331
-     */
1332
-    public function count_checkins_not_checkedout()
1333
-    {
1334
-        return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1)));
1335
-    }
1336
-
1337
-
1338
-    /**
1339
-     * The purpose of this method is simply to check whether this registration can checkin to the given datetime.
1340
-     *
1341
-     * @param int | EE_Datetime $DTT_OR_ID      The datetime the registration is being checked against
1342
-     * @param bool              $check_approved This is used to indicate whether the caller wants can_checkin to also
1343
-     *                                          consider registration status as well as datetime access.
1344
-     * @return bool
1345
-     * @throws EE_Error
1346
-     */
1347
-    public function can_checkin($DTT_OR_ID, $check_approved = true)
1348
-    {
1349
-        $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1350
-
1351
-        //first check registration status
1352
-        if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) {
1353
-            return false;
1354
-        }
1355
-        //is there a datetime ticket that matches this dtt_ID?
1356
-        if (! (EEM_Datetime_Ticket::instance()->exists(array(
1357
-            array(
1358
-                'TKT_ID' => $this->get('TKT_ID'),
1359
-                'DTT_ID' => $DTT_ID,
1360
-            ),
1361
-        )))
1362
-        ) {
1363
-            return false;
1364
-        }
1365
-
1366
-        //final check is against TKT_uses
1367
-        return $this->verify_can_checkin_against_TKT_uses($DTT_ID);
1368
-    }
1369
-
1370
-
1371
-    /**
1372
-     * This method verifies whether the user can checkin for the given datetime considering the max uses value set on
1373
-     * the ticket. To do this,  a query is done to get the count of the datetime records already checked into.  If the
1374
-     * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses,
1375
-     * then return false.  Otherwise return true.
1376
-     *
1377
-     * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against
1378
-     * @return bool true means can checkin.  false means cannot checkin.
1379
-     * @throws EE_Error
1380
-     */
1381
-    public function verify_can_checkin_against_TKT_uses($DTT_OR_ID)
1382
-    {
1383
-        $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1384
-
1385
-        if (! $DTT_ID) {
1386
-            return false;
1387
-        }
1388
-
1389
-        $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF;
1390
-
1391
-        // if max uses is not set or equals infinity then return true cause its not a factor for whether user can
1392
-        // check-in or not.
1393
-        if (! $max_uses || $max_uses === EE_INF) {
1394
-            return true;
1395
-        }
1396
-
1397
-        //does this datetime have a checkin record?  If so, then the dtt count has already been verified so we can just
1398
-        //go ahead and toggle.
1399
-        if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) {
1400
-            return true;
1401
-        }
1402
-
1403
-        //made it here so the last check is whether the number of checkins per unique datetime on this registration
1404
-        //disallows further check-ins.
1405
-        $count_unique_dtt_checkins = EEM_Checkin::instance()->count(array(
1406
-            array(
1407
-                'REG_ID' => $this->ID(),
1408
-                'CHK_in' => true,
1409
-            ),
1410
-        ), 'DTT_ID', true);
1411
-        // checkins have already reached their max number of uses
1412
-        // so registrant can NOT checkin
1413
-        if ($count_unique_dtt_checkins >= $max_uses) {
1414
-            EE_Error::add_error(
1415
-                esc_html__(
1416
-                    'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.',
1417
-                    'event_espresso'
1418
-                ),
1419
-                __FILE__,
1420
-                __FUNCTION__,
1421
-                __LINE__
1422
-            );
1423
-            return false;
1424
-        }
1425
-        return true;
1426
-    }
1427
-
1428
-
1429
-    /**
1430
-     * toggle Check-in status for this registration
1431
-     * Check-ins are toggled in the following order:
1432
-     * never checked in -> checked in
1433
-     * checked in -> checked out
1434
-     * checked out -> checked in
1435
-     *
1436
-     * @param  int $DTT_ID  include specific datetime to toggle Check-in for.
1437
-     *                      If not included or null, then it is assumed latest datetime is being toggled.
1438
-     * @param bool $verify  If true then can_checkin() is used to verify whether the person
1439
-     *                      can be checked in or not.  Otherwise this forces change in checkin status.
1440
-     * @return bool|int     the chk_in status toggled to OR false if nothing got changed.
1441
-     * @throws EE_Error
1442
-     */
1443
-    public function toggle_checkin_status($DTT_ID = null, $verify = false)
1444
-    {
1445
-        if (empty($DTT_ID)) {
1446
-            $datetime = $this->get_latest_related_datetime();
1447
-            $DTT_ID   = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
1448
-            // verify the registration can checkin for the given DTT_ID
1449
-        } elseif (! $this->can_checkin($DTT_ID, $verify)) {
1450
-            EE_Error::add_error(
1451
-                sprintf(
1452
-                    esc_html__(
1453
-                        'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access',
1454
-                        'event_espresso'
1455
-                    ),
1456
-                    $this->ID(),
1457
-                    $DTT_ID
1458
-                ),
1459
-                __FILE__,
1460
-                __FUNCTION__,
1461
-                __LINE__
1462
-            );
1463
-            return false;
1464
-        }
1465
-        $status_paths = array(
1466
-            EE_Checkin::status_checked_never => EE_Checkin::status_checked_in,
1467
-            EE_Checkin::status_checked_in    => EE_Checkin::status_checked_out,
1468
-            EE_Checkin::status_checked_out   => EE_Checkin::status_checked_in,
1469
-        );
1470
-        //start by getting the current status so we know what status we'll be changing to.
1471
-        $cur_status = $this->check_in_status_for_datetime($DTT_ID, null);
1472
-        $status_to  = $status_paths[$cur_status];
1473
-        // database only records true for checked IN or false for checked OUT
1474
-        // no record ( null ) means checked in NEVER, but we obviously don't save that
1475
-        $new_status = $status_to === EE_Checkin::status_checked_in ? true : false;
1476
-        // add relation - note Check-ins are always creating new rows
1477
-        // because we are keeping track of Check-ins over time.
1478
-        // Eventually we'll probably want to show a list table
1479
-        // for the individual Check-ins so that they can be managed.
1480
-        $checkin = EE_Checkin::new_instance(array(
1481
-            'REG_ID' => $this->ID(),
1482
-            'DTT_ID' => $DTT_ID,
1483
-            'CHK_in' => $new_status,
1484
-        ));
1485
-        // if the record could not be saved then return false
1486
-        if ($checkin->save() === 0) {
1487
-            if (WP_DEBUG) {
1488
-                global $wpdb;
1489
-                $error = sprintf(
1490
-                    esc_html__(
1491
-                        'Registration check in update failed because of the following database error: %1$s%2$s',
1492
-                        'event_espresso'
1493
-                    ),
1494
-                    '<br />',
1495
-                    $wpdb->last_error
1496
-                );
1497
-            } else {
1498
-                $error = esc_html__(
1499
-                    'Registration check in update failed because of an unknown database error',
1500
-                    'event_espresso'
1501
-                );
1502
-            }
1503
-            EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
1504
-            return false;
1505
-        }
1506
-        return $status_to;
1507
-    }
1508
-
1509
-
1510
-    /**
1511
-     * Returns the latest datetime related to this registration (via the ticket attached to the registration).
1512
-     * "Latest" is defined by the `DTT_EVT_start` column.
1513
-     *
1514
-     * @return EE_Datetime|null
1515
-     * @throws \EE_Error
1516
-     */
1517
-    public function get_latest_related_datetime()
1518
-    {
1519
-        return EEM_Datetime::instance()->get_one(
1520
-            array(
1521
-                array(
1522
-                    'Ticket.Registration.REG_ID' => $this->ID(),
1523
-                ),
1524
-                'order_by' => array('DTT_EVT_start' => 'DESC'),
1525
-            )
1526
-        );
1527
-    }
1528
-
1529
-
1530
-    /**
1531
-     * Returns the earliest datetime related to this registration (via the ticket attached to the registration).
1532
-     * "Earliest" is defined by the `DTT_EVT_start` column.
1533
-     *
1534
-     * @throws \EE_Error
1535
-     */
1536
-    public function get_earliest_related_datetime()
1537
-    {
1538
-        return EEM_Datetime::instance()->get_one(
1539
-            array(
1540
-                array(
1541
-                    'Ticket.Registration.REG_ID' => $this->ID(),
1542
-                ),
1543
-                'order_by' => array('DTT_EVT_start' => 'ASC'),
1544
-            )
1545
-        );
1546
-    }
1547
-
1548
-
1549
-    /**
1550
-     * This method simply returns the check-in status for this registration and the given datetime.
1551
-     * If neither the datetime nor the checkin values are provided as arguments,
1552
-     * then this will return the LATEST check-in status for the registration across all datetimes it belongs to.
1553
-     *
1554
-     * @param  int       $DTT_ID  The ID of the datetime we're checking against
1555
-     *                            (if empty we'll get the primary datetime for
1556
-     *                            this registration (via event) and use it's ID);
1557
-     * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id.
1558
-     * @return int                Integer representing Check-in status.
1559
-     * @throws \EE_Error
1560
-     */
1561
-    public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null)
1562
-    {
1563
-        $checkin_query_params = array(
1564
-            'order_by' => array('CHK_timestamp' => 'DESC'),
1565
-        );
1566
-
1567
-        if ($DTT_ID > 0) {
1568
-            $checkin_query_params[0] = array('DTT_ID' => $DTT_ID);
1569
-        }
1570
-
1571
-        //get checkin object (if exists)
1572
-        $checkin = $checkin instanceof EE_Checkin
1573
-            ? $checkin
1574
-            : $this->get_first_related('Checkin', $checkin_query_params);
1575
-        if ($checkin instanceof EE_Checkin) {
1576
-            if ($checkin->get('CHK_in')) {
1577
-                return EE_Checkin::status_checked_in; //checked in
1578
-            }
1579
-            return EE_Checkin::status_checked_out; //had checked in but is now checked out.
1580
-        }
1581
-        return EE_Checkin::status_checked_never; //never been checked in
1582
-    }
1583
-
1584
-
1585
-    /**
1586
-     * This method returns a localized message for the toggled Check-in message.
1587
-     *
1588
-     * @param  int $DTT_ID include specific datetime to get the correct Check-in message.  If not included or null,
1589
-     *                     then it is assumed Check-in for primary datetime was toggled.
1590
-     * @param bool $error  This just flags that you want an error message returned. This is put in so that the error
1591
-     *                     message can be customized with the attendee name.
1592
-     * @return string internationalized message
1593
-     * @throws EE_Error
1594
-     */
1595
-    public function get_checkin_msg($DTT_ID, $error = false)
1596
-    {
1597
-        //let's get the attendee first so we can include the name of the attendee
1598
-        $attendee = $this->get_first_related('Attendee');
1599
-        if ($attendee instanceof EE_Attendee) {
1600
-            if ($error) {
1601
-                return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name());
1602
-            }
1603
-            $cur_status = $this->check_in_status_for_datetime($DTT_ID);
1604
-            //what is the status message going to be?
1605
-            switch ($cur_status) {
1606
-                case EE_Checkin::status_checked_never:
1607
-                    return sprintf(__("%s has been removed from Check-in records", "event_espresso"),
1608
-                        $attendee->full_name());
1609
-                    break;
1610
-                case EE_Checkin::status_checked_in:
1611
-                    return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name());
1612
-                    break;
1613
-                case EE_Checkin::status_checked_out:
1614
-                    return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name());
1615
-                    break;
1616
-            }
1617
-        }
1618
-        return esc_html__("The check-in status could not be determined.", "event_espresso");
1619
-    }
1620
-
1621
-
1622
-    /**
1623
-     * Returns the related EE_Transaction to this registration
1624
-     *
1625
-     * @return EE_Transaction
1626
-     * @throws EE_Error
1627
-     * @throws EntityNotFoundException
1628
-     */
1629
-    public function transaction()
1630
-    {
1631
-        $transaction = $this->get_first_related('Transaction');
1632
-        if (! $transaction instanceof \EE_Transaction) {
1633
-            throw new EntityNotFoundException('Transaction ID', $this->transaction_ID());
1634
-        }
1635
-        return $transaction;
1636
-    }
1637
-
1638
-
1639
-    /**
1640
-     *        get Registration Code
1641
-     */
1642
-    public function reg_code()
1643
-    {
1644
-        return $this->get('REG_code');
1645
-    }
1646
-
1647
-
1648
-    /**
1649
-     *        get Transaction ID
1650
-     */
1651
-    public function transaction_ID()
1652
-    {
1653
-        return $this->get('TXN_ID');
1654
-    }
1655
-
1656
-
1657
-    /**
1658
-     * @return int
1659
-     * @throws EE_Error
1660
-     */
1661
-    public function ticket_ID()
1662
-    {
1663
-        return $this->get('TKT_ID');
1664
-    }
1665
-
1666
-
1667
-    /**
1668
-     *        Set Registration Code
1669
-     *
1670
-     * @access    public
1671
-     * @param    string  $REG_code Registration Code
1672
-     * @param    boolean $use_default
1673
-     * @throws EE_Error
1674
-     */
1675
-    public function set_reg_code($REG_code, $use_default = false)
1676
-    {
1677
-        if (empty($REG_code)) {
1678
-            EE_Error::add_error(
1679
-                esc_html__('REG_code can not be empty.', 'event_espresso'),
1680
-                __FILE__,
1681
-                __FUNCTION__,
1682
-                __LINE__
1683
-            );
1684
-            return;
1685
-        }
1686
-        if (! $this->reg_code()) {
1687
-            parent::set('REG_code', $REG_code, $use_default);
1688
-        } else {
1689
-            EE_Error::doing_it_wrong(
1690
-                __CLASS__ . '::' . __FUNCTION__,
1691
-                esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'),
1692
-                '4.6.0'
1693
-            );
1694
-        }
1695
-    }
1696
-
1697
-
1698
-    /**
1699
-     * Returns all other registrations in the same group as this registrant who have the same ticket option.
1700
-     * Note, if you want to just get all registrations in the same transaction (group), use:
1701
-     *    $registration->transaction()->registrations();
1702
-     *
1703
-     * @since 4.5.0
1704
-     * @return EE_Registration[] or empty array if this isn't a group registration.
1705
-     * @throws EE_Error
1706
-     */
1707
-    public function get_all_other_registrations_in_group()
1708
-    {
1709
-        if ($this->group_size() < 2) {
1710
-            return array();
1711
-        }
1712
-
1713
-        $query[0] = array(
1714
-            'TXN_ID' => $this->transaction_ID(),
1715
-            'REG_ID' => array('!=', $this->ID()),
1716
-            'TKT_ID' => $this->ticket_ID(),
1717
-        );
1718
-        /** @var EE_Registration[] $registrations */
1719
-        $registrations = $this->get_model()->get_all($query);
1720
-        return $registrations;
1721
-    }
1722
-
1723
-    /**
1724
-     * Return the link to the admin details for the object.
1725
-     *
1726
-     * @return string
1727
-     * @throws EE_Error
1728
-     */
1729
-    public function get_admin_details_link()
1730
-    {
1731
-        EE_Registry::instance()->load_helper('URL');
1732
-        return EEH_URL::add_query_args_and_nonce(
1733
-            array(
1734
-                'page'    => 'espresso_registrations',
1735
-                'action'  => 'view_registration',
1736
-                '_REG_ID' => $this->ID(),
1737
-            ),
1738
-            admin_url('admin.php')
1739
-        );
1740
-    }
1741
-
1742
-    /**
1743
-     * Returns the link to the editor for the object.  Sometimes this is the same as the details.
1744
-     *
1745
-     * @return string
1746
-     * @throws EE_Error
1747
-     */
1748
-    public function get_admin_edit_link()
1749
-    {
1750
-        return $this->get_admin_details_link();
1751
-    }
1752
-
1753
-    /**
1754
-     * Returns the link to a settings page for the object.
1755
-     *
1756
-     * @return string
1757
-     * @throws EE_Error
1758
-     */
1759
-    public function get_admin_settings_link()
1760
-    {
1761
-        return $this->get_admin_details_link();
1762
-    }
1763
-
1764
-    /**
1765
-     * Returns the link to the "overview" for the object (typically the "list table" view).
1766
-     *
1767
-     * @return string
1768
-     */
1769
-    public function get_admin_overview_link()
1770
-    {
1771
-        EE_Registry::instance()->load_helper('URL');
1772
-        return EEH_URL::add_query_args_and_nonce(
1773
-            array(
1774
-                'page' => 'espresso_registrations',
1775
-            ),
1776
-            admin_url('admin.php')
1777
-        );
1778
-    }
1779
-
1780
-
1781
-    /**
1782
-     * @param array $query_params
1783
-     * @return \EE_Registration[]
1784
-     * @throws \EE_Error
1785
-     */
1786
-    public function payments($query_params = array())
1787
-    {
1788
-        return $this->get_many_related('Payment', $query_params);
1789
-    }
1790
-
1791
-
1792
-    /**
1793
-     * @param array $query_params
1794
-     * @return \EE_Registration_Payment[]
1795
-     * @throws \EE_Error
1796
-     */
1797
-    public function registration_payments($query_params = array())
1798
-    {
1799
-        return $this->get_many_related('Registration_Payment', $query_params);
1800
-    }
1801
-
1802
-
1803
-    /**
1804
-     * This grabs the payment method corresponding to the last payment made for the amount owing on the registration.
1805
-     * Note: if there are no payments on the registration there will be no payment method returned.
1806
-     *
1807
-     * @return EE_Payment_Method|null
1808
-     */
1809
-    public function payment_method()
1810
-    {
1811
-        return EEM_Payment_Method::instance()->get_last_used_for_registration($this);
1812
-    }
1813
-
1814
-
1815
-    /**
1816
-     * @return \EE_Line_Item
1817
-     * @throws EntityNotFoundException
1818
-     * @throws \EE_Error
1819
-     */
1820
-    public function ticket_line_item()
1821
-    {
1822
-        $ticket            = $this->ticket();
1823
-        $transaction       = $this->transaction();
1824
-        $line_item         = null;
1825
-        $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs(
1826
-            $transaction->total_line_item(),
1827
-            'Ticket',
1828
-            array($ticket->ID())
1829
-        );
1830
-        foreach ($ticket_line_items as $ticket_line_item) {
1831
-            if (
1832
-                $ticket_line_item instanceof \EE_Line_Item
1833
-                && $ticket_line_item->OBJ_type() === 'Ticket'
1834
-                && $ticket_line_item->OBJ_ID() === $ticket->ID()
1835
-            ) {
1836
-                $line_item = $ticket_line_item;
1837
-                break;
1838
-            }
1839
-        }
1840
-        if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) {
1841
-            throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID());
1842
-        }
1843
-        return $line_item;
1844
-    }
1845
-
1846
-
1847
-    /**
1848
-     * Soft Deletes this model object.
1849
-     *
1850
-     * @return boolean | int
1851
-     * @throws \RuntimeException
1852
-     * @throws \EE_Error
1853
-     */
1854
-    public function delete()
1855
-    {
1856
-        if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) {
1857
-            $this->set_status(EEM_Registration::status_id_cancelled);
1858
-        }
1859
-        return parent::delete();
1860
-    }
1861
-
1862
-
1863
-    /**
1864
-     * Restores whatever the previous status was on a registration before it was trashed (if possible)
1865
-     *
1866
-     * @throws \EE_Error
1867
-     * @throws \RuntimeException
1868
-     */
1869
-    public function restore()
1870
-    {
1871
-        $previous_status = $this->get_extra_meta(
1872
-            EE_Registration::PRE_TRASH_REG_STATUS_KEY,
1873
-            true,
1874
-            EEM_Registration::status_id_cancelled
1875
-        );
1876
-        if ($previous_status) {
1877
-            $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY);
1878
-            $this->set_status($previous_status);
1879
-        }
1880
-        return parent::restore();
1881
-    }
1882
-
1883
-
1884
-
1885
-    /*************************** DEPRECATED ***************************/
1886
-
1887
-
1888
-    /**
1889
-     * @deprecated
1890
-     * @since     4.7.0
1891
-     * @access    public
1892
-     */
1893
-    public function price_paid()
1894
-    {
1895
-        EE_Error::doing_it_wrong('EE_Registration::price_paid()',
1896
-            esc_html__('This method is deprecated, please use EE_Registration::final_price() instead.', 'event_espresso'),
1897
-            '4.7.0');
1898
-        return $this->final_price();
1899
-    }
1900
-
1901
-
1902
-    /**
1903
-     * @deprecated
1904
-     * @since     4.7.0
1905
-     * @access    public
1906
-     * @param    float $REG_final_price
1907
-     * @throws EE_Error
1908
-     * @throws RuntimeException
1909
-     */
1910
-    public function set_price_paid($REG_final_price = 0.00)
1911
-    {
1912
-        EE_Error::doing_it_wrong('EE_Registration::set_price_paid()',
1913
-            esc_html__('This method is deprecated, please use EE_Registration::set_final_price() instead.', 'event_espresso'),
1914
-            '4.7.0');
1915
-        $this->set_final_price($REG_final_price);
1916
-    }
1917
-
1918
-
1919
-    /**
1920
-     * @deprecated
1921
-     * @since 4.7.0
1922
-     * @return string
1923
-     * @throws EE_Error
1924
-     */
1925
-    public function pretty_price_paid()
1926
-    {
1927
-        EE_Error::doing_it_wrong('EE_Registration::pretty_price_paid()',
1928
-            esc_html__('This method is deprecated, please use EE_Registration::pretty_final_price() instead.',
1929
-                'event_espresso'), '4.7.0');
1930
-        return $this->pretty_final_price();
1931
-    }
1932
-
1933
-
1934
-    /**
1935
-     * Gets the primary datetime related to this registration via the related Event to this registration
1936
-     *
1937
-     * @deprecated 4.9.17
1938
-     * @return EE_Datetime
1939
-     * @throws EE_Error
1940
-     * @throws EntityNotFoundException
1941
-     */
1942
-    public function get_related_primary_datetime()
1943
-    {
1944
-        EE_Error::doing_it_wrong(
1945
-            __METHOD__,
1946
-            esc_html__(
1947
-                'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()',
1948
-                'event_espresso'
1949
-            ),
1950
-            '4.9.17',
1951
-            '5.0.0'
1952
-        );
1953
-        return $this->event()->primary_datetime();
1954
-    }
21
+	/**
22
+	 * Used to reference when a registration has never been checked in.
23
+	 *
24
+	 * @deprecated use \EE_Checkin::status_checked_never instead
25
+	 * @type int
26
+	 */
27
+	const checkin_status_never = 2;
28
+
29
+	/**
30
+	 * Used to reference when a registration has been checked in.
31
+	 *
32
+	 * @deprecated use \EE_Checkin::status_checked_in instead
33
+	 * @type int
34
+	 */
35
+	const checkin_status_in = 1;
36
+
37
+
38
+	/**
39
+	 * Used to reference when a registration has been checked out.
40
+	 *
41
+	 * @deprecated use \EE_Checkin::status_checked_out instead
42
+	 * @type int
43
+	 */
44
+	const checkin_status_out = 0;
45
+
46
+
47
+	/**
48
+	 * extra meta key for tracking reg status os trashed registrations
49
+	 *
50
+	 * @type string
51
+	 */
52
+	const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status';
53
+
54
+
55
+	/**
56
+	 * extra meta key for tracking if registration has reserved ticket
57
+	 *
58
+	 * @type string
59
+	 */
60
+	const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket';
61
+
62
+
63
+	/**
64
+	 * @param array  $props_n_values          incoming values
65
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
66
+	 *                                        used.)
67
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
68
+	 *                                        date_format and the second value is the time format
69
+	 * @return EE_Registration
70
+	 * @throws EE_Error
71
+	 */
72
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
73
+	{
74
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
75
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
76
+	}
77
+
78
+
79
+	/**
80
+	 * @param array  $props_n_values  incoming values from the database
81
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
82
+	 *                                the website will be used.
83
+	 * @return EE_Registration
84
+	 */
85
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
86
+	{
87
+		return new self($props_n_values, true, $timezone);
88
+	}
89
+
90
+
91
+	/**
92
+	 *        Set Event ID
93
+	 *
94
+	 * @param        int $EVT_ID Event ID
95
+	 * @throws EE_Error
96
+	 * @throws RuntimeException
97
+	 */
98
+	public function set_event($EVT_ID = 0)
99
+	{
100
+		$this->set('EVT_ID', $EVT_ID);
101
+	}
102
+
103
+
104
+	/**
105
+	 * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can
106
+	 * be routed to internal methods
107
+	 *
108
+	 * @param string $field_name
109
+	 * @param mixed  $field_value
110
+	 * @param bool   $use_default
111
+	 * @throws EE_Error
112
+	 * @throws EntityNotFoundException
113
+	 * @throws InvalidArgumentException
114
+	 * @throws InvalidDataTypeException
115
+	 * @throws InvalidInterfaceException
116
+	 * @throws ReflectionException
117
+	 * @throws RuntimeException
118
+	 */
119
+	public function set($field_name, $field_value, $use_default = false)
120
+	{
121
+		switch ($field_name) {
122
+			case 'REG_code':
123
+				if (! empty($field_value) && $this->reg_code() === null) {
124
+					$this->set_reg_code($field_value, $use_default);
125
+				}
126
+				break;
127
+			case 'STS_ID':
128
+				$this->set_status($field_value, $use_default);
129
+				break;
130
+			default:
131
+				parent::set($field_name, $field_value, $use_default);
132
+		}
133
+	}
134
+
135
+
136
+	/**
137
+	 * Set Status ID
138
+	 * updates the registration status and ALSO...
139
+	 * calls reserve_registration_space() if the reg status changes TO approved from any other reg status
140
+	 * calls release_registration_space() if the reg status changes FROM approved to any other reg status
141
+	 *
142
+	 * @param string       $new_STS_ID
143
+	 * @param boolean      $use_default
144
+	 * @param Context|null $context
145
+	 * @return bool
146
+	 * @throws EE_Error
147
+	 * @throws EntityNotFoundException
148
+	 * @throws InvalidArgumentException
149
+	 * @throws ReflectionException
150
+	 * @throws RuntimeException
151
+	 * @throws InvalidDataTypeException
152
+	 * @throws InvalidInterfaceException
153
+	 */
154
+	public function set_status($new_STS_ID = null, $use_default = false, Context $context = null)
155
+	{
156
+		// get current REG_Status
157
+		$old_STS_ID = $this->status_ID();
158
+		// if status has changed
159
+		if ($old_STS_ID !== $new_STS_ID // and that status has actually changed
160
+			&& ! empty($old_STS_ID) // and that old status is actually set
161
+			&& ! empty($new_STS_ID) // as well as the new status
162
+			&& $this->ID() // ensure registration is in the db
163
+		) {
164
+			// TO approved
165
+			if ($new_STS_ID === EEM_Registration::status_id_approved) {
166
+				// reserve a space by incrementing ticket and datetime sold values
167
+				$this->_reserve_registration_space();
168
+				do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context);
169
+				// OR FROM  approved
170
+			} elseif ($old_STS_ID === EEM_Registration::status_id_approved) {
171
+				// release a space by decrementing ticket and datetime sold values
172
+				$this->_release_registration_space();
173
+				do_action(
174
+					'AHEE__EE_Registration__set_status__from_approved',
175
+					$this,
176
+					$old_STS_ID,
177
+					$new_STS_ID,
178
+					$context
179
+				);
180
+			}
181
+			// update status
182
+			parent::set('STS_ID', $new_STS_ID, $use_default);
183
+			$this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, $context);
184
+			if($this->statusChangeUpdatesTransaction($context)) {
185
+				$this->updateTransactionAfterStatusChange();
186
+			}
187
+			do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context);
188
+			return true;
189
+		}
190
+		//even though the old value matches the new value, it's still good to
191
+		//allow the parent set method to have a say
192
+		parent::set('STS_ID', $new_STS_ID, $use_default);
193
+		return true;
194
+	}
195
+
196
+
197
+	/**
198
+	 * update REGs and TXN when cancelled or declined registrations involved
199
+	 *
200
+	 * @param string       $new_STS_ID
201
+	 * @param string       $old_STS_ID
202
+	 * @param Context|null $context
203
+	 * @throws EE_Error
204
+	 * @throws InvalidArgumentException
205
+	 * @throws InvalidDataTypeException
206
+	 * @throws InvalidInterfaceException
207
+	 * @throws ReflectionException
208
+	 */
209
+	private function _update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, Context $context = null)
210
+	{
211
+		// these reg statuses should not be considered in any calculations involving monies owing
212
+		$closed_reg_statuses = EEM_Registration::closed_reg_statuses();
213
+		// true if registration has been cancelled or declined
214
+		$this->updateIfCanceled(
215
+			$closed_reg_statuses,
216
+			$new_STS_ID,
217
+			$old_STS_ID,
218
+			$context
219
+		);
220
+		$this->updateIfDeclined(
221
+			$closed_reg_statuses,
222
+			$new_STS_ID,
223
+			$old_STS_ID,
224
+			$context
225
+		);
226
+	}
227
+
228
+
229
+	/**
230
+	 * update REGs and TXN when cancelled or declined registrations involved
231
+	 *
232
+	 * @param array        $closed_reg_statuses
233
+	 * @param string       $new_STS_ID
234
+	 * @param string       $old_STS_ID
235
+	 * @param Context|null $context
236
+	 * @throws EE_Error
237
+	 * @throws InvalidArgumentException
238
+	 * @throws InvalidDataTypeException
239
+	 * @throws InvalidInterfaceException
240
+	 * @throws ReflectionException
241
+	 */
242
+	private function updateIfCanceled(array $closed_reg_statuses, $new_STS_ID, $old_STS_ID, Context $context = null)
243
+	{
244
+		// true if registration has been cancelled or declined
245
+		if (in_array($new_STS_ID, $closed_reg_statuses, true)
246
+			&& ! in_array($old_STS_ID, $closed_reg_statuses, true)
247
+		) {
248
+			/** @type EE_Registration_Processor $registration_processor */
249
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
250
+			/** @type EE_Transaction_Processor $transaction_processor */
251
+			$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
252
+			// cancelled or declined registration
253
+			$registration_processor->update_registration_after_being_canceled_or_declined(
254
+				$this,
255
+				$closed_reg_statuses
256
+			);
257
+			$transaction_processor->update_transaction_after_canceled_or_declined_registration(
258
+				$this,
259
+				$closed_reg_statuses,
260
+				false
261
+			);
262
+			do_action(
263
+				'AHEE__EE_Registration__set_status__canceled_or_declined',
264
+				$this,
265
+				$old_STS_ID,
266
+				$new_STS_ID,
267
+				$context
268
+			);
269
+			return;
270
+		}
271
+	}
272
+
273
+
274
+	/**
275
+	 * update REGs and TXN when cancelled or declined registrations involved
276
+	 *
277
+	 * @param array        $closed_reg_statuses
278
+	 * @param string       $new_STS_ID
279
+	 * @param string       $old_STS_ID
280
+	 * @param Context|null $context
281
+	 * @throws EE_Error
282
+	 * @throws InvalidArgumentException
283
+	 * @throws InvalidDataTypeException
284
+	 * @throws InvalidInterfaceException
285
+	 * @throws ReflectionException
286
+	 */
287
+	private function updateIfDeclined(array $closed_reg_statuses, $new_STS_ID, $old_STS_ID, Context $context = null)
288
+	{
289
+		// true if reinstating cancelled or declined registration
290
+		if (in_array($old_STS_ID, $closed_reg_statuses, true)
291
+			&& ! in_array($new_STS_ID, $closed_reg_statuses, true)
292
+		) {
293
+			/** @type EE_Registration_Processor $registration_processor */
294
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
295
+			/** @type EE_Transaction_Processor $transaction_processor */
296
+			$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
297
+			// reinstating cancelled or declined registration
298
+			$registration_processor->update_canceled_or_declined_registration_after_being_reinstated(
299
+				$this,
300
+				$closed_reg_statuses
301
+			);
302
+			$transaction_processor->update_transaction_after_reinstating_canceled_registration(
303
+				$this,
304
+				$closed_reg_statuses,
305
+				false
306
+			);
307
+			do_action(
308
+				'AHEE__EE_Registration__set_status__after_reinstated',
309
+				$this,
310
+				$old_STS_ID,
311
+				$new_STS_ID,
312
+				$context
313
+			);
314
+		}
315
+	}
316
+
317
+
318
+	/**
319
+	 * @param Context|null $context
320
+	 * @return bool
321
+	 */
322
+	private function statusChangeUpdatesTransaction(Context $context = null)
323
+	{
324
+		$contexts_that_do_not_update_transaction = (array) apply_filters(
325
+			'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction',
326
+			array('spco_reg_step_attendee_information_process_registrations'),
327
+			$context,
328
+			$this
329
+		);
330
+		return ! (
331
+			$context instanceof Context
332
+			&& in_array($context->slug(), $contexts_that_do_not_update_transaction, true)
333
+		);
334
+	}
335
+
336
+
337
+	/**
338
+	 * @throws EE_Error
339
+	 * @throws EntityNotFoundException
340
+	 * @throws InvalidArgumentException
341
+	 * @throws InvalidDataTypeException
342
+	 * @throws InvalidInterfaceException
343
+	 * @throws ReflectionException
344
+	 * @throws RuntimeException
345
+	 */
346
+	private function updateTransactionAfterStatusChange()
347
+	{
348
+		/** @type EE_Transaction_Payments $transaction_payments */
349
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
350
+		$transaction_payments->recalculate_transaction_total($this->transaction(), false);
351
+		$this->transaction()->update_status_based_on_total_paid(true);
352
+	}
353
+
354
+
355
+	/**
356
+	 *        get Status ID
357
+	 */
358
+	public function status_ID()
359
+	{
360
+		return $this->get('STS_ID');
361
+	}
362
+
363
+
364
+	/**
365
+	 * increments this registration's related ticket sold and corresponding datetime sold values
366
+	 *
367
+	 * @return void
368
+	 * @throws EE_Error
369
+	 * @throws EntityNotFoundException
370
+	 */
371
+	private function _reserve_registration_space()
372
+	{
373
+		// reserved ticket and datetime counts will be decremented as sold counts are incremented
374
+		// so stop tracking that this reg has a ticket reserved
375
+		$this->release_reserved_ticket();
376
+		$ticket = $this->ticket();
377
+		$ticket->increase_sold();
378
+		$ticket->save();
379
+		// possibly set event status to sold out
380
+		$this->event()->perform_sold_out_status_check();
381
+	}
382
+
383
+
384
+	/**
385
+	 * Gets the ticket this registration is for
386
+	 *
387
+	 * @param boolean $include_archived whether to include archived tickets or not.
388
+	 * @return EE_Ticket|EE_Base_Class
389
+	 * @throws \EE_Error
390
+	 */
391
+	public function ticket($include_archived = true)
392
+	{
393
+		$query_params = array();
394
+		if ($include_archived) {
395
+			$query_params['default_where_conditions'] = 'none';
396
+		}
397
+		return $this->get_first_related('Ticket', $query_params);
398
+	}
399
+
400
+
401
+	/**
402
+	 * Gets the event this registration is for
403
+	 *
404
+	 * @return EE_Event
405
+	 * @throws EE_Error
406
+	 * @throws EntityNotFoundException
407
+	 */
408
+	public function event()
409
+	{
410
+		$event = $this->get_first_related('Event');
411
+		if (! $event instanceof \EE_Event) {
412
+			throw new EntityNotFoundException('Event ID', $this->event_ID());
413
+		}
414
+		return $event;
415
+	}
416
+
417
+
418
+	/**
419
+	 * Gets the "author" of the registration.  Note that for the purposes of registrations, the author will correspond
420
+	 * with the author of the event this registration is for.
421
+	 *
422
+	 * @since 4.5.0
423
+	 * @return int
424
+	 * @throws EE_Error
425
+	 * @throws EntityNotFoundException
426
+	 */
427
+	public function wp_user()
428
+	{
429
+		$event = $this->event();
430
+		if ($event instanceof EE_Event) {
431
+			return $event->wp_user();
432
+		}
433
+		return 0;
434
+	}
435
+
436
+
437
+	/**
438
+	 * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values
439
+	 *
440
+	 * @return void
441
+	 * @throws \EE_Error
442
+	 */
443
+	private function _release_registration_space()
444
+	{
445
+		$ticket = $this->ticket();
446
+		$ticket->decrease_sold();
447
+		$ticket->save();
448
+	}
449
+
450
+
451
+	/**
452
+	 * tracks this registration's ticket reservation in extra meta
453
+	 * and can increment related ticket reserved and corresponding datetime reserved values
454
+	 *
455
+	 * @param bool $update_ticket if true, will increment ticket and datetime reserved count
456
+	 * @return void
457
+	 * @throws \EE_Error
458
+	 */
459
+	public function reserve_ticket($update_ticket = false)
460
+	{
461
+		if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) === false) {
462
+			// PLZ NOTE: although checking $update_ticket first would be more efficient,
463
+			// we NEED to ALWAYS call update_extra_meta(), which is why that is done first
464
+			if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) && $update_ticket) {
465
+				$ticket = $this->ticket();
466
+				$ticket->increase_reserved();
467
+				$ticket->save();
468
+			}
469
+		}
470
+	}
471
+
472
+
473
+	/**
474
+	 * stops tracking this registration's ticket reservation in extra meta
475
+	 * decrements (subtracts) related ticket reserved and corresponding datetime reserved values
476
+	 *
477
+	 * @param bool $update_ticket if true, will decrement ticket and datetime reserved count
478
+	 * @return void
479
+	 * @throws \EE_Error
480
+	 */
481
+	public function release_reserved_ticket($update_ticket = false)
482
+	{
483
+		if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) !== false) {
484
+			// PLZ NOTE: although checking $update_ticket first would be more efficient,
485
+			// we NEED to ALWAYS call delete_extra_meta(), which is why that is done first
486
+			if ($this->delete_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY) && $update_ticket) {
487
+				$ticket = $this->ticket();
488
+				$ticket->decrease_reserved();
489
+				$ticket->save();
490
+			}
491
+		}
492
+	}
493
+
494
+
495
+	/**
496
+	 * Set Attendee ID
497
+	 *
498
+	 * @param        int $ATT_ID Attendee ID
499
+	 * @throws EE_Error
500
+	 * @throws RuntimeException
501
+	 */
502
+	public function set_attendee_id($ATT_ID = 0)
503
+	{
504
+		$this->set('ATT_ID', $ATT_ID);
505
+	}
506
+
507
+
508
+	/**
509
+	 *        Set Transaction ID
510
+	 *
511
+	 * @param        int $TXN_ID Transaction ID
512
+	 * @throws EE_Error
513
+	 * @throws RuntimeException
514
+	 */
515
+	public function set_transaction_id($TXN_ID = 0)
516
+	{
517
+		$this->set('TXN_ID', $TXN_ID);
518
+	}
519
+
520
+
521
+	/**
522
+	 *        Set Session
523
+	 *
524
+	 * @param    string $REG_session PHP Session ID
525
+	 * @throws EE_Error
526
+	 * @throws RuntimeException
527
+	 */
528
+	public function set_session($REG_session = '')
529
+	{
530
+		$this->set('REG_session', $REG_session);
531
+	}
532
+
533
+
534
+	/**
535
+	 *        Set Registration URL Link
536
+	 *
537
+	 * @param    string $REG_url_link Registration URL Link
538
+	 * @throws EE_Error
539
+	 * @throws RuntimeException
540
+	 */
541
+	public function set_reg_url_link($REG_url_link = '')
542
+	{
543
+		$this->set('REG_url_link', $REG_url_link);
544
+	}
545
+
546
+
547
+	/**
548
+	 *        Set Attendee Counter
549
+	 *
550
+	 * @param        int $REG_count Primary Attendee
551
+	 * @throws EE_Error
552
+	 * @throws RuntimeException
553
+	 */
554
+	public function set_count($REG_count = 1)
555
+	{
556
+		$this->set('REG_count', $REG_count);
557
+	}
558
+
559
+
560
+	/**
561
+	 *        Set Group Size
562
+	 *
563
+	 * @param        boolean $REG_group_size Group Registration
564
+	 * @throws EE_Error
565
+	 * @throws RuntimeException
566
+	 */
567
+	public function set_group_size($REG_group_size = false)
568
+	{
569
+		$this->set('REG_group_size', $REG_group_size);
570
+	}
571
+
572
+
573
+	/**
574
+	 *    is_not_approved -  convenience method that returns TRUE if REG status ID ==
575
+	 *    EEM_Registration::status_id_not_approved
576
+	 *
577
+	 * @return        boolean
578
+	 */
579
+	public function is_not_approved()
580
+	{
581
+		return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false;
582
+	}
583
+
584
+
585
+	/**
586
+	 *    is_pending_payment -  convenience method that returns TRUE if REG status ID ==
587
+	 *    EEM_Registration::status_id_pending_payment
588
+	 *
589
+	 * @return        boolean
590
+	 */
591
+	public function is_pending_payment()
592
+	{
593
+		return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false;
594
+	}
595
+
596
+
597
+	/**
598
+	 *    is_approved -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved
599
+	 *
600
+	 * @return        boolean
601
+	 */
602
+	public function is_approved()
603
+	{
604
+		return $this->status_ID() == EEM_Registration::status_id_approved ? true : false;
605
+	}
606
+
607
+
608
+	/**
609
+	 *    is_cancelled -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled
610
+	 *
611
+	 * @return        boolean
612
+	 */
613
+	public function is_cancelled()
614
+	{
615
+		return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false;
616
+	}
617
+
618
+
619
+	/**
620
+	 *    is_declined -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined
621
+	 *
622
+	 * @return        boolean
623
+	 */
624
+	public function is_declined()
625
+	{
626
+		return $this->status_ID() == EEM_Registration::status_id_declined ? true : false;
627
+	}
628
+
629
+
630
+	/**
631
+	 *    is_incomplete -  convenience method that returns TRUE if REG status ID ==
632
+	 *    EEM_Registration::status_id_incomplete
633
+	 *
634
+	 * @return        boolean
635
+	 */
636
+	public function is_incomplete()
637
+	{
638
+		return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false;
639
+	}
640
+
641
+
642
+	/**
643
+	 *        Set Registration Date
644
+	 *
645
+	 * @param        mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of
646
+	 *                                                 Date
647
+	 * @throws EE_Error
648
+	 * @throws RuntimeException
649
+	 */
650
+	public function set_reg_date($REG_date = false)
651
+	{
652
+		$this->set('REG_date', $REG_date);
653
+	}
654
+
655
+
656
+	/**
657
+	 *    Set final price owing for this registration after all ticket/price modifications
658
+	 *
659
+	 * @access    public
660
+	 * @param    float $REG_final_price
661
+	 * @throws EE_Error
662
+	 * @throws RuntimeException
663
+	 */
664
+	public function set_final_price($REG_final_price = 0.00)
665
+	{
666
+		$this->set('REG_final_price', $REG_final_price);
667
+	}
668
+
669
+
670
+	/**
671
+	 *    Set amount paid towards this registration's final price
672
+	 *
673
+	 * @access    public
674
+	 * @param    float $REG_paid
675
+	 * @throws EE_Error
676
+	 * @throws RuntimeException
677
+	 */
678
+	public function set_paid($REG_paid = 0.00)
679
+	{
680
+		$this->set('REG_paid', $REG_paid);
681
+	}
682
+
683
+
684
+	/**
685
+	 *        Attendee Is Going
686
+	 *
687
+	 * @param        boolean $REG_att_is_going Attendee Is Going
688
+	 * @throws EE_Error
689
+	 * @throws RuntimeException
690
+	 */
691
+	public function set_att_is_going($REG_att_is_going = false)
692
+	{
693
+		$this->set('REG_att_is_going', $REG_att_is_going);
694
+	}
695
+
696
+
697
+	/**
698
+	 * Gets the related attendee
699
+	 *
700
+	 * @return EE_Attendee
701
+	 * @throws EE_Error
702
+	 */
703
+	public function attendee()
704
+	{
705
+		return $this->get_first_related('Attendee');
706
+	}
707
+
708
+
709
+	/**
710
+	 *        get Event ID
711
+	 */
712
+	public function event_ID()
713
+	{
714
+		return $this->get('EVT_ID');
715
+	}
716
+
717
+
718
+	/**
719
+	 *        get Event ID
720
+	 */
721
+	public function event_name()
722
+	{
723
+		$event = $this->event_obj();
724
+		if ($event) {
725
+			return $event->name();
726
+		} else {
727
+			return null;
728
+		}
729
+	}
730
+
731
+
732
+	/**
733
+	 * Fetches the event this registration is for
734
+	 *
735
+	 * @return EE_Event
736
+	 * @throws EE_Error
737
+	 */
738
+	public function event_obj()
739
+	{
740
+		return $this->get_first_related('Event');
741
+	}
742
+
743
+
744
+	/**
745
+	 *        get Attendee ID
746
+	 */
747
+	public function attendee_ID()
748
+	{
749
+		return $this->get('ATT_ID');
750
+	}
751
+
752
+
753
+	/**
754
+	 *        get PHP Session ID
755
+	 */
756
+	public function session_ID()
757
+	{
758
+		return $this->get('REG_session');
759
+	}
760
+
761
+
762
+	/**
763
+	 * Gets the string which represents the URL trigger for the receipt template in the message template system.
764
+	 *
765
+	 * @param string $messenger 'pdf' or 'html'.  Default 'html'.
766
+	 * @return string
767
+	 */
768
+	public function receipt_url($messenger = 'html')
769
+	{
770
+
771
+		/**
772
+		 * The below will be deprecated one version after this.  We check first if there is a custom receipt template
773
+		 * already in use on old system.  If there is then we just return the standard url for it.
774
+		 *
775
+		 * @since 4.5.0
776
+		 */
777
+		$template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php';
778
+		$has_custom             = EEH_Template::locate_template(
779
+			$template_relative_path,
780
+			array(),
781
+			true,
782
+			true,
783
+			true
784
+		);
785
+
786
+		if ($has_custom) {
787
+			return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch'));
788
+		}
789
+		return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt');
790
+	}
791
+
792
+
793
+	/**
794
+	 * Gets the string which represents the URL trigger for the invoice template in the message template system.
795
+	 *
796
+	 * @param string $messenger 'pdf' or 'html'.  Default 'html'.
797
+	 * @return string
798
+	 * @throws EE_Error
799
+	 */
800
+	public function invoice_url($messenger = 'html')
801
+	{
802
+		/**
803
+		 * The below will be deprecated one version after this.  We check first if there is a custom invoice template
804
+		 * already in use on old system.  If there is then we just return the standard url for it.
805
+		 *
806
+		 * @since 4.5.0
807
+		 */
808
+		$template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php';
809
+		$has_custom             = EEH_Template::locate_template(
810
+			$template_relative_path,
811
+			array(),
812
+			true,
813
+			true,
814
+			true
815
+		);
816
+
817
+		if ($has_custom) {
818
+			if ($messenger == 'html') {
819
+				return $this->invoice_url('launch');
820
+			}
821
+			$route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice';
822
+
823
+			$query_args = array('ee' => $route, 'id' => $this->reg_url_link());
824
+			if ($messenger == 'html') {
825
+				$query_args['html'] = true;
826
+			}
827
+			return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id));
828
+		}
829
+		return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice');
830
+	}
831
+
832
+
833
+	/**
834
+	 * get Registration URL Link
835
+	 *
836
+	 * @access public
837
+	 * @return string
838
+	 * @throws \EE_Error
839
+	 */
840
+	public function reg_url_link()
841
+	{
842
+		return (string) $this->get('REG_url_link');
843
+	}
844
+
845
+
846
+	/**
847
+	 * Echoes out invoice_url()
848
+	 *
849
+	 * @param string $type 'download','launch', or 'html' (default is 'launch')
850
+	 * @return void
851
+	 * @throws EE_Error
852
+	 */
853
+	public function e_invoice_url($type = 'launch')
854
+	{
855
+		echo $this->invoice_url($type);
856
+	}
857
+
858
+
859
+	/**
860
+	 * Echoes out payment_overview_url
861
+	 */
862
+	public function e_payment_overview_url()
863
+	{
864
+		echo $this->payment_overview_url();
865
+	}
866
+
867
+
868
+	/**
869
+	 * Gets the URL of the thank you page with this registration REG_url_link added as
870
+	 * a query parameter
871
+	 *
872
+	 * @param bool $clear_session Set to true when you want to clear the session on revisiting the
873
+	 *                            payment overview url.
874
+	 * @return string
875
+	 * @throws EE_Error
876
+	 */
877
+	public function payment_overview_url($clear_session = false)
878
+	{
879
+		return add_query_arg(array(
880
+			'e_reg_url_link' => $this->reg_url_link(),
881
+			'step'           => 'payment_options',
882
+			'revisit'        => true,
883
+			'clear_session' => (bool) $clear_session
884
+		), EE_Registry::instance()->CFG->core->reg_page_url());
885
+	}
886
+
887
+
888
+	/**
889
+	 * Gets the URL of the thank you page with this registration REG_url_link added as
890
+	 * a query parameter
891
+	 *
892
+	 * @return string
893
+	 * @throws EE_Error
894
+	 */
895
+	public function edit_attendee_information_url()
896
+	{
897
+		return add_query_arg(array(
898
+			'e_reg_url_link' => $this->reg_url_link(),
899
+			'step'           => 'attendee_information',
900
+			'revisit'        => true,
901
+		), EE_Registry::instance()->CFG->core->reg_page_url());
902
+	}
903
+
904
+
905
+	/**
906
+	 * Simply generates and returns the appropriate admin_url link to edit this registration
907
+	 *
908
+	 * @return string
909
+	 * @throws EE_Error
910
+	 */
911
+	public function get_admin_edit_url()
912
+	{
913
+		return EEH_URL::add_query_args_and_nonce(array(
914
+			'page'    => 'espresso_registrations',
915
+			'action'  => 'view_registration',
916
+			'_REG_ID' => $this->ID(),
917
+		), admin_url('admin.php'));
918
+	}
919
+
920
+
921
+	/**
922
+	 *    is_primary_registrant?
923
+	 */
924
+	public function is_primary_registrant()
925
+	{
926
+		return $this->get('REG_count') == 1 ? true : false;
927
+	}
928
+
929
+
930
+	/**
931
+	 * This returns the primary registration object for this registration group (which may be this object).
932
+	 *
933
+	 * @return EE_Registration
934
+	 * @throws EE_Error
935
+	 */
936
+	public function get_primary_registration()
937
+	{
938
+		if ($this->is_primary_registrant()) {
939
+			return $this;
940
+		}
941
+
942
+		//k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1
943
+		/** @var EE_Registration $primary_registrant */
944
+		$primary_registrant = EEM_Registration::instance()->get_one(array(
945
+			array(
946
+				'TXN_ID'    => $this->transaction_ID(),
947
+				'REG_count' => 1,
948
+			),
949
+		));
950
+		return $primary_registrant;
951
+	}
952
+
953
+
954
+	/**
955
+	 *        get  Attendee Number
956
+	 *
957
+	 * @access        public
958
+	 */
959
+	public function count()
960
+	{
961
+		return $this->get('REG_count');
962
+	}
963
+
964
+
965
+	/**
966
+	 *        get Group Size
967
+	 */
968
+	public function group_size()
969
+	{
970
+		return $this->get('REG_group_size');
971
+	}
972
+
973
+
974
+	/**
975
+	 *        get Registration Date
976
+	 */
977
+	public function date()
978
+	{
979
+		return $this->get('REG_date');
980
+	}
981
+
982
+
983
+	/**
984
+	 * gets a pretty date
985
+	 *
986
+	 * @param string $date_format
987
+	 * @param string $time_format
988
+	 * @return string
989
+	 * @throws EE_Error
990
+	 */
991
+	public function pretty_date($date_format = null, $time_format = null)
992
+	{
993
+		return $this->get_datetime('REG_date', $date_format, $time_format);
994
+	}
995
+
996
+
997
+	/**
998
+	 * final_price
999
+	 * the registration's share of the transaction total, so that the
1000
+	 * sum of all the transaction's REG_final_prices equal the transaction's total
1001
+	 *
1002
+	 * @return float
1003
+	 * @throws EE_Error
1004
+	 */
1005
+	public function final_price()
1006
+	{
1007
+		return $this->get('REG_final_price');
1008
+	}
1009
+
1010
+
1011
+	/**
1012
+	 * pretty_final_price
1013
+	 *  final price as formatted string, with correct decimal places and currency symbol
1014
+	 *
1015
+	 * @return string
1016
+	 * @throws EE_Error
1017
+	 */
1018
+	public function pretty_final_price()
1019
+	{
1020
+		return $this->get_pretty('REG_final_price');
1021
+	}
1022
+
1023
+
1024
+	/**
1025
+	 * get paid (yeah)
1026
+	 *
1027
+	 * @return float
1028
+	 * @throws EE_Error
1029
+	 */
1030
+	public function paid()
1031
+	{
1032
+		return $this->get('REG_paid');
1033
+	}
1034
+
1035
+
1036
+	/**
1037
+	 * pretty_paid
1038
+	 *
1039
+	 * @return float
1040
+	 * @throws EE_Error
1041
+	 */
1042
+	public function pretty_paid()
1043
+	{
1044
+		return $this->get_pretty('REG_paid');
1045
+	}
1046
+
1047
+
1048
+	/**
1049
+	 * owes_monies_and_can_pay
1050
+	 * whether or not this registration has monies owing and it's' status allows payment
1051
+	 *
1052
+	 * @param array $requires_payment
1053
+	 * @return bool
1054
+	 * @throws EE_Error
1055
+	 */
1056
+	public function owes_monies_and_can_pay($requires_payment = array())
1057
+	{
1058
+		// these reg statuses require payment (if event is not free)
1059
+		$requires_payment = ! empty($requires_payment)
1060
+			? $requires_payment
1061
+			: EEM_Registration::reg_statuses_that_allow_payment();
1062
+		if (in_array($this->status_ID(), $requires_payment) &&
1063
+			$this->final_price() != 0 &&
1064
+			$this->final_price() != $this->paid()
1065
+		) {
1066
+			return true;
1067
+		} else {
1068
+			return false;
1069
+		}
1070
+	}
1071
+
1072
+
1073
+	/**
1074
+	 * Prints out the return value of $this->pretty_status()
1075
+	 *
1076
+	 * @param bool $show_icons
1077
+	 * @return void
1078
+	 * @throws EE_Error
1079
+	 */
1080
+	public function e_pretty_status($show_icons = false)
1081
+	{
1082
+		echo $this->pretty_status($show_icons);
1083
+	}
1084
+
1085
+
1086
+	/**
1087
+	 * Returns a nice version of the status for displaying to customers
1088
+	 *
1089
+	 * @param bool $show_icons
1090
+	 * @return string
1091
+	 * @throws EE_Error
1092
+	 */
1093
+	public function pretty_status($show_icons = false)
1094
+	{
1095
+		$status = EEM_Status::instance()->localized_status(
1096
+			array($this->status_ID() => esc_html__('unknown', 'event_espresso')),
1097
+			false,
1098
+			'sentence'
1099
+		);
1100
+		$icon   = '';
1101
+		switch ($this->status_ID()) {
1102
+			case EEM_Registration::status_id_approved:
1103
+				$icon = $show_icons
1104
+					? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>'
1105
+					: '';
1106
+				break;
1107
+			case EEM_Registration::status_id_pending_payment:
1108
+				$icon = $show_icons
1109
+					? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>'
1110
+					: '';
1111
+				break;
1112
+			case EEM_Registration::status_id_not_approved:
1113
+				$icon = $show_icons
1114
+					? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>'
1115
+					: '';
1116
+				break;
1117
+			case EEM_Registration::status_id_cancelled:
1118
+				$icon = $show_icons
1119
+					? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>'
1120
+					: '';
1121
+				break;
1122
+			case EEM_Registration::status_id_incomplete:
1123
+				$icon = $show_icons
1124
+					? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>'
1125
+					: '';
1126
+				break;
1127
+			case EEM_Registration::status_id_declined:
1128
+				$icon = $show_icons
1129
+					? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>'
1130
+					: '';
1131
+				break;
1132
+			case EEM_Registration::status_id_wait_list:
1133
+				$icon = $show_icons
1134
+					? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>'
1135
+					: '';
1136
+				break;
1137
+		}
1138
+		return $icon . $status[$this->status_ID()];
1139
+	}
1140
+
1141
+
1142
+	/**
1143
+	 *        get Attendee Is Going
1144
+	 */
1145
+	public function att_is_going()
1146
+	{
1147
+		return $this->get('REG_att_is_going');
1148
+	}
1149
+
1150
+
1151
+	/**
1152
+	 * Gets related answers
1153
+	 *
1154
+	 * @param array $query_params like EEM_Base::get_all
1155
+	 * @return EE_Answer[]
1156
+	 * @throws EE_Error
1157
+	 */
1158
+	public function answers($query_params = null)
1159
+	{
1160
+		return $this->get_many_related('Answer', $query_params);
1161
+	}
1162
+
1163
+
1164
+	/**
1165
+	 * Gets the registration's answer value to the specified question
1166
+	 * (either the question's ID or a question object)
1167
+	 *
1168
+	 * @param EE_Question|int $question
1169
+	 * @param bool            $pretty_value
1170
+	 * @return array|string if pretty_value= true, the result will always be a string
1171
+	 * (because the answer might be an array of answer values, so passing pretty_value=true
1172
+	 * will convert it into some kind of string)
1173
+	 * @throws EE_Error
1174
+	 */
1175
+	public function answer_value_to_question($question, $pretty_value = true)
1176
+	{
1177
+		$question_id = EEM_Question::instance()->ensure_is_ID($question);
1178
+		return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value);
1179
+	}
1180
+
1181
+
1182
+	/**
1183
+	 * question_groups
1184
+	 * returns an array of EE_Question_Group objects for this registration
1185
+	 *
1186
+	 * @return EE_Question_Group[]
1187
+	 * @throws EE_Error
1188
+	 * @throws EntityNotFoundException
1189
+	 */
1190
+	public function question_groups()
1191
+	{
1192
+		$question_groups = array();
1193
+		if ($this->event() instanceof EE_Event) {
1194
+			$question_groups = $this->event()->question_groups(
1195
+				array(
1196
+					array(
1197
+						'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false,
1198
+					),
1199
+					'order_by' => array('QSG_order' => 'ASC'),
1200
+				)
1201
+			);
1202
+		}
1203
+		return $question_groups;
1204
+	}
1205
+
1206
+
1207
+	/**
1208
+	 * count_question_groups
1209
+	 * returns a count of the number of EE_Question_Group objects for this registration
1210
+	 *
1211
+	 * @return int
1212
+	 * @throws EE_Error
1213
+	 * @throws EntityNotFoundException
1214
+	 */
1215
+	public function count_question_groups()
1216
+	{
1217
+		$qg_count = 0;
1218
+		if ($this->event() instanceof EE_Event) {
1219
+			$qg_count = $this->event()->count_related(
1220
+				'Question_Group',
1221
+				array(
1222
+					array(
1223
+						'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false,
1224
+					),
1225
+				)
1226
+			);
1227
+		}
1228
+		return $qg_count;
1229
+	}
1230
+
1231
+
1232
+	/**
1233
+	 * Returns the registration date in the 'standard' string format
1234
+	 * (function may be improved in the future to allow for different formats and timezones)
1235
+	 *
1236
+	 * @return string
1237
+	 * @throws EE_Error
1238
+	 */
1239
+	public function reg_date()
1240
+	{
1241
+		return $this->get_datetime('REG_date');
1242
+	}
1243
+
1244
+
1245
+	/**
1246
+	 * Gets the datetime-ticket for this registration (ie, it can be used to isolate
1247
+	 * the ticket this registration purchased, or the datetime they have registered
1248
+	 * to attend)
1249
+	 *
1250
+	 * @return EE_Datetime_Ticket
1251
+	 * @throws EE_Error
1252
+	 */
1253
+	public function datetime_ticket()
1254
+	{
1255
+		return $this->get_first_related('Datetime_Ticket');
1256
+	}
1257
+
1258
+
1259
+	/**
1260
+	 * Sets the registration's datetime_ticket.
1261
+	 *
1262
+	 * @param EE_Datetime_Ticket $datetime_ticket
1263
+	 * @return EE_Datetime_Ticket
1264
+	 * @throws EE_Error
1265
+	 */
1266
+	public function set_datetime_ticket($datetime_ticket)
1267
+	{
1268
+		return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket');
1269
+	}
1270
+
1271
+	/**
1272
+	 * Gets deleted
1273
+	 *
1274
+	 * @return bool
1275
+	 * @throws EE_Error
1276
+	 */
1277
+	public function deleted()
1278
+	{
1279
+		return $this->get('REG_deleted');
1280
+	}
1281
+
1282
+	/**
1283
+	 * Sets deleted
1284
+	 *
1285
+	 * @param boolean $deleted
1286
+	 * @return bool
1287
+	 * @throws EE_Error
1288
+	 * @throws RuntimeException
1289
+	 */
1290
+	public function set_deleted($deleted)
1291
+	{
1292
+		if ($deleted) {
1293
+			$this->delete();
1294
+		} else {
1295
+			$this->restore();
1296
+		}
1297
+	}
1298
+
1299
+
1300
+	/**
1301
+	 * Get the status object of this object
1302
+	 *
1303
+	 * @return EE_Status
1304
+	 * @throws EE_Error
1305
+	 */
1306
+	public function status_obj()
1307
+	{
1308
+		return $this->get_first_related('Status');
1309
+	}
1310
+
1311
+
1312
+	/**
1313
+	 * Returns the number of times this registration has checked into any of the datetimes
1314
+	 * its available for
1315
+	 *
1316
+	 * @return int
1317
+	 * @throws EE_Error
1318
+	 */
1319
+	public function count_checkins()
1320
+	{
1321
+		return $this->get_model()->count_related($this, 'Checkin');
1322
+	}
1323
+
1324
+
1325
+	/**
1326
+	 * Returns the number of current Check-ins this registration is checked into for any of the datetimes the
1327
+	 * registration is for.  Note, this is ONLY checked in (does not include checkedout)
1328
+	 *
1329
+	 * @return int
1330
+	 * @throws EE_Error
1331
+	 */
1332
+	public function count_checkins_not_checkedout()
1333
+	{
1334
+		return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1)));
1335
+	}
1336
+
1337
+
1338
+	/**
1339
+	 * The purpose of this method is simply to check whether this registration can checkin to the given datetime.
1340
+	 *
1341
+	 * @param int | EE_Datetime $DTT_OR_ID      The datetime the registration is being checked against
1342
+	 * @param bool              $check_approved This is used to indicate whether the caller wants can_checkin to also
1343
+	 *                                          consider registration status as well as datetime access.
1344
+	 * @return bool
1345
+	 * @throws EE_Error
1346
+	 */
1347
+	public function can_checkin($DTT_OR_ID, $check_approved = true)
1348
+	{
1349
+		$DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1350
+
1351
+		//first check registration status
1352
+		if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) {
1353
+			return false;
1354
+		}
1355
+		//is there a datetime ticket that matches this dtt_ID?
1356
+		if (! (EEM_Datetime_Ticket::instance()->exists(array(
1357
+			array(
1358
+				'TKT_ID' => $this->get('TKT_ID'),
1359
+				'DTT_ID' => $DTT_ID,
1360
+			),
1361
+		)))
1362
+		) {
1363
+			return false;
1364
+		}
1365
+
1366
+		//final check is against TKT_uses
1367
+		return $this->verify_can_checkin_against_TKT_uses($DTT_ID);
1368
+	}
1369
+
1370
+
1371
+	/**
1372
+	 * This method verifies whether the user can checkin for the given datetime considering the max uses value set on
1373
+	 * the ticket. To do this,  a query is done to get the count of the datetime records already checked into.  If the
1374
+	 * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses,
1375
+	 * then return false.  Otherwise return true.
1376
+	 *
1377
+	 * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against
1378
+	 * @return bool true means can checkin.  false means cannot checkin.
1379
+	 * @throws EE_Error
1380
+	 */
1381
+	public function verify_can_checkin_against_TKT_uses($DTT_OR_ID)
1382
+	{
1383
+		$DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1384
+
1385
+		if (! $DTT_ID) {
1386
+			return false;
1387
+		}
1388
+
1389
+		$max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF;
1390
+
1391
+		// if max uses is not set or equals infinity then return true cause its not a factor for whether user can
1392
+		// check-in or not.
1393
+		if (! $max_uses || $max_uses === EE_INF) {
1394
+			return true;
1395
+		}
1396
+
1397
+		//does this datetime have a checkin record?  If so, then the dtt count has already been verified so we can just
1398
+		//go ahead and toggle.
1399
+		if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) {
1400
+			return true;
1401
+		}
1402
+
1403
+		//made it here so the last check is whether the number of checkins per unique datetime on this registration
1404
+		//disallows further check-ins.
1405
+		$count_unique_dtt_checkins = EEM_Checkin::instance()->count(array(
1406
+			array(
1407
+				'REG_ID' => $this->ID(),
1408
+				'CHK_in' => true,
1409
+			),
1410
+		), 'DTT_ID', true);
1411
+		// checkins have already reached their max number of uses
1412
+		// so registrant can NOT checkin
1413
+		if ($count_unique_dtt_checkins >= $max_uses) {
1414
+			EE_Error::add_error(
1415
+				esc_html__(
1416
+					'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.',
1417
+					'event_espresso'
1418
+				),
1419
+				__FILE__,
1420
+				__FUNCTION__,
1421
+				__LINE__
1422
+			);
1423
+			return false;
1424
+		}
1425
+		return true;
1426
+	}
1427
+
1428
+
1429
+	/**
1430
+	 * toggle Check-in status for this registration
1431
+	 * Check-ins are toggled in the following order:
1432
+	 * never checked in -> checked in
1433
+	 * checked in -> checked out
1434
+	 * checked out -> checked in
1435
+	 *
1436
+	 * @param  int $DTT_ID  include specific datetime to toggle Check-in for.
1437
+	 *                      If not included or null, then it is assumed latest datetime is being toggled.
1438
+	 * @param bool $verify  If true then can_checkin() is used to verify whether the person
1439
+	 *                      can be checked in or not.  Otherwise this forces change in checkin status.
1440
+	 * @return bool|int     the chk_in status toggled to OR false if nothing got changed.
1441
+	 * @throws EE_Error
1442
+	 */
1443
+	public function toggle_checkin_status($DTT_ID = null, $verify = false)
1444
+	{
1445
+		if (empty($DTT_ID)) {
1446
+			$datetime = $this->get_latest_related_datetime();
1447
+			$DTT_ID   = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
1448
+			// verify the registration can checkin for the given DTT_ID
1449
+		} elseif (! $this->can_checkin($DTT_ID, $verify)) {
1450
+			EE_Error::add_error(
1451
+				sprintf(
1452
+					esc_html__(
1453
+						'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access',
1454
+						'event_espresso'
1455
+					),
1456
+					$this->ID(),
1457
+					$DTT_ID
1458
+				),
1459
+				__FILE__,
1460
+				__FUNCTION__,
1461
+				__LINE__
1462
+			);
1463
+			return false;
1464
+		}
1465
+		$status_paths = array(
1466
+			EE_Checkin::status_checked_never => EE_Checkin::status_checked_in,
1467
+			EE_Checkin::status_checked_in    => EE_Checkin::status_checked_out,
1468
+			EE_Checkin::status_checked_out   => EE_Checkin::status_checked_in,
1469
+		);
1470
+		//start by getting the current status so we know what status we'll be changing to.
1471
+		$cur_status = $this->check_in_status_for_datetime($DTT_ID, null);
1472
+		$status_to  = $status_paths[$cur_status];
1473
+		// database only records true for checked IN or false for checked OUT
1474
+		// no record ( null ) means checked in NEVER, but we obviously don't save that
1475
+		$new_status = $status_to === EE_Checkin::status_checked_in ? true : false;
1476
+		// add relation - note Check-ins are always creating new rows
1477
+		// because we are keeping track of Check-ins over time.
1478
+		// Eventually we'll probably want to show a list table
1479
+		// for the individual Check-ins so that they can be managed.
1480
+		$checkin = EE_Checkin::new_instance(array(
1481
+			'REG_ID' => $this->ID(),
1482
+			'DTT_ID' => $DTT_ID,
1483
+			'CHK_in' => $new_status,
1484
+		));
1485
+		// if the record could not be saved then return false
1486
+		if ($checkin->save() === 0) {
1487
+			if (WP_DEBUG) {
1488
+				global $wpdb;
1489
+				$error = sprintf(
1490
+					esc_html__(
1491
+						'Registration check in update failed because of the following database error: %1$s%2$s',
1492
+						'event_espresso'
1493
+					),
1494
+					'<br />',
1495
+					$wpdb->last_error
1496
+				);
1497
+			} else {
1498
+				$error = esc_html__(
1499
+					'Registration check in update failed because of an unknown database error',
1500
+					'event_espresso'
1501
+				);
1502
+			}
1503
+			EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
1504
+			return false;
1505
+		}
1506
+		return $status_to;
1507
+	}
1508
+
1509
+
1510
+	/**
1511
+	 * Returns the latest datetime related to this registration (via the ticket attached to the registration).
1512
+	 * "Latest" is defined by the `DTT_EVT_start` column.
1513
+	 *
1514
+	 * @return EE_Datetime|null
1515
+	 * @throws \EE_Error
1516
+	 */
1517
+	public function get_latest_related_datetime()
1518
+	{
1519
+		return EEM_Datetime::instance()->get_one(
1520
+			array(
1521
+				array(
1522
+					'Ticket.Registration.REG_ID' => $this->ID(),
1523
+				),
1524
+				'order_by' => array('DTT_EVT_start' => 'DESC'),
1525
+			)
1526
+		);
1527
+	}
1528
+
1529
+
1530
+	/**
1531
+	 * Returns the earliest datetime related to this registration (via the ticket attached to the registration).
1532
+	 * "Earliest" is defined by the `DTT_EVT_start` column.
1533
+	 *
1534
+	 * @throws \EE_Error
1535
+	 */
1536
+	public function get_earliest_related_datetime()
1537
+	{
1538
+		return EEM_Datetime::instance()->get_one(
1539
+			array(
1540
+				array(
1541
+					'Ticket.Registration.REG_ID' => $this->ID(),
1542
+				),
1543
+				'order_by' => array('DTT_EVT_start' => 'ASC'),
1544
+			)
1545
+		);
1546
+	}
1547
+
1548
+
1549
+	/**
1550
+	 * This method simply returns the check-in status for this registration and the given datetime.
1551
+	 * If neither the datetime nor the checkin values are provided as arguments,
1552
+	 * then this will return the LATEST check-in status for the registration across all datetimes it belongs to.
1553
+	 *
1554
+	 * @param  int       $DTT_ID  The ID of the datetime we're checking against
1555
+	 *                            (if empty we'll get the primary datetime for
1556
+	 *                            this registration (via event) and use it's ID);
1557
+	 * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id.
1558
+	 * @return int                Integer representing Check-in status.
1559
+	 * @throws \EE_Error
1560
+	 */
1561
+	public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null)
1562
+	{
1563
+		$checkin_query_params = array(
1564
+			'order_by' => array('CHK_timestamp' => 'DESC'),
1565
+		);
1566
+
1567
+		if ($DTT_ID > 0) {
1568
+			$checkin_query_params[0] = array('DTT_ID' => $DTT_ID);
1569
+		}
1570
+
1571
+		//get checkin object (if exists)
1572
+		$checkin = $checkin instanceof EE_Checkin
1573
+			? $checkin
1574
+			: $this->get_first_related('Checkin', $checkin_query_params);
1575
+		if ($checkin instanceof EE_Checkin) {
1576
+			if ($checkin->get('CHK_in')) {
1577
+				return EE_Checkin::status_checked_in; //checked in
1578
+			}
1579
+			return EE_Checkin::status_checked_out; //had checked in but is now checked out.
1580
+		}
1581
+		return EE_Checkin::status_checked_never; //never been checked in
1582
+	}
1583
+
1584
+
1585
+	/**
1586
+	 * This method returns a localized message for the toggled Check-in message.
1587
+	 *
1588
+	 * @param  int $DTT_ID include specific datetime to get the correct Check-in message.  If not included or null,
1589
+	 *                     then it is assumed Check-in for primary datetime was toggled.
1590
+	 * @param bool $error  This just flags that you want an error message returned. This is put in so that the error
1591
+	 *                     message can be customized with the attendee name.
1592
+	 * @return string internationalized message
1593
+	 * @throws EE_Error
1594
+	 */
1595
+	public function get_checkin_msg($DTT_ID, $error = false)
1596
+	{
1597
+		//let's get the attendee first so we can include the name of the attendee
1598
+		$attendee = $this->get_first_related('Attendee');
1599
+		if ($attendee instanceof EE_Attendee) {
1600
+			if ($error) {
1601
+				return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name());
1602
+			}
1603
+			$cur_status = $this->check_in_status_for_datetime($DTT_ID);
1604
+			//what is the status message going to be?
1605
+			switch ($cur_status) {
1606
+				case EE_Checkin::status_checked_never:
1607
+					return sprintf(__("%s has been removed from Check-in records", "event_espresso"),
1608
+						$attendee->full_name());
1609
+					break;
1610
+				case EE_Checkin::status_checked_in:
1611
+					return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name());
1612
+					break;
1613
+				case EE_Checkin::status_checked_out:
1614
+					return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name());
1615
+					break;
1616
+			}
1617
+		}
1618
+		return esc_html__("The check-in status could not be determined.", "event_espresso");
1619
+	}
1620
+
1621
+
1622
+	/**
1623
+	 * Returns the related EE_Transaction to this registration
1624
+	 *
1625
+	 * @return EE_Transaction
1626
+	 * @throws EE_Error
1627
+	 * @throws EntityNotFoundException
1628
+	 */
1629
+	public function transaction()
1630
+	{
1631
+		$transaction = $this->get_first_related('Transaction');
1632
+		if (! $transaction instanceof \EE_Transaction) {
1633
+			throw new EntityNotFoundException('Transaction ID', $this->transaction_ID());
1634
+		}
1635
+		return $transaction;
1636
+	}
1637
+
1638
+
1639
+	/**
1640
+	 *        get Registration Code
1641
+	 */
1642
+	public function reg_code()
1643
+	{
1644
+		return $this->get('REG_code');
1645
+	}
1646
+
1647
+
1648
+	/**
1649
+	 *        get Transaction ID
1650
+	 */
1651
+	public function transaction_ID()
1652
+	{
1653
+		return $this->get('TXN_ID');
1654
+	}
1655
+
1656
+
1657
+	/**
1658
+	 * @return int
1659
+	 * @throws EE_Error
1660
+	 */
1661
+	public function ticket_ID()
1662
+	{
1663
+		return $this->get('TKT_ID');
1664
+	}
1665
+
1666
+
1667
+	/**
1668
+	 *        Set Registration Code
1669
+	 *
1670
+	 * @access    public
1671
+	 * @param    string  $REG_code Registration Code
1672
+	 * @param    boolean $use_default
1673
+	 * @throws EE_Error
1674
+	 */
1675
+	public function set_reg_code($REG_code, $use_default = false)
1676
+	{
1677
+		if (empty($REG_code)) {
1678
+			EE_Error::add_error(
1679
+				esc_html__('REG_code can not be empty.', 'event_espresso'),
1680
+				__FILE__,
1681
+				__FUNCTION__,
1682
+				__LINE__
1683
+			);
1684
+			return;
1685
+		}
1686
+		if (! $this->reg_code()) {
1687
+			parent::set('REG_code', $REG_code, $use_default);
1688
+		} else {
1689
+			EE_Error::doing_it_wrong(
1690
+				__CLASS__ . '::' . __FUNCTION__,
1691
+				esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'),
1692
+				'4.6.0'
1693
+			);
1694
+		}
1695
+	}
1696
+
1697
+
1698
+	/**
1699
+	 * Returns all other registrations in the same group as this registrant who have the same ticket option.
1700
+	 * Note, if you want to just get all registrations in the same transaction (group), use:
1701
+	 *    $registration->transaction()->registrations();
1702
+	 *
1703
+	 * @since 4.5.0
1704
+	 * @return EE_Registration[] or empty array if this isn't a group registration.
1705
+	 * @throws EE_Error
1706
+	 */
1707
+	public function get_all_other_registrations_in_group()
1708
+	{
1709
+		if ($this->group_size() < 2) {
1710
+			return array();
1711
+		}
1712
+
1713
+		$query[0] = array(
1714
+			'TXN_ID' => $this->transaction_ID(),
1715
+			'REG_ID' => array('!=', $this->ID()),
1716
+			'TKT_ID' => $this->ticket_ID(),
1717
+		);
1718
+		/** @var EE_Registration[] $registrations */
1719
+		$registrations = $this->get_model()->get_all($query);
1720
+		return $registrations;
1721
+	}
1722
+
1723
+	/**
1724
+	 * Return the link to the admin details for the object.
1725
+	 *
1726
+	 * @return string
1727
+	 * @throws EE_Error
1728
+	 */
1729
+	public function get_admin_details_link()
1730
+	{
1731
+		EE_Registry::instance()->load_helper('URL');
1732
+		return EEH_URL::add_query_args_and_nonce(
1733
+			array(
1734
+				'page'    => 'espresso_registrations',
1735
+				'action'  => 'view_registration',
1736
+				'_REG_ID' => $this->ID(),
1737
+			),
1738
+			admin_url('admin.php')
1739
+		);
1740
+	}
1741
+
1742
+	/**
1743
+	 * Returns the link to the editor for the object.  Sometimes this is the same as the details.
1744
+	 *
1745
+	 * @return string
1746
+	 * @throws EE_Error
1747
+	 */
1748
+	public function get_admin_edit_link()
1749
+	{
1750
+		return $this->get_admin_details_link();
1751
+	}
1752
+
1753
+	/**
1754
+	 * Returns the link to a settings page for the object.
1755
+	 *
1756
+	 * @return string
1757
+	 * @throws EE_Error
1758
+	 */
1759
+	public function get_admin_settings_link()
1760
+	{
1761
+		return $this->get_admin_details_link();
1762
+	}
1763
+
1764
+	/**
1765
+	 * Returns the link to the "overview" for the object (typically the "list table" view).
1766
+	 *
1767
+	 * @return string
1768
+	 */
1769
+	public function get_admin_overview_link()
1770
+	{
1771
+		EE_Registry::instance()->load_helper('URL');
1772
+		return EEH_URL::add_query_args_and_nonce(
1773
+			array(
1774
+				'page' => 'espresso_registrations',
1775
+			),
1776
+			admin_url('admin.php')
1777
+		);
1778
+	}
1779
+
1780
+
1781
+	/**
1782
+	 * @param array $query_params
1783
+	 * @return \EE_Registration[]
1784
+	 * @throws \EE_Error
1785
+	 */
1786
+	public function payments($query_params = array())
1787
+	{
1788
+		return $this->get_many_related('Payment', $query_params);
1789
+	}
1790
+
1791
+
1792
+	/**
1793
+	 * @param array $query_params
1794
+	 * @return \EE_Registration_Payment[]
1795
+	 * @throws \EE_Error
1796
+	 */
1797
+	public function registration_payments($query_params = array())
1798
+	{
1799
+		return $this->get_many_related('Registration_Payment', $query_params);
1800
+	}
1801
+
1802
+
1803
+	/**
1804
+	 * This grabs the payment method corresponding to the last payment made for the amount owing on the registration.
1805
+	 * Note: if there are no payments on the registration there will be no payment method returned.
1806
+	 *
1807
+	 * @return EE_Payment_Method|null
1808
+	 */
1809
+	public function payment_method()
1810
+	{
1811
+		return EEM_Payment_Method::instance()->get_last_used_for_registration($this);
1812
+	}
1813
+
1814
+
1815
+	/**
1816
+	 * @return \EE_Line_Item
1817
+	 * @throws EntityNotFoundException
1818
+	 * @throws \EE_Error
1819
+	 */
1820
+	public function ticket_line_item()
1821
+	{
1822
+		$ticket            = $this->ticket();
1823
+		$transaction       = $this->transaction();
1824
+		$line_item         = null;
1825
+		$ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs(
1826
+			$transaction->total_line_item(),
1827
+			'Ticket',
1828
+			array($ticket->ID())
1829
+		);
1830
+		foreach ($ticket_line_items as $ticket_line_item) {
1831
+			if (
1832
+				$ticket_line_item instanceof \EE_Line_Item
1833
+				&& $ticket_line_item->OBJ_type() === 'Ticket'
1834
+				&& $ticket_line_item->OBJ_ID() === $ticket->ID()
1835
+			) {
1836
+				$line_item = $ticket_line_item;
1837
+				break;
1838
+			}
1839
+		}
1840
+		if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) {
1841
+			throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID());
1842
+		}
1843
+		return $line_item;
1844
+	}
1845
+
1846
+
1847
+	/**
1848
+	 * Soft Deletes this model object.
1849
+	 *
1850
+	 * @return boolean | int
1851
+	 * @throws \RuntimeException
1852
+	 * @throws \EE_Error
1853
+	 */
1854
+	public function delete()
1855
+	{
1856
+		if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) {
1857
+			$this->set_status(EEM_Registration::status_id_cancelled);
1858
+		}
1859
+		return parent::delete();
1860
+	}
1861
+
1862
+
1863
+	/**
1864
+	 * Restores whatever the previous status was on a registration before it was trashed (if possible)
1865
+	 *
1866
+	 * @throws \EE_Error
1867
+	 * @throws \RuntimeException
1868
+	 */
1869
+	public function restore()
1870
+	{
1871
+		$previous_status = $this->get_extra_meta(
1872
+			EE_Registration::PRE_TRASH_REG_STATUS_KEY,
1873
+			true,
1874
+			EEM_Registration::status_id_cancelled
1875
+		);
1876
+		if ($previous_status) {
1877
+			$this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY);
1878
+			$this->set_status($previous_status);
1879
+		}
1880
+		return parent::restore();
1881
+	}
1882
+
1883
+
1884
+
1885
+	/*************************** DEPRECATED ***************************/
1886
+
1887
+
1888
+	/**
1889
+	 * @deprecated
1890
+	 * @since     4.7.0
1891
+	 * @access    public
1892
+	 */
1893
+	public function price_paid()
1894
+	{
1895
+		EE_Error::doing_it_wrong('EE_Registration::price_paid()',
1896
+			esc_html__('This method is deprecated, please use EE_Registration::final_price() instead.', 'event_espresso'),
1897
+			'4.7.0');
1898
+		return $this->final_price();
1899
+	}
1900
+
1901
+
1902
+	/**
1903
+	 * @deprecated
1904
+	 * @since     4.7.0
1905
+	 * @access    public
1906
+	 * @param    float $REG_final_price
1907
+	 * @throws EE_Error
1908
+	 * @throws RuntimeException
1909
+	 */
1910
+	public function set_price_paid($REG_final_price = 0.00)
1911
+	{
1912
+		EE_Error::doing_it_wrong('EE_Registration::set_price_paid()',
1913
+			esc_html__('This method is deprecated, please use EE_Registration::set_final_price() instead.', 'event_espresso'),
1914
+			'4.7.0');
1915
+		$this->set_final_price($REG_final_price);
1916
+	}
1917
+
1918
+
1919
+	/**
1920
+	 * @deprecated
1921
+	 * @since 4.7.0
1922
+	 * @return string
1923
+	 * @throws EE_Error
1924
+	 */
1925
+	public function pretty_price_paid()
1926
+	{
1927
+		EE_Error::doing_it_wrong('EE_Registration::pretty_price_paid()',
1928
+			esc_html__('This method is deprecated, please use EE_Registration::pretty_final_price() instead.',
1929
+				'event_espresso'), '4.7.0');
1930
+		return $this->pretty_final_price();
1931
+	}
1932
+
1933
+
1934
+	/**
1935
+	 * Gets the primary datetime related to this registration via the related Event to this registration
1936
+	 *
1937
+	 * @deprecated 4.9.17
1938
+	 * @return EE_Datetime
1939
+	 * @throws EE_Error
1940
+	 * @throws EntityNotFoundException
1941
+	 */
1942
+	public function get_related_primary_datetime()
1943
+	{
1944
+		EE_Error::doing_it_wrong(
1945
+			__METHOD__,
1946
+			esc_html__(
1947
+				'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()',
1948
+				'event_espresso'
1949
+			),
1950
+			'4.9.17',
1951
+			'5.0.0'
1952
+		);
1953
+		return $this->event()->primary_datetime();
1954
+	}
1955 1955
 
1956 1956
 
1957 1957
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -120,7 +120,7 @@  discard block
 block discarded – undo
120 120
     {
121 121
         switch ($field_name) {
122 122
             case 'REG_code':
123
-                if (! empty($field_value) && $this->reg_code() === null) {
123
+                if ( ! empty($field_value) && $this->reg_code() === null) {
124 124
                     $this->set_reg_code($field_value, $use_default);
125 125
                 }
126 126
                 break;
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
             // update status
182 182
             parent::set('STS_ID', $new_STS_ID, $use_default);
183 183
             $this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, $context);
184
-            if($this->statusChangeUpdatesTransaction($context)) {
184
+            if ($this->statusChangeUpdatesTransaction($context)) {
185 185
                 $this->updateTransactionAfterStatusChange();
186 186
             }
187 187
             do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context);
@@ -408,7 +408,7 @@  discard block
 block discarded – undo
408 408
     public function event()
409 409
     {
410 410
         $event = $this->get_first_related('Event');
411
-        if (! $event instanceof \EE_Event) {
411
+        if ( ! $event instanceof \EE_Event) {
412 412
             throw new EntityNotFoundException('Event ID', $this->event_ID());
413 413
         }
414 414
         return $event;
@@ -1097,7 +1097,7 @@  discard block
 block discarded – undo
1097 1097
             false,
1098 1098
             'sentence'
1099 1099
         );
1100
-        $icon   = '';
1100
+        $icon = '';
1101 1101
         switch ($this->status_ID()) {
1102 1102
             case EEM_Registration::status_id_approved:
1103 1103
                 $icon = $show_icons
@@ -1135,7 +1135,7 @@  discard block
 block discarded – undo
1135 1135
                     : '';
1136 1136
                 break;
1137 1137
         }
1138
-        return $icon . $status[$this->status_ID()];
1138
+        return $icon.$status[$this->status_ID()];
1139 1139
     }
1140 1140
 
1141 1141
 
@@ -1353,7 +1353,7 @@  discard block
 block discarded – undo
1353 1353
             return false;
1354 1354
         }
1355 1355
         //is there a datetime ticket that matches this dtt_ID?
1356
-        if (! (EEM_Datetime_Ticket::instance()->exists(array(
1356
+        if ( ! (EEM_Datetime_Ticket::instance()->exists(array(
1357 1357
             array(
1358 1358
                 'TKT_ID' => $this->get('TKT_ID'),
1359 1359
                 'DTT_ID' => $DTT_ID,
@@ -1382,7 +1382,7 @@  discard block
 block discarded – undo
1382 1382
     {
1383 1383
         $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1384 1384
 
1385
-        if (! $DTT_ID) {
1385
+        if ( ! $DTT_ID) {
1386 1386
             return false;
1387 1387
         }
1388 1388
 
@@ -1390,7 +1390,7 @@  discard block
 block discarded – undo
1390 1390
 
1391 1391
         // if max uses is not set or equals infinity then return true cause its not a factor for whether user can
1392 1392
         // check-in or not.
1393
-        if (! $max_uses || $max_uses === EE_INF) {
1393
+        if ( ! $max_uses || $max_uses === EE_INF) {
1394 1394
             return true;
1395 1395
         }
1396 1396
 
@@ -1446,7 +1446,7 @@  discard block
 block discarded – undo
1446 1446
             $datetime = $this->get_latest_related_datetime();
1447 1447
             $DTT_ID   = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
1448 1448
             // verify the registration can checkin for the given DTT_ID
1449
-        } elseif (! $this->can_checkin($DTT_ID, $verify)) {
1449
+        } elseif ( ! $this->can_checkin($DTT_ID, $verify)) {
1450 1450
             EE_Error::add_error(
1451 1451
                 sprintf(
1452 1452
                     esc_html__(
@@ -1629,7 +1629,7 @@  discard block
 block discarded – undo
1629 1629
     public function transaction()
1630 1630
     {
1631 1631
         $transaction = $this->get_first_related('Transaction');
1632
-        if (! $transaction instanceof \EE_Transaction) {
1632
+        if ( ! $transaction instanceof \EE_Transaction) {
1633 1633
             throw new EntityNotFoundException('Transaction ID', $this->transaction_ID());
1634 1634
         }
1635 1635
         return $transaction;
@@ -1683,11 +1683,11 @@  discard block
 block discarded – undo
1683 1683
             );
1684 1684
             return;
1685 1685
         }
1686
-        if (! $this->reg_code()) {
1686
+        if ( ! $this->reg_code()) {
1687 1687
             parent::set('REG_code', $REG_code, $use_default);
1688 1688
         } else {
1689 1689
             EE_Error::doing_it_wrong(
1690
-                __CLASS__ . '::' . __FUNCTION__,
1690
+                __CLASS__.'::'.__FUNCTION__,
1691 1691
                 esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'),
1692 1692
                 '4.6.0'
1693 1693
             );
@@ -1837,7 +1837,7 @@  discard block
 block discarded – undo
1837 1837
                 break;
1838 1838
             }
1839 1839
         }
1840
-        if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) {
1840
+        if ( ! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) {
1841 1841
             throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID());
1842 1842
         }
1843 1843
         return $line_item;
Please login to merge, or discard this patch.
modules/single_page_checkout/EED_Single_Page_Checkout.module.php 2 patches
Indentation   +1856 added lines, -1856 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
 use EventEspresso\core\exceptions\InvalidEntityException;
6 6
 
7 7
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
8
-    exit('No direct script access allowed');
8
+	exit('No direct script access allowed');
9 9
 }
10 10
 
11 11
 
@@ -20,1861 +20,1861 @@  discard block
 block discarded – undo
20 20
 class EED_Single_Page_Checkout extends EED_Module
21 21
 {
22 22
 
23
-    /**
24
-     * $_initialized - has the SPCO controller already been initialized ?
25
-     *
26
-     * @access private
27
-     * @var bool $_initialized
28
-     */
29
-    private static $_initialized = false;
30
-
31
-
32
-    /**
33
-     * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
34
-     *
35
-     * @access private
36
-     * @var bool $_valid_checkout
37
-     */
38
-    private static $_checkout_verified = true;
39
-
40
-    /**
41
-     *    $_reg_steps_array - holds initial array of reg steps
42
-     *
43
-     * @access private
44
-     * @var array $_reg_steps_array
45
-     */
46
-    private static $_reg_steps_array = array();
47
-
48
-    /**
49
-     *    $checkout - EE_Checkout object for handling the properties of the current checkout process
50
-     *
51
-     * @access public
52
-     * @var EE_Checkout $checkout
53
-     */
54
-    public $checkout;
55
-
56
-
57
-
58
-    /**
59
-     * @return EED_Module|EED_Single_Page_Checkout
60
-     */
61
-    public static function instance()
62
-    {
63
-        add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
64
-        return parent::get_instance(__CLASS__);
65
-    }
66
-
67
-
68
-
69
-    /**
70
-     * @return EE_CART
71
-     */
72
-    public function cart()
73
-    {
74
-        return $this->checkout->cart;
75
-    }
76
-
77
-
78
-
79
-    /**
80
-     * @return EE_Transaction
81
-     */
82
-    public function transaction()
83
-    {
84
-        return $this->checkout->transaction;
85
-    }
86
-
87
-
88
-
89
-    /**
90
-     *    set_hooks - for hooking into EE Core, other modules, etc
91
-     *
92
-     * @access    public
93
-     * @return    void
94
-     * @throws EE_Error
95
-     */
96
-    public static function set_hooks()
97
-    {
98
-        EED_Single_Page_Checkout::set_definitions();
99
-    }
100
-
101
-
102
-
103
-    /**
104
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
105
-     *
106
-     * @access    public
107
-     * @return    void
108
-     * @throws EE_Error
109
-     */
110
-    public static function set_hooks_admin()
111
-    {
112
-        EED_Single_Page_Checkout::set_definitions();
113
-        if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
114
-            return;
115
-        }
116
-        // going to start an output buffer in case anything gets accidentally output
117
-        // that might disrupt our JSON response
118
-        ob_start();
119
-        EED_Single_Page_Checkout::load_request_handler();
120
-        EED_Single_Page_Checkout::load_reg_steps();
121
-        // set ajax hooks
122
-        add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
123
-        add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
124
-        add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
125
-        add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
126
-        add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
127
-        add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
128
-    }
129
-
130
-
131
-
132
-    /**
133
-     *    process ajax request
134
-     *
135
-     * @param string $ajax_action
136
-     * @throws EE_Error
137
-     */
138
-    public static function process_ajax_request($ajax_action)
139
-    {
140
-        EE_Registry::instance()->REQ->set('action', $ajax_action);
141
-        EED_Single_Page_Checkout::instance()->_initialize();
142
-    }
143
-
144
-
145
-
146
-    /**
147
-     *    ajax display registration step
148
-     *
149
-     * @throws EE_Error
150
-     */
151
-    public static function display_reg_step()
152
-    {
153
-        EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
154
-    }
155
-
156
-
157
-
158
-    /**
159
-     *    ajax process registration step
160
-     *
161
-     * @throws EE_Error
162
-     */
163
-    public static function process_reg_step()
164
-    {
165
-        EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
166
-    }
167
-
168
-
169
-
170
-    /**
171
-     *    ajax process registration step
172
-     *
173
-     * @throws EE_Error
174
-     */
175
-    public static function update_reg_step()
176
-    {
177
-        EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
178
-    }
179
-
180
-
181
-
182
-    /**
183
-     *   update_checkout
184
-     *
185
-     * @access public
186
-     * @return void
187
-     * @throws EE_Error
188
-     */
189
-    public static function update_checkout()
190
-    {
191
-        EED_Single_Page_Checkout::process_ajax_request('update_checkout');
192
-    }
193
-
194
-
195
-
196
-    /**
197
-     *    load_request_handler
198
-     *
199
-     * @access    public
200
-     * @return    void
201
-     */
202
-    public static function load_request_handler()
203
-    {
204
-        // load core Request_Handler class
205
-        if (EE_Registry::instance()->REQ !== null) {
206
-            EE_Registry::instance()->load_core('Request_Handler');
207
-        }
208
-    }
209
-
210
-
211
-
212
-    /**
213
-     *    set_definitions
214
-     *
215
-     * @access    public
216
-     * @return    void
217
-     * @throws EE_Error
218
-     */
219
-    public static function set_definitions()
220
-    {
221
-        if(defined('SPCO_BASE_PATH')) {
222
-            return;
223
-        }
224
-        define(
225
-            'SPCO_BASE_PATH',
226
-            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
227
-        );
228
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
234
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236
-            __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
237
-                'event_espresso'),
238
-            '<h4 class="important-notice">',
239
-            '</h4>',
240
-            '<br />',
241
-            '<p>',
242
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
243
-            '">',
244
-            '</a>',
245
-            '</p>'
246
-        );
247
-    }
248
-
249
-
250
-
251
-    /**
252
-     * load_reg_steps
253
-     * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
254
-     *
255
-     * @access    private
256
-     * @throws EE_Error
257
-     */
258
-    public static function load_reg_steps()
259
-    {
260
-        static $reg_steps_loaded = false;
261
-        if ($reg_steps_loaded) {
262
-            return;
263
-        }
264
-        // filter list of reg_steps
265
-        $reg_steps_to_load = (array)apply_filters(
266
-            'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267
-            EED_Single_Page_Checkout::get_reg_steps()
268
-        );
269
-        // sort by key (order)
270
-        ksort($reg_steps_to_load);
271
-        // loop through folders
272
-        foreach ($reg_steps_to_load as $order => $reg_step) {
273
-            // we need a
274
-            if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
275
-                // copy over to the reg_steps_array
276
-                EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step;
277
-                // register custom key route for each reg step
278
-                // ie: step=>"slug" - this is the entire reason we load the reg steps array now
279
-                EE_Config::register_route(
280
-                    $reg_step['slug'],
281
-                    'EED_Single_Page_Checkout',
282
-                    'run',
283
-                    'step'
284
-                );
285
-                // add AJAX or other hooks
286
-                if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
287
-                    // setup autoloaders if necessary
288
-                    if ( ! class_exists($reg_step['class_name'])) {
289
-                        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(
290
-                            $reg_step['file_path'],
291
-                            true
292
-                        );
293
-                    }
294
-                    if (is_callable($reg_step['class_name'], 'set_hooks')) {
295
-                        call_user_func(array($reg_step['class_name'], 'set_hooks'));
296
-                    }
297
-                }
298
-            }
299
-        }
300
-        $reg_steps_loaded = true;
301
-    }
302
-
303
-
304
-
305
-    /**
306
-     *    get_reg_steps
307
-     *
308
-     * @access    public
309
-     * @return    array
310
-     */
311
-    public static function get_reg_steps()
312
-    {
313
-        $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
314
-        if (empty($reg_steps)) {
315
-            $reg_steps = array(
316
-                10  => array(
317
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
318
-                    'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319
-                    'slug'       => 'attendee_information',
320
-                    'has_hooks'  => false,
321
-                ),
322
-                20  => array(
323
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
324
-                    'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325
-                    'slug'       => 'registration_confirmation',
326
-                    'has_hooks'  => false,
327
-                ),
328
-                30  => array(
329
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
330
-                    'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331
-                    'slug'       => 'payment_options',
332
-                    'has_hooks'  => true,
333
-                ),
334
-                999 => array(
335
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
336
-                    'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337
-                    'slug'       => 'finalize_registration',
338
-                    'has_hooks'  => false,
339
-                ),
340
-            );
341
-        }
342
-        return $reg_steps;
343
-    }
344
-
345
-
346
-
347
-    /**
348
-     *    registration_checkout_for_admin
349
-     *
350
-     * @access    public
351
-     * @return    string
352
-     * @throws EE_Error
353
-     */
354
-    public static function registration_checkout_for_admin()
355
-    {
356
-        EED_Single_Page_Checkout::load_request_handler();
357
-        EE_Registry::instance()->REQ->set('step', 'attendee_information');
358
-        EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step');
359
-        EE_Registry::instance()->REQ->set('process_form_submission', false);
360
-        EED_Single_Page_Checkout::instance()->_initialize();
361
-        EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
362
-        return EE_Registry::instance()->REQ->get_output();
363
-    }
364
-
365
-
366
-
367
-    /**
368
-     * process_registration_from_admin
369
-     *
370
-     * @access public
371
-     * @return \EE_Transaction
372
-     * @throws EE_Error
373
-     */
374
-    public static function process_registration_from_admin()
375
-    {
376
-        EED_Single_Page_Checkout::load_request_handler();
377
-        EE_Registry::instance()->REQ->set('step', 'attendee_information');
378
-        EE_Registry::instance()->REQ->set('action', 'process_reg_step');
379
-        EE_Registry::instance()->REQ->set('process_form_submission', true);
380
-        EED_Single_Page_Checkout::instance()->_initialize();
381
-        if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
382
-            $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
383
-            if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
384
-                EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
385
-                if ($final_reg_step->process_reg_step()) {
386
-                    $final_reg_step->set_completed();
387
-                    EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
388
-                    return EED_Single_Page_Checkout::instance()->checkout->transaction;
389
-                }
390
-            }
391
-        }
392
-        return null;
393
-    }
394
-
395
-
396
-
397
-    /**
398
-     *    run
399
-     *
400
-     * @access    public
401
-     * @param WP_Query $WP_Query
402
-     * @return    void
403
-     * @throws EE_Error
404
-     */
405
-    public function run($WP_Query)
406
-    {
407
-        if (
408
-            $WP_Query instanceof WP_Query
409
-            && $WP_Query->is_main_query()
410
-            && apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
411
-            && $this->_is_reg_checkout()
412
-        ) {
413
-            $this->_initialize();
414
-        }
415
-    }
416
-
417
-
418
-
419
-    /**
420
-     * determines whether current url matches reg page url
421
-     *
422
-     * @return bool
423
-     */
424
-    protected function _is_reg_checkout()
425
-    {
426
-        // get current permalink for reg page without any extra query args
427
-        $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id);
428
-        // get request URI for current request, but without the scheme or host
429
-        $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI');
430
-        $current_request_uri = html_entity_decode($current_request_uri);
431
-        // get array of query args from the current request URI
432
-        $query_args = \EEH_URL::get_query_string($current_request_uri);
433
-        // grab page id if it is set
434
-        $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
435
-        // and remove the page id from the query args (we will re-add it later)
436
-        unset($query_args['page_id']);
437
-        // now strip all query args from current request URI
438
-        $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
439
-        // and re-add the page id if it was set
440
-        if ($page_id) {
441
-            $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
442
-        }
443
-        // remove slashes and ?
444
-        $current_request_uri = trim($current_request_uri, '?/');
445
-        // is current request URI part of the known full reg page URL ?
446
-        return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
447
-    }
448
-
449
-
450
-
451
-    /**
452
-     * @param WP_Query $wp_query
453
-     * @return    void
454
-     * @throws EE_Error
455
-     */
456
-    public static function init($wp_query)
457
-    {
458
-        EED_Single_Page_Checkout::instance()->run($wp_query);
459
-    }
460
-
461
-
462
-
463
-    /**
464
-     *    _initialize - initial module setup
465
-     *
466
-     * @access    private
467
-     * @throws EE_Error
468
-     * @return    void
469
-     */
470
-    private function _initialize()
471
-    {
472
-        // ensure SPCO doesn't run twice
473
-        if (EED_Single_Page_Checkout::$_initialized) {
474
-            return;
475
-        }
476
-        try {
477
-            EED_Single_Page_Checkout::load_reg_steps();
478
-            $this->_verify_session();
479
-            // setup the EE_Checkout object
480
-            $this->checkout = $this->_initialize_checkout();
481
-            // filter checkout
482
-            $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
483
-            // get the $_GET
484
-            $this->_get_request_vars();
485
-            if ($this->_block_bots()) {
486
-                return;
487
-            }
488
-            // filter continue_reg
489
-            $this->checkout->continue_reg = apply_filters(
490
-                'FHEE__EED_Single_Page_Checkout__init___continue_reg',
491
-                true,
492
-                $this->checkout
493
-            );
494
-            // load the reg steps array
495
-            if ( ! $this->_load_and_instantiate_reg_steps()) {
496
-                EED_Single_Page_Checkout::$_initialized = true;
497
-                return;
498
-            }
499
-            // set the current step
500
-            $this->checkout->set_current_step($this->checkout->step);
501
-            // and the next step
502
-            $this->checkout->set_next_step();
503
-            // verify that everything has been setup correctly
504
-            if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
505
-                EED_Single_Page_Checkout::$_initialized = true;
506
-                return;
507
-            }
508
-            // lock the transaction
509
-            $this->checkout->transaction->lock();
510
-            // make sure all of our cached objects are added to their respective model entity mappers
511
-            $this->checkout->refresh_all_entities();
512
-            // set amount owing
513
-            $this->checkout->amount_owing = $this->checkout->transaction->remaining();
514
-            // initialize each reg step, which gives them the chance to potentially alter the process
515
-            $this->_initialize_reg_steps();
516
-            // DEBUG LOG
517
-            //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
518
-            // get reg form
519
-            if( ! $this->_check_form_submission()) {
520
-                EED_Single_Page_Checkout::$_initialized = true;
521
-                return;
522
-            }
523
-            // checkout the action!!!
524
-            $this->_process_form_action();
525
-            // add some style and make it dance
526
-            $this->add_styles_and_scripts();
527
-            // kk... SPCO has successfully run
528
-            EED_Single_Page_Checkout::$_initialized = true;
529
-            // set no cache headers and constants
530
-            EE_System::do_not_cache();
531
-            // add anchor
532
-            add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
533
-            // remove transaction lock
534
-            add_action('shutdown', array($this, 'unlock_transaction'), 1);
535
-        } catch (Exception $e) {
536
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
537
-        }
538
-    }
539
-
540
-
541
-
542
-    /**
543
-     *    _verify_session
544
-     * checks that the session is valid and not expired
545
-     *
546
-     * @access    private
547
-     * @throws EE_Error
548
-     */
549
-    private function _verify_session()
550
-    {
551
-        if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
552
-            throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
553
-        }
554
-        $clear_session_requested = filter_var(
555
-            EE_Registry::instance()->REQ->get('clear_session', false),
556
-            FILTER_VALIDATE_BOOLEAN
557
-        );
558
-        // is session still valid ?
559
-        if ($clear_session_requested
560
-            || ( EE_Registry::instance()->SSN->expired()
561
-              && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === ''
562
-            )
563
-        ) {
564
-            $this->checkout = new EE_Checkout();
565
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
566
-            // EE_Registry::instance()->SSN->reset_cart();
567
-            // EE_Registry::instance()->SSN->reset_checkout();
568
-            // EE_Registry::instance()->SSN->reset_transaction();
569
-            if (! $clear_session_requested) {
570
-                EE_Error::add_attention(
571
-                    EE_Registry::$i18n_js_strings['registration_expiration_notice'],
572
-                    __FILE__, __FUNCTION__, __LINE__
573
-                );
574
-            }
575
-            // EE_Registry::instance()->SSN->reset_expired();
576
-        }
577
-    }
578
-
579
-
580
-
581
-    /**
582
-     *    _initialize_checkout
583
-     * loads and instantiates EE_Checkout
584
-     *
585
-     * @access    private
586
-     * @throws EE_Error
587
-     * @return EE_Checkout
588
-     */
589
-    private function _initialize_checkout()
590
-    {
591
-        // look in session for existing checkout
592
-        /** @type EE_Checkout $checkout */
593
-        $checkout = EE_Registry::instance()->SSN->checkout();
594
-        // verify
595
-        if ( ! $checkout instanceof EE_Checkout) {
596
-            // instantiate EE_Checkout object for handling the properties of the current checkout process
597
-            $checkout = EE_Registry::instance()->load_file(
598
-                SPCO_INC_PATH,
599
-                'EE_Checkout',
600
-                'class', array(),
601
-                false
602
-            );
603
-        } else {
604
-            if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
605
-                $this->unlock_transaction();
606
-                wp_safe_redirect($checkout->redirect_url);
607
-                exit();
608
-            }
609
-        }
610
-        $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
611
-        // verify again
612
-        if ( ! $checkout instanceof EE_Checkout) {
613
-            throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
614
-        }
615
-        // reset anything that needs a clean slate for each request
616
-        $checkout->reset_for_current_request();
617
-        return $checkout;
618
-    }
619
-
620
-
621
-
622
-    /**
623
-     *    _get_request_vars
624
-     *
625
-     * @access    private
626
-     * @return    void
627
-     * @throws EE_Error
628
-     */
629
-    private function _get_request_vars()
630
-    {
631
-        // load classes
632
-        EED_Single_Page_Checkout::load_request_handler();
633
-        //make sure this request is marked as belonging to EE
634
-        EE_Registry::instance()->REQ->set_espresso_page(true);
635
-        // which step is being requested ?
636
-        $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
637
-        // which step is being edited ?
638
-        $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
639
-        // and what we're doing on the current step
640
-        $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
641
-        // timestamp
642
-        $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
643
-        // returning to edit ?
644
-        $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
645
-        // or some other kind of revisit ?
646
-        $this->checkout->revisit = filter_var(
647
-            EE_Registry::instance()->REQ->get('revisit', false),
648
-            FILTER_VALIDATE_BOOLEAN
649
-        );
650
-        // and whether or not to generate a reg form for this request
651
-        $this->checkout->generate_reg_form = filter_var(
652
-            EE_Registry::instance()->REQ->get('generate_reg_form', true),
653
-            FILTER_VALIDATE_BOOLEAN
654
-        );
655
-        // and whether or not to process a reg form submission for this request
656
-        $this->checkout->process_form_submission = filter_var(
657
-            EE_Registry::instance()->REQ->get(
658
-                'process_form_submission',
659
-                $this->checkout->action === 'process_reg_step'
660
-            ),
661
-            FILTER_VALIDATE_BOOLEAN
662
-        );
663
-        $this->checkout->process_form_submission = filter_var(
664
-            $this->checkout->action !== 'display_spco_reg_step'
665
-                ? $this->checkout->process_form_submission
666
-                : false,
667
-            FILTER_VALIDATE_BOOLEAN
668
-        );
669
-        // $this->_display_request_vars();
670
-    }
671
-
672
-
673
-
674
-    /**
675
-     *  _display_request_vars
676
-     *
677
-     * @access    protected
678
-     * @return    void
679
-     */
680
-    protected function _display_request_vars()
681
-    {
682
-        if ( ! WP_DEBUG) {
683
-            return;
684
-        }
685
-        EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
686
-        EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
687
-        EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
688
-        EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
689
-        EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
690
-        EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
691
-        EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
692
-        EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
693
-    }
694
-
695
-
696
-
697
-    /**
698
-     * _block_bots
699
-     * checks that the incoming request has either of the following set:
700
-     *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
701
-     *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
702
-     * so if you're not coming from the Ticket Selector nor returning for a valid IP...
703
-     * then where you coming from man?
704
-     *
705
-     * @return boolean
706
-     */
707
-    private function _block_bots()
708
-    {
709
-        $invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
710
-        if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
711
-            return true;
712
-        }
713
-        return false;
714
-    }
715
-
716
-
717
-
718
-    /**
719
-     *    _get_first_step
720
-     *  gets slug for first step in $_reg_steps_array
721
-     *
722
-     * @access    private
723
-     * @throws EE_Error
724
-     * @return    string
725
-     */
726
-    private function _get_first_step()
727
-    {
728
-        $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
729
-        return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
730
-    }
731
-
732
-
733
-
734
-    /**
735
-     *    _load_and_instantiate_reg_steps
736
-     *  instantiates each reg step based on the loaded reg_steps array
737
-     *
738
-     * @access    private
739
-     * @throws EE_Error
740
-     * @return    bool
741
-     */
742
-    private function _load_and_instantiate_reg_steps()
743
-    {
744
-        do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
745
-        // have reg_steps already been instantiated ?
746
-        if (
747
-            empty($this->checkout->reg_steps)
748
-            || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
749
-        ) {
750
-            // if not, then loop through raw reg steps array
751
-            foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
752
-                if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
753
-                    return false;
754
-                }
755
-            }
756
-            EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true;
757
-            EE_Registry::instance()->CFG->registration->reg_confirmation_last = true;
758
-            // skip the registration_confirmation page ?
759
-            if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) {
760
-                // just remove it from the reg steps array
761
-                $this->checkout->remove_reg_step('registration_confirmation', false);
762
-            } else if (
763
-                isset($this->checkout->reg_steps['registration_confirmation'])
764
-                && EE_Registry::instance()->CFG->registration->reg_confirmation_last
765
-            ) {
766
-                // set the order to something big like 100
767
-                $this->checkout->set_reg_step_order('registration_confirmation', 100);
768
-            }
769
-            // filter the array for good luck
770
-            $this->checkout->reg_steps = apply_filters(
771
-                'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
772
-                $this->checkout->reg_steps
773
-            );
774
-            // finally re-sort based on the reg step class order properties
775
-            $this->checkout->sort_reg_steps();
776
-        } else {
777
-            foreach ($this->checkout->reg_steps as $reg_step) {
778
-                // set all current step stati to FALSE
779
-                $reg_step->set_is_current_step(false);
780
-            }
781
-        }
782
-        if (empty($this->checkout->reg_steps)) {
783
-            EE_Error::add_error(
784
-                __('No Reg Steps were loaded..', 'event_espresso'),
785
-                __FILE__, __FUNCTION__, __LINE__
786
-            );
787
-            return false;
788
-        }
789
-        // make reg step details available to JS
790
-        $this->checkout->set_reg_step_JSON_info();
791
-        return true;
792
-    }
793
-
794
-
795
-
796
-    /**
797
-     *     _load_and_instantiate_reg_step
798
-     *
799
-     * @access    private
800
-     * @param array $reg_step
801
-     * @param int   $order
802
-     * @return bool
803
-     */
804
-    private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0)
805
-    {
806
-        // we need a file_path, class_name, and slug to add a reg step
807
-        if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
808
-            // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
809
-            if (
810
-                $this->checkout->reg_url_link
811
-                && $this->checkout->step !== $reg_step['slug']
812
-                && $reg_step['slug'] !== 'finalize_registration'
813
-                // normally at this point we would NOT load the reg step, but this filter can change that
814
-                && apply_filters(
815
-                    'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
816
-                    true,
817
-                    $reg_step,
818
-                    $this->checkout
819
-                )
820
-            ) {
821
-                return true;
822
-            }
823
-            // instantiate step class using file path and class name
824
-            $reg_step_obj = EE_Registry::instance()->load_file(
825
-                $reg_step['file_path'],
826
-                $reg_step['class_name'],
827
-                'class',
828
-                $this->checkout,
829
-                false
830
-            );
831
-            // did we gets the goods ?
832
-            if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
833
-                // set reg step order based on config
834
-                $reg_step_obj->set_order($order);
835
-                // add instantiated reg step object to the master reg steps array
836
-                $this->checkout->add_reg_step($reg_step_obj);
837
-            } else {
838
-                EE_Error::add_error(
839
-                    __('The current step could not be set.', 'event_espresso'),
840
-                    __FILE__, __FUNCTION__, __LINE__
841
-                );
842
-                return false;
843
-            }
844
-        } else {
845
-            if (WP_DEBUG) {
846
-                EE_Error::add_error(
847
-                    sprintf(
848
-                        __(
849
-                            'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s',
850
-                            'event_espresso'
851
-                        ),
852
-                        isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
853
-                        isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
854
-                        isset($reg_step['slug']) ? $reg_step['slug'] : '',
855
-                        '<ul>',
856
-                        '<li>',
857
-                        '</li>',
858
-                        '</ul>'
859
-                    ),
860
-                    __FILE__, __FUNCTION__, __LINE__
861
-                );
862
-            }
863
-            return false;
864
-        }
865
-        return true;
866
-    }
867
-
868
-
869
-    /**
870
-     * _verify_transaction_and_get_registrations
871
-     *
872
-     * @access private
873
-     * @return bool
874
-     * @throws InvalidDataTypeException
875
-     * @throws InvalidEntityException
876
-     * @throws EE_Error
877
-     */
878
-    private function _verify_transaction_and_get_registrations()
879
-    {
880
-        // was there already a valid transaction in the checkout from the session ?
881
-        if ( ! $this->checkout->transaction instanceof EE_Transaction) {
882
-            // get transaction from db or session
883
-            $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
884
-                ? $this->_get_transaction_and_cart_for_previous_visit()
885
-                : $this->_get_cart_for_current_session_and_setup_new_transaction();
886
-            if ( ! $this->checkout->transaction instanceof EE_Transaction) {
887
-                EE_Error::add_error(
888
-                    __('Your Registration and Transaction information could not be retrieved from the db.',
889
-                        'event_espresso'),
890
-                    __FILE__, __FUNCTION__, __LINE__
891
-                );
892
-                $this->checkout->transaction = EE_Transaction::new_instance();
893
-                // add some style and make it dance
894
-                $this->add_styles_and_scripts();
895
-                EED_Single_Page_Checkout::$_initialized = true;
896
-                return false;
897
-            }
898
-            // and the registrations for the transaction
899
-            $this->_get_registrations($this->checkout->transaction);
900
-        }
901
-        return true;
902
-    }
903
-
904
-
905
-
906
-    /**
907
-     * _get_transaction_and_cart_for_previous_visit
908
-     *
909
-     * @access private
910
-     * @return mixed EE_Transaction|NULL
911
-     */
912
-    private function _get_transaction_and_cart_for_previous_visit()
913
-    {
914
-        /** @var $TXN_model EEM_Transaction */
915
-        $TXN_model = EE_Registry::instance()->load_model('Transaction');
916
-        // because the reg_url_link is present in the request,
917
-        // this is a return visit to SPCO, so we'll get the transaction data from the db
918
-        $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
919
-        // verify transaction
920
-        if ($transaction instanceof EE_Transaction) {
921
-            // and get the cart that was used for that transaction
922
-            $this->checkout->cart = $this->_get_cart_for_transaction($transaction);
923
-            return $transaction;
924
-        }
925
-        EE_Error::add_error(
926
-            __('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'),
927
-            __FILE__, __FUNCTION__, __LINE__
928
-        );
929
-        return null;
930
-
931
-    }
932
-
933
-
934
-
935
-    /**
936
-     * _get_cart_for_transaction
937
-     *
938
-     * @access private
939
-     * @param EE_Transaction $transaction
940
-     * @return EE_Cart
941
-     */
942
-    private function _get_cart_for_transaction($transaction)
943
-    {
944
-        return $this->checkout->get_cart_for_transaction($transaction);
945
-    }
946
-
947
-
948
-
949
-    /**
950
-     * get_cart_for_transaction
951
-     *
952
-     * @access public
953
-     * @param EE_Transaction $transaction
954
-     * @return EE_Cart
955
-     */
956
-    public function get_cart_for_transaction(EE_Transaction $transaction)
957
-    {
958
-        return $this->checkout->get_cart_for_transaction($transaction);
959
-    }
960
-
961
-
962
-
963
-    /**
964
-     * _get_transaction_and_cart_for_current_session
965
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
966
-     *
967
-     * @access private
968
-     * @return EE_Transaction
969
-     * @throws EE_Error
970
-     */
971
-    private function _get_cart_for_current_session_and_setup_new_transaction()
972
-    {
973
-        //  if there's no transaction, then this is the FIRST visit to SPCO
974
-        // so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
975
-        $this->checkout->cart = $this->_get_cart_for_transaction(null);
976
-        // and then create a new transaction
977
-        $transaction = $this->_initialize_transaction();
978
-        // verify transaction
979
-        if ($transaction instanceof EE_Transaction) {
980
-            // save it so that we have an ID for other objects to use
981
-            $transaction->save();
982
-            // and save TXN data to the cart
983
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
984
-        } else {
985
-            EE_Error::add_error(
986
-                __('A Valid Transaction could not be initialized.', 'event_espresso'),
987
-                __FILE__, __FUNCTION__, __LINE__
988
-            );
989
-        }
990
-        return $transaction;
991
-    }
992
-
993
-
994
-
995
-    /**
996
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
997
-     *
998
-     * @access private
999
-     * @return mixed EE_Transaction|NULL
1000
-     */
1001
-    private function _initialize_transaction()
1002
-    {
1003
-        try {
1004
-            // ensure cart totals have been calculated
1005
-            $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
1006
-            // grab the cart grand total
1007
-            $cart_total = $this->checkout->cart->get_cart_grand_total();
1008
-            // create new TXN
1009
-            $transaction = EE_Transaction::new_instance(
1010
-                array(
1011
-                    'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
1012
-                    'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
1013
-                    'TXN_paid'      => 0,
1014
-                    'STS_ID'        => EEM_Transaction::failed_status_code,
1015
-                )
1016
-            );
1017
-            // save it so that we have an ID for other objects to use
1018
-            $transaction->save();
1019
-            // set cron job for following up on TXNs after their session has expired
1020
-            EE_Cron_Tasks::schedule_expired_transaction_check(
1021
-                EE_Registry::instance()->SSN->expiration() + 1,
1022
-                $transaction->ID()
1023
-            );
1024
-            return $transaction;
1025
-        } catch (Exception $e) {
1026
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1027
-        }
1028
-        return null;
1029
-    }
1030
-
1031
-
1032
-    /**
1033
-     * _get_registrations
1034
-     *
1035
-     * @access private
1036
-     * @param EE_Transaction $transaction
1037
-     * @return void
1038
-     * @throws InvalidDataTypeException
1039
-     * @throws InvalidEntityException
1040
-     * @throws EE_Error
1041
-     */
1042
-    private function _get_registrations(EE_Transaction $transaction)
1043
-    {
1044
-        // first step: grab the registrants  { : o
1045
-        $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true);
1046
-        // verify registrations have been set
1047
-        if (empty($registrations)) {
1048
-            // if no cached registrations, then check the db
1049
-            $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
1050
-            // still nothing ? well as long as this isn't a revisit
1051
-            if (empty($registrations) && ! $this->checkout->revisit) {
1052
-                // generate new registrations from scratch
1053
-                $registrations = $this->_initialize_registrations($transaction);
1054
-            }
1055
-        }
1056
-        // sort by their original registration order
1057
-        usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1058
-        // then loop thru the array
1059
-        foreach ($registrations as $registration) {
1060
-            // verify each registration
1061
-            if ($registration instanceof EE_Registration) {
1062
-                // we display all attendee info for the primary registrant
1063
-                if ($this->checkout->reg_url_link === $registration->reg_url_link()
1064
-                    && $registration->is_primary_registrant()
1065
-                ) {
1066
-                    $this->checkout->primary_revisit = true;
1067
-                    break;
1068
-                }
1069
-                if ($this->checkout->revisit
1070
-                           && $this->checkout->reg_url_link !== $registration->reg_url_link()
1071
-                ) {
1072
-                    // but hide info if it doesn't belong to you
1073
-                    $transaction->clear_cache('Registration', $registration->ID());
1074
-                }
1075
-                $this->checkout->set_reg_status_updated($registration->ID(), false);
1076
-            }
1077
-        }
1078
-    }
1079
-
1080
-
1081
-    /**
1082
-     *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1083
-     *
1084
-     * @access private
1085
-     * @param EE_Transaction $transaction
1086
-     * @return    array
1087
-     * @throws InvalidDataTypeException
1088
-     * @throws InvalidEntityException
1089
-     * @throws EE_Error
1090
-     */
1091
-    private function _initialize_registrations(EE_Transaction $transaction)
1092
-    {
1093
-        $att_nmbr = 0;
1094
-        $registrations = array();
1095
-        if ($transaction instanceof EE_Transaction) {
1096
-            /** @type EE_Registration_Processor $registration_processor */
1097
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1098
-            $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1099
-            // now let's add the cart items to the $transaction
1100
-            foreach ($this->checkout->cart->get_tickets() as $line_item) {
1101
-                //do the following for each ticket of this type they selected
1102
-                for ($x = 1; $x <= $line_item->quantity(); $x++) {
1103
-                    $att_nmbr++;
1104
-                    /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1105
-                    $CreateRegistrationCommand = EE_Registry::instance()->create(
1106
-                        'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1107
-                        array(
1108
-                            $transaction,
1109
-                            $line_item,
1110
-                            $att_nmbr,
1111
-                            $this->checkout->total_ticket_count,
1112
-                        )
1113
-                    );
1114
-                    // override capabilities for frontend registrations
1115
-                    if ( ! is_admin()) {
1116
-                        $CreateRegistrationCommand->setCapCheck(
1117
-                            new PublicCapabilities('', 'create_new_registration')
1118
-                        );
1119
-                    }
1120
-                    $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1121
-                    if ( ! $registration instanceof EE_Registration) {
1122
-                        throw new InvalidEntityException($registration, 'EE_Registration');
1123
-                    }
1124
-                    $registrations[ $registration->ID() ] = $registration;
1125
-                }
1126
-            }
1127
-            $registration_processor->fix_reg_final_price_rounding_issue($transaction);
1128
-        }
1129
-        return $registrations;
1130
-    }
1131
-
1132
-
1133
-
1134
-    /**
1135
-     * sorts registrations by REG_count
1136
-     *
1137
-     * @access public
1138
-     * @param EE_Registration $reg_A
1139
-     * @param EE_Registration $reg_B
1140
-     * @return int
1141
-     */
1142
-    public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1143
-    {
1144
-        // this shouldn't ever happen within the same TXN, but oh well
1145
-        if ($reg_A->count() === $reg_B->count()) {
1146
-            return 0;
1147
-        }
1148
-        return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1149
-    }
1150
-
1151
-
1152
-
1153
-    /**
1154
-     *    _final_verifications
1155
-     * just makes sure that everything is set up correctly before proceeding
1156
-     *
1157
-     * @access    private
1158
-     * @return    bool
1159
-     * @throws EE_Error
1160
-     */
1161
-    private function _final_verifications()
1162
-    {
1163
-        // filter checkout
1164
-        $this->checkout = apply_filters(
1165
-            'FHEE__EED_Single_Page_Checkout___final_verifications__checkout',
1166
-            $this->checkout
1167
-        );
1168
-        //verify that current step is still set correctly
1169
-        if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1170
-            EE_Error::add_error(
1171
-                __('We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso'),
1172
-                __FILE__,
1173
-                __FUNCTION__,
1174
-                __LINE__
1175
-            );
1176
-            return false;
1177
-        }
1178
-        // if returning to SPCO, then verify that primary registrant is set
1179
-        if ( ! empty($this->checkout->reg_url_link)) {
1180
-            $valid_registrant = $this->checkout->transaction->primary_registration();
1181
-            if ( ! $valid_registrant instanceof EE_Registration) {
1182
-                EE_Error::add_error(
1183
-                    __('We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso'),
1184
-                    __FILE__,
1185
-                    __FUNCTION__,
1186
-                    __LINE__
1187
-                );
1188
-                return false;
1189
-            }
1190
-            $valid_registrant = null;
1191
-            foreach (
1192
-                $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration
1193
-            ) {
1194
-                if (
1195
-                    $registration instanceof EE_Registration
1196
-                    && $registration->reg_url_link() === $this->checkout->reg_url_link
1197
-                ) {
1198
-                    $valid_registrant = $registration;
1199
-                }
1200
-            }
1201
-            if ( ! $valid_registrant instanceof EE_Registration) {
1202
-                // hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1203
-                if (EED_Single_Page_Checkout::$_checkout_verified) {
1204
-                    // clear the session, mark the checkout as unverified, and try again
1205
-                    EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1206
-                    EED_Single_Page_Checkout::$_initialized = false;
1207
-                    EED_Single_Page_Checkout::$_checkout_verified = false;
1208
-                    $this->_initialize();
1209
-                    EE_Error::reset_notices();
1210
-                    return false;
1211
-                }
1212
-                EE_Error::add_error(
1213
-                    __(
1214
-                        'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.',
1215
-                        'event_espresso'
1216
-                    ),
1217
-                    __FILE__,
1218
-                    __FUNCTION__,
1219
-                    __LINE__
1220
-                );
1221
-                return false;
1222
-            }
1223
-        }
1224
-        // now that things have been kinda sufficiently verified,
1225
-        // let's add the checkout to the session so that it's available to other systems
1226
-        EE_Registry::instance()->SSN->set_checkout($this->checkout);
1227
-        return true;
1228
-    }
1229
-
1230
-
1231
-
1232
-    /**
1233
-     *    _initialize_reg_steps
1234
-     * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1235
-     * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1236
-     *
1237
-     * @access    private
1238
-     * @param bool $reinitializing
1239
-     * @throws EE_Error
1240
-     */
1241
-    private function _initialize_reg_steps($reinitializing = false)
1242
-    {
1243
-        $this->checkout->set_reg_step_initiated($this->checkout->current_step);
1244
-        // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1245
-        foreach ($this->checkout->reg_steps as $reg_step) {
1246
-            if ( ! $reg_step->initialize_reg_step()) {
1247
-                // if not initialized then maybe this step is being removed...
1248
-                if ( ! $reinitializing && $reg_step->is_current_step()) {
1249
-                    // if it was the current step, then we need to start over here
1250
-                    $this->_initialize_reg_steps(true);
1251
-                    return;
1252
-                }
1253
-                continue;
1254
-            }
1255
-            // add css and JS for current step
1256
-            $reg_step->enqueue_styles_and_scripts();
1257
-            // i18n
1258
-            $reg_step->translate_js_strings();
1259
-            if ($reg_step->is_current_step()) {
1260
-                // the text that appears on the reg step form submit button
1261
-                $reg_step->set_submit_button_text();
1262
-            }
1263
-        }
1264
-        // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1265
-        do_action(
1266
-            "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}",
1267
-            $this->checkout->current_step
1268
-        );
1269
-    }
1270
-
1271
-
1272
-
1273
-    /**
1274
-     * _check_form_submission
1275
-     *
1276
-     * @access private
1277
-     * @return boolean
1278
-     */
1279
-    private function _check_form_submission()
1280
-    {
1281
-        //does this request require the reg form to be generated ?
1282
-        if ($this->checkout->generate_reg_form) {
1283
-            // ever heard that song by Blue Rodeo ?
1284
-            try {
1285
-                $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1286
-                // if not displaying a form, then check for form submission
1287
-                if (
1288
-                    $this->checkout->process_form_submission
1289
-                    && $this->checkout->current_step->reg_form->was_submitted()
1290
-                ) {
1291
-                    // clear out any old data in case this step is being run again
1292
-                    $this->checkout->current_step->set_valid_data(array());
1293
-                    // capture submitted form data
1294
-                    $this->checkout->current_step->reg_form->receive_form_submission(
1295
-                        apply_filters(
1296
-                            'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1297
-                            EE_Registry::instance()->REQ->params(),
1298
-                            $this->checkout
1299
-                        )
1300
-                    );
1301
-                    // validate submitted form data
1302
-                    if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1303
-                        // thou shall not pass !!!
1304
-                        $this->checkout->continue_reg = false;
1305
-                        // any form validation errors?
1306
-                        if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1307
-                            $submission_error_messages = array();
1308
-                            // bad, bad, bad registrant
1309
-                            foreach (
1310
-                                $this->checkout->current_step->reg_form->get_validation_errors_accumulated()
1311
-                                as $validation_error
1312
-                            ) {
1313
-                                if ($validation_error instanceof EE_Validation_Error) {
1314
-                                    $submission_error_messages[] = sprintf(
1315
-                                        __('%s : %s', 'event_espresso'),
1316
-                                        $validation_error->get_form_section()->html_label_text(),
1317
-                                        $validation_error->getMessage()
1318
-                                    );
1319
-                                }
1320
-                            }
1321
-                            EE_Error::add_error(
1322
-                                implode('<br />', $submission_error_messages),
1323
-                                __FILE__, __FUNCTION__, __LINE__
1324
-                            );
1325
-                        }
1326
-                        // well not really... what will happen is
1327
-                        // we'll just get redirected back to redo the current step
1328
-                        $this->go_to_next_step();
1329
-                        return false;
1330
-                    }
1331
-                }
1332
-            } catch (EE_Error $e) {
1333
-                $e->get_error();
1334
-            }
1335
-        }
1336
-        return true;
1337
-    }
1338
-
1339
-
1340
-
1341
-    /**
1342
-     * _process_action
1343
-     *
1344
-     * @access private
1345
-     * @return void
1346
-     * @throws EE_Error
1347
-     */
1348
-    private function _process_form_action()
1349
-    {
1350
-        // what cha wanna do?
1351
-        switch ($this->checkout->action) {
1352
-            // AJAX next step reg form
1353
-            case 'display_spco_reg_step' :
1354
-                $this->checkout->redirect = false;
1355
-                if (EE_Registry::instance()->REQ->ajax) {
1356
-                    $this->checkout->json_response->set_reg_step_html(
1357
-                        $this->checkout->current_step->display_reg_form()
1358
-                    );
1359
-                }
1360
-                break;
1361
-            default :
1362
-                // meh... do one of those other steps first
1363
-                if (
1364
-                    ! empty($this->checkout->action)
1365
-                    && is_callable(array($this->checkout->current_step, $this->checkout->action))
1366
-                ) {
1367
-                    // dynamically creates hook point like:
1368
-                    //   AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1369
-                    do_action(
1370
-                        "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1371
-                        $this->checkout->current_step
1372
-                    );
1373
-                    // call action on current step
1374
-                    if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1375
-                        // good registrant, you get to proceed
1376
-                        if (
1377
-                            $this->checkout->current_step->success_message() !== ''
1378
-                            && apply_filters(
1379
-                                'FHEE__Single_Page_Checkout___process_form_action__display_success',
1380
-                                false
1381
-                            )
1382
-                        ) {
1383
-                            EE_Error::add_success(
1384
-                                $this->checkout->current_step->success_message()
1385
-                                . '<br />' . $this->checkout->next_step->_instructions()
1386
-                            );
1387
-                        }
1388
-                        // pack it up, pack it in...
1389
-                        $this->_setup_redirect();
1390
-                    }
1391
-                    // dynamically creates hook point like:
1392
-                    //  AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1393
-                    do_action(
1394
-                        "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1395
-                        $this->checkout->current_step
1396
-                    );
1397
-                } else {
1398
-                    EE_Error::add_error(
1399
-                        sprintf(
1400
-                            __(
1401
-                                'The requested form action "%s" does not exist for the current "%s" registration step.',
1402
-                                'event_espresso'
1403
-                            ),
1404
-                            $this->checkout->action,
1405
-                            $this->checkout->current_step->name()
1406
-                        ),
1407
-                        __FILE__,
1408
-                        __FUNCTION__,
1409
-                        __LINE__
1410
-                    );
1411
-                }
1412
-            // end default
1413
-        }
1414
-        // store our progress so far
1415
-        $this->checkout->stash_transaction_and_checkout();
1416
-        // advance to the next step! If you pass GO, collect $200
1417
-        $this->go_to_next_step();
1418
-    }
1419
-
1420
-
1421
-
1422
-    /**
1423
-     *        add_styles_and_scripts
1424
-     *
1425
-     * @access        public
1426
-     * @return        void
1427
-     */
1428
-    public function add_styles_and_scripts()
1429
-    {
1430
-        // i18n
1431
-        $this->translate_js_strings();
1432
-        if ($this->checkout->admin_request) {
1433
-            add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1434
-        } else {
1435
-            add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1436
-        }
1437
-    }
1438
-
1439
-
1440
-
1441
-    /**
1442
-     *        translate_js_strings
1443
-     *
1444
-     * @access        public
1445
-     * @return        void
1446
-     */
1447
-    public function translate_js_strings()
1448
-    {
1449
-        EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1450
-        EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1451
-        EE_Registry::$i18n_js_strings['server_error'] = __(
1452
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
1453
-            'event_espresso'
1454
-        );
1455
-        EE_Registry::$i18n_js_strings['invalid_json_response'] = __(
1456
-            'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.',
1457
-            'event_espresso'
1458
-        );
1459
-        EE_Registry::$i18n_js_strings['validation_error'] = __(
1460
-            'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.',
1461
-            'event_espresso'
1462
-        );
1463
-        EE_Registry::$i18n_js_strings['invalid_payment_method'] = __(
1464
-            'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.',
1465
-            'event_espresso'
1466
-        );
1467
-        EE_Registry::$i18n_js_strings['reg_step_error'] = __(
1468
-            'This registration step could not be completed. Please refresh the page and try again.',
1469
-            'event_espresso'
1470
-        );
1471
-        EE_Registry::$i18n_js_strings['invalid_coupon'] = __(
1472
-            'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.',
1473
-            'event_espresso'
1474
-        );
1475
-        EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1476
-            __(
1477
-                'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.',
1478
-                'event_espresso'
1479
-            ),
1480
-            '<br/>',
1481
-            '<br/>'
1482
-        );
1483
-        EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1484
-        EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1485
-        EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1486
-        EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1487
-        EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1488
-        EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1489
-        EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1490
-        EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1491
-        EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1492
-        EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1493
-        EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1494
-        EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1495
-        EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1496
-        EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1497
-        EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1498
-        EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1499
-        EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1500
-        EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1501
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1502
-            __(
1503
-                '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
1504
-                'event_espresso'
1505
-            ),
1506
-            '<h4 class="important-notice">',
1507
-            '</h4>',
1508
-            '<br />',
1509
-            '<p>',
1510
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1511
-            '">',
1512
-            '</a>',
1513
-            '</p>'
1514
-        );
1515
-        EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters(
1516
-            'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
1517
-            true
1518
-        );
1519
-        EE_Registry::$i18n_js_strings['session_extension'] = absint(
1520
-            apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1521
-        );
1522
-        EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1523
-            'M d, Y H:i:s',
1524
-            EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1525
-        );
1526
-    }
1527
-
1528
-
1529
-
1530
-    /**
1531
-     *    enqueue_styles_and_scripts
1532
-     *
1533
-     * @access        public
1534
-     * @return        void
1535
-     * @throws EE_Error
1536
-     */
1537
-    public function enqueue_styles_and_scripts()
1538
-    {
1539
-        // load css
1540
-        wp_register_style(
1541
-            'single_page_checkout',
1542
-            SPCO_CSS_URL . 'single_page_checkout.css',
1543
-            array('espresso_default'),
1544
-            EVENT_ESPRESSO_VERSION
1545
-        );
1546
-        wp_enqueue_style('single_page_checkout');
1547
-        // load JS
1548
-        wp_register_script(
1549
-            'jquery_plugin',
1550
-            EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1551
-            array('jquery'),
1552
-            '1.0.1',
1553
-            true
1554
-        );
1555
-        wp_register_script(
1556
-            'jquery_countdown',
1557
-            EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1558
-            array('jquery_plugin'),
1559
-            '2.0.2',
1560
-            true
1561
-        );
1562
-        wp_register_script(
1563
-            'single_page_checkout',
1564
-            SPCO_JS_URL . 'single_page_checkout.js',
1565
-            array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1566
-            EVENT_ESPRESSO_VERSION,
1567
-            true
1568
-        );
1569
-        if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1570
-            $this->checkout->registration_form->enqueue_js();
1571
-        }
1572
-        if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1573
-            $this->checkout->current_step->reg_form->enqueue_js();
1574
-        }
1575
-        wp_enqueue_script('single_page_checkout');
1576
-        /**
1577
-         * global action hook for enqueueing styles and scripts with
1578
-         * spco calls.
1579
-         */
1580
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1581
-        /**
1582
-         * dynamic action hook for enqueueing styles and scripts with spco calls.
1583
-         * The hook will end up being something like:
1584
-         *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1585
-         */
1586
-        do_action(
1587
-            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1588
-            $this
1589
-        );
1590
-    }
1591
-
1592
-
1593
-
1594
-    /**
1595
-     *    display the Registration Single Page Checkout Form
1596
-     *
1597
-     * @access    private
1598
-     * @return    void
1599
-     * @throws EE_Error
1600
-     */
1601
-    private function _display_spco_reg_form()
1602
-    {
1603
-        // if registering via the admin, just display the reg form for the current step
1604
-        if ($this->checkout->admin_request) {
1605
-            EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1606
-        } else {
1607
-            // add powered by EE msg
1608
-            add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1609
-            $empty_cart = count(
1610
-                $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)
1611
-            ) < 1;
1612
-            EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1613
-            $cookies_not_set_msg = '';
1614
-            if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1615
-                $cookies_not_set_msg = apply_filters(
1616
-                    'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1617
-                    sprintf(
1618
-                        __(
1619
-                            '%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s',
1620
-                            'event_espresso'
1621
-                        ),
1622
-                        '<div class="ee-attention">',
1623
-                        '</div>',
1624
-                        '<h6 class="important-notice">',
1625
-                        '</h6>',
1626
-                        '<p>',
1627
-                        '</p>',
1628
-                        '<br />',
1629
-                        '<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1630
-                        '</a>'
1631
-                    )
1632
-                );
1633
-            }
1634
-            $this->checkout->registration_form = new EE_Form_Section_Proper(
1635
-                array(
1636
-                    'name'            => 'single-page-checkout',
1637
-                    'html_id'         => 'ee-single-page-checkout-dv',
1638
-                    'layout_strategy' =>
1639
-                        new EE_Template_Layout(
1640
-                            array(
1641
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1642
-                                'template_args'        => array(
1643
-                                    'empty_cart'              => $empty_cart,
1644
-                                    'revisit'                 => $this->checkout->revisit,
1645
-                                    'reg_steps'               => $this->checkout->reg_steps,
1646
-                                    'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1647
-                                        ? $this->checkout->next_step->slug()
1648
-                                        : '',
1649
-                                    'cancel_page_url'         => $this->checkout->cancel_page_url,
1650
-                                    'empty_msg'               => apply_filters(
1651
-                                        'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1652
-                                        sprintf(
1653
-                                            __(
1654
-                                                'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1655
-                                                'event_espresso'
1656
-                                            ),
1657
-                                            '<a href="'
1658
-                                            . get_post_type_archive_link('espresso_events')
1659
-                                            . '" title="',
1660
-                                            '">',
1661
-                                            '</a>'
1662
-                                        )
1663
-                                    ),
1664
-                                    'cookies_not_set_msg'     => $cookies_not_set_msg,
1665
-                                    'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1666
-                                    'session_expiration'      => gmdate(
1667
-                                        'M d, Y H:i:s',
1668
-                                        EE_Registry::instance()->SSN->expiration()
1669
-                                        + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1670
-                                    ),
1671
-                                ),
1672
-                            )
1673
-                        ),
1674
-                )
1675
-            );
1676
-            // load template and add to output sent that gets filtered into the_content()
1677
-            EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1678
-        }
1679
-    }
1680
-
1681
-
1682
-
1683
-    /**
1684
-     *    add_extra_finalize_registration_inputs
1685
-     *
1686
-     * @access    public
1687
-     * @param $next_step
1688
-     * @internal  param string $label
1689
-     * @return void
1690
-     */
1691
-    public function add_extra_finalize_registration_inputs($next_step)
1692
-    {
1693
-        if ($next_step === 'finalize_registration') {
1694
-            echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1695
-        }
1696
-    }
1697
-
1698
-
1699
-
1700
-    /**
1701
-     *    display_registration_footer
1702
-     *
1703
-     * @access    public
1704
-     * @return    string
1705
-     */
1706
-    public static function display_registration_footer()
1707
-    {
1708
-        if (
1709
-        apply_filters(
1710
-            'FHEE__EE_Front__Controller__show_reg_footer',
1711
-            EE_Registry::instance()->CFG->admin->show_reg_footer
1712
-        )
1713
-        ) {
1714
-            add_filter(
1715
-                'FHEE__EEH_Template__powered_by_event_espresso__url',
1716
-                function ($url) {
1717
-                    return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1718
-                }
1719
-            );
1720
-            echo apply_filters(
1721
-                'FHEE__EE_Front_Controller__display_registration_footer',
1722
-                \EEH_Template::powered_by_event_espresso(
1723
-                    '',
1724
-                    'espresso-registration-footer-dv',
1725
-                    array('utm_content' => 'registration_checkout')
1726
-                )
1727
-            );
1728
-        }
1729
-        return '';
1730
-    }
1731
-
1732
-
1733
-
1734
-    /**
1735
-     *    unlock_transaction
1736
-     *
1737
-     * @access    public
1738
-     * @return    void
1739
-     * @throws EE_Error
1740
-     */
1741
-    public function unlock_transaction()
1742
-    {
1743
-        if ($this->checkout->transaction instanceof EE_Transaction) {
1744
-            $this->checkout->transaction->unlock();
1745
-        }
1746
-    }
1747
-
1748
-
1749
-
1750
-    /**
1751
-     *        _setup_redirect
1752
-     *
1753
-     * @access    private
1754
-     * @return void
1755
-     */
1756
-    private function _setup_redirect()
1757
-    {
1758
-        if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1759
-            $this->checkout->redirect = true;
1760
-            if (empty($this->checkout->redirect_url)) {
1761
-                $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1762
-            }
1763
-            $this->checkout->redirect_url = apply_filters(
1764
-                'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1765
-                $this->checkout->redirect_url,
1766
-                $this->checkout
1767
-            );
1768
-        }
1769
-    }
1770
-
1771
-
1772
-
1773
-    /**
1774
-     *   handle ajax message responses and redirects
1775
-     *
1776
-     * @access public
1777
-     * @return void
1778
-     * @throws EE_Error
1779
-     */
1780
-    public function go_to_next_step()
1781
-    {
1782
-        if (EE_Registry::instance()->REQ->ajax) {
1783
-            // capture contents of output buffer we started earlier in the request, and insert into JSON response
1784
-            $this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1785
-        }
1786
-        $this->unlock_transaction();
1787
-        // just return for these conditions
1788
-        if (
1789
-            $this->checkout->admin_request
1790
-            || $this->checkout->action === 'redirect_form'
1791
-            || $this->checkout->action === 'update_checkout'
1792
-        ) {
1793
-            return;
1794
-        }
1795
-        // AJAX response
1796
-        $this->_handle_json_response();
1797
-        // redirect to next step or the Thank You page
1798
-        $this->_handle_html_redirects();
1799
-        // hmmm... must be something wrong, so let's just display the form again !
1800
-        $this->_display_spco_reg_form();
1801
-    }
1802
-
1803
-
1804
-
1805
-    /**
1806
-     *   _handle_json_response
1807
-     *
1808
-     * @access protected
1809
-     * @return void
1810
-     */
1811
-    protected function _handle_json_response()
1812
-    {
1813
-        // if this is an ajax request
1814
-        if (EE_Registry::instance()->REQ->ajax) {
1815
-            // DEBUG LOG
1816
-            //$this->checkout->log(
1817
-            //	__CLASS__, __FUNCTION__, __LINE__,
1818
-            //	array(
1819
-            //		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1820
-            //		'redirect'                   => $this->checkout->redirect,
1821
-            //		'continue_reg'               => $this->checkout->continue_reg,
1822
-            //	)
1823
-            //);
1824
-            $this->checkout->json_response->set_registration_time_limit(
1825
-                $this->checkout->get_registration_time_limit()
1826
-            );
1827
-            $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1828
-            // just send the ajax (
1829
-            $json_response = apply_filters(
1830
-                'FHEE__EE_Single_Page_Checkout__JSON_response',
1831
-                $this->checkout->json_response
1832
-            );
1833
-            echo $json_response;
1834
-            exit();
1835
-        }
1836
-    }
1837
-
1838
-
1839
-
1840
-    /**
1841
-     *   _handle_redirects
1842
-     *
1843
-     * @access protected
1844
-     * @return void
1845
-     */
1846
-    protected function _handle_html_redirects()
1847
-    {
1848
-        // going somewhere ?
1849
-        if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1850
-            // store notices in a transient
1851
-            EE_Error::get_notices(false, true, true);
1852
-            // DEBUG LOG
1853
-            //$this->checkout->log(
1854
-            //	__CLASS__, __FUNCTION__, __LINE__,
1855
-            //	array(
1856
-            //		'headers_sent' => headers_sent(),
1857
-            //		'redirect_url'     => $this->checkout->redirect_url,
1858
-            //		'headers_list'    => headers_list(),
1859
-            //	)
1860
-            //);
1861
-            wp_safe_redirect($this->checkout->redirect_url);
1862
-            exit();
1863
-        }
1864
-    }
1865
-
1866
-
1867
-
1868
-    /**
1869
-     *   set_checkout_anchor
1870
-     *
1871
-     * @access public
1872
-     * @return void
1873
-     */
1874
-    public function set_checkout_anchor()
1875
-    {
1876
-        echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1877
-    }
23
+	/**
24
+	 * $_initialized - has the SPCO controller already been initialized ?
25
+	 *
26
+	 * @access private
27
+	 * @var bool $_initialized
28
+	 */
29
+	private static $_initialized = false;
30
+
31
+
32
+	/**
33
+	 * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
34
+	 *
35
+	 * @access private
36
+	 * @var bool $_valid_checkout
37
+	 */
38
+	private static $_checkout_verified = true;
39
+
40
+	/**
41
+	 *    $_reg_steps_array - holds initial array of reg steps
42
+	 *
43
+	 * @access private
44
+	 * @var array $_reg_steps_array
45
+	 */
46
+	private static $_reg_steps_array = array();
47
+
48
+	/**
49
+	 *    $checkout - EE_Checkout object for handling the properties of the current checkout process
50
+	 *
51
+	 * @access public
52
+	 * @var EE_Checkout $checkout
53
+	 */
54
+	public $checkout;
55
+
56
+
57
+
58
+	/**
59
+	 * @return EED_Module|EED_Single_Page_Checkout
60
+	 */
61
+	public static function instance()
62
+	{
63
+		add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
64
+		return parent::get_instance(__CLASS__);
65
+	}
66
+
67
+
68
+
69
+	/**
70
+	 * @return EE_CART
71
+	 */
72
+	public function cart()
73
+	{
74
+		return $this->checkout->cart;
75
+	}
76
+
77
+
78
+
79
+	/**
80
+	 * @return EE_Transaction
81
+	 */
82
+	public function transaction()
83
+	{
84
+		return $this->checkout->transaction;
85
+	}
86
+
87
+
88
+
89
+	/**
90
+	 *    set_hooks - for hooking into EE Core, other modules, etc
91
+	 *
92
+	 * @access    public
93
+	 * @return    void
94
+	 * @throws EE_Error
95
+	 */
96
+	public static function set_hooks()
97
+	{
98
+		EED_Single_Page_Checkout::set_definitions();
99
+	}
100
+
101
+
102
+
103
+	/**
104
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
105
+	 *
106
+	 * @access    public
107
+	 * @return    void
108
+	 * @throws EE_Error
109
+	 */
110
+	public static function set_hooks_admin()
111
+	{
112
+		EED_Single_Page_Checkout::set_definitions();
113
+		if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
114
+			return;
115
+		}
116
+		// going to start an output buffer in case anything gets accidentally output
117
+		// that might disrupt our JSON response
118
+		ob_start();
119
+		EED_Single_Page_Checkout::load_request_handler();
120
+		EED_Single_Page_Checkout::load_reg_steps();
121
+		// set ajax hooks
122
+		add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
123
+		add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
124
+		add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
125
+		add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
126
+		add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
127
+		add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
128
+	}
129
+
130
+
131
+
132
+	/**
133
+	 *    process ajax request
134
+	 *
135
+	 * @param string $ajax_action
136
+	 * @throws EE_Error
137
+	 */
138
+	public static function process_ajax_request($ajax_action)
139
+	{
140
+		EE_Registry::instance()->REQ->set('action', $ajax_action);
141
+		EED_Single_Page_Checkout::instance()->_initialize();
142
+	}
143
+
144
+
145
+
146
+	/**
147
+	 *    ajax display registration step
148
+	 *
149
+	 * @throws EE_Error
150
+	 */
151
+	public static function display_reg_step()
152
+	{
153
+		EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
154
+	}
155
+
156
+
157
+
158
+	/**
159
+	 *    ajax process registration step
160
+	 *
161
+	 * @throws EE_Error
162
+	 */
163
+	public static function process_reg_step()
164
+	{
165
+		EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
166
+	}
167
+
168
+
169
+
170
+	/**
171
+	 *    ajax process registration step
172
+	 *
173
+	 * @throws EE_Error
174
+	 */
175
+	public static function update_reg_step()
176
+	{
177
+		EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
178
+	}
179
+
180
+
181
+
182
+	/**
183
+	 *   update_checkout
184
+	 *
185
+	 * @access public
186
+	 * @return void
187
+	 * @throws EE_Error
188
+	 */
189
+	public static function update_checkout()
190
+	{
191
+		EED_Single_Page_Checkout::process_ajax_request('update_checkout');
192
+	}
193
+
194
+
195
+
196
+	/**
197
+	 *    load_request_handler
198
+	 *
199
+	 * @access    public
200
+	 * @return    void
201
+	 */
202
+	public static function load_request_handler()
203
+	{
204
+		// load core Request_Handler class
205
+		if (EE_Registry::instance()->REQ !== null) {
206
+			EE_Registry::instance()->load_core('Request_Handler');
207
+		}
208
+	}
209
+
210
+
211
+
212
+	/**
213
+	 *    set_definitions
214
+	 *
215
+	 * @access    public
216
+	 * @return    void
217
+	 * @throws EE_Error
218
+	 */
219
+	public static function set_definitions()
220
+	{
221
+		if(defined('SPCO_BASE_PATH')) {
222
+			return;
223
+		}
224
+		define(
225
+			'SPCO_BASE_PATH',
226
+			rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
227
+		);
228
+		define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
+		define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
+		define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
+		define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
+		define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
+		define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
234
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236
+			__('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
237
+				'event_espresso'),
238
+			'<h4 class="important-notice">',
239
+			'</h4>',
240
+			'<br />',
241
+			'<p>',
242
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
243
+			'">',
244
+			'</a>',
245
+			'</p>'
246
+		);
247
+	}
248
+
249
+
250
+
251
+	/**
252
+	 * load_reg_steps
253
+	 * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
254
+	 *
255
+	 * @access    private
256
+	 * @throws EE_Error
257
+	 */
258
+	public static function load_reg_steps()
259
+	{
260
+		static $reg_steps_loaded = false;
261
+		if ($reg_steps_loaded) {
262
+			return;
263
+		}
264
+		// filter list of reg_steps
265
+		$reg_steps_to_load = (array)apply_filters(
266
+			'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267
+			EED_Single_Page_Checkout::get_reg_steps()
268
+		);
269
+		// sort by key (order)
270
+		ksort($reg_steps_to_load);
271
+		// loop through folders
272
+		foreach ($reg_steps_to_load as $order => $reg_step) {
273
+			// we need a
274
+			if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
275
+				// copy over to the reg_steps_array
276
+				EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step;
277
+				// register custom key route for each reg step
278
+				// ie: step=>"slug" - this is the entire reason we load the reg steps array now
279
+				EE_Config::register_route(
280
+					$reg_step['slug'],
281
+					'EED_Single_Page_Checkout',
282
+					'run',
283
+					'step'
284
+				);
285
+				// add AJAX or other hooks
286
+				if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
287
+					// setup autoloaders if necessary
288
+					if ( ! class_exists($reg_step['class_name'])) {
289
+						EEH_Autoloader::register_autoloaders_for_each_file_in_folder(
290
+							$reg_step['file_path'],
291
+							true
292
+						);
293
+					}
294
+					if (is_callable($reg_step['class_name'], 'set_hooks')) {
295
+						call_user_func(array($reg_step['class_name'], 'set_hooks'));
296
+					}
297
+				}
298
+			}
299
+		}
300
+		$reg_steps_loaded = true;
301
+	}
302
+
303
+
304
+
305
+	/**
306
+	 *    get_reg_steps
307
+	 *
308
+	 * @access    public
309
+	 * @return    array
310
+	 */
311
+	public static function get_reg_steps()
312
+	{
313
+		$reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
314
+		if (empty($reg_steps)) {
315
+			$reg_steps = array(
316
+				10  => array(
317
+					'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
318
+					'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319
+					'slug'       => 'attendee_information',
320
+					'has_hooks'  => false,
321
+				),
322
+				20  => array(
323
+					'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
324
+					'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325
+					'slug'       => 'registration_confirmation',
326
+					'has_hooks'  => false,
327
+				),
328
+				30  => array(
329
+					'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
330
+					'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331
+					'slug'       => 'payment_options',
332
+					'has_hooks'  => true,
333
+				),
334
+				999 => array(
335
+					'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
336
+					'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337
+					'slug'       => 'finalize_registration',
338
+					'has_hooks'  => false,
339
+				),
340
+			);
341
+		}
342
+		return $reg_steps;
343
+	}
344
+
345
+
346
+
347
+	/**
348
+	 *    registration_checkout_for_admin
349
+	 *
350
+	 * @access    public
351
+	 * @return    string
352
+	 * @throws EE_Error
353
+	 */
354
+	public static function registration_checkout_for_admin()
355
+	{
356
+		EED_Single_Page_Checkout::load_request_handler();
357
+		EE_Registry::instance()->REQ->set('step', 'attendee_information');
358
+		EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step');
359
+		EE_Registry::instance()->REQ->set('process_form_submission', false);
360
+		EED_Single_Page_Checkout::instance()->_initialize();
361
+		EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
362
+		return EE_Registry::instance()->REQ->get_output();
363
+	}
364
+
365
+
366
+
367
+	/**
368
+	 * process_registration_from_admin
369
+	 *
370
+	 * @access public
371
+	 * @return \EE_Transaction
372
+	 * @throws EE_Error
373
+	 */
374
+	public static function process_registration_from_admin()
375
+	{
376
+		EED_Single_Page_Checkout::load_request_handler();
377
+		EE_Registry::instance()->REQ->set('step', 'attendee_information');
378
+		EE_Registry::instance()->REQ->set('action', 'process_reg_step');
379
+		EE_Registry::instance()->REQ->set('process_form_submission', true);
380
+		EED_Single_Page_Checkout::instance()->_initialize();
381
+		if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
382
+			$final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
383
+			if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
384
+				EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
385
+				if ($final_reg_step->process_reg_step()) {
386
+					$final_reg_step->set_completed();
387
+					EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
388
+					return EED_Single_Page_Checkout::instance()->checkout->transaction;
389
+				}
390
+			}
391
+		}
392
+		return null;
393
+	}
394
+
395
+
396
+
397
+	/**
398
+	 *    run
399
+	 *
400
+	 * @access    public
401
+	 * @param WP_Query $WP_Query
402
+	 * @return    void
403
+	 * @throws EE_Error
404
+	 */
405
+	public function run($WP_Query)
406
+	{
407
+		if (
408
+			$WP_Query instanceof WP_Query
409
+			&& $WP_Query->is_main_query()
410
+			&& apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
411
+			&& $this->_is_reg_checkout()
412
+		) {
413
+			$this->_initialize();
414
+		}
415
+	}
416
+
417
+
418
+
419
+	/**
420
+	 * determines whether current url matches reg page url
421
+	 *
422
+	 * @return bool
423
+	 */
424
+	protected function _is_reg_checkout()
425
+	{
426
+		// get current permalink for reg page without any extra query args
427
+		$reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id);
428
+		// get request URI for current request, but without the scheme or host
429
+		$current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI');
430
+		$current_request_uri = html_entity_decode($current_request_uri);
431
+		// get array of query args from the current request URI
432
+		$query_args = \EEH_URL::get_query_string($current_request_uri);
433
+		// grab page id if it is set
434
+		$page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
435
+		// and remove the page id from the query args (we will re-add it later)
436
+		unset($query_args['page_id']);
437
+		// now strip all query args from current request URI
438
+		$current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
439
+		// and re-add the page id if it was set
440
+		if ($page_id) {
441
+			$current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
442
+		}
443
+		// remove slashes and ?
444
+		$current_request_uri = trim($current_request_uri, '?/');
445
+		// is current request URI part of the known full reg page URL ?
446
+		return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
447
+	}
448
+
449
+
450
+
451
+	/**
452
+	 * @param WP_Query $wp_query
453
+	 * @return    void
454
+	 * @throws EE_Error
455
+	 */
456
+	public static function init($wp_query)
457
+	{
458
+		EED_Single_Page_Checkout::instance()->run($wp_query);
459
+	}
460
+
461
+
462
+
463
+	/**
464
+	 *    _initialize - initial module setup
465
+	 *
466
+	 * @access    private
467
+	 * @throws EE_Error
468
+	 * @return    void
469
+	 */
470
+	private function _initialize()
471
+	{
472
+		// ensure SPCO doesn't run twice
473
+		if (EED_Single_Page_Checkout::$_initialized) {
474
+			return;
475
+		}
476
+		try {
477
+			EED_Single_Page_Checkout::load_reg_steps();
478
+			$this->_verify_session();
479
+			// setup the EE_Checkout object
480
+			$this->checkout = $this->_initialize_checkout();
481
+			// filter checkout
482
+			$this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
483
+			// get the $_GET
484
+			$this->_get_request_vars();
485
+			if ($this->_block_bots()) {
486
+				return;
487
+			}
488
+			// filter continue_reg
489
+			$this->checkout->continue_reg = apply_filters(
490
+				'FHEE__EED_Single_Page_Checkout__init___continue_reg',
491
+				true,
492
+				$this->checkout
493
+			);
494
+			// load the reg steps array
495
+			if ( ! $this->_load_and_instantiate_reg_steps()) {
496
+				EED_Single_Page_Checkout::$_initialized = true;
497
+				return;
498
+			}
499
+			// set the current step
500
+			$this->checkout->set_current_step($this->checkout->step);
501
+			// and the next step
502
+			$this->checkout->set_next_step();
503
+			// verify that everything has been setup correctly
504
+			if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
505
+				EED_Single_Page_Checkout::$_initialized = true;
506
+				return;
507
+			}
508
+			// lock the transaction
509
+			$this->checkout->transaction->lock();
510
+			// make sure all of our cached objects are added to their respective model entity mappers
511
+			$this->checkout->refresh_all_entities();
512
+			// set amount owing
513
+			$this->checkout->amount_owing = $this->checkout->transaction->remaining();
514
+			// initialize each reg step, which gives them the chance to potentially alter the process
515
+			$this->_initialize_reg_steps();
516
+			// DEBUG LOG
517
+			//$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
518
+			// get reg form
519
+			if( ! $this->_check_form_submission()) {
520
+				EED_Single_Page_Checkout::$_initialized = true;
521
+				return;
522
+			}
523
+			// checkout the action!!!
524
+			$this->_process_form_action();
525
+			// add some style and make it dance
526
+			$this->add_styles_and_scripts();
527
+			// kk... SPCO has successfully run
528
+			EED_Single_Page_Checkout::$_initialized = true;
529
+			// set no cache headers and constants
530
+			EE_System::do_not_cache();
531
+			// add anchor
532
+			add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
533
+			// remove transaction lock
534
+			add_action('shutdown', array($this, 'unlock_transaction'), 1);
535
+		} catch (Exception $e) {
536
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
537
+		}
538
+	}
539
+
540
+
541
+
542
+	/**
543
+	 *    _verify_session
544
+	 * checks that the session is valid and not expired
545
+	 *
546
+	 * @access    private
547
+	 * @throws EE_Error
548
+	 */
549
+	private function _verify_session()
550
+	{
551
+		if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
552
+			throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
553
+		}
554
+		$clear_session_requested = filter_var(
555
+			EE_Registry::instance()->REQ->get('clear_session', false),
556
+			FILTER_VALIDATE_BOOLEAN
557
+		);
558
+		// is session still valid ?
559
+		if ($clear_session_requested
560
+			|| ( EE_Registry::instance()->SSN->expired()
561
+			  && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === ''
562
+			)
563
+		) {
564
+			$this->checkout = new EE_Checkout();
565
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
566
+			// EE_Registry::instance()->SSN->reset_cart();
567
+			// EE_Registry::instance()->SSN->reset_checkout();
568
+			// EE_Registry::instance()->SSN->reset_transaction();
569
+			if (! $clear_session_requested) {
570
+				EE_Error::add_attention(
571
+					EE_Registry::$i18n_js_strings['registration_expiration_notice'],
572
+					__FILE__, __FUNCTION__, __LINE__
573
+				);
574
+			}
575
+			// EE_Registry::instance()->SSN->reset_expired();
576
+		}
577
+	}
578
+
579
+
580
+
581
+	/**
582
+	 *    _initialize_checkout
583
+	 * loads and instantiates EE_Checkout
584
+	 *
585
+	 * @access    private
586
+	 * @throws EE_Error
587
+	 * @return EE_Checkout
588
+	 */
589
+	private function _initialize_checkout()
590
+	{
591
+		// look in session for existing checkout
592
+		/** @type EE_Checkout $checkout */
593
+		$checkout = EE_Registry::instance()->SSN->checkout();
594
+		// verify
595
+		if ( ! $checkout instanceof EE_Checkout) {
596
+			// instantiate EE_Checkout object for handling the properties of the current checkout process
597
+			$checkout = EE_Registry::instance()->load_file(
598
+				SPCO_INC_PATH,
599
+				'EE_Checkout',
600
+				'class', array(),
601
+				false
602
+			);
603
+		} else {
604
+			if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
605
+				$this->unlock_transaction();
606
+				wp_safe_redirect($checkout->redirect_url);
607
+				exit();
608
+			}
609
+		}
610
+		$checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
611
+		// verify again
612
+		if ( ! $checkout instanceof EE_Checkout) {
613
+			throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
614
+		}
615
+		// reset anything that needs a clean slate for each request
616
+		$checkout->reset_for_current_request();
617
+		return $checkout;
618
+	}
619
+
620
+
621
+
622
+	/**
623
+	 *    _get_request_vars
624
+	 *
625
+	 * @access    private
626
+	 * @return    void
627
+	 * @throws EE_Error
628
+	 */
629
+	private function _get_request_vars()
630
+	{
631
+		// load classes
632
+		EED_Single_Page_Checkout::load_request_handler();
633
+		//make sure this request is marked as belonging to EE
634
+		EE_Registry::instance()->REQ->set_espresso_page(true);
635
+		// which step is being requested ?
636
+		$this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
637
+		// which step is being edited ?
638
+		$this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
639
+		// and what we're doing on the current step
640
+		$this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
641
+		// timestamp
642
+		$this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
643
+		// returning to edit ?
644
+		$this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
645
+		// or some other kind of revisit ?
646
+		$this->checkout->revisit = filter_var(
647
+			EE_Registry::instance()->REQ->get('revisit', false),
648
+			FILTER_VALIDATE_BOOLEAN
649
+		);
650
+		// and whether or not to generate a reg form for this request
651
+		$this->checkout->generate_reg_form = filter_var(
652
+			EE_Registry::instance()->REQ->get('generate_reg_form', true),
653
+			FILTER_VALIDATE_BOOLEAN
654
+		);
655
+		// and whether or not to process a reg form submission for this request
656
+		$this->checkout->process_form_submission = filter_var(
657
+			EE_Registry::instance()->REQ->get(
658
+				'process_form_submission',
659
+				$this->checkout->action === 'process_reg_step'
660
+			),
661
+			FILTER_VALIDATE_BOOLEAN
662
+		);
663
+		$this->checkout->process_form_submission = filter_var(
664
+			$this->checkout->action !== 'display_spco_reg_step'
665
+				? $this->checkout->process_form_submission
666
+				: false,
667
+			FILTER_VALIDATE_BOOLEAN
668
+		);
669
+		// $this->_display_request_vars();
670
+	}
671
+
672
+
673
+
674
+	/**
675
+	 *  _display_request_vars
676
+	 *
677
+	 * @access    protected
678
+	 * @return    void
679
+	 */
680
+	protected function _display_request_vars()
681
+	{
682
+		if ( ! WP_DEBUG) {
683
+			return;
684
+		}
685
+		EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
686
+		EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
687
+		EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
688
+		EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
689
+		EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
690
+		EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
691
+		EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
692
+		EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
693
+	}
694
+
695
+
696
+
697
+	/**
698
+	 * _block_bots
699
+	 * checks that the incoming request has either of the following set:
700
+	 *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
701
+	 *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
702
+	 * so if you're not coming from the Ticket Selector nor returning for a valid IP...
703
+	 * then where you coming from man?
704
+	 *
705
+	 * @return boolean
706
+	 */
707
+	private function _block_bots()
708
+	{
709
+		$invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
710
+		if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
711
+			return true;
712
+		}
713
+		return false;
714
+	}
715
+
716
+
717
+
718
+	/**
719
+	 *    _get_first_step
720
+	 *  gets slug for first step in $_reg_steps_array
721
+	 *
722
+	 * @access    private
723
+	 * @throws EE_Error
724
+	 * @return    string
725
+	 */
726
+	private function _get_first_step()
727
+	{
728
+		$first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
729
+		return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
730
+	}
731
+
732
+
733
+
734
+	/**
735
+	 *    _load_and_instantiate_reg_steps
736
+	 *  instantiates each reg step based on the loaded reg_steps array
737
+	 *
738
+	 * @access    private
739
+	 * @throws EE_Error
740
+	 * @return    bool
741
+	 */
742
+	private function _load_and_instantiate_reg_steps()
743
+	{
744
+		do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
745
+		// have reg_steps already been instantiated ?
746
+		if (
747
+			empty($this->checkout->reg_steps)
748
+			|| apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
749
+		) {
750
+			// if not, then loop through raw reg steps array
751
+			foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
752
+				if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
753
+					return false;
754
+				}
755
+			}
756
+			EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true;
757
+			EE_Registry::instance()->CFG->registration->reg_confirmation_last = true;
758
+			// skip the registration_confirmation page ?
759
+			if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) {
760
+				// just remove it from the reg steps array
761
+				$this->checkout->remove_reg_step('registration_confirmation', false);
762
+			} else if (
763
+				isset($this->checkout->reg_steps['registration_confirmation'])
764
+				&& EE_Registry::instance()->CFG->registration->reg_confirmation_last
765
+			) {
766
+				// set the order to something big like 100
767
+				$this->checkout->set_reg_step_order('registration_confirmation', 100);
768
+			}
769
+			// filter the array for good luck
770
+			$this->checkout->reg_steps = apply_filters(
771
+				'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
772
+				$this->checkout->reg_steps
773
+			);
774
+			// finally re-sort based on the reg step class order properties
775
+			$this->checkout->sort_reg_steps();
776
+		} else {
777
+			foreach ($this->checkout->reg_steps as $reg_step) {
778
+				// set all current step stati to FALSE
779
+				$reg_step->set_is_current_step(false);
780
+			}
781
+		}
782
+		if (empty($this->checkout->reg_steps)) {
783
+			EE_Error::add_error(
784
+				__('No Reg Steps were loaded..', 'event_espresso'),
785
+				__FILE__, __FUNCTION__, __LINE__
786
+			);
787
+			return false;
788
+		}
789
+		// make reg step details available to JS
790
+		$this->checkout->set_reg_step_JSON_info();
791
+		return true;
792
+	}
793
+
794
+
795
+
796
+	/**
797
+	 *     _load_and_instantiate_reg_step
798
+	 *
799
+	 * @access    private
800
+	 * @param array $reg_step
801
+	 * @param int   $order
802
+	 * @return bool
803
+	 */
804
+	private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0)
805
+	{
806
+		// we need a file_path, class_name, and slug to add a reg step
807
+		if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
808
+			// if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
809
+			if (
810
+				$this->checkout->reg_url_link
811
+				&& $this->checkout->step !== $reg_step['slug']
812
+				&& $reg_step['slug'] !== 'finalize_registration'
813
+				// normally at this point we would NOT load the reg step, but this filter can change that
814
+				&& apply_filters(
815
+					'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
816
+					true,
817
+					$reg_step,
818
+					$this->checkout
819
+				)
820
+			) {
821
+				return true;
822
+			}
823
+			// instantiate step class using file path and class name
824
+			$reg_step_obj = EE_Registry::instance()->load_file(
825
+				$reg_step['file_path'],
826
+				$reg_step['class_name'],
827
+				'class',
828
+				$this->checkout,
829
+				false
830
+			);
831
+			// did we gets the goods ?
832
+			if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
833
+				// set reg step order based on config
834
+				$reg_step_obj->set_order($order);
835
+				// add instantiated reg step object to the master reg steps array
836
+				$this->checkout->add_reg_step($reg_step_obj);
837
+			} else {
838
+				EE_Error::add_error(
839
+					__('The current step could not be set.', 'event_espresso'),
840
+					__FILE__, __FUNCTION__, __LINE__
841
+				);
842
+				return false;
843
+			}
844
+		} else {
845
+			if (WP_DEBUG) {
846
+				EE_Error::add_error(
847
+					sprintf(
848
+						__(
849
+							'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s',
850
+							'event_espresso'
851
+						),
852
+						isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
853
+						isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
854
+						isset($reg_step['slug']) ? $reg_step['slug'] : '',
855
+						'<ul>',
856
+						'<li>',
857
+						'</li>',
858
+						'</ul>'
859
+					),
860
+					__FILE__, __FUNCTION__, __LINE__
861
+				);
862
+			}
863
+			return false;
864
+		}
865
+		return true;
866
+	}
867
+
868
+
869
+	/**
870
+	 * _verify_transaction_and_get_registrations
871
+	 *
872
+	 * @access private
873
+	 * @return bool
874
+	 * @throws InvalidDataTypeException
875
+	 * @throws InvalidEntityException
876
+	 * @throws EE_Error
877
+	 */
878
+	private function _verify_transaction_and_get_registrations()
879
+	{
880
+		// was there already a valid transaction in the checkout from the session ?
881
+		if ( ! $this->checkout->transaction instanceof EE_Transaction) {
882
+			// get transaction from db or session
883
+			$this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
884
+				? $this->_get_transaction_and_cart_for_previous_visit()
885
+				: $this->_get_cart_for_current_session_and_setup_new_transaction();
886
+			if ( ! $this->checkout->transaction instanceof EE_Transaction) {
887
+				EE_Error::add_error(
888
+					__('Your Registration and Transaction information could not be retrieved from the db.',
889
+						'event_espresso'),
890
+					__FILE__, __FUNCTION__, __LINE__
891
+				);
892
+				$this->checkout->transaction = EE_Transaction::new_instance();
893
+				// add some style and make it dance
894
+				$this->add_styles_and_scripts();
895
+				EED_Single_Page_Checkout::$_initialized = true;
896
+				return false;
897
+			}
898
+			// and the registrations for the transaction
899
+			$this->_get_registrations($this->checkout->transaction);
900
+		}
901
+		return true;
902
+	}
903
+
904
+
905
+
906
+	/**
907
+	 * _get_transaction_and_cart_for_previous_visit
908
+	 *
909
+	 * @access private
910
+	 * @return mixed EE_Transaction|NULL
911
+	 */
912
+	private function _get_transaction_and_cart_for_previous_visit()
913
+	{
914
+		/** @var $TXN_model EEM_Transaction */
915
+		$TXN_model = EE_Registry::instance()->load_model('Transaction');
916
+		// because the reg_url_link is present in the request,
917
+		// this is a return visit to SPCO, so we'll get the transaction data from the db
918
+		$transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
919
+		// verify transaction
920
+		if ($transaction instanceof EE_Transaction) {
921
+			// and get the cart that was used for that transaction
922
+			$this->checkout->cart = $this->_get_cart_for_transaction($transaction);
923
+			return $transaction;
924
+		}
925
+		EE_Error::add_error(
926
+			__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'),
927
+			__FILE__, __FUNCTION__, __LINE__
928
+		);
929
+		return null;
930
+
931
+	}
932
+
933
+
934
+
935
+	/**
936
+	 * _get_cart_for_transaction
937
+	 *
938
+	 * @access private
939
+	 * @param EE_Transaction $transaction
940
+	 * @return EE_Cart
941
+	 */
942
+	private function _get_cart_for_transaction($transaction)
943
+	{
944
+		return $this->checkout->get_cart_for_transaction($transaction);
945
+	}
946
+
947
+
948
+
949
+	/**
950
+	 * get_cart_for_transaction
951
+	 *
952
+	 * @access public
953
+	 * @param EE_Transaction $transaction
954
+	 * @return EE_Cart
955
+	 */
956
+	public function get_cart_for_transaction(EE_Transaction $transaction)
957
+	{
958
+		return $this->checkout->get_cart_for_transaction($transaction);
959
+	}
960
+
961
+
962
+
963
+	/**
964
+	 * _get_transaction_and_cart_for_current_session
965
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
966
+	 *
967
+	 * @access private
968
+	 * @return EE_Transaction
969
+	 * @throws EE_Error
970
+	 */
971
+	private function _get_cart_for_current_session_and_setup_new_transaction()
972
+	{
973
+		//  if there's no transaction, then this is the FIRST visit to SPCO
974
+		// so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
975
+		$this->checkout->cart = $this->_get_cart_for_transaction(null);
976
+		// and then create a new transaction
977
+		$transaction = $this->_initialize_transaction();
978
+		// verify transaction
979
+		if ($transaction instanceof EE_Transaction) {
980
+			// save it so that we have an ID for other objects to use
981
+			$transaction->save();
982
+			// and save TXN data to the cart
983
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
984
+		} else {
985
+			EE_Error::add_error(
986
+				__('A Valid Transaction could not be initialized.', 'event_espresso'),
987
+				__FILE__, __FUNCTION__, __LINE__
988
+			);
989
+		}
990
+		return $transaction;
991
+	}
992
+
993
+
994
+
995
+	/**
996
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
997
+	 *
998
+	 * @access private
999
+	 * @return mixed EE_Transaction|NULL
1000
+	 */
1001
+	private function _initialize_transaction()
1002
+	{
1003
+		try {
1004
+			// ensure cart totals have been calculated
1005
+			$this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
1006
+			// grab the cart grand total
1007
+			$cart_total = $this->checkout->cart->get_cart_grand_total();
1008
+			// create new TXN
1009
+			$transaction = EE_Transaction::new_instance(
1010
+				array(
1011
+					'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
1012
+					'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
1013
+					'TXN_paid'      => 0,
1014
+					'STS_ID'        => EEM_Transaction::failed_status_code,
1015
+				)
1016
+			);
1017
+			// save it so that we have an ID for other objects to use
1018
+			$transaction->save();
1019
+			// set cron job for following up on TXNs after their session has expired
1020
+			EE_Cron_Tasks::schedule_expired_transaction_check(
1021
+				EE_Registry::instance()->SSN->expiration() + 1,
1022
+				$transaction->ID()
1023
+			);
1024
+			return $transaction;
1025
+		} catch (Exception $e) {
1026
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1027
+		}
1028
+		return null;
1029
+	}
1030
+
1031
+
1032
+	/**
1033
+	 * _get_registrations
1034
+	 *
1035
+	 * @access private
1036
+	 * @param EE_Transaction $transaction
1037
+	 * @return void
1038
+	 * @throws InvalidDataTypeException
1039
+	 * @throws InvalidEntityException
1040
+	 * @throws EE_Error
1041
+	 */
1042
+	private function _get_registrations(EE_Transaction $transaction)
1043
+	{
1044
+		// first step: grab the registrants  { : o
1045
+		$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, true);
1046
+		// verify registrations have been set
1047
+		if (empty($registrations)) {
1048
+			// if no cached registrations, then check the db
1049
+			$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
1050
+			// still nothing ? well as long as this isn't a revisit
1051
+			if (empty($registrations) && ! $this->checkout->revisit) {
1052
+				// generate new registrations from scratch
1053
+				$registrations = $this->_initialize_registrations($transaction);
1054
+			}
1055
+		}
1056
+		// sort by their original registration order
1057
+		usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1058
+		// then loop thru the array
1059
+		foreach ($registrations as $registration) {
1060
+			// verify each registration
1061
+			if ($registration instanceof EE_Registration) {
1062
+				// we display all attendee info for the primary registrant
1063
+				if ($this->checkout->reg_url_link === $registration->reg_url_link()
1064
+					&& $registration->is_primary_registrant()
1065
+				) {
1066
+					$this->checkout->primary_revisit = true;
1067
+					break;
1068
+				}
1069
+				if ($this->checkout->revisit
1070
+						   && $this->checkout->reg_url_link !== $registration->reg_url_link()
1071
+				) {
1072
+					// but hide info if it doesn't belong to you
1073
+					$transaction->clear_cache('Registration', $registration->ID());
1074
+				}
1075
+				$this->checkout->set_reg_status_updated($registration->ID(), false);
1076
+			}
1077
+		}
1078
+	}
1079
+
1080
+
1081
+	/**
1082
+	 *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1083
+	 *
1084
+	 * @access private
1085
+	 * @param EE_Transaction $transaction
1086
+	 * @return    array
1087
+	 * @throws InvalidDataTypeException
1088
+	 * @throws InvalidEntityException
1089
+	 * @throws EE_Error
1090
+	 */
1091
+	private function _initialize_registrations(EE_Transaction $transaction)
1092
+	{
1093
+		$att_nmbr = 0;
1094
+		$registrations = array();
1095
+		if ($transaction instanceof EE_Transaction) {
1096
+			/** @type EE_Registration_Processor $registration_processor */
1097
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1098
+			$this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1099
+			// now let's add the cart items to the $transaction
1100
+			foreach ($this->checkout->cart->get_tickets() as $line_item) {
1101
+				//do the following for each ticket of this type they selected
1102
+				for ($x = 1; $x <= $line_item->quantity(); $x++) {
1103
+					$att_nmbr++;
1104
+					/** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1105
+					$CreateRegistrationCommand = EE_Registry::instance()->create(
1106
+						'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1107
+						array(
1108
+							$transaction,
1109
+							$line_item,
1110
+							$att_nmbr,
1111
+							$this->checkout->total_ticket_count,
1112
+						)
1113
+					);
1114
+					// override capabilities for frontend registrations
1115
+					if ( ! is_admin()) {
1116
+						$CreateRegistrationCommand->setCapCheck(
1117
+							new PublicCapabilities('', 'create_new_registration')
1118
+						);
1119
+					}
1120
+					$registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1121
+					if ( ! $registration instanceof EE_Registration) {
1122
+						throw new InvalidEntityException($registration, 'EE_Registration');
1123
+					}
1124
+					$registrations[ $registration->ID() ] = $registration;
1125
+				}
1126
+			}
1127
+			$registration_processor->fix_reg_final_price_rounding_issue($transaction);
1128
+		}
1129
+		return $registrations;
1130
+	}
1131
+
1132
+
1133
+
1134
+	/**
1135
+	 * sorts registrations by REG_count
1136
+	 *
1137
+	 * @access public
1138
+	 * @param EE_Registration $reg_A
1139
+	 * @param EE_Registration $reg_B
1140
+	 * @return int
1141
+	 */
1142
+	public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1143
+	{
1144
+		// this shouldn't ever happen within the same TXN, but oh well
1145
+		if ($reg_A->count() === $reg_B->count()) {
1146
+			return 0;
1147
+		}
1148
+		return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1149
+	}
1150
+
1151
+
1152
+
1153
+	/**
1154
+	 *    _final_verifications
1155
+	 * just makes sure that everything is set up correctly before proceeding
1156
+	 *
1157
+	 * @access    private
1158
+	 * @return    bool
1159
+	 * @throws EE_Error
1160
+	 */
1161
+	private function _final_verifications()
1162
+	{
1163
+		// filter checkout
1164
+		$this->checkout = apply_filters(
1165
+			'FHEE__EED_Single_Page_Checkout___final_verifications__checkout',
1166
+			$this->checkout
1167
+		);
1168
+		//verify that current step is still set correctly
1169
+		if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1170
+			EE_Error::add_error(
1171
+				__('We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso'),
1172
+				__FILE__,
1173
+				__FUNCTION__,
1174
+				__LINE__
1175
+			);
1176
+			return false;
1177
+		}
1178
+		// if returning to SPCO, then verify that primary registrant is set
1179
+		if ( ! empty($this->checkout->reg_url_link)) {
1180
+			$valid_registrant = $this->checkout->transaction->primary_registration();
1181
+			if ( ! $valid_registrant instanceof EE_Registration) {
1182
+				EE_Error::add_error(
1183
+					__('We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso'),
1184
+					__FILE__,
1185
+					__FUNCTION__,
1186
+					__LINE__
1187
+				);
1188
+				return false;
1189
+			}
1190
+			$valid_registrant = null;
1191
+			foreach (
1192
+				$this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration
1193
+			) {
1194
+				if (
1195
+					$registration instanceof EE_Registration
1196
+					&& $registration->reg_url_link() === $this->checkout->reg_url_link
1197
+				) {
1198
+					$valid_registrant = $registration;
1199
+				}
1200
+			}
1201
+			if ( ! $valid_registrant instanceof EE_Registration) {
1202
+				// hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1203
+				if (EED_Single_Page_Checkout::$_checkout_verified) {
1204
+					// clear the session, mark the checkout as unverified, and try again
1205
+					EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1206
+					EED_Single_Page_Checkout::$_initialized = false;
1207
+					EED_Single_Page_Checkout::$_checkout_verified = false;
1208
+					$this->_initialize();
1209
+					EE_Error::reset_notices();
1210
+					return false;
1211
+				}
1212
+				EE_Error::add_error(
1213
+					__(
1214
+						'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.',
1215
+						'event_espresso'
1216
+					),
1217
+					__FILE__,
1218
+					__FUNCTION__,
1219
+					__LINE__
1220
+				);
1221
+				return false;
1222
+			}
1223
+		}
1224
+		// now that things have been kinda sufficiently verified,
1225
+		// let's add the checkout to the session so that it's available to other systems
1226
+		EE_Registry::instance()->SSN->set_checkout($this->checkout);
1227
+		return true;
1228
+	}
1229
+
1230
+
1231
+
1232
+	/**
1233
+	 *    _initialize_reg_steps
1234
+	 * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1235
+	 * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1236
+	 *
1237
+	 * @access    private
1238
+	 * @param bool $reinitializing
1239
+	 * @throws EE_Error
1240
+	 */
1241
+	private function _initialize_reg_steps($reinitializing = false)
1242
+	{
1243
+		$this->checkout->set_reg_step_initiated($this->checkout->current_step);
1244
+		// loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1245
+		foreach ($this->checkout->reg_steps as $reg_step) {
1246
+			if ( ! $reg_step->initialize_reg_step()) {
1247
+				// if not initialized then maybe this step is being removed...
1248
+				if ( ! $reinitializing && $reg_step->is_current_step()) {
1249
+					// if it was the current step, then we need to start over here
1250
+					$this->_initialize_reg_steps(true);
1251
+					return;
1252
+				}
1253
+				continue;
1254
+			}
1255
+			// add css and JS for current step
1256
+			$reg_step->enqueue_styles_and_scripts();
1257
+			// i18n
1258
+			$reg_step->translate_js_strings();
1259
+			if ($reg_step->is_current_step()) {
1260
+				// the text that appears on the reg step form submit button
1261
+				$reg_step->set_submit_button_text();
1262
+			}
1263
+		}
1264
+		// dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1265
+		do_action(
1266
+			"AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}",
1267
+			$this->checkout->current_step
1268
+		);
1269
+	}
1270
+
1271
+
1272
+
1273
+	/**
1274
+	 * _check_form_submission
1275
+	 *
1276
+	 * @access private
1277
+	 * @return boolean
1278
+	 */
1279
+	private function _check_form_submission()
1280
+	{
1281
+		//does this request require the reg form to be generated ?
1282
+		if ($this->checkout->generate_reg_form) {
1283
+			// ever heard that song by Blue Rodeo ?
1284
+			try {
1285
+				$this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1286
+				// if not displaying a form, then check for form submission
1287
+				if (
1288
+					$this->checkout->process_form_submission
1289
+					&& $this->checkout->current_step->reg_form->was_submitted()
1290
+				) {
1291
+					// clear out any old data in case this step is being run again
1292
+					$this->checkout->current_step->set_valid_data(array());
1293
+					// capture submitted form data
1294
+					$this->checkout->current_step->reg_form->receive_form_submission(
1295
+						apply_filters(
1296
+							'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1297
+							EE_Registry::instance()->REQ->params(),
1298
+							$this->checkout
1299
+						)
1300
+					);
1301
+					// validate submitted form data
1302
+					if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1303
+						// thou shall not pass !!!
1304
+						$this->checkout->continue_reg = false;
1305
+						// any form validation errors?
1306
+						if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1307
+							$submission_error_messages = array();
1308
+							// bad, bad, bad registrant
1309
+							foreach (
1310
+								$this->checkout->current_step->reg_form->get_validation_errors_accumulated()
1311
+								as $validation_error
1312
+							) {
1313
+								if ($validation_error instanceof EE_Validation_Error) {
1314
+									$submission_error_messages[] = sprintf(
1315
+										__('%s : %s', 'event_espresso'),
1316
+										$validation_error->get_form_section()->html_label_text(),
1317
+										$validation_error->getMessage()
1318
+									);
1319
+								}
1320
+							}
1321
+							EE_Error::add_error(
1322
+								implode('<br />', $submission_error_messages),
1323
+								__FILE__, __FUNCTION__, __LINE__
1324
+							);
1325
+						}
1326
+						// well not really... what will happen is
1327
+						// we'll just get redirected back to redo the current step
1328
+						$this->go_to_next_step();
1329
+						return false;
1330
+					}
1331
+				}
1332
+			} catch (EE_Error $e) {
1333
+				$e->get_error();
1334
+			}
1335
+		}
1336
+		return true;
1337
+	}
1338
+
1339
+
1340
+
1341
+	/**
1342
+	 * _process_action
1343
+	 *
1344
+	 * @access private
1345
+	 * @return void
1346
+	 * @throws EE_Error
1347
+	 */
1348
+	private function _process_form_action()
1349
+	{
1350
+		// what cha wanna do?
1351
+		switch ($this->checkout->action) {
1352
+			// AJAX next step reg form
1353
+			case 'display_spco_reg_step' :
1354
+				$this->checkout->redirect = false;
1355
+				if (EE_Registry::instance()->REQ->ajax) {
1356
+					$this->checkout->json_response->set_reg_step_html(
1357
+						$this->checkout->current_step->display_reg_form()
1358
+					);
1359
+				}
1360
+				break;
1361
+			default :
1362
+				// meh... do one of those other steps first
1363
+				if (
1364
+					! empty($this->checkout->action)
1365
+					&& is_callable(array($this->checkout->current_step, $this->checkout->action))
1366
+				) {
1367
+					// dynamically creates hook point like:
1368
+					//   AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1369
+					do_action(
1370
+						"AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1371
+						$this->checkout->current_step
1372
+					);
1373
+					// call action on current step
1374
+					if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1375
+						// good registrant, you get to proceed
1376
+						if (
1377
+							$this->checkout->current_step->success_message() !== ''
1378
+							&& apply_filters(
1379
+								'FHEE__Single_Page_Checkout___process_form_action__display_success',
1380
+								false
1381
+							)
1382
+						) {
1383
+							EE_Error::add_success(
1384
+								$this->checkout->current_step->success_message()
1385
+								. '<br />' . $this->checkout->next_step->_instructions()
1386
+							);
1387
+						}
1388
+						// pack it up, pack it in...
1389
+						$this->_setup_redirect();
1390
+					}
1391
+					// dynamically creates hook point like:
1392
+					//  AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1393
+					do_action(
1394
+						"AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1395
+						$this->checkout->current_step
1396
+					);
1397
+				} else {
1398
+					EE_Error::add_error(
1399
+						sprintf(
1400
+							__(
1401
+								'The requested form action "%s" does not exist for the current "%s" registration step.',
1402
+								'event_espresso'
1403
+							),
1404
+							$this->checkout->action,
1405
+							$this->checkout->current_step->name()
1406
+						),
1407
+						__FILE__,
1408
+						__FUNCTION__,
1409
+						__LINE__
1410
+					);
1411
+				}
1412
+			// end default
1413
+		}
1414
+		// store our progress so far
1415
+		$this->checkout->stash_transaction_and_checkout();
1416
+		// advance to the next step! If you pass GO, collect $200
1417
+		$this->go_to_next_step();
1418
+	}
1419
+
1420
+
1421
+
1422
+	/**
1423
+	 *        add_styles_and_scripts
1424
+	 *
1425
+	 * @access        public
1426
+	 * @return        void
1427
+	 */
1428
+	public function add_styles_and_scripts()
1429
+	{
1430
+		// i18n
1431
+		$this->translate_js_strings();
1432
+		if ($this->checkout->admin_request) {
1433
+			add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1434
+		} else {
1435
+			add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1436
+		}
1437
+	}
1438
+
1439
+
1440
+
1441
+	/**
1442
+	 *        translate_js_strings
1443
+	 *
1444
+	 * @access        public
1445
+	 * @return        void
1446
+	 */
1447
+	public function translate_js_strings()
1448
+	{
1449
+		EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1450
+		EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1451
+		EE_Registry::$i18n_js_strings['server_error'] = __(
1452
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
1453
+			'event_espresso'
1454
+		);
1455
+		EE_Registry::$i18n_js_strings['invalid_json_response'] = __(
1456
+			'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.',
1457
+			'event_espresso'
1458
+		);
1459
+		EE_Registry::$i18n_js_strings['validation_error'] = __(
1460
+			'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.',
1461
+			'event_espresso'
1462
+		);
1463
+		EE_Registry::$i18n_js_strings['invalid_payment_method'] = __(
1464
+			'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.',
1465
+			'event_espresso'
1466
+		);
1467
+		EE_Registry::$i18n_js_strings['reg_step_error'] = __(
1468
+			'This registration step could not be completed. Please refresh the page and try again.',
1469
+			'event_espresso'
1470
+		);
1471
+		EE_Registry::$i18n_js_strings['invalid_coupon'] = __(
1472
+			'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.',
1473
+			'event_espresso'
1474
+		);
1475
+		EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1476
+			__(
1477
+				'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.',
1478
+				'event_espresso'
1479
+			),
1480
+			'<br/>',
1481
+			'<br/>'
1482
+		);
1483
+		EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1484
+		EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1485
+		EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1486
+		EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1487
+		EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1488
+		EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1489
+		EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1490
+		EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1491
+		EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1492
+		EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1493
+		EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1494
+		EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1495
+		EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1496
+		EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1497
+		EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1498
+		EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1499
+		EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1500
+		EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1501
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1502
+			__(
1503
+				'%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
1504
+				'event_espresso'
1505
+			),
1506
+			'<h4 class="important-notice">',
1507
+			'</h4>',
1508
+			'<br />',
1509
+			'<p>',
1510
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1511
+			'">',
1512
+			'</a>',
1513
+			'</p>'
1514
+		);
1515
+		EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters(
1516
+			'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
1517
+			true
1518
+		);
1519
+		EE_Registry::$i18n_js_strings['session_extension'] = absint(
1520
+			apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1521
+		);
1522
+		EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1523
+			'M d, Y H:i:s',
1524
+			EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1525
+		);
1526
+	}
1527
+
1528
+
1529
+
1530
+	/**
1531
+	 *    enqueue_styles_and_scripts
1532
+	 *
1533
+	 * @access        public
1534
+	 * @return        void
1535
+	 * @throws EE_Error
1536
+	 */
1537
+	public function enqueue_styles_and_scripts()
1538
+	{
1539
+		// load css
1540
+		wp_register_style(
1541
+			'single_page_checkout',
1542
+			SPCO_CSS_URL . 'single_page_checkout.css',
1543
+			array('espresso_default'),
1544
+			EVENT_ESPRESSO_VERSION
1545
+		);
1546
+		wp_enqueue_style('single_page_checkout');
1547
+		// load JS
1548
+		wp_register_script(
1549
+			'jquery_plugin',
1550
+			EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1551
+			array('jquery'),
1552
+			'1.0.1',
1553
+			true
1554
+		);
1555
+		wp_register_script(
1556
+			'jquery_countdown',
1557
+			EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1558
+			array('jquery_plugin'),
1559
+			'2.0.2',
1560
+			true
1561
+		);
1562
+		wp_register_script(
1563
+			'single_page_checkout',
1564
+			SPCO_JS_URL . 'single_page_checkout.js',
1565
+			array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1566
+			EVENT_ESPRESSO_VERSION,
1567
+			true
1568
+		);
1569
+		if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1570
+			$this->checkout->registration_form->enqueue_js();
1571
+		}
1572
+		if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1573
+			$this->checkout->current_step->reg_form->enqueue_js();
1574
+		}
1575
+		wp_enqueue_script('single_page_checkout');
1576
+		/**
1577
+		 * global action hook for enqueueing styles and scripts with
1578
+		 * spco calls.
1579
+		 */
1580
+		do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1581
+		/**
1582
+		 * dynamic action hook for enqueueing styles and scripts with spco calls.
1583
+		 * The hook will end up being something like:
1584
+		 *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1585
+		 */
1586
+		do_action(
1587
+			'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1588
+			$this
1589
+		);
1590
+	}
1591
+
1592
+
1593
+
1594
+	/**
1595
+	 *    display the Registration Single Page Checkout Form
1596
+	 *
1597
+	 * @access    private
1598
+	 * @return    void
1599
+	 * @throws EE_Error
1600
+	 */
1601
+	private function _display_spco_reg_form()
1602
+	{
1603
+		// if registering via the admin, just display the reg form for the current step
1604
+		if ($this->checkout->admin_request) {
1605
+			EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1606
+		} else {
1607
+			// add powered by EE msg
1608
+			add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1609
+			$empty_cart = count(
1610
+				$this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)
1611
+			) < 1;
1612
+			EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1613
+			$cookies_not_set_msg = '';
1614
+			if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1615
+				$cookies_not_set_msg = apply_filters(
1616
+					'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1617
+					sprintf(
1618
+						__(
1619
+							'%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s',
1620
+							'event_espresso'
1621
+						),
1622
+						'<div class="ee-attention">',
1623
+						'</div>',
1624
+						'<h6 class="important-notice">',
1625
+						'</h6>',
1626
+						'<p>',
1627
+						'</p>',
1628
+						'<br />',
1629
+						'<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1630
+						'</a>'
1631
+					)
1632
+				);
1633
+			}
1634
+			$this->checkout->registration_form = new EE_Form_Section_Proper(
1635
+				array(
1636
+					'name'            => 'single-page-checkout',
1637
+					'html_id'         => 'ee-single-page-checkout-dv',
1638
+					'layout_strategy' =>
1639
+						new EE_Template_Layout(
1640
+							array(
1641
+								'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1642
+								'template_args'        => array(
1643
+									'empty_cart'              => $empty_cart,
1644
+									'revisit'                 => $this->checkout->revisit,
1645
+									'reg_steps'               => $this->checkout->reg_steps,
1646
+									'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1647
+										? $this->checkout->next_step->slug()
1648
+										: '',
1649
+									'cancel_page_url'         => $this->checkout->cancel_page_url,
1650
+									'empty_msg'               => apply_filters(
1651
+										'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1652
+										sprintf(
1653
+											__(
1654
+												'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1655
+												'event_espresso'
1656
+											),
1657
+											'<a href="'
1658
+											. get_post_type_archive_link('espresso_events')
1659
+											. '" title="',
1660
+											'">',
1661
+											'</a>'
1662
+										)
1663
+									),
1664
+									'cookies_not_set_msg'     => $cookies_not_set_msg,
1665
+									'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1666
+									'session_expiration'      => gmdate(
1667
+										'M d, Y H:i:s',
1668
+										EE_Registry::instance()->SSN->expiration()
1669
+										+ (get_option('gmt_offset') * HOUR_IN_SECONDS)
1670
+									),
1671
+								),
1672
+							)
1673
+						),
1674
+				)
1675
+			);
1676
+			// load template and add to output sent that gets filtered into the_content()
1677
+			EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1678
+		}
1679
+	}
1680
+
1681
+
1682
+
1683
+	/**
1684
+	 *    add_extra_finalize_registration_inputs
1685
+	 *
1686
+	 * @access    public
1687
+	 * @param $next_step
1688
+	 * @internal  param string $label
1689
+	 * @return void
1690
+	 */
1691
+	public function add_extra_finalize_registration_inputs($next_step)
1692
+	{
1693
+		if ($next_step === 'finalize_registration') {
1694
+			echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1695
+		}
1696
+	}
1697
+
1698
+
1699
+
1700
+	/**
1701
+	 *    display_registration_footer
1702
+	 *
1703
+	 * @access    public
1704
+	 * @return    string
1705
+	 */
1706
+	public static function display_registration_footer()
1707
+	{
1708
+		if (
1709
+		apply_filters(
1710
+			'FHEE__EE_Front__Controller__show_reg_footer',
1711
+			EE_Registry::instance()->CFG->admin->show_reg_footer
1712
+		)
1713
+		) {
1714
+			add_filter(
1715
+				'FHEE__EEH_Template__powered_by_event_espresso__url',
1716
+				function ($url) {
1717
+					return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1718
+				}
1719
+			);
1720
+			echo apply_filters(
1721
+				'FHEE__EE_Front_Controller__display_registration_footer',
1722
+				\EEH_Template::powered_by_event_espresso(
1723
+					'',
1724
+					'espresso-registration-footer-dv',
1725
+					array('utm_content' => 'registration_checkout')
1726
+				)
1727
+			);
1728
+		}
1729
+		return '';
1730
+	}
1731
+
1732
+
1733
+
1734
+	/**
1735
+	 *    unlock_transaction
1736
+	 *
1737
+	 * @access    public
1738
+	 * @return    void
1739
+	 * @throws EE_Error
1740
+	 */
1741
+	public function unlock_transaction()
1742
+	{
1743
+		if ($this->checkout->transaction instanceof EE_Transaction) {
1744
+			$this->checkout->transaction->unlock();
1745
+		}
1746
+	}
1747
+
1748
+
1749
+
1750
+	/**
1751
+	 *        _setup_redirect
1752
+	 *
1753
+	 * @access    private
1754
+	 * @return void
1755
+	 */
1756
+	private function _setup_redirect()
1757
+	{
1758
+		if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1759
+			$this->checkout->redirect = true;
1760
+			if (empty($this->checkout->redirect_url)) {
1761
+				$this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1762
+			}
1763
+			$this->checkout->redirect_url = apply_filters(
1764
+				'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1765
+				$this->checkout->redirect_url,
1766
+				$this->checkout
1767
+			);
1768
+		}
1769
+	}
1770
+
1771
+
1772
+
1773
+	/**
1774
+	 *   handle ajax message responses and redirects
1775
+	 *
1776
+	 * @access public
1777
+	 * @return void
1778
+	 * @throws EE_Error
1779
+	 */
1780
+	public function go_to_next_step()
1781
+	{
1782
+		if (EE_Registry::instance()->REQ->ajax) {
1783
+			// capture contents of output buffer we started earlier in the request, and insert into JSON response
1784
+			$this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1785
+		}
1786
+		$this->unlock_transaction();
1787
+		// just return for these conditions
1788
+		if (
1789
+			$this->checkout->admin_request
1790
+			|| $this->checkout->action === 'redirect_form'
1791
+			|| $this->checkout->action === 'update_checkout'
1792
+		) {
1793
+			return;
1794
+		}
1795
+		// AJAX response
1796
+		$this->_handle_json_response();
1797
+		// redirect to next step or the Thank You page
1798
+		$this->_handle_html_redirects();
1799
+		// hmmm... must be something wrong, so let's just display the form again !
1800
+		$this->_display_spco_reg_form();
1801
+	}
1802
+
1803
+
1804
+
1805
+	/**
1806
+	 *   _handle_json_response
1807
+	 *
1808
+	 * @access protected
1809
+	 * @return void
1810
+	 */
1811
+	protected function _handle_json_response()
1812
+	{
1813
+		// if this is an ajax request
1814
+		if (EE_Registry::instance()->REQ->ajax) {
1815
+			// DEBUG LOG
1816
+			//$this->checkout->log(
1817
+			//	__CLASS__, __FUNCTION__, __LINE__,
1818
+			//	array(
1819
+			//		'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1820
+			//		'redirect'                   => $this->checkout->redirect,
1821
+			//		'continue_reg'               => $this->checkout->continue_reg,
1822
+			//	)
1823
+			//);
1824
+			$this->checkout->json_response->set_registration_time_limit(
1825
+				$this->checkout->get_registration_time_limit()
1826
+			);
1827
+			$this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1828
+			// just send the ajax (
1829
+			$json_response = apply_filters(
1830
+				'FHEE__EE_Single_Page_Checkout__JSON_response',
1831
+				$this->checkout->json_response
1832
+			);
1833
+			echo $json_response;
1834
+			exit();
1835
+		}
1836
+	}
1837
+
1838
+
1839
+
1840
+	/**
1841
+	 *   _handle_redirects
1842
+	 *
1843
+	 * @access protected
1844
+	 * @return void
1845
+	 */
1846
+	protected function _handle_html_redirects()
1847
+	{
1848
+		// going somewhere ?
1849
+		if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1850
+			// store notices in a transient
1851
+			EE_Error::get_notices(false, true, true);
1852
+			// DEBUG LOG
1853
+			//$this->checkout->log(
1854
+			//	__CLASS__, __FUNCTION__, __LINE__,
1855
+			//	array(
1856
+			//		'headers_sent' => headers_sent(),
1857
+			//		'redirect_url'     => $this->checkout->redirect_url,
1858
+			//		'headers_list'    => headers_list(),
1859
+			//	)
1860
+			//);
1861
+			wp_safe_redirect($this->checkout->redirect_url);
1862
+			exit();
1863
+		}
1864
+	}
1865
+
1866
+
1867
+
1868
+	/**
1869
+	 *   set_checkout_anchor
1870
+	 *
1871
+	 * @access public
1872
+	 * @return void
1873
+	 */
1874
+	public function set_checkout_anchor()
1875
+	{
1876
+		echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1877
+	}
1878 1878
 
1879 1879
 
1880 1880
 
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -218,19 +218,19 @@  discard block
 block discarded – undo
218 218
      */
219 219
     public static function set_definitions()
220 220
     {
221
-        if(defined('SPCO_BASE_PATH')) {
221
+        if (defined('SPCO_BASE_PATH')) {
222 222
             return;
223 223
         }
224 224
         define(
225 225
             'SPCO_BASE_PATH',
226
-            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
226
+            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS).DS
227 227
         );
228
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
228
+        define('SPCO_CSS_URL', plugin_dir_url(__FILE__).'css'.DS);
229
+        define('SPCO_IMG_URL', plugin_dir_url(__FILE__).'img'.DS);
230
+        define('SPCO_JS_URL', plugin_dir_url(__FILE__).'js'.DS);
231
+        define('SPCO_INC_PATH', SPCO_BASE_PATH.'inc'.DS);
232
+        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH.'reg_steps'.DS);
233
+        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH.'templates'.DS);
234 234
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235 235
         EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236 236
             __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
             '</h4>',
240 240
             '<br />',
241 241
             '<p>',
242
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
242
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
243 243
             '">',
244 244
             '</a>',
245 245
             '</p>'
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
             return;
263 263
         }
264 264
         // filter list of reg_steps
265
-        $reg_steps_to_load = (array)apply_filters(
265
+        $reg_steps_to_load = (array) apply_filters(
266 266
             'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267 267
             EED_Single_Page_Checkout::get_reg_steps()
268 268
         );
@@ -314,25 +314,25 @@  discard block
 block discarded – undo
314 314
         if (empty($reg_steps)) {
315 315
             $reg_steps = array(
316 316
                 10  => array(
317
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
317
+                    'file_path'  => SPCO_REG_STEPS_PATH.'attendee_information',
318 318
                     'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319 319
                     'slug'       => 'attendee_information',
320 320
                     'has_hooks'  => false,
321 321
                 ),
322 322
                 20  => array(
323
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
323
+                    'file_path'  => SPCO_REG_STEPS_PATH.'registration_confirmation',
324 324
                     'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325 325
                     'slug'       => 'registration_confirmation',
326 326
                     'has_hooks'  => false,
327 327
                 ),
328 328
                 30  => array(
329
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
329
+                    'file_path'  => SPCO_REG_STEPS_PATH.'payment_options',
330 330
                     'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331 331
                     'slug'       => 'payment_options',
332 332
                     'has_hooks'  => true,
333 333
                 ),
334 334
                 999 => array(
335
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
335
+                    'file_path'  => SPCO_REG_STEPS_PATH.'finalize_registration',
336 336
                     'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337 337
                     'slug'       => 'finalize_registration',
338 338
                     'has_hooks'  => false,
@@ -516,7 +516,7 @@  discard block
 block discarded – undo
516 516
             // DEBUG LOG
517 517
             //$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
518 518
             // get reg form
519
-            if( ! $this->_check_form_submission()) {
519
+            if ( ! $this->_check_form_submission()) {
520 520
                 EED_Single_Page_Checkout::$_initialized = true;
521 521
                 return;
522 522
             }
@@ -557,7 +557,7 @@  discard block
 block discarded – undo
557 557
         );
558 558
         // is session still valid ?
559 559
         if ($clear_session_requested
560
-            || ( EE_Registry::instance()->SSN->expired()
560
+            || (EE_Registry::instance()->SSN->expired()
561 561
               && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === ''
562 562
             )
563 563
         ) {
@@ -566,7 +566,7 @@  discard block
 block discarded – undo
566 566
             // EE_Registry::instance()->SSN->reset_cart();
567 567
             // EE_Registry::instance()->SSN->reset_checkout();
568 568
             // EE_Registry::instance()->SSN->reset_transaction();
569
-            if (! $clear_session_requested) {
569
+            if ( ! $clear_session_requested) {
570 570
                 EE_Error::add_attention(
571 571
                     EE_Registry::$i18n_js_strings['registration_expiration_notice'],
572 572
                     __FILE__, __FUNCTION__, __LINE__
@@ -1121,7 +1121,7 @@  discard block
 block discarded – undo
1121 1121
                     if ( ! $registration instanceof EE_Registration) {
1122 1122
                         throw new InvalidEntityException($registration, 'EE_Registration');
1123 1123
                     }
1124
-                    $registrations[ $registration->ID() ] = $registration;
1124
+                    $registrations[$registration->ID()] = $registration;
1125 1125
                 }
1126 1126
             }
1127 1127
             $registration_processor->fix_reg_final_price_rounding_issue($transaction);
@@ -1382,7 +1382,7 @@  discard block
 block discarded – undo
1382 1382
                         ) {
1383 1383
                             EE_Error::add_success(
1384 1384
                                 $this->checkout->current_step->success_message()
1385
-                                . '<br />' . $this->checkout->next_step->_instructions()
1385
+                                . '<br />'.$this->checkout->next_step->_instructions()
1386 1386
                             );
1387 1387
                         }
1388 1388
                         // pack it up, pack it in...
@@ -1507,7 +1507,7 @@  discard block
 block discarded – undo
1507 1507
             '</h4>',
1508 1508
             '<br />',
1509 1509
             '<p>',
1510
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1510
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
1511 1511
             '">',
1512 1512
             '</a>',
1513 1513
             '</p>'
@@ -1539,7 +1539,7 @@  discard block
 block discarded – undo
1539 1539
         // load css
1540 1540
         wp_register_style(
1541 1541
             'single_page_checkout',
1542
-            SPCO_CSS_URL . 'single_page_checkout.css',
1542
+            SPCO_CSS_URL.'single_page_checkout.css',
1543 1543
             array('espresso_default'),
1544 1544
             EVENT_ESPRESSO_VERSION
1545 1545
         );
@@ -1547,21 +1547,21 @@  discard block
 block discarded – undo
1547 1547
         // load JS
1548 1548
         wp_register_script(
1549 1549
             'jquery_plugin',
1550
-            EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1550
+            EE_THIRD_PARTY_URL.'jquery	.plugin.min.js',
1551 1551
             array('jquery'),
1552 1552
             '1.0.1',
1553 1553
             true
1554 1554
         );
1555 1555
         wp_register_script(
1556 1556
             'jquery_countdown',
1557
-            EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1557
+            EE_THIRD_PARTY_URL.'jquery	.countdown.min.js',
1558 1558
             array('jquery_plugin'),
1559 1559
             '2.0.2',
1560 1560
             true
1561 1561
         );
1562 1562
         wp_register_script(
1563 1563
             'single_page_checkout',
1564
-            SPCO_JS_URL . 'single_page_checkout.js',
1564
+            SPCO_JS_URL.'single_page_checkout.js',
1565 1565
             array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1566 1566
             EVENT_ESPRESSO_VERSION,
1567 1567
             true
@@ -1584,7 +1584,7 @@  discard block
 block discarded – undo
1584 1584
          *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1585 1585
          */
1586 1586
         do_action(
1587
-            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1587
+            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__'.$this->checkout->current_step->slug(),
1588 1588
             $this
1589 1589
         );
1590 1590
     }
@@ -1638,7 +1638,7 @@  discard block
 block discarded – undo
1638 1638
                     'layout_strategy' =>
1639 1639
                         new EE_Template_Layout(
1640 1640
                             array(
1641
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1641
+                                'layout_template_file' => SPCO_TEMPLATES_PATH.'registration_page_wrapper.template.php',
1642 1642
                                 'template_args'        => array(
1643 1643
                                     'empty_cart'              => $empty_cart,
1644 1644
                                     'revisit'                 => $this->checkout->revisit,
@@ -1713,7 +1713,7 @@  discard block
 block discarded – undo
1713 1713
         ) {
1714 1714
             add_filter(
1715 1715
                 'FHEE__EEH_Template__powered_by_event_espresso__url',
1716
-                function ($url) {
1716
+                function($url) {
1717 1717
                     return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1718 1718
                 }
1719 1719
             );
Please login to merge, or discard this patch.
core/libraries/plugin_api/EE_Register_Capabilities.lib.php 2 patches
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -7,7 +7,7 @@  discard block
 block discarded – undo
7 7
  * @since           4.5.0
8 8
  */
9 9
 if (! defined('EVENT_ESPRESSO_VERSION')) {
10
-    exit('No direct script access allowed');
10
+	exit('No direct script access allowed');
11 11
 }
12 12
 
13 13
 /**
@@ -21,174 +21,174 @@  discard block
 block discarded – undo
21 21
 class EE_Register_Capabilities implements EEI_Plugin_API
22 22
 {
23 23
 
24
-    /**
25
-     * Holds the settings for a specific registration.
26
-     *
27
-     * @var array
28
-     */
29
-    protected static $_registry = array();
24
+	/**
25
+	 * Holds the settings for a specific registration.
26
+	 *
27
+	 * @var array
28
+	 */
29
+	protected static $_registry = array();
30 30
 
31 31
 
32
-    /**
33
-     * Used to register capability items with EE core.
34
-     *
35
-     * @since 4.5.0
36
-     * @param string $cap_reference                                                       usually will be a class name
37
-     *                                                                                    that references capability
38
-     *                                                                                    related items setup for
39
-     *                                                                                    something.
40
-     * @param array  $setup_args                                                          {
41
-     *                                                                                    An array of items related to
42
-     *                                                                                    registering capabilities.
43
-     * @type array   $capabilities                                                        An array mapping capability
44
-     *       strings to core WP Role. Something like: array(
45
-     *                                                                                    'administrator'    => array(
46
-     *                                                                                    'read_cap', 'edit_cap',
47
-     *                                                                                    'delete_cap'),
48
-     *                                                                                    'author'                =>
49
-     *                                                                                    array( 'read_cap' )
50
-     *                                                                                    ).
51
-     * @type array   $capability_maps                                                     EE_Meta_Capability_Map[]
52
-     * @see   EE_Capabilities.php for php docs on these objects.
53
-     *                                                                                    Should be indexed by the
54
-     *                                                                                    classname for the capability
55
-     *                                                                                    map and values representing
56
-     *                                                                                    the arguments for the map.
57
-     *                                                                                    }
58
-     * @throws EE_Error
59
-     * @return void
60
-     */
61
-    public static function register($cap_reference = null, $setup_args = array())
62
-    {
63
-        //required fields MUST be present, so let's make sure they are.
64
-        if ($cap_reference === null || ! is_array($setup_args) || empty($setup_args['capabilities'])) {
65
-            throw new EE_Error(
66
-                __('In order to register capabilities with EE_Register_Capabilities::register, you must include a unique name to reference the capabilities being registered, plus an array containing the following keys: "capabilities".',
67
-                    'event_espresso')
68
-            );
69
-        }
70
-        //make sure we don't register twice
71
-        if (isset(self::$_registry[$cap_reference])) {
72
-            return;
73
-        }
74
-        //make sure this is not registered too late or too early.
75
-        if (! did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')) {
76
-            EE_Error::doing_it_wrong(__METHOD__,
77
-                sprintf(__('%s has been registered too late.  Please ensure that EE_Register_Capabilities::register has been called at some point before the "AHEE__EE_System___detect_if_activation_or_upgrade__begin" action hook has been called.',
78
-                    'event_espresso'), $cap_reference), '4.5.0');
79
-        }
80
-        //some preliminary sanitization and setting to the $_registry property
81
-        self::$_registry[ $cap_reference ] = array(
82
-            'caps'               => isset($setup_args['capabilities']) && is_array($setup_args['capabilities'])
83
-                ? $setup_args['capabilities']
84
-                : array(),
85
-            'cap_maps'           => isset($setup_args['capability_maps'])
86
-                ? $setup_args['capability_maps']
87
-                : array(),
88
-        );
89
-        //set initial caps (note that EE_Capabilities takes care of making sure that the caps get added only once)
90
-        add_filter(
91
-            'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
92
-            array('EE_Register_Capabilities', 'register_capabilities')
93
-        );
94
-        //add filter for cap maps
95
-        add_filter(
96
-            'FHEE__EE_Capabilities___set_meta_caps__meta_caps',
97
-            array('EE_Register_Capabilities', 'register_cap_maps')
98
-        );
99
-    }
32
+	/**
33
+	 * Used to register capability items with EE core.
34
+	 *
35
+	 * @since 4.5.0
36
+	 * @param string $cap_reference                                                       usually will be a class name
37
+	 *                                                                                    that references capability
38
+	 *                                                                                    related items setup for
39
+	 *                                                                                    something.
40
+	 * @param array  $setup_args                                                          {
41
+	 *                                                                                    An array of items related to
42
+	 *                                                                                    registering capabilities.
43
+	 * @type array   $capabilities                                                        An array mapping capability
44
+	 *       strings to core WP Role. Something like: array(
45
+	 *                                                                                    'administrator'    => array(
46
+	 *                                                                                    'read_cap', 'edit_cap',
47
+	 *                                                                                    'delete_cap'),
48
+	 *                                                                                    'author'                =>
49
+	 *                                                                                    array( 'read_cap' )
50
+	 *                                                                                    ).
51
+	 * @type array   $capability_maps                                                     EE_Meta_Capability_Map[]
52
+	 * @see   EE_Capabilities.php for php docs on these objects.
53
+	 *                                                                                    Should be indexed by the
54
+	 *                                                                                    classname for the capability
55
+	 *                                                                                    map and values representing
56
+	 *                                                                                    the arguments for the map.
57
+	 *                                                                                    }
58
+	 * @throws EE_Error
59
+	 * @return void
60
+	 */
61
+	public static function register($cap_reference = null, $setup_args = array())
62
+	{
63
+		//required fields MUST be present, so let's make sure they are.
64
+		if ($cap_reference === null || ! is_array($setup_args) || empty($setup_args['capabilities'])) {
65
+			throw new EE_Error(
66
+				__('In order to register capabilities with EE_Register_Capabilities::register, you must include a unique name to reference the capabilities being registered, plus an array containing the following keys: "capabilities".',
67
+					'event_espresso')
68
+			);
69
+		}
70
+		//make sure we don't register twice
71
+		if (isset(self::$_registry[$cap_reference])) {
72
+			return;
73
+		}
74
+		//make sure this is not registered too late or too early.
75
+		if (! did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')) {
76
+			EE_Error::doing_it_wrong(__METHOD__,
77
+				sprintf(__('%s has been registered too late.  Please ensure that EE_Register_Capabilities::register has been called at some point before the "AHEE__EE_System___detect_if_activation_or_upgrade__begin" action hook has been called.',
78
+					'event_espresso'), $cap_reference), '4.5.0');
79
+		}
80
+		//some preliminary sanitization and setting to the $_registry property
81
+		self::$_registry[ $cap_reference ] = array(
82
+			'caps'               => isset($setup_args['capabilities']) && is_array($setup_args['capabilities'])
83
+				? $setup_args['capabilities']
84
+				: array(),
85
+			'cap_maps'           => isset($setup_args['capability_maps'])
86
+				? $setup_args['capability_maps']
87
+				: array(),
88
+		);
89
+		//set initial caps (note that EE_Capabilities takes care of making sure that the caps get added only once)
90
+		add_filter(
91
+			'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
92
+			array('EE_Register_Capabilities', 'register_capabilities')
93
+		);
94
+		//add filter for cap maps
95
+		add_filter(
96
+			'FHEE__EE_Capabilities___set_meta_caps__meta_caps',
97
+			array('EE_Register_Capabilities', 'register_cap_maps')
98
+		);
99
+	}
100 100
 
101 101
 
102
-    /**
103
-     * callback for FHEE__EE_Capabilities__init_caps_map__caps filter.
104
-     * Takes care of registering additional capabilities to the caps map.   Note, that this also on the initial
105
-     * registration ensures that new capabilities are added to existing roles.
106
-     *
107
-     * @param array $incoming_caps The original caps map.
108
-     * @return array merged in new caps.
109
-     */
110
-    public static function register_capabilities($incoming_caps)
111
-    {
112
-        foreach (self::$_registry as $cap_reference => $caps_and_cap_map) {
113
-            $incoming_caps = array_merge_recursive($incoming_caps, $caps_and_cap_map['caps']);
114
-        }
115
-        return $incoming_caps;
116
-    }
102
+	/**
103
+	 * callback for FHEE__EE_Capabilities__init_caps_map__caps filter.
104
+	 * Takes care of registering additional capabilities to the caps map.   Note, that this also on the initial
105
+	 * registration ensures that new capabilities are added to existing roles.
106
+	 *
107
+	 * @param array $incoming_caps The original caps map.
108
+	 * @return array merged in new caps.
109
+	 */
110
+	public static function register_capabilities($incoming_caps)
111
+	{
112
+		foreach (self::$_registry as $cap_reference => $caps_and_cap_map) {
113
+			$incoming_caps = array_merge_recursive($incoming_caps, $caps_and_cap_map['caps']);
114
+		}
115
+		return $incoming_caps;
116
+	}
117 117
 
118 118
 
119
-    /**
120
-     * Callback for the 'FHEE__EE_Capabilities___set_meta_caps__meta_caps' filter which registers an array of
121
-     * capability maps for the WP meta_caps filter called in EE_Capabilities.
122
-     *
123
-     * @since 4.5.0
124
-     * @param EE_Meta_Capability_Map[] $cap_maps The existing cap maps array.
125
-     * @return EE_Meta_Capability_Map[]
126
-     * @throws EE_Error
127
-     */
128
-    public static function register_cap_maps($cap_maps)
129
-    {
130
-        //loop through and instantiate cap maps.
131
-        foreach (self::$_registry as $cap_reference => $setup) {
132
-            if (! isset($setup['cap_maps'])) {
133
-                continue;
134
-            }
135
-            foreach ($setup['cap_maps'] as $cap_class => $args) {
119
+	/**
120
+	 * Callback for the 'FHEE__EE_Capabilities___set_meta_caps__meta_caps' filter which registers an array of
121
+	 * capability maps for the WP meta_caps filter called in EE_Capabilities.
122
+	 *
123
+	 * @since 4.5.0
124
+	 * @param EE_Meta_Capability_Map[] $cap_maps The existing cap maps array.
125
+	 * @return EE_Meta_Capability_Map[]
126
+	 * @throws EE_Error
127
+	 */
128
+	public static function register_cap_maps($cap_maps)
129
+	{
130
+		//loop through and instantiate cap maps.
131
+		foreach (self::$_registry as $cap_reference => $setup) {
132
+			if (! isset($setup['cap_maps'])) {
133
+				continue;
134
+			}
135
+			foreach ($setup['cap_maps'] as $cap_class => $args) {
136 136
 
137
-                /**
138
-                 * account for cases where capability maps may be indexed
139
-                 * numerically to allow for the same map class to be utilized
140
-                 * In those cases, maps will be setup in an array like:
141
-                 * array(
142
-                 *    0 => array( 'EE_Meta_Capability' => array(
143
-                 *        'ee_edit_cap', array( 'Object_Name',
144
-                 *        'ee_edit_published_cap',
145
-                 *        'ee_edit_others_cap', 'ee_edit_private_cap' )
146
-                 *        ) )
147
-                 *    1 => ...
148
-                 * )
149
-                 * instead of:
150
-                 * array(
151
-                 *    'EE_Meta_Capability' => array(
152
-                 *        'ee_edit_cap', array( 'Object_Name',
153
-                 *        'ee_edit_published_cap',
154
-                 *        'ee_edit_others_cap', 'ee_edit_private_cap' )
155
-                 *        ),
156
-                 *    ...
157
-                 * )
158
-                 */
159
-                if (is_numeric($cap_class)) {
160
-                    $cap_class = key($args);
161
-                    $args      = $args[$cap_class];
162
-                }
137
+				/**
138
+				 * account for cases where capability maps may be indexed
139
+				 * numerically to allow for the same map class to be utilized
140
+				 * In those cases, maps will be setup in an array like:
141
+				 * array(
142
+				 *    0 => array( 'EE_Meta_Capability' => array(
143
+				 *        'ee_edit_cap', array( 'Object_Name',
144
+				 *        'ee_edit_published_cap',
145
+				 *        'ee_edit_others_cap', 'ee_edit_private_cap' )
146
+				 *        ) )
147
+				 *    1 => ...
148
+				 * )
149
+				 * instead of:
150
+				 * array(
151
+				 *    'EE_Meta_Capability' => array(
152
+				 *        'ee_edit_cap', array( 'Object_Name',
153
+				 *        'ee_edit_published_cap',
154
+				 *        'ee_edit_others_cap', 'ee_edit_private_cap' )
155
+				 *        ),
156
+				 *    ...
157
+				 * )
158
+				 */
159
+				if (is_numeric($cap_class)) {
160
+					$cap_class = key($args);
161
+					$args      = $args[$cap_class];
162
+				}
163 163
 
164
-                if (! class_exists($cap_class)) {
165
-                    throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly.  Capability map arrays must be indexed by capability map classname, and an array for the class arguments',
166
-                        'event_espresso'), $cap_reference));
167
-                }
164
+				if (! class_exists($cap_class)) {
165
+					throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly.  Capability map arrays must be indexed by capability map classname, and an array for the class arguments',
166
+						'event_espresso'), $cap_reference));
167
+				}
168 168
 
169
-                if (count($args) !== 2) {
170
-                    throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly.  Capability map arrays must be indexed by capability map classname, and an array for the class arguments.  The array should have two values the first being a string and the second an array.',
171
-                        'event_espresso'), $cap_reference));
172
-                }
173
-                $cap_maps[] = new $cap_class($args[0], $args[1]);
174
-            }
175
-        }
176
-        return $cap_maps;
177
-    }
169
+				if (count($args) !== 2) {
170
+					throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly.  Capability map arrays must be indexed by capability map classname, and an array for the class arguments.  The array should have two values the first being a string and the second an array.',
171
+						'event_espresso'), $cap_reference));
172
+				}
173
+				$cap_maps[] = new $cap_class($args[0], $args[1]);
174
+			}
175
+		}
176
+		return $cap_maps;
177
+	}
178 178
 
179 179
 
180 180
 
181
-    /**
182
-     * @param string $cap_reference
183
-     * @throws EE_Error
184
-     */
185
-    public static function deregister($cap_reference = '')
186
-    {
187
-        if (! empty(self::$_registry[$cap_reference])) {
188
-            if (! empty(self::$_registry[ $cap_reference ]['caps'])) {
189
-                EE_Capabilities::instance()->removeCaps(self::$_registry[ $cap_reference ]['caps']);
190
-            }
191
-            unset(self::$_registry[$cap_reference]);
192
-        }
193
-    }
181
+	/**
182
+	 * @param string $cap_reference
183
+	 * @throws EE_Error
184
+	 */
185
+	public static function deregister($cap_reference = '')
186
+	{
187
+		if (! empty(self::$_registry[$cap_reference])) {
188
+			if (! empty(self::$_registry[ $cap_reference ]['caps'])) {
189
+				EE_Capabilities::instance()->removeCaps(self::$_registry[ $cap_reference ]['caps']);
190
+			}
191
+			unset(self::$_registry[$cap_reference]);
192
+		}
193
+	}
194 194
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@  discard block
 block discarded – undo
6 6
  * @subpackage      plugin api, capabilities
7 7
  * @since           4.5.0
8 8
  */
9
-if (! defined('EVENT_ESPRESSO_VERSION')) {
9
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
10 10
     exit('No direct script access allowed');
11 11
 }
12 12
 
@@ -72,13 +72,13 @@  discard block
 block discarded – undo
72 72
             return;
73 73
         }
74 74
         //make sure this is not registered too late or too early.
75
-        if (! did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')) {
75
+        if ( ! did_action('AHEE__EE_System__load_espresso_addons') || did_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin')) {
76 76
             EE_Error::doing_it_wrong(__METHOD__,
77 77
                 sprintf(__('%s has been registered too late.  Please ensure that EE_Register_Capabilities::register has been called at some point before the "AHEE__EE_System___detect_if_activation_or_upgrade__begin" action hook has been called.',
78 78
                     'event_espresso'), $cap_reference), '4.5.0');
79 79
         }
80 80
         //some preliminary sanitization and setting to the $_registry property
81
-        self::$_registry[ $cap_reference ] = array(
81
+        self::$_registry[$cap_reference] = array(
82 82
             'caps'               => isset($setup_args['capabilities']) && is_array($setup_args['capabilities'])
83 83
                 ? $setup_args['capabilities']
84 84
                 : array(),
@@ -129,7 +129,7 @@  discard block
 block discarded – undo
129 129
     {
130 130
         //loop through and instantiate cap maps.
131 131
         foreach (self::$_registry as $cap_reference => $setup) {
132
-            if (! isset($setup['cap_maps'])) {
132
+            if ( ! isset($setup['cap_maps'])) {
133 133
                 continue;
134 134
             }
135 135
             foreach ($setup['cap_maps'] as $cap_class => $args) {
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
                     $args      = $args[$cap_class];
162 162
                 }
163 163
 
164
-                if (! class_exists($cap_class)) {
164
+                if ( ! class_exists($cap_class)) {
165 165
                     throw new EE_Error(sprintf(__('An addon (%s) has tried to register a capability map improperly.  Capability map arrays must be indexed by capability map classname, and an array for the class arguments',
166 166
                         'event_espresso'), $cap_reference));
167 167
                 }
@@ -184,9 +184,9 @@  discard block
 block discarded – undo
184 184
      */
185 185
     public static function deregister($cap_reference = '')
186 186
     {
187
-        if (! empty(self::$_registry[$cap_reference])) {
188
-            if (! empty(self::$_registry[ $cap_reference ]['caps'])) {
189
-                EE_Capabilities::instance()->removeCaps(self::$_registry[ $cap_reference ]['caps']);
187
+        if ( ! empty(self::$_registry[$cap_reference])) {
188
+            if ( ! empty(self::$_registry[$cap_reference]['caps'])) {
189
+                EE_Capabilities::instance()->removeCaps(self::$_registry[$cap_reference]['caps']);
190 190
             }
191 191
             unset(self::$_registry[$cap_reference]);
192 192
         }
Please login to merge, or discard this patch.
core/libraries/payment_methods/EE_Payment_Method_Manager.lib.php 2 patches
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -20,7 +20,7 @@  discard block
 block discarded – undo
20 20
     /**
21 21
      * prefix added to all payment method capabilities names
22 22
      */
23
-    const   CAPABILITIES_PREFIX= 'ee_payment_method_';
23
+    const   CAPABILITIES_PREFIX = 'ee_payment_method_';
24 24
 
25 25
     /**
26 26
      * @var EE_Payment_Method_Manager $_instance
@@ -76,7 +76,7 @@  discard block
 block discarded – undo
76 76
     public static function instance()
77 77
     {
78 78
         // check if class object is instantiated, and instantiated properly
79
-        if (! self::$_instance instanceof EE_Payment_Method_Manager) {
79
+        if ( ! self::$_instance instanceof EE_Payment_Method_Manager) {
80 80
             EE_Registry::instance()->load_lib('PMT_Base');
81 81
             self::$_instance = new self();
82 82
         }
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
      */
110 110
     public function maybe_register_payment_methods($force_recheck = false)
111 111
     {
112
-        if (! $this->_payment_method_types || $force_recheck) {
112
+        if ( ! $this->_payment_method_types || $force_recheck) {
113 113
             $this->_register_payment_methods();
114 114
         }
115 115
     }
@@ -124,7 +124,7 @@  discard block
 block discarded – undo
124 124
     protected function _register_payment_methods()
125 125
     {
126 126
         // grab list of installed modules
127
-        $pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR);
127
+        $pm_to_register = glob(EE_PAYMENT_METHODS.'*', GLOB_ONLYDIR);
128 128
         // filter list of modules to register
129 129
         $pm_to_register = apply_filters(
130 130
             'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
@@ -165,31 +165,31 @@  discard block
 block discarded – undo
165 165
         // create class name from module directory name
166 166
         $module = str_replace(array('_', ' '), array(' ', '_'), $module_dir);
167 167
         // add class prefix
168
-        $module_class = 'EE_PMT_' . $module;
168
+        $module_class = 'EE_PMT_'.$module;
169 169
         // does the module exist ?
170
-        if (! is_readable($payment_method_path . DS . $module_class . $module_ext)) {
170
+        if ( ! is_readable($payment_method_path.DS.$module_class.$module_ext)) {
171 171
             $msg = sprintf(
172 172
                 esc_html__(
173 173
                     'The requested %s payment method file could not be found or is not readable due to file permissions.',
174 174
                     'event_espresso'
175 175
                 ), $module
176 176
             );
177
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
177
+            EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
178 178
             return false;
179 179
         }
180 180
         // load the module class file
181
-        require_once($payment_method_path . DS . $module_class . $module_ext);
181
+        require_once($payment_method_path.DS.$module_class.$module_ext);
182 182
         // verify that class exists
183
-        if (! class_exists($module_class)) {
183
+        if ( ! class_exists($module_class)) {
184 184
             $msg = sprintf(
185 185
                 esc_html__('The requested %s module class does not exist.', 'event_espresso'),
186 186
                 $module_class
187 187
             );
188
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
188
+            EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
189 189
             return false;
190 190
         }
191 191
         // add to array of registered modules
192
-        $this->_payment_method_types[$module] = $payment_method_path . DS . $module_class . $module_ext;
192
+        $this->_payment_method_types[$module] = $payment_method_path.DS.$module_class.$module_ext;
193 193
         return true;
194 194
     }
195 195
 
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
         if ($force_recheck || empty($this->payment_method_objects)) {
257 257
             $this->maybe_register_payment_methods($force_recheck);
258 258
             foreach ($this->payment_method_type_names(true) as $classname) {
259
-                if (! isset($this->payment_method_objects[$classname])) {
259
+                if ( ! isset($this->payment_method_objects[$classname])) {
260 260
                     $this->payment_method_objects[$classname] = new $classname;
261 261
                 }
262 262
             }
@@ -288,7 +288,7 @@  discard block
 block discarded – undo
288 288
      */
289 289
     public function payment_method_class_from_type($type)
290 290
     {
291
-        return 'EE_PMT_' . $type;
291
+        return 'EE_PMT_'.$type;
292 292
     }
293 293
 
294 294
 
@@ -304,13 +304,13 @@  discard block
 block discarded – undo
304 304
     {
305 305
         $this->maybe_register_payment_methods();
306 306
         $payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type);
307
-        if (! $payment_method instanceof EE_Payment_Method) {
307
+        if ( ! $payment_method instanceof EE_Payment_Method) {
308 308
             $pm_type_class = $this->payment_method_class_from_type($payment_method_type);
309 309
             if (class_exists($pm_type_class)) {
310 310
                 /** @var $pm_type_obj EE_PMT_Base */
311 311
                 $pm_type_obj = new $pm_type_class;
312 312
                 $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name());
313
-                if (! $payment_method) {
313
+                if ( ! $payment_method) {
314 314
                     $payment_method = $this->create_payment_method_of_type($pm_type_obj);
315 315
                 }
316 316
                 $payment_method->set_type($payment_method_type);
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
                         'The Invoice payment method has been activated. It requires the invoice message type, html messenger, and pdf messenger be activated as well for the %1$smessages system%2$s, so it has been automatically verified that they are also active.',
342 342
                         'event_espresso'
343 343
                     ),
344
-                    '<a href="' . admin_url('admin.php?page=espresso_messages') . '">',
344
+                    '<a href="'.admin_url('admin.php?page=espresso_messages').'">',
345 345
                     '</a>'
346 346
                 ),
347 347
                 true
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
                 'PMD_type'       => $pm_type_obj->system_name(),
369 369
                 'PMD_name'       => $pm_type_obj->pretty_name(),
370 370
                 'PMD_admin_name' => $pm_type_obj->pretty_name(),
371
-                'PMD_slug'       => $pm_type_obj->system_name(),//automatically converted to slug
371
+                'PMD_slug'       => $pm_type_obj->system_name(), //automatically converted to slug
372 372
                 'PMD_wp_user'    => $current_user->ID,
373 373
                 'PMD_order'      => EEM_Payment_Method::instance()->count(
374 374
                         array(array('PMD_type' => array('!=', 'Admin_Only')))
@@ -391,14 +391,14 @@  discard block
 block discarded – undo
391 391
     {
392 392
         $pm_type_obj = $payment_method->type_obj();
393 393
         $payment_method->set_description($pm_type_obj->default_description());
394
-        if (! $payment_method->button_url()) {
394
+        if ( ! $payment_method->button_url()) {
395 395
             $payment_method->set_button_url($pm_type_obj->default_button_url());
396 396
         }
397 397
         //now add setup its default extra meta properties
398 398
         $extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs();
399
-        if (! empty($extra_metas)) {
399
+        if ( ! empty($extra_metas)) {
400 400
             //verify the payment method has an ID before adding extra meta
401
-            if (! $payment_method->ID()) {
401
+            if ( ! $payment_method->ID()) {
402 402
                 $payment_method->save();
403 403
             }
404 404
             foreach ($extra_metas as $meta_name => $input) {
@@ -506,7 +506,7 @@  discard block
 block discarded – undo
506 506
     {
507 507
         $caps = array();
508 508
         foreach ($this->payment_method_type_names() as $payment_method_name) {
509
-            $caps = $this->addPaymentMethodCap($payment_method_name,$caps);
509
+            $caps = $this->addPaymentMethodCap($payment_method_name, $caps);
510 510
         }
511 511
         return $caps;
512 512
     }
@@ -541,7 +541,7 @@  discard block
 block discarded – undo
541 541
                 )
542 542
             );
543 543
         }
544
-        if(! isset($payment_method_caps[$role])) {
544
+        if ( ! isset($payment_method_caps[$role])) {
545 545
             $payment_method_caps[$role] = array();
546 546
         }
547 547
         $payment_method_caps[$role][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
Please login to merge, or discard this patch.
Indentation   +564 added lines, -564 removed lines patch added patch discarded remove patch
@@ -19,570 +19,570 @@
 block discarded – undo
19 19
 class EE_Payment_Method_Manager implements ResettableInterface
20 20
 {
21 21
 
22
-    /**
23
-     * prefix added to all payment method capabilities names
24
-     */
25
-    const   CAPABILITIES_PREFIX= 'ee_payment_method_';
26
-
27
-    /**
28
-     * @var EE_Payment_Method_Manager $_instance
29
-     */
30
-    private static $_instance;
31
-
32
-    /**
33
-     * @var boolean
34
-     */
35
-    protected $payment_method_caps_initialized = false;
36
-
37
-    /**
38
-     * @var array keys are class names without 'EE_PMT_', values are their filepaths
39
-     */
40
-    protected $_payment_method_types = array();
41
-
42
-    /**
43
-     * @var EE_PMT_Base[]
44
-     */
45
-    protected $payment_method_objects = array();
46
-
47
-
48
-
49
-    /**
50
-     * EE_Payment_Method_Manager constructor.
51
-     *
52
-     * @throws EE_Error
53
-     * @throws DomainException
54
-     */
55
-    public function __construct()
56
-    {
57
-        // if in admin lets ensure caps are set.
58
-        if (is_admin()) {
59
-            $this->_register_payment_methods();
60
-            // set them immediately
61
-            $this->initializePaymentMethodCaps();
62
-            // plus any time they get reset
63
-            add_filter(
64
-                'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
65
-                array($this, 'addPaymentMethodCapsDuringReset')
66
-            );
67
-        }
68
-    }
69
-
70
-
71
-
72
-    /**
73
-     * @singleton method used to instantiate class object
74
-     * @return EE_Payment_Method_Manager instance
75
-     * @throws DomainException
76
-     * @throws EE_Error
77
-     */
78
-    public static function instance()
79
-    {
80
-        // check if class object is instantiated, and instantiated properly
81
-        if (! self::$_instance instanceof EE_Payment_Method_Manager) {
82
-            EE_Registry::instance()->load_lib('PMT_Base');
83
-            self::$_instance = new self();
84
-        }
85
-        return self::$_instance;
86
-    }
87
-
88
-
89
-
90
-    /**
91
-     * Resets the instance and returns a new one
92
-     *
93
-     * @return EE_Payment_Method_Manager
94
-     * @throws DomainException
95
-     * @throws EE_Error
96
-     */
97
-    public static function reset()
98
-    {
99
-        self::$_instance = null;
100
-        return self::instance();
101
-    }
102
-
103
-
104
-
105
-    /**
106
-     * If necessary, re-register payment methods
107
-     *
108
-     * @param boolean $force_recheck whether to recheck for payment method types,
109
-     *                               or just re-use the PMTs we found last time we checked during this request (if
110
-     *                               we have not yet checked during this request, then we need to check anyways)
111
-     */
112
-    public function maybe_register_payment_methods($force_recheck = false)
113
-    {
114
-        if (! $this->_payment_method_types || $force_recheck) {
115
-            $this->_register_payment_methods();
116
-        }
117
-    }
118
-
119
-
120
-
121
-    /**
122
-     * register_payment_methods
123
-     *
124
-     * @return array
125
-     */
126
-    protected function _register_payment_methods()
127
-    {
128
-        // grab list of installed modules
129
-        $pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR);
130
-        // filter list of modules to register
131
-        $pm_to_register = apply_filters(
132
-            'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
133
-            $pm_to_register
134
-        );
135
-        // remove any duplicates if that should happen for some reason
136
-        $pm_to_register = array_unique($pm_to_register);
137
-        // loop through folders
138
-        foreach ($pm_to_register as $pm_path) {
139
-            $this->register_payment_method($pm_path);
140
-        }
141
-        do_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods');
142
-        // filter list of installed modules
143
-        //keep them organized alphabetically by the payment method type's name
144
-        ksort($this->_payment_method_types);
145
-        return apply_filters(
146
-            'FHEE__EE_Payment_Method_Manager__register_payment_methods__installed_payment_methods',
147
-            $this->_payment_method_types
148
-        );
149
-    }
150
-
151
-
152
-
153
-    /**
154
-     * register_payment_method- makes core aware of this payment method
155
-     *
156
-     * @param string $payment_method_path - full path up to and including payment method folder
157
-     * @return boolean
158
-     */
159
-    public function register_payment_method($payment_method_path = '')
160
-    {
161
-        do_action('AHEE__EE_Payment_Method_Manager__register_payment_method__begin', $payment_method_path);
162
-        $module_ext = '.pm.php';
163
-        // make all separators match
164
-        $payment_method_path = rtrim(str_replace('/\\', DS, $payment_method_path), DS);
165
-        // grab and sanitize module name
166
-        $module_dir = basename($payment_method_path);
167
-        // create class name from module directory name
168
-        $module = str_replace(array('_', ' '), array(' ', '_'), $module_dir);
169
-        // add class prefix
170
-        $module_class = 'EE_PMT_' . $module;
171
-        // does the module exist ?
172
-        if (! is_readable($payment_method_path . DS . $module_class . $module_ext)) {
173
-            $msg = sprintf(
174
-                esc_html__(
175
-                    'The requested %s payment method file could not be found or is not readable due to file permissions.',
176
-                    'event_espresso'
177
-                ), $module
178
-            );
179
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
180
-            return false;
181
-        }
182
-        // load the module class file
183
-        require_once($payment_method_path . DS . $module_class . $module_ext);
184
-        // verify that class exists
185
-        if (! class_exists($module_class)) {
186
-            $msg = sprintf(
187
-                esc_html__('The requested %s module class does not exist.', 'event_espresso'),
188
-                $module_class
189
-            );
190
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
191
-            return false;
192
-        }
193
-        // add to array of registered modules
194
-        $this->_payment_method_types[$module] = $payment_method_path . DS . $module_class . $module_ext;
195
-        return true;
196
-    }
197
-
198
-
199
-
200
-    /**
201
-     * Checks if a payment method has been registered, and if so includes it
202
-     *
203
-     * @param string  $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_')
204
-     * @param boolean $force_recheck       whether to force re-checking for new payment method types
205
-     * @return boolean
206
-     */
207
-    public function payment_method_type_exists($payment_method_name, $force_recheck = false)
208
-    {
209
-        if (
210
-            $force_recheck
211
-            || ! is_array($this->_payment_method_types)
212
-            || ! isset($this->_payment_method_types[$payment_method_name])
213
-        ) {
214
-            $this->maybe_register_payment_methods($force_recheck);
215
-        }
216
-        if (isset($this->_payment_method_types[$payment_method_name])) {
217
-            require_once($this->_payment_method_types[$payment_method_name]);
218
-            return true;
219
-        }
220
-        return false;
221
-    }
222
-
223
-
224
-
225
-    /**
226
-     * Returns all the class names of the various payment method types
227
-     *
228
-     * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names'
229
-     *                               (what you'd find in wp_esp_payment_method.PMD_type)
230
-     * @param boolean $force_recheck whether to force re-checking for new payment method types
231
-     * @return array
232
-     */
233
-    public function payment_method_type_names($with_prefixes = false, $force_recheck = false)
234
-    {
235
-        $this->maybe_register_payment_methods($force_recheck);
236
-        if ($with_prefixes) {
237
-            $classnames = array_keys($this->_payment_method_types);
238
-            $payment_methods = array();
239
-            foreach ($classnames as $classname) {
240
-                $payment_methods[] = $this->payment_method_class_from_type($classname);
241
-            }
242
-            return $payment_methods;
243
-        }
244
-        return array_keys($this->_payment_method_types);
245
-    }
246
-
247
-
248
-
249
-    /**
250
-     * Gets an object of each payment method type, none of which are bound to a
251
-     * payment method instance
252
-     *
253
-     * @param boolean $force_recheck whether to force re-checking for new payment method types
254
-     * @return EE_PMT_Base[]
255
-     */
256
-    public function payment_method_types($force_recheck = false)
257
-    {
258
-        if ($force_recheck || empty($this->payment_method_objects)) {
259
-            $this->maybe_register_payment_methods($force_recheck);
260
-            foreach ($this->payment_method_type_names(true) as $classname) {
261
-                if (! isset($this->payment_method_objects[$classname])) {
262
-                    $this->payment_method_objects[$classname] = new $classname;
263
-                }
264
-            }
265
-        }
266
-        return $this->payment_method_objects;
267
-    }
268
-
269
-
270
-
271
-    /**
272
-     * Changes the payment method's class name into the payment method type's name
273
-     * (as used on the payment method's table's PMD_type field)
274
-     *
275
-     * @param string $classname
276
-     * @return string
277
-     */
278
-    public function payment_method_type_sans_class_prefix($classname)
279
-    {
280
-        return str_replace('EE_PMT_', '', $classname);
281
-    }
282
-
283
-
284
-
285
-    /**
286
-     * Does the opposite of payment-method_type_sans_prefix
287
-     *
288
-     * @param string $type
289
-     * @return string
290
-     */
291
-    public function payment_method_class_from_type($type)
292
-    {
293
-        return 'EE_PMT_' . $type;
294
-    }
295
-
296
-
297
-
298
-    /**
299
-     * Activates a payment method of the given type.
300
-     *
301
-     * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice'
302
-     * @return EE_Payment_Method
303
-     * @throws EE_Error
304
-     */
305
-    public function activate_a_payment_method_of_type($payment_method_type)
306
-    {
307
-        $this->maybe_register_payment_methods();
308
-        $payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type);
309
-        if (! $payment_method instanceof EE_Payment_Method) {
310
-            $pm_type_class = $this->payment_method_class_from_type($payment_method_type);
311
-            if (class_exists($pm_type_class)) {
312
-                /** @var $pm_type_obj EE_PMT_Base */
313
-                $pm_type_obj = new $pm_type_class;
314
-                $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name());
315
-                if (! $payment_method) {
316
-                    $payment_method = $this->create_payment_method_of_type($pm_type_obj);
317
-                }
318
-                $payment_method->set_type($payment_method_type);
319
-                $this->initialize_payment_method($payment_method);
320
-            } else {
321
-                throw new EE_Error(
322
-                    sprintf(
323
-                        esc_html__(
324
-                            'There is no payment method of type %1$s, so it could not be activated',
325
-                            'event_espresso'
326
-                        ),
327
-                        $pm_type_class
328
-                    )
329
-                );
330
-            }
331
-        }
332
-        $payment_method->set_active();
333
-        $payment_method->save();
334
-        if ($payment_method->type() === 'Invoice') {
335
-            /** @type EE_Message_Resource_Manager $message_resource_manager */
336
-            $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
337
-            $message_resource_manager->ensure_message_type_is_active('invoice', 'html');
338
-            $message_resource_manager->ensure_messenger_is_active('pdf');
339
-            EE_Error::add_persistent_admin_notice(
340
-                'invoice_pm_requirements_notice',
341
-                sprintf(
342
-                    esc_html__(
343
-                        'The Invoice payment method has been activated. It requires the invoice message type, html messenger, and pdf messenger be activated as well for the %1$smessages system%2$s, so it has been automatically verified that they are also active.',
344
-                        'event_espresso'
345
-                    ),
346
-                    '<a href="' . admin_url('admin.php?page=espresso_messages') . '">',
347
-                    '</a>'
348
-                ),
349
-                true
350
-            );
351
-        }
352
-        return $payment_method;
353
-    }
354
-
355
-
356
-
357
-    /**
358
-     * Creates a payment method of the specified type. Does not save it.
359
-     *
360
-     * @global WP_User    $current_user
361
-     * @param EE_PMT_Base $pm_type_obj
362
-     * @return EE_Payment_Method
363
-     * @throws EE_Error
364
-     */
365
-    public function create_payment_method_of_type($pm_type_obj)
366
-    {
367
-        global $current_user;
368
-        $payment_method = EE_Payment_Method::new_instance(
369
-            array(
370
-                'PMD_type'       => $pm_type_obj->system_name(),
371
-                'PMD_name'       => $pm_type_obj->pretty_name(),
372
-                'PMD_admin_name' => $pm_type_obj->pretty_name(),
373
-                'PMD_slug'       => $pm_type_obj->system_name(),//automatically converted to slug
374
-                'PMD_wp_user'    => $current_user->ID,
375
-                'PMD_order'      => EEM_Payment_Method::instance()->count(
376
-                        array(array('PMD_type' => array('!=', 'Admin_Only')))
377
-                    ) * 10,
378
-            )
379
-        );
380
-        return $payment_method;
381
-    }
382
-
383
-
384
-
385
-    /**
386
-     * Sets the initial payment method properties (including extra meta)
387
-     *
388
-     * @param EE_Payment_Method $payment_method
389
-     * @return EE_Payment_Method
390
-     * @throws EE_Error
391
-     */
392
-    public function initialize_payment_method($payment_method)
393
-    {
394
-        $pm_type_obj = $payment_method->type_obj();
395
-        $payment_method->set_description($pm_type_obj->default_description());
396
-        if (! $payment_method->button_url()) {
397
-            $payment_method->set_button_url($pm_type_obj->default_button_url());
398
-        }
399
-        //now add setup its default extra meta properties
400
-        $extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs();
401
-        if (! empty($extra_metas)) {
402
-            //verify the payment method has an ID before adding extra meta
403
-            if (! $payment_method->ID()) {
404
-                $payment_method->save();
405
-            }
406
-            foreach ($extra_metas as $meta_name => $input) {
407
-                $payment_method->update_extra_meta($meta_name, $input->raw_value());
408
-            }
409
-        }
410
-        return $payment_method;
411
-    }
412
-
413
-
414
-
415
-    /**
416
-     * Makes sure the payment method is related to the specified payment method
417
-     *
418
-     * @deprecated in 4.9.40 because the currency payment method table is being deprecated
419
-     * @param EE_Payment_Method $payment_method
420
-     * @return EE_Payment_Method
421
-     * @throws EE_Error
422
-     */
423
-    public function set_usable_currencies_on_payment_method($payment_method)
424
-    {
425
-        EE_Error::doing_it_wrong(
426
-            'EE_Payment_Method_Manager::set_usable_currencies_on_payment_method',
427
-            esc_html__(
428
-                'We no longer define what currencies are usable by payment methods. Its not used nor efficient.',
429
-                'event_espresso'
430
-            ),
431
-            '4.9.40'
432
-        );
433
-        return $payment_method;
434
-    }
435
-
436
-
437
-
438
-    /**
439
-     * Deactivates a payment method of the given payment method slug.
440
-     *
441
-     * @param string $payment_method_slug The slug for the payment method to deactivate.
442
-     * @return int count of rows updated.
443
-     * @throws EE_Error
444
-     */
445
-    public function deactivate_payment_method($payment_method_slug)
446
-    {
447
-        EE_Log::instance()->log(
448
-            __FILE__,
449
-            __FUNCTION__,
450
-            sprintf(
451
-                esc_html__(
452
-                    'Payment method with slug %1$s is being deactivated by site admin',
453
-                    'event_espresso'
454
-                ),
455
-                $payment_method_slug
456
-            ),
457
-            'payment_method_change'
458
-        );
459
-        $count_updated = EEM_Payment_Method::instance()->update(
460
-            array('PMD_scope' => array()),
461
-            array(array('PMD_slug' => $payment_method_slug))
462
-        );
463
-        return $count_updated;
464
-    }
465
-
466
-
467
-
468
-    /**
469
-     * initializes payment method access caps via EE_Capabilities::init_role_caps()
470
-     * upon EE_Payment_Method_Manager construction
471
-     *
472
-     * @throws EE_Error
473
-     * @throws DomainException
474
-     */
475
-    protected function initializePaymentMethodCaps()
476
-    {
477
-        // don't do this twice
478
-        if ($this->payment_method_caps_initialized) {
479
-            return;
480
-        }
481
-        EE_Capabilities::instance()->addCaps(
482
-            $this->getPaymentMethodCaps()
483
-        );
484
-        $this->payment_method_caps_initialized = true;
485
-    }
486
-
487
-
488
-
489
-    /**
490
-     * array  of dynamic payment method access caps.
491
-     * at the time of writing, october 20 2014, these are the caps added:
492
-     *  ee_payment_method_admin_only
493
-     *  ee_payment_method_aim
494
-     *  ee_payment_method_bank
495
-     *  ee_payment_method_check
496
-     *  ee_payment_method_invoice
497
-     *  ee_payment_method_mijireh
498
-     *  ee_payment_method_paypal_pro
499
-     *  ee_payment_method_paypal_standard
500
-     * Any other payment methods added to core or via addons will also get
501
-     * their related capability automatically added too, so long as they are
502
-     * registered properly using EE_Register_Payment_Method::register()
503
-     *
504
-     * @return array
505
-     * @throws DomainException
506
-     */
507
-    protected function getPaymentMethodCaps()
508
-    {
509
-        $caps = array();
510
-        foreach ($this->payment_method_type_names() as $payment_method_name) {
511
-            $caps = $this->addPaymentMethodCap($payment_method_name,$caps);
512
-        }
513
-        return $caps;
514
-    }
515
-
516
-
517
-
518
-    /**
519
-     * @param string $payment_method_name
520
-     * @param array  $payment_method_caps
521
-     * @param string $role
522
-     * @return array
523
-     * @throws DomainException
524
-     */
525
-    public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator')
526
-    {
527
-        if (empty($payment_method_name)) {
528
-            throw new DomainException(
529
-                esc_html__(
530
-                    'The name of a payment method must be specified to add capabilities.',
531
-                    'event_espresso'
532
-                )
533
-            );
534
-        }
535
-        if (empty($role)) {
536
-            throw new DomainException(
537
-                sprintf(
538
-                    esc_html__(
539
-                        'No role was supplied while trying to add capabilities for the %1$s payment method.',
540
-                        'event_espresso'
541
-                    ),
542
-                    $payment_method_name
543
-                )
544
-            );
545
-        }
546
-        if(! isset($payment_method_caps[$role])) {
547
-            $payment_method_caps[$role] = array();
548
-        }
549
-        $payment_method_caps[$role][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
550
-                                                  . strtolower($payment_method_name);
551
-        return $payment_method_caps;
552
-    }
553
-
554
-
555
-
556
-    /**
557
-     * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter
558
-     * to add dynamic payment method access caps when capabilities are reset
559
-     * (or if that filter is called and PM caps are not already set)
560
-     *
561
-     * @param array $caps capabilities being filtered
562
-     * @param bool  $reset
563
-     * @return array
564
-     * @throws DomainException
565
-     */
566
-    public function addPaymentMethodCapsDuringReset(array $caps, $reset = false)
567
-    {
568
-        if ($reset || ! $this->payment_method_caps_initialized) {
569
-            $this->payment_method_caps_initialized = true;
570
-            $caps = array_merge_recursive($caps, $this->getPaymentMethodCaps());
571
-        }
572
-        return $caps;
573
-    }
574
-
575
-
576
-
577
-    /**
578
-     * @deprecated 4.9.42
579
-     * @param $caps
580
-     * @return mixed
581
-     */
582
-    public function add_payment_method_caps($caps)
583
-    {
584
-        return $caps;
585
-    }
22
+	/**
23
+	 * prefix added to all payment method capabilities names
24
+	 */
25
+	const   CAPABILITIES_PREFIX= 'ee_payment_method_';
26
+
27
+	/**
28
+	 * @var EE_Payment_Method_Manager $_instance
29
+	 */
30
+	private static $_instance;
31
+
32
+	/**
33
+	 * @var boolean
34
+	 */
35
+	protected $payment_method_caps_initialized = false;
36
+
37
+	/**
38
+	 * @var array keys are class names without 'EE_PMT_', values are their filepaths
39
+	 */
40
+	protected $_payment_method_types = array();
41
+
42
+	/**
43
+	 * @var EE_PMT_Base[]
44
+	 */
45
+	protected $payment_method_objects = array();
46
+
47
+
48
+
49
+	/**
50
+	 * EE_Payment_Method_Manager constructor.
51
+	 *
52
+	 * @throws EE_Error
53
+	 * @throws DomainException
54
+	 */
55
+	public function __construct()
56
+	{
57
+		// if in admin lets ensure caps are set.
58
+		if (is_admin()) {
59
+			$this->_register_payment_methods();
60
+			// set them immediately
61
+			$this->initializePaymentMethodCaps();
62
+			// plus any time they get reset
63
+			add_filter(
64
+				'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
65
+				array($this, 'addPaymentMethodCapsDuringReset')
66
+			);
67
+		}
68
+	}
69
+
70
+
71
+
72
+	/**
73
+	 * @singleton method used to instantiate class object
74
+	 * @return EE_Payment_Method_Manager instance
75
+	 * @throws DomainException
76
+	 * @throws EE_Error
77
+	 */
78
+	public static function instance()
79
+	{
80
+		// check if class object is instantiated, and instantiated properly
81
+		if (! self::$_instance instanceof EE_Payment_Method_Manager) {
82
+			EE_Registry::instance()->load_lib('PMT_Base');
83
+			self::$_instance = new self();
84
+		}
85
+		return self::$_instance;
86
+	}
87
+
88
+
89
+
90
+	/**
91
+	 * Resets the instance and returns a new one
92
+	 *
93
+	 * @return EE_Payment_Method_Manager
94
+	 * @throws DomainException
95
+	 * @throws EE_Error
96
+	 */
97
+	public static function reset()
98
+	{
99
+		self::$_instance = null;
100
+		return self::instance();
101
+	}
102
+
103
+
104
+
105
+	/**
106
+	 * If necessary, re-register payment methods
107
+	 *
108
+	 * @param boolean $force_recheck whether to recheck for payment method types,
109
+	 *                               or just re-use the PMTs we found last time we checked during this request (if
110
+	 *                               we have not yet checked during this request, then we need to check anyways)
111
+	 */
112
+	public function maybe_register_payment_methods($force_recheck = false)
113
+	{
114
+		if (! $this->_payment_method_types || $force_recheck) {
115
+			$this->_register_payment_methods();
116
+		}
117
+	}
118
+
119
+
120
+
121
+	/**
122
+	 * register_payment_methods
123
+	 *
124
+	 * @return array
125
+	 */
126
+	protected function _register_payment_methods()
127
+	{
128
+		// grab list of installed modules
129
+		$pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR);
130
+		// filter list of modules to register
131
+		$pm_to_register = apply_filters(
132
+			'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
133
+			$pm_to_register
134
+		);
135
+		// remove any duplicates if that should happen for some reason
136
+		$pm_to_register = array_unique($pm_to_register);
137
+		// loop through folders
138
+		foreach ($pm_to_register as $pm_path) {
139
+			$this->register_payment_method($pm_path);
140
+		}
141
+		do_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods');
142
+		// filter list of installed modules
143
+		//keep them organized alphabetically by the payment method type's name
144
+		ksort($this->_payment_method_types);
145
+		return apply_filters(
146
+			'FHEE__EE_Payment_Method_Manager__register_payment_methods__installed_payment_methods',
147
+			$this->_payment_method_types
148
+		);
149
+	}
150
+
151
+
152
+
153
+	/**
154
+	 * register_payment_method- makes core aware of this payment method
155
+	 *
156
+	 * @param string $payment_method_path - full path up to and including payment method folder
157
+	 * @return boolean
158
+	 */
159
+	public function register_payment_method($payment_method_path = '')
160
+	{
161
+		do_action('AHEE__EE_Payment_Method_Manager__register_payment_method__begin', $payment_method_path);
162
+		$module_ext = '.pm.php';
163
+		// make all separators match
164
+		$payment_method_path = rtrim(str_replace('/\\', DS, $payment_method_path), DS);
165
+		// grab and sanitize module name
166
+		$module_dir = basename($payment_method_path);
167
+		// create class name from module directory name
168
+		$module = str_replace(array('_', ' '), array(' ', '_'), $module_dir);
169
+		// add class prefix
170
+		$module_class = 'EE_PMT_' . $module;
171
+		// does the module exist ?
172
+		if (! is_readable($payment_method_path . DS . $module_class . $module_ext)) {
173
+			$msg = sprintf(
174
+				esc_html__(
175
+					'The requested %s payment method file could not be found or is not readable due to file permissions.',
176
+					'event_espresso'
177
+				), $module
178
+			);
179
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
180
+			return false;
181
+		}
182
+		// load the module class file
183
+		require_once($payment_method_path . DS . $module_class . $module_ext);
184
+		// verify that class exists
185
+		if (! class_exists($module_class)) {
186
+			$msg = sprintf(
187
+				esc_html__('The requested %s module class does not exist.', 'event_espresso'),
188
+				$module_class
189
+			);
190
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
191
+			return false;
192
+		}
193
+		// add to array of registered modules
194
+		$this->_payment_method_types[$module] = $payment_method_path . DS . $module_class . $module_ext;
195
+		return true;
196
+	}
197
+
198
+
199
+
200
+	/**
201
+	 * Checks if a payment method has been registered, and if so includes it
202
+	 *
203
+	 * @param string  $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_')
204
+	 * @param boolean $force_recheck       whether to force re-checking for new payment method types
205
+	 * @return boolean
206
+	 */
207
+	public function payment_method_type_exists($payment_method_name, $force_recheck = false)
208
+	{
209
+		if (
210
+			$force_recheck
211
+			|| ! is_array($this->_payment_method_types)
212
+			|| ! isset($this->_payment_method_types[$payment_method_name])
213
+		) {
214
+			$this->maybe_register_payment_methods($force_recheck);
215
+		}
216
+		if (isset($this->_payment_method_types[$payment_method_name])) {
217
+			require_once($this->_payment_method_types[$payment_method_name]);
218
+			return true;
219
+		}
220
+		return false;
221
+	}
222
+
223
+
224
+
225
+	/**
226
+	 * Returns all the class names of the various payment method types
227
+	 *
228
+	 * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names'
229
+	 *                               (what you'd find in wp_esp_payment_method.PMD_type)
230
+	 * @param boolean $force_recheck whether to force re-checking for new payment method types
231
+	 * @return array
232
+	 */
233
+	public function payment_method_type_names($with_prefixes = false, $force_recheck = false)
234
+	{
235
+		$this->maybe_register_payment_methods($force_recheck);
236
+		if ($with_prefixes) {
237
+			$classnames = array_keys($this->_payment_method_types);
238
+			$payment_methods = array();
239
+			foreach ($classnames as $classname) {
240
+				$payment_methods[] = $this->payment_method_class_from_type($classname);
241
+			}
242
+			return $payment_methods;
243
+		}
244
+		return array_keys($this->_payment_method_types);
245
+	}
246
+
247
+
248
+
249
+	/**
250
+	 * Gets an object of each payment method type, none of which are bound to a
251
+	 * payment method instance
252
+	 *
253
+	 * @param boolean $force_recheck whether to force re-checking for new payment method types
254
+	 * @return EE_PMT_Base[]
255
+	 */
256
+	public function payment_method_types($force_recheck = false)
257
+	{
258
+		if ($force_recheck || empty($this->payment_method_objects)) {
259
+			$this->maybe_register_payment_methods($force_recheck);
260
+			foreach ($this->payment_method_type_names(true) as $classname) {
261
+				if (! isset($this->payment_method_objects[$classname])) {
262
+					$this->payment_method_objects[$classname] = new $classname;
263
+				}
264
+			}
265
+		}
266
+		return $this->payment_method_objects;
267
+	}
268
+
269
+
270
+
271
+	/**
272
+	 * Changes the payment method's class name into the payment method type's name
273
+	 * (as used on the payment method's table's PMD_type field)
274
+	 *
275
+	 * @param string $classname
276
+	 * @return string
277
+	 */
278
+	public function payment_method_type_sans_class_prefix($classname)
279
+	{
280
+		return str_replace('EE_PMT_', '', $classname);
281
+	}
282
+
283
+
284
+
285
+	/**
286
+	 * Does the opposite of payment-method_type_sans_prefix
287
+	 *
288
+	 * @param string $type
289
+	 * @return string
290
+	 */
291
+	public function payment_method_class_from_type($type)
292
+	{
293
+		return 'EE_PMT_' . $type;
294
+	}
295
+
296
+
297
+
298
+	/**
299
+	 * Activates a payment method of the given type.
300
+	 *
301
+	 * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice'
302
+	 * @return EE_Payment_Method
303
+	 * @throws EE_Error
304
+	 */
305
+	public function activate_a_payment_method_of_type($payment_method_type)
306
+	{
307
+		$this->maybe_register_payment_methods();
308
+		$payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type);
309
+		if (! $payment_method instanceof EE_Payment_Method) {
310
+			$pm_type_class = $this->payment_method_class_from_type($payment_method_type);
311
+			if (class_exists($pm_type_class)) {
312
+				/** @var $pm_type_obj EE_PMT_Base */
313
+				$pm_type_obj = new $pm_type_class;
314
+				$payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name());
315
+				if (! $payment_method) {
316
+					$payment_method = $this->create_payment_method_of_type($pm_type_obj);
317
+				}
318
+				$payment_method->set_type($payment_method_type);
319
+				$this->initialize_payment_method($payment_method);
320
+			} else {
321
+				throw new EE_Error(
322
+					sprintf(
323
+						esc_html__(
324
+							'There is no payment method of type %1$s, so it could not be activated',
325
+							'event_espresso'
326
+						),
327
+						$pm_type_class
328
+					)
329
+				);
330
+			}
331
+		}
332
+		$payment_method->set_active();
333
+		$payment_method->save();
334
+		if ($payment_method->type() === 'Invoice') {
335
+			/** @type EE_Message_Resource_Manager $message_resource_manager */
336
+			$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
337
+			$message_resource_manager->ensure_message_type_is_active('invoice', 'html');
338
+			$message_resource_manager->ensure_messenger_is_active('pdf');
339
+			EE_Error::add_persistent_admin_notice(
340
+				'invoice_pm_requirements_notice',
341
+				sprintf(
342
+					esc_html__(
343
+						'The Invoice payment method has been activated. It requires the invoice message type, html messenger, and pdf messenger be activated as well for the %1$smessages system%2$s, so it has been automatically verified that they are also active.',
344
+						'event_espresso'
345
+					),
346
+					'<a href="' . admin_url('admin.php?page=espresso_messages') . '">',
347
+					'</a>'
348
+				),
349
+				true
350
+			);
351
+		}
352
+		return $payment_method;
353
+	}
354
+
355
+
356
+
357
+	/**
358
+	 * Creates a payment method of the specified type. Does not save it.
359
+	 *
360
+	 * @global WP_User    $current_user
361
+	 * @param EE_PMT_Base $pm_type_obj
362
+	 * @return EE_Payment_Method
363
+	 * @throws EE_Error
364
+	 */
365
+	public function create_payment_method_of_type($pm_type_obj)
366
+	{
367
+		global $current_user;
368
+		$payment_method = EE_Payment_Method::new_instance(
369
+			array(
370
+				'PMD_type'       => $pm_type_obj->system_name(),
371
+				'PMD_name'       => $pm_type_obj->pretty_name(),
372
+				'PMD_admin_name' => $pm_type_obj->pretty_name(),
373
+				'PMD_slug'       => $pm_type_obj->system_name(),//automatically converted to slug
374
+				'PMD_wp_user'    => $current_user->ID,
375
+				'PMD_order'      => EEM_Payment_Method::instance()->count(
376
+						array(array('PMD_type' => array('!=', 'Admin_Only')))
377
+					) * 10,
378
+			)
379
+		);
380
+		return $payment_method;
381
+	}
382
+
383
+
384
+
385
+	/**
386
+	 * Sets the initial payment method properties (including extra meta)
387
+	 *
388
+	 * @param EE_Payment_Method $payment_method
389
+	 * @return EE_Payment_Method
390
+	 * @throws EE_Error
391
+	 */
392
+	public function initialize_payment_method($payment_method)
393
+	{
394
+		$pm_type_obj = $payment_method->type_obj();
395
+		$payment_method->set_description($pm_type_obj->default_description());
396
+		if (! $payment_method->button_url()) {
397
+			$payment_method->set_button_url($pm_type_obj->default_button_url());
398
+		}
399
+		//now add setup its default extra meta properties
400
+		$extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs();
401
+		if (! empty($extra_metas)) {
402
+			//verify the payment method has an ID before adding extra meta
403
+			if (! $payment_method->ID()) {
404
+				$payment_method->save();
405
+			}
406
+			foreach ($extra_metas as $meta_name => $input) {
407
+				$payment_method->update_extra_meta($meta_name, $input->raw_value());
408
+			}
409
+		}
410
+		return $payment_method;
411
+	}
412
+
413
+
414
+
415
+	/**
416
+	 * Makes sure the payment method is related to the specified payment method
417
+	 *
418
+	 * @deprecated in 4.9.40 because the currency payment method table is being deprecated
419
+	 * @param EE_Payment_Method $payment_method
420
+	 * @return EE_Payment_Method
421
+	 * @throws EE_Error
422
+	 */
423
+	public function set_usable_currencies_on_payment_method($payment_method)
424
+	{
425
+		EE_Error::doing_it_wrong(
426
+			'EE_Payment_Method_Manager::set_usable_currencies_on_payment_method',
427
+			esc_html__(
428
+				'We no longer define what currencies are usable by payment methods. Its not used nor efficient.',
429
+				'event_espresso'
430
+			),
431
+			'4.9.40'
432
+		);
433
+		return $payment_method;
434
+	}
435
+
436
+
437
+
438
+	/**
439
+	 * Deactivates a payment method of the given payment method slug.
440
+	 *
441
+	 * @param string $payment_method_slug The slug for the payment method to deactivate.
442
+	 * @return int count of rows updated.
443
+	 * @throws EE_Error
444
+	 */
445
+	public function deactivate_payment_method($payment_method_slug)
446
+	{
447
+		EE_Log::instance()->log(
448
+			__FILE__,
449
+			__FUNCTION__,
450
+			sprintf(
451
+				esc_html__(
452
+					'Payment method with slug %1$s is being deactivated by site admin',
453
+					'event_espresso'
454
+				),
455
+				$payment_method_slug
456
+			),
457
+			'payment_method_change'
458
+		);
459
+		$count_updated = EEM_Payment_Method::instance()->update(
460
+			array('PMD_scope' => array()),
461
+			array(array('PMD_slug' => $payment_method_slug))
462
+		);
463
+		return $count_updated;
464
+	}
465
+
466
+
467
+
468
+	/**
469
+	 * initializes payment method access caps via EE_Capabilities::init_role_caps()
470
+	 * upon EE_Payment_Method_Manager construction
471
+	 *
472
+	 * @throws EE_Error
473
+	 * @throws DomainException
474
+	 */
475
+	protected function initializePaymentMethodCaps()
476
+	{
477
+		// don't do this twice
478
+		if ($this->payment_method_caps_initialized) {
479
+			return;
480
+		}
481
+		EE_Capabilities::instance()->addCaps(
482
+			$this->getPaymentMethodCaps()
483
+		);
484
+		$this->payment_method_caps_initialized = true;
485
+	}
486
+
487
+
488
+
489
+	/**
490
+	 * array  of dynamic payment method access caps.
491
+	 * at the time of writing, october 20 2014, these are the caps added:
492
+	 *  ee_payment_method_admin_only
493
+	 *  ee_payment_method_aim
494
+	 *  ee_payment_method_bank
495
+	 *  ee_payment_method_check
496
+	 *  ee_payment_method_invoice
497
+	 *  ee_payment_method_mijireh
498
+	 *  ee_payment_method_paypal_pro
499
+	 *  ee_payment_method_paypal_standard
500
+	 * Any other payment methods added to core or via addons will also get
501
+	 * their related capability automatically added too, so long as they are
502
+	 * registered properly using EE_Register_Payment_Method::register()
503
+	 *
504
+	 * @return array
505
+	 * @throws DomainException
506
+	 */
507
+	protected function getPaymentMethodCaps()
508
+	{
509
+		$caps = array();
510
+		foreach ($this->payment_method_type_names() as $payment_method_name) {
511
+			$caps = $this->addPaymentMethodCap($payment_method_name,$caps);
512
+		}
513
+		return $caps;
514
+	}
515
+
516
+
517
+
518
+	/**
519
+	 * @param string $payment_method_name
520
+	 * @param array  $payment_method_caps
521
+	 * @param string $role
522
+	 * @return array
523
+	 * @throws DomainException
524
+	 */
525
+	public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator')
526
+	{
527
+		if (empty($payment_method_name)) {
528
+			throw new DomainException(
529
+				esc_html__(
530
+					'The name of a payment method must be specified to add capabilities.',
531
+					'event_espresso'
532
+				)
533
+			);
534
+		}
535
+		if (empty($role)) {
536
+			throw new DomainException(
537
+				sprintf(
538
+					esc_html__(
539
+						'No role was supplied while trying to add capabilities for the %1$s payment method.',
540
+						'event_espresso'
541
+					),
542
+					$payment_method_name
543
+				)
544
+			);
545
+		}
546
+		if(! isset($payment_method_caps[$role])) {
547
+			$payment_method_caps[$role] = array();
548
+		}
549
+		$payment_method_caps[$role][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
550
+												  . strtolower($payment_method_name);
551
+		return $payment_method_caps;
552
+	}
553
+
554
+
555
+
556
+	/**
557
+	 * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter
558
+	 * to add dynamic payment method access caps when capabilities are reset
559
+	 * (or if that filter is called and PM caps are not already set)
560
+	 *
561
+	 * @param array $caps capabilities being filtered
562
+	 * @param bool  $reset
563
+	 * @return array
564
+	 * @throws DomainException
565
+	 */
566
+	public function addPaymentMethodCapsDuringReset(array $caps, $reset = false)
567
+	{
568
+		if ($reset || ! $this->payment_method_caps_initialized) {
569
+			$this->payment_method_caps_initialized = true;
570
+			$caps = array_merge_recursive($caps, $this->getPaymentMethodCaps());
571
+		}
572
+		return $caps;
573
+	}
574
+
575
+
576
+
577
+	/**
578
+	 * @deprecated 4.9.42
579
+	 * @param $caps
580
+	 * @return mixed
581
+	 */
582
+	public function add_payment_method_caps($caps)
583
+	{
584
+		return $caps;
585
+	}
586 586
 
587 587
 
588 588
 
Please login to merge, or discard this patch.
modules/core_rest_api/EED_Core_Rest_Api.module.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -421,7 +421,7 @@
 block discarded – undo
421 421
     /**
422 422
      * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
423 423
      * in this versioned namespace of EE4
424
-     * @param $version
424
+     * @param string $version
425 425
      * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
426 426
      */
427 427
     public static function model_names_with_plural_routes($version){
Please login to merge, or discard this patch.
Indentation   +1221 added lines, -1221 removed lines patch added patch discarded remove patch
@@ -23,1228 +23,1228 @@
 block discarded – undo
23 23
 class EED_Core_Rest_Api extends \EED_Module
24 24
 {
25 25
 
26
-    const ee_api_namespace           = 'ee/v';
26
+	const ee_api_namespace           = 'ee/v';
27 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
-    /**
47
-     * @return EED_Core_Rest_Api|EED_Module
48
-     */
49
-    public static function instance()
50
-    {
51
-        self::$_field_calculator = new CalculatedModelFields();
52
-        return parent::get_instance(__CLASS__);
53
-    }
54
-
55
-
56
-
57
-    /**
58
-     *    set_hooks - for hooking into EE Core, other modules, etc
59
-     *
60
-     * @access    public
61
-     * @return    void
62
-     */
63
-    public static function set_hooks()
64
-    {
65
-        self::set_hooks_both();
66
-    }
67
-
68
-
69
-
70
-    /**
71
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
72
-     *
73
-     * @access    public
74
-     * @return    void
75
-     */
76
-    public static function set_hooks_admin()
77
-    {
78
-        self::set_hooks_both();
79
-    }
80
-
81
-
82
-
83
-    public static function set_hooks_both()
84
-    {
85
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
86
-        add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
87
-        add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
88
-        add_filter('rest_index',
89
-            array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'));
90
-        EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
91
-    }
92
-
93
-
94
-
95
-    /**
96
-     * sets up hooks which only need to be included as part of REST API requests;
97
-     * other requests like to the frontend or admin etc don't need them
98
-     *
99
-     * @throws \EE_Error
100
-     */
101
-    public static function set_hooks_rest_api()
102
-    {
103
-        //set hooks which account for changes made to the API
104
-        EED_Core_Rest_Api::_set_hooks_for_changes();
105
-    }
106
-
107
-
108
-
109
-    /**
110
-     * public wrapper of _set_hooks_for_changes.
111
-     * Loads all the hooks which make requests to old versions of the API
112
-     * appear the same as they always did
113
-     *
114
-     * @throws EE_Error
115
-     */
116
-    public static function set_hooks_for_changes()
117
-    {
118
-        self::_set_hooks_for_changes();
119
-    }
120
-
121
-
122
-
123
-    /**
124
-     * Loads all the hooks which make requests to old versions of the API
125
-     * appear the same as they always did
126
-     *
127
-     * @throws EE_Error
128
-     */
129
-    protected static function _set_hooks_for_changes()
130
-    {
131
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
132
-        foreach ($folder_contents as $classname_in_namespace => $filepath) {
133
-            //ignore the base parent class
134
-            //and legacy named classes
135
-            if ($classname_in_namespace === 'ChangesInBase'
136
-                || strpos($classname_in_namespace, 'Changes_In_') === 0
137
-            ) {
138
-                continue;
139
-            }
140
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
141
-            if (class_exists($full_classname)) {
142
-                $instance_of_class = new $full_classname;
143
-                if ($instance_of_class instanceof ChangesInBase) {
144
-                    $instance_of_class->setHooks();
145
-                }
146
-            }
147
-        }
148
-    }
149
-
150
-
151
-
152
-    /**
153
-     * Filters the WP routes to add our EE-related ones. This takes a bit of time
154
-     * so we actually prefer to only do it when an EE plugin is activated or upgraded
155
-     *
156
-     * @throws \EE_Error
157
-     */
158
-    public static function register_routes()
159
-    {
160
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
161
-            foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
162
-                /**
163
-                 * @var array $data_for_multiple_endpoints numerically indexed array
164
-                 *                                         but can also contain route options like {
165
-                 * @type array    $schema                      {
166
-                 * @type callable $schema_callback
167
-                 * @type array    $callback_args               arguments that will be passed to the callback, after the
168
-                 * WP_REST_Request of course
169
-                 * }
170
-                 * }
171
-                 */
172
-                //when registering routes, register all the endpoints' data at the same time
173
-                $multiple_endpoint_args = array();
174
-                foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
175
-                    /**
176
-                     * @var array     $data_for_single_endpoint {
177
-                     * @type callable $callback
178
-                     * @type string methods
179
-                     * @type array args
180
-                     * @type array _links
181
-                     * @type array    $callback_args            arguments that will be passed to the callback, after the
182
-                     * WP_REST_Request of course
183
-                     * }
184
-                     */
185
-                    //skip route options
186
-                    if (! is_numeric($endpoint_key)) {
187
-                        continue;
188
-                    }
189
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
190
-                        throw new EE_Error(
191
-                            esc_html__(
192
-                                // @codingStandardsIgnoreStart
193
-                                'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
194
-                                // @codingStandardsIgnoreEnd
195
-                                'event_espresso')
196
-                        );
197
-                    }
198
-                    $callback = $data_for_single_endpoint['callback'];
199
-                    $single_endpoint_args = array(
200
-                        'methods' => $data_for_single_endpoint['methods'],
201
-                        'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
202
-                            : array(),
203
-                    );
204
-                    if (isset($data_for_single_endpoint['_links'])) {
205
-                        $single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
206
-                    }
207
-                    if (isset($data_for_single_endpoint['callback_args'])) {
208
-                        $callback_args = $data_for_single_endpoint['callback_args'];
209
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
210
-                            $callback,
211
-                            $callback_args
212
-                        ) {
213
-                            array_unshift($callback_args, $request);
214
-                            return call_user_func_array(
215
-                                $callback,
216
-                                $callback_args
217
-                            );
218
-                        };
219
-                    } else {
220
-                        $single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
221
-                    }
222
-                    $multiple_endpoint_args[] = $single_endpoint_args;
223
-                }
224
-                if (isset($data_for_multiple_endpoints['schema'])) {
225
-                    $schema_route_data = $data_for_multiple_endpoints['schema'];
226
-                    $schema_callback = $schema_route_data['schema_callback'];
227
-                    $callback_args = $schema_route_data['callback_args'];
228
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
229
-                        return call_user_func_array(
230
-                            $schema_callback,
231
-                            $callback_args
232
-                        );
233
-                    };
234
-                }
235
-                register_rest_route(
236
-                    $namespace,
237
-                    $relative_route,
238
-                    $multiple_endpoint_args
239
-                );
240
-            }
241
-        }
242
-    }
243
-
244
-
245
-
246
-    /**
247
-     * Checks if there was a version change or something that merits invalidating the cached
248
-     * route data. If so, invalidates the cached route data so that it gets refreshed
249
-     * next time the WP API is used
250
-     */
251
-    public static function invalidate_cached_route_data_on_version_change()
252
-    {
253
-        if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
254
-            EED_Core_Rest_Api::invalidate_cached_route_data();
255
-        }
256
-        foreach (EE_Registry::instance()->addons as $addon) {
257
-            if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
258
-                EED_Core_Rest_Api::invalidate_cached_route_data();
259
-            }
260
-        }
261
-    }
262
-
263
-
264
-
265
-    /**
266
-     * Removes the cached route data so it will get refreshed next time the WP API is used
267
-     */
268
-    public static function invalidate_cached_route_data()
269
-    {
270
-        //delete the saved EE REST API routes
271
-        foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
272
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
273
-        }
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
-    /**
303
-     * Gets the EE route data from the wp options if it exists already,
304
-     * otherwise re-generates it and saves it to the option
305
-     *
306
-     * @param string  $version
307
-     * @param boolean $hidden_endpoints
308
-     * @return array
309
-     * @throws \EE_Error
310
-     */
311
-    protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
312
-    {
313
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
314
-        if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
315
-            $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
316
-        }
317
-        return $ee_routes;
318
-    }
319
-
320
-
321
-
322
-    /**
323
-     * Saves the EE REST API route data to a wp option and returns it
324
-     *
325
-     * @param string  $version
326
-     * @param boolean $hidden_endpoints
327
-     * @return mixed|null
328
-     * @throws \EE_Error
329
-     */
330
-    protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
331
-    {
332
-        $instance = self::instance();
333
-        $routes = apply_filters(
334
-            'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
335
-            array_replace_recursive(
336
-                $instance->_get_config_route_data_for_version($version, $hidden_endpoints),
337
-                $instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
338
-                $instance->_get_model_route_data_for_version($version, $hidden_endpoints),
339
-                $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
340
-            )
341
-        );
342
-        $option_name = self::saved_routes_option_names . $version;
343
-        if (get_option($option_name)) {
344
-            update_option($option_name, $routes, true);
345
-        } else {
346
-            add_option($option_name, $routes, null, 'no');
347
-        }
348
-        return $routes;
349
-    }
350
-
351
-
352
-
353
-    /**
354
-     * Calculates all the EE routes and saves it to a WordPress option so we don't
355
-     * need to calculate it on every request
356
-     *
357
-     * @deprecated since version 4.9.1
358
-     * @return void
359
-     */
360
-    public static function save_ee_routes()
361
-    {
362
-        if (EE_Maintenance_Mode::instance()->models_can_query()) {
363
-            $instance = self::instance();
364
-            $routes = apply_filters(
365
-                'EED_Core_Rest_Api__save_ee_routes__routes',
366
-                array_replace_recursive(
367
-                    $instance->_register_config_routes(),
368
-                    $instance->_register_meta_routes(),
369
-                    $instance->_register_model_routes(),
370
-                    $instance->_register_rpc_routes()
371
-                )
372
-            );
373
-            update_option(self::saved_routes_option_names, $routes, true);
374
-        }
375
-    }
376
-
377
-
378
-
379
-    /**
380
-     * Gets all the route information relating to EE models
381
-     *
382
-     * @return array @see get_ee_route_data
383
-     * @deprecated since version 4.9.1
384
-     */
385
-    protected function _register_model_routes()
386
-    {
387
-        $model_routes = array();
388
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
389
-            $model_routes[EED_Core_Rest_Api::ee_api_namespace
390
-                          . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
391
-        }
392
-        return $model_routes;
393
-    }
394
-
395
-
396
-
397
-    /**
398
-     * Decides whether or not to add write endpoints for this model.
399
-     *
400
-     * Currently, this defaults to exclude all global tables and models
401
-     * which would allow inserting WP core data (we don't want to duplicate
402
-     * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
403
-     * @param EEM_Base $model
404
-     * @return bool
405
-     */
406
-    public static function should_have_write_endpoints(EEM_Base $model)
407
-    {
408
-        if ($model->is_wp_core_model()){
409
-            return false;
410
-        }
411
-        foreach($model->get_tables() as $table){
412
-            if( $table->is_global()){
413
-                return false;
414
-            }
415
-        }
416
-        return true;
417
-    }
418
-
419
-
420
-
421
-    /**
422
-     * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
423
-     * in this versioned namespace of EE4
424
-     * @param $version
425
-     * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
426
-     */
427
-    public static function model_names_with_plural_routes($version){
428
-        $model_version_info = new ModelVersionInfo($version);
429
-        $models_to_register = $model_version_info->modelsForRequestedVersion();
430
-        //let's not bother having endpoints for extra metas
431
-        unset(
432
-            $models_to_register['Extra_Meta'],
433
-            $models_to_register['Extra_Join'],
434
-            $models_to_register['Post_Meta']
435
-        );
436
-        return apply_filters(
437
-            'FHEE__EED_Core_REST_API___register_model_routes',
438
-            $models_to_register
439
-        );
440
-    }
441
-
442
-
443
-
444
-    /**
445
-     * Gets the route data for EE models in the specified version
446
-     *
447
-     * @param string  $version
448
-     * @param boolean $hidden_endpoint
449
-     * @return array
450
-     * @throws EE_Error
451
-     */
452
-    protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
453
-    {
454
-        $model_routes = array();
455
-        $model_version_info = new ModelVersionInfo($version);
456
-        foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
457
-            $model = \EE_Registry::instance()->load_model($model_name);
458
-            //if this isn't a valid model then let's skip iterate to the next item in the loop.
459
-            if (! $model instanceof EEM_Base) {
460
-                continue;
461
-            }
462
-            //yes we could just register one route for ALL models, but then they wouldn't show up in the index
463
-            $plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
464
-            $singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
465
-            $model_routes[$plural_model_route] = array(
466
-                array(
467
-                    'callback'        => array(
468
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
469
-                        'handleRequestGetAll',
470
-                    ),
471
-                    'callback_args'   => array($version, $model_name),
472
-                    'methods'         => WP_REST_Server::READABLE,
473
-                    'hidden_endpoint' => $hidden_endpoint,
474
-                    'args'            => $this->_get_read_query_params($model, $version),
475
-                    '_links'          => array(
476
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
477
-                    ),
478
-                ),
479
-                'schema' => array(
480
-                    'schema_callback' => array(
481
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
482
-                        'handleSchemaRequest',
483
-                    ),
484
-                    'callback_args'   => array($version, $model_name),
485
-                ),
486
-            );
487
-            $model_routes[$singular_model_route] = array(
488
-                array(
489
-                    'callback'        => array(
490
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Read',
491
-                        'handleRequestGetOne',
492
-                    ),
493
-                    'callback_args'   => array($version, $model_name),
494
-                    'methods'         => WP_REST_Server::READABLE,
495
-                    'hidden_endpoint' => $hidden_endpoint,
496
-                    'args'            => $this->_get_response_selection_query_params($model, $version),
497
-                ),
498
-            );
499
-            if( apply_filters(
500
-                'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
501
-                EED_Core_Rest_Api::should_have_write_endpoints($model),
502
-                $model
503
-            )){
504
-                $model_routes[$plural_model_route][] = array(
505
-                    'callback'        => array(
506
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Write',
507
-                        'handleRequestInsert',
508
-                    ),
509
-                    'callback_args'   => array($version, $model_name),
510
-                    'methods'         => WP_REST_Server::CREATABLE,
511
-                    'hidden_endpoint' => $hidden_endpoint,
512
-                    'args'            => $this->_get_write_params($model_name, $model_version_info, true),
513
-                );
514
-                $model_routes[$singular_model_route] = array_merge(
515
-                    $model_routes[$singular_model_route],
516
-                    array(
517
-                        array(
518
-                            'callback'        => array(
519
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
520
-                                'handleRequestUpdate',
521
-                            ),
522
-                            'callback_args'   => array($version, $model_name),
523
-                            'methods'         => WP_REST_Server::EDITABLE,
524
-                            'hidden_endpoint' => $hidden_endpoint,
525
-                            'args'            => $this->_get_write_params($model_name, $model_version_info),
526
-                        ),
527
-                        array(
528
-                            'callback'        => array(
529
-                                'EventEspresso\core\libraries\rest_api\controllers\model\Write',
530
-                                'handleRequestDelete',
531
-                            ),
532
-                            'callback_args'   => array($version, $model_name),
533
-                            'methods'         => WP_REST_Server::DELETABLE,
534
-                            'hidden_endpoint' => $hidden_endpoint,
535
-                            'args'            => $this->_get_delete_query_params($model, $version),
536
-                        )
537
-                    )
538
-                );
539
-            }
540
-            foreach ($model->relation_settings() as $relation_name => $relation_obj) {
541
-
542
-                $related_route = EED_Core_Rest_Api::get_relation_route_via(
543
-                    $model,
544
-                    '(?P<id>[^\/]+)',
545
-                    $relation_obj
546
-                );
547
-                $endpoints = array(
548
-                    array(
549
-                        'callback'        => array(
550
-                            'EventEspresso\core\libraries\rest_api\controllers\model\Read',
551
-                            'handleRequestGetRelated',
552
-                        ),
553
-                        'callback_args'   => array($version, $model_name, $relation_name),
554
-                        'methods'         => WP_REST_Server::READABLE,
555
-                        'hidden_endpoint' => $hidden_endpoint,
556
-                        'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
557
-                    ),
558
-                );
559
-                $model_routes[$related_route] = $endpoints;
560
-            }
561
-        }
562
-        return $model_routes;
563
-    }
564
-
565
-
566
-
567
-    /**
568
-     * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
569
-     * excluding the preceding slash.
570
-     * Eg you pass get_plural_route_to('Event') = 'events'
571
-     *
572
-     * @param EEM_Base $model
573
-     * @return string
574
-     */
575
-    public static function get_collection_route(EEM_Base $model)
576
-    {
577
-        return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
578
-    }
579
-
580
-
581
-
582
-    /**
583
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
584
-     * excluding the preceding slash.
585
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
586
-     *
587
-     * @param EEM_Base $model eg Event or Venue
588
-     * @param string $id
589
-     * @return string
590
-     */
591
-    public static function get_entity_route($model, $id)
592
-    {
593
-        return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
594
-    }
595
-
596
-
597
-    /**
598
-     * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
599
-     * excluding the preceding slash.
600
-     * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
601
-     *
602
-     * @param EEM_Base                 $model eg Event or Venue
603
-     * @param string                 $id
604
-     * @param EE_Model_Relation_Base $relation_obj
605
-     * @return string
606
-     */
607
-    public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
608
-    {
609
-        $related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
610
-            $relation_obj->get_other_model()->get_this_model_name(),
611
-            $relation_obj
612
-        );
613
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
614
-    }
615
-
616
-
617
-
618
-    /**
619
-     * Adds onto the $relative_route the EE4 REST API versioned namespace.
620
-     * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
621
-     * @param string $relative_route
622
-     * @param string $version
623
-     * @return string
624
-     */
625
-    public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
626
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
627
-    }
628
-
629
-
630
-
631
-    /**
632
-     * Adds all the RPC-style routes (remote procedure call-like routes, ie
633
-     * routes that don't conform to the traditional REST CRUD-style).
634
-     *
635
-     * @deprecated since 4.9.1
636
-     */
637
-    protected function _register_rpc_routes()
638
-    {
639
-        $routes = array();
640
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
641
-            $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
642
-                $version,
643
-                $hidden_endpoint
644
-            );
645
-        }
646
-        return $routes;
647
-    }
648
-
649
-
650
-
651
-    /**
652
-     * @param string  $version
653
-     * @param boolean $hidden_endpoint
654
-     * @return array
655
-     */
656
-    protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
657
-    {
658
-        $this_versions_routes = array();
659
-        //checkin endpoint
660
-        $this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
661
-            array(
662
-                'callback'        => array(
663
-                    'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
664
-                    'handleRequestToggleCheckin',
665
-                ),
666
-                'methods'         => WP_REST_Server::CREATABLE,
667
-                'hidden_endpoint' => $hidden_endpoint,
668
-                'args'            => array(
669
-                    'force' => array(
670
-                        'required'    => false,
671
-                        'default'     => false,
672
-                        'description' => __(
673
-                            // @codingStandardsIgnoreStart
674
-                            'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
675
-                            // @codingStandardsIgnoreEnd
676
-                            'event_espresso'
677
-                        ),
678
-                    ),
679
-                ),
680
-                'callback_args'   => array($version),
681
-            ),
682
-        );
683
-        return apply_filters(
684
-            'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
685
-            $this_versions_routes,
686
-            $version,
687
-            $hidden_endpoint
688
-        );
689
-    }
690
-
691
-
692
-
693
-    /**
694
-     * Gets the query params that can be used when request one or many
695
-     *
696
-     * @param EEM_Base $model
697
-     * @param string   $version
698
-     * @return array
699
-     */
700
-    protected function _get_response_selection_query_params(\EEM_Base $model, $version)
701
-    {
702
-        return apply_filters(
703
-            'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
704
-            array(
705
-                'include'   => array(
706
-                    'required' => false,
707
-                    'default'  => '*',
708
-                    'type'     => 'string',
709
-                ),
710
-                'calculate' => array(
711
-                    'required'          => false,
712
-                    'default'           => '',
713
-                    'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
714
-                    'type'              => 'string',
715
-                    //because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
716
-                    //freaks out. We'll just validate this argument while handling the request
717
-                    'validate_callback' => null,
718
-                    'sanitize_callback' => null,
719
-                ),
720
-            ),
721
-            $model,
722
-            $version
723
-        );
724
-    }
725
-
726
-
727
-
728
-    /**
729
-     * Gets the parameters acceptable for delete requests
730
-     *
731
-     * @param \EEM_Base $model
732
-     * @param string    $version
733
-     * @return array
734
-     */
735
-    protected function _get_delete_query_params(\EEM_Base $model, $version)
736
-    {
737
-        $params_for_delete = array(
738
-            'allow_blocking' => array(
739
-                'required' => false,
740
-                'default'  => true,
741
-                'type'     => 'boolean',
742
-            ),
743
-        );
744
-        $params_for_delete['force'] = array(
745
-            'required' => false,
746
-            'default'  => false,
747
-            'type'     => 'boolean',
748
-        );
749
-        return apply_filters(
750
-            'FHEE__EED_Core_Rest_Api___get_delete_query_params',
751
-            $params_for_delete,
752
-            $model,
753
-            $version
754
-        );
755
-    }
756
-
757
-
758
-
759
-    /**
760
-     * Gets info about reading query params that are acceptable
761
-     *
762
-     * @param \EEM_Base $model eg 'Event' or 'Venue'
763
-     * @param  string   $version
764
-     * @return array    describing the args acceptable when querying this model
765
-     * @throws EE_Error
766
-     */
767
-    protected function _get_read_query_params(\EEM_Base $model, $version)
768
-    {
769
-        $default_orderby = array();
770
-        foreach ($model->get_combined_primary_key_fields() as $key_field) {
771
-            $default_orderby[$key_field->get_name()] = 'ASC';
772
-        }
773
-        return array_merge(
774
-            $this->_get_response_selection_query_params($model, $version),
775
-            array(
776
-                'where'    => array(
777
-                    'required' => false,
778
-                    'default'  => array(),
779
-                    'type'     => 'object',
780
-                ),
781
-                'limit'    => array(
782
-                    'required' => false,
783
-                    'default'  => EED_Core_Rest_Api::get_default_query_limit(),
784
-                    'type'     => array(
785
-                        'object',
786
-                        'string',
787
-                        'integer',
788
-                    ),
789
-                ),
790
-                'order_by' => array(
791
-                    'required' => false,
792
-                    'default'  => $default_orderby,
793
-                    'type'     => array(
794
-                        'object',
795
-                        'string',
796
-                    ),
797
-                ),
798
-                'group_by' => array(
799
-                    'required' => false,
800
-                    'default'  => null,
801
-                    'type'     => array(
802
-                        'object',
803
-                        'string',
804
-                    ),
805
-                ),
806
-                'having'   => array(
807
-                    'required' => false,
808
-                    'default'  => null,
809
-                    'type'     => 'object',
810
-                ),
811
-                'caps'     => array(
812
-                    'required' => false,
813
-                    'default'  => EEM_Base::caps_read,
814
-                    'type'     => 'string',
815
-                ),
816
-            )
817
-        );
818
-    }
819
-
820
-
821
-
822
-    /**
823
-     * Gets parameter information for a model regarding writing data
824
-     *
825
-     * @param string           $model_name
826
-     * @param ModelVersionInfo $model_version_info
827
-     * @param boolean          $create                                       whether this is for request to create (in which case we need
828
-     *                                                                       all required params) or just to update (in which case we don't need those on every request)
829
-     * @return array
830
-     */
831
-    protected function _get_write_params(
832
-        $model_name,
833
-        ModelVersionInfo $model_version_info,
834
-        $create = false
835
-    ) {
836
-        $model = EE_Registry::instance()->load_model($model_name);
837
-        $fields = $model_version_info->fieldsOnModelInThisVersion($model);
838
-        $args_info = array();
839
-        foreach ($fields as $field_name => $field_obj) {
840
-            if ($field_obj->is_auto_increment()) {
841
-                //totally ignore auto increment IDs
842
-                continue;
843
-            }
844
-            $arg_info = $field_obj->getSchema();
845
-            $required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
846
-            $arg_info['required'] = $required;
847
-            //remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
848
-            unset($arg_info['readonly']);
849
-            $schema_properties = $field_obj->getSchemaProperties();
850
-            if (
851
-                isset($schema_properties['raw'])
852
-                && $field_obj->getSchemaType() === 'object'
853
-            ) {
854
-                //if there's a "raw" form of this argument, use those properties instead
855
-                $arg_info = array_replace(
856
-                    $arg_info,
857
-                    $schema_properties['raw']
858
-                );
859
-            }
860
-            $arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
861
-                $field_obj,
862
-                $field_obj->get_default_value(),
863
-                $model_version_info->requestedVersion()
864
-            );
865
-            //we do our own validation and sanitization within the controller
866
-            $arg_info['sanitize_callback'] =
867
-                array(
868
-                    'EED_Core_Rest_Api',
869
-                    'default_sanitize_callback',
870
-                );
871
-            $args_info[$field_name] = $arg_info;
872
-            if ($field_obj instanceof EE_Datetime_Field) {
873
-                $gmt_arg_info = $arg_info;
874
-                $gmt_arg_info['description'] = sprintf(
875
-                    esc_html__(
876
-                        '%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
877
-                        'event_espresso'
878
-                    ),
879
-                    $field_obj->get_nicename(),
880
-                    $field_name
881
-                );
882
-                $args_info[$field_name . '_gmt'] = $gmt_arg_info;
883
-            }
884
-        }
885
-        return $args_info;
886
-    }
887
-
888
-
889
-
890
-    /**
891
-     * Replacement for WP API's 'rest_parse_request_arg'.
892
-     * If the value is blank but not required, don't bother validating it.
893
-     * Also, it uses our email validation instead of WP API's default.
894
-     *
895
-     * @param                 $value
896
-     * @param WP_REST_Request $request
897
-     * @param                 $param
898
-     * @return bool|true|WP_Error
899
-     * @throws InvalidArgumentException
900
-     * @throws InvalidInterfaceException
901
-     * @throws InvalidDataTypeException
902
-     */
903
-    public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
904
-    {
905
-        $attributes = $request->get_attributes();
906
-        if (! isset($attributes['args'][$param])
907
-            || ! is_array($attributes['args'][$param])) {
908
-            $validation_result = true;
909
-        } else {
910
-            $args = $attributes['args'][$param];
911
-            if ((
912
-                    $value === ''
913
-                    || $value === null
914
-                )
915
-                && (! isset($args['required'])
916
-                    || $args['required'] === false
917
-                )
918
-            ) {
919
-                //not required and not provided? that's cool
920
-                $validation_result = true;
921
-            } elseif (isset($args['format'])
922
-                && $args['format'] === 'email'
923
-            ) {
924
-                $validation_result = true;
925
-                if (! self::_validate_email($value)) {
926
-                    $validation_result = new WP_Error(
927
-                        'rest_invalid_param',
928
-                        esc_html__(
929
-                            'The email address is not valid or does not exist.',
930
-                            'event_espresso'
931
-                        )
932
-                    );
933
-                }
934
-            } else {
935
-                $validation_result = rest_validate_value_from_schema($value, $args, $param);
936
-            }
937
-        }
938
-        if (is_wp_error($validation_result)) {
939
-            return $validation_result;
940
-        }
941
-        return rest_sanitize_request_arg($value, $request, $param);
942
-    }
943
-
944
-
945
-
946
-    /**
947
-     * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
948
-     *
949
-     * @param $email
950
-     * @return bool
951
-     * @throws InvalidArgumentException
952
-     * @throws InvalidInterfaceException
953
-     * @throws InvalidDataTypeException
954
-     */
955
-    protected static function _validate_email($email){
956
-        try {
957
-            EmailAddressFactory::create($email);
958
-            return true;
959
-        } catch (EmailValidationException $e) {
960
-            return false;
961
-        }
962
-    }
963
-
964
-
965
-
966
-    /**
967
-     * Gets routes for the config
968
-     *
969
-     * @return array @see _register_model_routes
970
-     * @deprecated since version 4.9.1
971
-     */
972
-    protected function _register_config_routes()
973
-    {
974
-        $config_routes = array();
975
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
976
-            $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
977
-                $version,
978
-                $hidden_endpoint
979
-            );
980
-        }
981
-        return $config_routes;
982
-    }
983
-
984
-
985
-
986
-    /**
987
-     * Gets routes for the config for the specified version
988
-     *
989
-     * @param string  $version
990
-     * @param boolean $hidden_endpoint
991
-     * @return array
992
-     */
993
-    protected function _get_config_route_data_for_version($version, $hidden_endpoint)
994
-    {
995
-        return array(
996
-            'config'    => array(
997
-                array(
998
-                    'callback'        => array(
999
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1000
-                        'handleRequest',
1001
-                    ),
1002
-                    'methods'         => WP_REST_Server::READABLE,
1003
-                    'hidden_endpoint' => $hidden_endpoint,
1004
-                    'callback_args'   => array($version),
1005
-                ),
1006
-            ),
1007
-            'site_info' => array(
1008
-                array(
1009
-                    'callback'        => array(
1010
-                        'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1011
-                        'handleRequestSiteInfo',
1012
-                    ),
1013
-                    'methods'         => WP_REST_Server::READABLE,
1014
-                    'hidden_endpoint' => $hidden_endpoint,
1015
-                    'callback_args'   => array($version),
1016
-                ),
1017
-            ),
1018
-        );
1019
-    }
1020
-
1021
-
1022
-
1023
-    /**
1024
-     * Gets the meta info routes
1025
-     *
1026
-     * @return array @see _register_model_routes
1027
-     * @deprecated since version 4.9.1
1028
-     */
1029
-    protected function _register_meta_routes()
1030
-    {
1031
-        $meta_routes = array();
1032
-        foreach (self::versions_served() as $version => $hidden_endpoint) {
1033
-            $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1034
-                $version,
1035
-                $hidden_endpoint
1036
-            );
1037
-        }
1038
-        return $meta_routes;
1039
-    }
1040
-
1041
-
1042
-
1043
-    /**
1044
-     * @param string  $version
1045
-     * @param boolean $hidden_endpoint
1046
-     * @return array
1047
-     */
1048
-    protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1049
-    {
1050
-        return array(
1051
-            'resources' => array(
1052
-                array(
1053
-                    'callback'        => array(
1054
-                        'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1055
-                        'handleRequestModelsMeta',
1056
-                    ),
1057
-                    'methods'         => WP_REST_Server::READABLE,
1058
-                    'hidden_endpoint' => $hidden_endpoint,
1059
-                    'callback_args'   => array($version),
1060
-                ),
1061
-            ),
1062
-        );
1063
-    }
1064
-
1065
-
1066
-
1067
-    /**
1068
-     * Tries to hide old 4.6 endpoints from the
1069
-     *
1070
-     * @param array $route_data
1071
-     * @return array
1072
-     * @throws \EE_Error
1073
-     */
1074
-    public static function hide_old_endpoints($route_data)
1075
-    {
1076
-        //allow API clients to override which endpoints get hidden, in case
1077
-        //they want to discover particular endpoints
1078
-        //also, we don't have access to the request so we have to just grab it from the superglobal
1079
-        $force_show_ee_namespace = ltrim(
1080
-            EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''),
1081
-            '/'
1082
-        );
1083
-        foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1084
-            foreach ($relative_urls as $resource_name => $endpoints) {
1085
-                foreach ($endpoints as $key => $endpoint) {
1086
-                    //skip schema and other route options
1087
-                    if (! is_numeric($key)) {
1088
-                        continue;
1089
-                    }
1090
-                    //by default, hide "hidden_endpoint"s, unless the request indicates
1091
-                    //to $force_show_ee_namespace, in which case only show that one
1092
-                    //namespace's endpoints (and hide all others)
1093
-                    if (
1094
-                        ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1095
-                        || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1096
-                    ) {
1097
-                        $full_route = '/' . ltrim($namespace, '/');
1098
-                        $full_route .= '/' . ltrim($resource_name, '/');
1099
-                        unset($route_data[$full_route]);
1100
-                    }
1101
-                }
1102
-            }
1103
-        }
1104
-        return $route_data;
1105
-    }
1106
-
1107
-
1108
-
1109
-    /**
1110
-     * Returns an array describing which versions of core support serving requests for.
1111
-     * Keys are core versions' major and minor version, and values are the
1112
-     * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1113
-     * data by just removing a few models and fields from the responses. However, 4.15 might remove
1114
-     * the answers table entirely, in which case it would be very difficult for
1115
-     * it to serve 4.6-style responses.
1116
-     * Versions of core that are missing from this array are unknowns.
1117
-     * previous ver
1118
-     *
1119
-     * @return array
1120
-     */
1121
-    public static function version_compatibilities()
1122
-    {
1123
-        return apply_filters(
1124
-            'FHEE__EED_Core_REST_API__version_compatibilities',
1125
-            array(
1126
-                '4.8.29' => '4.8.29',
1127
-                '4.8.33' => '4.8.29',
1128
-                '4.8.34' => '4.8.29',
1129
-                '4.8.36' => '4.8.29',
1130
-            )
1131
-        );
1132
-    }
1133
-
1134
-
1135
-
1136
-    /**
1137
-     * Gets the latest API version served. Eg if there
1138
-     * are two versions served of the API, 4.8.29 and 4.8.32, and
1139
-     * we are on core version 4.8.34, it will return the string "4.8.32"
1140
-     *
1141
-     * @return string
1142
-     */
1143
-    public static function latest_rest_api_version()
1144
-    {
1145
-        $versions_served = \EED_Core_Rest_Api::versions_served();
1146
-        $versions_served_keys = array_keys($versions_served);
1147
-        return end($versions_served_keys);
1148
-    }
1149
-
1150
-
1151
-
1152
-    /**
1153
-     * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1154
-     * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1155
-     * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1156
-     * We also indicate whether or not this version should be put in the index or not
1157
-     *
1158
-     * @return array keys are API version numbers (just major and minor numbers), and values
1159
-     * are whether or not they should be hidden
1160
-     */
1161
-    public static function versions_served()
1162
-    {
1163
-        $versions_served = array();
1164
-        $possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1165
-        $lowest_compatible_version = end($possibly_served_versions);
1166
-        reset($possibly_served_versions);
1167
-        $versions_served_historically = array_keys($possibly_served_versions);
1168
-        $latest_version = end($versions_served_historically);
1169
-        reset($versions_served_historically);
1170
-        //for each version of core we have ever served:
1171
-        foreach ($versions_served_historically as $key_versioned_endpoint) {
1172
-            //if it's not above the current core version, and it's compatible with the current version of core
1173
-            if ($key_versioned_endpoint === $latest_version) {
1174
-                //don't hide the latest version in the index
1175
-                $versions_served[$key_versioned_endpoint] = false;
1176
-            } elseif (
1177
-                $key_versioned_endpoint >= $lowest_compatible_version
1178
-                && $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1179
-            ) {
1180
-                //include, but hide, previous versions which are still supported
1181
-                $versions_served[$key_versioned_endpoint] = true;
1182
-            } elseif (apply_filters(
1183
-                'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1184
-                false,
1185
-                $possibly_served_versions
1186
-            )) {
1187
-                //if a version is no longer supported, don't include it in index or list of versions served
1188
-                $versions_served[$key_versioned_endpoint] = true;
1189
-            }
1190
-        }
1191
-        return $versions_served;
1192
-    }
1193
-
1194
-
1195
-
1196
-    /**
1197
-     * Gets the major and minor version of EE core's version string
1198
-     *
1199
-     * @return string
1200
-     */
1201
-    public static function core_version()
1202
-    {
1203
-        return apply_filters(
1204
-            'FHEE__EED_Core_REST_API__core_version',
1205
-            implode(
1206
-                '.',
1207
-                array_slice(
1208
-                    explode(
1209
-                        '.',
1210
-                        espresso_version()
1211
-                    ),
1212
-                0,
1213
-                3
1214
-                )
1215
-            )
1216
-        );
1217
-    }
1218
-
1219
-
1220
-
1221
-    /**
1222
-     * Gets the default limit that should be used when querying for resources
1223
-     *
1224
-     * @return int
1225
-     */
1226
-    public static function get_default_query_limit()
1227
-    {
1228
-        //we actually don't use a const because we want folks to always use
1229
-        //this method, not the const directly
1230
-        return apply_filters(
1231
-            'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1232
-            50
1233
-        );
1234
-    }
1235
-
1236
-
1237
-
1238
-    /**
1239
-     *    run - initial module setup
1240
-     *
1241
-     * @access    public
1242
-     * @param  WP $WP
1243
-     * @return    void
1244
-     */
1245
-    public function run($WP)
1246
-    {
1247
-    }
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
+	/**
47
+	 * @return EED_Core_Rest_Api|EED_Module
48
+	 */
49
+	public static function instance()
50
+	{
51
+		self::$_field_calculator = new CalculatedModelFields();
52
+		return parent::get_instance(__CLASS__);
53
+	}
54
+
55
+
56
+
57
+	/**
58
+	 *    set_hooks - for hooking into EE Core, other modules, etc
59
+	 *
60
+	 * @access    public
61
+	 * @return    void
62
+	 */
63
+	public static function set_hooks()
64
+	{
65
+		self::set_hooks_both();
66
+	}
67
+
68
+
69
+
70
+	/**
71
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
72
+	 *
73
+	 * @access    public
74
+	 * @return    void
75
+	 */
76
+	public static function set_hooks_admin()
77
+	{
78
+		self::set_hooks_both();
79
+	}
80
+
81
+
82
+
83
+	public static function set_hooks_both()
84
+	{
85
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'register_routes'), 10);
86
+		add_action('rest_api_init', array('EED_Core_Rest_Api', 'set_hooks_rest_api'), 5);
87
+		add_filter('rest_route_data', array('EED_Core_Rest_Api', 'hide_old_endpoints'), 10, 2);
88
+		add_filter('rest_index',
89
+			array('EventEspresso\core\libraries\rest_api\controllers\model\Meta', 'filterEeMetadataIntoIndex'));
90
+		EED_Core_Rest_Api::invalidate_cached_route_data_on_version_change();
91
+	}
92
+
93
+
94
+
95
+	/**
96
+	 * sets up hooks which only need to be included as part of REST API requests;
97
+	 * other requests like to the frontend or admin etc don't need them
98
+	 *
99
+	 * @throws \EE_Error
100
+	 */
101
+	public static function set_hooks_rest_api()
102
+	{
103
+		//set hooks which account for changes made to the API
104
+		EED_Core_Rest_Api::_set_hooks_for_changes();
105
+	}
106
+
107
+
108
+
109
+	/**
110
+	 * public wrapper of _set_hooks_for_changes.
111
+	 * Loads all the hooks which make requests to old versions of the API
112
+	 * appear the same as they always did
113
+	 *
114
+	 * @throws EE_Error
115
+	 */
116
+	public static function set_hooks_for_changes()
117
+	{
118
+		self::_set_hooks_for_changes();
119
+	}
120
+
121
+
122
+
123
+	/**
124
+	 * Loads all the hooks which make requests to old versions of the API
125
+	 * appear the same as they always did
126
+	 *
127
+	 * @throws EE_Error
128
+	 */
129
+	protected static function _set_hooks_for_changes()
130
+	{
131
+		$folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
132
+		foreach ($folder_contents as $classname_in_namespace => $filepath) {
133
+			//ignore the base parent class
134
+			//and legacy named classes
135
+			if ($classname_in_namespace === 'ChangesInBase'
136
+				|| strpos($classname_in_namespace, 'Changes_In_') === 0
137
+			) {
138
+				continue;
139
+			}
140
+			$full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
141
+			if (class_exists($full_classname)) {
142
+				$instance_of_class = new $full_classname;
143
+				if ($instance_of_class instanceof ChangesInBase) {
144
+					$instance_of_class->setHooks();
145
+				}
146
+			}
147
+		}
148
+	}
149
+
150
+
151
+
152
+	/**
153
+	 * Filters the WP routes to add our EE-related ones. This takes a bit of time
154
+	 * so we actually prefer to only do it when an EE plugin is activated or upgraded
155
+	 *
156
+	 * @throws \EE_Error
157
+	 */
158
+	public static function register_routes()
159
+	{
160
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_routes) {
161
+			foreach ($relative_routes as $relative_route => $data_for_multiple_endpoints) {
162
+				/**
163
+				 * @var array $data_for_multiple_endpoints numerically indexed array
164
+				 *                                         but can also contain route options like {
165
+				 * @type array    $schema                      {
166
+				 * @type callable $schema_callback
167
+				 * @type array    $callback_args               arguments that will be passed to the callback, after the
168
+				 * WP_REST_Request of course
169
+				 * }
170
+				 * }
171
+				 */
172
+				//when registering routes, register all the endpoints' data at the same time
173
+				$multiple_endpoint_args = array();
174
+				foreach ($data_for_multiple_endpoints as $endpoint_key => $data_for_single_endpoint) {
175
+					/**
176
+					 * @var array     $data_for_single_endpoint {
177
+					 * @type callable $callback
178
+					 * @type string methods
179
+					 * @type array args
180
+					 * @type array _links
181
+					 * @type array    $callback_args            arguments that will be passed to the callback, after the
182
+					 * WP_REST_Request of course
183
+					 * }
184
+					 */
185
+					//skip route options
186
+					if (! is_numeric($endpoint_key)) {
187
+						continue;
188
+					}
189
+					if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
190
+						throw new EE_Error(
191
+							esc_html__(
192
+								// @codingStandardsIgnoreStart
193
+								'Endpoint configuration data needs to have entries "callback" (callable) and "methods" (comma-separated list of accepts HTTP methods).',
194
+								// @codingStandardsIgnoreEnd
195
+								'event_espresso')
196
+						);
197
+					}
198
+					$callback = $data_for_single_endpoint['callback'];
199
+					$single_endpoint_args = array(
200
+						'methods' => $data_for_single_endpoint['methods'],
201
+						'args'    => isset($data_for_single_endpoint['args']) ? $data_for_single_endpoint['args']
202
+							: array(),
203
+					);
204
+					if (isset($data_for_single_endpoint['_links'])) {
205
+						$single_endpoint_args['_links'] = $data_for_single_endpoint['_links'];
206
+					}
207
+					if (isset($data_for_single_endpoint['callback_args'])) {
208
+						$callback_args = $data_for_single_endpoint['callback_args'];
209
+						$single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
210
+							$callback,
211
+							$callback_args
212
+						) {
213
+							array_unshift($callback_args, $request);
214
+							return call_user_func_array(
215
+								$callback,
216
+								$callback_args
217
+							);
218
+						};
219
+					} else {
220
+						$single_endpoint_args['callback'] = $data_for_single_endpoint['callback'];
221
+					}
222
+					$multiple_endpoint_args[] = $single_endpoint_args;
223
+				}
224
+				if (isset($data_for_multiple_endpoints['schema'])) {
225
+					$schema_route_data = $data_for_multiple_endpoints['schema'];
226
+					$schema_callback = $schema_route_data['schema_callback'];
227
+					$callback_args = $schema_route_data['callback_args'];
228
+					$multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
229
+						return call_user_func_array(
230
+							$schema_callback,
231
+							$callback_args
232
+						);
233
+					};
234
+				}
235
+				register_rest_route(
236
+					$namespace,
237
+					$relative_route,
238
+					$multiple_endpoint_args
239
+				);
240
+			}
241
+		}
242
+	}
243
+
244
+
245
+
246
+	/**
247
+	 * Checks if there was a version change or something that merits invalidating the cached
248
+	 * route data. If so, invalidates the cached route data so that it gets refreshed
249
+	 * next time the WP API is used
250
+	 */
251
+	public static function invalidate_cached_route_data_on_version_change()
252
+	{
253
+		if (EE_System::instance()->detect_req_type() !== EE_System::req_type_normal) {
254
+			EED_Core_Rest_Api::invalidate_cached_route_data();
255
+		}
256
+		foreach (EE_Registry::instance()->addons as $addon) {
257
+			if ($addon instanceof EE_Addon && $addon->detect_req_type() !== EE_System::req_type_normal) {
258
+				EED_Core_Rest_Api::invalidate_cached_route_data();
259
+			}
260
+		}
261
+	}
262
+
263
+
264
+
265
+	/**
266
+	 * Removes the cached route data so it will get refreshed next time the WP API is used
267
+	 */
268
+	public static function invalidate_cached_route_data()
269
+	{
270
+		//delete the saved EE REST API routes
271
+		foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
272
+			delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
273
+		}
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
+	/**
303
+	 * Gets the EE route data from the wp options if it exists already,
304
+	 * otherwise re-generates it and saves it to the option
305
+	 *
306
+	 * @param string  $version
307
+	 * @param boolean $hidden_endpoints
308
+	 * @return array
309
+	 * @throws \EE_Error
310
+	 */
311
+	protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
312
+	{
313
+		$ee_routes = get_option(self::saved_routes_option_names . $version, null);
314
+		if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
315
+			$ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
316
+		}
317
+		return $ee_routes;
318
+	}
319
+
320
+
321
+
322
+	/**
323
+	 * Saves the EE REST API route data to a wp option and returns it
324
+	 *
325
+	 * @param string  $version
326
+	 * @param boolean $hidden_endpoints
327
+	 * @return mixed|null
328
+	 * @throws \EE_Error
329
+	 */
330
+	protected static function _save_ee_route_data_for_version($version, $hidden_endpoints = false)
331
+	{
332
+		$instance = self::instance();
333
+		$routes = apply_filters(
334
+			'EED_Core_Rest_Api__save_ee_route_data_for_version__routes',
335
+			array_replace_recursive(
336
+				$instance->_get_config_route_data_for_version($version, $hidden_endpoints),
337
+				$instance->_get_meta_route_data_for_version($version, $hidden_endpoints),
338
+				$instance->_get_model_route_data_for_version($version, $hidden_endpoints),
339
+				$instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
340
+			)
341
+		);
342
+		$option_name = self::saved_routes_option_names . $version;
343
+		if (get_option($option_name)) {
344
+			update_option($option_name, $routes, true);
345
+		} else {
346
+			add_option($option_name, $routes, null, 'no');
347
+		}
348
+		return $routes;
349
+	}
350
+
351
+
352
+
353
+	/**
354
+	 * Calculates all the EE routes and saves it to a WordPress option so we don't
355
+	 * need to calculate it on every request
356
+	 *
357
+	 * @deprecated since version 4.9.1
358
+	 * @return void
359
+	 */
360
+	public static function save_ee_routes()
361
+	{
362
+		if (EE_Maintenance_Mode::instance()->models_can_query()) {
363
+			$instance = self::instance();
364
+			$routes = apply_filters(
365
+				'EED_Core_Rest_Api__save_ee_routes__routes',
366
+				array_replace_recursive(
367
+					$instance->_register_config_routes(),
368
+					$instance->_register_meta_routes(),
369
+					$instance->_register_model_routes(),
370
+					$instance->_register_rpc_routes()
371
+				)
372
+			);
373
+			update_option(self::saved_routes_option_names, $routes, true);
374
+		}
375
+	}
376
+
377
+
378
+
379
+	/**
380
+	 * Gets all the route information relating to EE models
381
+	 *
382
+	 * @return array @see get_ee_route_data
383
+	 * @deprecated since version 4.9.1
384
+	 */
385
+	protected function _register_model_routes()
386
+	{
387
+		$model_routes = array();
388
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
389
+			$model_routes[EED_Core_Rest_Api::ee_api_namespace
390
+						  . $version] = $this->_get_config_route_data_for_version($version, $hidden_endpoint);
391
+		}
392
+		return $model_routes;
393
+	}
394
+
395
+
396
+
397
+	/**
398
+	 * Decides whether or not to add write endpoints for this model.
399
+	 *
400
+	 * Currently, this defaults to exclude all global tables and models
401
+	 * which would allow inserting WP core data (we don't want to duplicate
402
+	 * what WP API does, as it's unnecessary, extra work, and potentially extra bugs)
403
+	 * @param EEM_Base $model
404
+	 * @return bool
405
+	 */
406
+	public static function should_have_write_endpoints(EEM_Base $model)
407
+	{
408
+		if ($model->is_wp_core_model()){
409
+			return false;
410
+		}
411
+		foreach($model->get_tables() as $table){
412
+			if( $table->is_global()){
413
+				return false;
414
+			}
415
+		}
416
+		return true;
417
+	}
418
+
419
+
420
+
421
+	/**
422
+	 * Gets the names of all models which should have plural routes (eg `ee/v4.8.36/events`)
423
+	 * in this versioned namespace of EE4
424
+	 * @param $version
425
+	 * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
426
+	 */
427
+	public static function model_names_with_plural_routes($version){
428
+		$model_version_info = new ModelVersionInfo($version);
429
+		$models_to_register = $model_version_info->modelsForRequestedVersion();
430
+		//let's not bother having endpoints for extra metas
431
+		unset(
432
+			$models_to_register['Extra_Meta'],
433
+			$models_to_register['Extra_Join'],
434
+			$models_to_register['Post_Meta']
435
+		);
436
+		return apply_filters(
437
+			'FHEE__EED_Core_REST_API___register_model_routes',
438
+			$models_to_register
439
+		);
440
+	}
441
+
442
+
443
+
444
+	/**
445
+	 * Gets the route data for EE models in the specified version
446
+	 *
447
+	 * @param string  $version
448
+	 * @param boolean $hidden_endpoint
449
+	 * @return array
450
+	 * @throws EE_Error
451
+	 */
452
+	protected function _get_model_route_data_for_version($version, $hidden_endpoint = false)
453
+	{
454
+		$model_routes = array();
455
+		$model_version_info = new ModelVersionInfo($version);
456
+		foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
457
+			$model = \EE_Registry::instance()->load_model($model_name);
458
+			//if this isn't a valid model then let's skip iterate to the next item in the loop.
459
+			if (! $model instanceof EEM_Base) {
460
+				continue;
461
+			}
462
+			//yes we could just register one route for ALL models, but then they wouldn't show up in the index
463
+			$plural_model_route = EED_Core_Rest_Api::get_collection_route($model);
464
+			$singular_model_route = EED_Core_Rest_Api::get_entity_route($model, '(?P<id>[^\/]+)');
465
+			$model_routes[$plural_model_route] = array(
466
+				array(
467
+					'callback'        => array(
468
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
469
+						'handleRequestGetAll',
470
+					),
471
+					'callback_args'   => array($version, $model_name),
472
+					'methods'         => WP_REST_Server::READABLE,
473
+					'hidden_endpoint' => $hidden_endpoint,
474
+					'args'            => $this->_get_read_query_params($model, $version),
475
+					'_links'          => array(
476
+						'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
477
+					),
478
+				),
479
+				'schema' => array(
480
+					'schema_callback' => array(
481
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
482
+						'handleSchemaRequest',
483
+					),
484
+					'callback_args'   => array($version, $model_name),
485
+				),
486
+			);
487
+			$model_routes[$singular_model_route] = array(
488
+				array(
489
+					'callback'        => array(
490
+						'EventEspresso\core\libraries\rest_api\controllers\model\Read',
491
+						'handleRequestGetOne',
492
+					),
493
+					'callback_args'   => array($version, $model_name),
494
+					'methods'         => WP_REST_Server::READABLE,
495
+					'hidden_endpoint' => $hidden_endpoint,
496
+					'args'            => $this->_get_response_selection_query_params($model, $version),
497
+				),
498
+			);
499
+			if( apply_filters(
500
+				'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
501
+				EED_Core_Rest_Api::should_have_write_endpoints($model),
502
+				$model
503
+			)){
504
+				$model_routes[$plural_model_route][] = array(
505
+					'callback'        => array(
506
+						'EventEspresso\core\libraries\rest_api\controllers\model\Write',
507
+						'handleRequestInsert',
508
+					),
509
+					'callback_args'   => array($version, $model_name),
510
+					'methods'         => WP_REST_Server::CREATABLE,
511
+					'hidden_endpoint' => $hidden_endpoint,
512
+					'args'            => $this->_get_write_params($model_name, $model_version_info, true),
513
+				);
514
+				$model_routes[$singular_model_route] = array_merge(
515
+					$model_routes[$singular_model_route],
516
+					array(
517
+						array(
518
+							'callback'        => array(
519
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
520
+								'handleRequestUpdate',
521
+							),
522
+							'callback_args'   => array($version, $model_name),
523
+							'methods'         => WP_REST_Server::EDITABLE,
524
+							'hidden_endpoint' => $hidden_endpoint,
525
+							'args'            => $this->_get_write_params($model_name, $model_version_info),
526
+						),
527
+						array(
528
+							'callback'        => array(
529
+								'EventEspresso\core\libraries\rest_api\controllers\model\Write',
530
+								'handleRequestDelete',
531
+							),
532
+							'callback_args'   => array($version, $model_name),
533
+							'methods'         => WP_REST_Server::DELETABLE,
534
+							'hidden_endpoint' => $hidden_endpoint,
535
+							'args'            => $this->_get_delete_query_params($model, $version),
536
+						)
537
+					)
538
+				);
539
+			}
540
+			foreach ($model->relation_settings() as $relation_name => $relation_obj) {
541
+
542
+				$related_route = EED_Core_Rest_Api::get_relation_route_via(
543
+					$model,
544
+					'(?P<id>[^\/]+)',
545
+					$relation_obj
546
+				);
547
+				$endpoints = array(
548
+					array(
549
+						'callback'        => array(
550
+							'EventEspresso\core\libraries\rest_api\controllers\model\Read',
551
+							'handleRequestGetRelated',
552
+						),
553
+						'callback_args'   => array($version, $model_name, $relation_name),
554
+						'methods'         => WP_REST_Server::READABLE,
555
+						'hidden_endpoint' => $hidden_endpoint,
556
+						'args'            => $this->_get_read_query_params($relation_obj->get_other_model(), $version),
557
+					),
558
+				);
559
+				$model_routes[$related_route] = $endpoints;
560
+			}
561
+		}
562
+		return $model_routes;
563
+	}
564
+
565
+
566
+
567
+	/**
568
+	 * Gets the relative URI to a model's REST API plural route, after the EE4 versioned namespace,
569
+	 * excluding the preceding slash.
570
+	 * Eg you pass get_plural_route_to('Event') = 'events'
571
+	 *
572
+	 * @param EEM_Base $model
573
+	 * @return string
574
+	 */
575
+	public static function get_collection_route(EEM_Base $model)
576
+	{
577
+		return EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
578
+	}
579
+
580
+
581
+
582
+	/**
583
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
584
+	 * excluding the preceding slash.
585
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
586
+	 *
587
+	 * @param EEM_Base $model eg Event or Venue
588
+	 * @param string $id
589
+	 * @return string
590
+	 */
591
+	public static function get_entity_route($model, $id)
592
+	{
593
+		return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
594
+	}
595
+
596
+
597
+	/**
598
+	 * Gets the relative URI to a model's REST API singular route, after the EE4 versioned namespace,
599
+	 * excluding the preceding slash.
600
+	 * Eg you pass get_plural_route_to('Event', 12) = 'events/12'
601
+	 *
602
+	 * @param EEM_Base                 $model eg Event or Venue
603
+	 * @param string                 $id
604
+	 * @param EE_Model_Relation_Base $relation_obj
605
+	 * @return string
606
+	 */
607
+	public static function get_relation_route_via(EEM_Base $model, $id, EE_Model_Relation_Base $relation_obj)
608
+	{
609
+		$related_model_name_endpoint_part = ModelRead::getRelatedEntityName(
610
+			$relation_obj->get_other_model()->get_this_model_name(),
611
+			$relation_obj
612
+		);
613
+		return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
614
+	}
615
+
616
+
617
+
618
+	/**
619
+	 * Adds onto the $relative_route the EE4 REST API versioned namespace.
620
+	 * Eg if given '4.8.36' and 'events', will return 'ee/v4.8.36/events'
621
+	 * @param string $relative_route
622
+	 * @param string $version
623
+	 * @return string
624
+	 */
625
+	public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
626
+		return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
627
+	}
628
+
629
+
630
+
631
+	/**
632
+	 * Adds all the RPC-style routes (remote procedure call-like routes, ie
633
+	 * routes that don't conform to the traditional REST CRUD-style).
634
+	 *
635
+	 * @deprecated since 4.9.1
636
+	 */
637
+	protected function _register_rpc_routes()
638
+	{
639
+		$routes = array();
640
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
641
+			$routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
642
+				$version,
643
+				$hidden_endpoint
644
+			);
645
+		}
646
+		return $routes;
647
+	}
648
+
649
+
650
+
651
+	/**
652
+	 * @param string  $version
653
+	 * @param boolean $hidden_endpoint
654
+	 * @return array
655
+	 */
656
+	protected function _get_rpc_route_data_for_version($version, $hidden_endpoint = false)
657
+	{
658
+		$this_versions_routes = array();
659
+		//checkin endpoint
660
+		$this_versions_routes['registrations/(?P<REG_ID>\d+)/toggle_checkin_for_datetime/(?P<DTT_ID>\d+)'] = array(
661
+			array(
662
+				'callback'        => array(
663
+					'EventEspresso\core\libraries\rest_api\controllers\rpc\Checkin',
664
+					'handleRequestToggleCheckin',
665
+				),
666
+				'methods'         => WP_REST_Server::CREATABLE,
667
+				'hidden_endpoint' => $hidden_endpoint,
668
+				'args'            => array(
669
+					'force' => array(
670
+						'required'    => false,
671
+						'default'     => false,
672
+						'description' => __(
673
+							// @codingStandardsIgnoreStart
674
+							'Whether to force toggle checkin, or to verify the registration status and allowed ticket uses',
675
+							// @codingStandardsIgnoreEnd
676
+							'event_espresso'
677
+						),
678
+					),
679
+				),
680
+				'callback_args'   => array($version),
681
+			),
682
+		);
683
+		return apply_filters(
684
+			'FHEE__EED_Core_Rest_Api___register_rpc_routes__this_versions_routes',
685
+			$this_versions_routes,
686
+			$version,
687
+			$hidden_endpoint
688
+		);
689
+	}
690
+
691
+
692
+
693
+	/**
694
+	 * Gets the query params that can be used when request one or many
695
+	 *
696
+	 * @param EEM_Base $model
697
+	 * @param string   $version
698
+	 * @return array
699
+	 */
700
+	protected function _get_response_selection_query_params(\EEM_Base $model, $version)
701
+	{
702
+		return apply_filters(
703
+			'FHEE__EED_Core_Rest_Api___get_response_selection_query_params',
704
+			array(
705
+				'include'   => array(
706
+					'required' => false,
707
+					'default'  => '*',
708
+					'type'     => 'string',
709
+				),
710
+				'calculate' => array(
711
+					'required'          => false,
712
+					'default'           => '',
713
+					'enum'              => self::$_field_calculator->retrieveCalculatedFieldsForModel($model),
714
+					'type'              => 'string',
715
+					//because we accept a CSV'd list of the enumerated strings, WP core validation and sanitization
716
+					//freaks out. We'll just validate this argument while handling the request
717
+					'validate_callback' => null,
718
+					'sanitize_callback' => null,
719
+				),
720
+			),
721
+			$model,
722
+			$version
723
+		);
724
+	}
725
+
726
+
727
+
728
+	/**
729
+	 * Gets the parameters acceptable for delete requests
730
+	 *
731
+	 * @param \EEM_Base $model
732
+	 * @param string    $version
733
+	 * @return array
734
+	 */
735
+	protected function _get_delete_query_params(\EEM_Base $model, $version)
736
+	{
737
+		$params_for_delete = array(
738
+			'allow_blocking' => array(
739
+				'required' => false,
740
+				'default'  => true,
741
+				'type'     => 'boolean',
742
+			),
743
+		);
744
+		$params_for_delete['force'] = array(
745
+			'required' => false,
746
+			'default'  => false,
747
+			'type'     => 'boolean',
748
+		);
749
+		return apply_filters(
750
+			'FHEE__EED_Core_Rest_Api___get_delete_query_params',
751
+			$params_for_delete,
752
+			$model,
753
+			$version
754
+		);
755
+	}
756
+
757
+
758
+
759
+	/**
760
+	 * Gets info about reading query params that are acceptable
761
+	 *
762
+	 * @param \EEM_Base $model eg 'Event' or 'Venue'
763
+	 * @param  string   $version
764
+	 * @return array    describing the args acceptable when querying this model
765
+	 * @throws EE_Error
766
+	 */
767
+	protected function _get_read_query_params(\EEM_Base $model, $version)
768
+	{
769
+		$default_orderby = array();
770
+		foreach ($model->get_combined_primary_key_fields() as $key_field) {
771
+			$default_orderby[$key_field->get_name()] = 'ASC';
772
+		}
773
+		return array_merge(
774
+			$this->_get_response_selection_query_params($model, $version),
775
+			array(
776
+				'where'    => array(
777
+					'required' => false,
778
+					'default'  => array(),
779
+					'type'     => 'object',
780
+				),
781
+				'limit'    => array(
782
+					'required' => false,
783
+					'default'  => EED_Core_Rest_Api::get_default_query_limit(),
784
+					'type'     => array(
785
+						'object',
786
+						'string',
787
+						'integer',
788
+					),
789
+				),
790
+				'order_by' => array(
791
+					'required' => false,
792
+					'default'  => $default_orderby,
793
+					'type'     => array(
794
+						'object',
795
+						'string',
796
+					),
797
+				),
798
+				'group_by' => array(
799
+					'required' => false,
800
+					'default'  => null,
801
+					'type'     => array(
802
+						'object',
803
+						'string',
804
+					),
805
+				),
806
+				'having'   => array(
807
+					'required' => false,
808
+					'default'  => null,
809
+					'type'     => 'object',
810
+				),
811
+				'caps'     => array(
812
+					'required' => false,
813
+					'default'  => EEM_Base::caps_read,
814
+					'type'     => 'string',
815
+				),
816
+			)
817
+		);
818
+	}
819
+
820
+
821
+
822
+	/**
823
+	 * Gets parameter information for a model regarding writing data
824
+	 *
825
+	 * @param string           $model_name
826
+	 * @param ModelVersionInfo $model_version_info
827
+	 * @param boolean          $create                                       whether this is for request to create (in which case we need
828
+	 *                                                                       all required params) or just to update (in which case we don't need those on every request)
829
+	 * @return array
830
+	 */
831
+	protected function _get_write_params(
832
+		$model_name,
833
+		ModelVersionInfo $model_version_info,
834
+		$create = false
835
+	) {
836
+		$model = EE_Registry::instance()->load_model($model_name);
837
+		$fields = $model_version_info->fieldsOnModelInThisVersion($model);
838
+		$args_info = array();
839
+		foreach ($fields as $field_name => $field_obj) {
840
+			if ($field_obj->is_auto_increment()) {
841
+				//totally ignore auto increment IDs
842
+				continue;
843
+			}
844
+			$arg_info = $field_obj->getSchema();
845
+			$required = $create && ! $field_obj->is_nullable() && $field_obj->get_default_value() === null;
846
+			$arg_info['required'] = $required;
847
+			//remove the read-only flag. If it were read-only we wouldn't list it as an argument while writing, right?
848
+			unset($arg_info['readonly']);
849
+			$schema_properties = $field_obj->getSchemaProperties();
850
+			if (
851
+				isset($schema_properties['raw'])
852
+				&& $field_obj->getSchemaType() === 'object'
853
+			) {
854
+				//if there's a "raw" form of this argument, use those properties instead
855
+				$arg_info = array_replace(
856
+					$arg_info,
857
+					$schema_properties['raw']
858
+				);
859
+			}
860
+			$arg_info['default'] = ModelDataTranslator::prepareFieldValueForJson(
861
+				$field_obj,
862
+				$field_obj->get_default_value(),
863
+				$model_version_info->requestedVersion()
864
+			);
865
+			//we do our own validation and sanitization within the controller
866
+			$arg_info['sanitize_callback'] =
867
+				array(
868
+					'EED_Core_Rest_Api',
869
+					'default_sanitize_callback',
870
+				);
871
+			$args_info[$field_name] = $arg_info;
872
+			if ($field_obj instanceof EE_Datetime_Field) {
873
+				$gmt_arg_info = $arg_info;
874
+				$gmt_arg_info['description'] = sprintf(
875
+					esc_html__(
876
+						'%1$s - the value for this field in UTC. Ignored if %2$s is provided.',
877
+						'event_espresso'
878
+					),
879
+					$field_obj->get_nicename(),
880
+					$field_name
881
+				);
882
+				$args_info[$field_name . '_gmt'] = $gmt_arg_info;
883
+			}
884
+		}
885
+		return $args_info;
886
+	}
887
+
888
+
889
+
890
+	/**
891
+	 * Replacement for WP API's 'rest_parse_request_arg'.
892
+	 * If the value is blank but not required, don't bother validating it.
893
+	 * Also, it uses our email validation instead of WP API's default.
894
+	 *
895
+	 * @param                 $value
896
+	 * @param WP_REST_Request $request
897
+	 * @param                 $param
898
+	 * @return bool|true|WP_Error
899
+	 * @throws InvalidArgumentException
900
+	 * @throws InvalidInterfaceException
901
+	 * @throws InvalidDataTypeException
902
+	 */
903
+	public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
904
+	{
905
+		$attributes = $request->get_attributes();
906
+		if (! isset($attributes['args'][$param])
907
+			|| ! is_array($attributes['args'][$param])) {
908
+			$validation_result = true;
909
+		} else {
910
+			$args = $attributes['args'][$param];
911
+			if ((
912
+					$value === ''
913
+					|| $value === null
914
+				)
915
+				&& (! isset($args['required'])
916
+					|| $args['required'] === false
917
+				)
918
+			) {
919
+				//not required and not provided? that's cool
920
+				$validation_result = true;
921
+			} elseif (isset($args['format'])
922
+				&& $args['format'] === 'email'
923
+			) {
924
+				$validation_result = true;
925
+				if (! self::_validate_email($value)) {
926
+					$validation_result = new WP_Error(
927
+						'rest_invalid_param',
928
+						esc_html__(
929
+							'The email address is not valid or does not exist.',
930
+							'event_espresso'
931
+						)
932
+					);
933
+				}
934
+			} else {
935
+				$validation_result = rest_validate_value_from_schema($value, $args, $param);
936
+			}
937
+		}
938
+		if (is_wp_error($validation_result)) {
939
+			return $validation_result;
940
+		}
941
+		return rest_sanitize_request_arg($value, $request, $param);
942
+	}
943
+
944
+
945
+
946
+	/**
947
+	 * Returns whether or not this email address is valid. Copied from EE_Email_Validation_Strategy::_validate_email()
948
+	 *
949
+	 * @param $email
950
+	 * @return bool
951
+	 * @throws InvalidArgumentException
952
+	 * @throws InvalidInterfaceException
953
+	 * @throws InvalidDataTypeException
954
+	 */
955
+	protected static function _validate_email($email){
956
+		try {
957
+			EmailAddressFactory::create($email);
958
+			return true;
959
+		} catch (EmailValidationException $e) {
960
+			return false;
961
+		}
962
+	}
963
+
964
+
965
+
966
+	/**
967
+	 * Gets routes for the config
968
+	 *
969
+	 * @return array @see _register_model_routes
970
+	 * @deprecated since version 4.9.1
971
+	 */
972
+	protected function _register_config_routes()
973
+	{
974
+		$config_routes = array();
975
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
976
+			$config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
977
+				$version,
978
+				$hidden_endpoint
979
+			);
980
+		}
981
+		return $config_routes;
982
+	}
983
+
984
+
985
+
986
+	/**
987
+	 * Gets routes for the config for the specified version
988
+	 *
989
+	 * @param string  $version
990
+	 * @param boolean $hidden_endpoint
991
+	 * @return array
992
+	 */
993
+	protected function _get_config_route_data_for_version($version, $hidden_endpoint)
994
+	{
995
+		return array(
996
+			'config'    => array(
997
+				array(
998
+					'callback'        => array(
999
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1000
+						'handleRequest',
1001
+					),
1002
+					'methods'         => WP_REST_Server::READABLE,
1003
+					'hidden_endpoint' => $hidden_endpoint,
1004
+					'callback_args'   => array($version),
1005
+				),
1006
+			),
1007
+			'site_info' => array(
1008
+				array(
1009
+					'callback'        => array(
1010
+						'EventEspresso\core\libraries\rest_api\controllers\config\Read',
1011
+						'handleRequestSiteInfo',
1012
+					),
1013
+					'methods'         => WP_REST_Server::READABLE,
1014
+					'hidden_endpoint' => $hidden_endpoint,
1015
+					'callback_args'   => array($version),
1016
+				),
1017
+			),
1018
+		);
1019
+	}
1020
+
1021
+
1022
+
1023
+	/**
1024
+	 * Gets the meta info routes
1025
+	 *
1026
+	 * @return array @see _register_model_routes
1027
+	 * @deprecated since version 4.9.1
1028
+	 */
1029
+	protected function _register_meta_routes()
1030
+	{
1031
+		$meta_routes = array();
1032
+		foreach (self::versions_served() as $version => $hidden_endpoint) {
1033
+			$meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1034
+				$version,
1035
+				$hidden_endpoint
1036
+			);
1037
+		}
1038
+		return $meta_routes;
1039
+	}
1040
+
1041
+
1042
+
1043
+	/**
1044
+	 * @param string  $version
1045
+	 * @param boolean $hidden_endpoint
1046
+	 * @return array
1047
+	 */
1048
+	protected function _get_meta_route_data_for_version($version, $hidden_endpoint = false)
1049
+	{
1050
+		return array(
1051
+			'resources' => array(
1052
+				array(
1053
+					'callback'        => array(
1054
+						'EventEspresso\core\libraries\rest_api\controllers\model\Meta',
1055
+						'handleRequestModelsMeta',
1056
+					),
1057
+					'methods'         => WP_REST_Server::READABLE,
1058
+					'hidden_endpoint' => $hidden_endpoint,
1059
+					'callback_args'   => array($version),
1060
+				),
1061
+			),
1062
+		);
1063
+	}
1064
+
1065
+
1066
+
1067
+	/**
1068
+	 * Tries to hide old 4.6 endpoints from the
1069
+	 *
1070
+	 * @param array $route_data
1071
+	 * @return array
1072
+	 * @throws \EE_Error
1073
+	 */
1074
+	public static function hide_old_endpoints($route_data)
1075
+	{
1076
+		//allow API clients to override which endpoints get hidden, in case
1077
+		//they want to discover particular endpoints
1078
+		//also, we don't have access to the request so we have to just grab it from the superglobal
1079
+		$force_show_ee_namespace = ltrim(
1080
+			EEH_Array::is_set($_REQUEST, 'force_show_ee_namespace', ''),
1081
+			'/'
1082
+		);
1083
+		foreach (EED_Core_Rest_Api::get_ee_route_data() as $namespace => $relative_urls) {
1084
+			foreach ($relative_urls as $resource_name => $endpoints) {
1085
+				foreach ($endpoints as $key => $endpoint) {
1086
+					//skip schema and other route options
1087
+					if (! is_numeric($key)) {
1088
+						continue;
1089
+					}
1090
+					//by default, hide "hidden_endpoint"s, unless the request indicates
1091
+					//to $force_show_ee_namespace, in which case only show that one
1092
+					//namespace's endpoints (and hide all others)
1093
+					if (
1094
+						($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1095
+						|| ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1096
+					) {
1097
+						$full_route = '/' . ltrim($namespace, '/');
1098
+						$full_route .= '/' . ltrim($resource_name, '/');
1099
+						unset($route_data[$full_route]);
1100
+					}
1101
+				}
1102
+			}
1103
+		}
1104
+		return $route_data;
1105
+	}
1106
+
1107
+
1108
+
1109
+	/**
1110
+	 * Returns an array describing which versions of core support serving requests for.
1111
+	 * Keys are core versions' major and minor version, and values are the
1112
+	 * LOWEST requested version they can serve. Eg, 4.7 can serve requests for 4.6-like
1113
+	 * data by just removing a few models and fields from the responses. However, 4.15 might remove
1114
+	 * the answers table entirely, in which case it would be very difficult for
1115
+	 * it to serve 4.6-style responses.
1116
+	 * Versions of core that are missing from this array are unknowns.
1117
+	 * previous ver
1118
+	 *
1119
+	 * @return array
1120
+	 */
1121
+	public static function version_compatibilities()
1122
+	{
1123
+		return apply_filters(
1124
+			'FHEE__EED_Core_REST_API__version_compatibilities',
1125
+			array(
1126
+				'4.8.29' => '4.8.29',
1127
+				'4.8.33' => '4.8.29',
1128
+				'4.8.34' => '4.8.29',
1129
+				'4.8.36' => '4.8.29',
1130
+			)
1131
+		);
1132
+	}
1133
+
1134
+
1135
+
1136
+	/**
1137
+	 * Gets the latest API version served. Eg if there
1138
+	 * are two versions served of the API, 4.8.29 and 4.8.32, and
1139
+	 * we are on core version 4.8.34, it will return the string "4.8.32"
1140
+	 *
1141
+	 * @return string
1142
+	 */
1143
+	public static function latest_rest_api_version()
1144
+	{
1145
+		$versions_served = \EED_Core_Rest_Api::versions_served();
1146
+		$versions_served_keys = array_keys($versions_served);
1147
+		return end($versions_served_keys);
1148
+	}
1149
+
1150
+
1151
+
1152
+	/**
1153
+	 * Using EED_Core_Rest_Api::version_compatibilities(), determines what version of
1154
+	 * EE the API can serve requests for. Eg, if we are on 4.15 of core, and
1155
+	 * we can serve requests from 4.12 or later, this will return array( '4.12', '4.13', '4.14', '4.15' ).
1156
+	 * We also indicate whether or not this version should be put in the index or not
1157
+	 *
1158
+	 * @return array keys are API version numbers (just major and minor numbers), and values
1159
+	 * are whether or not they should be hidden
1160
+	 */
1161
+	public static function versions_served()
1162
+	{
1163
+		$versions_served = array();
1164
+		$possibly_served_versions = EED_Core_Rest_Api::version_compatibilities();
1165
+		$lowest_compatible_version = end($possibly_served_versions);
1166
+		reset($possibly_served_versions);
1167
+		$versions_served_historically = array_keys($possibly_served_versions);
1168
+		$latest_version = end($versions_served_historically);
1169
+		reset($versions_served_historically);
1170
+		//for each version of core we have ever served:
1171
+		foreach ($versions_served_historically as $key_versioned_endpoint) {
1172
+			//if it's not above the current core version, and it's compatible with the current version of core
1173
+			if ($key_versioned_endpoint === $latest_version) {
1174
+				//don't hide the latest version in the index
1175
+				$versions_served[$key_versioned_endpoint] = false;
1176
+			} elseif (
1177
+				$key_versioned_endpoint >= $lowest_compatible_version
1178
+				&& $key_versioned_endpoint < EED_Core_Rest_Api::core_version()
1179
+			) {
1180
+				//include, but hide, previous versions which are still supported
1181
+				$versions_served[$key_versioned_endpoint] = true;
1182
+			} elseif (apply_filters(
1183
+				'FHEE__EED_Core_Rest_Api__versions_served__include_incompatible_versions',
1184
+				false,
1185
+				$possibly_served_versions
1186
+			)) {
1187
+				//if a version is no longer supported, don't include it in index or list of versions served
1188
+				$versions_served[$key_versioned_endpoint] = true;
1189
+			}
1190
+		}
1191
+		return $versions_served;
1192
+	}
1193
+
1194
+
1195
+
1196
+	/**
1197
+	 * Gets the major and minor version of EE core's version string
1198
+	 *
1199
+	 * @return string
1200
+	 */
1201
+	public static function core_version()
1202
+	{
1203
+		return apply_filters(
1204
+			'FHEE__EED_Core_REST_API__core_version',
1205
+			implode(
1206
+				'.',
1207
+				array_slice(
1208
+					explode(
1209
+						'.',
1210
+						espresso_version()
1211
+					),
1212
+				0,
1213
+				3
1214
+				)
1215
+			)
1216
+		);
1217
+	}
1218
+
1219
+
1220
+
1221
+	/**
1222
+	 * Gets the default limit that should be used when querying for resources
1223
+	 *
1224
+	 * @return int
1225
+	 */
1226
+	public static function get_default_query_limit()
1227
+	{
1228
+		//we actually don't use a const because we want folks to always use
1229
+		//this method, not the const directly
1230
+		return apply_filters(
1231
+			'FHEE__EED_Core_Rest_Api__get_default_query_limit',
1232
+			50
1233
+		);
1234
+	}
1235
+
1236
+
1237
+
1238
+	/**
1239
+	 *    run - initial module setup
1240
+	 *
1241
+	 * @access    public
1242
+	 * @param  WP $WP
1243
+	 * @return    void
1244
+	 */
1245
+	public function run($WP)
1246
+	{
1247
+	}
1248 1248
 }
1249 1249
 
1250 1250
 // End of file EED_Core_Rest_Api.module.php
Please login to merge, or discard this patch.
Spacing   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
      */
129 129
     protected static function _set_hooks_for_changes()
130 130
     {
131
-        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES . 'rest_api' . DS . 'changes'), false);
131
+        $folder_contents = EEH_File::get_contents_of_folders(array(EE_LIBRARIES.'rest_api'.DS.'changes'), false);
132 132
         foreach ($folder_contents as $classname_in_namespace => $filepath) {
133 133
             //ignore the base parent class
134 134
             //and legacy named classes
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
             ) {
138 138
                 continue;
139 139
             }
140
-            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\' . $classname_in_namespace;
140
+            $full_classname = 'EventEspresso\core\libraries\rest_api\changes\\'.$classname_in_namespace;
141 141
             if (class_exists($full_classname)) {
142 142
                 $instance_of_class = new $full_classname;
143 143
                 if ($instance_of_class instanceof ChangesInBase) {
@@ -183,10 +183,10 @@  discard block
 block discarded – undo
183 183
                      * }
184 184
                      */
185 185
                     //skip route options
186
-                    if (! is_numeric($endpoint_key)) {
186
+                    if ( ! is_numeric($endpoint_key)) {
187 187
                         continue;
188 188
                     }
189
-                    if (! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
189
+                    if ( ! isset($data_for_single_endpoint['callback'], $data_for_single_endpoint['methods'])) {
190 190
                         throw new EE_Error(
191 191
                             esc_html__(
192 192
                                 // @codingStandardsIgnoreStart
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
                     }
207 207
                     if (isset($data_for_single_endpoint['callback_args'])) {
208 208
                         $callback_args = $data_for_single_endpoint['callback_args'];
209
-                        $single_endpoint_args['callback'] = function (\WP_REST_Request $request) use (
209
+                        $single_endpoint_args['callback'] = function(\WP_REST_Request $request) use (
210 210
                             $callback,
211 211
                             $callback_args
212 212
                         ) {
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
                     $schema_route_data = $data_for_multiple_endpoints['schema'];
226 226
                     $schema_callback = $schema_route_data['schema_callback'];
227 227
                     $callback_args = $schema_route_data['callback_args'];
228
-                    $multiple_endpoint_args['schema'] = function () use ($schema_callback, $callback_args) {
228
+                    $multiple_endpoint_args['schema'] = function() use ($schema_callback, $callback_args) {
229 229
                         return call_user_func_array(
230 230
                             $schema_callback,
231 231
                             $callback_args
@@ -269,7 +269,7 @@  discard block
 block discarded – undo
269 269
     {
270 270
         //delete the saved EE REST API routes
271 271
         foreach (EED_Core_Rest_Api::versions_served() as $version => $hidden) {
272
-            delete_option(EED_Core_Rest_Api::saved_routes_option_names . $version);
272
+            delete_option(EED_Core_Rest_Api::saved_routes_option_names.$version);
273 273
         }
274 274
     }
275 275
 
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
     {
290 290
         $ee_routes = array();
291 291
         foreach (self::versions_served() as $version => $hidden_endpoints) {
292
-            $ee_routes[self::ee_api_namespace . $version] = self::_get_ee_route_data_for_version(
292
+            $ee_routes[self::ee_api_namespace.$version] = self::_get_ee_route_data_for_version(
293 293
                 $version,
294 294
                 $hidden_endpoints
295 295
             );
@@ -310,8 +310,8 @@  discard block
 block discarded – undo
310 310
      */
311 311
     protected static function _get_ee_route_data_for_version($version, $hidden_endpoints = false)
312 312
     {
313
-        $ee_routes = get_option(self::saved_routes_option_names . $version, null);
314
-        if (! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
313
+        $ee_routes = get_option(self::saved_routes_option_names.$version, null);
314
+        if ( ! $ee_routes || (defined('EE_REST_API_DEBUG_MODE') && EE_REST_API_DEBUG_MODE)) {
315 315
             $ee_routes = self::_save_ee_route_data_for_version($version, $hidden_endpoints);
316 316
         }
317 317
         return $ee_routes;
@@ -339,7 +339,7 @@  discard block
 block discarded – undo
339 339
                 $instance->_get_rpc_route_data_for_version($version, $hidden_endpoints)
340 340
             )
341 341
         );
342
-        $option_name = self::saved_routes_option_names . $version;
342
+        $option_name = self::saved_routes_option_names.$version;
343 343
         if (get_option($option_name)) {
344 344
             update_option($option_name, $routes, true);
345 345
         } else {
@@ -405,11 +405,11 @@  discard block
 block discarded – undo
405 405
      */
406 406
     public static function should_have_write_endpoints(EEM_Base $model)
407 407
     {
408
-        if ($model->is_wp_core_model()){
408
+        if ($model->is_wp_core_model()) {
409 409
             return false;
410 410
         }
411
-        foreach($model->get_tables() as $table){
412
-            if( $table->is_global()){
411
+        foreach ($model->get_tables() as $table) {
412
+            if ($table->is_global()) {
413 413
                 return false;
414 414
             }
415 415
         }
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
      * @param $version
425 425
      * @return array keys are model names (eg 'Event') and values ar either classnames (eg 'EEM_Event')
426 426
      */
427
-    public static function model_names_with_plural_routes($version){
427
+    public static function model_names_with_plural_routes($version) {
428 428
         $model_version_info = new ModelVersionInfo($version);
429 429
         $models_to_register = $model_version_info->modelsForRequestedVersion();
430 430
         //let's not bother having endpoints for extra metas
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
         foreach (EED_Core_Rest_Api::model_names_with_plural_routes($version) as $model_name => $model_classname) {
457 457
             $model = \EE_Registry::instance()->load_model($model_name);
458 458
             //if this isn't a valid model then let's skip iterate to the next item in the loop.
459
-            if (! $model instanceof EEM_Base) {
459
+            if ( ! $model instanceof EEM_Base) {
460 460
                 continue;
461 461
             }
462 462
             //yes we could just register one route for ALL models, but then they wouldn't show up in the index
@@ -473,7 +473,7 @@  discard block
 block discarded – undo
473 473
                     'hidden_endpoint' => $hidden_endpoint,
474 474
                     'args'            => $this->_get_read_query_params($model, $version),
475 475
                     '_links'          => array(
476
-                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace . $version . $singular_model_route),
476
+                        'self' => rest_url(EED_Core_Rest_Api::ee_api_namespace.$version.$singular_model_route),
477 477
                     ),
478 478
                 ),
479 479
                 'schema' => array(
@@ -496,11 +496,11 @@  discard block
 block discarded – undo
496 496
                     'args'            => $this->_get_response_selection_query_params($model, $version),
497 497
                 ),
498 498
             );
499
-            if( apply_filters(
499
+            if (apply_filters(
500 500
                 'FHEE__EED_Core_Rest_Api___get_model_route_data_for_version__add_write_endpoints',
501 501
                 EED_Core_Rest_Api::should_have_write_endpoints($model),
502 502
                 $model
503
-            )){
503
+            )) {
504 504
                 $model_routes[$plural_model_route][] = array(
505 505
                     'callback'        => array(
506 506
                         'EventEspresso\core\libraries\rest_api\controllers\model\Write',
@@ -590,7 +590,7 @@  discard block
 block discarded – undo
590 590
      */
591 591
     public static function get_entity_route($model, $id)
592 592
     {
593
-        return EED_Core_Rest_Api::get_collection_route($model). '/' . $id;
593
+        return EED_Core_Rest_Api::get_collection_route($model).'/'.$id;
594 594
     }
595 595
 
596 596
 
@@ -610,7 +610,7 @@  discard block
 block discarded – undo
610 610
             $relation_obj->get_other_model()->get_this_model_name(),
611 611
             $relation_obj
612 612
         );
613
-        return EED_Core_Rest_Api::get_entity_route($model, $id) . '/' . $related_model_name_endpoint_part;
613
+        return EED_Core_Rest_Api::get_entity_route($model, $id).'/'.$related_model_name_endpoint_part;
614 614
     }
615 615
 
616 616
 
@@ -622,8 +622,8 @@  discard block
 block discarded – undo
622 622
      * @param string $version
623 623
      * @return string
624 624
      */
625
-    public static function get_versioned_route_to($relative_route, $version = '4.8.36'){
626
-        return '/' . EED_Core_Rest_Api::ee_api_namespace . $version . '/' . $relative_route;
625
+    public static function get_versioned_route_to($relative_route, $version = '4.8.36') {
626
+        return '/'.EED_Core_Rest_Api::ee_api_namespace.$version.'/'.$relative_route;
627 627
     }
628 628
 
629 629
 
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
     {
639 639
         $routes = array();
640 640
         foreach (self::versions_served() as $version => $hidden_endpoint) {
641
-            $routes[self::ee_api_namespace . $version] = $this->_get_rpc_route_data_for_version(
641
+            $routes[self::ee_api_namespace.$version] = $this->_get_rpc_route_data_for_version(
642 642
                 $version,
643 643
                 $hidden_endpoint
644 644
             );
@@ -879,7 +879,7 @@  discard block
 block discarded – undo
879 879
                     $field_obj->get_nicename(),
880 880
                     $field_name
881 881
                 );
882
-                $args_info[$field_name . '_gmt'] = $gmt_arg_info;
882
+                $args_info[$field_name.'_gmt'] = $gmt_arg_info;
883 883
             }
884 884
         }
885 885
         return $args_info;
@@ -900,10 +900,10 @@  discard block
 block discarded – undo
900 900
      * @throws InvalidInterfaceException
901 901
      * @throws InvalidDataTypeException
902 902
      */
903
-    public static function default_sanitize_callback( $value, WP_REST_Request $request, $param)
903
+    public static function default_sanitize_callback($value, WP_REST_Request $request, $param)
904 904
     {
905 905
         $attributes = $request->get_attributes();
906
-        if (! isset($attributes['args'][$param])
906
+        if ( ! isset($attributes['args'][$param])
907 907
             || ! is_array($attributes['args'][$param])) {
908 908
             $validation_result = true;
909 909
         } else {
@@ -912,7 +912,7 @@  discard block
 block discarded – undo
912 912
                     $value === ''
913 913
                     || $value === null
914 914
                 )
915
-                && (! isset($args['required'])
915
+                && ( ! isset($args['required'])
916 916
                     || $args['required'] === false
917 917
                 )
918 918
             ) {
@@ -922,7 +922,7 @@  discard block
 block discarded – undo
922 922
                 && $args['format'] === 'email'
923 923
             ) {
924 924
                 $validation_result = true;
925
-                if (! self::_validate_email($value)) {
925
+                if ( ! self::_validate_email($value)) {
926 926
                     $validation_result = new WP_Error(
927 927
                         'rest_invalid_param',
928 928
                         esc_html__(
@@ -952,7 +952,7 @@  discard block
 block discarded – undo
952 952
      * @throws InvalidInterfaceException
953 953
      * @throws InvalidDataTypeException
954 954
      */
955
-    protected static function _validate_email($email){
955
+    protected static function _validate_email($email) {
956 956
         try {
957 957
             EmailAddressFactory::create($email);
958 958
             return true;
@@ -973,7 +973,7 @@  discard block
 block discarded – undo
973 973
     {
974 974
         $config_routes = array();
975 975
         foreach (self::versions_served() as $version => $hidden_endpoint) {
976
-            $config_routes[self::ee_api_namespace . $version] = $this->_get_config_route_data_for_version(
976
+            $config_routes[self::ee_api_namespace.$version] = $this->_get_config_route_data_for_version(
977 977
                 $version,
978 978
                 $hidden_endpoint
979 979
             );
@@ -1030,7 +1030,7 @@  discard block
 block discarded – undo
1030 1030
     {
1031 1031
         $meta_routes = array();
1032 1032
         foreach (self::versions_served() as $version => $hidden_endpoint) {
1033
-            $meta_routes[self::ee_api_namespace . $version] = $this->_get_meta_route_data_for_version(
1033
+            $meta_routes[self::ee_api_namespace.$version] = $this->_get_meta_route_data_for_version(
1034 1034
                 $version,
1035 1035
                 $hidden_endpoint
1036 1036
             );
@@ -1084,7 +1084,7 @@  discard block
 block discarded – undo
1084 1084
             foreach ($relative_urls as $resource_name => $endpoints) {
1085 1085
                 foreach ($endpoints as $key => $endpoint) {
1086 1086
                     //skip schema and other route options
1087
-                    if (! is_numeric($key)) {
1087
+                    if ( ! is_numeric($key)) {
1088 1088
                         continue;
1089 1089
                     }
1090 1090
                     //by default, hide "hidden_endpoint"s, unless the request indicates
@@ -1094,8 +1094,8 @@  discard block
 block discarded – undo
1094 1094
                         ($force_show_ee_namespace !== '' && $force_show_ee_namespace !== $namespace)
1095 1095
                         || ($endpoint['hidden_endpoint'] && $force_show_ee_namespace === '')
1096 1096
                     ) {
1097
-                        $full_route = '/' . ltrim($namespace, '/');
1098
-                        $full_route .= '/' . ltrim($resource_name, '/');
1097
+                        $full_route = '/'.ltrim($namespace, '/');
1098
+                        $full_route .= '/'.ltrim($resource_name, '/');
1099 1099
                         unset($route_data[$full_route]);
1100 1100
                     }
1101 1101
                 }
Please login to merge, or discard this patch.
core/db_models/fields/EE_Email_Field.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -16,38 +16,38 @@
 block discarded – undo
16 16
 {
17 17
 
18 18
 
19
-    /**
20
-     * @param string $table_column
21
-     * @param string $nice_name
22
-     * @param bool   $nullable
23
-     * @param null   $default_value
24
-     * @throws InvalidArgumentException
25
-     */
26
-    public function __construct($table_column, $nice_name, $nullable, $default_value = null)
27
-    {
28
-        parent::__construct($table_column, $nice_name, $nullable, $default_value);
29
-        $this->setSchemaFormat('email');
30
-    }
19
+	/**
20
+	 * @param string $table_column
21
+	 * @param string $nice_name
22
+	 * @param bool   $nullable
23
+	 * @param null   $default_value
24
+	 * @throws InvalidArgumentException
25
+	 */
26
+	public function __construct($table_column, $nice_name, $nullable, $default_value = null)
27
+	{
28
+		parent::__construct($table_column, $nice_name, $nullable, $default_value);
29
+		$this->setSchemaFormat('email');
30
+	}
31 31
 
32 32
 
33 33
 
34
-    /**
35
-     * In form inputs, we should have called htmlentities and addslashes() on form inputs,
36
-     * so we need to undo that on setting of these fields
37
-     *
38
-     * @param string $email_address
39
-     * @return string
40
-     * @throws InvalidArgumentException
41
-     * @throws InvalidInterfaceException
42
-     * @throws InvalidDataTypeException
43
-     */
44
-    public function prepare_for_set($email_address)
45
-    {
46
-        try {
47
-            $email_address = EmailAddressFactory::create($email_address);
48
-            return $email_address->get();
49
-        } catch (EmailValidationException $e) {
50
-            return '';
51
-        }
52
-    }
34
+	/**
35
+	 * In form inputs, we should have called htmlentities and addslashes() on form inputs,
36
+	 * so we need to undo that on setting of these fields
37
+	 *
38
+	 * @param string $email_address
39
+	 * @return string
40
+	 * @throws InvalidArgumentException
41
+	 * @throws InvalidInterfaceException
42
+	 * @throws InvalidDataTypeException
43
+	 */
44
+	public function prepare_for_set($email_address)
45
+	{
46
+		try {
47
+			$email_address = EmailAddressFactory::create($email_address);
48
+			return $email_address->get();
49
+		} catch (EmailValidationException $e) {
50
+			return '';
51
+		}
52
+	}
53 53
 }
Please login to merge, or discard this patch.