Completed
Branch EDTR/master (6ca8c5)
by
unknown
26:04 queued 17:36
created
caffeinated/payment_methods/Aim/EEG_Aim.gateway.php 1 patch
Indentation   +595 added lines, -595 removed lines patch added patch discarded remove patch
@@ -26,417 +26,417 @@  discard block
 block discarded – undo
26 26
 class EEG_Aim extends EE_Onsite_Gateway
27 27
 {
28 28
 
29
-    const LIVE_URL    = 'https://secure2.authorize.net/gateway/transact.dll'; // Authnet URL
30
-
31
-    const SANDBOX_URL = 'https://test.authorize.net/gateway/transact.dll';
32
-
33
-    protected $_login_id;
34
-
35
-    protected $_transaction_key;
36
-
37
-    protected $_currencies_supported = array(
38
-        'AUD',
39
-        'USD',
40
-        'CAD',
41
-        'EUR',
42
-        'GBP',
43
-        'NZD',
44
-    );
45
-
46
-    /**
47
-     * Whether to send test transactions (even to live site)
48
-     *
49
-     * @var boolean
50
-     */
51
-    protected $_test_transactions;
52
-
53
-    private $VERIFY_PEER = false;
54
-
55
-    private $_x_post_fields = array(
56
-        "version"        => "3.1",
57
-        "delim_char"     => ",",
58
-        "delim_data"     => "TRUE",
59
-        "relay_response" => "FALSE",
60
-        "encap_char"     => "|",
61
-    );
62
-
63
-    private $_additional_line_items = array();
64
-
65
-    /**
66
-     * A list of all fields in the AIM API.
67
-     * Used to warn user if they try to set a field not offered in the API.
68
-     */
69
-    private $_all_aim_fields = array(
70
-        "address",
71
-        "allow_partial_auth",
72
-        "amount",
73
-        "auth_code",
74
-        "authentication_indicator",
75
-        "bank_aba_code",
76
-        "bank_acct_name",
77
-        "bank_acct_num",
78
-        "bank_acct_type",
79
-        "bank_check_number",
80
-        "bank_name",
81
-        "card_code",
82
-        "card_num",
83
-        "cardholder_authentication_value",
84
-        "city",
85
-        "company",
86
-        "country",
87
-        "cust_id",
88
-        "customer_ip",
89
-        "delim_char",
90
-        "delim_data",
91
-        "description",
92
-        "duplicate_window",
93
-        "duty",
94
-        "echeck_type",
95
-        "email",
96
-        "email_customer",
97
-        "encap_char",
98
-        "exp_date",
99
-        "fax",
100
-        "first_name",
101
-        "footer_email_receipt",
102
-        "freight",
103
-        "header_email_receipt",
104
-        "invoice_num",
105
-        "last_name",
106
-        "line_item",
107
-        "login",
108
-        "method",
109
-        "phone",
110
-        "po_num",
111
-        "recurring_billing",
112
-        "relay_response",
113
-        "ship_to_address",
114
-        "ship_to_city",
115
-        "ship_to_company",
116
-        "ship_to_country",
117
-        "ship_to_first_name",
118
-        "ship_to_last_name",
119
-        "ship_to_state",
120
-        "ship_to_zip",
121
-        "split_tender_id",
122
-        "state",
123
-        "tax",
124
-        "tax_exempt",
125
-        "test_request",
126
-        "tran_key",
127
-        "trans_id",
128
-        "type",
129
-        "version",
130
-        "zip",
131
-        "solution_id",
132
-        "currency_code"
133
-    );
134
-
135
-
136
-    /**
137
-     * Gets the URL where the request should go. This is filterable
138
-     *
139
-     * @return string
140
-     */
141
-    protected function _get_server_url()
142
-    {
143
-        return apply_filters(
144
-            'FHEE__EEG_Aim___get_server_url',
145
-            $this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL,
146
-            $this
147
-        );
148
-    }
149
-
150
-
151
-    /**
152
-     * Asks the gateway to do whatever it does to process the payment. Onsite gateways will
153
-     * usually send a request directly to the payment provider and update the payment's status based on that;
154
-     * whereas offsite gateways will usually just update the payment with the URL and query parameters to use
155
-     * for sending the request via http_remote_request()
156
-     *
157
-     * @param EEI_Payment $payment
158
-     * @param array $billing_info {
159
-     *  @type $credit_card string
160
-     *  @type $cvv string
161
-     *  @type $exp_month string
162
-     *  @type $exp_year string
163
-     *  @see parent::do_direct_payment
164
-     * }
165
-     * @return EEI_Payment updated
166
-     */
167
-    public function do_direct_payment($payment, $billing_info = null)
168
-    {
169
-        // Enable test mode if needed
170
-        // 4007000000027  <-- test successful visa
171
-        // 4222222222222  <-- test failure card number
172
-
173
-        $item_num = 1;
174
-        $transaction = $payment->transaction();
175
-        $gateway_formatter = $this->_get_gateway_formatter();
176
-        $order_description = $this->prepareStringForAuthnet($gateway_formatter->formatOrderDescription($payment));
177
-        $primary_registrant = $transaction->primary_registration();
178
-        // if we're are charging for the full amount, show the normal line items
179
-        // and the itemized total adds up properly
180
-        if ($this->_can_easily_itemize_transaction_for($payment)) {
181
-            $total_line_item = $transaction->total_line_item();
182
-            foreach ($total_line_item->get_items() as $line_item) {
183
-                if ($line_item->quantity() == 0) {
184
-                    continue;
185
-                }
186
-                $this->addLineItem(
187
-                    $item_num++,
188
-                    $gateway_formatter->formatLineItemName($line_item, $payment),
189
-                    $gateway_formatter->formatLineItemDesc($line_item, $payment),
190
-                    $line_item->quantity(),
191
-                    $line_item->unit_price(),
192
-                    'N'
193
-                );
194
-                $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', ';
195
-            }
196
-            foreach ($total_line_item->tax_descendants() as $tax_line_item) {
197
-                $this->addLineItem(
198
-                    $item_num++,
199
-                    $tax_line_item->name(),
200
-                    $tax_line_item->desc(),
201
-                    1,
202
-                    $tax_line_item->total(),
203
-                    'N'
204
-                );
205
-            }
206
-        }
207
-
208
-        // start transaction
209
-        // if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id
210
-        $partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363';
211
-        $this->setField('solution_id', $partner_id);
212
-        $this->setField('amount', $gateway_formatter->formatCurrency($payment->amount()));
213
-        $this->setField('description', substr(rtrim($order_description, ', '), 0, 255));
214
-        $this->_set_sensitive_billing_data($billing_info);
215
-        $this->setField('first_name', $billing_info['first_name']);
216
-        $this->setField('last_name', $billing_info['last_name']);
217
-        $this->setField('email', $billing_info['email']);
218
-        $this->setField('company', $billing_info['company']);
219
-        $this->setField('address', $billing_info['address'].' '.$billing_info['address2']);
220
-        $this->setField('city', $billing_info['city']);
221
-        $this->setField('state', $billing_info['state']);
222
-        $this->setField('country', $billing_info['country']);
223
-        $this->setField('zip', $billing_info['zip']);
224
-        $this->setField('fax', $billing_info['fax']);
225
-        $this->setField('cust_id', $primary_registrant->ID());
226
-        $this->setField('phone', $billing_info['phone']);
227
-        $currency_config = LoaderFactory::getLoader()->load('EE_Currency_Config');
228
-        $this->setField('currency_code', $currency_config->code);
229
-        // invoice_num would be nice to have it be unique per SPCO page-load, that way if users
230
-        // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page
231
-        // in which case, we need to generate teh invoice num per request right here...
232
-        $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
233
-        // tell AIM that any duplicates sent in the next 5 minutes are to be ignored
234
-        $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS);
235
-
236
-        if ($this->_test_transactions) {
237
-            $this->test_request = "true";
238
-        }
239
-
240
-        // Capture response
241
-        $this->type = "AUTH_CAPTURE";
242
-        $response = $this->_sendRequest($payment);
243
-        if (! empty($response)) {
244
-            if ($response->error_message) {
245
-                $payment->set_status($this->_pay_model->failed_status());
246
-                $payment->set_gateway_response($response->error_message);
247
-            } else {
248
-                $payment_status = $response->approved
249
-                    ? $this->_pay_model->approved_status()
250
-                    : $this->_pay_model->declined_status();
251
-                $payment->set_status($payment_status);
252
-                // make sure we interpret the AMT as a float, not an international string (where periods are thousand separators)
253
-                $payment->set_amount((float) $response->amount);
254
-                $payment->set_gateway_response(
255
-                    sprintf(
256
-                        esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'),
257
-                        $response->response_reason_text,
258
-                        $response->response_reason_code
259
-                    )
260
-                );
261
-                if ($this->_debug_mode) {
262
-                    $txn_id = $response->invoice_number;
263
-                } else {
264
-                    $txn_id = $response->transaction_id;
265
-                }
266
-                $payment->set_txn_id_chq_nmbr($txn_id);
267
-            }
268
-            $payment->set_extra_accntng($primary_registrant->reg_code());
269
-            $payment->set_details(print_r($response, true));
270
-        } else {
271
-            $payment->set_status($this->_pay_model->failed_status());
272
-            $payment->set_gateway_response(__("There was no response from Authorize.net", 'event_espresso'));
273
-            $payment->set_details(print_r($response, true));
274
-        }
275
-        return $payment;
276
-    }
277
-
278
-
279
-    /**
280
-     * Sets billing data for the upcoming request to AIM that is considered sensitive;
281
-     * also this method can be overridden by children classes to easily change
282
-     * what billing data gets sent
283
-     *
284
-     * @param array $billing_info
285
-     */
286
-    protected function _set_sensitive_billing_data($billing_info)
287
-    {
288
-        $this->setField('card_num', $billing_info['credit_card']);
289
-        $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']);
290
-        $this->setField('card_code', $billing_info['cvv']);
291
-    }
292
-
293
-
294
-    /**
295
-     * Add a line item.
296
-     *
297
-     * @param string $item_id
298
-     * @param string $item_name
299
-     * @param string $item_description
300
-     * @param string $item_quantity
301
-     * @param string $item_unit_price
302
-     * @param string $item_taxable
303
-     */
304
-    public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable)
305
-    {
306
-        $args = array(
307
-            substr($item_id, 0, 31),
308
-            substr($this->prepareStringForAuthnet($item_name), 0, 31),
309
-            substr($this->prepareStringForAuthnet($item_description), 0, 255),
310
-            number_format(abs($item_quantity), 2, '.', ''),
311
-            number_format(abs($item_unit_price), 2, '.', ''),
312
-            $item_taxable === 'N' ? 'N' : 'Y'
313
-        );
314
-        $this->_additional_line_items[] = implode('<|>', $args);
315
-    }
316
-
317
-
318
-    /**
319
-     * Set an individual name/value pair. This will append x_ to the name
320
-     * before posting.
321
-     *
322
-     * @param string $name
323
-     * @param string $value
324
-     * @throws AuthorizeNetException
325
-     */
326
-    protected function setField($name, $value)
327
-    {
328
-        if (in_array($name, $this->_all_aim_fields)) {
329
-            $this->_x_post_fields[ $name ] = $value;
330
-        } else {
331
-            throw new AuthorizeNetException("Error: no field $name exists in the AIM API.
29
+	const LIVE_URL    = 'https://secure2.authorize.net/gateway/transact.dll'; // Authnet URL
30
+
31
+	const SANDBOX_URL = 'https://test.authorize.net/gateway/transact.dll';
32
+
33
+	protected $_login_id;
34
+
35
+	protected $_transaction_key;
36
+
37
+	protected $_currencies_supported = array(
38
+		'AUD',
39
+		'USD',
40
+		'CAD',
41
+		'EUR',
42
+		'GBP',
43
+		'NZD',
44
+	);
45
+
46
+	/**
47
+	 * Whether to send test transactions (even to live site)
48
+	 *
49
+	 * @var boolean
50
+	 */
51
+	protected $_test_transactions;
52
+
53
+	private $VERIFY_PEER = false;
54
+
55
+	private $_x_post_fields = array(
56
+		"version"        => "3.1",
57
+		"delim_char"     => ",",
58
+		"delim_data"     => "TRUE",
59
+		"relay_response" => "FALSE",
60
+		"encap_char"     => "|",
61
+	);
62
+
63
+	private $_additional_line_items = array();
64
+
65
+	/**
66
+	 * A list of all fields in the AIM API.
67
+	 * Used to warn user if they try to set a field not offered in the API.
68
+	 */
69
+	private $_all_aim_fields = array(
70
+		"address",
71
+		"allow_partial_auth",
72
+		"amount",
73
+		"auth_code",
74
+		"authentication_indicator",
75
+		"bank_aba_code",
76
+		"bank_acct_name",
77
+		"bank_acct_num",
78
+		"bank_acct_type",
79
+		"bank_check_number",
80
+		"bank_name",
81
+		"card_code",
82
+		"card_num",
83
+		"cardholder_authentication_value",
84
+		"city",
85
+		"company",
86
+		"country",
87
+		"cust_id",
88
+		"customer_ip",
89
+		"delim_char",
90
+		"delim_data",
91
+		"description",
92
+		"duplicate_window",
93
+		"duty",
94
+		"echeck_type",
95
+		"email",
96
+		"email_customer",
97
+		"encap_char",
98
+		"exp_date",
99
+		"fax",
100
+		"first_name",
101
+		"footer_email_receipt",
102
+		"freight",
103
+		"header_email_receipt",
104
+		"invoice_num",
105
+		"last_name",
106
+		"line_item",
107
+		"login",
108
+		"method",
109
+		"phone",
110
+		"po_num",
111
+		"recurring_billing",
112
+		"relay_response",
113
+		"ship_to_address",
114
+		"ship_to_city",
115
+		"ship_to_company",
116
+		"ship_to_country",
117
+		"ship_to_first_name",
118
+		"ship_to_last_name",
119
+		"ship_to_state",
120
+		"ship_to_zip",
121
+		"split_tender_id",
122
+		"state",
123
+		"tax",
124
+		"tax_exempt",
125
+		"test_request",
126
+		"tran_key",
127
+		"trans_id",
128
+		"type",
129
+		"version",
130
+		"zip",
131
+		"solution_id",
132
+		"currency_code"
133
+	);
134
+
135
+
136
+	/**
137
+	 * Gets the URL where the request should go. This is filterable
138
+	 *
139
+	 * @return string
140
+	 */
141
+	protected function _get_server_url()
142
+	{
143
+		return apply_filters(
144
+			'FHEE__EEG_Aim___get_server_url',
145
+			$this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL,
146
+			$this
147
+		);
148
+	}
149
+
150
+
151
+	/**
152
+	 * Asks the gateway to do whatever it does to process the payment. Onsite gateways will
153
+	 * usually send a request directly to the payment provider and update the payment's status based on that;
154
+	 * whereas offsite gateways will usually just update the payment with the URL and query parameters to use
155
+	 * for sending the request via http_remote_request()
156
+	 *
157
+	 * @param EEI_Payment $payment
158
+	 * @param array $billing_info {
159
+	 *  @type $credit_card string
160
+	 *  @type $cvv string
161
+	 *  @type $exp_month string
162
+	 *  @type $exp_year string
163
+	 *  @see parent::do_direct_payment
164
+	 * }
165
+	 * @return EEI_Payment updated
166
+	 */
167
+	public function do_direct_payment($payment, $billing_info = null)
168
+	{
169
+		// Enable test mode if needed
170
+		// 4007000000027  <-- test successful visa
171
+		// 4222222222222  <-- test failure card number
172
+
173
+		$item_num = 1;
174
+		$transaction = $payment->transaction();
175
+		$gateway_formatter = $this->_get_gateway_formatter();
176
+		$order_description = $this->prepareStringForAuthnet($gateway_formatter->formatOrderDescription($payment));
177
+		$primary_registrant = $transaction->primary_registration();
178
+		// if we're are charging for the full amount, show the normal line items
179
+		// and the itemized total adds up properly
180
+		if ($this->_can_easily_itemize_transaction_for($payment)) {
181
+			$total_line_item = $transaction->total_line_item();
182
+			foreach ($total_line_item->get_items() as $line_item) {
183
+				if ($line_item->quantity() == 0) {
184
+					continue;
185
+				}
186
+				$this->addLineItem(
187
+					$item_num++,
188
+					$gateway_formatter->formatLineItemName($line_item, $payment),
189
+					$gateway_formatter->formatLineItemDesc($line_item, $payment),
190
+					$line_item->quantity(),
191
+					$line_item->unit_price(),
192
+					'N'
193
+				);
194
+				$order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', ';
195
+			}
196
+			foreach ($total_line_item->tax_descendants() as $tax_line_item) {
197
+				$this->addLineItem(
198
+					$item_num++,
199
+					$tax_line_item->name(),
200
+					$tax_line_item->desc(),
201
+					1,
202
+					$tax_line_item->total(),
203
+					'N'
204
+				);
205
+			}
206
+		}
207
+
208
+		// start transaction
209
+		// if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id
210
+		$partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363';
211
+		$this->setField('solution_id', $partner_id);
212
+		$this->setField('amount', $gateway_formatter->formatCurrency($payment->amount()));
213
+		$this->setField('description', substr(rtrim($order_description, ', '), 0, 255));
214
+		$this->_set_sensitive_billing_data($billing_info);
215
+		$this->setField('first_name', $billing_info['first_name']);
216
+		$this->setField('last_name', $billing_info['last_name']);
217
+		$this->setField('email', $billing_info['email']);
218
+		$this->setField('company', $billing_info['company']);
219
+		$this->setField('address', $billing_info['address'].' '.$billing_info['address2']);
220
+		$this->setField('city', $billing_info['city']);
221
+		$this->setField('state', $billing_info['state']);
222
+		$this->setField('country', $billing_info['country']);
223
+		$this->setField('zip', $billing_info['zip']);
224
+		$this->setField('fax', $billing_info['fax']);
225
+		$this->setField('cust_id', $primary_registrant->ID());
226
+		$this->setField('phone', $billing_info['phone']);
227
+		$currency_config = LoaderFactory::getLoader()->load('EE_Currency_Config');
228
+		$this->setField('currency_code', $currency_config->code);
229
+		// invoice_num would be nice to have it be unique per SPCO page-load, that way if users
230
+		// press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page
231
+		// in which case, we need to generate teh invoice num per request right here...
232
+		$this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
233
+		// tell AIM that any duplicates sent in the next 5 minutes are to be ignored
234
+		$this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS);
235
+
236
+		if ($this->_test_transactions) {
237
+			$this->test_request = "true";
238
+		}
239
+
240
+		// Capture response
241
+		$this->type = "AUTH_CAPTURE";
242
+		$response = $this->_sendRequest($payment);
243
+		if (! empty($response)) {
244
+			if ($response->error_message) {
245
+				$payment->set_status($this->_pay_model->failed_status());
246
+				$payment->set_gateway_response($response->error_message);
247
+			} else {
248
+				$payment_status = $response->approved
249
+					? $this->_pay_model->approved_status()
250
+					: $this->_pay_model->declined_status();
251
+				$payment->set_status($payment_status);
252
+				// make sure we interpret the AMT as a float, not an international string (where periods are thousand separators)
253
+				$payment->set_amount((float) $response->amount);
254
+				$payment->set_gateway_response(
255
+					sprintf(
256
+						esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'),
257
+						$response->response_reason_text,
258
+						$response->response_reason_code
259
+					)
260
+				);
261
+				if ($this->_debug_mode) {
262
+					$txn_id = $response->invoice_number;
263
+				} else {
264
+					$txn_id = $response->transaction_id;
265
+				}
266
+				$payment->set_txn_id_chq_nmbr($txn_id);
267
+			}
268
+			$payment->set_extra_accntng($primary_registrant->reg_code());
269
+			$payment->set_details(print_r($response, true));
270
+		} else {
271
+			$payment->set_status($this->_pay_model->failed_status());
272
+			$payment->set_gateway_response(__("There was no response from Authorize.net", 'event_espresso'));
273
+			$payment->set_details(print_r($response, true));
274
+		}
275
+		return $payment;
276
+	}
277
+
278
+
279
+	/**
280
+	 * Sets billing data for the upcoming request to AIM that is considered sensitive;
281
+	 * also this method can be overridden by children classes to easily change
282
+	 * what billing data gets sent
283
+	 *
284
+	 * @param array $billing_info
285
+	 */
286
+	protected function _set_sensitive_billing_data($billing_info)
287
+	{
288
+		$this->setField('card_num', $billing_info['credit_card']);
289
+		$this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']);
290
+		$this->setField('card_code', $billing_info['cvv']);
291
+	}
292
+
293
+
294
+	/**
295
+	 * Add a line item.
296
+	 *
297
+	 * @param string $item_id
298
+	 * @param string $item_name
299
+	 * @param string $item_description
300
+	 * @param string $item_quantity
301
+	 * @param string $item_unit_price
302
+	 * @param string $item_taxable
303
+	 */
304
+	public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable)
305
+	{
306
+		$args = array(
307
+			substr($item_id, 0, 31),
308
+			substr($this->prepareStringForAuthnet($item_name), 0, 31),
309
+			substr($this->prepareStringForAuthnet($item_description), 0, 255),
310
+			number_format(abs($item_quantity), 2, '.', ''),
311
+			number_format(abs($item_unit_price), 2, '.', ''),
312
+			$item_taxable === 'N' ? 'N' : 'Y'
313
+		);
314
+		$this->_additional_line_items[] = implode('<|>', $args);
315
+	}
316
+
317
+
318
+	/**
319
+	 * Set an individual name/value pair. This will append x_ to the name
320
+	 * before posting.
321
+	 *
322
+	 * @param string $name
323
+	 * @param string $value
324
+	 * @throws AuthorizeNetException
325
+	 */
326
+	protected function setField($name, $value)
327
+	{
328
+		if (in_array($name, $this->_all_aim_fields)) {
329
+			$this->_x_post_fields[ $name ] = $value;
330
+		} else {
331
+			throw new AuthorizeNetException("Error: no field $name exists in the AIM API.
332 332
             To set a custom field use setCustomField('field','value') instead.");
333
-        }
334
-    }
335
-
336
-
337
-    /**
338
-     * Posts the request to AuthorizeNet & returns response.
339
-     *
340
-     * @param $payment
341
-     * @return \EE_AuthorizeNetAIM_Response
342
-     */
343
-    private function _sendRequest($payment)
344
-    {
345
-        $this->_x_post_fields['login'] = $this->_login_id;
346
-        $this->_x_post_fields['tran_key'] = $this->_transaction_key;
347
-        $x_keys = array();
348
-        foreach ($this->_x_post_fields as $key => $value) {
349
-            $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value));
350
-        }
351
-        // Add line items
352
-        foreach ($this->_additional_line_items as $key => $value) {
353
-            $x_keys[] =  "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value));
354
-        }
355
-        $this->_log_clean_request($x_keys, $payment);
356
-        $post_url = $this->_get_server_url();
357
-        $curl_request = curl_init($post_url);
358
-        $post_body = implode("&", $x_keys);
359
-        curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body);
360
-        curl_setopt($curl_request, CURLOPT_HEADER, 0);
361
-        curl_setopt($curl_request, CURLOPT_TIMEOUT, 45);
362
-        curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
363
-        curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);
364
-        if ($this->VERIFY_PEER) {
365
-            curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem');
366
-        } else {
367
-            curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
368
-        }
369
-
370
-        if (preg_match('/xml/', $post_url)) {
371
-            curl_setopt($curl_request, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
372
-        }
373
-
374
-        $response = curl_exec($curl_request);
375
-
376
-        curl_close($curl_request);
377
-        $response_obj =  new EE_AuthorizeNetAIM_Response($response);
378
-
379
-        return $this->_log_and_clean_response($response_obj, $payment);
380
-    }
381
-
382
-
383
-    /**
384
-     * Logs the clean data only
385
-     *
386
-     * @param array $request_array
387
-     * @param EEI_Payment $payment
388
-     */
389
-    protected function _log_clean_request($request_array, $payment)
390
-    {
391
-        $keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date');
392
-        foreach ($request_array as $index => $keyvaltogether) {
393
-            foreach ($keys_to_filter_out as $key) {
394
-                if (strpos($keyvaltogether, $key) === 0) {
395
-                    // found it at the first character
396
-                    // so its one of them
397
-                    unset($request_array[ $index ]);
398
-                }
399
-            }
400
-        }
401
-        $this->log(
402
-            array(
403
-                'AIM Request sent:' => $request_array,
404
-                'Server URL'        => $this->_get_server_url()
405
-            ),
406
-            $payment
407
-        );
408
-    }
409
-
410
-
411
-
412
-    /**
413
-     * Logs the response and cleans it
414
-     *
415
-     * @param EE_AuthorizeNetAIM_Response $response_obj
416
-     * @param EE_Payment                  $payment
417
-     * @return \EE_AuthorizeNetAIM_Response
418
-     */
419
-    private function _log_and_clean_response($response_obj, $payment)
420
-    {
421
-        $response_obj->account_number = '';
422
-        $this->log(array('AIM Response received:' => (array) $response_obj), $payment);
423
-        return $response_obj;
424
-    }
425
-
426
-    /**
427
-     * Removes characters Authorize.net doesn't handle well.
428
-     * @since 4.9.82.p
429
-     * @param $text
430
-     * @return string
431
-     */
432
-    private function prepareStringForAuthnet($text)
433
-    {
434
-        return str_replace(
435
-            '\'',
436
-            '',
437
-            $text
438
-        );
439
-    }
333
+		}
334
+	}
335
+
336
+
337
+	/**
338
+	 * Posts the request to AuthorizeNet & returns response.
339
+	 *
340
+	 * @param $payment
341
+	 * @return \EE_AuthorizeNetAIM_Response
342
+	 */
343
+	private function _sendRequest($payment)
344
+	{
345
+		$this->_x_post_fields['login'] = $this->_login_id;
346
+		$this->_x_post_fields['tran_key'] = $this->_transaction_key;
347
+		$x_keys = array();
348
+		foreach ($this->_x_post_fields as $key => $value) {
349
+			$x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value));
350
+		}
351
+		// Add line items
352
+		foreach ($this->_additional_line_items as $key => $value) {
353
+			$x_keys[] =  "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value));
354
+		}
355
+		$this->_log_clean_request($x_keys, $payment);
356
+		$post_url = $this->_get_server_url();
357
+		$curl_request = curl_init($post_url);
358
+		$post_body = implode("&", $x_keys);
359
+		curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body);
360
+		curl_setopt($curl_request, CURLOPT_HEADER, 0);
361
+		curl_setopt($curl_request, CURLOPT_TIMEOUT, 45);
362
+		curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
363
+		curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);
364
+		if ($this->VERIFY_PEER) {
365
+			curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem');
366
+		} else {
367
+			curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
368
+		}
369
+
370
+		if (preg_match('/xml/', $post_url)) {
371
+			curl_setopt($curl_request, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
372
+		}
373
+
374
+		$response = curl_exec($curl_request);
375
+
376
+		curl_close($curl_request);
377
+		$response_obj =  new EE_AuthorizeNetAIM_Response($response);
378
+
379
+		return $this->_log_and_clean_response($response_obj, $payment);
380
+	}
381
+
382
+
383
+	/**
384
+	 * Logs the clean data only
385
+	 *
386
+	 * @param array $request_array
387
+	 * @param EEI_Payment $payment
388
+	 */
389
+	protected function _log_clean_request($request_array, $payment)
390
+	{
391
+		$keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date');
392
+		foreach ($request_array as $index => $keyvaltogether) {
393
+			foreach ($keys_to_filter_out as $key) {
394
+				if (strpos($keyvaltogether, $key) === 0) {
395
+					// found it at the first character
396
+					// so its one of them
397
+					unset($request_array[ $index ]);
398
+				}
399
+			}
400
+		}
401
+		$this->log(
402
+			array(
403
+				'AIM Request sent:' => $request_array,
404
+				'Server URL'        => $this->_get_server_url()
405
+			),
406
+			$payment
407
+		);
408
+	}
409
+
410
+
411
+
412
+	/**
413
+	 * Logs the response and cleans it
414
+	 *
415
+	 * @param EE_AuthorizeNetAIM_Response $response_obj
416
+	 * @param EE_Payment                  $payment
417
+	 * @return \EE_AuthorizeNetAIM_Response
418
+	 */
419
+	private function _log_and_clean_response($response_obj, $payment)
420
+	{
421
+		$response_obj->account_number = '';
422
+		$this->log(array('AIM Response received:' => (array) $response_obj), $payment);
423
+		return $response_obj;
424
+	}
425
+
426
+	/**
427
+	 * Removes characters Authorize.net doesn't handle well.
428
+	 * @since 4.9.82.p
429
+	 * @param $text
430
+	 * @return string
431
+	 */
432
+	private function prepareStringForAuthnet($text)
433
+	{
434
+		return str_replace(
435
+			'\'',
436
+			'',
437
+			$text
438
+		);
439
+	}
440 440
 }
441 441
 
442 442
 
@@ -452,192 +452,192 @@  discard block
 block discarded – undo
452 452
 class EE_AuthorizeNetAIM_Response
453 453
 {
454 454
 
455
-    const APPROVED = '1';
456
-    const DECLINED = '2';
457
-    const ERROR = '3';
458
-    const HELD = '4';
459
-
460
-    protected $_x_post_fields = array(
461
-        "version"        => "3.1",
462
-        "delim_char"     => ",",
463
-        "delim_data"     => "TRUE",
464
-        "relay_response" => "FALSE",
465
-        "encap_char"     => "|",
466
-    );
467
-    public $approved;
468
-    public $declined;
469
-    public $error;
470
-    public $held;
471
-    public $response_code;
472
-    public $response_subcode;
473
-    public $response_reason_code;
474
-    public $response_reason_text;
475
-    public $authorization_code;
476
-    public $avs_response;
477
-    public $transaction_id;
478
-    public $invoice_number;
479
-    public $description;
480
-    public $amount;
481
-    public $method;
482
-    public $transaction_type;
483
-    public $customer_id;
484
-    public $first_name;
485
-    public $last_name;
486
-    public $company;
487
-    public $address;
488
-    public $city;
489
-    public $state;
490
-    public $zip_code;
491
-    public $country;
492
-    public $phone;
493
-    public $fax;
494
-    public $email_address;
495
-    public $ship_to_first_name;
496
-    public $ship_to_last_name;
497
-    public $ship_to_company;
498
-    public $ship_to_address;
499
-    public $ship_to_city;
500
-    public $ship_to_state;
501
-    public $ship_to_zip_code;
502
-    public $ship_to_country;
503
-    public $tax;
504
-    public $duty;
505
-    public $freight;
506
-    public $tax_exempt;
507
-    public $purchase_order_number;
508
-    public $md5_hash;
509
-    public $card_code_response;
510
-    public $cavv_response; // cardholder_authentication_verification_response
511
-    public $account_number;
512
-    public $card_type;
513
-    public $split_tender_id;
514
-    public $requested_amount;
515
-    public $balance_on_card;
516
-    public $response; // The response string from AuthorizeNet.
517
-    public $error_message;
518
-    private $_response_array = array(); // An array with the split response.
519
-
520
-
521
-    /**
522
-     * Constructor. Parses the AuthorizeNet response string
523
-     *
524
-     * @param string $response The response from the AuthNet server.
525
-     * @var string   $delimiter The delimiter used (default is ",")
526
-     * @var string   $encap_char The encap_char used (default is "|")
527
-     * @var array    $custom_fields Any custom fields set in the request.
528
-     */
529
-
530
-    public function __construct($response)
531
-    {
532
-        $encap_char = $this->_x_post_fields['encap_char'];
533
-        $delimiter = $this->_x_post_fields['delim_char'];
534
-        if ($response) {
535
-            // Split Array
536
-            $this->response = $response;
537
-            if ($encap_char) {
538
-                $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1));
539
-            } else {
540
-                $this->_response_array = explode($delimiter, $response);
541
-            }
542
-
543
-            /**
544
-             * If AuthorizeNet doesn't return a delimited response.
545
-             */
546
-            if (count($this->_response_array) < 10) {
547
-                $this->approved = false;
548
-                $this->error = true;
549
-                $this->error_message = sprintf(
550
-                    esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'),
551
-                    esc_html($response)
552
-                );
553
-                return;
554
-            }
555
-
556
-
557
-
558
-            // Set all fields
559
-            $this->response_code = $this->_response_array[0];
560
-            $this->response_subcode = $this->_response_array[1];
561
-            $this->response_reason_code = $this->_response_array[2];
562
-            $this->response_reason_text = $this->_response_array[3];
563
-            $this->authorization_code = $this->_response_array[4];
564
-            $this->avs_response = $this->_response_array[5];
565
-            $this->transaction_id = $this->_response_array[6];
566
-            $this->invoice_number = $this->_response_array[7];
567
-            $this->description = $this->_response_array[8];
568
-            $this->amount = $this->_response_array[9];
569
-            $this->method = $this->_response_array[10];
570
-            $this->transaction_type = $this->_response_array[11];
571
-            $this->customer_id = $this->_response_array[12];
572
-            $this->first_name = $this->_response_array[13];
573
-            $this->last_name = $this->_response_array[14];
574
-            $this->company = $this->_response_array[15];
575
-            $this->address = $this->_response_array[16];
576
-            $this->city = $this->_response_array[17];
577
-            $this->state = $this->_response_array[18];
578
-            $this->zip_code = $this->_response_array[19];
579
-            $this->country = $this->_response_array[20];
580
-            $this->phone = $this->_response_array[21];
581
-            $this->fax = $this->_response_array[22];
582
-            $this->email_address = $this->_response_array[23];
583
-            $this->ship_to_first_name = $this->_response_array[24];
584
-            $this->ship_to_last_name = $this->_response_array[25];
585
-            $this->ship_to_company = $this->_response_array[26];
586
-            $this->ship_to_address = $this->_response_array[27];
587
-            $this->ship_to_city = $this->_response_array[28];
588
-            $this->ship_to_state = $this->_response_array[29];
589
-            $this->ship_to_zip_code = $this->_response_array[30];
590
-            $this->ship_to_country = $this->_response_array[31];
591
-            $this->tax = $this->_response_array[32];
592
-            $this->duty = $this->_response_array[33];
593
-            $this->freight = $this->_response_array[34];
594
-            $this->tax_exempt = $this->_response_array[35];
595
-            $this->purchase_order_number = $this->_response_array[36];
596
-            $this->md5_hash = $this->_response_array[37];
597
-            $this->card_code_response = $this->_response_array[38];
598
-            $this->cavv_response = $this->_response_array[39];
599
-            $this->account_number = $this->_response_array[50];
600
-            $this->card_type = $this->_response_array[51];
601
-            $this->split_tender_id = $this->_response_array[52];
602
-            $this->requested_amount = $this->_response_array[53];
603
-            $this->balance_on_card = $this->_response_array[54];
604
-
605
-            $this->approved = ($this->response_code === self::APPROVED);
606
-            $this->declined = ($this->response_code === self::DECLINED);
607
-            $this->error = ($this->response_code === self::ERROR);
608
-            $this->held = ($this->response_code === self::HELD);
609
-        } else {
610
-            $this->approved = false;
611
-            $this->error = true;
612
-            $this->error_message = esc_html__(
613
-                'Error connecting to Authorize.net',
614
-                'event_espresso'
615
-            );
616
-        }
617
-    }
455
+	const APPROVED = '1';
456
+	const DECLINED = '2';
457
+	const ERROR = '3';
458
+	const HELD = '4';
459
+
460
+	protected $_x_post_fields = array(
461
+		"version"        => "3.1",
462
+		"delim_char"     => ",",
463
+		"delim_data"     => "TRUE",
464
+		"relay_response" => "FALSE",
465
+		"encap_char"     => "|",
466
+	);
467
+	public $approved;
468
+	public $declined;
469
+	public $error;
470
+	public $held;
471
+	public $response_code;
472
+	public $response_subcode;
473
+	public $response_reason_code;
474
+	public $response_reason_text;
475
+	public $authorization_code;
476
+	public $avs_response;
477
+	public $transaction_id;
478
+	public $invoice_number;
479
+	public $description;
480
+	public $amount;
481
+	public $method;
482
+	public $transaction_type;
483
+	public $customer_id;
484
+	public $first_name;
485
+	public $last_name;
486
+	public $company;
487
+	public $address;
488
+	public $city;
489
+	public $state;
490
+	public $zip_code;
491
+	public $country;
492
+	public $phone;
493
+	public $fax;
494
+	public $email_address;
495
+	public $ship_to_first_name;
496
+	public $ship_to_last_name;
497
+	public $ship_to_company;
498
+	public $ship_to_address;
499
+	public $ship_to_city;
500
+	public $ship_to_state;
501
+	public $ship_to_zip_code;
502
+	public $ship_to_country;
503
+	public $tax;
504
+	public $duty;
505
+	public $freight;
506
+	public $tax_exempt;
507
+	public $purchase_order_number;
508
+	public $md5_hash;
509
+	public $card_code_response;
510
+	public $cavv_response; // cardholder_authentication_verification_response
511
+	public $account_number;
512
+	public $card_type;
513
+	public $split_tender_id;
514
+	public $requested_amount;
515
+	public $balance_on_card;
516
+	public $response; // The response string from AuthorizeNet.
517
+	public $error_message;
518
+	private $_response_array = array(); // An array with the split response.
519
+
520
+
521
+	/**
522
+	 * Constructor. Parses the AuthorizeNet response string
523
+	 *
524
+	 * @param string $response The response from the AuthNet server.
525
+	 * @var string   $delimiter The delimiter used (default is ",")
526
+	 * @var string   $encap_char The encap_char used (default is "|")
527
+	 * @var array    $custom_fields Any custom fields set in the request.
528
+	 */
529
+
530
+	public function __construct($response)
531
+	{
532
+		$encap_char = $this->_x_post_fields['encap_char'];
533
+		$delimiter = $this->_x_post_fields['delim_char'];
534
+		if ($response) {
535
+			// Split Array
536
+			$this->response = $response;
537
+			if ($encap_char) {
538
+				$this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1));
539
+			} else {
540
+				$this->_response_array = explode($delimiter, $response);
541
+			}
542
+
543
+			/**
544
+			 * If AuthorizeNet doesn't return a delimited response.
545
+			 */
546
+			if (count($this->_response_array) < 10) {
547
+				$this->approved = false;
548
+				$this->error = true;
549
+				$this->error_message = sprintf(
550
+					esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'),
551
+					esc_html($response)
552
+				);
553
+				return;
554
+			}
555
+
556
+
557
+
558
+			// Set all fields
559
+			$this->response_code = $this->_response_array[0];
560
+			$this->response_subcode = $this->_response_array[1];
561
+			$this->response_reason_code = $this->_response_array[2];
562
+			$this->response_reason_text = $this->_response_array[3];
563
+			$this->authorization_code = $this->_response_array[4];
564
+			$this->avs_response = $this->_response_array[5];
565
+			$this->transaction_id = $this->_response_array[6];
566
+			$this->invoice_number = $this->_response_array[7];
567
+			$this->description = $this->_response_array[8];
568
+			$this->amount = $this->_response_array[9];
569
+			$this->method = $this->_response_array[10];
570
+			$this->transaction_type = $this->_response_array[11];
571
+			$this->customer_id = $this->_response_array[12];
572
+			$this->first_name = $this->_response_array[13];
573
+			$this->last_name = $this->_response_array[14];
574
+			$this->company = $this->_response_array[15];
575
+			$this->address = $this->_response_array[16];
576
+			$this->city = $this->_response_array[17];
577
+			$this->state = $this->_response_array[18];
578
+			$this->zip_code = $this->_response_array[19];
579
+			$this->country = $this->_response_array[20];
580
+			$this->phone = $this->_response_array[21];
581
+			$this->fax = $this->_response_array[22];
582
+			$this->email_address = $this->_response_array[23];
583
+			$this->ship_to_first_name = $this->_response_array[24];
584
+			$this->ship_to_last_name = $this->_response_array[25];
585
+			$this->ship_to_company = $this->_response_array[26];
586
+			$this->ship_to_address = $this->_response_array[27];
587
+			$this->ship_to_city = $this->_response_array[28];
588
+			$this->ship_to_state = $this->_response_array[29];
589
+			$this->ship_to_zip_code = $this->_response_array[30];
590
+			$this->ship_to_country = $this->_response_array[31];
591
+			$this->tax = $this->_response_array[32];
592
+			$this->duty = $this->_response_array[33];
593
+			$this->freight = $this->_response_array[34];
594
+			$this->tax_exempt = $this->_response_array[35];
595
+			$this->purchase_order_number = $this->_response_array[36];
596
+			$this->md5_hash = $this->_response_array[37];
597
+			$this->card_code_response = $this->_response_array[38];
598
+			$this->cavv_response = $this->_response_array[39];
599
+			$this->account_number = $this->_response_array[50];
600
+			$this->card_type = $this->_response_array[51];
601
+			$this->split_tender_id = $this->_response_array[52];
602
+			$this->requested_amount = $this->_response_array[53];
603
+			$this->balance_on_card = $this->_response_array[54];
604
+
605
+			$this->approved = ($this->response_code === self::APPROVED);
606
+			$this->declined = ($this->response_code === self::DECLINED);
607
+			$this->error = ($this->response_code === self::ERROR);
608
+			$this->held = ($this->response_code === self::HELD);
609
+		} else {
610
+			$this->approved = false;
611
+			$this->error = true;
612
+			$this->error_message = esc_html__(
613
+				'Error connecting to Authorize.net',
614
+				'event_espresso'
615
+			);
616
+		}
617
+	}
618 618
 }
619 619
 
620 620
 if (! class_exists('AuthorizeNetException')) {
621
-    /**
622
-     * Class AuthorizeNetException
623
-     *
624
-     * @package    AuthorizeNet
625
-     */
626
-    class AuthorizeNetException extends Exception
627
-    {
628
-
629
-        /**
630
-         * Construct the exception. Note: The message is NOT binary safe.
631
-         *
632
-         * @link http://php.net/manual/en/exception.construct.php
633
-         * @param string $message [optional] The Exception message to throw.
634
-         * @param int $code [optional] The Exception code.
635
-         * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0
636
-         * @since 5.1.0
637
-         */
638
-        public function __construct($message = "", $code = 0, Exception $previous = null)
639
-        {
640
-            parent::__construct($message, $code, $previous);
641
-        }
642
-    }
621
+	/**
622
+	 * Class AuthorizeNetException
623
+	 *
624
+	 * @package    AuthorizeNet
625
+	 */
626
+	class AuthorizeNetException extends Exception
627
+	{
628
+
629
+		/**
630
+		 * Construct the exception. Note: The message is NOT binary safe.
631
+		 *
632
+		 * @link http://php.net/manual/en/exception.construct.php
633
+		 * @param string $message [optional] The Exception message to throw.
634
+		 * @param int $code [optional] The Exception code.
635
+		 * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0
636
+		 * @since 5.1.0
637
+		 */
638
+		public function __construct($message = "", $code = 0, Exception $previous = null)
639
+		{
640
+			parent::__construct($message, $code, $previous);
641
+		}
642
+	}
643 643
 }
Please login to merge, or discard this patch.
payment_methods/Aim/help_tabs/payment_methods_overview_aim.help_tab.php 1 patch
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -4,75 +4,75 @@
 block discarded – undo
4 4
 </p>
5 5
 <p>
6 6
     <?php printf(
7
-        esc_html__(
8
-            'See %1$shere%2$s for list of currencies supported by Authorize.net AIM.',
9
-            'event_espresso'
10
-        ),
11
-        "<a href='https://support.authorize.net/s/article/Which-Currencies-Does-Authorize-Net-Support/' target='_blank' rel='noopener noreferrer'>",
12
-        "</a>"
13
-    ); ?>
7
+		esc_html__(
8
+			'See %1$shere%2$s for list of currencies supported by Authorize.net AIM.',
9
+			'event_espresso'
10
+		),
11
+		"<a href='https://support.authorize.net/s/article/Which-Currencies-Does-Authorize-Net-Support/' target='_blank' rel='noopener noreferrer'>",
12
+		"</a>"
13
+	); ?>
14 14
 </p>
15 15
 <p><strong><?php esc_html_e('Authorize.net AIM Settings', 'event_espresso'); ?></strong></p>
16 16
 <ul>
17 17
     <li>
18 18
         <strong><?php esc_html_e('Authorize.net API Login ID', 'event_espresso'); ?></strong><br/>
19 19
         <?php printf(
20
-            esc_html__(
21
-                'Enter your API Login ID for Authorize.net. Learn how to find your %1$sAPI Login%2$s ID.',
22
-                'event_espresso'
23
-            ),
24
-            '<a href="https://support.authorize.net/authkb/index?page=content&id=A405" target="_blank" rel="noopener noreferrer">',
25
-            '</a>'
26
-        ); ?>
20
+			esc_html__(
21
+				'Enter your API Login ID for Authorize.net. Learn how to find your %1$sAPI Login%2$s ID.',
22
+				'event_espresso'
23
+			),
24
+			'<a href="https://support.authorize.net/authkb/index?page=content&id=A405" target="_blank" rel="noopener noreferrer">',
25
+			'</a>'
26
+		); ?>
27 27
     </li>
28 28
     <li>
29 29
         <strong><?php esc_html_e('Authorize.net Transaction Key', 'event_espresso'); ?></strong><br/>
30 30
         <?php printf(
31
-            esc_html__(
32
-                'Enter your Transaction Key for Authorize.net. Learn how to find your %1$sTransaction Key%2$s.',
33
-                'event_espresso'
34
-            ),
35
-            '<a href="https://support.authorize.net/authkb/index?page=content&id=A405" target="_blank" rel="noopener noreferrer">',
36
-            '</a>'
37
-        ); ?>
31
+			esc_html__(
32
+				'Enter your Transaction Key for Authorize.net. Learn how to find your %1$sTransaction Key%2$s.',
33
+				'event_espresso'
34
+			),
35
+			'<a href="https://support.authorize.net/authkb/index?page=content&id=A405" target="_blank" rel="noopener noreferrer">',
36
+			'</a>'
37
+		); ?>
38 38
     </li>
39 39
     <li>
40 40
         <strong>
41 41
             <?php esc_html_e(
42
-                'Is this an account on the Authorize.net development server?',
43
-                'event_espresso'
44
-            ); ?></strong><br/>
42
+				'Is this an account on the Authorize.net development server?',
43
+				'event_espresso'
44
+			); ?></strong><br/>
45 45
         <?php esc_html_e(
46
-            'Specify whether this is a live/production account or a test account on the Authorize.net development server.',
47
-            'event_espresso'
48
-        ); ?>
46
+			'Specify whether this is a live/production account or a test account on the Authorize.net development server.',
47
+			'event_espresso'
48
+		); ?>
49 49
     </li>
50 50
     <li>
51 51
         <strong><?php esc_html_e('Do you want to submit a test transaction?', 'event_espresso'); ?></strong><br/>
52 52
         <?php esc_html_e(
53
-            'Specify if you want to test the Authorize.net AIM payment gateway by submitting a test transaction. Be sure to turn this setting off when you are done testing.',
54
-            'event_espresso'
55
-        ); ?>
53
+			'Specify if you want to test the Authorize.net AIM payment gateway by submitting a test transaction. Be sure to turn this setting off when you are done testing.',
54
+			'event_espresso'
55
+		); ?>
56 56
     </li>
57 57
     <li>
58 58
         <strong><?php esc_html_e('Excluded and Required Payment Form Fields', 'event_espresso'); ?></strong><br/>
59 59
         <?php esc_html_e(
60
-            'By logging into Authorize.net, you can change which payment fields are required by Authorize.net when processing payments. These settings affect both the Advanced Integration Method (AIM, this) and the Simple Integration Method (SIM, different). The payment method settings "Excluded Payment Form Fields" and "Required Payment Form Fields" allow you to change the billing form in Event Espresso to reflect your payment form settings in Authorize.net.',
61
-            'event_espresso'
62
-        ); ?>
60
+			'By logging into Authorize.net, you can change which payment fields are required by Authorize.net when processing payments. These settings affect both the Advanced Integration Method (AIM, this) and the Simple Integration Method (SIM, different). The payment method settings "Excluded Payment Form Fields" and "Required Payment Form Fields" allow you to change the billing form in Event Espresso to reflect your payment form settings in Authorize.net.',
61
+			'event_espresso'
62
+		); ?>
63 63
         <br>
64 64
         <?php
65
-        printf(
66
-            esc_html__(
67
-                'To change your payment form settings in Authorize.net, %1$slog in to authorize.net%2$s, go to %3$sAccount then Payment Form%2$s, then %4$sForm Fields%2$s. It will look similar to %5$sthis%2$s. If you make a field required in Authorize.net, you should also make it required in Event Espresso. If it isn\'t required in Authorize.net, and you want to simplify the billing form in Event Espresso, you can exclude it from the Event Espresso Form too.',
68
-                'event_espresso'
69
-            ),
70
-            '<a href="http://authorize.net" target="_blank" rel="noopener noreferrer">',
71
-            '</a>',
72
-            '<a href="https://monosnap.com/file/nebVteOkEXcdDIos88SojStWOifP23" target="_blank" rel="noopener noreferrer">',
73
-            '<a href="https://monosnap.com/file/WyxGJtev87TcDmdGBEZ2oi1xaBIQAm" target="_blank" rel="noopener noreferrer">',
74
-            '<a href="https://monosnap.com/image/DbCJNfEesWXeSNUs1wLIpGYODFw52m" target="_blank" rel="noopener noreferrer">'
75
-        ); ?>
65
+		printf(
66
+			esc_html__(
67
+				'To change your payment form settings in Authorize.net, %1$slog in to authorize.net%2$s, go to %3$sAccount then Payment Form%2$s, then %4$sForm Fields%2$s. It will look similar to %5$sthis%2$s. If you make a field required in Authorize.net, you should also make it required in Event Espresso. If it isn\'t required in Authorize.net, and you want to simplify the billing form in Event Espresso, you can exclude it from the Event Espresso Form too.',
68
+				'event_espresso'
69
+			),
70
+			'<a href="http://authorize.net" target="_blank" rel="noopener noreferrer">',
71
+			'</a>',
72
+			'<a href="https://monosnap.com/file/nebVteOkEXcdDIos88SojStWOifP23" target="_blank" rel="noopener noreferrer">',
73
+			'<a href="https://monosnap.com/file/WyxGJtev87TcDmdGBEZ2oi1xaBIQAm" target="_blank" rel="noopener noreferrer">',
74
+			'<a href="https://monosnap.com/image/DbCJNfEesWXeSNUs1wLIpGYODFw52m" target="_blank" rel="noopener noreferrer">'
75
+		); ?>
76 76
     </li>
77 77
     <li>
78 78
         <strong><?php esc_html_e('Button Image URL', 'event_espresso'); ?></strong><br/>
Please login to merge, or discard this patch.
caffeinated/payment_methods/Aim/EE_PMT_Aim.pm.php 1 patch
Indentation   +238 added lines, -238 removed lines patch added patch discarded remove patch
@@ -12,260 +12,260 @@
 block discarded – undo
12 12
 {
13 13
 
14 14
 
15
-    /**
16
-     * @param EE_Payment_Method $pm_instance
17
-     * @return EE_PMT_Aim
18
-     * @throws \EE_Error
19
-     */
20
-    public function __construct($pm_instance = null)
21
-    {
22
-        $this->_setup_properties();
23
-        parent::__construct($pm_instance);
24
-    }
15
+	/**
16
+	 * @param EE_Payment_Method $pm_instance
17
+	 * @return EE_PMT_Aim
18
+	 * @throws \EE_Error
19
+	 */
20
+	public function __construct($pm_instance = null)
21
+	{
22
+		$this->_setup_properties();
23
+		parent::__construct($pm_instance);
24
+	}
25 25
     
26
-    /**
27
-     * Sets up payment method type properties for this gateway, which is normally
28
-     * done in the constructor, but we want this to be easy for similar gateways to override
29
-     * while still calling the parent constructor.
30
-     * So children should override this method instead of __construct
31
-     */
32
-    protected function _setup_properties()
33
-    {
34
-        require_once($this->file_folder().'EEG_Aim.gateway.php');
35
-        $this->_gateway = new EEG_Aim();
36
-        $this->_pretty_name = __("Authorize.net AIM", 'event_espresso');
37
-        $this->_default_description = __('Please provide the following billing information.', 'event_espresso');
38
-        $this->_requires_https = true;
39
-    }
26
+	/**
27
+	 * Sets up payment method type properties for this gateway, which is normally
28
+	 * done in the constructor, but we want this to be easy for similar gateways to override
29
+	 * while still calling the parent constructor.
30
+	 * So children should override this method instead of __construct
31
+	 */
32
+	protected function _setup_properties()
33
+	{
34
+		require_once($this->file_folder().'EEG_Aim.gateway.php');
35
+		$this->_gateway = new EEG_Aim();
36
+		$this->_pretty_name = __("Authorize.net AIM", 'event_espresso');
37
+		$this->_default_description = __('Please provide the following billing information.', 'event_espresso');
38
+		$this->_requires_https = true;
39
+	}
40 40
 
41 41
 
42 42
 
43
-    /**
44
-     * Creates the billing form for this payment method type
45
-     *
46
-     * @param \EE_Transaction $transaction
47
-     * @return EE_Billing_Info_Form
48
-     * @throws \EE_Error
49
-     */
50
-    public function generate_new_billing_form(EE_Transaction $transaction = null)
51
-    {
52
-        $billing_form = new EE_Billing_Attendee_Info_Form($this->_pm_instance, array(
53
-            'name'=>'AIM_Form',
54
-            'subsections'=>array(
55
-                'credit_card'=>new EE_Credit_Card_Input(array(
56
-                    'required'=>true,
57
-                    'html_label_text' => __('Card Number', 'event_espresso')
58
-                )),
59
-                'exp_month'=>new EE_Credit_Card_Month_Input(true, array(
60
-                    'required'=>true,
61
-                    'html_label_text' => __('Expiry Month', 'event_espresso')
62
-                )),
63
-                'exp_year'=>new EE_Credit_Card_Year_Input(array(
64
-                    'required'=>true,
65
-                    'html_label_text' => __('Expiry Year', 'event_espresso')
66
-                )),
67
-                'cvv'=>new EE_CVV_Input(array(
68
-                    'required'=>true,
69
-                    'html_label_text' => __('CVV', 'event_espresso') )),
70
-            )
71
-        ));
72
-        $billing_form->add_subsections(array(
73
-            'company' => new EE_Text_Input(array(
74
-                'html_label_text' => __('Company', 'event_espresso')
75
-            ))
76
-        ), 'email', false);
77
-        $billing_form->add_subsections(
78
-            array(
79
-                    'fax' => new EE_Text_Input(array(
80
-                        'html_label_text' => __('Fax', 'event_espresso')
81
-                    ))
82
-                ),
83
-            'phone',
84
-            false
85
-        );
86
-        $settings_form = $this->settings_form();
87
-        if ($settings_form->get_input('excluded_billing_inputs') instanceof EE_Checkbox_Multi_Input) {
88
-                $billing_form->exclude($settings_form->get_input('excluded_billing_inputs')->normalized_value());
89
-        }
90
-        if ($settings_form->get_input('required_billing_inputs') instanceof EE_Checkbox_Multi_Input) {
91
-            $required_inputs = $settings_form->get_input('required_billing_inputs')->normalized_value();
92
-            // only change the requirement of inputs which are allowed to be changed
93
-            /** @var EE_Form_Input_Base[] $inputs_to_evaluate */
94
-            $inputs_to_evaluate = array_intersect_key(
95
-                $billing_form->inputs(),
96
-                $this->billing_input_names()
97
-            );
98
-            foreach ($inputs_to_evaluate as $input_name => $input) {
99
-                if (in_array($input_name, $required_inputs)) {
100
-                    $input->set_required(true);
101
-                } else {
102
-                    $input->set_required(false);
103
-                }
104
-            }
105
-        }
106
-        return $this->apply_billing_form_debug_settings($billing_form);
107
-    }
43
+	/**
44
+	 * Creates the billing form for this payment method type
45
+	 *
46
+	 * @param \EE_Transaction $transaction
47
+	 * @return EE_Billing_Info_Form
48
+	 * @throws \EE_Error
49
+	 */
50
+	public function generate_new_billing_form(EE_Transaction $transaction = null)
51
+	{
52
+		$billing_form = new EE_Billing_Attendee_Info_Form($this->_pm_instance, array(
53
+			'name'=>'AIM_Form',
54
+			'subsections'=>array(
55
+				'credit_card'=>new EE_Credit_Card_Input(array(
56
+					'required'=>true,
57
+					'html_label_text' => __('Card Number', 'event_espresso')
58
+				)),
59
+				'exp_month'=>new EE_Credit_Card_Month_Input(true, array(
60
+					'required'=>true,
61
+					'html_label_text' => __('Expiry Month', 'event_espresso')
62
+				)),
63
+				'exp_year'=>new EE_Credit_Card_Year_Input(array(
64
+					'required'=>true,
65
+					'html_label_text' => __('Expiry Year', 'event_espresso')
66
+				)),
67
+				'cvv'=>new EE_CVV_Input(array(
68
+					'required'=>true,
69
+					'html_label_text' => __('CVV', 'event_espresso') )),
70
+			)
71
+		));
72
+		$billing_form->add_subsections(array(
73
+			'company' => new EE_Text_Input(array(
74
+				'html_label_text' => __('Company', 'event_espresso')
75
+			))
76
+		), 'email', false);
77
+		$billing_form->add_subsections(
78
+			array(
79
+					'fax' => new EE_Text_Input(array(
80
+						'html_label_text' => __('Fax', 'event_espresso')
81
+					))
82
+				),
83
+			'phone',
84
+			false
85
+		);
86
+		$settings_form = $this->settings_form();
87
+		if ($settings_form->get_input('excluded_billing_inputs') instanceof EE_Checkbox_Multi_Input) {
88
+				$billing_form->exclude($settings_form->get_input('excluded_billing_inputs')->normalized_value());
89
+		}
90
+		if ($settings_form->get_input('required_billing_inputs') instanceof EE_Checkbox_Multi_Input) {
91
+			$required_inputs = $settings_form->get_input('required_billing_inputs')->normalized_value();
92
+			// only change the requirement of inputs which are allowed to be changed
93
+			/** @var EE_Form_Input_Base[] $inputs_to_evaluate */
94
+			$inputs_to_evaluate = array_intersect_key(
95
+				$billing_form->inputs(),
96
+				$this->billing_input_names()
97
+			);
98
+			foreach ($inputs_to_evaluate as $input_name => $input) {
99
+				if (in_array($input_name, $required_inputs)) {
100
+					$input->set_required(true);
101
+				} else {
102
+					$input->set_required(false);
103
+				}
104
+			}
105
+		}
106
+		return $this->apply_billing_form_debug_settings($billing_form);
107
+	}
108 108
 
109 109
 
110 110
 
111
-    /**
112
-     * apply_billing_form_debug_settings
113
-     * applies debug data to the form
114
-     *
115
-     * @param \EE_Billing_Info_Form $billing_form
116
-     * @return \EE_Billing_Info_Form
117
-     * @throws \EE_Error
118
-     */
119
-    public function apply_billing_form_debug_settings(EE_Billing_Info_Form $billing_form)
120
-    {
121
-        if ($this->_pm_instance->debug_mode()
122
-            || $this->_pm_instance->get_extra_meta('test_transactions', true, false)
123
-        ) {
124
-            $billing_form->get_input('credit_card')->set_default('4007000000027');
125
-            $billing_form->get_input('exp_year')->set_default('2020');
126
-            if ($billing_form->get_subsection('cvv') instanceof EE_Form_Input_Base) {
127
-                $billing_form->get_input('cvv')->set_default('123');
128
-            }
129
-            $billing_form->add_subsections(
130
-                array( 'fyi_about_autofill' => $billing_form->payment_fields_autofilled_notice_html() ),
131
-                'credit_card'
132
-            );
133
-            $billing_form->add_subsections(
134
-                array(
135
-                    'debug_content' => new EE_Form_Section_HTML_From_Template(
136
-                        __DIR__.'/templates/authorize_net_aim_debug_info.template.php'
137
-                    )
138
-                ),
139
-                'first_name'
140
-            );
141
-        }
142
-        return $billing_form;
143
-    }
111
+	/**
112
+	 * apply_billing_form_debug_settings
113
+	 * applies debug data to the form
114
+	 *
115
+	 * @param \EE_Billing_Info_Form $billing_form
116
+	 * @return \EE_Billing_Info_Form
117
+	 * @throws \EE_Error
118
+	 */
119
+	public function apply_billing_form_debug_settings(EE_Billing_Info_Form $billing_form)
120
+	{
121
+		if ($this->_pm_instance->debug_mode()
122
+			|| $this->_pm_instance->get_extra_meta('test_transactions', true, false)
123
+		) {
124
+			$billing_form->get_input('credit_card')->set_default('4007000000027');
125
+			$billing_form->get_input('exp_year')->set_default('2020');
126
+			if ($billing_form->get_subsection('cvv') instanceof EE_Form_Input_Base) {
127
+				$billing_form->get_input('cvv')->set_default('123');
128
+			}
129
+			$billing_form->add_subsections(
130
+				array( 'fyi_about_autofill' => $billing_form->payment_fields_autofilled_notice_html() ),
131
+				'credit_card'
132
+			);
133
+			$billing_form->add_subsections(
134
+				array(
135
+					'debug_content' => new EE_Form_Section_HTML_From_Template(
136
+						__DIR__.'/templates/authorize_net_aim_debug_info.template.php'
137
+					)
138
+				),
139
+				'first_name'
140
+			);
141
+		}
142
+		return $billing_form;
143
+	}
144 144
 
145 145
 
146 146
 
147
-    /**
148
-     * Gets the form for all the settings related to this payment method type
149
-     * @return EE_Payment_Method_Form
150
-     */
151
-    public function generate_new_settings_form()
152
-    {
153
-        $billing_input_names = $this->billing_input_names();
154
-        return new EE_Payment_Method_Form(
155
-            array(
156
-                'extra_meta_inputs'=>array(
157
-                    'login_id'=>new EE_Text_Input(
158
-                        array(
159
-                            'html_label_text'=>  sprintf(__("Authorize.net API Login ID %s", "event_espresso"), $this->get_help_tab_link()),
160
-                            'required' => true )
161
-                    ),
162
-                    'transaction_key'=>new EE_Text_Input(
163
-                        array(
164
-                            'html_label_text'=> sprintf(__("Authorize.net Transaction Key %s", "event_espresso"), $this->get_help_tab_link()),
165
-                            'required' => true )
166
-                    ),
167
-                    'test_transactions'=>new EE_Yes_No_Input(
168
-                        array(
169
-                            'html_label_text'=>  sprintf(__("Send test transactions? %s", 'event_espresso'), $this->get_help_tab_link()),
170
-                            'html_help_text'=>  __("Send test transactions, even to live server", 'event_espresso'),
171
-                            'default' => false,
172
-                            'required' => true
173
-                        )
174
-                    ),
175
-                    'excluded_billing_inputs' => new EE_Checkbox_Multi_Input(
176
-                        $billing_input_names,
177
-                        array(
178
-                        'html_label_text' => sprintf(__("Excluded Payment Form Fields %s", 'event_espresso'), $this->get_help_tab_link()),
179
-                        'default' => array(
180
-                            'company',
181
-                            'fax',
182
-                        )
183
-                        )
184
-                    ),
185
-                    'required_billing_inputs' => new EE_Checkbox_Multi_Input(
186
-                        $billing_input_names,
187
-                        array(
188
-                            'html_label_text' => sprintf(__("Required Payment Form Fields %s", 'event_espresso'), $this->get_help_tab_link()),
189
-                            'default' => array_diff(
190
-                                array_keys($billing_input_names),
191
-                                array( 'address2', 'phone', 'company', 'fax' )
192
-                            ),
193
-                            'html_help_text' => __('Note: if fields are excluded they cannot be required.', 'event_espresso')
194
-                        )
195
-                    ),
196
-                )
197
-            )
198
-        );
199
-    }
147
+	/**
148
+	 * Gets the form for all the settings related to this payment method type
149
+	 * @return EE_Payment_Method_Form
150
+	 */
151
+	public function generate_new_settings_form()
152
+	{
153
+		$billing_input_names = $this->billing_input_names();
154
+		return new EE_Payment_Method_Form(
155
+			array(
156
+				'extra_meta_inputs'=>array(
157
+					'login_id'=>new EE_Text_Input(
158
+						array(
159
+							'html_label_text'=>  sprintf(__("Authorize.net API Login ID %s", "event_espresso"), $this->get_help_tab_link()),
160
+							'required' => true )
161
+					),
162
+					'transaction_key'=>new EE_Text_Input(
163
+						array(
164
+							'html_label_text'=> sprintf(__("Authorize.net Transaction Key %s", "event_espresso"), $this->get_help_tab_link()),
165
+							'required' => true )
166
+					),
167
+					'test_transactions'=>new EE_Yes_No_Input(
168
+						array(
169
+							'html_label_text'=>  sprintf(__("Send test transactions? %s", 'event_espresso'), $this->get_help_tab_link()),
170
+							'html_help_text'=>  __("Send test transactions, even to live server", 'event_espresso'),
171
+							'default' => false,
172
+							'required' => true
173
+						)
174
+					),
175
+					'excluded_billing_inputs' => new EE_Checkbox_Multi_Input(
176
+						$billing_input_names,
177
+						array(
178
+						'html_label_text' => sprintf(__("Excluded Payment Form Fields %s", 'event_espresso'), $this->get_help_tab_link()),
179
+						'default' => array(
180
+							'company',
181
+							'fax',
182
+						)
183
+						)
184
+					),
185
+					'required_billing_inputs' => new EE_Checkbox_Multi_Input(
186
+						$billing_input_names,
187
+						array(
188
+							'html_label_text' => sprintf(__("Required Payment Form Fields %s", 'event_espresso'), $this->get_help_tab_link()),
189
+							'default' => array_diff(
190
+								array_keys($billing_input_names),
191
+								array( 'address2', 'phone', 'company', 'fax' )
192
+							),
193
+							'html_help_text' => __('Note: if fields are excluded they cannot be required.', 'event_espresso')
194
+						)
195
+					),
196
+				)
197
+			)
198
+		);
199
+	}
200 200
     
201
-    /**
202
-     * Returns an array where keys are the slugs for billing inputs, and values
203
-     * are their i18n names
204
-     * @return array
205
-     */
206
-    public function billing_input_names()
207
-    {
208
-        return array(
209
-            'first_name' => __('First Name', 'event_espresso'),
210
-            'last_name' => __('Last Name', 'event_espresso'),
211
-            'email' => __('Email', 'event_espresso'),
212
-            'company' => __('Company', 'event_espresso'),
213
-            'address' => __('Address', 'event_espresso'),
214
-            'address2' => __('Address2', 'event_espresso'),
215
-            'city' => __('City', 'event_espresso'),
216
-            'state' => __('State', 'event_espresso'),
217
-            'country' => __('Country', 'event_espresso'),
218
-            'zip' =>  __('Zip', 'event_espresso'),
219
-            'phone' => __('Phone', 'event_espresso'),
220
-            'fax' => __('Fax', 'event_espresso'),
221
-            'cvv' => __('CVV', 'event_espresso')
222
-        );
223
-    }
201
+	/**
202
+	 * Returns an array where keys are the slugs for billing inputs, and values
203
+	 * are their i18n names
204
+	 * @return array
205
+	 */
206
+	public function billing_input_names()
207
+	{
208
+		return array(
209
+			'first_name' => __('First Name', 'event_espresso'),
210
+			'last_name' => __('Last Name', 'event_espresso'),
211
+			'email' => __('Email', 'event_espresso'),
212
+			'company' => __('Company', 'event_espresso'),
213
+			'address' => __('Address', 'event_espresso'),
214
+			'address2' => __('Address2', 'event_espresso'),
215
+			'city' => __('City', 'event_espresso'),
216
+			'state' => __('State', 'event_espresso'),
217
+			'country' => __('Country', 'event_espresso'),
218
+			'zip' =>  __('Zip', 'event_espresso'),
219
+			'phone' => __('Phone', 'event_espresso'),
220
+			'fax' => __('Fax', 'event_espresso'),
221
+			'cvv' => __('CVV', 'event_espresso')
222
+		);
223
+	}
224 224
     
225
-    /**
226
-     * Overrides parent so we always have all billing inputs in the returned array,
227
-     * not just the ones included at the time. This helps simplify the gateway code
228
-     *
229
-     * @param EE_Billing_Info_Form $billing_form
230
-     * @return array
231
-     */
232
-    protected function _get_billing_values_from_form($billing_form)
233
-    {
234
-        $all_billing_values_empty = array();
235
-        foreach (array_keys($this->billing_input_names()) as $input_name) {
236
-            $all_billing_values_empty[ $input_name ] = '';
237
-        }
238
-        return array_merge(
239
-            $all_billing_values_empty,
240
-            parent::_get_billing_values_from_form($billing_form)
241
-        );
242
-    }
225
+	/**
226
+	 * Overrides parent so we always have all billing inputs in the returned array,
227
+	 * not just the ones included at the time. This helps simplify the gateway code
228
+	 *
229
+	 * @param EE_Billing_Info_Form $billing_form
230
+	 * @return array
231
+	 */
232
+	protected function _get_billing_values_from_form($billing_form)
233
+	{
234
+		$all_billing_values_empty = array();
235
+		foreach (array_keys($this->billing_input_names()) as $input_name) {
236
+			$all_billing_values_empty[ $input_name ] = '';
237
+		}
238
+		return array_merge(
239
+			$all_billing_values_empty,
240
+			parent::_get_billing_values_from_form($billing_form)
241
+		);
242
+	}
243 243
 
244 244
 
245 245
 
246
-    /**
247
-     * Adds the help tab
248
-     * @see EE_PMT_Base::help_tabs_config()
249
-     * @return array
250
-     */
251
-    public function help_tabs_config()
252
-    {
253
-        return array(
254
-            $this->get_help_tab_name() => array(
255
-                'title' => __('Authorize.net AIM Settings', 'event_espresso'),
256
-                'filename' => 'payment_methods_overview_aim'
257
-            ),
258
-        );
259
-    }
246
+	/**
247
+	 * Adds the help tab
248
+	 * @see EE_PMT_Base::help_tabs_config()
249
+	 * @return array
250
+	 */
251
+	public function help_tabs_config()
252
+	{
253
+		return array(
254
+			$this->get_help_tab_name() => array(
255
+				'title' => __('Authorize.net AIM Settings', 'event_espresso'),
256
+				'filename' => 'payment_methods_overview_aim'
257
+			),
258
+		);
259
+	}
260 260
 
261 261
 
262 262
 
263
-    /**
264
-     * Gets a list of instructions and/or information regarding how the payment is to be completed
265
-     * @return string
266
-     */
267
-    public function payment_information()
268
-    {
269
-        // TODO: Implement payment_information() method.
270
-    }
263
+	/**
264
+	 * Gets a list of instructions and/or information regarding how the payment is to be completed
265
+	 * @return string
266
+	 */
267
+	public function payment_information()
268
+	{
269
+		// TODO: Implement payment_information() method.
270
+	}
271 271
 }
Please login to merge, or discard this patch.
core/EE_Error.core.php 1 patch
Indentation   +1126 added lines, -1126 removed lines patch added patch discarded remove patch
@@ -10,8 +10,8 @@  discard block
 block discarded – undo
10 10
 // if you're a dev and want to receive all errors via email
11 11
 // add this to your wp-config.php: define( 'EE_ERROR_EMAILS', TRUE );
12 12
 if (defined('WP_DEBUG') && WP_DEBUG === true && defined('EE_ERROR_EMAILS') && EE_ERROR_EMAILS === true) {
13
-    set_error_handler(array('EE_Error', 'error_handler'));
14
-    register_shutdown_function(array('EE_Error', 'fatal_error_handler'));
13
+	set_error_handler(array('EE_Error', 'error_handler'));
14
+	register_shutdown_function(array('EE_Error', 'fatal_error_handler'));
15 15
 }
16 16
 
17 17
 
@@ -25,251 +25,251 @@  discard block
 block discarded – undo
25 25
 class EE_Error extends Exception
26 26
 {
27 27
 
28
-    const OPTIONS_KEY_NOTICES = 'ee_notices';
29
-
30
-
31
-    /**
32
-     * name of the file to log exceptions to
33
-     *
34
-     * @var string
35
-     */
36
-    private static $_exception_log_file = 'espresso_error_log.txt';
37
-
38
-    /**
39
-     *    stores details for all exception
40
-     *
41
-     * @var array
42
-     */
43
-    private static $_all_exceptions = array();
44
-
45
-    /**
46
-     *    tracks number of errors
47
-     *
48
-     * @var int
49
-     */
50
-    private static $_error_count = 0;
51
-
52
-    /**
53
-     * @var array $_espresso_notices
54
-     */
55
-    private static $_espresso_notices = array('success' => false, 'errors' => false, 'attention' => false);
56
-
57
-
58
-    /**
59
-     * @override default exception handling
60
-     * @param string         $message
61
-     * @param int            $code
62
-     * @param Exception|null $previous
63
-     */
64
-    public function __construct($message, $code = 0, Exception $previous = null)
65
-    {
66
-        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
67
-            parent::__construct($message, $code);
68
-        } else {
69
-            parent::__construct($message, $code, $previous);
70
-        }
71
-    }
72
-
73
-
74
-    /**
75
-     *    error_handler
76
-     *
77
-     * @param $code
78
-     * @param $message
79
-     * @param $file
80
-     * @param $line
81
-     * @return void
82
-     */
83
-    public static function error_handler($code, $message, $file, $line)
84
-    {
85
-        $type = EE_Error::error_type($code);
86
-        $site = site_url();
87
-        switch ($site) {
88
-            case 'http://ee4.eventespresso.com/':
89
-            case 'http://ee4decaf.eventespresso.com/':
90
-            case 'http://ee4hf.eventespresso.com/':
91
-            case 'http://ee4a.eventespresso.com/':
92
-            case 'http://ee4ad.eventespresso.com/':
93
-            case 'http://ee4b.eventespresso.com/':
94
-            case 'http://ee4bd.eventespresso.com/':
95
-            case 'http://ee4d.eventespresso.com/':
96
-            case 'http://ee4dd.eventespresso.com/':
97
-                $to = '[email protected]';
98
-                break;
99
-            default:
100
-                $to = get_option('admin_email');
101
-        }
102
-        $subject = $type . ' ' . $message . ' in ' . EVENT_ESPRESSO_VERSION . ' on ' . site_url();
103
-        $msg = EE_Error::_format_error($type, $message, $file, $line);
104
-        if (function_exists('wp_mail')) {
105
-            add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type'));
106
-            wp_mail($to, $subject, $msg);
107
-        }
108
-        echo '<div id="message" class="espresso-notices error"><p>';
109
-        echo $type . ': ' . $message . '<br />' . $file . ' line ' . $line;
110
-        echo '<br /></p></div>';
111
-    }
112
-
113
-
114
-    /**
115
-     * error_type
116
-     * http://www.php.net/manual/en/errorfunc.constants.php#109430
117
-     *
118
-     * @param $code
119
-     * @return string
120
-     */
121
-    public static function error_type($code)
122
-    {
123
-        switch ($code) {
124
-            case E_ERROR: // 1 //
125
-                return 'E_ERROR';
126
-            case E_WARNING: // 2 //
127
-                return 'E_WARNING';
128
-            case E_PARSE: // 4 //
129
-                return 'E_PARSE';
130
-            case E_NOTICE: // 8 //
131
-                return 'E_NOTICE';
132
-            case E_CORE_ERROR: // 16 //
133
-                return 'E_CORE_ERROR';
134
-            case E_CORE_WARNING: // 32 //
135
-                return 'E_CORE_WARNING';
136
-            case E_COMPILE_ERROR: // 64 //
137
-                return 'E_COMPILE_ERROR';
138
-            case E_COMPILE_WARNING: // 128 //
139
-                return 'E_COMPILE_WARNING';
140
-            case E_USER_ERROR: // 256 //
141
-                return 'E_USER_ERROR';
142
-            case E_USER_WARNING: // 512 //
143
-                return 'E_USER_WARNING';
144
-            case E_USER_NOTICE: // 1024 //
145
-                return 'E_USER_NOTICE';
146
-            case E_STRICT: // 2048 //
147
-                return 'E_STRICT';
148
-            case E_RECOVERABLE_ERROR: // 4096 //
149
-                return 'E_RECOVERABLE_ERROR';
150
-            case E_DEPRECATED: // 8192 //
151
-                return 'E_DEPRECATED';
152
-            case E_USER_DEPRECATED: // 16384 //
153
-                return 'E_USER_DEPRECATED';
154
-            case E_ALL: // 16384 //
155
-                return 'E_ALL';
156
-        }
157
-        return '';
158
-    }
159
-
160
-
161
-    /**
162
-     *    fatal_error_handler
163
-     *
164
-     * @return void
165
-     */
166
-    public static function fatal_error_handler()
167
-    {
168
-        $last_error = error_get_last();
169
-        if ($last_error['type'] === E_ERROR) {
170
-            EE_Error::error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
171
-        }
172
-    }
173
-
174
-
175
-    /**
176
-     * _format_error
177
-     *
178
-     * @param $code
179
-     * @param $message
180
-     * @param $file
181
-     * @param $line
182
-     * @return string
183
-     */
184
-    private static function _format_error($code, $message, $file, $line)
185
-    {
186
-        $html = "<table cellpadding='5'><thead bgcolor='#f8f8f8'><th>Item</th><th align='left'>Details</th></thead><tbody>";
187
-        $html .= "<tr valign='top'><td><b>Code</b></td><td>$code</td></tr>";
188
-        $html .= "<tr valign='top'><td><b>Error</b></td><td>$message</td></tr>";
189
-        $html .= "<tr valign='top'><td><b>File</b></td><td>$file</td></tr>";
190
-        $html .= "<tr valign='top'><td><b>Line</b></td><td>$line</td></tr>";
191
-        $html .= '</tbody></table>';
192
-        return $html;
193
-    }
194
-
195
-
196
-    /**
197
-     * set_content_type
198
-     *
199
-     * @param $content_type
200
-     * @return string
201
-     */
202
-    public static function set_content_type($content_type)
203
-    {
204
-        return 'text/html';
205
-    }
206
-
207
-
208
-    /**
209
-     * @return void
210
-     * @throws EE_Error
211
-     * @throws ReflectionException
212
-     */
213
-    public function get_error()
214
-    {
215
-        if (apply_filters('FHEE__EE_Error__get_error__show_normal_exceptions', false)) {
216
-            throw $this;
217
-        }
218
-        // get separate user and developer messages if they exist
219
-        $msg = explode('||', $this->getMessage());
220
-        $user_msg = $msg[0];
221
-        $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0];
222
-        $msg = WP_DEBUG ? $dev_msg : $user_msg;
223
-        // add details to _all_exceptions array
224
-        $x_time = time();
225
-        self::$_all_exceptions[ $x_time ]['name'] = get_class($this);
226
-        self::$_all_exceptions[ $x_time ]['file'] = $this->getFile();
227
-        self::$_all_exceptions[ $x_time ]['line'] = $this->getLine();
228
-        self::$_all_exceptions[ $x_time ]['msg'] = $msg;
229
-        self::$_all_exceptions[ $x_time ]['code'] = $this->getCode();
230
-        self::$_all_exceptions[ $x_time ]['trace'] = $this->getTrace();
231
-        self::$_all_exceptions[ $x_time ]['string'] = $this->getTraceAsString();
232
-        self::$_error_count++;
233
-        // add_action( 'shutdown', array( $this, 'display_errors' ));
234
-        $this->display_errors();
235
-    }
236
-
237
-
238
-    /**
239
-     * @param bool   $check_stored
240
-     * @param string $type_to_check
241
-     * @return bool
242
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
243
-     * @throws \InvalidArgumentException
244
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
245
-     * @throws InvalidInterfaceException
246
-     */
247
-    public static function has_error($check_stored = false, $type_to_check = 'errors')
248
-    {
249
-        $has_error = isset(self::$_espresso_notices[ $type_to_check ])
250
-                     && ! empty(self::$_espresso_notices[ $type_to_check ])
251
-            ? true
252
-            : false;
253
-        if ($check_stored && ! $has_error) {
254
-            $notices = EE_Error::getStoredNotices();
255
-            foreach ($notices as $type => $notice) {
256
-                if ($type === $type_to_check && $notice) {
257
-                    return true;
258
-                }
259
-            }
260
-        }
261
-        return $has_error;
262
-    }
263
-
264
-
265
-    /**
266
-     * @echo string
267
-     * @throws \ReflectionException
268
-     */
269
-    public function display_errors()
270
-    {
271
-        $trace_details = '';
272
-        $output = '
28
+	const OPTIONS_KEY_NOTICES = 'ee_notices';
29
+
30
+
31
+	/**
32
+	 * name of the file to log exceptions to
33
+	 *
34
+	 * @var string
35
+	 */
36
+	private static $_exception_log_file = 'espresso_error_log.txt';
37
+
38
+	/**
39
+	 *    stores details for all exception
40
+	 *
41
+	 * @var array
42
+	 */
43
+	private static $_all_exceptions = array();
44
+
45
+	/**
46
+	 *    tracks number of errors
47
+	 *
48
+	 * @var int
49
+	 */
50
+	private static $_error_count = 0;
51
+
52
+	/**
53
+	 * @var array $_espresso_notices
54
+	 */
55
+	private static $_espresso_notices = array('success' => false, 'errors' => false, 'attention' => false);
56
+
57
+
58
+	/**
59
+	 * @override default exception handling
60
+	 * @param string         $message
61
+	 * @param int            $code
62
+	 * @param Exception|null $previous
63
+	 */
64
+	public function __construct($message, $code = 0, Exception $previous = null)
65
+	{
66
+		if (version_compare(PHP_VERSION, '5.3.0', '<')) {
67
+			parent::__construct($message, $code);
68
+		} else {
69
+			parent::__construct($message, $code, $previous);
70
+		}
71
+	}
72
+
73
+
74
+	/**
75
+	 *    error_handler
76
+	 *
77
+	 * @param $code
78
+	 * @param $message
79
+	 * @param $file
80
+	 * @param $line
81
+	 * @return void
82
+	 */
83
+	public static function error_handler($code, $message, $file, $line)
84
+	{
85
+		$type = EE_Error::error_type($code);
86
+		$site = site_url();
87
+		switch ($site) {
88
+			case 'http://ee4.eventespresso.com/':
89
+			case 'http://ee4decaf.eventespresso.com/':
90
+			case 'http://ee4hf.eventespresso.com/':
91
+			case 'http://ee4a.eventespresso.com/':
92
+			case 'http://ee4ad.eventespresso.com/':
93
+			case 'http://ee4b.eventespresso.com/':
94
+			case 'http://ee4bd.eventespresso.com/':
95
+			case 'http://ee4d.eventespresso.com/':
96
+			case 'http://ee4dd.eventespresso.com/':
97
+				$to = '[email protected]';
98
+				break;
99
+			default:
100
+				$to = get_option('admin_email');
101
+		}
102
+		$subject = $type . ' ' . $message . ' in ' . EVENT_ESPRESSO_VERSION . ' on ' . site_url();
103
+		$msg = EE_Error::_format_error($type, $message, $file, $line);
104
+		if (function_exists('wp_mail')) {
105
+			add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type'));
106
+			wp_mail($to, $subject, $msg);
107
+		}
108
+		echo '<div id="message" class="espresso-notices error"><p>';
109
+		echo $type . ': ' . $message . '<br />' . $file . ' line ' . $line;
110
+		echo '<br /></p></div>';
111
+	}
112
+
113
+
114
+	/**
115
+	 * error_type
116
+	 * http://www.php.net/manual/en/errorfunc.constants.php#109430
117
+	 *
118
+	 * @param $code
119
+	 * @return string
120
+	 */
121
+	public static function error_type($code)
122
+	{
123
+		switch ($code) {
124
+			case E_ERROR: // 1 //
125
+				return 'E_ERROR';
126
+			case E_WARNING: // 2 //
127
+				return 'E_WARNING';
128
+			case E_PARSE: // 4 //
129
+				return 'E_PARSE';
130
+			case E_NOTICE: // 8 //
131
+				return 'E_NOTICE';
132
+			case E_CORE_ERROR: // 16 //
133
+				return 'E_CORE_ERROR';
134
+			case E_CORE_WARNING: // 32 //
135
+				return 'E_CORE_WARNING';
136
+			case E_COMPILE_ERROR: // 64 //
137
+				return 'E_COMPILE_ERROR';
138
+			case E_COMPILE_WARNING: // 128 //
139
+				return 'E_COMPILE_WARNING';
140
+			case E_USER_ERROR: // 256 //
141
+				return 'E_USER_ERROR';
142
+			case E_USER_WARNING: // 512 //
143
+				return 'E_USER_WARNING';
144
+			case E_USER_NOTICE: // 1024 //
145
+				return 'E_USER_NOTICE';
146
+			case E_STRICT: // 2048 //
147
+				return 'E_STRICT';
148
+			case E_RECOVERABLE_ERROR: // 4096 //
149
+				return 'E_RECOVERABLE_ERROR';
150
+			case E_DEPRECATED: // 8192 //
151
+				return 'E_DEPRECATED';
152
+			case E_USER_DEPRECATED: // 16384 //
153
+				return 'E_USER_DEPRECATED';
154
+			case E_ALL: // 16384 //
155
+				return 'E_ALL';
156
+		}
157
+		return '';
158
+	}
159
+
160
+
161
+	/**
162
+	 *    fatal_error_handler
163
+	 *
164
+	 * @return void
165
+	 */
166
+	public static function fatal_error_handler()
167
+	{
168
+		$last_error = error_get_last();
169
+		if ($last_error['type'] === E_ERROR) {
170
+			EE_Error::error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
171
+		}
172
+	}
173
+
174
+
175
+	/**
176
+	 * _format_error
177
+	 *
178
+	 * @param $code
179
+	 * @param $message
180
+	 * @param $file
181
+	 * @param $line
182
+	 * @return string
183
+	 */
184
+	private static function _format_error($code, $message, $file, $line)
185
+	{
186
+		$html = "<table cellpadding='5'><thead bgcolor='#f8f8f8'><th>Item</th><th align='left'>Details</th></thead><tbody>";
187
+		$html .= "<tr valign='top'><td><b>Code</b></td><td>$code</td></tr>";
188
+		$html .= "<tr valign='top'><td><b>Error</b></td><td>$message</td></tr>";
189
+		$html .= "<tr valign='top'><td><b>File</b></td><td>$file</td></tr>";
190
+		$html .= "<tr valign='top'><td><b>Line</b></td><td>$line</td></tr>";
191
+		$html .= '</tbody></table>';
192
+		return $html;
193
+	}
194
+
195
+
196
+	/**
197
+	 * set_content_type
198
+	 *
199
+	 * @param $content_type
200
+	 * @return string
201
+	 */
202
+	public static function set_content_type($content_type)
203
+	{
204
+		return 'text/html';
205
+	}
206
+
207
+
208
+	/**
209
+	 * @return void
210
+	 * @throws EE_Error
211
+	 * @throws ReflectionException
212
+	 */
213
+	public function get_error()
214
+	{
215
+		if (apply_filters('FHEE__EE_Error__get_error__show_normal_exceptions', false)) {
216
+			throw $this;
217
+		}
218
+		// get separate user and developer messages if they exist
219
+		$msg = explode('||', $this->getMessage());
220
+		$user_msg = $msg[0];
221
+		$dev_msg = isset($msg[1]) ? $msg[1] : $msg[0];
222
+		$msg = WP_DEBUG ? $dev_msg : $user_msg;
223
+		// add details to _all_exceptions array
224
+		$x_time = time();
225
+		self::$_all_exceptions[ $x_time ]['name'] = get_class($this);
226
+		self::$_all_exceptions[ $x_time ]['file'] = $this->getFile();
227
+		self::$_all_exceptions[ $x_time ]['line'] = $this->getLine();
228
+		self::$_all_exceptions[ $x_time ]['msg'] = $msg;
229
+		self::$_all_exceptions[ $x_time ]['code'] = $this->getCode();
230
+		self::$_all_exceptions[ $x_time ]['trace'] = $this->getTrace();
231
+		self::$_all_exceptions[ $x_time ]['string'] = $this->getTraceAsString();
232
+		self::$_error_count++;
233
+		// add_action( 'shutdown', array( $this, 'display_errors' ));
234
+		$this->display_errors();
235
+	}
236
+
237
+
238
+	/**
239
+	 * @param bool   $check_stored
240
+	 * @param string $type_to_check
241
+	 * @return bool
242
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
243
+	 * @throws \InvalidArgumentException
244
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
245
+	 * @throws InvalidInterfaceException
246
+	 */
247
+	public static function has_error($check_stored = false, $type_to_check = 'errors')
248
+	{
249
+		$has_error = isset(self::$_espresso_notices[ $type_to_check ])
250
+					 && ! empty(self::$_espresso_notices[ $type_to_check ])
251
+			? true
252
+			: false;
253
+		if ($check_stored && ! $has_error) {
254
+			$notices = EE_Error::getStoredNotices();
255
+			foreach ($notices as $type => $notice) {
256
+				if ($type === $type_to_check && $notice) {
257
+					return true;
258
+				}
259
+			}
260
+		}
261
+		return $has_error;
262
+	}
263
+
264
+
265
+	/**
266
+	 * @echo string
267
+	 * @throws \ReflectionException
268
+	 */
269
+	public function display_errors()
270
+	{
271
+		$trace_details = '';
272
+		$output = '
273 273
 <style type="text/css">
274 274
 	#ee-error-message {
275 275
 		max-width:90% !important;
@@ -325,21 +325,21 @@  discard block
 block discarded – undo
325 325
 	}
326 326
 </style>
327 327
 <div id="ee-error-message" class="error">';
328
-        if (! WP_DEBUG) {
329
-            $output .= '
328
+		if (! WP_DEBUG) {
329
+			$output .= '
330 330
 	<p>';
331
-        }
332
-        // cycle thru errors
333
-        foreach (self::$_all_exceptions as $time => $ex) {
334
-            $error_code = '';
335
-            // process trace info
336
-            if (empty($ex['trace'])) {
337
-                $trace_details .= __(
338
-                    'Sorry, but no trace information was available for this exception.',
339
-                    'event_espresso'
340
-                );
341
-            } else {
342
-                $trace_details .= '
331
+		}
332
+		// cycle thru errors
333
+		foreach (self::$_all_exceptions as $time => $ex) {
334
+			$error_code = '';
335
+			// process trace info
336
+			if (empty($ex['trace'])) {
337
+				$trace_details .= __(
338
+					'Sorry, but no trace information was available for this exception.',
339
+					'event_espresso'
340
+				);
341
+			} else {
342
+				$trace_details .= '
343 343
 			<div id="ee-trace-details">
344 344
 			<table width="100%" border="0" cellpadding="5" cellspacing="0">
345 345
 				<tr>
@@ -349,43 +349,43 @@  discard block
 block discarded – undo
349 349
 					<th scope="col" align="left">Class</th>
350 350
 					<th scope="col" align="left">Method( arguments )</th>
351 351
 				</tr>';
352
-                $last_on_stack = count($ex['trace']) - 1;
353
-                // reverse array so that stack is in proper chronological order
354
-                $sorted_trace = array_reverse($ex['trace']);
355
-                foreach ($sorted_trace as $nmbr => $trace) {
356
-                    $file = isset($trace['file']) ? $trace['file'] : '';
357
-                    $class = isset($trace['class']) ? $trace['class'] : '';
358
-                    $type = isset($trace['type']) ? $trace['type'] : '';
359
-                    $function = isset($trace['function']) ? $trace['function'] : '';
360
-                    $args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : '';
361
-                    $line = isset($trace['line']) ? $trace['line'] : '';
362
-                    $zebra = ($nmbr % 2) ? ' odd' : '';
363
-                    if (empty($file) && ! empty($class)) {
364
-                        $a = new ReflectionClass($class);
365
-                        $file = $a->getFileName();
366
-                        if (empty($line) && ! empty($function)) {
367
-                            try {
368
-                                // if $function is a closure, this throws an exception
369
-                                $b = new ReflectionMethod($class, $function);
370
-                                $line = $b->getStartLine();
371
-                            } catch (Exception $closure_exception) {
372
-                                $line = 'unknown';
373
-                            }
374
-                        }
375
-                    }
376
-                    if ($nmbr === $last_on_stack) {
377
-                        $file = $ex['file'] !== '' ? $ex['file'] : $file;
378
-                        $line = $ex['line'] !== '' ? $ex['line'] : $line;
379
-                        $error_code = self::generate_error_code($file, $trace['function'], $line);
380
-                    }
381
-                    $nmbr_dsply = ! empty($nmbr) ? $nmbr : '&nbsp;';
382
-                    $line_dsply = ! empty($line) ? $line : '&nbsp;';
383
-                    $file_dsply = ! empty($file) ? $file : '&nbsp;';
384
-                    $class_dsply = ! empty($class) ? $class : '&nbsp;';
385
-                    $type_dsply = ! empty($type) ? $type : '&nbsp;';
386
-                    $function_dsply = ! empty($function) ? $function : '&nbsp;';
387
-                    $args_dsply = ! empty($args) ? '( ' . $args . ' )' : '';
388
-                    $trace_details .= '
352
+				$last_on_stack = count($ex['trace']) - 1;
353
+				// reverse array so that stack is in proper chronological order
354
+				$sorted_trace = array_reverse($ex['trace']);
355
+				foreach ($sorted_trace as $nmbr => $trace) {
356
+					$file = isset($trace['file']) ? $trace['file'] : '';
357
+					$class = isset($trace['class']) ? $trace['class'] : '';
358
+					$type = isset($trace['type']) ? $trace['type'] : '';
359
+					$function = isset($trace['function']) ? $trace['function'] : '';
360
+					$args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : '';
361
+					$line = isset($trace['line']) ? $trace['line'] : '';
362
+					$zebra = ($nmbr % 2) ? ' odd' : '';
363
+					if (empty($file) && ! empty($class)) {
364
+						$a = new ReflectionClass($class);
365
+						$file = $a->getFileName();
366
+						if (empty($line) && ! empty($function)) {
367
+							try {
368
+								// if $function is a closure, this throws an exception
369
+								$b = new ReflectionMethod($class, $function);
370
+								$line = $b->getStartLine();
371
+							} catch (Exception $closure_exception) {
372
+								$line = 'unknown';
373
+							}
374
+						}
375
+					}
376
+					if ($nmbr === $last_on_stack) {
377
+						$file = $ex['file'] !== '' ? $ex['file'] : $file;
378
+						$line = $ex['line'] !== '' ? $ex['line'] : $line;
379
+						$error_code = self::generate_error_code($file, $trace['function'], $line);
380
+					}
381
+					$nmbr_dsply = ! empty($nmbr) ? $nmbr : '&nbsp;';
382
+					$line_dsply = ! empty($line) ? $line : '&nbsp;';
383
+					$file_dsply = ! empty($file) ? $file : '&nbsp;';
384
+					$class_dsply = ! empty($class) ? $class : '&nbsp;';
385
+					$type_dsply = ! empty($type) ? $type : '&nbsp;';
386
+					$function_dsply = ! empty($function) ? $function : '&nbsp;';
387
+					$args_dsply = ! empty($args) ? '( ' . $args . ' )' : '';
388
+					$trace_details .= '
389 389
 					<tr>
390 390
 						<td align="right" class="' . $zebra . '">' . $nmbr_dsply . '</td>
391 391
 						<td align="right" class="' . $zebra . '">' . $line_dsply . '</td>
@@ -393,626 +393,626 @@  discard block
 block discarded – undo
393 393
 						<td align="left" class="' . $zebra . '">' . $class_dsply . '</td>
394 394
 						<td align="left" class="' . $zebra . '">' . $type_dsply . $function_dsply . $args_dsply . '</td>
395 395
 					</tr>';
396
-                }
397
-                $trace_details .= '
396
+				}
397
+				$trace_details .= '
398 398
 			 </table>
399 399
 			</div>';
400
-            }
401
-            $ex['code'] = $ex['code'] ? $ex['code'] : $error_code;
402
-            // add generic non-identifying messages for non-privileged users
403
-            if (! WP_DEBUG) {
404
-                $output .= '<span class="ee-error-user-msg-spn">'
405
-                           . trim($ex['msg'])
406
-                           . '</span> &nbsp; <sup>'
407
-                           . $ex['code']
408
-                           . '</sup><br />';
409
-            } else {
410
-                // or helpful developer messages if debugging is on
411
-                $output .= '
400
+			}
401
+			$ex['code'] = $ex['code'] ? $ex['code'] : $error_code;
402
+			// add generic non-identifying messages for non-privileged users
403
+			if (! WP_DEBUG) {
404
+				$output .= '<span class="ee-error-user-msg-spn">'
405
+						   . trim($ex['msg'])
406
+						   . '</span> &nbsp; <sup>'
407
+						   . $ex['code']
408
+						   . '</sup><br />';
409
+			} else {
410
+				// or helpful developer messages if debugging is on
411
+				$output .= '
412 412
 		<div class="ee-error-dev-msg-dv">
413 413
 			<p class="ee-error-dev-msg-pg">
414 414
 				<strong class="ee-error-dev-msg-str">An '
415
-                           . $ex['name']
416
-                           . ' exception was thrown!</strong>  &nbsp; <span>code: '
417
-                           . $ex['code']
418
-                           . '</span><br />
415
+						   . $ex['name']
416
+						   . ' exception was thrown!</strong>  &nbsp; <span>code: '
417
+						   . $ex['code']
418
+						   . '</span><br />
419 419
 				<span class="big-text">"'
420
-                           . trim($ex['msg'])
421
-                           . '"</span><br/>
420
+						   . trim($ex['msg'])
421
+						   . '"</span><br/>
422 422
 				<a id="display-ee-error-trace-'
423
-                           . self::$_error_count
424
-                           . $time
425
-                           . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-'
426
-                           . self::$_error_count
427
-                           . $time
428
-                           . '">
423
+						   . self::$_error_count
424
+						   . $time
425
+						   . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-'
426
+						   . self::$_error_count
427
+						   . $time
428
+						   . '">
429 429
 					'
430
-                           . __('click to view backtrace and class/method details', 'event_espresso')
431
-                           . '
430
+						   . __('click to view backtrace and class/method details', 'event_espresso')
431
+						   . '
432 432
 				</a><br />
433 433
 				<span class="small-text lt-grey-text">'
434
-                           . $ex['file']
435
-                           . ' &nbsp; ( line no: '
436
-                           . $ex['line']
437
-                           . ' )</span>
434
+						   . $ex['file']
435
+						   . ' &nbsp; ( line no: '
436
+						   . $ex['line']
437
+						   . ' )</span>
438 438
 			</p>
439 439
 			<div id="ee-error-trace-'
440
-                           . self::$_error_count
441
-                           . $time
442
-                           . '-dv" class="ee-error-trace-dv" style="display: none;">
440
+						   . self::$_error_count
441
+						   . $time
442
+						   . '-dv" class="ee-error-trace-dv" style="display: none;">
443 443
 				'
444
-                           . $trace_details;
445
-                if (! empty($class)) {
446
-                    $output .= '
444
+						   . $trace_details;
445
+				if (! empty($class)) {
446
+					$output .= '
447 447
 				<div style="padding:3px; margin:0 0 1em; border:1px solid #666; background:#fff; border-radius:3px;">
448 448
 					<div style="padding:1em 2em; border:1px solid #666; background:#f9f9f9;">
449 449
 						<h3>Class Details</h3>';
450
-                    $a = new ReflectionClass($class);
451
-                    $output .= '
450
+					$a = new ReflectionClass($class);
451
+					$output .= '
452 452
 						<pre>' . $a . '</pre>
453 453
 					</div>
454 454
 				</div>';
455
-                }
456
-                $output .= '
455
+				}
456
+				$output .= '
457 457
 			</div>
458 458
 		</div>
459 459
 		<br />';
460
-            }
461
-            $this->write_to_error_log($time, $ex);
462
-        }
463
-        // remove last linebreak
464
-        $output = substr($output, 0, -6);
465
-        if (! WP_DEBUG) {
466
-            $output .= '
460
+			}
461
+			$this->write_to_error_log($time, $ex);
462
+		}
463
+		// remove last linebreak
464
+		$output = substr($output, 0, -6);
465
+		if (! WP_DEBUG) {
466
+			$output .= '
467 467
 	</p>';
468
-        }
469
-        $output .= '
468
+		}
469
+		$output .= '
470 470
 </div>';
471
-        $output .= self::_print_scripts(true);
472
-        if (defined('DOING_AJAX')) {
473
-            echo wp_json_encode(array('error' => $output));
474
-            exit();
475
-        }
476
-        echo $output;
477
-        die();
478
-    }
479
-
480
-
481
-    /**
482
-     *    generate string from exception trace args
483
-     *
484
-     * @param array $arguments
485
-     * @param bool  $array
486
-     * @return string
487
-     */
488
-    private function _convert_args_to_string($arguments = array(), $array = false)
489
-    {
490
-        $arg_string = '';
491
-        if (! empty($arguments)) {
492
-            $args = array();
493
-            foreach ($arguments as $arg) {
494
-                if (! empty($arg)) {
495
-                    if (is_string($arg)) {
496
-                        $args[] = " '" . $arg . "'";
497
-                    } elseif (is_array($arg)) {
498
-                        $args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true);
499
-                    } elseif ($arg === null) {
500
-                        $args[] = ' NULL';
501
-                    } elseif (is_bool($arg)) {
502
-                        $args[] = ($arg) ? ' TRUE' : ' FALSE';
503
-                    } elseif (is_object($arg)) {
504
-                        $args[] = ' OBJECT ' . get_class($arg);
505
-                    } elseif (is_resource($arg)) {
506
-                        $args[] = get_resource_type($arg);
507
-                    } else {
508
-                        $args[] = $arg;
509
-                    }
510
-                }
511
-            }
512
-            $arg_string = implode(', ', $args);
513
-        }
514
-        if ($array) {
515
-            $arg_string .= ' )';
516
-        }
517
-        return $arg_string;
518
-    }
519
-
520
-
521
-    /**
522
-     *    add error message
523
-     *
524
-     * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
525
-     *                            separate messages for user || dev
526
-     * @param        string $file the file that the error occurred in - just use __FILE__
527
-     * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
528
-     * @param        string $line the line number where the error occurred - just use __LINE__
529
-     * @return        void
530
-     */
531
-    public static function add_error($msg = null, $file = null, $func = null, $line = null)
532
-    {
533
-        self::_add_notice('errors', $msg, $file, $func, $line);
534
-        self::$_error_count++;
535
-    }
536
-
537
-
538
-    /**
539
-     * If WP_DEBUG is active, throws an exception. If WP_DEBUG is off, just
540
-     * adds an error
541
-     *
542
-     * @param string $msg
543
-     * @param string $file
544
-     * @param string $func
545
-     * @param string $line
546
-     * @throws EE_Error
547
-     */
548
-    public static function throw_exception_if_debugging($msg = null, $file = null, $func = null, $line = null)
549
-    {
550
-        if (WP_DEBUG) {
551
-            throw new EE_Error($msg);
552
-        }
553
-        EE_Error::add_error($msg, $file, $func, $line);
554
-    }
555
-
556
-
557
-    /**
558
-     *    add success message
559
-     *
560
-     * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
561
-     *                            separate messages for user || dev
562
-     * @param        string $file the file that the error occurred in - just use __FILE__
563
-     * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
564
-     * @param        string $line the line number where the error occurred - just use __LINE__
565
-     * @return        void
566
-     */
567
-    public static function add_success($msg = null, $file = null, $func = null, $line = null)
568
-    {
569
-        self::_add_notice('success', $msg, $file, $func, $line);
570
-    }
571
-
572
-
573
-    /**
574
-     *    add attention message
575
-     *
576
-     * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
577
-     *                            separate messages for user || dev
578
-     * @param        string $file the file that the error occurred in - just use __FILE__
579
-     * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
580
-     * @param        string $line the line number where the error occurred - just use __LINE__
581
-     * @return        void
582
-     */
583
-    public static function add_attention($msg = null, $file = null, $func = null, $line = null)
584
-    {
585
-        self::_add_notice('attention', $msg, $file, $func, $line);
586
-    }
587
-
588
-
589
-    /**
590
-     * @param string $type whether the message is for a success or error notification
591
-     * @param string $msg  the message to display to users or developers
592
-     *                     - adding a double pipe || (OR) creates separate messages for user || dev
593
-     * @param string $file the file that the error occurred in - just use __FILE__
594
-     * @param string $func the function/method that the error occurred in - just use __FUNCTION__
595
-     * @param string $line the line number where the error occurred - just use __LINE__
596
-     * @return void
597
-     */
598
-    private static function _add_notice($type = 'success', $msg = '', $file = '', $func = '', $line = '')
599
-    {
600
-        if (empty($msg)) {
601
-            EE_Error::doing_it_wrong(
602
-                'EE_Error::add_' . $type . '()',
603
-                sprintf(
604
-                    __(
605
-                        'Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d',
606
-                        'event_espresso'
607
-                    ),
608
-                    $type,
609
-                    $file,
610
-                    $line
611
-                ),
612
-                EVENT_ESPRESSO_VERSION
613
-            );
614
-        }
615
-        if ($type === 'errors' && (empty($file) || empty($func) || empty($line))) {
616
-            EE_Error::doing_it_wrong(
617
-                'EE_Error::add_error()',
618
-                __(
619
-                    'You need to provide the file name, function name, and line number that the error occurred on in order to better assist with debugging.',
620
-                    'event_espresso'
621
-                ),
622
-                EVENT_ESPRESSO_VERSION
623
-            );
624
-        }
625
-        // get separate user and developer messages if they exist
626
-        $msg = explode('||', $msg);
627
-        $user_msg = $msg[0];
628
-        $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0];
629
-        /**
630
-         * Do an action so other code can be triggered when a notice is created
631
-         *
632
-         * @param string $type     can be 'errors', 'attention', or 'success'
633
-         * @param string $user_msg message displayed to user when WP_DEBUG is off
634
-         * @param string $user_msg message displayed to user when WP_DEBUG is on
635
-         * @param string $file     file where error was generated
636
-         * @param string $func     function where error was generated
637
-         * @param string $line     line where error was generated
638
-         */
639
-        do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line);
640
-        $msg = WP_DEBUG ? $dev_msg : $user_msg;
641
-        // add notice if message exists
642
-        if (! empty($msg)) {
643
-            // get error code
644
-            $notice_code = EE_Error::generate_error_code($file, $func, $line);
645
-            if (WP_DEBUG && $type === 'errors') {
646
-                $msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>';
647
-            }
648
-            // add notice. Index by code if it's not blank
649
-            if ($notice_code) {
650
-                self::$_espresso_notices[ $type ][ $notice_code ] = $msg;
651
-            } else {
652
-                self::$_espresso_notices[ $type ][] = $msg;
653
-            }
654
-            add_action('wp_footer', array('EE_Error', 'enqueue_error_scripts'), 1);
655
-        }
656
-    }
657
-
658
-
659
-    /**
660
-     * in some case it may be necessary to overwrite the existing success messages
661
-     *
662
-     * @return        void
663
-     */
664
-    public static function overwrite_success()
665
-    {
666
-        self::$_espresso_notices['success'] = false;
667
-    }
668
-
669
-
670
-    /**
671
-     * in some case it may be necessary to overwrite the existing attention messages
672
-     *
673
-     * @return void
674
-     */
675
-    public static function overwrite_attention()
676
-    {
677
-        self::$_espresso_notices['attention'] = false;
678
-    }
679
-
680
-
681
-    /**
682
-     * in some case it may be necessary to overwrite the existing error messages
683
-     *
684
-     * @return void
685
-     */
686
-    public static function overwrite_errors()
687
-    {
688
-        self::$_espresso_notices['errors'] = false;
689
-    }
690
-
691
-
692
-    /**
693
-     * @return void
694
-     */
695
-    public static function reset_notices()
696
-    {
697
-        self::$_espresso_notices['success'] = false;
698
-        self::$_espresso_notices['attention'] = false;
699
-        self::$_espresso_notices['errors'] = false;
700
-    }
701
-
702
-
703
-    /**
704
-     * @return int
705
-     */
706
-    public static function has_notices()
707
-    {
708
-        $has_notices = 0;
709
-        // check for success messages
710
-        $has_notices = self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])
711
-            ? 3
712
-            : $has_notices;
713
-        // check for attention messages
714
-        $has_notices = self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])
715
-            ? 2
716
-            : $has_notices;
717
-        // check for error messages
718
-        $has_notices = self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])
719
-            ? 1
720
-            : $has_notices;
721
-        return $has_notices;
722
-    }
723
-
724
-
725
-    /**
726
-     * This simply returns non formatted error notices as they were sent into the EE_Error object.
727
-     *
728
-     * @since 4.9.0
729
-     * @return array
730
-     */
731
-    public static function get_vanilla_notices()
732
-    {
733
-        return array(
734
-            'success'   => isset(self::$_espresso_notices['success'])
735
-                ? self::$_espresso_notices['success']
736
-                : array(),
737
-            'attention' => isset(self::$_espresso_notices['attention'])
738
-                ? self::$_espresso_notices['attention']
739
-                : array(),
740
-            'errors'    => isset(self::$_espresso_notices['errors'])
741
-                ? self::$_espresso_notices['errors']
742
-                : array(),
743
-        );
744
-    }
745
-
746
-
747
-    /**
748
-     * @return array
749
-     * @throws InvalidArgumentException
750
-     * @throws InvalidDataTypeException
751
-     * @throws InvalidInterfaceException
752
-     */
753
-    public static function getStoredNotices()
754
-    {
755
-        if ($user_id = get_current_user_id()) {
756
-            // get notices for logged in user
757
-            $notices = get_user_option(EE_Error::OPTIONS_KEY_NOTICES, $user_id);
758
-            return is_array($notices) ? $notices : array();
759
-        }
760
-        if (EE_Session::isLoadedAndActive()) {
761
-            // get notices for user currently engaged in a session
762
-            $session_data = EE_Session::instance()->get_session_data(EE_Error::OPTIONS_KEY_NOTICES);
763
-            return is_array($session_data) ? $session_data : array();
764
-        }
765
-        // get global notices and hope they apply to the current site visitor
766
-        $notices = get_option(EE_Error::OPTIONS_KEY_NOTICES, array());
767
-        return is_array($notices) ? $notices : array();
768
-    }
769
-
770
-
771
-    /**
772
-     * @param array $notices
773
-     * @return bool
774
-     * @throws InvalidArgumentException
775
-     * @throws InvalidDataTypeException
776
-     * @throws InvalidInterfaceException
777
-     */
778
-    public static function storeNotices(array $notices)
779
-    {
780
-        if ($user_id = get_current_user_id()) {
781
-            // store notices for logged in user
782
-            return (bool) update_user_option(
783
-                $user_id,
784
-                EE_Error::OPTIONS_KEY_NOTICES,
785
-                $notices
786
-            );
787
-        }
788
-        if (EE_Session::isLoadedAndActive()) {
789
-            // store notices for user currently engaged in a session
790
-            return EE_Session::instance()->set_session_data(
791
-                array(EE_Error::OPTIONS_KEY_NOTICES => $notices)
792
-            );
793
-        }
794
-        // store global notices and hope they apply to the same site visitor on the next request
795
-        return update_option(EE_Error::OPTIONS_KEY_NOTICES, $notices);
796
-    }
797
-
798
-
799
-    /**
800
-     * @return bool|TRUE
801
-     * @throws InvalidArgumentException
802
-     * @throws InvalidDataTypeException
803
-     * @throws InvalidInterfaceException
804
-     */
805
-    public static function clearNotices()
806
-    {
807
-        if ($user_id = get_current_user_id()) {
808
-            // clear notices for logged in user
809
-            return (bool) update_user_option(
810
-                $user_id,
811
-                EE_Error::OPTIONS_KEY_NOTICES,
812
-                array()
813
-            );
814
-        }
815
-        if (EE_Session::isLoadedAndActive()) {
816
-            // clear notices for user currently engaged in a session
817
-            return EE_Session::instance()->reset_data(EE_Error::OPTIONS_KEY_NOTICES);
818
-        }
819
-        // clear global notices and hope none belonged to some for some other site visitor
820
-        return update_option(EE_Error::OPTIONS_KEY_NOTICES, array());
821
-    }
822
-
823
-
824
-    /**
825
-     * saves notices to the db for retrieval on next request
826
-     *
827
-     * @return void
828
-     * @throws InvalidArgumentException
829
-     * @throws InvalidDataTypeException
830
-     * @throws InvalidInterfaceException
831
-     */
832
-    public static function stashNoticesBeforeRedirect()
833
-    {
834
-        EE_Error::get_notices(false, true);
835
-    }
836
-
837
-
838
-    /**
839
-     * compile all error or success messages into one string
840
-     *
841
-     * @see EE_Error::get_raw_notices if you want the raw notices without any preparations made to them
842
-     * @param boolean $format_output            whether or not to format the messages for display in the WP admin
843
-     * @param boolean $save_to_transient        whether or not to save notices to the db for retrieval on next request
844
-     *                                          - ONLY do this just before redirecting
845
-     * @param boolean $remove_empty             whether or not to unset empty messages
846
-     * @return array
847
-     * @throws InvalidArgumentException
848
-     * @throws InvalidDataTypeException
849
-     * @throws InvalidInterfaceException
850
-     */
851
-    public static function get_notices($format_output = true, $save_to_transient = false, $remove_empty = true)
852
-    {
853
-        $success_messages = '';
854
-        $attention_messages = '';
855
-        $error_messages = '';
856
-        // either save notices to the db
857
-        if ($save_to_transient || isset($_REQUEST['activate-selected'])) {
858
-            self::$_espresso_notices = array_merge(
859
-                EE_Error::getStoredNotices(),
860
-                self::$_espresso_notices
861
-            );
862
-            EE_Error::storeNotices(self::$_espresso_notices);
863
-            return array();
864
-        }
865
-        $print_scripts = EE_Error::combineExistingAndNewNotices();
866
-        // check for success messages
867
-        if (self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])) {
868
-            // combine messages
869
-            $success_messages .= implode('<br />', self::$_espresso_notices['success']);
870
-            $print_scripts = true;
871
-        }
872
-        // check for attention messages
873
-        if (self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])) {
874
-            // combine messages
875
-            $attention_messages .= implode('<br />', self::$_espresso_notices['attention']);
876
-            $print_scripts = true;
877
-        }
878
-        // check for error messages
879
-        if (self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])) {
880
-            $error_messages .= count(self::$_espresso_notices['errors']) > 1
881
-                ? __('The following errors have occurred:<br />', 'event_espresso')
882
-                : __('An error has occurred:<br />', 'event_espresso');
883
-            // combine messages
884
-            $error_messages .= implode('<br />', self::$_espresso_notices['errors']);
885
-            $print_scripts = true;
886
-        }
887
-        if ($format_output) {
888
-            $notices = EE_Error::formatNoticesOutput(
889
-                $success_messages,
890
-                $attention_messages,
891
-                $error_messages
892
-            );
893
-        } else {
894
-            $notices = array(
895
-                'success'   => $success_messages,
896
-                'attention' => $attention_messages,
897
-                'errors'    => $error_messages,
898
-            );
899
-            if ($remove_empty) {
900
-                // remove empty notices
901
-                foreach ($notices as $type => $notice) {
902
-                    if (empty($notice)) {
903
-                        unset($notices[ $type ]);
904
-                    }
905
-                }
906
-            }
907
-        }
908
-        if ($print_scripts) {
909
-            self::_print_scripts();
910
-        }
911
-        return $notices;
912
-    }
913
-
914
-
915
-    /**
916
-     * @return bool
917
-     * @throws InvalidArgumentException
918
-     * @throws InvalidDataTypeException
919
-     * @throws InvalidInterfaceException
920
-     */
921
-    private static function combineExistingAndNewNotices()
922
-    {
923
-        $print_scripts = false;
924
-        // grab any notices that have been previously saved
925
-        $notices = EE_Error::getStoredNotices();
926
-        if (! empty($notices)) {
927
-            foreach ($notices as $type => $notice) {
928
-                if (is_array($notice) && ! empty($notice)) {
929
-                    // make sure that existing notice type is an array
930
-                    self::$_espresso_notices[ $type ] = is_array(self::$_espresso_notices[ $type ])
931
-                                                        && ! empty(self::$_espresso_notices[ $type ])
932
-                        ? self::$_espresso_notices[ $type ]
933
-                        : array();
934
-                    // add newly created notices to existing ones
935
-                    self::$_espresso_notices[ $type ] += $notice;
936
-                    $print_scripts = true;
937
-                }
938
-            }
939
-            // now clear any stored notices
940
-            EE_Error::clearNotices();
941
-        }
942
-        return $print_scripts;
943
-    }
944
-
945
-
946
-    /**
947
-     * @param string $success_messages
948
-     * @param string $attention_messages
949
-     * @param string $error_messages
950
-     * @return string
951
-     */
952
-    private static function formatNoticesOutput($success_messages, $attention_messages, $error_messages)
953
-    {
954
-        $notices = '<div id="espresso-notices">';
955
-        $close = is_admin()
956
-            ? ''
957
-            : '<a class="close-espresso-notice hide-if-no-js"><span class="dashicons dashicons-no"/></a>';
958
-        if ($success_messages !== '') {
959
-            $css_id = is_admin() ? 'ee-success-message' : 'espresso-notices-success';
960
-            $css_class = is_admin() ? 'updated fade' : 'success fade-away';
961
-            // showMessage( $success_messages );
962
-            $notices .= '<div id="' . $css_id . '" '
963
-                        . 'class="espresso-notices ' . $css_class . '" '
964
-                        . 'style="display:none;">'
965
-                        . '<p>' . $success_messages . '</p>'
966
-                        . $close
967
-                        . '</div>';
968
-        }
969
-        if ($attention_messages !== '') {
970
-            $css_id = is_admin() ? 'ee-attention-message' : 'espresso-notices-attention';
971
-            $css_class = is_admin() ? 'updated ee-notices-attention' : 'attention fade-away';
972
-            // showMessage( $error_messages, TRUE );
973
-            $notices .= '<div id="' . $css_id . '" '
974
-                        . 'class="espresso-notices ' . $css_class . '" '
975
-                        . 'style="display:none;">'
976
-                        . '<p>' . $attention_messages . '</p>'
977
-                        . $close
978
-                        . '</div>';
979
-        }
980
-        if ($error_messages !== '') {
981
-            $css_id = is_admin() ? 'ee-error-message' : 'espresso-notices-error';
982
-            $css_class = is_admin() ? 'error' : 'error fade-away';
983
-            // showMessage( $error_messages, TRUE );
984
-            $notices .= '<div id="' . $css_id . '" '
985
-                        . 'class="espresso-notices ' . $css_class . '" '
986
-                        . 'style="display:none;">'
987
-                        . '<p>' . $error_messages . '</p>'
988
-                        . $close
989
-                        . '</div>';
990
-        }
991
-        $notices .= '</div>';
992
-        return $notices;
993
-    }
994
-
995
-
996
-    /**
997
-     * _print_scripts
998
-     *
999
-     * @param    bool $force_print
1000
-     * @return    string
1001
-     */
1002
-    private static function _print_scripts($force_print = false)
1003
-    {
1004
-        if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
1005
-            if (wp_script_is('ee_error_js', 'registered')) {
1006
-                wp_enqueue_style('espresso_default');
1007
-                wp_enqueue_style('espresso_custom_css');
1008
-                wp_enqueue_script('ee_error_js');
1009
-            }
1010
-            if (wp_script_is('ee_error_js', 'enqueued')) {
1011
-                wp_localize_script('ee_error_js', 'ee_settings', array('wp_debug' => WP_DEBUG));
1012
-                return '';
1013
-            }
1014
-        } else {
1015
-            return '
471
+		$output .= self::_print_scripts(true);
472
+		if (defined('DOING_AJAX')) {
473
+			echo wp_json_encode(array('error' => $output));
474
+			exit();
475
+		}
476
+		echo $output;
477
+		die();
478
+	}
479
+
480
+
481
+	/**
482
+	 *    generate string from exception trace args
483
+	 *
484
+	 * @param array $arguments
485
+	 * @param bool  $array
486
+	 * @return string
487
+	 */
488
+	private function _convert_args_to_string($arguments = array(), $array = false)
489
+	{
490
+		$arg_string = '';
491
+		if (! empty($arguments)) {
492
+			$args = array();
493
+			foreach ($arguments as $arg) {
494
+				if (! empty($arg)) {
495
+					if (is_string($arg)) {
496
+						$args[] = " '" . $arg . "'";
497
+					} elseif (is_array($arg)) {
498
+						$args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true);
499
+					} elseif ($arg === null) {
500
+						$args[] = ' NULL';
501
+					} elseif (is_bool($arg)) {
502
+						$args[] = ($arg) ? ' TRUE' : ' FALSE';
503
+					} elseif (is_object($arg)) {
504
+						$args[] = ' OBJECT ' . get_class($arg);
505
+					} elseif (is_resource($arg)) {
506
+						$args[] = get_resource_type($arg);
507
+					} else {
508
+						$args[] = $arg;
509
+					}
510
+				}
511
+			}
512
+			$arg_string = implode(', ', $args);
513
+		}
514
+		if ($array) {
515
+			$arg_string .= ' )';
516
+		}
517
+		return $arg_string;
518
+	}
519
+
520
+
521
+	/**
522
+	 *    add error message
523
+	 *
524
+	 * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
525
+	 *                            separate messages for user || dev
526
+	 * @param        string $file the file that the error occurred in - just use __FILE__
527
+	 * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
528
+	 * @param        string $line the line number where the error occurred - just use __LINE__
529
+	 * @return        void
530
+	 */
531
+	public static function add_error($msg = null, $file = null, $func = null, $line = null)
532
+	{
533
+		self::_add_notice('errors', $msg, $file, $func, $line);
534
+		self::$_error_count++;
535
+	}
536
+
537
+
538
+	/**
539
+	 * If WP_DEBUG is active, throws an exception. If WP_DEBUG is off, just
540
+	 * adds an error
541
+	 *
542
+	 * @param string $msg
543
+	 * @param string $file
544
+	 * @param string $func
545
+	 * @param string $line
546
+	 * @throws EE_Error
547
+	 */
548
+	public static function throw_exception_if_debugging($msg = null, $file = null, $func = null, $line = null)
549
+	{
550
+		if (WP_DEBUG) {
551
+			throw new EE_Error($msg);
552
+		}
553
+		EE_Error::add_error($msg, $file, $func, $line);
554
+	}
555
+
556
+
557
+	/**
558
+	 *    add success message
559
+	 *
560
+	 * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
561
+	 *                            separate messages for user || dev
562
+	 * @param        string $file the file that the error occurred in - just use __FILE__
563
+	 * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
564
+	 * @param        string $line the line number where the error occurred - just use __LINE__
565
+	 * @return        void
566
+	 */
567
+	public static function add_success($msg = null, $file = null, $func = null, $line = null)
568
+	{
569
+		self::_add_notice('success', $msg, $file, $func, $line);
570
+	}
571
+
572
+
573
+	/**
574
+	 *    add attention message
575
+	 *
576
+	 * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
577
+	 *                            separate messages for user || dev
578
+	 * @param        string $file the file that the error occurred in - just use __FILE__
579
+	 * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
580
+	 * @param        string $line the line number where the error occurred - just use __LINE__
581
+	 * @return        void
582
+	 */
583
+	public static function add_attention($msg = null, $file = null, $func = null, $line = null)
584
+	{
585
+		self::_add_notice('attention', $msg, $file, $func, $line);
586
+	}
587
+
588
+
589
+	/**
590
+	 * @param string $type whether the message is for a success or error notification
591
+	 * @param string $msg  the message to display to users or developers
592
+	 *                     - adding a double pipe || (OR) creates separate messages for user || dev
593
+	 * @param string $file the file that the error occurred in - just use __FILE__
594
+	 * @param string $func the function/method that the error occurred in - just use __FUNCTION__
595
+	 * @param string $line the line number where the error occurred - just use __LINE__
596
+	 * @return void
597
+	 */
598
+	private static function _add_notice($type = 'success', $msg = '', $file = '', $func = '', $line = '')
599
+	{
600
+		if (empty($msg)) {
601
+			EE_Error::doing_it_wrong(
602
+				'EE_Error::add_' . $type . '()',
603
+				sprintf(
604
+					__(
605
+						'Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d',
606
+						'event_espresso'
607
+					),
608
+					$type,
609
+					$file,
610
+					$line
611
+				),
612
+				EVENT_ESPRESSO_VERSION
613
+			);
614
+		}
615
+		if ($type === 'errors' && (empty($file) || empty($func) || empty($line))) {
616
+			EE_Error::doing_it_wrong(
617
+				'EE_Error::add_error()',
618
+				__(
619
+					'You need to provide the file name, function name, and line number that the error occurred on in order to better assist with debugging.',
620
+					'event_espresso'
621
+				),
622
+				EVENT_ESPRESSO_VERSION
623
+			);
624
+		}
625
+		// get separate user and developer messages if they exist
626
+		$msg = explode('||', $msg);
627
+		$user_msg = $msg[0];
628
+		$dev_msg = isset($msg[1]) ? $msg[1] : $msg[0];
629
+		/**
630
+		 * Do an action so other code can be triggered when a notice is created
631
+		 *
632
+		 * @param string $type     can be 'errors', 'attention', or 'success'
633
+		 * @param string $user_msg message displayed to user when WP_DEBUG is off
634
+		 * @param string $user_msg message displayed to user when WP_DEBUG is on
635
+		 * @param string $file     file where error was generated
636
+		 * @param string $func     function where error was generated
637
+		 * @param string $line     line where error was generated
638
+		 */
639
+		do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line);
640
+		$msg = WP_DEBUG ? $dev_msg : $user_msg;
641
+		// add notice if message exists
642
+		if (! empty($msg)) {
643
+			// get error code
644
+			$notice_code = EE_Error::generate_error_code($file, $func, $line);
645
+			if (WP_DEBUG && $type === 'errors') {
646
+				$msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>';
647
+			}
648
+			// add notice. Index by code if it's not blank
649
+			if ($notice_code) {
650
+				self::$_espresso_notices[ $type ][ $notice_code ] = $msg;
651
+			} else {
652
+				self::$_espresso_notices[ $type ][] = $msg;
653
+			}
654
+			add_action('wp_footer', array('EE_Error', 'enqueue_error_scripts'), 1);
655
+		}
656
+	}
657
+
658
+
659
+	/**
660
+	 * in some case it may be necessary to overwrite the existing success messages
661
+	 *
662
+	 * @return        void
663
+	 */
664
+	public static function overwrite_success()
665
+	{
666
+		self::$_espresso_notices['success'] = false;
667
+	}
668
+
669
+
670
+	/**
671
+	 * in some case it may be necessary to overwrite the existing attention messages
672
+	 *
673
+	 * @return void
674
+	 */
675
+	public static function overwrite_attention()
676
+	{
677
+		self::$_espresso_notices['attention'] = false;
678
+	}
679
+
680
+
681
+	/**
682
+	 * in some case it may be necessary to overwrite the existing error messages
683
+	 *
684
+	 * @return void
685
+	 */
686
+	public static function overwrite_errors()
687
+	{
688
+		self::$_espresso_notices['errors'] = false;
689
+	}
690
+
691
+
692
+	/**
693
+	 * @return void
694
+	 */
695
+	public static function reset_notices()
696
+	{
697
+		self::$_espresso_notices['success'] = false;
698
+		self::$_espresso_notices['attention'] = false;
699
+		self::$_espresso_notices['errors'] = false;
700
+	}
701
+
702
+
703
+	/**
704
+	 * @return int
705
+	 */
706
+	public static function has_notices()
707
+	{
708
+		$has_notices = 0;
709
+		// check for success messages
710
+		$has_notices = self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])
711
+			? 3
712
+			: $has_notices;
713
+		// check for attention messages
714
+		$has_notices = self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])
715
+			? 2
716
+			: $has_notices;
717
+		// check for error messages
718
+		$has_notices = self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])
719
+			? 1
720
+			: $has_notices;
721
+		return $has_notices;
722
+	}
723
+
724
+
725
+	/**
726
+	 * This simply returns non formatted error notices as they were sent into the EE_Error object.
727
+	 *
728
+	 * @since 4.9.0
729
+	 * @return array
730
+	 */
731
+	public static function get_vanilla_notices()
732
+	{
733
+		return array(
734
+			'success'   => isset(self::$_espresso_notices['success'])
735
+				? self::$_espresso_notices['success']
736
+				: array(),
737
+			'attention' => isset(self::$_espresso_notices['attention'])
738
+				? self::$_espresso_notices['attention']
739
+				: array(),
740
+			'errors'    => isset(self::$_espresso_notices['errors'])
741
+				? self::$_espresso_notices['errors']
742
+				: array(),
743
+		);
744
+	}
745
+
746
+
747
+	/**
748
+	 * @return array
749
+	 * @throws InvalidArgumentException
750
+	 * @throws InvalidDataTypeException
751
+	 * @throws InvalidInterfaceException
752
+	 */
753
+	public static function getStoredNotices()
754
+	{
755
+		if ($user_id = get_current_user_id()) {
756
+			// get notices for logged in user
757
+			$notices = get_user_option(EE_Error::OPTIONS_KEY_NOTICES, $user_id);
758
+			return is_array($notices) ? $notices : array();
759
+		}
760
+		if (EE_Session::isLoadedAndActive()) {
761
+			// get notices for user currently engaged in a session
762
+			$session_data = EE_Session::instance()->get_session_data(EE_Error::OPTIONS_KEY_NOTICES);
763
+			return is_array($session_data) ? $session_data : array();
764
+		}
765
+		// get global notices and hope they apply to the current site visitor
766
+		$notices = get_option(EE_Error::OPTIONS_KEY_NOTICES, array());
767
+		return is_array($notices) ? $notices : array();
768
+	}
769
+
770
+
771
+	/**
772
+	 * @param array $notices
773
+	 * @return bool
774
+	 * @throws InvalidArgumentException
775
+	 * @throws InvalidDataTypeException
776
+	 * @throws InvalidInterfaceException
777
+	 */
778
+	public static function storeNotices(array $notices)
779
+	{
780
+		if ($user_id = get_current_user_id()) {
781
+			// store notices for logged in user
782
+			return (bool) update_user_option(
783
+				$user_id,
784
+				EE_Error::OPTIONS_KEY_NOTICES,
785
+				$notices
786
+			);
787
+		}
788
+		if (EE_Session::isLoadedAndActive()) {
789
+			// store notices for user currently engaged in a session
790
+			return EE_Session::instance()->set_session_data(
791
+				array(EE_Error::OPTIONS_KEY_NOTICES => $notices)
792
+			);
793
+		}
794
+		// store global notices and hope they apply to the same site visitor on the next request
795
+		return update_option(EE_Error::OPTIONS_KEY_NOTICES, $notices);
796
+	}
797
+
798
+
799
+	/**
800
+	 * @return bool|TRUE
801
+	 * @throws InvalidArgumentException
802
+	 * @throws InvalidDataTypeException
803
+	 * @throws InvalidInterfaceException
804
+	 */
805
+	public static function clearNotices()
806
+	{
807
+		if ($user_id = get_current_user_id()) {
808
+			// clear notices for logged in user
809
+			return (bool) update_user_option(
810
+				$user_id,
811
+				EE_Error::OPTIONS_KEY_NOTICES,
812
+				array()
813
+			);
814
+		}
815
+		if (EE_Session::isLoadedAndActive()) {
816
+			// clear notices for user currently engaged in a session
817
+			return EE_Session::instance()->reset_data(EE_Error::OPTIONS_KEY_NOTICES);
818
+		}
819
+		// clear global notices and hope none belonged to some for some other site visitor
820
+		return update_option(EE_Error::OPTIONS_KEY_NOTICES, array());
821
+	}
822
+
823
+
824
+	/**
825
+	 * saves notices to the db for retrieval on next request
826
+	 *
827
+	 * @return void
828
+	 * @throws InvalidArgumentException
829
+	 * @throws InvalidDataTypeException
830
+	 * @throws InvalidInterfaceException
831
+	 */
832
+	public static function stashNoticesBeforeRedirect()
833
+	{
834
+		EE_Error::get_notices(false, true);
835
+	}
836
+
837
+
838
+	/**
839
+	 * compile all error or success messages into one string
840
+	 *
841
+	 * @see EE_Error::get_raw_notices if you want the raw notices without any preparations made to them
842
+	 * @param boolean $format_output            whether or not to format the messages for display in the WP admin
843
+	 * @param boolean $save_to_transient        whether or not to save notices to the db for retrieval on next request
844
+	 *                                          - ONLY do this just before redirecting
845
+	 * @param boolean $remove_empty             whether or not to unset empty messages
846
+	 * @return array
847
+	 * @throws InvalidArgumentException
848
+	 * @throws InvalidDataTypeException
849
+	 * @throws InvalidInterfaceException
850
+	 */
851
+	public static function get_notices($format_output = true, $save_to_transient = false, $remove_empty = true)
852
+	{
853
+		$success_messages = '';
854
+		$attention_messages = '';
855
+		$error_messages = '';
856
+		// either save notices to the db
857
+		if ($save_to_transient || isset($_REQUEST['activate-selected'])) {
858
+			self::$_espresso_notices = array_merge(
859
+				EE_Error::getStoredNotices(),
860
+				self::$_espresso_notices
861
+			);
862
+			EE_Error::storeNotices(self::$_espresso_notices);
863
+			return array();
864
+		}
865
+		$print_scripts = EE_Error::combineExistingAndNewNotices();
866
+		// check for success messages
867
+		if (self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])) {
868
+			// combine messages
869
+			$success_messages .= implode('<br />', self::$_espresso_notices['success']);
870
+			$print_scripts = true;
871
+		}
872
+		// check for attention messages
873
+		if (self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])) {
874
+			// combine messages
875
+			$attention_messages .= implode('<br />', self::$_espresso_notices['attention']);
876
+			$print_scripts = true;
877
+		}
878
+		// check for error messages
879
+		if (self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])) {
880
+			$error_messages .= count(self::$_espresso_notices['errors']) > 1
881
+				? __('The following errors have occurred:<br />', 'event_espresso')
882
+				: __('An error has occurred:<br />', 'event_espresso');
883
+			// combine messages
884
+			$error_messages .= implode('<br />', self::$_espresso_notices['errors']);
885
+			$print_scripts = true;
886
+		}
887
+		if ($format_output) {
888
+			$notices = EE_Error::formatNoticesOutput(
889
+				$success_messages,
890
+				$attention_messages,
891
+				$error_messages
892
+			);
893
+		} else {
894
+			$notices = array(
895
+				'success'   => $success_messages,
896
+				'attention' => $attention_messages,
897
+				'errors'    => $error_messages,
898
+			);
899
+			if ($remove_empty) {
900
+				// remove empty notices
901
+				foreach ($notices as $type => $notice) {
902
+					if (empty($notice)) {
903
+						unset($notices[ $type ]);
904
+					}
905
+				}
906
+			}
907
+		}
908
+		if ($print_scripts) {
909
+			self::_print_scripts();
910
+		}
911
+		return $notices;
912
+	}
913
+
914
+
915
+	/**
916
+	 * @return bool
917
+	 * @throws InvalidArgumentException
918
+	 * @throws InvalidDataTypeException
919
+	 * @throws InvalidInterfaceException
920
+	 */
921
+	private static function combineExistingAndNewNotices()
922
+	{
923
+		$print_scripts = false;
924
+		// grab any notices that have been previously saved
925
+		$notices = EE_Error::getStoredNotices();
926
+		if (! empty($notices)) {
927
+			foreach ($notices as $type => $notice) {
928
+				if (is_array($notice) && ! empty($notice)) {
929
+					// make sure that existing notice type is an array
930
+					self::$_espresso_notices[ $type ] = is_array(self::$_espresso_notices[ $type ])
931
+														&& ! empty(self::$_espresso_notices[ $type ])
932
+						? self::$_espresso_notices[ $type ]
933
+						: array();
934
+					// add newly created notices to existing ones
935
+					self::$_espresso_notices[ $type ] += $notice;
936
+					$print_scripts = true;
937
+				}
938
+			}
939
+			// now clear any stored notices
940
+			EE_Error::clearNotices();
941
+		}
942
+		return $print_scripts;
943
+	}
944
+
945
+
946
+	/**
947
+	 * @param string $success_messages
948
+	 * @param string $attention_messages
949
+	 * @param string $error_messages
950
+	 * @return string
951
+	 */
952
+	private static function formatNoticesOutput($success_messages, $attention_messages, $error_messages)
953
+	{
954
+		$notices = '<div id="espresso-notices">';
955
+		$close = is_admin()
956
+			? ''
957
+			: '<a class="close-espresso-notice hide-if-no-js"><span class="dashicons dashicons-no"/></a>';
958
+		if ($success_messages !== '') {
959
+			$css_id = is_admin() ? 'ee-success-message' : 'espresso-notices-success';
960
+			$css_class = is_admin() ? 'updated fade' : 'success fade-away';
961
+			// showMessage( $success_messages );
962
+			$notices .= '<div id="' . $css_id . '" '
963
+						. 'class="espresso-notices ' . $css_class . '" '
964
+						. 'style="display:none;">'
965
+						. '<p>' . $success_messages . '</p>'
966
+						. $close
967
+						. '</div>';
968
+		}
969
+		if ($attention_messages !== '') {
970
+			$css_id = is_admin() ? 'ee-attention-message' : 'espresso-notices-attention';
971
+			$css_class = is_admin() ? 'updated ee-notices-attention' : 'attention fade-away';
972
+			// showMessage( $error_messages, TRUE );
973
+			$notices .= '<div id="' . $css_id . '" '
974
+						. 'class="espresso-notices ' . $css_class . '" '
975
+						. 'style="display:none;">'
976
+						. '<p>' . $attention_messages . '</p>'
977
+						. $close
978
+						. '</div>';
979
+		}
980
+		if ($error_messages !== '') {
981
+			$css_id = is_admin() ? 'ee-error-message' : 'espresso-notices-error';
982
+			$css_class = is_admin() ? 'error' : 'error fade-away';
983
+			// showMessage( $error_messages, TRUE );
984
+			$notices .= '<div id="' . $css_id . '" '
985
+						. 'class="espresso-notices ' . $css_class . '" '
986
+						. 'style="display:none;">'
987
+						. '<p>' . $error_messages . '</p>'
988
+						. $close
989
+						. '</div>';
990
+		}
991
+		$notices .= '</div>';
992
+		return $notices;
993
+	}
994
+
995
+
996
+	/**
997
+	 * _print_scripts
998
+	 *
999
+	 * @param    bool $force_print
1000
+	 * @return    string
1001
+	 */
1002
+	private static function _print_scripts($force_print = false)
1003
+	{
1004
+		if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
1005
+			if (wp_script_is('ee_error_js', 'registered')) {
1006
+				wp_enqueue_style('espresso_default');
1007
+				wp_enqueue_style('espresso_custom_css');
1008
+				wp_enqueue_script('ee_error_js');
1009
+			}
1010
+			if (wp_script_is('ee_error_js', 'enqueued')) {
1011
+				wp_localize_script('ee_error_js', 'ee_settings', array('wp_debug' => WP_DEBUG));
1012
+				return '';
1013
+			}
1014
+		} else {
1015
+			return '
1016 1016
 <script>
1017 1017
 /* <![CDATA[ */
1018 1018
 var ee_settings = {"wp_debug":"' . WP_DEBUG . '"};
@@ -1022,221 +1022,221 @@  discard block
 block discarded – undo
1022 1022
 <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
1023 1023
 <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
1024 1024
 ';
1025
-        }
1026
-        return '';
1027
-    }
1028
-
1029
-
1030
-    /**
1031
-     * @return void
1032
-     */
1033
-    public static function enqueue_error_scripts()
1034
-    {
1035
-        self::_print_scripts();
1036
-    }
1037
-
1038
-
1039
-    /**
1040
-     * create error code from filepath, function name,
1041
-     * and line number where exception or error was thrown
1042
-     *
1043
-     * @param string $file
1044
-     * @param string $func
1045
-     * @param string $line
1046
-     * @return string
1047
-     */
1048
-    public static function generate_error_code($file = '', $func = '', $line = '')
1049
-    {
1050
-        $file = explode('.', basename($file));
1051
-        $error_code = ! empty($file[0]) ? $file[0] : '';
1052
-        $error_code .= ! empty($func) ? ' - ' . $func : '';
1053
-        $error_code .= ! empty($line) ? ' - ' . $line : '';
1054
-        return $error_code;
1055
-    }
1056
-
1057
-
1058
-    /**
1059
-     * write exception details to log file
1060
-     * Since 4.9.53.rc.006 this writes to the standard PHP log file, not EE's custom log file
1061
-     *
1062
-     * @param int   $time
1063
-     * @param array $ex
1064
-     * @param bool  $clear
1065
-     * @return void
1066
-     */
1067
-    public function write_to_error_log($time = 0, $ex = array(), $clear = false)
1068
-    {
1069
-        if (empty($ex)) {
1070
-            return;
1071
-        }
1072
-        if (! $time) {
1073
-            $time = time();
1074
-        }
1075
-        $exception_log = '----------------------------------------------------------------------------------------'
1076
-                         . PHP_EOL;
1077
-        $exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
1078
-        $exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
1079
-        $exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
1080
-        $exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
1081
-        $exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
1082
-        $exception_log .= 'Stack trace: ' . PHP_EOL;
1083
-        $exception_log .= $ex['string'] . PHP_EOL;
1084
-        $exception_log .= '----------------------------------------------------------------------------------------'
1085
-                          . PHP_EOL;
1086
-        try {
1087
-            error_log($exception_log);
1088
-        } catch (EE_Error $e) {
1089
-            EE_Error::add_error(
1090
-                sprintf(
1091
-                    __(
1092
-                        'Event Espresso error logging could not be setup because: %s',
1093
-                        'event_espresso'
1094
-                    ),
1095
-                    $e->getMessage()
1096
-                )
1097
-            );
1098
-        }
1099
-    }
1100
-
1101
-
1102
-    /**
1103
-     * This is just a wrapper for the EEH_Debug_Tools::instance()->doing_it_wrong() method.
1104
-     * doing_it_wrong() is used in those cases where a normal PHP error won't get thrown,
1105
-     * but the code execution is done in a manner that could lead to unexpected results
1106
-     * (i.e. running to early, or too late in WP or EE loading process).
1107
-     * A good test for knowing whether to use this method is:
1108
-     * 1. Is there going to be a PHP error if something isn't setup/used correctly?
1109
-     * Yes -> use EE_Error::add_error() or throw new EE_Error()
1110
-     * 2. If this is loaded before something else, it won't break anything,
1111
-     * but just wont' do what its supposed to do? Yes -> use EE_Error::doing_it_wrong()
1112
-     *
1113
-     * @uses   constant WP_DEBUG test if wp_debug is on or not
1114
-     * @param string $function      The function that was called
1115
-     * @param string $message       A message explaining what has been done incorrectly
1116
-     * @param string $version       The version of Event Espresso where the error was added
1117
-     * @param string $applies_when  a version string for when you want the doing_it_wrong notice to begin appearing
1118
-     *                              for a deprecated function. This allows deprecation to occur during one version,
1119
-     *                              but not have any notices appear until a later version. This allows developers
1120
-     *                              extra time to update their code before notices appear.
1121
-     * @param int    $error_type
1122
-     */
1123
-    public static function doing_it_wrong(
1124
-        $function,
1125
-        $message,
1126
-        $version,
1127
-        $applies_when = '',
1128
-        $error_type = null
1129
-    ) {
1130
-        if (defined('WP_DEBUG') && WP_DEBUG) {
1131
-            EEH_Debug_Tools::instance()->doing_it_wrong($function, $message, $version, $applies_when, $error_type);
1132
-        }
1133
-    }
1134
-
1135
-
1136
-    /**
1137
-     * Like get_notices, but returns an array of all the notices of the given type.
1138
-     *
1139
-     * @return array {
1140
-     * @type array $success   all the success messages
1141
-     * @type array $errors    all the error messages
1142
-     * @type array $attention all the attention messages
1143
-     * }
1144
-     */
1145
-    public static function get_raw_notices()
1146
-    {
1147
-        return self::$_espresso_notices;
1148
-    }
1149
-
1150
-
1151
-    /**
1152
-     * @deprecated 4.9.27
1153
-     * @param string $pan_name     the name, or key of the Persistent Admin Notice to be stored
1154
-     * @param string $pan_message  the message to be stored persistently until dismissed
1155
-     * @param bool   $force_update allows one to enforce the reappearance of a persistent message.
1156
-     * @return void
1157
-     * @throws InvalidDataTypeException
1158
-     */
1159
-    public static function add_persistent_admin_notice($pan_name = '', $pan_message, $force_update = false)
1160
-    {
1161
-        new PersistentAdminNotice(
1162
-            $pan_name,
1163
-            $pan_message,
1164
-            $force_update
1165
-        );
1166
-        EE_Error::doing_it_wrong(
1167
-            __METHOD__,
1168
-            sprintf(
1169
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1170
-                '\EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
1171
-            ),
1172
-            '4.9.27'
1173
-        );
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * @deprecated 4.9.27
1179
-     * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
1180
-     * @param bool   $purge
1181
-     * @param bool   $return
1182
-     * @throws DomainException
1183
-     * @throws InvalidInterfaceException
1184
-     * @throws InvalidDataTypeException
1185
-     * @throws ServiceNotFoundException
1186
-     * @throws InvalidArgumentException
1187
-     */
1188
-    public static function dismiss_persistent_admin_notice($pan_name = '', $purge = false, $return = false)
1189
-    {
1190
-        /** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
1191
-        $persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
1192
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1193
-        );
1194
-        $persistent_admin_notice_manager->dismissNotice($pan_name, $purge, $return);
1195
-        EE_Error::doing_it_wrong(
1196
-            __METHOD__,
1197
-            sprintf(
1198
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1199
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1200
-            ),
1201
-            '4.9.27'
1202
-        );
1203
-    }
1204
-
1205
-
1206
-    /**
1207
-     * @deprecated 4.9.27
1208
-     * @param  string $pan_name    the name, or key of the Persistent Admin Notice to be stored
1209
-     * @param  string $pan_message the message to be stored persistently until dismissed
1210
-     * @param  string $return_url  URL to go back to after nag notice is dismissed
1211
-     */
1212
-    public static function display_persistent_admin_notices($pan_name = '', $pan_message = '', $return_url = '')
1213
-    {
1214
-        EE_Error::doing_it_wrong(
1215
-            __METHOD__,
1216
-            sprintf(
1217
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1218
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1219
-            ),
1220
-            '4.9.27'
1221
-        );
1222
-    }
1223
-
1224
-
1225
-    /**
1226
-     * @deprecated 4.9.27
1227
-     * @param string $return_url
1228
-     */
1229
-    public static function get_persistent_admin_notices($return_url = '')
1230
-    {
1231
-        EE_Error::doing_it_wrong(
1232
-            __METHOD__,
1233
-            sprintf(
1234
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1235
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1236
-            ),
1237
-            '4.9.27'
1238
-        );
1239
-    }
1025
+		}
1026
+		return '';
1027
+	}
1028
+
1029
+
1030
+	/**
1031
+	 * @return void
1032
+	 */
1033
+	public static function enqueue_error_scripts()
1034
+	{
1035
+		self::_print_scripts();
1036
+	}
1037
+
1038
+
1039
+	/**
1040
+	 * create error code from filepath, function name,
1041
+	 * and line number where exception or error was thrown
1042
+	 *
1043
+	 * @param string $file
1044
+	 * @param string $func
1045
+	 * @param string $line
1046
+	 * @return string
1047
+	 */
1048
+	public static function generate_error_code($file = '', $func = '', $line = '')
1049
+	{
1050
+		$file = explode('.', basename($file));
1051
+		$error_code = ! empty($file[0]) ? $file[0] : '';
1052
+		$error_code .= ! empty($func) ? ' - ' . $func : '';
1053
+		$error_code .= ! empty($line) ? ' - ' . $line : '';
1054
+		return $error_code;
1055
+	}
1056
+
1057
+
1058
+	/**
1059
+	 * write exception details to log file
1060
+	 * Since 4.9.53.rc.006 this writes to the standard PHP log file, not EE's custom log file
1061
+	 *
1062
+	 * @param int   $time
1063
+	 * @param array $ex
1064
+	 * @param bool  $clear
1065
+	 * @return void
1066
+	 */
1067
+	public function write_to_error_log($time = 0, $ex = array(), $clear = false)
1068
+	{
1069
+		if (empty($ex)) {
1070
+			return;
1071
+		}
1072
+		if (! $time) {
1073
+			$time = time();
1074
+		}
1075
+		$exception_log = '----------------------------------------------------------------------------------------'
1076
+						 . PHP_EOL;
1077
+		$exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
1078
+		$exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
1079
+		$exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
1080
+		$exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
1081
+		$exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
1082
+		$exception_log .= 'Stack trace: ' . PHP_EOL;
1083
+		$exception_log .= $ex['string'] . PHP_EOL;
1084
+		$exception_log .= '----------------------------------------------------------------------------------------'
1085
+						  . PHP_EOL;
1086
+		try {
1087
+			error_log($exception_log);
1088
+		} catch (EE_Error $e) {
1089
+			EE_Error::add_error(
1090
+				sprintf(
1091
+					__(
1092
+						'Event Espresso error logging could not be setup because: %s',
1093
+						'event_espresso'
1094
+					),
1095
+					$e->getMessage()
1096
+				)
1097
+			);
1098
+		}
1099
+	}
1100
+
1101
+
1102
+	/**
1103
+	 * This is just a wrapper for the EEH_Debug_Tools::instance()->doing_it_wrong() method.
1104
+	 * doing_it_wrong() is used in those cases where a normal PHP error won't get thrown,
1105
+	 * but the code execution is done in a manner that could lead to unexpected results
1106
+	 * (i.e. running to early, or too late in WP or EE loading process).
1107
+	 * A good test for knowing whether to use this method is:
1108
+	 * 1. Is there going to be a PHP error if something isn't setup/used correctly?
1109
+	 * Yes -> use EE_Error::add_error() or throw new EE_Error()
1110
+	 * 2. If this is loaded before something else, it won't break anything,
1111
+	 * but just wont' do what its supposed to do? Yes -> use EE_Error::doing_it_wrong()
1112
+	 *
1113
+	 * @uses   constant WP_DEBUG test if wp_debug is on or not
1114
+	 * @param string $function      The function that was called
1115
+	 * @param string $message       A message explaining what has been done incorrectly
1116
+	 * @param string $version       The version of Event Espresso where the error was added
1117
+	 * @param string $applies_when  a version string for when you want the doing_it_wrong notice to begin appearing
1118
+	 *                              for a deprecated function. This allows deprecation to occur during one version,
1119
+	 *                              but not have any notices appear until a later version. This allows developers
1120
+	 *                              extra time to update their code before notices appear.
1121
+	 * @param int    $error_type
1122
+	 */
1123
+	public static function doing_it_wrong(
1124
+		$function,
1125
+		$message,
1126
+		$version,
1127
+		$applies_when = '',
1128
+		$error_type = null
1129
+	) {
1130
+		if (defined('WP_DEBUG') && WP_DEBUG) {
1131
+			EEH_Debug_Tools::instance()->doing_it_wrong($function, $message, $version, $applies_when, $error_type);
1132
+		}
1133
+	}
1134
+
1135
+
1136
+	/**
1137
+	 * Like get_notices, but returns an array of all the notices of the given type.
1138
+	 *
1139
+	 * @return array {
1140
+	 * @type array $success   all the success messages
1141
+	 * @type array $errors    all the error messages
1142
+	 * @type array $attention all the attention messages
1143
+	 * }
1144
+	 */
1145
+	public static function get_raw_notices()
1146
+	{
1147
+		return self::$_espresso_notices;
1148
+	}
1149
+
1150
+
1151
+	/**
1152
+	 * @deprecated 4.9.27
1153
+	 * @param string $pan_name     the name, or key of the Persistent Admin Notice to be stored
1154
+	 * @param string $pan_message  the message to be stored persistently until dismissed
1155
+	 * @param bool   $force_update allows one to enforce the reappearance of a persistent message.
1156
+	 * @return void
1157
+	 * @throws InvalidDataTypeException
1158
+	 */
1159
+	public static function add_persistent_admin_notice($pan_name = '', $pan_message, $force_update = false)
1160
+	{
1161
+		new PersistentAdminNotice(
1162
+			$pan_name,
1163
+			$pan_message,
1164
+			$force_update
1165
+		);
1166
+		EE_Error::doing_it_wrong(
1167
+			__METHOD__,
1168
+			sprintf(
1169
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1170
+				'\EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
1171
+			),
1172
+			'4.9.27'
1173
+		);
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * @deprecated 4.9.27
1179
+	 * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
1180
+	 * @param bool   $purge
1181
+	 * @param bool   $return
1182
+	 * @throws DomainException
1183
+	 * @throws InvalidInterfaceException
1184
+	 * @throws InvalidDataTypeException
1185
+	 * @throws ServiceNotFoundException
1186
+	 * @throws InvalidArgumentException
1187
+	 */
1188
+	public static function dismiss_persistent_admin_notice($pan_name = '', $purge = false, $return = false)
1189
+	{
1190
+		/** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
1191
+		$persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
1192
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1193
+		);
1194
+		$persistent_admin_notice_manager->dismissNotice($pan_name, $purge, $return);
1195
+		EE_Error::doing_it_wrong(
1196
+			__METHOD__,
1197
+			sprintf(
1198
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1199
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1200
+			),
1201
+			'4.9.27'
1202
+		);
1203
+	}
1204
+
1205
+
1206
+	/**
1207
+	 * @deprecated 4.9.27
1208
+	 * @param  string $pan_name    the name, or key of the Persistent Admin Notice to be stored
1209
+	 * @param  string $pan_message the message to be stored persistently until dismissed
1210
+	 * @param  string $return_url  URL to go back to after nag notice is dismissed
1211
+	 */
1212
+	public static function display_persistent_admin_notices($pan_name = '', $pan_message = '', $return_url = '')
1213
+	{
1214
+		EE_Error::doing_it_wrong(
1215
+			__METHOD__,
1216
+			sprintf(
1217
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1218
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1219
+			),
1220
+			'4.9.27'
1221
+		);
1222
+	}
1223
+
1224
+
1225
+	/**
1226
+	 * @deprecated 4.9.27
1227
+	 * @param string $return_url
1228
+	 */
1229
+	public static function get_persistent_admin_notices($return_url = '')
1230
+	{
1231
+		EE_Error::doing_it_wrong(
1232
+			__METHOD__,
1233
+			sprintf(
1234
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1235
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1236
+			),
1237
+			'4.9.27'
1238
+		);
1239
+	}
1240 1240
 }
1241 1241
 
1242 1242
 // end of Class EE_Exceptions
@@ -1249,27 +1249,27 @@  discard block
 block discarded – undo
1249 1249
  */
1250 1250
 function espresso_error_enqueue_scripts()
1251 1251
 {
1252
-    // js for error handling
1253
-    wp_register_script(
1254
-        'espresso_core',
1255
-        EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
1256
-        array('jquery'),
1257
-        EVENT_ESPRESSO_VERSION,
1258
-        false
1259
-    );
1260
-    wp_register_script(
1261
-        'ee_error_js',
1262
-        EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
1263
-        array('espresso_core'),
1264
-        EVENT_ESPRESSO_VERSION,
1265
-        false
1266
-    );
1252
+	// js for error handling
1253
+	wp_register_script(
1254
+		'espresso_core',
1255
+		EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
1256
+		array('jquery'),
1257
+		EVENT_ESPRESSO_VERSION,
1258
+		false
1259
+	);
1260
+	wp_register_script(
1261
+		'ee_error_js',
1262
+		EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
1263
+		array('espresso_core'),
1264
+		EVENT_ESPRESSO_VERSION,
1265
+		false
1266
+	);
1267 1267
 }
1268 1268
 
1269 1269
 if (is_admin()) {
1270
-    add_action('admin_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1270
+	add_action('admin_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1271 1271
 } else {
1272
-    add_action('wp_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1272
+	add_action('wp_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1273 1273
 }
1274 1274
 
1275 1275
 
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.4.0');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.4.0');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.4.rc.009');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.4.rc.009');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
Please login to merge, or discard this patch.
admin_pages/registrations/Registrations_Admin_Page.core.php 2 patches
Indentation   +3705 added lines, -3705 removed lines patch added patch discarded remove patch
@@ -18,2227 +18,2227 @@  discard block
 block discarded – undo
18 18
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
19 19
 {
20 20
 
21
-    /**
22
-     * @var EE_Registration
23
-     */
24
-    private $_registration;
25
-
26
-    /**
27
-     * @var EE_Event
28
-     */
29
-    private $_reg_event;
30
-
31
-    /**
32
-     * @var EE_Session
33
-     */
34
-    private $_session;
35
-
36
-    private static $_reg_status;
37
-
38
-    /**
39
-     * Form for displaying the custom questions for this registration.
40
-     * This gets used a few times throughout the request so its best to cache it
41
-     *
42
-     * @var EE_Registration_Custom_Questions_Form
43
-     */
44
-    protected $_reg_custom_questions_form;
45
-
46
-    /**
47
-     * @var EEM_Registration $registration_model
48
-     */
49
-    private $registration_model;
50
-
51
-    /**
52
-     * @var EEM_Attendee $attendee_model
53
-     */
54
-    private $attendee_model;
55
-
56
-    /**
57
-     * @var EEM_Event $event_model
58
-     */
59
-    private $event_model;
60
-
61
-    /**
62
-     * @var EEM_Status $status_model
63
-     */
64
-    private $status_model;
65
-
66
-
67
-    /**
68
-     * @param bool $routing
69
-     * @throws EE_Error
70
-     * @throws InvalidArgumentException
71
-     * @throws InvalidDataTypeException
72
-     * @throws InvalidInterfaceException
73
-     * @throws ReflectionException
74
-     */
75
-    public function __construct($routing = true)
76
-    {
77
-        parent::__construct($routing);
78
-        add_action('wp_loaded', array($this, 'wp_loaded'));
79
-    }
80
-
81
-    /**
82
-     * @return EEM_Registration
83
-     * @throws InvalidArgumentException
84
-     * @throws InvalidDataTypeException
85
-     * @throws InvalidInterfaceException
86
-     * @since 4.10.2.p
87
-     */
88
-    protected function getRegistrationModel()
89
-    {
90
-        if (! $this->registration_model instanceof EEM_Registration) {
91
-            $this->registration_model = $this->loader->getShared('EEM_Registration');
92
-        }
93
-        return $this->registration_model;
94
-    }
95
-
96
-    /**
97
-     * @return EEM_Attendee
98
-     * @throws InvalidArgumentException
99
-     * @throws InvalidDataTypeException
100
-     * @throws InvalidInterfaceException
101
-     * @since 4.10.2.p
102
-     */
103
-    protected function getAttendeeModel()
104
-    {
105
-        if (! $this->attendee_model instanceof EEM_Attendee) {
106
-            $this->attendee_model = $this->loader->getShared('EEM_Attendee');
107
-        }
108
-        return $this->attendee_model;
109
-    }
110
-
111
-
112
-    /**
113
-     * @return EEM_Event
114
-     * @throws InvalidArgumentException
115
-     * @throws InvalidDataTypeException
116
-     * @throws InvalidInterfaceException
117
-     * @since 4.10.2.p
118
-     */
119
-    protected function getEventModel()
120
-    {
121
-        if (! $this->event_model instanceof EEM_Event) {
122
-            $this->event_model = $this->loader->getShared('EEM_Event');
123
-        }
124
-        return $this->event_model;
125
-    }
126
-
127
-    /**
128
-     * @return EEM_Status
129
-     * @throws InvalidArgumentException
130
-     * @throws InvalidDataTypeException
131
-     * @throws InvalidInterfaceException
132
-     * @since 4.10.2.p
133
-     */
134
-    protected function getStatusModel()
135
-    {
136
-        if (! $this->status_model instanceof EEM_Status) {
137
-            $this->status_model = $this->loader->getShared('EEM_Status');
138
-        }
139
-        return $this->status_model;
140
-    }
141
-
142
-
143
-    public function wp_loaded()
144
-    {
145
-        // when adding a new registration...
146
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
147
-            EE_System::do_not_cache();
148
-            if (! isset($this->_req_data['processing_registration'])
149
-                || absint($this->_req_data['processing_registration']) !== 1
150
-            ) {
151
-                // and it's NOT the attendee information reg step
152
-                // force cookie expiration by setting time to last week
153
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
154
-                // and update the global
155
-                $_COOKIE['ee_registration_added'] = 0;
156
-            }
157
-        }
158
-    }
159
-
160
-
161
-    protected function _init_page_props()
162
-    {
163
-        $this->page_slug = REG_PG_SLUG;
164
-        $this->_admin_base_url = REG_ADMIN_URL;
165
-        $this->_admin_base_path = REG_ADMIN;
166
-        $this->page_label = esc_html__('Registrations', 'event_espresso');
167
-        $this->_cpt_routes = array(
168
-            'add_new_attendee' => 'espresso_attendees',
169
-            'edit_attendee'    => 'espresso_attendees',
170
-            'insert_attendee'  => 'espresso_attendees',
171
-            'update_attendee'  => 'espresso_attendees',
172
-        );
173
-        $this->_cpt_model_names = array(
174
-            'add_new_attendee' => 'EEM_Attendee',
175
-            'edit_attendee'    => 'EEM_Attendee',
176
-        );
177
-        $this->_cpt_edit_routes = array(
178
-            'espresso_attendees' => 'edit_attendee',
179
-        );
180
-        $this->_pagenow_map = array(
181
-            'add_new_attendee' => 'post-new.php',
182
-            'edit_attendee'    => 'post.php',
183
-            'trash'            => 'post.php',
184
-        );
185
-        add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
186
-        // add filters so that the comment urls don't take users to a confusing 404 page
187
-        add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
188
-    }
189
-
190
-
191
-    public function clear_comment_link($link, $comment, $args)
192
-    {
193
-        // gotta make sure this only happens on this route
194
-        $post_type = get_post_type($comment->comment_post_ID);
195
-        if ($post_type === 'espresso_attendees') {
196
-            return '#commentsdiv';
197
-        }
198
-        return $link;
199
-    }
200
-
201
-
202
-    protected function _ajax_hooks()
203
-    {
204
-        // todo: all hooks for registrations ajax goes in here
205
-        add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
206
-    }
207
-
208
-
209
-    protected function _define_page_props()
210
-    {
211
-        $this->_admin_page_title = $this->page_label;
212
-        $this->_labels = array(
213
-            'buttons'                      => array(
214
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
215
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
216
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
217
-                'report'              => esc_html__('Event Registrations CSV Report', 'event_espresso'),
218
-                'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
219
-                'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
220
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
221
-                'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
222
-            ),
223
-            'publishbox'                   => array(
224
-                'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
225
-                'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
226
-            ),
227
-            'hide_add_button_on_cpt_route' => array(
228
-                'edit_attendee' => true,
229
-            ),
230
-        );
231
-    }
232
-
233
-
234
-    /**
235
-     *        grab url requests and route them
236
-     *
237
-     * @access private
238
-     * @return void
239
-     * @throws EE_Error
240
-     */
241
-    public function _set_page_routes()
242
-    {
243
-        $this->_get_registration_status_array();
244
-        $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
245
-            ? $this->_req_data['_REG_ID'] : 0;
246
-        $reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
247
-            ? $this->_req_data['reg_status_change_form']['REG_ID']
248
-            : $reg_id;
249
-        $att_id = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
250
-            ? $this->_req_data['ATT_ID'] : 0;
251
-        $att_id = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
252
-            ? $this->_req_data['post']
253
-            : $att_id;
254
-        $this->_page_routes = array(
255
-            'default'                             => array(
256
-                'func'       => '_registrations_overview_list_table',
257
-                'capability' => 'ee_read_registrations',
258
-            ),
259
-            'view_registration'                   => array(
260
-                'func'       => '_registration_details',
261
-                'capability' => 'ee_read_registration',
262
-                'obj_id'     => $reg_id,
263
-            ),
264
-            'edit_registration'                   => array(
265
-                'func'               => '_update_attendee_registration_form',
266
-                'noheader'           => true,
267
-                'headers_sent_route' => 'view_registration',
268
-                'capability'         => 'ee_edit_registration',
269
-                'obj_id'             => $reg_id,
270
-                '_REG_ID'            => $reg_id,
271
-            ),
272
-            'trash_registrations'                 => array(
273
-                'func'       => '_trash_or_restore_registrations',
274
-                'args'       => array('trash' => true),
275
-                'noheader'   => true,
276
-                'capability' => 'ee_delete_registrations',
277
-            ),
278
-            'restore_registrations'               => array(
279
-                'func'       => '_trash_or_restore_registrations',
280
-                'args'       => array('trash' => false),
281
-                'noheader'   => true,
282
-                'capability' => 'ee_delete_registrations',
283
-            ),
284
-            'delete_registrations'                => array(
285
-                'func'       => '_delete_registrations',
286
-                'noheader'   => true,
287
-                'capability' => 'ee_delete_registrations',
288
-            ),
289
-            'new_registration'                    => array(
290
-                'func'       => 'new_registration',
291
-                'capability' => 'ee_edit_registrations',
292
-            ),
293
-            'process_reg_step'                    => array(
294
-                'func'       => 'process_reg_step',
295
-                'noheader'   => true,
296
-                'capability' => 'ee_edit_registrations',
297
-            ),
298
-            'redirect_to_txn'                     => array(
299
-                'func'       => 'redirect_to_txn',
300
-                'noheader'   => true,
301
-                'capability' => 'ee_edit_registrations',
302
-            ),
303
-            'change_reg_status'                   => array(
304
-                'func'       => '_change_reg_status',
305
-                'noheader'   => true,
306
-                'capability' => 'ee_edit_registration',
307
-                'obj_id'     => $reg_id,
308
-            ),
309
-            'approve_registration'                => array(
310
-                'func'       => 'approve_registration',
311
-                'noheader'   => true,
312
-                'capability' => 'ee_edit_registration',
313
-                'obj_id'     => $reg_id,
314
-            ),
315
-            'approve_and_notify_registration'     => array(
316
-                'func'       => 'approve_registration',
317
-                'noheader'   => true,
318
-                'args'       => array(true),
319
-                'capability' => 'ee_edit_registration',
320
-                'obj_id'     => $reg_id,
321
-            ),
322
-            'approve_registrations'               => array(
323
-                'func'       => 'bulk_action_on_registrations',
324
-                'noheader'   => true,
325
-                'capability' => 'ee_edit_registrations',
326
-                'args'       => array('approve'),
327
-            ),
328
-            'approve_and_notify_registrations'    => array(
329
-                'func'       => 'bulk_action_on_registrations',
330
-                'noheader'   => true,
331
-                'capability' => 'ee_edit_registrations',
332
-                'args'       => array('approve', true),
333
-            ),
334
-            'decline_registration'                => array(
335
-                'func'       => 'decline_registration',
336
-                'noheader'   => true,
337
-                'capability' => 'ee_edit_registration',
338
-                'obj_id'     => $reg_id,
339
-            ),
340
-            'decline_and_notify_registration'     => array(
341
-                'func'       => 'decline_registration',
342
-                'noheader'   => true,
343
-                'args'       => array(true),
344
-                'capability' => 'ee_edit_registration',
345
-                'obj_id'     => $reg_id,
346
-            ),
347
-            'decline_registrations'               => array(
348
-                'func'       => 'bulk_action_on_registrations',
349
-                'noheader'   => true,
350
-                'capability' => 'ee_edit_registrations',
351
-                'args'       => array('decline'),
352
-            ),
353
-            'decline_and_notify_registrations'    => array(
354
-                'func'       => 'bulk_action_on_registrations',
355
-                'noheader'   => true,
356
-                'capability' => 'ee_edit_registrations',
357
-                'args'       => array('decline', true),
358
-            ),
359
-            'pending_registration'                => array(
360
-                'func'       => 'pending_registration',
361
-                'noheader'   => true,
362
-                'capability' => 'ee_edit_registration',
363
-                'obj_id'     => $reg_id,
364
-            ),
365
-            'pending_and_notify_registration'     => array(
366
-                'func'       => 'pending_registration',
367
-                'noheader'   => true,
368
-                'args'       => array(true),
369
-                'capability' => 'ee_edit_registration',
370
-                'obj_id'     => $reg_id,
371
-            ),
372
-            'pending_registrations'               => array(
373
-                'func'       => 'bulk_action_on_registrations',
374
-                'noheader'   => true,
375
-                'capability' => 'ee_edit_registrations',
376
-                'args'       => array('pending'),
377
-            ),
378
-            'pending_and_notify_registrations'    => array(
379
-                'func'       => 'bulk_action_on_registrations',
380
-                'noheader'   => true,
381
-                'capability' => 'ee_edit_registrations',
382
-                'args'       => array('pending', true),
383
-            ),
384
-            'no_approve_registration'             => array(
385
-                'func'       => 'not_approve_registration',
386
-                'noheader'   => true,
387
-                'capability' => 'ee_edit_registration',
388
-                'obj_id'     => $reg_id,
389
-            ),
390
-            'no_approve_and_notify_registration'  => array(
391
-                'func'       => 'not_approve_registration',
392
-                'noheader'   => true,
393
-                'args'       => array(true),
394
-                'capability' => 'ee_edit_registration',
395
-                'obj_id'     => $reg_id,
396
-            ),
397
-            'no_approve_registrations'            => array(
398
-                'func'       => 'bulk_action_on_registrations',
399
-                'noheader'   => true,
400
-                'capability' => 'ee_edit_registrations',
401
-                'args'       => array('not_approve'),
402
-            ),
403
-            'no_approve_and_notify_registrations' => array(
404
-                'func'       => 'bulk_action_on_registrations',
405
-                'noheader'   => true,
406
-                'capability' => 'ee_edit_registrations',
407
-                'args'       => array('not_approve', true),
408
-            ),
409
-            'cancel_registration'                 => array(
410
-                'func'       => 'cancel_registration',
411
-                'noheader'   => true,
412
-                'capability' => 'ee_edit_registration',
413
-                'obj_id'     => $reg_id,
414
-            ),
415
-            'cancel_and_notify_registration'      => array(
416
-                'func'       => 'cancel_registration',
417
-                'noheader'   => true,
418
-                'args'       => array(true),
419
-                'capability' => 'ee_edit_registration',
420
-                'obj_id'     => $reg_id,
421
-            ),
422
-            'cancel_registrations'                => array(
423
-                'func'       => 'bulk_action_on_registrations',
424
-                'noheader'   => true,
425
-                'capability' => 'ee_edit_registrations',
426
-                'args'       => array('cancel'),
427
-            ),
428
-            'cancel_and_notify_registrations'     => array(
429
-                'func'       => 'bulk_action_on_registrations',
430
-                'noheader'   => true,
431
-                'capability' => 'ee_edit_registrations',
432
-                'args'       => array('cancel', true),
433
-            ),
434
-            'wait_list_registration'              => array(
435
-                'func'       => 'wait_list_registration',
436
-                'noheader'   => true,
437
-                'capability' => 'ee_edit_registration',
438
-                'obj_id'     => $reg_id,
439
-            ),
440
-            'wait_list_and_notify_registration'   => array(
441
-                'func'       => 'wait_list_registration',
442
-                'noheader'   => true,
443
-                'args'       => array(true),
444
-                'capability' => 'ee_edit_registration',
445
-                'obj_id'     => $reg_id,
446
-            ),
447
-            'contact_list'                        => array(
448
-                'func'       => '_attendee_contact_list_table',
449
-                'capability' => 'ee_read_contacts',
450
-            ),
451
-            'add_new_attendee'                    => array(
452
-                'func' => '_create_new_cpt_item',
453
-                'args' => array(
454
-                    'new_attendee' => true,
455
-                    'capability'   => 'ee_edit_contacts',
456
-                ),
457
-            ),
458
-            'edit_attendee'                       => array(
459
-                'func'       => '_edit_cpt_item',
460
-                'capability' => 'ee_edit_contacts',
461
-                'obj_id'     => $att_id,
462
-            ),
463
-            'duplicate_attendee'                  => array(
464
-                'func'       => '_duplicate_attendee',
465
-                'noheader'   => true,
466
-                'capability' => 'ee_edit_contacts',
467
-                'obj_id'     => $att_id,
468
-            ),
469
-            'insert_attendee'                     => array(
470
-                'func'       => '_insert_or_update_attendee',
471
-                'args'       => array(
472
-                    'new_attendee' => true,
473
-                ),
474
-                'noheader'   => true,
475
-                'capability' => 'ee_edit_contacts',
476
-            ),
477
-            'update_attendee'                     => array(
478
-                'func'       => '_insert_or_update_attendee',
479
-                'args'       => array(
480
-                    'new_attendee' => false,
481
-                ),
482
-                'noheader'   => true,
483
-                'capability' => 'ee_edit_contacts',
484
-                'obj_id'     => $att_id,
485
-            ),
486
-            'trash_attendees'                     => array(
487
-                'func'       => '_trash_or_restore_attendees',
488
-                'args'       => array(
489
-                    'trash' => 'true',
490
-                ),
491
-                'noheader'   => true,
492
-                'capability' => 'ee_delete_contacts',
493
-            ),
494
-            'trash_attendee'                      => array(
495
-                'func'       => '_trash_or_restore_attendees',
496
-                'args'       => array(
497
-                    'trash' => true,
498
-                ),
499
-                'noheader'   => true,
500
-                'capability' => 'ee_delete_contacts',
501
-                'obj_id'     => $att_id,
502
-            ),
503
-            'restore_attendees'                   => array(
504
-                'func'       => '_trash_or_restore_attendees',
505
-                'args'       => array(
506
-                    'trash' => false,
507
-                ),
508
-                'noheader'   => true,
509
-                'capability' => 'ee_delete_contacts',
510
-                'obj_id'     => $att_id,
511
-            ),
512
-            'resend_registration'                 => array(
513
-                'func'       => '_resend_registration',
514
-                'noheader'   => true,
515
-                'capability' => 'ee_send_message',
516
-            ),
517
-            'registrations_report'                => array(
518
-                'func'       => '_registrations_report',
519
-                'noheader'   => true,
520
-                'capability' => 'ee_read_registrations',
521
-            ),
522
-            'contact_list_export'                 => array(
523
-                'func'       => '_contact_list_export',
524
-                'noheader'   => true,
525
-                'capability' => 'export',
526
-            ),
527
-            'contact_list_report'                 => array(
528
-                'func'       => '_contact_list_report',
529
-                'noheader'   => true,
530
-                'capability' => 'ee_read_contacts',
531
-            ),
532
-        );
533
-    }
534
-
535
-
536
-    protected function _set_page_config()
537
-    {
538
-        $this->_page_config = array(
539
-            'default'           => array(
540
-                'nav'           => array(
541
-                    'label' => esc_html__('Overview', 'event_espresso'),
542
-                    'order' => 5,
543
-                ),
544
-                'help_tabs'     => array(
545
-                    'registrations_overview_help_tab'                       => array(
546
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
547
-                        'filename' => 'registrations_overview',
548
-                    ),
549
-                    'registrations_overview_table_column_headings_help_tab' => array(
550
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
551
-                        'filename' => 'registrations_overview_table_column_headings',
552
-                    ),
553
-                    'registrations_overview_filters_help_tab'               => array(
554
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
555
-                        'filename' => 'registrations_overview_filters',
556
-                    ),
557
-                    'registrations_overview_views_help_tab'                 => array(
558
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
559
-                        'filename' => 'registrations_overview_views',
560
-                    ),
561
-                    'registrations_regoverview_other_help_tab'              => array(
562
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
563
-                        'filename' => 'registrations_overview_other',
564
-                    ),
565
-                ),
566
-                'help_tour'     => array('Registration_Overview_Help_Tour'),
567
-                'qtips'         => array('Registration_List_Table_Tips'),
568
-                'list_table'    => 'EE_Registrations_List_Table',
569
-                'require_nonce' => false,
570
-            ),
571
-            'view_registration' => array(
572
-                'nav'           => array(
573
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
574
-                    'order'      => 15,
575
-                    'url'        => isset($this->_req_data['_REG_ID'])
576
-                        ? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
577
-                        : $this->_admin_base_url,
578
-                    'persistent' => false,
579
-                ),
580
-                'help_tabs'     => array(
581
-                    'registrations_details_help_tab'                    => array(
582
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
583
-                        'filename' => 'registrations_details',
584
-                    ),
585
-                    'registrations_details_table_help_tab'              => array(
586
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
587
-                        'filename' => 'registrations_details_table',
588
-                    ),
589
-                    'registrations_details_form_answers_help_tab'       => array(
590
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
591
-                        'filename' => 'registrations_details_form_answers',
592
-                    ),
593
-                    'registrations_details_registrant_details_help_tab' => array(
594
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
595
-                        'filename' => 'registrations_details_registrant_details',
596
-                    ),
597
-                ),
598
-                'help_tour'     => array('Registration_Details_Help_Tour'),
599
-                'metaboxes'     => array_merge(
600
-                    $this->_default_espresso_metaboxes,
601
-                    array('_registration_details_metaboxes')
602
-                ),
603
-                'require_nonce' => false,
604
-            ),
605
-            'new_registration'  => array(
606
-                'nav'           => array(
607
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
608
-                    'url'        => '#',
609
-                    'order'      => 15,
610
-                    'persistent' => false,
611
-                ),
612
-                'metaboxes'     => $this->_default_espresso_metaboxes,
613
-                'labels'        => array(
614
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
615
-                ),
616
-                'require_nonce' => false,
617
-            ),
618
-            'add_new_attendee'  => array(
619
-                'nav'           => array(
620
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
621
-                    'order'      => 15,
622
-                    'persistent' => false,
623
-                ),
624
-                'metaboxes'     => array_merge(
625
-                    $this->_default_espresso_metaboxes,
626
-                    array('_publish_post_box', 'attendee_editor_metaboxes')
627
-                ),
628
-                'require_nonce' => false,
629
-            ),
630
-            'edit_attendee'     => array(
631
-                'nav'           => array(
632
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
633
-                    'order'      => 15,
634
-                    'persistent' => false,
635
-                    'url'        => isset($this->_req_data['ATT_ID'])
636
-                        ? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
637
-                        : $this->_admin_base_url,
638
-                ),
639
-                'metaboxes'     => array('attendee_editor_metaboxes'),
640
-                'require_nonce' => false,
641
-            ),
642
-            'contact_list'      => array(
643
-                'nav'           => array(
644
-                    'label' => esc_html__('Contact List', 'event_espresso'),
645
-                    'order' => 20,
646
-                ),
647
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
648
-                'help_tabs'     => array(
649
-                    'registrations_contact_list_help_tab'                       => array(
650
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
651
-                        'filename' => 'registrations_contact_list',
652
-                    ),
653
-                    'registrations_contact-list_table_column_headings_help_tab' => array(
654
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
655
-                        'filename' => 'registrations_contact_list_table_column_headings',
656
-                    ),
657
-                    'registrations_contact_list_views_help_tab'                 => array(
658
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
659
-                        'filename' => 'registrations_contact_list_views',
660
-                    ),
661
-                    'registrations_contact_list_other_help_tab'                 => array(
662
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
663
-                        'filename' => 'registrations_contact_list_other',
664
-                    ),
665
-                ),
666
-                'help_tour'     => array('Contact_List_Help_Tour'),
667
-                'metaboxes'     => array(),
668
-                'require_nonce' => false,
669
-            ),
670
-            // override default cpt routes
671
-            'create_new'        => '',
672
-            'edit'              => '',
673
-        );
674
-    }
675
-
676
-
677
-    /**
678
-     * The below methods aren't used by this class currently
679
-     */
680
-    protected function _add_screen_options()
681
-    {
682
-    }
683
-
684
-
685
-    protected function _add_feature_pointers()
686
-    {
687
-    }
688
-
689
-
690
-    public function admin_init()
691
-    {
692
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
693
-            'click "Update Registration Questions" to save your changes',
694
-            'event_espresso'
695
-        );
696
-    }
697
-
698
-
699
-    public function admin_notices()
700
-    {
701
-    }
702
-
703
-
704
-    public function admin_footer_scripts()
705
-    {
706
-    }
707
-
708
-
709
-    /**
710
-     *        get list of registration statuses
711
-     *
712
-     * @access private
713
-     * @return void
714
-     * @throws EE_Error
715
-     */
716
-    private function _get_registration_status_array()
717
-    {
718
-        self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
719
-    }
720
-
721
-
722
-    /**
723
-     * @throws InvalidArgumentException
724
-     * @throws InvalidDataTypeException
725
-     * @throws InvalidInterfaceException
726
-     * @since 4.10.2.p
727
-     */
728
-    protected function _add_screen_options_default()
729
-    {
730
-        $this->_per_page_screen_option();
731
-    }
732
-
733
-
734
-    /**
735
-     * @throws InvalidArgumentException
736
-     * @throws InvalidDataTypeException
737
-     * @throws InvalidInterfaceException
738
-     * @since 4.10.2.p
739
-     */
740
-    protected function _add_screen_options_contact_list()
741
-    {
742
-        $page_title = $this->_admin_page_title;
743
-        $this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
744
-        $this->_per_page_screen_option();
745
-        $this->_admin_page_title = $page_title;
746
-    }
747
-
748
-
749
-    public function load_scripts_styles()
750
-    {
751
-        // style
752
-        wp_register_style(
753
-            'espresso_reg',
754
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
755
-            array('ee-admin-css'),
756
-            EVENT_ESPRESSO_VERSION
757
-        );
758
-        wp_enqueue_style('espresso_reg');
759
-        // script
760
-        wp_register_script(
761
-            'espresso_reg',
762
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
763
-            array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
764
-            EVENT_ESPRESSO_VERSION,
765
-            true
766
-        );
767
-        wp_enqueue_script('espresso_reg');
768
-    }
769
-
770
-
771
-    /**
772
-     * @throws EE_Error
773
-     * @throws InvalidArgumentException
774
-     * @throws InvalidDataTypeException
775
-     * @throws InvalidInterfaceException
776
-     * @throws ReflectionException
777
-     * @since 4.10.2.p
778
-     */
779
-    public function load_scripts_styles_edit_attendee()
780
-    {
781
-        // stuff to only show up on our attendee edit details page.
782
-        $attendee_details_translations = array(
783
-            'att_publish_text' => sprintf(
784
-                /* translators: The date and time */
785
-                wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
786
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
787
-            ),
788
-        );
789
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
790
-        wp_enqueue_script('jquery-validate');
791
-    }
792
-
793
-
794
-    /**
795
-     * @throws EE_Error
796
-     * @throws InvalidArgumentException
797
-     * @throws InvalidDataTypeException
798
-     * @throws InvalidInterfaceException
799
-     * @throws ReflectionException
800
-     * @since 4.10.2.p
801
-     */
802
-    public function load_scripts_styles_view_registration()
803
-    {
804
-        // styles
805
-        wp_enqueue_style('espresso-ui-theme');
806
-        // scripts
807
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
808
-        $this->_reg_custom_questions_form->wp_enqueue_scripts(true);
809
-    }
810
-
811
-
812
-    public function load_scripts_styles_contact_list()
813
-    {
814
-        wp_dequeue_style('espresso_reg');
815
-        wp_register_style(
816
-            'espresso_att',
817
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
818
-            array('ee-admin-css'),
819
-            EVENT_ESPRESSO_VERSION
820
-        );
821
-        wp_enqueue_style('espresso_att');
822
-    }
823
-
824
-
825
-    public function load_scripts_styles_new_registration()
826
-    {
827
-        wp_register_script(
828
-            'ee-spco-for-admin',
829
-            REG_ASSETS_URL . 'spco_for_admin.js',
830
-            array('underscore', 'jquery'),
831
-            EVENT_ESPRESSO_VERSION,
832
-            true
833
-        );
834
-        wp_enqueue_script('ee-spco-for-admin');
835
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
836
-        EE_Form_Section_Proper::wp_enqueue_scripts();
837
-        EED_Ticket_Selector::load_tckt_slctr_assets();
838
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
839
-    }
840
-
841
-
842
-    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
843
-    {
844
-        add_filter('FHEE_load_EE_messages', '__return_true');
845
-    }
846
-
847
-
848
-    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
849
-    {
850
-        add_filter('FHEE_load_EE_messages', '__return_true');
851
-    }
852
-
853
-
854
-    /**
855
-     * @throws EE_Error
856
-     * @throws InvalidArgumentException
857
-     * @throws InvalidDataTypeException
858
-     * @throws InvalidInterfaceException
859
-     * @throws ReflectionException
860
-     * @since 4.10.2.p
861
-     */
862
-    protected function _set_list_table_views_default()
863
-    {
864
-        // for notification related bulk actions we need to make sure only active messengers have an option.
865
-        EED_Messages::set_autoloaders();
866
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
867
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
868
-        $active_mts = $message_resource_manager->list_of_active_message_types();
869
-        // key= bulk_action_slug, value= message type.
870
-        $match_array = array(
871
-            'approve_registrations'    => 'registration',
872
-            'decline_registrations'    => 'declined_registration',
873
-            'pending_registrations'    => 'pending_approval',
874
-            'no_approve_registrations' => 'not_approved_registration',
875
-            'cancel_registrations'     => 'cancelled_registration',
876
-        );
877
-        $can_send = EE_Registry::instance()->CAP->current_user_can(
878
-            'ee_send_message',
879
-            'batch_send_messages'
880
-        );
881
-        /** setup reg status bulk actions **/
882
-        $def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
883
-        if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
884
-            $def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
885
-                'Approve and Notify Registrations',
886
-                'event_espresso'
887
-            );
888
-        }
889
-        $def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
890
-        if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
891
-            $def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
892
-                'Decline and Notify Registrations',
893
-                'event_espresso'
894
-            );
895
-        }
896
-        $def_reg_status_actions['pending_registrations'] = esc_html__(
897
-            'Set Registrations to Pending Payment',
898
-            'event_espresso'
899
-        );
900
-        if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
901
-            $def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
902
-                'Set Registrations to Pending Payment and Notify',
903
-                'event_espresso'
904
-            );
905
-        }
906
-        $def_reg_status_actions['no_approve_registrations'] = esc_html__(
907
-            'Set Registrations to Not Approved',
908
-            'event_espresso'
909
-        );
910
-        if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
911
-            $def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
912
-                'Set Registrations to Not Approved and Notify',
913
-                'event_espresso'
914
-            );
915
-        }
916
-        $def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
917
-        if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
918
-            $def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
919
-                'Cancel Registrations and Notify',
920
-                'event_espresso'
921
-            );
922
-        }
923
-        $def_reg_status_actions = apply_filters(
924
-            'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
925
-            $def_reg_status_actions,
926
-            $active_mts,
927
-            $can_send
928
-        );
929
-
930
-        $this->_views = array(
931
-            'all'   => array(
932
-                'slug'        => 'all',
933
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
934
-                'count'       => 0,
935
-                'bulk_action' => array_merge(
936
-                    $def_reg_status_actions,
937
-                    array(
938
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
939
-                    )
940
-                ),
941
-            ),
942
-            'month' => array(
943
-                'slug'        => 'month',
944
-                'label'       => esc_html__('This Month', 'event_espresso'),
945
-                'count'       => 0,
946
-                'bulk_action' => array_merge(
947
-                    $def_reg_status_actions,
948
-                    array(
949
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
950
-                    )
951
-                ),
952
-            ),
953
-            'today' => array(
954
-                'slug'        => 'today',
955
-                'label'       => sprintf(
956
-                    esc_html__('Today - %s', 'event_espresso'),
957
-                    date('M d, Y', current_time('timestamp'))
958
-                ),
959
-                'count'       => 0,
960
-                'bulk_action' => array_merge(
961
-                    $def_reg_status_actions,
962
-                    array(
963
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
964
-                    )
965
-                ),
966
-            ),
967
-        );
968
-        if (EE_Registry::instance()->CAP->current_user_can(
969
-            'ee_delete_registrations',
970
-            'espresso_registrations_delete_registration'
971
-        )) {
972
-            $this->_views['incomplete'] = array(
973
-                'slug'        => 'incomplete',
974
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
975
-                'count'       => 0,
976
-                'bulk_action' => array(
977
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
978
-                ),
979
-            );
980
-            $this->_views['trash'] = array(
981
-                'slug'        => 'trash',
982
-                'label'       => esc_html__('Trash', 'event_espresso'),
983
-                'count'       => 0,
984
-                'bulk_action' => array(
985
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
986
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
987
-                ),
988
-            );
989
-        }
990
-    }
991
-
992
-
993
-    protected function _set_list_table_views_contact_list()
994
-    {
995
-        $this->_views = array(
996
-            'in_use' => array(
997
-                'slug'        => 'in_use',
998
-                'label'       => esc_html__('In Use', 'event_espresso'),
999
-                'count'       => 0,
1000
-                'bulk_action' => array(
1001
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1002
-                ),
1003
-            ),
1004
-        );
1005
-        if (EE_Registry::instance()->CAP->current_user_can(
1006
-            'ee_delete_contacts',
1007
-            'espresso_registrations_trash_attendees'
1008
-        )
1009
-        ) {
1010
-            $this->_views['trash'] = array(
1011
-                'slug'        => 'trash',
1012
-                'label'       => esc_html__('Trash', 'event_espresso'),
1013
-                'count'       => 0,
1014
-                'bulk_action' => array(
1015
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1016
-                ),
1017
-            );
1018
-        }
1019
-    }
1020
-
1021
-
1022
-    protected function _registration_legend_items()
1023
-    {
1024
-        $fc_items = array(
1025
-            'star-icon'        => array(
1026
-                'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
1027
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1028
-            ),
1029
-            'view_details'     => array(
1030
-                'class' => 'dashicons dashicons-clipboard',
1031
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1032
-            ),
1033
-            'edit_attendee'    => array(
1034
-                'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
1035
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1036
-            ),
1037
-            'view_transaction' => array(
1038
-                'class' => 'dashicons dashicons-cart',
1039
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1040
-            ),
1041
-            'view_invoice'     => array(
1042
-                'class' => 'dashicons dashicons-media-spreadsheet',
1043
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1044
-            ),
1045
-        );
1046
-        if (EE_Registry::instance()->CAP->current_user_can(
1047
-            'ee_send_message',
1048
-            'espresso_registrations_resend_registration'
1049
-        )) {
1050
-            $fc_items['resend_registration'] = array(
1051
-                'class' => 'dashicons dashicons-email-alt',
1052
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1053
-            );
1054
-        } else {
1055
-            $fc_items['blank'] = array('class' => 'blank', 'desc' => '');
1056
-        }
1057
-        if (EE_Registry::instance()->CAP->current_user_can(
1058
-            'ee_read_global_messages',
1059
-            'view_filtered_messages'
1060
-        )) {
1061
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1062
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1063
-                $fc_items['view_related_messages'] = array(
1064
-                    'class' => $related_for_icon['css_class'],
1065
-                    'desc'  => $related_for_icon['label'],
1066
-                );
1067
-            }
1068
-        }
1069
-        $sc_items = array(
1070
-            'approved_status'   => array(
1071
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
1072
-                'desc'  => EEH_Template::pretty_status(
1073
-                    EEM_Registration::status_id_approved,
1074
-                    false,
1075
-                    'sentence'
1076
-                ),
1077
-            ),
1078
-            'pending_status'    => array(
1079
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
1080
-                'desc'  => EEH_Template::pretty_status(
1081
-                    EEM_Registration::status_id_pending_payment,
1082
-                    false,
1083
-                    'sentence'
1084
-                ),
1085
-            ),
1086
-            'wait_list'         => array(
1087
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
1088
-                'desc'  => EEH_Template::pretty_status(
1089
-                    EEM_Registration::status_id_wait_list,
1090
-                    false,
1091
-                    'sentence'
1092
-                ),
1093
-            ),
1094
-            'incomplete_status' => array(
1095
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
1096
-                'desc'  => EEH_Template::pretty_status(
1097
-                    EEM_Registration::status_id_incomplete,
1098
-                    false,
1099
-                    'sentence'
1100
-                ),
1101
-            ),
1102
-            'not_approved'      => array(
1103
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
1104
-                'desc'  => EEH_Template::pretty_status(
1105
-                    EEM_Registration::status_id_not_approved,
1106
-                    false,
1107
-                    'sentence'
1108
-                ),
1109
-            ),
1110
-            'declined_status'   => array(
1111
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
1112
-                'desc'  => EEH_Template::pretty_status(
1113
-                    EEM_Registration::status_id_declined,
1114
-                    false,
1115
-                    'sentence'
1116
-                ),
1117
-            ),
1118
-            'cancelled_status'  => array(
1119
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1120
-                'desc'  => EEH_Template::pretty_status(
1121
-                    EEM_Registration::status_id_cancelled,
1122
-                    false,
1123
-                    'sentence'
1124
-                ),
1125
-            ),
1126
-        );
1127
-        return array_merge($fc_items, $sc_items);
1128
-    }
1129
-
1130
-
1131
-
1132
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
1133
-
1134
-
1135
-
1136
-    /**
1137
-     * @throws DomainException
1138
-     * @throws EE_Error
1139
-     * @throws InvalidArgumentException
1140
-     * @throws InvalidDataTypeException
1141
-     * @throws InvalidInterfaceException
1142
-     * @throws ReflectionException
1143
-     */
1144
-    protected function _registrations_overview_list_table()
1145
-    {
1146
-        $this->appendAddNewRegistrationButtonToPageTitle();
1147
-        $header_text = '';
1148
-        $admin_page_header_decorators = [
1149
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1150
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1151
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1152
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1153
-        ];
1154
-        foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1155
-            $filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1156
-            $header_text = $filter_header_decorator->getHeaderText($header_text);
1157
-        }
1158
-        $this->_template_args['admin_page_header'] = $header_text;
1159
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1160
-        $this->display_admin_list_table_page_with_no_sidebar();
1161
-    }
1162
-
1163
-
1164
-    /**
1165
-     * @throws EE_Error
1166
-     * @throws InvalidArgumentException
1167
-     * @throws InvalidDataTypeException
1168
-     * @throws InvalidInterfaceException
1169
-     */
1170
-    private function appendAddNewRegistrationButtonToPageTitle()
1171
-    {
1172
-        $EVT_ID = ! empty($this->_req_data['event_id'])
1173
-            ? absint($this->_req_data['event_id'])
1174
-            : 0;
1175
-        if ($EVT_ID
1176
-            && EE_Registry::instance()->CAP->current_user_can(
1177
-                'ee_edit_registrations',
1178
-                'espresso_registrations_new_registration',
1179
-                $EVT_ID
1180
-            )
1181
-        ) {
1182
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1183
-                'new_registration',
1184
-                'add-registrant',
1185
-                array('event_id' => $EVT_ID),
1186
-                'add-new-h2'
1187
-            );
1188
-        }
1189
-    }
1190
-
1191
-
1192
-    /**
1193
-     * This sets the _registration property for the registration details screen
1194
-     *
1195
-     * @access private
1196
-     * @return bool
1197
-     * @throws EE_Error
1198
-     * @throws InvalidArgumentException
1199
-     * @throws InvalidDataTypeException
1200
-     * @throws InvalidInterfaceException
1201
-     */
1202
-    private function _set_registration_object()
1203
-    {
1204
-        // get out if we've already set the object
1205
-        if ($this->_registration instanceof EE_Registration) {
1206
-            return true;
1207
-        }
1208
-        $REG_ID = (! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1209
-        if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1210
-            return true;
1211
-        }
1212
-        $error_msg = sprintf(
1213
-            esc_html__(
1214
-                'An error occurred and the details for Registration ID #%s could not be retrieved.',
1215
-                'event_espresso'
1216
-            ),
1217
-            $REG_ID
1218
-        );
1219
-        EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1220
-        $this->_registration = null;
1221
-        return false;
1222
-    }
1223
-
1224
-
1225
-    /**
1226
-     * Used to retrieve registrations for the list table.
1227
-     *
1228
-     * @param int  $per_page
1229
-     * @param bool $count
1230
-     * @param bool $this_month
1231
-     * @param bool $today
1232
-     * @return EE_Registration[]|int
1233
-     * @throws EE_Error
1234
-     * @throws InvalidArgumentException
1235
-     * @throws InvalidDataTypeException
1236
-     * @throws InvalidInterfaceException
1237
-     */
1238
-    public function get_registrations(
1239
-        $per_page = 10,
1240
-        $count = false,
1241
-        $this_month = false,
1242
-        $today = false
1243
-    ) {
1244
-        if ($this_month) {
1245
-            $this->_req_data['status'] = 'month';
1246
-        }
1247
-        if ($today) {
1248
-            $this->_req_data['status'] = 'today';
1249
-        }
1250
-        $query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1251
-        /**
1252
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1253
-         *
1254
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1255
-         * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1256
-         *                             or if you have the development copy of EE you can view this at the path:
1257
-         *                             /docs/G--Model-System/model-query-params.md
1258
-         */
1259
-        $query_params['group_by'] = '';
1260
-
1261
-        return $count
1262
-            ? $this->getRegistrationModel()->count($query_params)
1263
-            /** @type EE_Registration[] */
1264
-            : $this->getRegistrationModel()->get_all($query_params);
1265
-    }
1266
-
1267
-
1268
-    /**
1269
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1270
-     * Note: this listens to values on the request for some of the query parameters.
1271
-     *
1272
-     * @param array $request
1273
-     * @param int   $per_page
1274
-     * @param bool  $count
1275
-     * @return array
1276
-     * @throws EE_Error
1277
-     * @throws InvalidArgumentException
1278
-     * @throws InvalidDataTypeException
1279
-     * @throws InvalidInterfaceException
1280
-     */
1281
-    protected function _get_registration_query_parameters(
1282
-        $request = array(),
1283
-        $per_page = 10,
1284
-        $count = false
1285
-    ) {
1286
-        /** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1287
-        $list_table_query_builder = $this->loader->getNew(
1288
-            'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1289
-            [ $request ]
1290
-        );
1291
-        return $list_table_query_builder->getQueryParams($per_page, $count);
1292
-    }
1293
-
1294
-
1295
-    public function get_registration_status_array()
1296
-    {
1297
-        return self::$_reg_status;
1298
-    }
1299
-
1300
-
1301
-
1302
-
1303
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1304
-    /**
1305
-     *        generates HTML for the View Registration Details Admin page
1306
-     *
1307
-     * @access protected
1308
-     * @return void
1309
-     * @throws DomainException
1310
-     * @throws EE_Error
1311
-     * @throws InvalidArgumentException
1312
-     * @throws InvalidDataTypeException
1313
-     * @throws InvalidInterfaceException
1314
-     * @throws EntityNotFoundException
1315
-     * @throws ReflectionException
1316
-     */
1317
-    protected function _registration_details()
1318
-    {
1319
-        $this->_template_args = array();
1320
-        $this->_set_registration_object();
1321
-        if (is_object($this->_registration)) {
1322
-            $transaction = $this->_registration->transaction()
1323
-                ? $this->_registration->transaction()
1324
-                : EE_Transaction::new_instance();
1325
-            $this->_session = $transaction->session_data();
1326
-            $event_id = $this->_registration->event_ID();
1327
-            $this->_template_args['reg_nmbr']['value'] = $this->_registration->ID();
1328
-            $this->_template_args['reg_nmbr']['label'] = esc_html__('Registration Number', 'event_espresso');
1329
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1330
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1331
-            $this->_template_args['grand_total'] = $transaction->total();
1332
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
1333
-            // link back to overview
1334
-            $this->_template_args['reg_overview_url'] = REG_ADMIN_URL;
1335
-            $this->_template_args['registration'] = $this->_registration;
1336
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1337
-                array(
1338
-                    'action'   => 'default',
1339
-                    'event_id' => $event_id,
1340
-                ),
1341
-                REG_ADMIN_URL
1342
-            );
1343
-            $this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1344
-                array(
1345
-                    'action' => 'default',
1346
-                    'EVT_ID' => $event_id,
1347
-                    'page'   => 'espresso_transactions',
1348
-                ),
1349
-                admin_url('admin.php')
1350
-            );
1351
-            $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1352
-                array(
1353
-                    'page'   => 'espresso_events',
1354
-                    'action' => 'edit',
1355
-                    'post'   => $event_id,
1356
-                ),
1357
-                admin_url('admin.php')
1358
-            );
1359
-            // next and previous links
1360
-            $next_reg = $this->_registration->next(
1361
-                null,
1362
-                array(),
1363
-                'REG_ID'
1364
-            );
1365
-            $this->_template_args['next_registration'] = $next_reg
1366
-                ? $this->_next_link(
1367
-                    EE_Admin_Page::add_query_args_and_nonce(
1368
-                        array(
1369
-                            'action'  => 'view_registration',
1370
-                            '_REG_ID' => $next_reg['REG_ID'],
1371
-                        ),
1372
-                        REG_ADMIN_URL
1373
-                    ),
1374
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1375
-                )
1376
-                : '';
1377
-            $previous_reg = $this->_registration->previous(
1378
-                null,
1379
-                array(),
1380
-                'REG_ID'
1381
-            );
1382
-            $this->_template_args['previous_registration'] = $previous_reg
1383
-                ? $this->_previous_link(
1384
-                    EE_Admin_Page::add_query_args_and_nonce(
1385
-                        array(
1386
-                            'action'  => 'view_registration',
1387
-                            '_REG_ID' => $previous_reg['REG_ID'],
1388
-                        ),
1389
-                        REG_ADMIN_URL
1390
-                    ),
1391
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1392
-                )
1393
-                : '';
1394
-            // grab header
1395
-            $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1396
-            $this->_template_args['REG_ID'] = $this->_registration->ID();
1397
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1398
-                $template_path,
1399
-                $this->_template_args,
1400
-                true
1401
-            );
1402
-        } else {
1403
-            $this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1404
-        }
1405
-        // the details template wrapper
1406
-        $this->display_admin_page_with_sidebar();
1407
-    }
1408
-
1409
-
1410
-    /**
1411
-     * @throws EE_Error
1412
-     * @throws InvalidArgumentException
1413
-     * @throws InvalidDataTypeException
1414
-     * @throws InvalidInterfaceException
1415
-     * @throws ReflectionException
1416
-     * @since 4.10.2.p
1417
-     */
1418
-    protected function _registration_details_metaboxes()
1419
-    {
1420
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1421
-        $this->_set_registration_object();
1422
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1423
-        add_meta_box(
1424
-            'edit-reg-status-mbox',
1425
-            esc_html__('Registration Status', 'event_espresso'),
1426
-            array($this, 'set_reg_status_buttons_metabox'),
1427
-            $this->wp_page_slug,
1428
-            'normal',
1429
-            'high'
1430
-        );
1431
-        add_meta_box(
1432
-            'edit-reg-details-mbox',
1433
-            esc_html__('Registration Details', 'event_espresso'),
1434
-            array($this, '_reg_details_meta_box'),
1435
-            $this->wp_page_slug,
1436
-            'normal',
1437
-            'high'
1438
-        );
1439
-        if ($attendee instanceof EE_Attendee
1440
-            && EE_Registry::instance()->CAP->current_user_can(
1441
-                'ee_read_registration',
1442
-                'edit-reg-questions-mbox',
1443
-                $this->_registration->ID()
1444
-            )
1445
-        ) {
1446
-            add_meta_box(
1447
-                'edit-reg-questions-mbox',
1448
-                esc_html__('Registration Form Answers', 'event_espresso'),
1449
-                array($this, '_reg_questions_meta_box'),
1450
-                $this->wp_page_slug,
1451
-                'normal',
1452
-                'high'
1453
-            );
1454
-        }
1455
-        add_meta_box(
1456
-            'edit-reg-registrant-mbox',
1457
-            esc_html__('Contact Details', 'event_espresso'),
1458
-            array($this, '_reg_registrant_side_meta_box'),
1459
-            $this->wp_page_slug,
1460
-            'side',
1461
-            'high'
1462
-        );
1463
-        if ($this->_registration->group_size() > 1) {
1464
-            add_meta_box(
1465
-                'edit-reg-attendees-mbox',
1466
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1467
-                array($this, '_reg_attendees_meta_box'),
1468
-                $this->wp_page_slug,
1469
-                'normal',
1470
-                'high'
1471
-            );
1472
-        }
1473
-    }
1474
-
1475
-
1476
-    /**
1477
-     * set_reg_status_buttons_metabox
1478
-     *
1479
-     * @access protected
1480
-     * @return string
1481
-     * @throws EE_Error
1482
-     * @throws EntityNotFoundException
1483
-     * @throws InvalidArgumentException
1484
-     * @throws InvalidDataTypeException
1485
-     * @throws InvalidInterfaceException
1486
-     * @throws ReflectionException
1487
-     */
1488
-    public function set_reg_status_buttons_metabox()
1489
-    {
1490
-        $this->_set_registration_object();
1491
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1492
-        echo $change_reg_status_form->form_open(
1493
-            self::add_query_args_and_nonce(
1494
-                array(
1495
-                    'action' => 'change_reg_status',
1496
-                ),
1497
-                REG_ADMIN_URL
1498
-            )
1499
-        );
1500
-        echo $change_reg_status_form->get_html();
1501
-        echo $change_reg_status_form->form_close();
1502
-    }
1503
-
1504
-
1505
-    /**
1506
-     * @return EE_Form_Section_Proper
1507
-     * @throws EE_Error
1508
-     * @throws InvalidArgumentException
1509
-     * @throws InvalidDataTypeException
1510
-     * @throws InvalidInterfaceException
1511
-     * @throws EntityNotFoundException
1512
-     * @throws ReflectionException
1513
-     */
1514
-    protected function _generate_reg_status_change_form()
1515
-    {
1516
-        $reg_status_change_form_array = array(
1517
-            'name'            => 'reg_status_change_form',
1518
-            'html_id'         => 'reg-status-change-form',
1519
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1520
-            'subsections'     => array(
1521
-                'return'             => new EE_Hidden_Input(
1522
-                    array(
1523
-                        'name'    => 'return',
1524
-                        'default' => 'view_registration',
1525
-                    )
1526
-                ),
1527
-                'REG_ID'             => new EE_Hidden_Input(
1528
-                    array(
1529
-                        'name'    => 'REG_ID',
1530
-                        'default' => $this->_registration->ID(),
1531
-                    )
1532
-                ),
1533
-                'current_status'     => new EE_Form_Section_HTML(
1534
-                    EEH_HTML::table(
1535
-                        EEH_HTML::tr(
1536
-                            EEH_HTML::th(
1537
-                                EEH_HTML::label(
1538
-                                    EEH_HTML::strong(
1539
-                                        esc_html__('Current Registration Status', 'event_espresso')
1540
-                                    )
1541
-                                )
1542
-                            )
1543
-                            . EEH_HTML::td(
1544
-                                EEH_HTML::strong(
1545
-                                    $this->_registration->pretty_status(),
1546
-                                    '',
1547
-                                    'status-' . $this->_registration->status_ID(),
1548
-                                    'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1549
-                                )
1550
-                            )
1551
-                        )
1552
-                    )
1553
-                )
1554
-            )
1555
-        );
1556
-        if (EE_Registry::instance()->CAP->current_user_can(
1557
-            'ee_edit_registration',
1558
-            'toggle_registration_status',
1559
-            $this->_registration->ID()
1560
-        )) {
1561
-            $reg_status_change_form_array['subsections']['reg_status'] = new EE_Select_Input(
1562
-                $this->_get_reg_statuses(),
1563
-                array(
1564
-                    'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1565
-                    'default'         => $this->_registration->status_ID(),
1566
-                )
1567
-            );
1568
-            $reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1569
-                array(
1570
-                    'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1571
-                    'default'         => false,
1572
-                    'html_help_text'  => esc_html__(
1573
-                        'If set to "Yes", then the related messages will be sent to the registrant.',
1574
-                        'event_espresso'
1575
-                    )
1576
-                )
1577
-            );
1578
-            $reg_status_change_form_array['subsections']['submit'] = new EE_Submit_Input(
1579
-                array(
1580
-                    'html_class'      => 'button-primary',
1581
-                    'html_label_text' => '&nbsp;',
1582
-                    'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1583
-                )
1584
-            );
1585
-        }
1586
-        return new EE_Form_Section_Proper($reg_status_change_form_array);
1587
-    }
1588
-
1589
-
1590
-    /**
1591
-     * Returns an array of all the buttons for the various statuses and switch status actions
1592
-     *
1593
-     * @return array
1594
-     * @throws EE_Error
1595
-     * @throws InvalidArgumentException
1596
-     * @throws InvalidDataTypeException
1597
-     * @throws InvalidInterfaceException
1598
-     * @throws EntityNotFoundException
1599
-     */
1600
-    protected function _get_reg_statuses()
1601
-    {
1602
-        $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1603
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1604
-        // get current reg status
1605
-        $current_status = $this->_registration->status_ID();
1606
-        // is registration for free event? This will determine whether to display the pending payment option
1607
-        if ($current_status !== EEM_Registration::status_id_pending_payment
1608
-            && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1609
-        ) {
1610
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1611
-        }
1612
-        return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1613
-    }
1614
-
1615
-
1616
-    /**
1617
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1618
-     *
1619
-     * @param bool $status REG status given for changing registrations to.
1620
-     * @param bool $notify Whether to send messages notifications or not.
1621
-     * @return array (array with reg_id(s) updated and whether update was successful.
1622
-     * @throws DomainException
1623
-     * @throws EE_Error
1624
-     * @throws EntityNotFoundException
1625
-     * @throws InvalidArgumentException
1626
-     * @throws InvalidDataTypeException
1627
-     * @throws InvalidInterfaceException
1628
-     * @throws ReflectionException
1629
-     * @throws RuntimeException
1630
-     */
1631
-    protected function _set_registration_status_from_request($status = false, $notify = false)
1632
-    {
1633
-        if (isset($this->_req_data['reg_status_change_form'])) {
1634
-            $REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1635
-                ? (array) $this->_req_data['reg_status_change_form']['REG_ID']
1636
-                : array();
1637
-        } else {
1638
-            $REG_IDs = isset($this->_req_data['_REG_ID'])
1639
-                ? (array) $this->_req_data['_REG_ID']
1640
-                : array();
1641
-        }
1642
-        // sanitize $REG_IDs
1643
-        $REG_IDs = array_map('absint', $REG_IDs);
1644
-        // and remove empty entries
1645
-        $REG_IDs = array_filter($REG_IDs);
1646
-
1647
-        $result = $this->_set_registration_status($REG_IDs, $status, $notify);
1648
-
1649
-        /**
1650
-         * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1651
-         * Currently this value is used downstream by the _process_resend_registration method.
1652
-         *
1653
-         * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1654
-         * @param bool                     $status           The status registrations were changed to.
1655
-         * @param bool                     $success          If the status was changed successfully for all registrations.
1656
-         * @param Registrations_Admin_Page $admin_page_object
1657
-         */
1658
-        $this->_req_data['_REG_ID'] = apply_filters(
1659
-            'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1660
-            $result['REG_ID'],
1661
-            $status,
1662
-            $result['success'],
1663
-            $this
1664
-        );
1665
-
1666
-        // notify?
1667
-        if ($notify
1668
-            && $result['success']
1669
-            && ! empty($this->_req_data['_REG_ID'])
1670
-            && EE_Registry::instance()->CAP->current_user_can(
1671
-                'ee_send_message',
1672
-                'espresso_registrations_resend_registration'
1673
-            )
1674
-        ) {
1675
-            $this->_process_resend_registration();
1676
-        }
1677
-        return $result;
1678
-    }
1679
-
1680
-
1681
-    /**
1682
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1683
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1684
-     *
1685
-     * @param array  $REG_IDs
1686
-     * @param string $status
1687
-     * @param bool   $notify  Used to indicate whether notification was requested or not.  This determines the context
1688
-     *                        slug sent with setting the registration status.
1689
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1690
-     * @throws EE_Error
1691
-     * @throws InvalidArgumentException
1692
-     * @throws InvalidDataTypeException
1693
-     * @throws InvalidInterfaceException
1694
-     * @throws ReflectionException
1695
-     * @throws RuntimeException
1696
-     * @throws EntityNotFoundException
1697
-     * @throws DomainException
1698
-     */
1699
-    protected function _set_registration_status($REG_IDs = array(), $status = '', $notify = false)
1700
-    {
1701
-        $success = false;
1702
-        // typecast $REG_IDs
1703
-        $REG_IDs = (array) $REG_IDs;
1704
-        if (! empty($REG_IDs)) {
1705
-            $success = true;
1706
-            // set default status if none is passed
1707
-            $status = $status ? $status : EEM_Registration::status_id_pending_payment;
1708
-            $status_context = $notify
1709
-                ? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1710
-                : Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1711
-            // loop through REG_ID's and change status
1712
-            foreach ($REG_IDs as $REG_ID) {
1713
-                $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1714
-                if ($registration instanceof EE_Registration) {
1715
-                    $registration->set_status(
1716
-                        $status,
1717
-                        false,
1718
-                        new Context(
1719
-                            $status_context,
1720
-                            esc_html__(
1721
-                                'Manually triggered status change on a Registration Admin Page route.',
1722
-                                'event_espresso'
1723
-                            )
1724
-                        )
1725
-                    );
1726
-                    $result = $registration->save();
1727
-                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1728
-                    $success = $result !== false ? $success : false;
1729
-                }
1730
-            }
1731
-        }
1732
-
1733
-        // return $success and processed registrations
1734
-        return array('REG_ID' => $REG_IDs, 'success' => $success);
1735
-    }
1736
-
1737
-
1738
-    /**
1739
-     * Common logic for setting up success message and redirecting to appropriate route
1740
-     *
1741
-     * @param string $STS_ID status id for the registration changed to
1742
-     * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1743
-     * @return void
1744
-     * @throws DomainException
1745
-     * @throws EE_Error
1746
-     * @throws EntityNotFoundException
1747
-     * @throws InvalidArgumentException
1748
-     * @throws InvalidDataTypeException
1749
-     * @throws InvalidInterfaceException
1750
-     * @throws ReflectionException
1751
-     * @throws RuntimeException
1752
-     */
1753
-    protected function _reg_status_change_return($STS_ID, $notify = false)
1754
-    {
1755
-        $result = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1756
-            : array('success' => false);
1757
-        $success = isset($result['success']) && $result['success'];
1758
-        // setup success message
1759
-        if ($success) {
1760
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1761
-                $msg = sprintf(
1762
-                    esc_html__('Registration status has been set to %s', 'event_espresso'),
1763
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1764
-                );
1765
-            } else {
1766
-                $msg = sprintf(
1767
-                    esc_html__('Registrations have been set to %s.', 'event_espresso'),
1768
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1769
-                );
1770
-            }
1771
-            EE_Error::add_success($msg);
1772
-        } else {
1773
-            EE_Error::add_error(
1774
-                esc_html__(
1775
-                    'Something went wrong, and the status was not changed',
1776
-                    'event_espresso'
1777
-                ),
1778
-                __FILE__,
1779
-                __LINE__,
1780
-                __FUNCTION__
1781
-            );
1782
-        }
1783
-        if (isset($this->_req_data['return']) && $this->_req_data['return'] === 'view_registration') {
1784
-            $route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1785
-        } else {
1786
-            $route = array('action' => 'default');
1787
-        }
1788
-        $route = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1789
-        $this->_redirect_after_action($success, '', '', $route, true);
1790
-    }
1791
-
1792
-
1793
-    /**
1794
-     * incoming reg status change from reg details page.
1795
-     *
1796
-     * @return void
1797
-     * @throws EE_Error
1798
-     * @throws EntityNotFoundException
1799
-     * @throws InvalidArgumentException
1800
-     * @throws InvalidDataTypeException
1801
-     * @throws InvalidInterfaceException
1802
-     * @throws ReflectionException
1803
-     * @throws RuntimeException
1804
-     * @throws DomainException
1805
-     */
1806
-    protected function _change_reg_status()
1807
-    {
1808
-        $this->_req_data['return'] = 'view_registration';
1809
-        // set notify based on whether the send notifications toggle is set or not
1810
-        $notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1811
-        // $notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1812
-        $this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1813
-            ? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1814
-        switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1815
-            case EEM_Registration::status_id_approved:
1816
-            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1817
-                $this->approve_registration($notify);
1818
-                break;
1819
-            case EEM_Registration::status_id_pending_payment:
1820
-            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1821
-                $this->pending_registration($notify);
1822
-                break;
1823
-            case EEM_Registration::status_id_not_approved:
1824
-            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1825
-                $this->not_approve_registration($notify);
1826
-                break;
1827
-            case EEM_Registration::status_id_declined:
1828
-            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1829
-                $this->decline_registration($notify);
1830
-                break;
1831
-            case EEM_Registration::status_id_cancelled:
1832
-            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1833
-                $this->cancel_registration($notify);
1834
-                break;
1835
-            case EEM_Registration::status_id_wait_list:
1836
-            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1837
-                $this->wait_list_registration($notify);
1838
-                break;
1839
-            case EEM_Registration::status_id_incomplete:
1840
-            default:
1841
-                $result['success'] = false;
1842
-                unset($this->_req_data['return']);
1843
-                $this->_reg_status_change_return('', false);
1844
-                break;
1845
-        }
1846
-    }
1847
-
1848
-
1849
-    /**
1850
-     * Callback for bulk action routes.
1851
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1852
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
1853
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1854
-     * when an action is happening on just a single registration).
1855
-     *
1856
-     * @param      $action
1857
-     * @param bool $notify
1858
-     */
1859
-    protected function bulk_action_on_registrations($action, $notify = false)
1860
-    {
1861
-        do_action(
1862
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1863
-            $this,
1864
-            $action,
1865
-            $notify
1866
-        );
1867
-        $method = $action . '_registration';
1868
-        if (method_exists($this, $method)) {
1869
-            $this->$method($notify);
1870
-        }
1871
-    }
1872
-
1873
-
1874
-    /**
1875
-     * approve_registration
1876
-     *
1877
-     * @access protected
1878
-     * @param bool $notify whether or not to notify the registrant about their approval.
1879
-     * @return void
1880
-     * @throws EE_Error
1881
-     * @throws EntityNotFoundException
1882
-     * @throws InvalidArgumentException
1883
-     * @throws InvalidDataTypeException
1884
-     * @throws InvalidInterfaceException
1885
-     * @throws ReflectionException
1886
-     * @throws RuntimeException
1887
-     * @throws DomainException
1888
-     */
1889
-    protected function approve_registration($notify = false)
1890
-    {
1891
-        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1892
-    }
1893
-
1894
-
1895
-    /**
1896
-     *        decline_registration
1897
-     *
1898
-     * @access protected
1899
-     * @param bool $notify whether or not to notify the registrant about their status change.
1900
-     * @return void
1901
-     * @throws EE_Error
1902
-     * @throws EntityNotFoundException
1903
-     * @throws InvalidArgumentException
1904
-     * @throws InvalidDataTypeException
1905
-     * @throws InvalidInterfaceException
1906
-     * @throws ReflectionException
1907
-     * @throws RuntimeException
1908
-     * @throws DomainException
1909
-     */
1910
-    protected function decline_registration($notify = false)
1911
-    {
1912
-        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1913
-    }
1914
-
1915
-
1916
-    /**
1917
-     *        cancel_registration
1918
-     *
1919
-     * @access protected
1920
-     * @param bool $notify whether or not to notify the registrant about their status change.
1921
-     * @return void
1922
-     * @throws EE_Error
1923
-     * @throws EntityNotFoundException
1924
-     * @throws InvalidArgumentException
1925
-     * @throws InvalidDataTypeException
1926
-     * @throws InvalidInterfaceException
1927
-     * @throws ReflectionException
1928
-     * @throws RuntimeException
1929
-     * @throws DomainException
1930
-     */
1931
-    protected function cancel_registration($notify = false)
1932
-    {
1933
-        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1934
-    }
1935
-
1936
-
1937
-    /**
1938
-     *        not_approve_registration
1939
-     *
1940
-     * @access protected
1941
-     * @param bool $notify whether or not to notify the registrant about their status change.
1942
-     * @return void
1943
-     * @throws EE_Error
1944
-     * @throws EntityNotFoundException
1945
-     * @throws InvalidArgumentException
1946
-     * @throws InvalidDataTypeException
1947
-     * @throws InvalidInterfaceException
1948
-     * @throws ReflectionException
1949
-     * @throws RuntimeException
1950
-     * @throws DomainException
1951
-     */
1952
-    protected function not_approve_registration($notify = false)
1953
-    {
1954
-        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1955
-    }
1956
-
1957
-
1958
-    /**
1959
-     *        decline_registration
1960
-     *
1961
-     * @access protected
1962
-     * @param bool $notify whether or not to notify the registrant about their status change.
1963
-     * @return void
1964
-     * @throws EE_Error
1965
-     * @throws EntityNotFoundException
1966
-     * @throws InvalidArgumentException
1967
-     * @throws InvalidDataTypeException
1968
-     * @throws InvalidInterfaceException
1969
-     * @throws ReflectionException
1970
-     * @throws RuntimeException
1971
-     * @throws DomainException
1972
-     */
1973
-    protected function pending_registration($notify = false)
1974
-    {
1975
-        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1976
-    }
1977
-
1978
-
1979
-    /**
1980
-     * waitlist_registration
1981
-     *
1982
-     * @access protected
1983
-     * @param bool $notify whether or not to notify the registrant about their status change.
1984
-     * @return void
1985
-     * @throws EE_Error
1986
-     * @throws EntityNotFoundException
1987
-     * @throws InvalidArgumentException
1988
-     * @throws InvalidDataTypeException
1989
-     * @throws InvalidInterfaceException
1990
-     * @throws ReflectionException
1991
-     * @throws RuntimeException
1992
-     * @throws DomainException
1993
-     */
1994
-    protected function wait_list_registration($notify = false)
1995
-    {
1996
-        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1997
-    }
1998
-
1999
-
2000
-    /**
2001
-     *        generates HTML for the Registration main meta box
2002
-     *
2003
-     * @access public
2004
-     * @return void
2005
-     * @throws DomainException
2006
-     * @throws EE_Error
2007
-     * @throws InvalidArgumentException
2008
-     * @throws InvalidDataTypeException
2009
-     * @throws InvalidInterfaceException
2010
-     * @throws ReflectionException
2011
-     * @throws EntityNotFoundException
2012
-     */
2013
-    public function _reg_details_meta_box()
2014
-    {
2015
-        EEH_Autoloader::register_line_item_display_autoloaders();
2016
-        EEH_Autoloader::register_line_item_filter_autoloaders();
2017
-        EE_Registry::instance()->load_helper('Line_Item');
2018
-        $transaction = $this->_registration->transaction() ? $this->_registration->transaction()
2019
-            : EE_Transaction::new_instance();
2020
-        $this->_session = $transaction->session_data();
2021
-        $filters = new EE_Line_Item_Filter_Collection();
2022
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2023
-        $filters->add(new EE_Non_Zero_Line_Item_Filter());
2024
-        $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
2025
-            $filters,
2026
-            $transaction->total_line_item()
2027
-        );
2028
-        $filtered_line_item_tree = $line_item_filter_processor->process();
2029
-        $line_item_display = new EE_Line_Item_Display(
2030
-            'reg_admin_table',
2031
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2032
-        );
2033
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2034
-            $filtered_line_item_tree,
2035
-            array('EE_Registration' => $this->_registration)
2036
-        );
2037
-        $attendee = $this->_registration->attendee();
2038
-        if (EE_Registry::instance()->CAP->current_user_can(
2039
-            'ee_read_transaction',
2040
-            'espresso_transactions_view_transaction'
2041
-        )) {
2042
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2043
-                EE_Admin_Page::add_query_args_and_nonce(
2044
-                    array(
2045
-                        'action' => 'view_transaction',
2046
-                        'TXN_ID' => $transaction->ID(),
2047
-                    ),
2048
-                    TXN_ADMIN_URL
2049
-                ),
2050
-                esc_html__(' View Transaction', 'event_espresso'),
2051
-                'button secondary-button right',
2052
-                'dashicons dashicons-cart'
2053
-            );
2054
-        } else {
2055
-            $this->_template_args['view_transaction_button'] = '';
2056
-        }
2057
-        if ($attendee instanceof EE_Attendee
2058
-            && EE_Registry::instance()->CAP->current_user_can(
2059
-                'ee_send_message',
2060
-                'espresso_registrations_resend_registration'
2061
-            )
2062
-        ) {
2063
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2064
-                EE_Admin_Page::add_query_args_and_nonce(
2065
-                    array(
2066
-                        'action'      => 'resend_registration',
2067
-                        '_REG_ID'     => $this->_registration->ID(),
2068
-                        'redirect_to' => 'view_registration',
2069
-                    ),
2070
-                    REG_ADMIN_URL
2071
-                ),
2072
-                esc_html__(' Resend Registration', 'event_espresso'),
2073
-                'button secondary-button right',
2074
-                'dashicons dashicons-email-alt'
2075
-            );
2076
-        } else {
2077
-            $this->_template_args['resend_registration_button'] = '';
2078
-        }
2079
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2080
-        $payment = $transaction->get_first_related('Payment');
2081
-        $payment = ! $payment instanceof EE_Payment
2082
-            ? EE_Payment::new_instance()
2083
-            : $payment;
2084
-        $payment_method = $payment->get_first_related('Payment_Method');
2085
-        $payment_method = ! $payment_method instanceof EE_Payment_Method
2086
-            ? EE_Payment_Method::new_instance()
2087
-            : $payment_method;
2088
-        $reg_details = array(
2089
-            'payment_method'       => $payment_method->name(),
2090
-            'response_msg'         => $payment->gateway_response(),
2091
-            'registration_id'      => $this->_registration->get('REG_code'),
2092
-            'registration_session' => $this->_registration->session_ID(),
2093
-            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2094
-            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2095
-        );
2096
-        if (isset($reg_details['registration_id'])) {
2097
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2098
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2099
-                'Registration ID',
2100
-                'event_espresso'
2101
-            );
2102
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2103
-        }
2104
-        if (isset($reg_details['payment_method'])) {
2105
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2106
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2107
-                'Most Recent Payment Method',
2108
-                'event_espresso'
2109
-            );
2110
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2111
-            $this->_template_args['reg_details']['response_msg']['value'] = $reg_details['response_msg'];
2112
-            $this->_template_args['reg_details']['response_msg']['label'] = esc_html__(
2113
-                'Payment method response',
2114
-                'event_espresso'
2115
-            );
2116
-            $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2117
-        }
2118
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2119
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2120
-            'Registration Session',
2121
-            'event_espresso'
2122
-        );
2123
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2124
-        $this->_template_args['reg_details']['ip_address']['value'] = $reg_details['ip_address'];
2125
-        $this->_template_args['reg_details']['ip_address']['label'] = esc_html__(
2126
-            'Registration placed from IP',
2127
-            'event_espresso'
2128
-        );
2129
-        $this->_template_args['reg_details']['ip_address']['class'] = 'regular-text';
2130
-        $this->_template_args['reg_details']['user_agent']['value'] = $reg_details['user_agent'];
2131
-        $this->_template_args['reg_details']['user_agent']['label'] = esc_html__(
2132
-            'Registrant User Agent',
2133
-            'event_espresso'
2134
-        );
2135
-        $this->_template_args['reg_details']['user_agent']['class'] = 'large-text';
2136
-        $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
2137
-            array(
2138
-                'action'   => 'default',
2139
-                'event_id' => $this->_registration->event_ID(),
2140
-            ),
2141
-            REG_ADMIN_URL
2142
-        );
2143
-        $this->_template_args['REG_ID'] = $this->_registration->ID();
2144
-        $this->_template_args['event_id'] = $this->_registration->event_ID();
2145
-        $template_path =
2146
-            REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2147
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2148
-    }
2149
-
2150
-
2151
-    /**
2152
-     * generates HTML for the Registration Questions meta box.
2153
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2154
-     * otherwise uses new forms system
2155
-     *
2156
-     * @access public
2157
-     * @return void
2158
-     * @throws DomainException
2159
-     * @throws EE_Error
2160
-     * @throws InvalidArgumentException
2161
-     * @throws InvalidDataTypeException
2162
-     * @throws InvalidInterfaceException
2163
-     * @throws ReflectionException
2164
-     */
2165
-    public function _reg_questions_meta_box()
2166
-    {
2167
-        // allow someone to override this method entirely
2168
-        if (apply_filters(
2169
-            'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2170
-            true,
2171
-            $this,
2172
-            $this->_registration
2173
-        )) {
2174
-            $form = $this->_get_reg_custom_questions_form(
2175
-                $this->_registration->ID()
2176
-            );
2177
-            $this->_template_args['att_questions'] = count($form->subforms()) > 0
2178
-                ? $form->get_html_and_js()
2179
-                : '';
2180
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2181
-            $this->_template_args['REG_ID'] = $this->_registration->ID();
2182
-            $template_path =
2183
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2184
-            echo EEH_Template::display_template($template_path, $this->_template_args, true);
2185
-        }
2186
-    }
2187
-
2188
-
2189
-    /**
2190
-     * form_before_question_group
2191
-     *
2192
-     * @deprecated    as of 4.8.32.rc.000
2193
-     * @access        public
2194
-     * @param        string $output
2195
-     * @return        string
2196
-     */
2197
-    public function form_before_question_group($output)
2198
-    {
2199
-        EE_Error::doing_it_wrong(
2200
-            __CLASS__ . '::' . __FUNCTION__,
2201
-            esc_html__(
2202
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2203
-                'event_espresso'
2204
-            ),
2205
-            '4.8.32.rc.000'
2206
-        );
2207
-        return '
21
+	/**
22
+	 * @var EE_Registration
23
+	 */
24
+	private $_registration;
25
+
26
+	/**
27
+	 * @var EE_Event
28
+	 */
29
+	private $_reg_event;
30
+
31
+	/**
32
+	 * @var EE_Session
33
+	 */
34
+	private $_session;
35
+
36
+	private static $_reg_status;
37
+
38
+	/**
39
+	 * Form for displaying the custom questions for this registration.
40
+	 * This gets used a few times throughout the request so its best to cache it
41
+	 *
42
+	 * @var EE_Registration_Custom_Questions_Form
43
+	 */
44
+	protected $_reg_custom_questions_form;
45
+
46
+	/**
47
+	 * @var EEM_Registration $registration_model
48
+	 */
49
+	private $registration_model;
50
+
51
+	/**
52
+	 * @var EEM_Attendee $attendee_model
53
+	 */
54
+	private $attendee_model;
55
+
56
+	/**
57
+	 * @var EEM_Event $event_model
58
+	 */
59
+	private $event_model;
60
+
61
+	/**
62
+	 * @var EEM_Status $status_model
63
+	 */
64
+	private $status_model;
65
+
66
+
67
+	/**
68
+	 * @param bool $routing
69
+	 * @throws EE_Error
70
+	 * @throws InvalidArgumentException
71
+	 * @throws InvalidDataTypeException
72
+	 * @throws InvalidInterfaceException
73
+	 * @throws ReflectionException
74
+	 */
75
+	public function __construct($routing = true)
76
+	{
77
+		parent::__construct($routing);
78
+		add_action('wp_loaded', array($this, 'wp_loaded'));
79
+	}
80
+
81
+	/**
82
+	 * @return EEM_Registration
83
+	 * @throws InvalidArgumentException
84
+	 * @throws InvalidDataTypeException
85
+	 * @throws InvalidInterfaceException
86
+	 * @since 4.10.2.p
87
+	 */
88
+	protected function getRegistrationModel()
89
+	{
90
+		if (! $this->registration_model instanceof EEM_Registration) {
91
+			$this->registration_model = $this->loader->getShared('EEM_Registration');
92
+		}
93
+		return $this->registration_model;
94
+	}
95
+
96
+	/**
97
+	 * @return EEM_Attendee
98
+	 * @throws InvalidArgumentException
99
+	 * @throws InvalidDataTypeException
100
+	 * @throws InvalidInterfaceException
101
+	 * @since 4.10.2.p
102
+	 */
103
+	protected function getAttendeeModel()
104
+	{
105
+		if (! $this->attendee_model instanceof EEM_Attendee) {
106
+			$this->attendee_model = $this->loader->getShared('EEM_Attendee');
107
+		}
108
+		return $this->attendee_model;
109
+	}
110
+
111
+
112
+	/**
113
+	 * @return EEM_Event
114
+	 * @throws InvalidArgumentException
115
+	 * @throws InvalidDataTypeException
116
+	 * @throws InvalidInterfaceException
117
+	 * @since 4.10.2.p
118
+	 */
119
+	protected function getEventModel()
120
+	{
121
+		if (! $this->event_model instanceof EEM_Event) {
122
+			$this->event_model = $this->loader->getShared('EEM_Event');
123
+		}
124
+		return $this->event_model;
125
+	}
126
+
127
+	/**
128
+	 * @return EEM_Status
129
+	 * @throws InvalidArgumentException
130
+	 * @throws InvalidDataTypeException
131
+	 * @throws InvalidInterfaceException
132
+	 * @since 4.10.2.p
133
+	 */
134
+	protected function getStatusModel()
135
+	{
136
+		if (! $this->status_model instanceof EEM_Status) {
137
+			$this->status_model = $this->loader->getShared('EEM_Status');
138
+		}
139
+		return $this->status_model;
140
+	}
141
+
142
+
143
+	public function wp_loaded()
144
+	{
145
+		// when adding a new registration...
146
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
147
+			EE_System::do_not_cache();
148
+			if (! isset($this->_req_data['processing_registration'])
149
+				|| absint($this->_req_data['processing_registration']) !== 1
150
+			) {
151
+				// and it's NOT the attendee information reg step
152
+				// force cookie expiration by setting time to last week
153
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
154
+				// and update the global
155
+				$_COOKIE['ee_registration_added'] = 0;
156
+			}
157
+		}
158
+	}
159
+
160
+
161
+	protected function _init_page_props()
162
+	{
163
+		$this->page_slug = REG_PG_SLUG;
164
+		$this->_admin_base_url = REG_ADMIN_URL;
165
+		$this->_admin_base_path = REG_ADMIN;
166
+		$this->page_label = esc_html__('Registrations', 'event_espresso');
167
+		$this->_cpt_routes = array(
168
+			'add_new_attendee' => 'espresso_attendees',
169
+			'edit_attendee'    => 'espresso_attendees',
170
+			'insert_attendee'  => 'espresso_attendees',
171
+			'update_attendee'  => 'espresso_attendees',
172
+		);
173
+		$this->_cpt_model_names = array(
174
+			'add_new_attendee' => 'EEM_Attendee',
175
+			'edit_attendee'    => 'EEM_Attendee',
176
+		);
177
+		$this->_cpt_edit_routes = array(
178
+			'espresso_attendees' => 'edit_attendee',
179
+		);
180
+		$this->_pagenow_map = array(
181
+			'add_new_attendee' => 'post-new.php',
182
+			'edit_attendee'    => 'post.php',
183
+			'trash'            => 'post.php',
184
+		);
185
+		add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
186
+		// add filters so that the comment urls don't take users to a confusing 404 page
187
+		add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
188
+	}
189
+
190
+
191
+	public function clear_comment_link($link, $comment, $args)
192
+	{
193
+		// gotta make sure this only happens on this route
194
+		$post_type = get_post_type($comment->comment_post_ID);
195
+		if ($post_type === 'espresso_attendees') {
196
+			return '#commentsdiv';
197
+		}
198
+		return $link;
199
+	}
200
+
201
+
202
+	protected function _ajax_hooks()
203
+	{
204
+		// todo: all hooks for registrations ajax goes in here
205
+		add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
206
+	}
207
+
208
+
209
+	protected function _define_page_props()
210
+	{
211
+		$this->_admin_page_title = $this->page_label;
212
+		$this->_labels = array(
213
+			'buttons'                      => array(
214
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
215
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
216
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
217
+				'report'              => esc_html__('Event Registrations CSV Report', 'event_espresso'),
218
+				'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
219
+				'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
220
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
221
+				'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
222
+			),
223
+			'publishbox'                   => array(
224
+				'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
225
+				'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
226
+			),
227
+			'hide_add_button_on_cpt_route' => array(
228
+				'edit_attendee' => true,
229
+			),
230
+		);
231
+	}
232
+
233
+
234
+	/**
235
+	 *        grab url requests and route them
236
+	 *
237
+	 * @access private
238
+	 * @return void
239
+	 * @throws EE_Error
240
+	 */
241
+	public function _set_page_routes()
242
+	{
243
+		$this->_get_registration_status_array();
244
+		$reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
245
+			? $this->_req_data['_REG_ID'] : 0;
246
+		$reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
247
+			? $this->_req_data['reg_status_change_form']['REG_ID']
248
+			: $reg_id;
249
+		$att_id = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
250
+			? $this->_req_data['ATT_ID'] : 0;
251
+		$att_id = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
252
+			? $this->_req_data['post']
253
+			: $att_id;
254
+		$this->_page_routes = array(
255
+			'default'                             => array(
256
+				'func'       => '_registrations_overview_list_table',
257
+				'capability' => 'ee_read_registrations',
258
+			),
259
+			'view_registration'                   => array(
260
+				'func'       => '_registration_details',
261
+				'capability' => 'ee_read_registration',
262
+				'obj_id'     => $reg_id,
263
+			),
264
+			'edit_registration'                   => array(
265
+				'func'               => '_update_attendee_registration_form',
266
+				'noheader'           => true,
267
+				'headers_sent_route' => 'view_registration',
268
+				'capability'         => 'ee_edit_registration',
269
+				'obj_id'             => $reg_id,
270
+				'_REG_ID'            => $reg_id,
271
+			),
272
+			'trash_registrations'                 => array(
273
+				'func'       => '_trash_or_restore_registrations',
274
+				'args'       => array('trash' => true),
275
+				'noheader'   => true,
276
+				'capability' => 'ee_delete_registrations',
277
+			),
278
+			'restore_registrations'               => array(
279
+				'func'       => '_trash_or_restore_registrations',
280
+				'args'       => array('trash' => false),
281
+				'noheader'   => true,
282
+				'capability' => 'ee_delete_registrations',
283
+			),
284
+			'delete_registrations'                => array(
285
+				'func'       => '_delete_registrations',
286
+				'noheader'   => true,
287
+				'capability' => 'ee_delete_registrations',
288
+			),
289
+			'new_registration'                    => array(
290
+				'func'       => 'new_registration',
291
+				'capability' => 'ee_edit_registrations',
292
+			),
293
+			'process_reg_step'                    => array(
294
+				'func'       => 'process_reg_step',
295
+				'noheader'   => true,
296
+				'capability' => 'ee_edit_registrations',
297
+			),
298
+			'redirect_to_txn'                     => array(
299
+				'func'       => 'redirect_to_txn',
300
+				'noheader'   => true,
301
+				'capability' => 'ee_edit_registrations',
302
+			),
303
+			'change_reg_status'                   => array(
304
+				'func'       => '_change_reg_status',
305
+				'noheader'   => true,
306
+				'capability' => 'ee_edit_registration',
307
+				'obj_id'     => $reg_id,
308
+			),
309
+			'approve_registration'                => array(
310
+				'func'       => 'approve_registration',
311
+				'noheader'   => true,
312
+				'capability' => 'ee_edit_registration',
313
+				'obj_id'     => $reg_id,
314
+			),
315
+			'approve_and_notify_registration'     => array(
316
+				'func'       => 'approve_registration',
317
+				'noheader'   => true,
318
+				'args'       => array(true),
319
+				'capability' => 'ee_edit_registration',
320
+				'obj_id'     => $reg_id,
321
+			),
322
+			'approve_registrations'               => array(
323
+				'func'       => 'bulk_action_on_registrations',
324
+				'noheader'   => true,
325
+				'capability' => 'ee_edit_registrations',
326
+				'args'       => array('approve'),
327
+			),
328
+			'approve_and_notify_registrations'    => array(
329
+				'func'       => 'bulk_action_on_registrations',
330
+				'noheader'   => true,
331
+				'capability' => 'ee_edit_registrations',
332
+				'args'       => array('approve', true),
333
+			),
334
+			'decline_registration'                => array(
335
+				'func'       => 'decline_registration',
336
+				'noheader'   => true,
337
+				'capability' => 'ee_edit_registration',
338
+				'obj_id'     => $reg_id,
339
+			),
340
+			'decline_and_notify_registration'     => array(
341
+				'func'       => 'decline_registration',
342
+				'noheader'   => true,
343
+				'args'       => array(true),
344
+				'capability' => 'ee_edit_registration',
345
+				'obj_id'     => $reg_id,
346
+			),
347
+			'decline_registrations'               => array(
348
+				'func'       => 'bulk_action_on_registrations',
349
+				'noheader'   => true,
350
+				'capability' => 'ee_edit_registrations',
351
+				'args'       => array('decline'),
352
+			),
353
+			'decline_and_notify_registrations'    => array(
354
+				'func'       => 'bulk_action_on_registrations',
355
+				'noheader'   => true,
356
+				'capability' => 'ee_edit_registrations',
357
+				'args'       => array('decline', true),
358
+			),
359
+			'pending_registration'                => array(
360
+				'func'       => 'pending_registration',
361
+				'noheader'   => true,
362
+				'capability' => 'ee_edit_registration',
363
+				'obj_id'     => $reg_id,
364
+			),
365
+			'pending_and_notify_registration'     => array(
366
+				'func'       => 'pending_registration',
367
+				'noheader'   => true,
368
+				'args'       => array(true),
369
+				'capability' => 'ee_edit_registration',
370
+				'obj_id'     => $reg_id,
371
+			),
372
+			'pending_registrations'               => array(
373
+				'func'       => 'bulk_action_on_registrations',
374
+				'noheader'   => true,
375
+				'capability' => 'ee_edit_registrations',
376
+				'args'       => array('pending'),
377
+			),
378
+			'pending_and_notify_registrations'    => array(
379
+				'func'       => 'bulk_action_on_registrations',
380
+				'noheader'   => true,
381
+				'capability' => 'ee_edit_registrations',
382
+				'args'       => array('pending', true),
383
+			),
384
+			'no_approve_registration'             => array(
385
+				'func'       => 'not_approve_registration',
386
+				'noheader'   => true,
387
+				'capability' => 'ee_edit_registration',
388
+				'obj_id'     => $reg_id,
389
+			),
390
+			'no_approve_and_notify_registration'  => array(
391
+				'func'       => 'not_approve_registration',
392
+				'noheader'   => true,
393
+				'args'       => array(true),
394
+				'capability' => 'ee_edit_registration',
395
+				'obj_id'     => $reg_id,
396
+			),
397
+			'no_approve_registrations'            => array(
398
+				'func'       => 'bulk_action_on_registrations',
399
+				'noheader'   => true,
400
+				'capability' => 'ee_edit_registrations',
401
+				'args'       => array('not_approve'),
402
+			),
403
+			'no_approve_and_notify_registrations' => array(
404
+				'func'       => 'bulk_action_on_registrations',
405
+				'noheader'   => true,
406
+				'capability' => 'ee_edit_registrations',
407
+				'args'       => array('not_approve', true),
408
+			),
409
+			'cancel_registration'                 => array(
410
+				'func'       => 'cancel_registration',
411
+				'noheader'   => true,
412
+				'capability' => 'ee_edit_registration',
413
+				'obj_id'     => $reg_id,
414
+			),
415
+			'cancel_and_notify_registration'      => array(
416
+				'func'       => 'cancel_registration',
417
+				'noheader'   => true,
418
+				'args'       => array(true),
419
+				'capability' => 'ee_edit_registration',
420
+				'obj_id'     => $reg_id,
421
+			),
422
+			'cancel_registrations'                => array(
423
+				'func'       => 'bulk_action_on_registrations',
424
+				'noheader'   => true,
425
+				'capability' => 'ee_edit_registrations',
426
+				'args'       => array('cancel'),
427
+			),
428
+			'cancel_and_notify_registrations'     => array(
429
+				'func'       => 'bulk_action_on_registrations',
430
+				'noheader'   => true,
431
+				'capability' => 'ee_edit_registrations',
432
+				'args'       => array('cancel', true),
433
+			),
434
+			'wait_list_registration'              => array(
435
+				'func'       => 'wait_list_registration',
436
+				'noheader'   => true,
437
+				'capability' => 'ee_edit_registration',
438
+				'obj_id'     => $reg_id,
439
+			),
440
+			'wait_list_and_notify_registration'   => array(
441
+				'func'       => 'wait_list_registration',
442
+				'noheader'   => true,
443
+				'args'       => array(true),
444
+				'capability' => 'ee_edit_registration',
445
+				'obj_id'     => $reg_id,
446
+			),
447
+			'contact_list'                        => array(
448
+				'func'       => '_attendee_contact_list_table',
449
+				'capability' => 'ee_read_contacts',
450
+			),
451
+			'add_new_attendee'                    => array(
452
+				'func' => '_create_new_cpt_item',
453
+				'args' => array(
454
+					'new_attendee' => true,
455
+					'capability'   => 'ee_edit_contacts',
456
+				),
457
+			),
458
+			'edit_attendee'                       => array(
459
+				'func'       => '_edit_cpt_item',
460
+				'capability' => 'ee_edit_contacts',
461
+				'obj_id'     => $att_id,
462
+			),
463
+			'duplicate_attendee'                  => array(
464
+				'func'       => '_duplicate_attendee',
465
+				'noheader'   => true,
466
+				'capability' => 'ee_edit_contacts',
467
+				'obj_id'     => $att_id,
468
+			),
469
+			'insert_attendee'                     => array(
470
+				'func'       => '_insert_or_update_attendee',
471
+				'args'       => array(
472
+					'new_attendee' => true,
473
+				),
474
+				'noheader'   => true,
475
+				'capability' => 'ee_edit_contacts',
476
+			),
477
+			'update_attendee'                     => array(
478
+				'func'       => '_insert_or_update_attendee',
479
+				'args'       => array(
480
+					'new_attendee' => false,
481
+				),
482
+				'noheader'   => true,
483
+				'capability' => 'ee_edit_contacts',
484
+				'obj_id'     => $att_id,
485
+			),
486
+			'trash_attendees'                     => array(
487
+				'func'       => '_trash_or_restore_attendees',
488
+				'args'       => array(
489
+					'trash' => 'true',
490
+				),
491
+				'noheader'   => true,
492
+				'capability' => 'ee_delete_contacts',
493
+			),
494
+			'trash_attendee'                      => array(
495
+				'func'       => '_trash_or_restore_attendees',
496
+				'args'       => array(
497
+					'trash' => true,
498
+				),
499
+				'noheader'   => true,
500
+				'capability' => 'ee_delete_contacts',
501
+				'obj_id'     => $att_id,
502
+			),
503
+			'restore_attendees'                   => array(
504
+				'func'       => '_trash_or_restore_attendees',
505
+				'args'       => array(
506
+					'trash' => false,
507
+				),
508
+				'noheader'   => true,
509
+				'capability' => 'ee_delete_contacts',
510
+				'obj_id'     => $att_id,
511
+			),
512
+			'resend_registration'                 => array(
513
+				'func'       => '_resend_registration',
514
+				'noheader'   => true,
515
+				'capability' => 'ee_send_message',
516
+			),
517
+			'registrations_report'                => array(
518
+				'func'       => '_registrations_report',
519
+				'noheader'   => true,
520
+				'capability' => 'ee_read_registrations',
521
+			),
522
+			'contact_list_export'                 => array(
523
+				'func'       => '_contact_list_export',
524
+				'noheader'   => true,
525
+				'capability' => 'export',
526
+			),
527
+			'contact_list_report'                 => array(
528
+				'func'       => '_contact_list_report',
529
+				'noheader'   => true,
530
+				'capability' => 'ee_read_contacts',
531
+			),
532
+		);
533
+	}
534
+
535
+
536
+	protected function _set_page_config()
537
+	{
538
+		$this->_page_config = array(
539
+			'default'           => array(
540
+				'nav'           => array(
541
+					'label' => esc_html__('Overview', 'event_espresso'),
542
+					'order' => 5,
543
+				),
544
+				'help_tabs'     => array(
545
+					'registrations_overview_help_tab'                       => array(
546
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
547
+						'filename' => 'registrations_overview',
548
+					),
549
+					'registrations_overview_table_column_headings_help_tab' => array(
550
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
551
+						'filename' => 'registrations_overview_table_column_headings',
552
+					),
553
+					'registrations_overview_filters_help_tab'               => array(
554
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
555
+						'filename' => 'registrations_overview_filters',
556
+					),
557
+					'registrations_overview_views_help_tab'                 => array(
558
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
559
+						'filename' => 'registrations_overview_views',
560
+					),
561
+					'registrations_regoverview_other_help_tab'              => array(
562
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
563
+						'filename' => 'registrations_overview_other',
564
+					),
565
+				),
566
+				'help_tour'     => array('Registration_Overview_Help_Tour'),
567
+				'qtips'         => array('Registration_List_Table_Tips'),
568
+				'list_table'    => 'EE_Registrations_List_Table',
569
+				'require_nonce' => false,
570
+			),
571
+			'view_registration' => array(
572
+				'nav'           => array(
573
+					'label'      => esc_html__('REG Details', 'event_espresso'),
574
+					'order'      => 15,
575
+					'url'        => isset($this->_req_data['_REG_ID'])
576
+						? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
577
+						: $this->_admin_base_url,
578
+					'persistent' => false,
579
+				),
580
+				'help_tabs'     => array(
581
+					'registrations_details_help_tab'                    => array(
582
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
583
+						'filename' => 'registrations_details',
584
+					),
585
+					'registrations_details_table_help_tab'              => array(
586
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
587
+						'filename' => 'registrations_details_table',
588
+					),
589
+					'registrations_details_form_answers_help_tab'       => array(
590
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
591
+						'filename' => 'registrations_details_form_answers',
592
+					),
593
+					'registrations_details_registrant_details_help_tab' => array(
594
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
595
+						'filename' => 'registrations_details_registrant_details',
596
+					),
597
+				),
598
+				'help_tour'     => array('Registration_Details_Help_Tour'),
599
+				'metaboxes'     => array_merge(
600
+					$this->_default_espresso_metaboxes,
601
+					array('_registration_details_metaboxes')
602
+				),
603
+				'require_nonce' => false,
604
+			),
605
+			'new_registration'  => array(
606
+				'nav'           => array(
607
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
608
+					'url'        => '#',
609
+					'order'      => 15,
610
+					'persistent' => false,
611
+				),
612
+				'metaboxes'     => $this->_default_espresso_metaboxes,
613
+				'labels'        => array(
614
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
615
+				),
616
+				'require_nonce' => false,
617
+			),
618
+			'add_new_attendee'  => array(
619
+				'nav'           => array(
620
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
621
+					'order'      => 15,
622
+					'persistent' => false,
623
+				),
624
+				'metaboxes'     => array_merge(
625
+					$this->_default_espresso_metaboxes,
626
+					array('_publish_post_box', 'attendee_editor_metaboxes')
627
+				),
628
+				'require_nonce' => false,
629
+			),
630
+			'edit_attendee'     => array(
631
+				'nav'           => array(
632
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
633
+					'order'      => 15,
634
+					'persistent' => false,
635
+					'url'        => isset($this->_req_data['ATT_ID'])
636
+						? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
637
+						: $this->_admin_base_url,
638
+				),
639
+				'metaboxes'     => array('attendee_editor_metaboxes'),
640
+				'require_nonce' => false,
641
+			),
642
+			'contact_list'      => array(
643
+				'nav'           => array(
644
+					'label' => esc_html__('Contact List', 'event_espresso'),
645
+					'order' => 20,
646
+				),
647
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
648
+				'help_tabs'     => array(
649
+					'registrations_contact_list_help_tab'                       => array(
650
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
651
+						'filename' => 'registrations_contact_list',
652
+					),
653
+					'registrations_contact-list_table_column_headings_help_tab' => array(
654
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
655
+						'filename' => 'registrations_contact_list_table_column_headings',
656
+					),
657
+					'registrations_contact_list_views_help_tab'                 => array(
658
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
659
+						'filename' => 'registrations_contact_list_views',
660
+					),
661
+					'registrations_contact_list_other_help_tab'                 => array(
662
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
663
+						'filename' => 'registrations_contact_list_other',
664
+					),
665
+				),
666
+				'help_tour'     => array('Contact_List_Help_Tour'),
667
+				'metaboxes'     => array(),
668
+				'require_nonce' => false,
669
+			),
670
+			// override default cpt routes
671
+			'create_new'        => '',
672
+			'edit'              => '',
673
+		);
674
+	}
675
+
676
+
677
+	/**
678
+	 * The below methods aren't used by this class currently
679
+	 */
680
+	protected function _add_screen_options()
681
+	{
682
+	}
683
+
684
+
685
+	protected function _add_feature_pointers()
686
+	{
687
+	}
688
+
689
+
690
+	public function admin_init()
691
+	{
692
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
693
+			'click "Update Registration Questions" to save your changes',
694
+			'event_espresso'
695
+		);
696
+	}
697
+
698
+
699
+	public function admin_notices()
700
+	{
701
+	}
702
+
703
+
704
+	public function admin_footer_scripts()
705
+	{
706
+	}
707
+
708
+
709
+	/**
710
+	 *        get list of registration statuses
711
+	 *
712
+	 * @access private
713
+	 * @return void
714
+	 * @throws EE_Error
715
+	 */
716
+	private function _get_registration_status_array()
717
+	{
718
+		self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
719
+	}
720
+
721
+
722
+	/**
723
+	 * @throws InvalidArgumentException
724
+	 * @throws InvalidDataTypeException
725
+	 * @throws InvalidInterfaceException
726
+	 * @since 4.10.2.p
727
+	 */
728
+	protected function _add_screen_options_default()
729
+	{
730
+		$this->_per_page_screen_option();
731
+	}
732
+
733
+
734
+	/**
735
+	 * @throws InvalidArgumentException
736
+	 * @throws InvalidDataTypeException
737
+	 * @throws InvalidInterfaceException
738
+	 * @since 4.10.2.p
739
+	 */
740
+	protected function _add_screen_options_contact_list()
741
+	{
742
+		$page_title = $this->_admin_page_title;
743
+		$this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
744
+		$this->_per_page_screen_option();
745
+		$this->_admin_page_title = $page_title;
746
+	}
747
+
748
+
749
+	public function load_scripts_styles()
750
+	{
751
+		// style
752
+		wp_register_style(
753
+			'espresso_reg',
754
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
755
+			array('ee-admin-css'),
756
+			EVENT_ESPRESSO_VERSION
757
+		);
758
+		wp_enqueue_style('espresso_reg');
759
+		// script
760
+		wp_register_script(
761
+			'espresso_reg',
762
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
763
+			array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
764
+			EVENT_ESPRESSO_VERSION,
765
+			true
766
+		);
767
+		wp_enqueue_script('espresso_reg');
768
+	}
769
+
770
+
771
+	/**
772
+	 * @throws EE_Error
773
+	 * @throws InvalidArgumentException
774
+	 * @throws InvalidDataTypeException
775
+	 * @throws InvalidInterfaceException
776
+	 * @throws ReflectionException
777
+	 * @since 4.10.2.p
778
+	 */
779
+	public function load_scripts_styles_edit_attendee()
780
+	{
781
+		// stuff to only show up on our attendee edit details page.
782
+		$attendee_details_translations = array(
783
+			'att_publish_text' => sprintf(
784
+				/* translators: The date and time */
785
+				wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
786
+				'<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
787
+			),
788
+		);
789
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
790
+		wp_enqueue_script('jquery-validate');
791
+	}
792
+
793
+
794
+	/**
795
+	 * @throws EE_Error
796
+	 * @throws InvalidArgumentException
797
+	 * @throws InvalidDataTypeException
798
+	 * @throws InvalidInterfaceException
799
+	 * @throws ReflectionException
800
+	 * @since 4.10.2.p
801
+	 */
802
+	public function load_scripts_styles_view_registration()
803
+	{
804
+		// styles
805
+		wp_enqueue_style('espresso-ui-theme');
806
+		// scripts
807
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
808
+		$this->_reg_custom_questions_form->wp_enqueue_scripts(true);
809
+	}
810
+
811
+
812
+	public function load_scripts_styles_contact_list()
813
+	{
814
+		wp_dequeue_style('espresso_reg');
815
+		wp_register_style(
816
+			'espresso_att',
817
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
818
+			array('ee-admin-css'),
819
+			EVENT_ESPRESSO_VERSION
820
+		);
821
+		wp_enqueue_style('espresso_att');
822
+	}
823
+
824
+
825
+	public function load_scripts_styles_new_registration()
826
+	{
827
+		wp_register_script(
828
+			'ee-spco-for-admin',
829
+			REG_ASSETS_URL . 'spco_for_admin.js',
830
+			array('underscore', 'jquery'),
831
+			EVENT_ESPRESSO_VERSION,
832
+			true
833
+		);
834
+		wp_enqueue_script('ee-spco-for-admin');
835
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
836
+		EE_Form_Section_Proper::wp_enqueue_scripts();
837
+		EED_Ticket_Selector::load_tckt_slctr_assets();
838
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
839
+	}
840
+
841
+
842
+	public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
843
+	{
844
+		add_filter('FHEE_load_EE_messages', '__return_true');
845
+	}
846
+
847
+
848
+	public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
849
+	{
850
+		add_filter('FHEE_load_EE_messages', '__return_true');
851
+	}
852
+
853
+
854
+	/**
855
+	 * @throws EE_Error
856
+	 * @throws InvalidArgumentException
857
+	 * @throws InvalidDataTypeException
858
+	 * @throws InvalidInterfaceException
859
+	 * @throws ReflectionException
860
+	 * @since 4.10.2.p
861
+	 */
862
+	protected function _set_list_table_views_default()
863
+	{
864
+		// for notification related bulk actions we need to make sure only active messengers have an option.
865
+		EED_Messages::set_autoloaders();
866
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
867
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
868
+		$active_mts = $message_resource_manager->list_of_active_message_types();
869
+		// key= bulk_action_slug, value= message type.
870
+		$match_array = array(
871
+			'approve_registrations'    => 'registration',
872
+			'decline_registrations'    => 'declined_registration',
873
+			'pending_registrations'    => 'pending_approval',
874
+			'no_approve_registrations' => 'not_approved_registration',
875
+			'cancel_registrations'     => 'cancelled_registration',
876
+		);
877
+		$can_send = EE_Registry::instance()->CAP->current_user_can(
878
+			'ee_send_message',
879
+			'batch_send_messages'
880
+		);
881
+		/** setup reg status bulk actions **/
882
+		$def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
883
+		if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
884
+			$def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
885
+				'Approve and Notify Registrations',
886
+				'event_espresso'
887
+			);
888
+		}
889
+		$def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
890
+		if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
891
+			$def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
892
+				'Decline and Notify Registrations',
893
+				'event_espresso'
894
+			);
895
+		}
896
+		$def_reg_status_actions['pending_registrations'] = esc_html__(
897
+			'Set Registrations to Pending Payment',
898
+			'event_espresso'
899
+		);
900
+		if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
901
+			$def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
902
+				'Set Registrations to Pending Payment and Notify',
903
+				'event_espresso'
904
+			);
905
+		}
906
+		$def_reg_status_actions['no_approve_registrations'] = esc_html__(
907
+			'Set Registrations to Not Approved',
908
+			'event_espresso'
909
+		);
910
+		if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
911
+			$def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
912
+				'Set Registrations to Not Approved and Notify',
913
+				'event_espresso'
914
+			);
915
+		}
916
+		$def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
917
+		if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
918
+			$def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
919
+				'Cancel Registrations and Notify',
920
+				'event_espresso'
921
+			);
922
+		}
923
+		$def_reg_status_actions = apply_filters(
924
+			'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
925
+			$def_reg_status_actions,
926
+			$active_mts,
927
+			$can_send
928
+		);
929
+
930
+		$this->_views = array(
931
+			'all'   => array(
932
+				'slug'        => 'all',
933
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
934
+				'count'       => 0,
935
+				'bulk_action' => array_merge(
936
+					$def_reg_status_actions,
937
+					array(
938
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
939
+					)
940
+				),
941
+			),
942
+			'month' => array(
943
+				'slug'        => 'month',
944
+				'label'       => esc_html__('This Month', 'event_espresso'),
945
+				'count'       => 0,
946
+				'bulk_action' => array_merge(
947
+					$def_reg_status_actions,
948
+					array(
949
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
950
+					)
951
+				),
952
+			),
953
+			'today' => array(
954
+				'slug'        => 'today',
955
+				'label'       => sprintf(
956
+					esc_html__('Today - %s', 'event_espresso'),
957
+					date('M d, Y', current_time('timestamp'))
958
+				),
959
+				'count'       => 0,
960
+				'bulk_action' => array_merge(
961
+					$def_reg_status_actions,
962
+					array(
963
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
964
+					)
965
+				),
966
+			),
967
+		);
968
+		if (EE_Registry::instance()->CAP->current_user_can(
969
+			'ee_delete_registrations',
970
+			'espresso_registrations_delete_registration'
971
+		)) {
972
+			$this->_views['incomplete'] = array(
973
+				'slug'        => 'incomplete',
974
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
975
+				'count'       => 0,
976
+				'bulk_action' => array(
977
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
978
+				),
979
+			);
980
+			$this->_views['trash'] = array(
981
+				'slug'        => 'trash',
982
+				'label'       => esc_html__('Trash', 'event_espresso'),
983
+				'count'       => 0,
984
+				'bulk_action' => array(
985
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
986
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
987
+				),
988
+			);
989
+		}
990
+	}
991
+
992
+
993
+	protected function _set_list_table_views_contact_list()
994
+	{
995
+		$this->_views = array(
996
+			'in_use' => array(
997
+				'slug'        => 'in_use',
998
+				'label'       => esc_html__('In Use', 'event_espresso'),
999
+				'count'       => 0,
1000
+				'bulk_action' => array(
1001
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1002
+				),
1003
+			),
1004
+		);
1005
+		if (EE_Registry::instance()->CAP->current_user_can(
1006
+			'ee_delete_contacts',
1007
+			'espresso_registrations_trash_attendees'
1008
+		)
1009
+		) {
1010
+			$this->_views['trash'] = array(
1011
+				'slug'        => 'trash',
1012
+				'label'       => esc_html__('Trash', 'event_espresso'),
1013
+				'count'       => 0,
1014
+				'bulk_action' => array(
1015
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1016
+				),
1017
+			);
1018
+		}
1019
+	}
1020
+
1021
+
1022
+	protected function _registration_legend_items()
1023
+	{
1024
+		$fc_items = array(
1025
+			'star-icon'        => array(
1026
+				'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
1027
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1028
+			),
1029
+			'view_details'     => array(
1030
+				'class' => 'dashicons dashicons-clipboard',
1031
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1032
+			),
1033
+			'edit_attendee'    => array(
1034
+				'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
1035
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1036
+			),
1037
+			'view_transaction' => array(
1038
+				'class' => 'dashicons dashicons-cart',
1039
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1040
+			),
1041
+			'view_invoice'     => array(
1042
+				'class' => 'dashicons dashicons-media-spreadsheet',
1043
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1044
+			),
1045
+		);
1046
+		if (EE_Registry::instance()->CAP->current_user_can(
1047
+			'ee_send_message',
1048
+			'espresso_registrations_resend_registration'
1049
+		)) {
1050
+			$fc_items['resend_registration'] = array(
1051
+				'class' => 'dashicons dashicons-email-alt',
1052
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1053
+			);
1054
+		} else {
1055
+			$fc_items['blank'] = array('class' => 'blank', 'desc' => '');
1056
+		}
1057
+		if (EE_Registry::instance()->CAP->current_user_can(
1058
+			'ee_read_global_messages',
1059
+			'view_filtered_messages'
1060
+		)) {
1061
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1062
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1063
+				$fc_items['view_related_messages'] = array(
1064
+					'class' => $related_for_icon['css_class'],
1065
+					'desc'  => $related_for_icon['label'],
1066
+				);
1067
+			}
1068
+		}
1069
+		$sc_items = array(
1070
+			'approved_status'   => array(
1071
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
1072
+				'desc'  => EEH_Template::pretty_status(
1073
+					EEM_Registration::status_id_approved,
1074
+					false,
1075
+					'sentence'
1076
+				),
1077
+			),
1078
+			'pending_status'    => array(
1079
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
1080
+				'desc'  => EEH_Template::pretty_status(
1081
+					EEM_Registration::status_id_pending_payment,
1082
+					false,
1083
+					'sentence'
1084
+				),
1085
+			),
1086
+			'wait_list'         => array(
1087
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
1088
+				'desc'  => EEH_Template::pretty_status(
1089
+					EEM_Registration::status_id_wait_list,
1090
+					false,
1091
+					'sentence'
1092
+				),
1093
+			),
1094
+			'incomplete_status' => array(
1095
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
1096
+				'desc'  => EEH_Template::pretty_status(
1097
+					EEM_Registration::status_id_incomplete,
1098
+					false,
1099
+					'sentence'
1100
+				),
1101
+			),
1102
+			'not_approved'      => array(
1103
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
1104
+				'desc'  => EEH_Template::pretty_status(
1105
+					EEM_Registration::status_id_not_approved,
1106
+					false,
1107
+					'sentence'
1108
+				),
1109
+			),
1110
+			'declined_status'   => array(
1111
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
1112
+				'desc'  => EEH_Template::pretty_status(
1113
+					EEM_Registration::status_id_declined,
1114
+					false,
1115
+					'sentence'
1116
+				),
1117
+			),
1118
+			'cancelled_status'  => array(
1119
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1120
+				'desc'  => EEH_Template::pretty_status(
1121
+					EEM_Registration::status_id_cancelled,
1122
+					false,
1123
+					'sentence'
1124
+				),
1125
+			),
1126
+		);
1127
+		return array_merge($fc_items, $sc_items);
1128
+	}
1129
+
1130
+
1131
+
1132
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
1133
+
1134
+
1135
+
1136
+	/**
1137
+	 * @throws DomainException
1138
+	 * @throws EE_Error
1139
+	 * @throws InvalidArgumentException
1140
+	 * @throws InvalidDataTypeException
1141
+	 * @throws InvalidInterfaceException
1142
+	 * @throws ReflectionException
1143
+	 */
1144
+	protected function _registrations_overview_list_table()
1145
+	{
1146
+		$this->appendAddNewRegistrationButtonToPageTitle();
1147
+		$header_text = '';
1148
+		$admin_page_header_decorators = [
1149
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1150
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1151
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1152
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1153
+		];
1154
+		foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1155
+			$filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1156
+			$header_text = $filter_header_decorator->getHeaderText($header_text);
1157
+		}
1158
+		$this->_template_args['admin_page_header'] = $header_text;
1159
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1160
+		$this->display_admin_list_table_page_with_no_sidebar();
1161
+	}
1162
+
1163
+
1164
+	/**
1165
+	 * @throws EE_Error
1166
+	 * @throws InvalidArgumentException
1167
+	 * @throws InvalidDataTypeException
1168
+	 * @throws InvalidInterfaceException
1169
+	 */
1170
+	private function appendAddNewRegistrationButtonToPageTitle()
1171
+	{
1172
+		$EVT_ID = ! empty($this->_req_data['event_id'])
1173
+			? absint($this->_req_data['event_id'])
1174
+			: 0;
1175
+		if ($EVT_ID
1176
+			&& EE_Registry::instance()->CAP->current_user_can(
1177
+				'ee_edit_registrations',
1178
+				'espresso_registrations_new_registration',
1179
+				$EVT_ID
1180
+			)
1181
+		) {
1182
+			$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1183
+				'new_registration',
1184
+				'add-registrant',
1185
+				array('event_id' => $EVT_ID),
1186
+				'add-new-h2'
1187
+			);
1188
+		}
1189
+	}
1190
+
1191
+
1192
+	/**
1193
+	 * This sets the _registration property for the registration details screen
1194
+	 *
1195
+	 * @access private
1196
+	 * @return bool
1197
+	 * @throws EE_Error
1198
+	 * @throws InvalidArgumentException
1199
+	 * @throws InvalidDataTypeException
1200
+	 * @throws InvalidInterfaceException
1201
+	 */
1202
+	private function _set_registration_object()
1203
+	{
1204
+		// get out if we've already set the object
1205
+		if ($this->_registration instanceof EE_Registration) {
1206
+			return true;
1207
+		}
1208
+		$REG_ID = (! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1209
+		if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1210
+			return true;
1211
+		}
1212
+		$error_msg = sprintf(
1213
+			esc_html__(
1214
+				'An error occurred and the details for Registration ID #%s could not be retrieved.',
1215
+				'event_espresso'
1216
+			),
1217
+			$REG_ID
1218
+		);
1219
+		EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1220
+		$this->_registration = null;
1221
+		return false;
1222
+	}
1223
+
1224
+
1225
+	/**
1226
+	 * Used to retrieve registrations for the list table.
1227
+	 *
1228
+	 * @param int  $per_page
1229
+	 * @param bool $count
1230
+	 * @param bool $this_month
1231
+	 * @param bool $today
1232
+	 * @return EE_Registration[]|int
1233
+	 * @throws EE_Error
1234
+	 * @throws InvalidArgumentException
1235
+	 * @throws InvalidDataTypeException
1236
+	 * @throws InvalidInterfaceException
1237
+	 */
1238
+	public function get_registrations(
1239
+		$per_page = 10,
1240
+		$count = false,
1241
+		$this_month = false,
1242
+		$today = false
1243
+	) {
1244
+		if ($this_month) {
1245
+			$this->_req_data['status'] = 'month';
1246
+		}
1247
+		if ($today) {
1248
+			$this->_req_data['status'] = 'today';
1249
+		}
1250
+		$query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1251
+		/**
1252
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1253
+		 *
1254
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1255
+		 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1256
+		 *                             or if you have the development copy of EE you can view this at the path:
1257
+		 *                             /docs/G--Model-System/model-query-params.md
1258
+		 */
1259
+		$query_params['group_by'] = '';
1260
+
1261
+		return $count
1262
+			? $this->getRegistrationModel()->count($query_params)
1263
+			/** @type EE_Registration[] */
1264
+			: $this->getRegistrationModel()->get_all($query_params);
1265
+	}
1266
+
1267
+
1268
+	/**
1269
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1270
+	 * Note: this listens to values on the request for some of the query parameters.
1271
+	 *
1272
+	 * @param array $request
1273
+	 * @param int   $per_page
1274
+	 * @param bool  $count
1275
+	 * @return array
1276
+	 * @throws EE_Error
1277
+	 * @throws InvalidArgumentException
1278
+	 * @throws InvalidDataTypeException
1279
+	 * @throws InvalidInterfaceException
1280
+	 */
1281
+	protected function _get_registration_query_parameters(
1282
+		$request = array(),
1283
+		$per_page = 10,
1284
+		$count = false
1285
+	) {
1286
+		/** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1287
+		$list_table_query_builder = $this->loader->getNew(
1288
+			'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1289
+			[ $request ]
1290
+		);
1291
+		return $list_table_query_builder->getQueryParams($per_page, $count);
1292
+	}
1293
+
1294
+
1295
+	public function get_registration_status_array()
1296
+	{
1297
+		return self::$_reg_status;
1298
+	}
1299
+
1300
+
1301
+
1302
+
1303
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1304
+	/**
1305
+	 *        generates HTML for the View Registration Details Admin page
1306
+	 *
1307
+	 * @access protected
1308
+	 * @return void
1309
+	 * @throws DomainException
1310
+	 * @throws EE_Error
1311
+	 * @throws InvalidArgumentException
1312
+	 * @throws InvalidDataTypeException
1313
+	 * @throws InvalidInterfaceException
1314
+	 * @throws EntityNotFoundException
1315
+	 * @throws ReflectionException
1316
+	 */
1317
+	protected function _registration_details()
1318
+	{
1319
+		$this->_template_args = array();
1320
+		$this->_set_registration_object();
1321
+		if (is_object($this->_registration)) {
1322
+			$transaction = $this->_registration->transaction()
1323
+				? $this->_registration->transaction()
1324
+				: EE_Transaction::new_instance();
1325
+			$this->_session = $transaction->session_data();
1326
+			$event_id = $this->_registration->event_ID();
1327
+			$this->_template_args['reg_nmbr']['value'] = $this->_registration->ID();
1328
+			$this->_template_args['reg_nmbr']['label'] = esc_html__('Registration Number', 'event_espresso');
1329
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1330
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1331
+			$this->_template_args['grand_total'] = $transaction->total();
1332
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
1333
+			// link back to overview
1334
+			$this->_template_args['reg_overview_url'] = REG_ADMIN_URL;
1335
+			$this->_template_args['registration'] = $this->_registration;
1336
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1337
+				array(
1338
+					'action'   => 'default',
1339
+					'event_id' => $event_id,
1340
+				),
1341
+				REG_ADMIN_URL
1342
+			);
1343
+			$this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1344
+				array(
1345
+					'action' => 'default',
1346
+					'EVT_ID' => $event_id,
1347
+					'page'   => 'espresso_transactions',
1348
+				),
1349
+				admin_url('admin.php')
1350
+			);
1351
+			$this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1352
+				array(
1353
+					'page'   => 'espresso_events',
1354
+					'action' => 'edit',
1355
+					'post'   => $event_id,
1356
+				),
1357
+				admin_url('admin.php')
1358
+			);
1359
+			// next and previous links
1360
+			$next_reg = $this->_registration->next(
1361
+				null,
1362
+				array(),
1363
+				'REG_ID'
1364
+			);
1365
+			$this->_template_args['next_registration'] = $next_reg
1366
+				? $this->_next_link(
1367
+					EE_Admin_Page::add_query_args_and_nonce(
1368
+						array(
1369
+							'action'  => 'view_registration',
1370
+							'_REG_ID' => $next_reg['REG_ID'],
1371
+						),
1372
+						REG_ADMIN_URL
1373
+					),
1374
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1375
+				)
1376
+				: '';
1377
+			$previous_reg = $this->_registration->previous(
1378
+				null,
1379
+				array(),
1380
+				'REG_ID'
1381
+			);
1382
+			$this->_template_args['previous_registration'] = $previous_reg
1383
+				? $this->_previous_link(
1384
+					EE_Admin_Page::add_query_args_and_nonce(
1385
+						array(
1386
+							'action'  => 'view_registration',
1387
+							'_REG_ID' => $previous_reg['REG_ID'],
1388
+						),
1389
+						REG_ADMIN_URL
1390
+					),
1391
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1392
+				)
1393
+				: '';
1394
+			// grab header
1395
+			$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1396
+			$this->_template_args['REG_ID'] = $this->_registration->ID();
1397
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1398
+				$template_path,
1399
+				$this->_template_args,
1400
+				true
1401
+			);
1402
+		} else {
1403
+			$this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1404
+		}
1405
+		// the details template wrapper
1406
+		$this->display_admin_page_with_sidebar();
1407
+	}
1408
+
1409
+
1410
+	/**
1411
+	 * @throws EE_Error
1412
+	 * @throws InvalidArgumentException
1413
+	 * @throws InvalidDataTypeException
1414
+	 * @throws InvalidInterfaceException
1415
+	 * @throws ReflectionException
1416
+	 * @since 4.10.2.p
1417
+	 */
1418
+	protected function _registration_details_metaboxes()
1419
+	{
1420
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1421
+		$this->_set_registration_object();
1422
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1423
+		add_meta_box(
1424
+			'edit-reg-status-mbox',
1425
+			esc_html__('Registration Status', 'event_espresso'),
1426
+			array($this, 'set_reg_status_buttons_metabox'),
1427
+			$this->wp_page_slug,
1428
+			'normal',
1429
+			'high'
1430
+		);
1431
+		add_meta_box(
1432
+			'edit-reg-details-mbox',
1433
+			esc_html__('Registration Details', 'event_espresso'),
1434
+			array($this, '_reg_details_meta_box'),
1435
+			$this->wp_page_slug,
1436
+			'normal',
1437
+			'high'
1438
+		);
1439
+		if ($attendee instanceof EE_Attendee
1440
+			&& EE_Registry::instance()->CAP->current_user_can(
1441
+				'ee_read_registration',
1442
+				'edit-reg-questions-mbox',
1443
+				$this->_registration->ID()
1444
+			)
1445
+		) {
1446
+			add_meta_box(
1447
+				'edit-reg-questions-mbox',
1448
+				esc_html__('Registration Form Answers', 'event_espresso'),
1449
+				array($this, '_reg_questions_meta_box'),
1450
+				$this->wp_page_slug,
1451
+				'normal',
1452
+				'high'
1453
+			);
1454
+		}
1455
+		add_meta_box(
1456
+			'edit-reg-registrant-mbox',
1457
+			esc_html__('Contact Details', 'event_espresso'),
1458
+			array($this, '_reg_registrant_side_meta_box'),
1459
+			$this->wp_page_slug,
1460
+			'side',
1461
+			'high'
1462
+		);
1463
+		if ($this->_registration->group_size() > 1) {
1464
+			add_meta_box(
1465
+				'edit-reg-attendees-mbox',
1466
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1467
+				array($this, '_reg_attendees_meta_box'),
1468
+				$this->wp_page_slug,
1469
+				'normal',
1470
+				'high'
1471
+			);
1472
+		}
1473
+	}
1474
+
1475
+
1476
+	/**
1477
+	 * set_reg_status_buttons_metabox
1478
+	 *
1479
+	 * @access protected
1480
+	 * @return string
1481
+	 * @throws EE_Error
1482
+	 * @throws EntityNotFoundException
1483
+	 * @throws InvalidArgumentException
1484
+	 * @throws InvalidDataTypeException
1485
+	 * @throws InvalidInterfaceException
1486
+	 * @throws ReflectionException
1487
+	 */
1488
+	public function set_reg_status_buttons_metabox()
1489
+	{
1490
+		$this->_set_registration_object();
1491
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1492
+		echo $change_reg_status_form->form_open(
1493
+			self::add_query_args_and_nonce(
1494
+				array(
1495
+					'action' => 'change_reg_status',
1496
+				),
1497
+				REG_ADMIN_URL
1498
+			)
1499
+		);
1500
+		echo $change_reg_status_form->get_html();
1501
+		echo $change_reg_status_form->form_close();
1502
+	}
1503
+
1504
+
1505
+	/**
1506
+	 * @return EE_Form_Section_Proper
1507
+	 * @throws EE_Error
1508
+	 * @throws InvalidArgumentException
1509
+	 * @throws InvalidDataTypeException
1510
+	 * @throws InvalidInterfaceException
1511
+	 * @throws EntityNotFoundException
1512
+	 * @throws ReflectionException
1513
+	 */
1514
+	protected function _generate_reg_status_change_form()
1515
+	{
1516
+		$reg_status_change_form_array = array(
1517
+			'name'            => 'reg_status_change_form',
1518
+			'html_id'         => 'reg-status-change-form',
1519
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1520
+			'subsections'     => array(
1521
+				'return'             => new EE_Hidden_Input(
1522
+					array(
1523
+						'name'    => 'return',
1524
+						'default' => 'view_registration',
1525
+					)
1526
+				),
1527
+				'REG_ID'             => new EE_Hidden_Input(
1528
+					array(
1529
+						'name'    => 'REG_ID',
1530
+						'default' => $this->_registration->ID(),
1531
+					)
1532
+				),
1533
+				'current_status'     => new EE_Form_Section_HTML(
1534
+					EEH_HTML::table(
1535
+						EEH_HTML::tr(
1536
+							EEH_HTML::th(
1537
+								EEH_HTML::label(
1538
+									EEH_HTML::strong(
1539
+										esc_html__('Current Registration Status', 'event_espresso')
1540
+									)
1541
+								)
1542
+							)
1543
+							. EEH_HTML::td(
1544
+								EEH_HTML::strong(
1545
+									$this->_registration->pretty_status(),
1546
+									'',
1547
+									'status-' . $this->_registration->status_ID(),
1548
+									'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1549
+								)
1550
+							)
1551
+						)
1552
+					)
1553
+				)
1554
+			)
1555
+		);
1556
+		if (EE_Registry::instance()->CAP->current_user_can(
1557
+			'ee_edit_registration',
1558
+			'toggle_registration_status',
1559
+			$this->_registration->ID()
1560
+		)) {
1561
+			$reg_status_change_form_array['subsections']['reg_status'] = new EE_Select_Input(
1562
+				$this->_get_reg_statuses(),
1563
+				array(
1564
+					'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1565
+					'default'         => $this->_registration->status_ID(),
1566
+				)
1567
+			);
1568
+			$reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1569
+				array(
1570
+					'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1571
+					'default'         => false,
1572
+					'html_help_text'  => esc_html__(
1573
+						'If set to "Yes", then the related messages will be sent to the registrant.',
1574
+						'event_espresso'
1575
+					)
1576
+				)
1577
+			);
1578
+			$reg_status_change_form_array['subsections']['submit'] = new EE_Submit_Input(
1579
+				array(
1580
+					'html_class'      => 'button-primary',
1581
+					'html_label_text' => '&nbsp;',
1582
+					'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1583
+				)
1584
+			);
1585
+		}
1586
+		return new EE_Form_Section_Proper($reg_status_change_form_array);
1587
+	}
1588
+
1589
+
1590
+	/**
1591
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1592
+	 *
1593
+	 * @return array
1594
+	 * @throws EE_Error
1595
+	 * @throws InvalidArgumentException
1596
+	 * @throws InvalidDataTypeException
1597
+	 * @throws InvalidInterfaceException
1598
+	 * @throws EntityNotFoundException
1599
+	 */
1600
+	protected function _get_reg_statuses()
1601
+	{
1602
+		$reg_status_array = $this->getRegistrationModel()->reg_status_array();
1603
+		unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1604
+		// get current reg status
1605
+		$current_status = $this->_registration->status_ID();
1606
+		// is registration for free event? This will determine whether to display the pending payment option
1607
+		if ($current_status !== EEM_Registration::status_id_pending_payment
1608
+			&& EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1609
+		) {
1610
+			unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1611
+		}
1612
+		return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1613
+	}
1614
+
1615
+
1616
+	/**
1617
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1618
+	 *
1619
+	 * @param bool $status REG status given for changing registrations to.
1620
+	 * @param bool $notify Whether to send messages notifications or not.
1621
+	 * @return array (array with reg_id(s) updated and whether update was successful.
1622
+	 * @throws DomainException
1623
+	 * @throws EE_Error
1624
+	 * @throws EntityNotFoundException
1625
+	 * @throws InvalidArgumentException
1626
+	 * @throws InvalidDataTypeException
1627
+	 * @throws InvalidInterfaceException
1628
+	 * @throws ReflectionException
1629
+	 * @throws RuntimeException
1630
+	 */
1631
+	protected function _set_registration_status_from_request($status = false, $notify = false)
1632
+	{
1633
+		if (isset($this->_req_data['reg_status_change_form'])) {
1634
+			$REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1635
+				? (array) $this->_req_data['reg_status_change_form']['REG_ID']
1636
+				: array();
1637
+		} else {
1638
+			$REG_IDs = isset($this->_req_data['_REG_ID'])
1639
+				? (array) $this->_req_data['_REG_ID']
1640
+				: array();
1641
+		}
1642
+		// sanitize $REG_IDs
1643
+		$REG_IDs = array_map('absint', $REG_IDs);
1644
+		// and remove empty entries
1645
+		$REG_IDs = array_filter($REG_IDs);
1646
+
1647
+		$result = $this->_set_registration_status($REG_IDs, $status, $notify);
1648
+
1649
+		/**
1650
+		 * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1651
+		 * Currently this value is used downstream by the _process_resend_registration method.
1652
+		 *
1653
+		 * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1654
+		 * @param bool                     $status           The status registrations were changed to.
1655
+		 * @param bool                     $success          If the status was changed successfully for all registrations.
1656
+		 * @param Registrations_Admin_Page $admin_page_object
1657
+		 */
1658
+		$this->_req_data['_REG_ID'] = apply_filters(
1659
+			'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1660
+			$result['REG_ID'],
1661
+			$status,
1662
+			$result['success'],
1663
+			$this
1664
+		);
1665
+
1666
+		// notify?
1667
+		if ($notify
1668
+			&& $result['success']
1669
+			&& ! empty($this->_req_data['_REG_ID'])
1670
+			&& EE_Registry::instance()->CAP->current_user_can(
1671
+				'ee_send_message',
1672
+				'espresso_registrations_resend_registration'
1673
+			)
1674
+		) {
1675
+			$this->_process_resend_registration();
1676
+		}
1677
+		return $result;
1678
+	}
1679
+
1680
+
1681
+	/**
1682
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1683
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1684
+	 *
1685
+	 * @param array  $REG_IDs
1686
+	 * @param string $status
1687
+	 * @param bool   $notify  Used to indicate whether notification was requested or not.  This determines the context
1688
+	 *                        slug sent with setting the registration status.
1689
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1690
+	 * @throws EE_Error
1691
+	 * @throws InvalidArgumentException
1692
+	 * @throws InvalidDataTypeException
1693
+	 * @throws InvalidInterfaceException
1694
+	 * @throws ReflectionException
1695
+	 * @throws RuntimeException
1696
+	 * @throws EntityNotFoundException
1697
+	 * @throws DomainException
1698
+	 */
1699
+	protected function _set_registration_status($REG_IDs = array(), $status = '', $notify = false)
1700
+	{
1701
+		$success = false;
1702
+		// typecast $REG_IDs
1703
+		$REG_IDs = (array) $REG_IDs;
1704
+		if (! empty($REG_IDs)) {
1705
+			$success = true;
1706
+			// set default status if none is passed
1707
+			$status = $status ? $status : EEM_Registration::status_id_pending_payment;
1708
+			$status_context = $notify
1709
+				? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1710
+				: Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1711
+			// loop through REG_ID's and change status
1712
+			foreach ($REG_IDs as $REG_ID) {
1713
+				$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1714
+				if ($registration instanceof EE_Registration) {
1715
+					$registration->set_status(
1716
+						$status,
1717
+						false,
1718
+						new Context(
1719
+							$status_context,
1720
+							esc_html__(
1721
+								'Manually triggered status change on a Registration Admin Page route.',
1722
+								'event_espresso'
1723
+							)
1724
+						)
1725
+					);
1726
+					$result = $registration->save();
1727
+					// verifying explicit fails because update *may* just return 0 for 0 rows affected
1728
+					$success = $result !== false ? $success : false;
1729
+				}
1730
+			}
1731
+		}
1732
+
1733
+		// return $success and processed registrations
1734
+		return array('REG_ID' => $REG_IDs, 'success' => $success);
1735
+	}
1736
+
1737
+
1738
+	/**
1739
+	 * Common logic for setting up success message and redirecting to appropriate route
1740
+	 *
1741
+	 * @param string $STS_ID status id for the registration changed to
1742
+	 * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1743
+	 * @return void
1744
+	 * @throws DomainException
1745
+	 * @throws EE_Error
1746
+	 * @throws EntityNotFoundException
1747
+	 * @throws InvalidArgumentException
1748
+	 * @throws InvalidDataTypeException
1749
+	 * @throws InvalidInterfaceException
1750
+	 * @throws ReflectionException
1751
+	 * @throws RuntimeException
1752
+	 */
1753
+	protected function _reg_status_change_return($STS_ID, $notify = false)
1754
+	{
1755
+		$result = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1756
+			: array('success' => false);
1757
+		$success = isset($result['success']) && $result['success'];
1758
+		// setup success message
1759
+		if ($success) {
1760
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1761
+				$msg = sprintf(
1762
+					esc_html__('Registration status has been set to %s', 'event_espresso'),
1763
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1764
+				);
1765
+			} else {
1766
+				$msg = sprintf(
1767
+					esc_html__('Registrations have been set to %s.', 'event_espresso'),
1768
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1769
+				);
1770
+			}
1771
+			EE_Error::add_success($msg);
1772
+		} else {
1773
+			EE_Error::add_error(
1774
+				esc_html__(
1775
+					'Something went wrong, and the status was not changed',
1776
+					'event_espresso'
1777
+				),
1778
+				__FILE__,
1779
+				__LINE__,
1780
+				__FUNCTION__
1781
+			);
1782
+		}
1783
+		if (isset($this->_req_data['return']) && $this->_req_data['return'] === 'view_registration') {
1784
+			$route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1785
+		} else {
1786
+			$route = array('action' => 'default');
1787
+		}
1788
+		$route = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1789
+		$this->_redirect_after_action($success, '', '', $route, true);
1790
+	}
1791
+
1792
+
1793
+	/**
1794
+	 * incoming reg status change from reg details page.
1795
+	 *
1796
+	 * @return void
1797
+	 * @throws EE_Error
1798
+	 * @throws EntityNotFoundException
1799
+	 * @throws InvalidArgumentException
1800
+	 * @throws InvalidDataTypeException
1801
+	 * @throws InvalidInterfaceException
1802
+	 * @throws ReflectionException
1803
+	 * @throws RuntimeException
1804
+	 * @throws DomainException
1805
+	 */
1806
+	protected function _change_reg_status()
1807
+	{
1808
+		$this->_req_data['return'] = 'view_registration';
1809
+		// set notify based on whether the send notifications toggle is set or not
1810
+		$notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1811
+		// $notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1812
+		$this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1813
+			? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1814
+		switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1815
+			case EEM_Registration::status_id_approved:
1816
+			case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1817
+				$this->approve_registration($notify);
1818
+				break;
1819
+			case EEM_Registration::status_id_pending_payment:
1820
+			case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1821
+				$this->pending_registration($notify);
1822
+				break;
1823
+			case EEM_Registration::status_id_not_approved:
1824
+			case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1825
+				$this->not_approve_registration($notify);
1826
+				break;
1827
+			case EEM_Registration::status_id_declined:
1828
+			case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1829
+				$this->decline_registration($notify);
1830
+				break;
1831
+			case EEM_Registration::status_id_cancelled:
1832
+			case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1833
+				$this->cancel_registration($notify);
1834
+				break;
1835
+			case EEM_Registration::status_id_wait_list:
1836
+			case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1837
+				$this->wait_list_registration($notify);
1838
+				break;
1839
+			case EEM_Registration::status_id_incomplete:
1840
+			default:
1841
+				$result['success'] = false;
1842
+				unset($this->_req_data['return']);
1843
+				$this->_reg_status_change_return('', false);
1844
+				break;
1845
+		}
1846
+	}
1847
+
1848
+
1849
+	/**
1850
+	 * Callback for bulk action routes.
1851
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1852
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
1853
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1854
+	 * when an action is happening on just a single registration).
1855
+	 *
1856
+	 * @param      $action
1857
+	 * @param bool $notify
1858
+	 */
1859
+	protected function bulk_action_on_registrations($action, $notify = false)
1860
+	{
1861
+		do_action(
1862
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1863
+			$this,
1864
+			$action,
1865
+			$notify
1866
+		);
1867
+		$method = $action . '_registration';
1868
+		if (method_exists($this, $method)) {
1869
+			$this->$method($notify);
1870
+		}
1871
+	}
1872
+
1873
+
1874
+	/**
1875
+	 * approve_registration
1876
+	 *
1877
+	 * @access protected
1878
+	 * @param bool $notify whether or not to notify the registrant about their approval.
1879
+	 * @return void
1880
+	 * @throws EE_Error
1881
+	 * @throws EntityNotFoundException
1882
+	 * @throws InvalidArgumentException
1883
+	 * @throws InvalidDataTypeException
1884
+	 * @throws InvalidInterfaceException
1885
+	 * @throws ReflectionException
1886
+	 * @throws RuntimeException
1887
+	 * @throws DomainException
1888
+	 */
1889
+	protected function approve_registration($notify = false)
1890
+	{
1891
+		$this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1892
+	}
1893
+
1894
+
1895
+	/**
1896
+	 *        decline_registration
1897
+	 *
1898
+	 * @access protected
1899
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1900
+	 * @return void
1901
+	 * @throws EE_Error
1902
+	 * @throws EntityNotFoundException
1903
+	 * @throws InvalidArgumentException
1904
+	 * @throws InvalidDataTypeException
1905
+	 * @throws InvalidInterfaceException
1906
+	 * @throws ReflectionException
1907
+	 * @throws RuntimeException
1908
+	 * @throws DomainException
1909
+	 */
1910
+	protected function decline_registration($notify = false)
1911
+	{
1912
+		$this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1913
+	}
1914
+
1915
+
1916
+	/**
1917
+	 *        cancel_registration
1918
+	 *
1919
+	 * @access protected
1920
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1921
+	 * @return void
1922
+	 * @throws EE_Error
1923
+	 * @throws EntityNotFoundException
1924
+	 * @throws InvalidArgumentException
1925
+	 * @throws InvalidDataTypeException
1926
+	 * @throws InvalidInterfaceException
1927
+	 * @throws ReflectionException
1928
+	 * @throws RuntimeException
1929
+	 * @throws DomainException
1930
+	 */
1931
+	protected function cancel_registration($notify = false)
1932
+	{
1933
+		$this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1934
+	}
1935
+
1936
+
1937
+	/**
1938
+	 *        not_approve_registration
1939
+	 *
1940
+	 * @access protected
1941
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1942
+	 * @return void
1943
+	 * @throws EE_Error
1944
+	 * @throws EntityNotFoundException
1945
+	 * @throws InvalidArgumentException
1946
+	 * @throws InvalidDataTypeException
1947
+	 * @throws InvalidInterfaceException
1948
+	 * @throws ReflectionException
1949
+	 * @throws RuntimeException
1950
+	 * @throws DomainException
1951
+	 */
1952
+	protected function not_approve_registration($notify = false)
1953
+	{
1954
+		$this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1955
+	}
1956
+
1957
+
1958
+	/**
1959
+	 *        decline_registration
1960
+	 *
1961
+	 * @access protected
1962
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1963
+	 * @return void
1964
+	 * @throws EE_Error
1965
+	 * @throws EntityNotFoundException
1966
+	 * @throws InvalidArgumentException
1967
+	 * @throws InvalidDataTypeException
1968
+	 * @throws InvalidInterfaceException
1969
+	 * @throws ReflectionException
1970
+	 * @throws RuntimeException
1971
+	 * @throws DomainException
1972
+	 */
1973
+	protected function pending_registration($notify = false)
1974
+	{
1975
+		$this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1976
+	}
1977
+
1978
+
1979
+	/**
1980
+	 * waitlist_registration
1981
+	 *
1982
+	 * @access protected
1983
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1984
+	 * @return void
1985
+	 * @throws EE_Error
1986
+	 * @throws EntityNotFoundException
1987
+	 * @throws InvalidArgumentException
1988
+	 * @throws InvalidDataTypeException
1989
+	 * @throws InvalidInterfaceException
1990
+	 * @throws ReflectionException
1991
+	 * @throws RuntimeException
1992
+	 * @throws DomainException
1993
+	 */
1994
+	protected function wait_list_registration($notify = false)
1995
+	{
1996
+		$this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1997
+	}
1998
+
1999
+
2000
+	/**
2001
+	 *        generates HTML for the Registration main meta box
2002
+	 *
2003
+	 * @access public
2004
+	 * @return void
2005
+	 * @throws DomainException
2006
+	 * @throws EE_Error
2007
+	 * @throws InvalidArgumentException
2008
+	 * @throws InvalidDataTypeException
2009
+	 * @throws InvalidInterfaceException
2010
+	 * @throws ReflectionException
2011
+	 * @throws EntityNotFoundException
2012
+	 */
2013
+	public function _reg_details_meta_box()
2014
+	{
2015
+		EEH_Autoloader::register_line_item_display_autoloaders();
2016
+		EEH_Autoloader::register_line_item_filter_autoloaders();
2017
+		EE_Registry::instance()->load_helper('Line_Item');
2018
+		$transaction = $this->_registration->transaction() ? $this->_registration->transaction()
2019
+			: EE_Transaction::new_instance();
2020
+		$this->_session = $transaction->session_data();
2021
+		$filters = new EE_Line_Item_Filter_Collection();
2022
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2023
+		$filters->add(new EE_Non_Zero_Line_Item_Filter());
2024
+		$line_item_filter_processor = new EE_Line_Item_Filter_Processor(
2025
+			$filters,
2026
+			$transaction->total_line_item()
2027
+		);
2028
+		$filtered_line_item_tree = $line_item_filter_processor->process();
2029
+		$line_item_display = new EE_Line_Item_Display(
2030
+			'reg_admin_table',
2031
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2032
+		);
2033
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2034
+			$filtered_line_item_tree,
2035
+			array('EE_Registration' => $this->_registration)
2036
+		);
2037
+		$attendee = $this->_registration->attendee();
2038
+		if (EE_Registry::instance()->CAP->current_user_can(
2039
+			'ee_read_transaction',
2040
+			'espresso_transactions_view_transaction'
2041
+		)) {
2042
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2043
+				EE_Admin_Page::add_query_args_and_nonce(
2044
+					array(
2045
+						'action' => 'view_transaction',
2046
+						'TXN_ID' => $transaction->ID(),
2047
+					),
2048
+					TXN_ADMIN_URL
2049
+				),
2050
+				esc_html__(' View Transaction', 'event_espresso'),
2051
+				'button secondary-button right',
2052
+				'dashicons dashicons-cart'
2053
+			);
2054
+		} else {
2055
+			$this->_template_args['view_transaction_button'] = '';
2056
+		}
2057
+		if ($attendee instanceof EE_Attendee
2058
+			&& EE_Registry::instance()->CAP->current_user_can(
2059
+				'ee_send_message',
2060
+				'espresso_registrations_resend_registration'
2061
+			)
2062
+		) {
2063
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2064
+				EE_Admin_Page::add_query_args_and_nonce(
2065
+					array(
2066
+						'action'      => 'resend_registration',
2067
+						'_REG_ID'     => $this->_registration->ID(),
2068
+						'redirect_to' => 'view_registration',
2069
+					),
2070
+					REG_ADMIN_URL
2071
+				),
2072
+				esc_html__(' Resend Registration', 'event_espresso'),
2073
+				'button secondary-button right',
2074
+				'dashicons dashicons-email-alt'
2075
+			);
2076
+		} else {
2077
+			$this->_template_args['resend_registration_button'] = '';
2078
+		}
2079
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2080
+		$payment = $transaction->get_first_related('Payment');
2081
+		$payment = ! $payment instanceof EE_Payment
2082
+			? EE_Payment::new_instance()
2083
+			: $payment;
2084
+		$payment_method = $payment->get_first_related('Payment_Method');
2085
+		$payment_method = ! $payment_method instanceof EE_Payment_Method
2086
+			? EE_Payment_Method::new_instance()
2087
+			: $payment_method;
2088
+		$reg_details = array(
2089
+			'payment_method'       => $payment_method->name(),
2090
+			'response_msg'         => $payment->gateway_response(),
2091
+			'registration_id'      => $this->_registration->get('REG_code'),
2092
+			'registration_session' => $this->_registration->session_ID(),
2093
+			'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2094
+			'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2095
+		);
2096
+		if (isset($reg_details['registration_id'])) {
2097
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2098
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2099
+				'Registration ID',
2100
+				'event_espresso'
2101
+			);
2102
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2103
+		}
2104
+		if (isset($reg_details['payment_method'])) {
2105
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2106
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2107
+				'Most Recent Payment Method',
2108
+				'event_espresso'
2109
+			);
2110
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2111
+			$this->_template_args['reg_details']['response_msg']['value'] = $reg_details['response_msg'];
2112
+			$this->_template_args['reg_details']['response_msg']['label'] = esc_html__(
2113
+				'Payment method response',
2114
+				'event_espresso'
2115
+			);
2116
+			$this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2117
+		}
2118
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2119
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2120
+			'Registration Session',
2121
+			'event_espresso'
2122
+		);
2123
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2124
+		$this->_template_args['reg_details']['ip_address']['value'] = $reg_details['ip_address'];
2125
+		$this->_template_args['reg_details']['ip_address']['label'] = esc_html__(
2126
+			'Registration placed from IP',
2127
+			'event_espresso'
2128
+		);
2129
+		$this->_template_args['reg_details']['ip_address']['class'] = 'regular-text';
2130
+		$this->_template_args['reg_details']['user_agent']['value'] = $reg_details['user_agent'];
2131
+		$this->_template_args['reg_details']['user_agent']['label'] = esc_html__(
2132
+			'Registrant User Agent',
2133
+			'event_espresso'
2134
+		);
2135
+		$this->_template_args['reg_details']['user_agent']['class'] = 'large-text';
2136
+		$this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
2137
+			array(
2138
+				'action'   => 'default',
2139
+				'event_id' => $this->_registration->event_ID(),
2140
+			),
2141
+			REG_ADMIN_URL
2142
+		);
2143
+		$this->_template_args['REG_ID'] = $this->_registration->ID();
2144
+		$this->_template_args['event_id'] = $this->_registration->event_ID();
2145
+		$template_path =
2146
+			REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2147
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2148
+	}
2149
+
2150
+
2151
+	/**
2152
+	 * generates HTML for the Registration Questions meta box.
2153
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2154
+	 * otherwise uses new forms system
2155
+	 *
2156
+	 * @access public
2157
+	 * @return void
2158
+	 * @throws DomainException
2159
+	 * @throws EE_Error
2160
+	 * @throws InvalidArgumentException
2161
+	 * @throws InvalidDataTypeException
2162
+	 * @throws InvalidInterfaceException
2163
+	 * @throws ReflectionException
2164
+	 */
2165
+	public function _reg_questions_meta_box()
2166
+	{
2167
+		// allow someone to override this method entirely
2168
+		if (apply_filters(
2169
+			'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2170
+			true,
2171
+			$this,
2172
+			$this->_registration
2173
+		)) {
2174
+			$form = $this->_get_reg_custom_questions_form(
2175
+				$this->_registration->ID()
2176
+			);
2177
+			$this->_template_args['att_questions'] = count($form->subforms()) > 0
2178
+				? $form->get_html_and_js()
2179
+				: '';
2180
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2181
+			$this->_template_args['REG_ID'] = $this->_registration->ID();
2182
+			$template_path =
2183
+				REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2184
+			echo EEH_Template::display_template($template_path, $this->_template_args, true);
2185
+		}
2186
+	}
2187
+
2188
+
2189
+	/**
2190
+	 * form_before_question_group
2191
+	 *
2192
+	 * @deprecated    as of 4.8.32.rc.000
2193
+	 * @access        public
2194
+	 * @param        string $output
2195
+	 * @return        string
2196
+	 */
2197
+	public function form_before_question_group($output)
2198
+	{
2199
+		EE_Error::doing_it_wrong(
2200
+			__CLASS__ . '::' . __FUNCTION__,
2201
+			esc_html__(
2202
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2203
+				'event_espresso'
2204
+			),
2205
+			'4.8.32.rc.000'
2206
+		);
2207
+		return '
2208 2208
 	<table class="form-table ee-width-100">
2209 2209
 		<tbody>
2210 2210
 			';
2211
-    }
2212
-
2213
-
2214
-    /**
2215
-     * form_after_question_group
2216
-     *
2217
-     * @deprecated    as of 4.8.32.rc.000
2218
-     * @access        public
2219
-     * @param        string $output
2220
-     * @return        string
2221
-     */
2222
-    public function form_after_question_group($output)
2223
-    {
2224
-        EE_Error::doing_it_wrong(
2225
-            __CLASS__ . '::' . __FUNCTION__,
2226
-            esc_html__(
2227
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2228
-                'event_espresso'
2229
-            ),
2230
-            '4.8.32.rc.000'
2231
-        );
2232
-        return '
2211
+	}
2212
+
2213
+
2214
+	/**
2215
+	 * form_after_question_group
2216
+	 *
2217
+	 * @deprecated    as of 4.8.32.rc.000
2218
+	 * @access        public
2219
+	 * @param        string $output
2220
+	 * @return        string
2221
+	 */
2222
+	public function form_after_question_group($output)
2223
+	{
2224
+		EE_Error::doing_it_wrong(
2225
+			__CLASS__ . '::' . __FUNCTION__,
2226
+			esc_html__(
2227
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2228
+				'event_espresso'
2229
+			),
2230
+			'4.8.32.rc.000'
2231
+		);
2232
+		return '
2233 2233
 			<tr class="hide-if-no-js">
2234 2234
 				<th> </th>
2235 2235
 				<td class="reg-admin-edit-attendee-question-td">
2236 2236
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" title="'
2237
-               . esc_attr__('click to edit question', 'event_espresso')
2238
-               . '">
2237
+			   . esc_attr__('click to edit question', 'event_espresso')
2238
+			   . '">
2239 2239
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2240
-               . esc_html__('edit the above question group', 'event_espresso')
2241
-               . '</span>
2240
+			   . esc_html__('edit the above question group', 'event_espresso')
2241
+			   . '</span>
2242 2242
 						<div class="dashicons dashicons-edit"></div>
2243 2243
 					</a>
2244 2244
 				</td>
@@ -2246,642 +2246,642 @@  discard block
 block discarded – undo
2246 2246
 		</tbody>
2247 2247
 	</table>
2248 2248
 ';
2249
-    }
2250
-
2251
-
2252
-    /**
2253
-     * form_form_field_label_wrap
2254
-     *
2255
-     * @deprecated    as of 4.8.32.rc.000
2256
-     * @access        public
2257
-     * @param        string $label
2258
-     * @return        string
2259
-     */
2260
-    public function form_form_field_label_wrap($label)
2261
-    {
2262
-        EE_Error::doing_it_wrong(
2263
-            __CLASS__ . '::' . __FUNCTION__,
2264
-            esc_html__(
2265
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2266
-                'event_espresso'
2267
-            ),
2268
-            '4.8.32.rc.000'
2269
-        );
2270
-        return '
2249
+	}
2250
+
2251
+
2252
+	/**
2253
+	 * form_form_field_label_wrap
2254
+	 *
2255
+	 * @deprecated    as of 4.8.32.rc.000
2256
+	 * @access        public
2257
+	 * @param        string $label
2258
+	 * @return        string
2259
+	 */
2260
+	public function form_form_field_label_wrap($label)
2261
+	{
2262
+		EE_Error::doing_it_wrong(
2263
+			__CLASS__ . '::' . __FUNCTION__,
2264
+			esc_html__(
2265
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2266
+				'event_espresso'
2267
+			),
2268
+			'4.8.32.rc.000'
2269
+		);
2270
+		return '
2271 2271
 			<tr>
2272 2272
 				<th>
2273 2273
 					' . $label . '
2274 2274
 				</th>';
2275
-    }
2276
-
2277
-
2278
-    /**
2279
-     * form_form_field_input__wrap
2280
-     *
2281
-     * @deprecated    as of 4.8.32.rc.000
2282
-     * @access        public
2283
-     * @param        string $input
2284
-     * @return        string
2285
-     */
2286
-    public function form_form_field_input__wrap($input)
2287
-    {
2288
-        EE_Error::doing_it_wrong(
2289
-            __CLASS__ . '::' . __FUNCTION__,
2290
-            esc_html__(
2291
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2292
-                'event_espresso'
2293
-            ),
2294
-            '4.8.32.rc.000'
2295
-        );
2296
-        return '
2275
+	}
2276
+
2277
+
2278
+	/**
2279
+	 * form_form_field_input__wrap
2280
+	 *
2281
+	 * @deprecated    as of 4.8.32.rc.000
2282
+	 * @access        public
2283
+	 * @param        string $input
2284
+	 * @return        string
2285
+	 */
2286
+	public function form_form_field_input__wrap($input)
2287
+	{
2288
+		EE_Error::doing_it_wrong(
2289
+			__CLASS__ . '::' . __FUNCTION__,
2290
+			esc_html__(
2291
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2292
+				'event_espresso'
2293
+			),
2294
+			'4.8.32.rc.000'
2295
+		);
2296
+		return '
2297 2297
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2298 2298
 					' . $input . '
2299 2299
 				</td>
2300 2300
 			</tr>';
2301
-    }
2302
-
2303
-
2304
-    /**
2305
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2306
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2307
-     * to display the page
2308
-     *
2309
-     * @access protected
2310
-     * @return void
2311
-     * @throws EE_Error
2312
-     * @throws InvalidArgumentException
2313
-     * @throws InvalidDataTypeException
2314
-     * @throws InvalidInterfaceException
2315
-     * @throws ReflectionException
2316
-     */
2317
-    protected function _update_attendee_registration_form()
2318
-    {
2319
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2320
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2321
-            $REG_ID = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2322
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2323
-            if ($success) {
2324
-                $what = esc_html__('Registration Form', 'event_espresso');
2325
-                $route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2326
-                    : array('action' => 'default');
2327
-                $this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2328
-            }
2329
-        }
2330
-    }
2331
-
2332
-
2333
-    /**
2334
-     * Gets the form for saving registrations custom questions (if done
2335
-     * previously retrieves the cached form object, which may have validation errors in it)
2336
-     *
2337
-     * @param int $REG_ID
2338
-     * @return EE_Registration_Custom_Questions_Form
2339
-     * @throws EE_Error
2340
-     * @throws InvalidArgumentException
2341
-     * @throws InvalidDataTypeException
2342
-     * @throws InvalidInterfaceException
2343
-     */
2344
-    protected function _get_reg_custom_questions_form($REG_ID)
2345
-    {
2346
-        if (! $this->_reg_custom_questions_form) {
2347
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2348
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2349
-                $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2350
-            );
2351
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2352
-        }
2353
-        return $this->_reg_custom_questions_form;
2354
-    }
2355
-
2356
-
2357
-    /**
2358
-     * Saves
2359
-     *
2360
-     * @access private
2361
-     * @param bool $REG_ID
2362
-     * @return bool
2363
-     * @throws EE_Error
2364
-     * @throws InvalidArgumentException
2365
-     * @throws InvalidDataTypeException
2366
-     * @throws InvalidInterfaceException
2367
-     * @throws ReflectionException
2368
-     */
2369
-    private function _save_reg_custom_questions_form($REG_ID = false)
2370
-    {
2371
-        if (! $REG_ID) {
2372
-            EE_Error::add_error(
2373
-                esc_html__(
2374
-                    'An error occurred. No registration ID was received.',
2375
-                    'event_espresso'
2376
-                ),
2377
-                __FILE__,
2378
-                __FUNCTION__,
2379
-                __LINE__
2380
-            );
2381
-        }
2382
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2383
-        $form->receive_form_submission($this->_req_data);
2384
-        $success = false;
2385
-        if ($form->is_valid()) {
2386
-            foreach ($form->subforms() as $question_group_id => $question_group_form) {
2387
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2388
-                    $where_conditions = array(
2389
-                        'QST_ID' => $question_id,
2390
-                        'REG_ID' => $REG_ID,
2391
-                    );
2392
-                    $possibly_new_values = array(
2393
-                        'ANS_value' => $input->normalized_value(),
2394
-                    );
2395
-                    $answer = EEM_Answer::instance()->get_one(array($where_conditions));
2396
-                    if ($answer instanceof EE_Answer) {
2397
-                        $success = $answer->save($possibly_new_values);
2398
-                    } else {
2399
-                        // insert it then
2400
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2401
-                        $answer = EE_Answer::new_instance($cols_n_vals);
2402
-                        $success = $answer->save();
2403
-                    }
2404
-                }
2405
-            }
2406
-        } else {
2407
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2408
-        }
2409
-        return $success;
2410
-    }
2411
-
2412
-
2413
-    /**
2414
-     *        generates HTML for the Registration main meta box
2415
-     *
2416
-     * @access public
2417
-     * @return void
2418
-     * @throws DomainException
2419
-     * @throws EE_Error
2420
-     * @throws InvalidArgumentException
2421
-     * @throws InvalidDataTypeException
2422
-     * @throws InvalidInterfaceException
2423
-     * @throws ReflectionException
2424
-     */
2425
-    public function _reg_attendees_meta_box()
2426
-    {
2427
-        $REG = $this->getRegistrationModel();
2428
-        // get all other registrations on this transaction, and cache
2429
-        // the attendees for them so we don't have to run another query using force_join
2430
-        $registrations = $REG->get_all(
2431
-            array(
2432
-                array(
2433
-                    'TXN_ID' => $this->_registration->transaction_ID(),
2434
-                    'REG_ID' => array('!=', $this->_registration->ID()),
2435
-                ),
2436
-                'force_join' => array('Attendee'),
2437
-                'default_where_conditions' => 'other_models_only',
2438
-            )
2439
-        );
2440
-        $this->_template_args['attendees'] = array();
2441
-        $this->_template_args['attendee_notice'] = '';
2442
-        if (empty($registrations)
2443
-            || (is_array($registrations)
2444
-                && ! EEH_Array::get_one_item_from_array($registrations))
2445
-        ) {
2446
-            EE_Error::add_error(
2447
-                esc_html__(
2448
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2449
-                    'event_espresso'
2450
-                ),
2451
-                __FILE__,
2452
-                __FUNCTION__,
2453
-                __LINE__
2454
-            );
2455
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2456
-        } else {
2457
-            $att_nmbr = 1;
2458
-            foreach ($registrations as $registration) {
2459
-                /* @var $registration EE_Registration */
2460
-                $attendee = $registration->attendee()
2461
-                    ? $registration->attendee()
2462
-                    : $this->getAttendeeModel()->create_default_object();
2463
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID'] = $registration->status_ID();
2464
-                $this->_template_args['attendees'][ $att_nmbr ]['fname'] = $attendee->fname();
2465
-                $this->_template_args['attendees'][ $att_nmbr ]['lname'] = $attendee->lname();
2466
-                $this->_template_args['attendees'][ $att_nmbr ]['email'] = $attendee->email();
2467
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2468
-                $this->_template_args['attendees'][ $att_nmbr ]['address'] = implode(
2469
-                    ', ',
2470
-                    $attendee->full_address_as_array()
2471
-                );
2472
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link'] = self::add_query_args_and_nonce(
2473
-                    array(
2474
-                        'action' => 'edit_attendee',
2475
-                        'post'   => $attendee->ID(),
2476
-                    ),
2477
-                    REG_ADMIN_URL
2478
-                );
2479
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name'] = $registration->event_obj() instanceof EE_Event
2480
-                    ? $registration->event_obj()->name()
2481
-                    : '';
2482
-                $att_nmbr++;
2483
-            }
2484
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2485
-        }
2486
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2487
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2488
-    }
2489
-
2490
-
2491
-    /**
2492
-     *        generates HTML for the Edit Registration side meta box
2493
-     *
2494
-     * @access public
2495
-     * @return void
2496
-     * @throws DomainException
2497
-     * @throws EE_Error
2498
-     * @throws InvalidArgumentException
2499
-     * @throws InvalidDataTypeException
2500
-     * @throws InvalidInterfaceException
2501
-     * @throws ReflectionException
2502
-     */
2503
-    public function _reg_registrant_side_meta_box()
2504
-    {
2505
-        /*@var $attendee EE_Attendee */
2506
-        $att_check = $this->_registration->attendee();
2507
-        $attendee = $att_check instanceof EE_Attendee
2508
-            ? $att_check
2509
-            : $this->getAttendeeModel()->create_default_object();
2510
-        // now let's determine if this is not the primary registration.  If it isn't then we set the
2511
-        // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2512
-        // primary registration object (that way we know if we need to show create button or not)
2513
-        if (! $this->_registration->is_primary_registrant()) {
2514
-            $primary_registration = $this->_registration->get_primary_registration();
2515
-            $primary_attendee = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2516
-                : null;
2517
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2518
-                // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2519
-                // custom attendee object so let's not worry about the primary reg.
2520
-                $primary_registration = null;
2521
-            }
2522
-        } else {
2523
-            $primary_registration = null;
2524
-        }
2525
-        $this->_template_args['ATT_ID'] = $attendee->ID();
2526
-        $this->_template_args['fname'] = $attendee->fname();
2527
-        $this->_template_args['lname'] = $attendee->lname();
2528
-        $this->_template_args['email'] = $attendee->email();
2529
-        $this->_template_args['phone'] = $attendee->phone();
2530
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2531
-        // edit link
2532
-        $this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(
2533
-            array(
2534
-                'action' => 'edit_attendee',
2535
-                'post'   => $attendee->ID(),
2536
-            ),
2537
-            REG_ADMIN_URL
2538
-        );
2539
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2540
-        // create link
2541
-        $this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2542
-            ? EE_Admin_Page::add_query_args_and_nonce(
2543
-                array(
2544
-                    'action'  => 'duplicate_attendee',
2545
-                    '_REG_ID' => $this->_registration->ID(),
2546
-                ),
2547
-                REG_ADMIN_URL
2548
-            ) : '';
2549
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2550
-        $this->_template_args['att_check'] = $att_check;
2551
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2552
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2553
-    }
2554
-
2555
-
2556
-    /**
2557
-     * trash or restore registrations
2558
-     *
2559
-     * @param  boolean $trash whether to archive or restore
2560
-     * @return void
2561
-     * @throws EE_Error
2562
-     * @throws InvalidArgumentException
2563
-     * @throws InvalidDataTypeException
2564
-     * @throws InvalidInterfaceException
2565
-     * @throws RuntimeException
2566
-     * @access protected
2567
-     */
2568
-    protected function _trash_or_restore_registrations($trash = true)
2569
-    {
2570
-        // if empty _REG_ID then get out because there's nothing to do
2571
-        if (empty($this->_req_data['_REG_ID'])) {
2572
-            EE_Error::add_error(
2573
-                sprintf(
2574
-                    esc_html__(
2575
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2576
-                        'event_espresso'
2577
-                    ),
2578
-                    $trash ? 'trash' : 'restore'
2579
-                ),
2580
-                __FILE__,
2581
-                __LINE__,
2582
-                __FUNCTION__
2583
-            );
2584
-            $this->_redirect_after_action(false, '', '', array(), true);
2585
-        }
2586
-        $success = 0;
2587
-        $overwrite_msgs = false;
2588
-        // Checkboxes
2589
-        if (! is_array($this->_req_data['_REG_ID'])) {
2590
-            $this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2591
-        }
2592
-        $reg_count = count($this->_req_data['_REG_ID']);
2593
-        // cycle thru checkboxes
2594
-        foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2595
-            /** @var EE_Registration $REG */
2596
-            $REG = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2597
-            $payments = $REG->registration_payments();
2598
-            if (! empty($payments)) {
2599
-                $name = $REG->attendee() instanceof EE_Attendee
2600
-                    ? $REG->attendee()->full_name()
2601
-                    : esc_html__('Unknown Attendee', 'event_espresso');
2602
-                $overwrite_msgs = true;
2603
-                EE_Error::add_error(
2604
-                    sprintf(
2605
-                        esc_html__(
2606
-                            'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2607
-                            'event_espresso'
2608
-                        ),
2609
-                        $name
2610
-                    ),
2611
-                    __FILE__,
2612
-                    __FUNCTION__,
2613
-                    __LINE__
2614
-                );
2615
-                // can't trash this registration because it has payments.
2616
-                continue;
2617
-            }
2618
-            $updated = $trash ? $REG->delete() : $REG->restore();
2619
-            if ($updated) {
2620
-                $success++;
2621
-            }
2622
-        }
2623
-        $this->_redirect_after_action(
2624
-            $success === $reg_count, // were ALL registrations affected?
2625
-            $success > 1
2626
-                ? esc_html__('Registrations', 'event_espresso')
2627
-                : esc_html__('Registration', 'event_espresso'),
2628
-            $trash
2629
-                ? esc_html__('moved to the trash', 'event_espresso')
2630
-                : esc_html__('restored', 'event_espresso'),
2631
-            $this->mergeExistingRequestParamsWithRedirectArgs(array('action' => 'default')),
2632
-            $overwrite_msgs
2633
-        );
2634
-    }
2635
-
2636
-
2637
-    /**
2638
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2639
-     * registration but also.
2640
-     * 1. Removing relations to EE_Attendee
2641
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2642
-     * ALSO trashed.
2643
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2644
-     * 4. Removing relationships between all tickets and the related registrations
2645
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2646
-     * 6. Deleting permanently any related Checkins.
2647
-     *
2648
-     * @return void
2649
-     * @throws EE_Error
2650
-     * @throws InvalidArgumentException
2651
-     * @throws InvalidDataTypeException
2652
-     * @throws InvalidInterfaceException
2653
-     * @throws ReflectionException
2654
-     */
2655
-    protected function _delete_registrations()
2656
-    {
2657
-        $REG_MDL = $this->getRegistrationModel();
2658
-        $success = 1;
2659
-        // Checkboxes
2660
-        if (! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2661
-            // if array has more than one element than success message should be plural
2662
-            $success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2663
-            // cycle thru checkboxes
2664
-            foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2665
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2666
-                if (! $REG instanceof EE_Registration) {
2667
-                    continue;
2668
-                }
2669
-                $deleted = $this->_delete_registration($REG);
2670
-                if (! $deleted) {
2671
-                    $success = 0;
2672
-                }
2673
-            }
2674
-        } else {
2675
-            // grab single id and delete
2676
-            $REG_ID = $this->_req_data['_REG_ID'];
2677
-            /** @var EE_Registration $REG */
2678
-            $REG = $REG_MDL->get_one_by_ID($REG_ID);
2679
-            $deleted = $this->_delete_registration($REG);
2680
-            if (! $deleted) {
2681
-                $success = 0;
2682
-            }
2683
-        }
2684
-        $what = $success > 1
2685
-            ? esc_html__('Registrations', 'event_espresso')
2686
-            : esc_html__('Registration', 'event_espresso');
2687
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2688
-        $this->_redirect_after_action(
2689
-            $success,
2690
-            $what,
2691
-            $action_desc,
2692
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2693
-            true
2694
-        );
2695
-    }
2696
-
2697
-
2698
-    /**
2699
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2700
-     * models get affected.
2701
-     *
2702
-     * @param EE_Registration $REG registration to be deleted permanently
2703
-     * @return bool true = successful deletion, false = fail.
2704
-     * @throws EE_Error
2705
-     * @throws InvalidArgumentException
2706
-     * @throws InvalidDataTypeException
2707
-     * @throws InvalidInterfaceException
2708
-     * @throws ReflectionException
2709
-     */
2710
-    protected function _delete_registration(EE_Registration $REG)
2711
-    {
2712
-        // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2713
-        // registrations on the transaction that are NOT trashed.
2714
-        $TXN = $REG->get_first_related('Transaction');
2715
-        if (! $TXN instanceof EE_Transaction) {
2716
-            EE_Error::add_error(
2717
-                sprintf(
2718
-                    esc_html__(
2719
-                        'Unable to permanently delete registration %d because its related transaction has already been deleted. If you can restore the related transaction to the database then this registration can be deleted.',
2720
-                        'event_espresso'
2721
-                    ),
2722
-                    $REG->id()
2723
-                ),
2724
-                __FILE__,
2725
-                __FUNCTION__,
2726
-                __LINE__
2727
-            );
2728
-            return false;
2729
-        }
2730
-        $REGS = $TXN->get_many_related('Registration');
2731
-        $all_trashed = true;
2732
-        foreach ($REGS as $registration) {
2733
-            if (! $registration->get('REG_deleted')) {
2734
-                $all_trashed = false;
2735
-            }
2736
-        }
2737
-        if (! $all_trashed) {
2738
-            EE_Error::add_error(
2739
-                esc_html__(
2740
-                    'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2741
-                    'event_espresso'
2742
-                ),
2743
-                __FILE__,
2744
-                __FUNCTION__,
2745
-                __LINE__
2746
-            );
2747
-            return false;
2748
-        }
2749
-        // k made it here so that means we can delete all the related transactions and their answers (but let's do them
2750
-        // separately from THIS one).
2751
-        foreach ($REGS as $registration) {
2752
-            // delete related answers
2753
-            $registration->delete_related_permanently('Answer');
2754
-            // remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2755
-            $attendee = $registration->get_first_related('Attendee');
2756
-            if ($attendee instanceof EE_Attendee) {
2757
-                $registration->_remove_relation_to($attendee, 'Attendee');
2758
-            }
2759
-            // now remove relationships to tickets on this registration.
2760
-            $registration->_remove_relations('Ticket');
2761
-            // now delete permanently the checkins related to this registration.
2762
-            $registration->delete_related_permanently('Checkin');
2763
-            if ($registration->ID() === $REG->ID()) {
2764
-                continue;
2765
-            } //we don't want to delete permanently the existing registration just yet.
2766
-            // remove relation to transaction for these registrations if NOT the existing registrations
2767
-            $registration->_remove_relations('Transaction');
2768
-            // delete permanently any related messages.
2769
-            $registration->delete_related_permanently('Message');
2770
-            // now delete this registration permanently
2771
-            $registration->delete_permanently();
2772
-        }
2773
-        // now all related registrations on the transaction are handled.  So let's just handle this registration itself
2774
-        // (the transaction and line items should be all that's left).
2775
-        // delete the line items related to the transaction for this registration.
2776
-        $TXN->delete_related_permanently('Line_Item');
2777
-        // we need to remove all the relationships on the transaction
2778
-        $TXN->delete_related_permanently('Payment');
2779
-        $TXN->delete_related_permanently('Extra_Meta');
2780
-        $TXN->delete_related_permanently('Message');
2781
-        // now we can delete this REG permanently (and the transaction of course)
2782
-        $REG->delete_related_permanently('Transaction');
2783
-        return $REG->delete_permanently();
2784
-    }
2785
-
2786
-
2787
-    /**
2788
-     *    generates HTML for the Register New Attendee Admin page
2789
-     *
2790
-     * @access private
2791
-     * @throws DomainException
2792
-     * @throws EE_Error
2793
-     * @throws InvalidArgumentException
2794
-     * @throws InvalidDataTypeException
2795
-     * @throws InvalidInterfaceException
2796
-     * @throws ReflectionException
2797
-     */
2798
-    public function new_registration()
2799
-    {
2800
-        if (! $this->_set_reg_event()) {
2801
-            throw new EE_Error(
2802
-                esc_html__(
2803
-                    'Unable to continue with registering because there is no Event ID in the request',
2804
-                    'event_espresso'
2805
-                )
2806
-            );
2807
-        }
2808
-        EE_Registry::instance()->REQ->set_espresso_page(true);
2809
-        // gotta start with a clean slate if we're not coming here via ajax
2810
-        if (! defined('DOING_AJAX')
2811
-            && (! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2812
-        ) {
2813
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2814
-        }
2815
-        $this->_template_args['event_name'] = '';
2816
-        // event name
2817
-        if ($this->_reg_event) {
2818
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2819
-            $edit_event_url = self::add_query_args_and_nonce(
2820
-                array(
2821
-                    'action' => 'edit',
2822
-                    'post'   => $this->_reg_event->ID(),
2823
-                ),
2824
-                EVENTS_ADMIN_URL
2825
-            );
2826
-            $edit_event_lnk = '<a href="'
2827
-                              . $edit_event_url
2828
-                              . '" title="'
2829
-                              . esc_attr__('Edit ', 'event_espresso')
2830
-                              . $this->_reg_event->name()
2831
-                              . '">'
2832
-                              . esc_html__('Edit Event', 'event_espresso')
2833
-                              . '</a>';
2834
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2835
-                                                   . $edit_event_lnk
2836
-                                                   . '</span>';
2837
-        }
2838
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2839
-        if (defined('DOING_AJAX')) {
2840
-            $this->_return_json();
2841
-        }
2842
-        // grab header
2843
-        $template_path =
2844
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2845
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2846
-            $template_path,
2847
-            $this->_template_args,
2848
-            true
2849
-        );
2850
-        // $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2851
-        // the details template wrapper
2852
-        $this->display_admin_page_with_sidebar();
2853
-    }
2854
-
2855
-
2856
-    /**
2857
-     * This returns the content for a registration step
2858
-     *
2859
-     * @access protected
2860
-     * @return string html
2861
-     * @throws DomainException
2862
-     * @throws EE_Error
2863
-     * @throws InvalidArgumentException
2864
-     * @throws InvalidDataTypeException
2865
-     * @throws InvalidInterfaceException
2866
-     */
2867
-    protected function _get_registration_step_content()
2868
-    {
2869
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2870
-            $warning_msg = sprintf(
2871
-                esc_html__(
2872
-                    '%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2873
-                    'event_espresso'
2874
-                ),
2875
-                '<br />',
2876
-                '<h3 class="important-notice">',
2877
-                '</h3>',
2878
-                '<div class="float-right">',
2879
-                '<span id="redirect_timer" class="important-notice">30</span>',
2880
-                '</div>',
2881
-                '<b>',
2882
-                '</b>'
2883
-            );
2884
-            return '
2301
+	}
2302
+
2303
+
2304
+	/**
2305
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2306
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2307
+	 * to display the page
2308
+	 *
2309
+	 * @access protected
2310
+	 * @return void
2311
+	 * @throws EE_Error
2312
+	 * @throws InvalidArgumentException
2313
+	 * @throws InvalidDataTypeException
2314
+	 * @throws InvalidInterfaceException
2315
+	 * @throws ReflectionException
2316
+	 */
2317
+	protected function _update_attendee_registration_form()
2318
+	{
2319
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2320
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2321
+			$REG_ID = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2322
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2323
+			if ($success) {
2324
+				$what = esc_html__('Registration Form', 'event_espresso');
2325
+				$route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2326
+					: array('action' => 'default');
2327
+				$this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2328
+			}
2329
+		}
2330
+	}
2331
+
2332
+
2333
+	/**
2334
+	 * Gets the form for saving registrations custom questions (if done
2335
+	 * previously retrieves the cached form object, which may have validation errors in it)
2336
+	 *
2337
+	 * @param int $REG_ID
2338
+	 * @return EE_Registration_Custom_Questions_Form
2339
+	 * @throws EE_Error
2340
+	 * @throws InvalidArgumentException
2341
+	 * @throws InvalidDataTypeException
2342
+	 * @throws InvalidInterfaceException
2343
+	 */
2344
+	protected function _get_reg_custom_questions_form($REG_ID)
2345
+	{
2346
+		if (! $this->_reg_custom_questions_form) {
2347
+			require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2348
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2349
+				$this->getRegistrationModel()->get_one_by_ID($REG_ID)
2350
+			);
2351
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2352
+		}
2353
+		return $this->_reg_custom_questions_form;
2354
+	}
2355
+
2356
+
2357
+	/**
2358
+	 * Saves
2359
+	 *
2360
+	 * @access private
2361
+	 * @param bool $REG_ID
2362
+	 * @return bool
2363
+	 * @throws EE_Error
2364
+	 * @throws InvalidArgumentException
2365
+	 * @throws InvalidDataTypeException
2366
+	 * @throws InvalidInterfaceException
2367
+	 * @throws ReflectionException
2368
+	 */
2369
+	private function _save_reg_custom_questions_form($REG_ID = false)
2370
+	{
2371
+		if (! $REG_ID) {
2372
+			EE_Error::add_error(
2373
+				esc_html__(
2374
+					'An error occurred. No registration ID was received.',
2375
+					'event_espresso'
2376
+				),
2377
+				__FILE__,
2378
+				__FUNCTION__,
2379
+				__LINE__
2380
+			);
2381
+		}
2382
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2383
+		$form->receive_form_submission($this->_req_data);
2384
+		$success = false;
2385
+		if ($form->is_valid()) {
2386
+			foreach ($form->subforms() as $question_group_id => $question_group_form) {
2387
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2388
+					$where_conditions = array(
2389
+						'QST_ID' => $question_id,
2390
+						'REG_ID' => $REG_ID,
2391
+					);
2392
+					$possibly_new_values = array(
2393
+						'ANS_value' => $input->normalized_value(),
2394
+					);
2395
+					$answer = EEM_Answer::instance()->get_one(array($where_conditions));
2396
+					if ($answer instanceof EE_Answer) {
2397
+						$success = $answer->save($possibly_new_values);
2398
+					} else {
2399
+						// insert it then
2400
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2401
+						$answer = EE_Answer::new_instance($cols_n_vals);
2402
+						$success = $answer->save();
2403
+					}
2404
+				}
2405
+			}
2406
+		} else {
2407
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2408
+		}
2409
+		return $success;
2410
+	}
2411
+
2412
+
2413
+	/**
2414
+	 *        generates HTML for the Registration main meta box
2415
+	 *
2416
+	 * @access public
2417
+	 * @return void
2418
+	 * @throws DomainException
2419
+	 * @throws EE_Error
2420
+	 * @throws InvalidArgumentException
2421
+	 * @throws InvalidDataTypeException
2422
+	 * @throws InvalidInterfaceException
2423
+	 * @throws ReflectionException
2424
+	 */
2425
+	public function _reg_attendees_meta_box()
2426
+	{
2427
+		$REG = $this->getRegistrationModel();
2428
+		// get all other registrations on this transaction, and cache
2429
+		// the attendees for them so we don't have to run another query using force_join
2430
+		$registrations = $REG->get_all(
2431
+			array(
2432
+				array(
2433
+					'TXN_ID' => $this->_registration->transaction_ID(),
2434
+					'REG_ID' => array('!=', $this->_registration->ID()),
2435
+				),
2436
+				'force_join' => array('Attendee'),
2437
+				'default_where_conditions' => 'other_models_only',
2438
+			)
2439
+		);
2440
+		$this->_template_args['attendees'] = array();
2441
+		$this->_template_args['attendee_notice'] = '';
2442
+		if (empty($registrations)
2443
+			|| (is_array($registrations)
2444
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2445
+		) {
2446
+			EE_Error::add_error(
2447
+				esc_html__(
2448
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2449
+					'event_espresso'
2450
+				),
2451
+				__FILE__,
2452
+				__FUNCTION__,
2453
+				__LINE__
2454
+			);
2455
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2456
+		} else {
2457
+			$att_nmbr = 1;
2458
+			foreach ($registrations as $registration) {
2459
+				/* @var $registration EE_Registration */
2460
+				$attendee = $registration->attendee()
2461
+					? $registration->attendee()
2462
+					: $this->getAttendeeModel()->create_default_object();
2463
+				$this->_template_args['attendees'][ $att_nmbr ]['STS_ID'] = $registration->status_ID();
2464
+				$this->_template_args['attendees'][ $att_nmbr ]['fname'] = $attendee->fname();
2465
+				$this->_template_args['attendees'][ $att_nmbr ]['lname'] = $attendee->lname();
2466
+				$this->_template_args['attendees'][ $att_nmbr ]['email'] = $attendee->email();
2467
+				$this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2468
+				$this->_template_args['attendees'][ $att_nmbr ]['address'] = implode(
2469
+					', ',
2470
+					$attendee->full_address_as_array()
2471
+				);
2472
+				$this->_template_args['attendees'][ $att_nmbr ]['att_link'] = self::add_query_args_and_nonce(
2473
+					array(
2474
+						'action' => 'edit_attendee',
2475
+						'post'   => $attendee->ID(),
2476
+					),
2477
+					REG_ADMIN_URL
2478
+				);
2479
+				$this->_template_args['attendees'][ $att_nmbr ]['event_name'] = $registration->event_obj() instanceof EE_Event
2480
+					? $registration->event_obj()->name()
2481
+					: '';
2482
+				$att_nmbr++;
2483
+			}
2484
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2485
+		}
2486
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2487
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2488
+	}
2489
+
2490
+
2491
+	/**
2492
+	 *        generates HTML for the Edit Registration side meta box
2493
+	 *
2494
+	 * @access public
2495
+	 * @return void
2496
+	 * @throws DomainException
2497
+	 * @throws EE_Error
2498
+	 * @throws InvalidArgumentException
2499
+	 * @throws InvalidDataTypeException
2500
+	 * @throws InvalidInterfaceException
2501
+	 * @throws ReflectionException
2502
+	 */
2503
+	public function _reg_registrant_side_meta_box()
2504
+	{
2505
+		/*@var $attendee EE_Attendee */
2506
+		$att_check = $this->_registration->attendee();
2507
+		$attendee = $att_check instanceof EE_Attendee
2508
+			? $att_check
2509
+			: $this->getAttendeeModel()->create_default_object();
2510
+		// now let's determine if this is not the primary registration.  If it isn't then we set the
2511
+		// primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2512
+		// primary registration object (that way we know if we need to show create button or not)
2513
+		if (! $this->_registration->is_primary_registrant()) {
2514
+			$primary_registration = $this->_registration->get_primary_registration();
2515
+			$primary_attendee = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2516
+				: null;
2517
+			if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2518
+				// in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2519
+				// custom attendee object so let's not worry about the primary reg.
2520
+				$primary_registration = null;
2521
+			}
2522
+		} else {
2523
+			$primary_registration = null;
2524
+		}
2525
+		$this->_template_args['ATT_ID'] = $attendee->ID();
2526
+		$this->_template_args['fname'] = $attendee->fname();
2527
+		$this->_template_args['lname'] = $attendee->lname();
2528
+		$this->_template_args['email'] = $attendee->email();
2529
+		$this->_template_args['phone'] = $attendee->phone();
2530
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2531
+		// edit link
2532
+		$this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(
2533
+			array(
2534
+				'action' => 'edit_attendee',
2535
+				'post'   => $attendee->ID(),
2536
+			),
2537
+			REG_ADMIN_URL
2538
+		);
2539
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2540
+		// create link
2541
+		$this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2542
+			? EE_Admin_Page::add_query_args_and_nonce(
2543
+				array(
2544
+					'action'  => 'duplicate_attendee',
2545
+					'_REG_ID' => $this->_registration->ID(),
2546
+				),
2547
+				REG_ADMIN_URL
2548
+			) : '';
2549
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2550
+		$this->_template_args['att_check'] = $att_check;
2551
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2552
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2553
+	}
2554
+
2555
+
2556
+	/**
2557
+	 * trash or restore registrations
2558
+	 *
2559
+	 * @param  boolean $trash whether to archive or restore
2560
+	 * @return void
2561
+	 * @throws EE_Error
2562
+	 * @throws InvalidArgumentException
2563
+	 * @throws InvalidDataTypeException
2564
+	 * @throws InvalidInterfaceException
2565
+	 * @throws RuntimeException
2566
+	 * @access protected
2567
+	 */
2568
+	protected function _trash_or_restore_registrations($trash = true)
2569
+	{
2570
+		// if empty _REG_ID then get out because there's nothing to do
2571
+		if (empty($this->_req_data['_REG_ID'])) {
2572
+			EE_Error::add_error(
2573
+				sprintf(
2574
+					esc_html__(
2575
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2576
+						'event_espresso'
2577
+					),
2578
+					$trash ? 'trash' : 'restore'
2579
+				),
2580
+				__FILE__,
2581
+				__LINE__,
2582
+				__FUNCTION__
2583
+			);
2584
+			$this->_redirect_after_action(false, '', '', array(), true);
2585
+		}
2586
+		$success = 0;
2587
+		$overwrite_msgs = false;
2588
+		// Checkboxes
2589
+		if (! is_array($this->_req_data['_REG_ID'])) {
2590
+			$this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2591
+		}
2592
+		$reg_count = count($this->_req_data['_REG_ID']);
2593
+		// cycle thru checkboxes
2594
+		foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2595
+			/** @var EE_Registration $REG */
2596
+			$REG = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2597
+			$payments = $REG->registration_payments();
2598
+			if (! empty($payments)) {
2599
+				$name = $REG->attendee() instanceof EE_Attendee
2600
+					? $REG->attendee()->full_name()
2601
+					: esc_html__('Unknown Attendee', 'event_espresso');
2602
+				$overwrite_msgs = true;
2603
+				EE_Error::add_error(
2604
+					sprintf(
2605
+						esc_html__(
2606
+							'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2607
+							'event_espresso'
2608
+						),
2609
+						$name
2610
+					),
2611
+					__FILE__,
2612
+					__FUNCTION__,
2613
+					__LINE__
2614
+				);
2615
+				// can't trash this registration because it has payments.
2616
+				continue;
2617
+			}
2618
+			$updated = $trash ? $REG->delete() : $REG->restore();
2619
+			if ($updated) {
2620
+				$success++;
2621
+			}
2622
+		}
2623
+		$this->_redirect_after_action(
2624
+			$success === $reg_count, // were ALL registrations affected?
2625
+			$success > 1
2626
+				? esc_html__('Registrations', 'event_espresso')
2627
+				: esc_html__('Registration', 'event_espresso'),
2628
+			$trash
2629
+				? esc_html__('moved to the trash', 'event_espresso')
2630
+				: esc_html__('restored', 'event_espresso'),
2631
+			$this->mergeExistingRequestParamsWithRedirectArgs(array('action' => 'default')),
2632
+			$overwrite_msgs
2633
+		);
2634
+	}
2635
+
2636
+
2637
+	/**
2638
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2639
+	 * registration but also.
2640
+	 * 1. Removing relations to EE_Attendee
2641
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2642
+	 * ALSO trashed.
2643
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2644
+	 * 4. Removing relationships between all tickets and the related registrations
2645
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2646
+	 * 6. Deleting permanently any related Checkins.
2647
+	 *
2648
+	 * @return void
2649
+	 * @throws EE_Error
2650
+	 * @throws InvalidArgumentException
2651
+	 * @throws InvalidDataTypeException
2652
+	 * @throws InvalidInterfaceException
2653
+	 * @throws ReflectionException
2654
+	 */
2655
+	protected function _delete_registrations()
2656
+	{
2657
+		$REG_MDL = $this->getRegistrationModel();
2658
+		$success = 1;
2659
+		// Checkboxes
2660
+		if (! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2661
+			// if array has more than one element than success message should be plural
2662
+			$success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2663
+			// cycle thru checkboxes
2664
+			foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2665
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2666
+				if (! $REG instanceof EE_Registration) {
2667
+					continue;
2668
+				}
2669
+				$deleted = $this->_delete_registration($REG);
2670
+				if (! $deleted) {
2671
+					$success = 0;
2672
+				}
2673
+			}
2674
+		} else {
2675
+			// grab single id and delete
2676
+			$REG_ID = $this->_req_data['_REG_ID'];
2677
+			/** @var EE_Registration $REG */
2678
+			$REG = $REG_MDL->get_one_by_ID($REG_ID);
2679
+			$deleted = $this->_delete_registration($REG);
2680
+			if (! $deleted) {
2681
+				$success = 0;
2682
+			}
2683
+		}
2684
+		$what = $success > 1
2685
+			? esc_html__('Registrations', 'event_espresso')
2686
+			: esc_html__('Registration', 'event_espresso');
2687
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2688
+		$this->_redirect_after_action(
2689
+			$success,
2690
+			$what,
2691
+			$action_desc,
2692
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2693
+			true
2694
+		);
2695
+	}
2696
+
2697
+
2698
+	/**
2699
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2700
+	 * models get affected.
2701
+	 *
2702
+	 * @param EE_Registration $REG registration to be deleted permanently
2703
+	 * @return bool true = successful deletion, false = fail.
2704
+	 * @throws EE_Error
2705
+	 * @throws InvalidArgumentException
2706
+	 * @throws InvalidDataTypeException
2707
+	 * @throws InvalidInterfaceException
2708
+	 * @throws ReflectionException
2709
+	 */
2710
+	protected function _delete_registration(EE_Registration $REG)
2711
+	{
2712
+		// first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2713
+		// registrations on the transaction that are NOT trashed.
2714
+		$TXN = $REG->get_first_related('Transaction');
2715
+		if (! $TXN instanceof EE_Transaction) {
2716
+			EE_Error::add_error(
2717
+				sprintf(
2718
+					esc_html__(
2719
+						'Unable to permanently delete registration %d because its related transaction has already been deleted. If you can restore the related transaction to the database then this registration can be deleted.',
2720
+						'event_espresso'
2721
+					),
2722
+					$REG->id()
2723
+				),
2724
+				__FILE__,
2725
+				__FUNCTION__,
2726
+				__LINE__
2727
+			);
2728
+			return false;
2729
+		}
2730
+		$REGS = $TXN->get_many_related('Registration');
2731
+		$all_trashed = true;
2732
+		foreach ($REGS as $registration) {
2733
+			if (! $registration->get('REG_deleted')) {
2734
+				$all_trashed = false;
2735
+			}
2736
+		}
2737
+		if (! $all_trashed) {
2738
+			EE_Error::add_error(
2739
+				esc_html__(
2740
+					'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2741
+					'event_espresso'
2742
+				),
2743
+				__FILE__,
2744
+				__FUNCTION__,
2745
+				__LINE__
2746
+			);
2747
+			return false;
2748
+		}
2749
+		// k made it here so that means we can delete all the related transactions and their answers (but let's do them
2750
+		// separately from THIS one).
2751
+		foreach ($REGS as $registration) {
2752
+			// delete related answers
2753
+			$registration->delete_related_permanently('Answer');
2754
+			// remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2755
+			$attendee = $registration->get_first_related('Attendee');
2756
+			if ($attendee instanceof EE_Attendee) {
2757
+				$registration->_remove_relation_to($attendee, 'Attendee');
2758
+			}
2759
+			// now remove relationships to tickets on this registration.
2760
+			$registration->_remove_relations('Ticket');
2761
+			// now delete permanently the checkins related to this registration.
2762
+			$registration->delete_related_permanently('Checkin');
2763
+			if ($registration->ID() === $REG->ID()) {
2764
+				continue;
2765
+			} //we don't want to delete permanently the existing registration just yet.
2766
+			// remove relation to transaction for these registrations if NOT the existing registrations
2767
+			$registration->_remove_relations('Transaction');
2768
+			// delete permanently any related messages.
2769
+			$registration->delete_related_permanently('Message');
2770
+			// now delete this registration permanently
2771
+			$registration->delete_permanently();
2772
+		}
2773
+		// now all related registrations on the transaction are handled.  So let's just handle this registration itself
2774
+		// (the transaction and line items should be all that's left).
2775
+		// delete the line items related to the transaction for this registration.
2776
+		$TXN->delete_related_permanently('Line_Item');
2777
+		// we need to remove all the relationships on the transaction
2778
+		$TXN->delete_related_permanently('Payment');
2779
+		$TXN->delete_related_permanently('Extra_Meta');
2780
+		$TXN->delete_related_permanently('Message');
2781
+		// now we can delete this REG permanently (and the transaction of course)
2782
+		$REG->delete_related_permanently('Transaction');
2783
+		return $REG->delete_permanently();
2784
+	}
2785
+
2786
+
2787
+	/**
2788
+	 *    generates HTML for the Register New Attendee Admin page
2789
+	 *
2790
+	 * @access private
2791
+	 * @throws DomainException
2792
+	 * @throws EE_Error
2793
+	 * @throws InvalidArgumentException
2794
+	 * @throws InvalidDataTypeException
2795
+	 * @throws InvalidInterfaceException
2796
+	 * @throws ReflectionException
2797
+	 */
2798
+	public function new_registration()
2799
+	{
2800
+		if (! $this->_set_reg_event()) {
2801
+			throw new EE_Error(
2802
+				esc_html__(
2803
+					'Unable to continue with registering because there is no Event ID in the request',
2804
+					'event_espresso'
2805
+				)
2806
+			);
2807
+		}
2808
+		EE_Registry::instance()->REQ->set_espresso_page(true);
2809
+		// gotta start with a clean slate if we're not coming here via ajax
2810
+		if (! defined('DOING_AJAX')
2811
+			&& (! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2812
+		) {
2813
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2814
+		}
2815
+		$this->_template_args['event_name'] = '';
2816
+		// event name
2817
+		if ($this->_reg_event) {
2818
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2819
+			$edit_event_url = self::add_query_args_and_nonce(
2820
+				array(
2821
+					'action' => 'edit',
2822
+					'post'   => $this->_reg_event->ID(),
2823
+				),
2824
+				EVENTS_ADMIN_URL
2825
+			);
2826
+			$edit_event_lnk = '<a href="'
2827
+							  . $edit_event_url
2828
+							  . '" title="'
2829
+							  . esc_attr__('Edit ', 'event_espresso')
2830
+							  . $this->_reg_event->name()
2831
+							  . '">'
2832
+							  . esc_html__('Edit Event', 'event_espresso')
2833
+							  . '</a>';
2834
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2835
+												   . $edit_event_lnk
2836
+												   . '</span>';
2837
+		}
2838
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2839
+		if (defined('DOING_AJAX')) {
2840
+			$this->_return_json();
2841
+		}
2842
+		// grab header
2843
+		$template_path =
2844
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2845
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2846
+			$template_path,
2847
+			$this->_template_args,
2848
+			true
2849
+		);
2850
+		// $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2851
+		// the details template wrapper
2852
+		$this->display_admin_page_with_sidebar();
2853
+	}
2854
+
2855
+
2856
+	/**
2857
+	 * This returns the content for a registration step
2858
+	 *
2859
+	 * @access protected
2860
+	 * @return string html
2861
+	 * @throws DomainException
2862
+	 * @throws EE_Error
2863
+	 * @throws InvalidArgumentException
2864
+	 * @throws InvalidDataTypeException
2865
+	 * @throws InvalidInterfaceException
2866
+	 */
2867
+	protected function _get_registration_step_content()
2868
+	{
2869
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2870
+			$warning_msg = sprintf(
2871
+				esc_html__(
2872
+					'%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2873
+					'event_espresso'
2874
+				),
2875
+				'<br />',
2876
+				'<h3 class="important-notice">',
2877
+				'</h3>',
2878
+				'<div class="float-right">',
2879
+				'<span id="redirect_timer" class="important-notice">30</span>',
2880
+				'</div>',
2881
+				'<b>',
2882
+				'</b>'
2883
+			);
2884
+			return '
2885 2885
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2886 2886
 	<script >
2887 2887
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2894,868 +2894,868 @@  discard block
 block discarded – undo
2894 2894
 	        }
2895 2895
 	    }, 800 );
2896 2896
 	</script >';
2897
-        }
2898
-        $template_args = array(
2899
-            'title'                    => '',
2900
-            'content'                  => '',
2901
-            'step_button_text'         => '',
2902
-            'show_notification_toggle' => false,
2903
-        );
2904
-        // to indicate we're processing a new registration
2905
-        $hidden_fields = array(
2906
-            'processing_registration' => array(
2907
-                'type'  => 'hidden',
2908
-                'value' => 0,
2909
-            ),
2910
-            'event_id'                => array(
2911
-                'type'  => 'hidden',
2912
-                'value' => $this->_reg_event->ID(),
2913
-            ),
2914
-        );
2915
-        // if the cart is empty then we know we're at step one so we'll display ticket selector
2916
-        $cart = EE_Registry::instance()->SSN->cart();
2917
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2918
-        switch ($step) {
2919
-            case 'ticket':
2920
-                $hidden_fields['processing_registration']['value'] = 1;
2921
-                $template_args['title'] = esc_html__(
2922
-                    'Step One: Select the Ticket for this registration',
2923
-                    'event_espresso'
2924
-                );
2925
-                $template_args['content'] =
2926
-                    EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2927
-                $template_args['content'] .= '</div>';
2928
-                $template_args['step_button_text'] = esc_html__(
2929
-                    'Add Tickets and Continue to Registrant Details',
2930
-                    'event_espresso'
2931
-                );
2932
-                $template_args['show_notification_toggle'] = false;
2933
-                break;
2934
-            case 'questions':
2935
-                $hidden_fields['processing_registration']['value'] = 2;
2936
-                $template_args['title'] = esc_html__(
2937
-                    'Step Two: Add Registrant Details for this Registration',
2938
-                    'event_espresso'
2939
-                );
2940
-                // in theory we should be able to run EED_SPCO at this point because the cart should have been setup
2941
-                // properly by the first process_reg_step run.
2942
-                $template_args['content'] =
2943
-                    EED_Single_Page_Checkout::registration_checkout_for_admin();
2944
-                $template_args['step_button_text'] = esc_html__(
2945
-                    'Save Registration and Continue to Details',
2946
-                    'event_espresso'
2947
-                );
2948
-                $template_args['show_notification_toggle'] = true;
2949
-                break;
2950
-        }
2951
-        // we come back to the process_registration_step route.
2952
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2953
-        return EEH_Template::display_template(
2954
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2955
-            $template_args,
2956
-            true
2957
-        );
2958
-    }
2959
-
2960
-
2961
-    /**
2962
-     *        set_reg_event
2963
-     *
2964
-     * @access private
2965
-     * @return bool
2966
-     * @throws EE_Error
2967
-     * @throws InvalidArgumentException
2968
-     * @throws InvalidDataTypeException
2969
-     * @throws InvalidInterfaceException
2970
-     */
2971
-    private function _set_reg_event()
2972
-    {
2973
-        if (is_object($this->_reg_event)) {
2974
-            return true;
2975
-        }
2976
-        $EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2977
-        if (! $EVT_ID) {
2978
-            return false;
2979
-        }
2980
-        $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2981
-        return true;
2982
-    }
2983
-
2984
-
2985
-    /**
2986
-     * process_reg_step
2987
-     *
2988
-     * @access        public
2989
-     * @return string
2990
-     * @throws DomainException
2991
-     * @throws EE_Error
2992
-     * @throws InvalidArgumentException
2993
-     * @throws InvalidDataTypeException
2994
-     * @throws InvalidInterfaceException
2995
-     * @throws ReflectionException
2996
-     * @throws RuntimeException
2997
-     */
2998
-    public function process_reg_step()
2999
-    {
3000
-        EE_System::do_not_cache();
3001
-        $this->_set_reg_event();
3002
-        EE_Registry::instance()->REQ->set_espresso_page(true);
3003
-        EE_Registry::instance()->REQ->set('uts', time());
3004
-        // what step are we on?
3005
-        $cart = EE_Registry::instance()->SSN->cart();
3006
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3007
-        // if doing ajax then we need to verify the nonce
3008
-        if (defined('DOING_AJAX')) {
3009
-            $nonce = isset($this->_req_data[ $this->_req_nonce ])
3010
-                ? sanitize_text_field($this->_req_data[ $this->_req_nonce ]) : '';
3011
-            $this->_verify_nonce($nonce, $this->_req_nonce);
3012
-        }
3013
-        switch ($step) {
3014
-            case 'ticket':
3015
-                // process ticket selection
3016
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
3017
-                if ($success) {
3018
-                    EE_Error::add_success(
3019
-                        esc_html__(
3020
-                            'Tickets Selected. Now complete the registration.',
3021
-                            'event_espresso'
3022
-                        )
3023
-                    );
3024
-                } else {
3025
-                    $query_args['step_error'] = $this->_req_data['step_error'] = true;
3026
-                }
3027
-                if (defined('DOING_AJAX')) {
3028
-                    $this->new_registration(); // display next step
3029
-                } else {
3030
-                    $query_args = array(
3031
-                        'action'                  => 'new_registration',
3032
-                        'processing_registration' => 1,
3033
-                        'event_id'                => $this->_reg_event->ID(),
3034
-                        'uts'                     => time(),
3035
-                    );
3036
-                    $this->_redirect_after_action(
3037
-                        false,
3038
-                        '',
3039
-                        '',
3040
-                        $query_args,
3041
-                        true
3042
-                    );
3043
-                }
3044
-                break;
3045
-            case 'questions':
3046
-                if (! isset(
3047
-                    $this->_req_data['txn_reg_status_change'],
3048
-                    $this->_req_data['txn_reg_status_change']['send_notifications']
3049
-                )
3050
-                ) {
3051
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3052
-                }
3053
-                // process registration
3054
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3055
-                if ($cart instanceof EE_Cart) {
3056
-                    $grand_total = $cart->get_cart_grand_total();
3057
-                    if ($grand_total instanceof EE_Line_Item) {
3058
-                        $grand_total->save_this_and_descendants_to_txn();
3059
-                    }
3060
-                }
3061
-                if (! $transaction instanceof EE_Transaction) {
3062
-                    $query_args = array(
3063
-                        'action'                  => 'new_registration',
3064
-                        'processing_registration' => 2,
3065
-                        'event_id'                => $this->_reg_event->ID(),
3066
-                        'uts'                     => time(),
3067
-                    );
3068
-                    if (defined('DOING_AJAX')) {
3069
-                        // display registration form again because there are errors (maybe validation?)
3070
-                        $this->new_registration();
3071
-                        return;
3072
-                    }
3073
-                    $this->_redirect_after_action(
3074
-                        false,
3075
-                        '',
3076
-                        '',
3077
-                        $query_args,
3078
-                        true
3079
-                    );
3080
-                    return;
3081
-                }
3082
-                // maybe update status, and make sure to save transaction if not done already
3083
-                if (! $transaction->update_status_based_on_total_paid()) {
3084
-                    $transaction->save();
3085
-                }
3086
-                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3087
-                $this->_req_data = array();
3088
-                $query_args = array(
3089
-                    'action'        => 'redirect_to_txn',
3090
-                    'TXN_ID'        => $transaction->ID(),
3091
-                    'EVT_ID'        => $this->_reg_event->ID(),
3092
-                    'event_name'    => urlencode($this->_reg_event->name()),
3093
-                    'redirect_from' => 'new_registration',
3094
-                );
3095
-                $this->_redirect_after_action(false, '', '', $query_args, true);
3096
-                break;
3097
-        }
3098
-        // what are you looking here for?  Should be nothing to do at this point.
3099
-    }
3100
-
3101
-
3102
-    /**
3103
-     * redirect_to_txn
3104
-     *
3105
-     * @access public
3106
-     * @return void
3107
-     * @throws EE_Error
3108
-     * @throws InvalidArgumentException
3109
-     * @throws InvalidDataTypeException
3110
-     * @throws InvalidInterfaceException
3111
-     * @throws ReflectionException
3112
-     */
3113
-    public function redirect_to_txn()
3114
-    {
3115
-        EE_System::do_not_cache();
3116
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3117
-        $query_args = array(
3118
-            'action' => 'view_transaction',
3119
-            'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3120
-            'page'   => 'espresso_transactions',
3121
-        );
3122
-        if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3123
-            $query_args['EVT_ID'] = $this->_req_data['EVT_ID'];
3124
-            $query_args['event_name'] = urlencode($this->_req_data['event_name']);
3125
-            $query_args['redirect_from'] = $this->_req_data['redirect_from'];
3126
-        }
3127
-        EE_Error::add_success(
3128
-            esc_html__(
3129
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3130
-                'event_espresso'
3131
-            )
3132
-        );
3133
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3134
-    }
3135
-
3136
-
3137
-    /**
3138
-     *        generates HTML for the Attendee Contact List
3139
-     *
3140
-     * @access protected
3141
-     * @return void
3142
-     * @throws DomainException
3143
-     * @throws EE_Error
3144
-     */
3145
-    protected function _attendee_contact_list_table()
3146
-    {
3147
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3148
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3149
-        $this->display_admin_list_table_page_with_no_sidebar();
3150
-    }
3151
-
3152
-
3153
-    /**
3154
-     *        get_attendees
3155
-     *
3156
-     * @param      $per_page
3157
-     * @param bool $count whether to return count or data.
3158
-     * @param bool $trash
3159
-     * @return array
3160
-     * @throws EE_Error
3161
-     * @throws InvalidArgumentException
3162
-     * @throws InvalidDataTypeException
3163
-     * @throws InvalidInterfaceException
3164
-     * @access public
3165
-     */
3166
-    public function get_attendees($per_page, $count = false, $trash = false)
3167
-    {
3168
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3169
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3170
-        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3171
-        switch ($this->_req_data['orderby']) {
3172
-            case 'ATT_ID':
3173
-                $orderby = 'ATT_ID';
3174
-                break;
3175
-            case 'ATT_fname':
3176
-                $orderby = 'ATT_fname';
3177
-                break;
3178
-            case 'ATT_email':
3179
-                $orderby = 'ATT_email';
3180
-                break;
3181
-            case 'ATT_city':
3182
-                $orderby = 'ATT_city';
3183
-                break;
3184
-            case 'STA_ID':
3185
-                $orderby = 'STA_ID';
3186
-                break;
3187
-            case 'CNT_ID':
3188
-                $orderby = 'CNT_ID';
3189
-                break;
3190
-            case 'Registration_Count':
3191
-                $orderby = 'Registration_Count';
3192
-                break;
3193
-            default:
3194
-                $orderby = 'ATT_lname';
3195
-        }
3196
-        $sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3197
-            ? $this->_req_data['order']
3198
-            : 'ASC';
3199
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3200
-            ? $this->_req_data['paged']
3201
-            : 1;
3202
-        $per_page = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3203
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3204
-            ? $this->_req_data['perpage']
3205
-            : $per_page;
3206
-        $_where = array();
3207
-        if (! empty($this->_req_data['s'])) {
3208
-            $sstr = '%' . $this->_req_data['s'] . '%';
3209
-            $_where['OR'] = array(
3210
-                'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3211
-                'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3212
-                'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3213
-                'ATT_fname'                         => array('LIKE', $sstr),
3214
-                'ATT_lname'                         => array('LIKE', $sstr),
3215
-                'ATT_short_bio'                     => array('LIKE', $sstr),
3216
-                'ATT_email'                         => array('LIKE', $sstr),
3217
-                'ATT_address'                       => array('LIKE', $sstr),
3218
-                'ATT_address2'                      => array('LIKE', $sstr),
3219
-                'ATT_city'                          => array('LIKE', $sstr),
3220
-                'Country.CNT_name'                  => array('LIKE', $sstr),
3221
-                'State.STA_name'                    => array('LIKE', $sstr),
3222
-                'ATT_phone'                         => array('LIKE', $sstr),
3223
-                'Registration.REG_final_price'      => array('LIKE', $sstr),
3224
-                'Registration.REG_code'             => array('LIKE', $sstr),
3225
-                'Registration.REG_group_size'       => array('LIKE', $sstr),
3226
-            );
3227
-        }
3228
-        $offset = ($current_page - 1) * $per_page;
3229
-        $limit = $count ? null : array($offset, $per_page);
3230
-        $query_args = array(
3231
-            $_where,
3232
-            'extra_selects' => array('Registration_Count' => array('Registration.REG_ID', 'count', '%d')),
3233
-            'limit'         => $limit,
3234
-        );
3235
-        if (! $count) {
3236
-            $query_args['order_by'] = array($orderby => $sort);
3237
-        }
3238
-        if ($trash) {
3239
-            $query_args[0]['status'] = array('!=', 'publish');
3240
-            $all_attendees = $count
3241
-                ? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3242
-                : $this->getAttendeeModel()->get_all($query_args);
3243
-        } else {
3244
-            $query_args[0]['status'] = array('IN', array('publish'));
3245
-            $all_attendees = $count
3246
-                ? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3247
-                : $this->getAttendeeModel()->get_all($query_args);
3248
-        }
3249
-        return $all_attendees;
3250
-    }
3251
-
3252
-
3253
-    /**
3254
-     * This is just taking care of resending the registration confirmation
3255
-     *
3256
-     * @access protected
3257
-     * @return void
3258
-     * @throws EE_Error
3259
-     * @throws InvalidArgumentException
3260
-     * @throws InvalidDataTypeException
3261
-     * @throws InvalidInterfaceException
3262
-     * @throws ReflectionException
3263
-     */
3264
-    protected function _resend_registration()
3265
-    {
3266
-        $this->_process_resend_registration();
3267
-        $query_args = isset($this->_req_data['redirect_to'])
3268
-            ? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3269
-            : array('action' => 'default');
3270
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3271
-    }
3272
-
3273
-    /**
3274
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3275
-     * to use when selecting registrations
3276
-     *
3277
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3278
-     *                                                     the query parameters from the request
3279
-     * @return void ends the request with a redirect or download
3280
-     */
3281
-    public function _registrations_report_base($method_name_for_getting_query_params)
3282
-    {
3283
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3284
-            wp_redirect(
3285
-                EE_Admin_Page::add_query_args_and_nonce(
3286
-                    array(
3287
-                        'page'        => 'espresso_batch',
3288
-                        'batch'       => 'file',
3289
-                        'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3290
-                        'filters'     => urlencode(
3291
-                            serialize(
3292
-                                $this->$method_name_for_getting_query_params(
3293
-                                    EEH_Array::is_set(
3294
-                                        $this->_req_data,
3295
-                                        'filters',
3296
-                                        array()
3297
-                                    )
3298
-                                )
3299
-                            )
3300
-                        ),
3301
-                        'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3302
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3303
-                        'return_url'  => urlencode($this->_req_data['return_url']),
3304
-                    )
3305
-                )
3306
-            );
3307
-        } else {
3308
-            $new_request_args = array(
3309
-                'export' => 'report',
3310
-                'action' => 'registrations_report_for_event',
3311
-                'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3312
-            );
3313
-            $this->_req_data = array_merge($this->_req_data, $new_request_args);
3314
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3315
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3316
-                $EE_Export = EE_Export::instance($this->_req_data);
3317
-                $EE_Export->export();
3318
-            }
3319
-        }
3320
-    }
3321
-
3322
-
3323
-    /**
3324
-     * Creates a registration report using only query parameters in the request
3325
-     *
3326
-     * @return void
3327
-     */
3328
-    public function _registrations_report()
3329
-    {
3330
-        $this->_registrations_report_base('_get_registration_query_parameters');
3331
-    }
3332
-
3333
-
3334
-    public function _contact_list_export()
3335
-    {
3336
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3337
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3338
-            $EE_Export = EE_Export::instance($this->_req_data);
3339
-            $EE_Export->export_attendees();
3340
-        }
3341
-    }
3342
-
3343
-
3344
-    public function _contact_list_report()
3345
-    {
3346
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3347
-            wp_redirect(
3348
-                EE_Admin_Page::add_query_args_and_nonce(
3349
-                    array(
3350
-                        'page'        => 'espresso_batch',
3351
-                        'batch'       => 'file',
3352
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3353
-                        'return_url'  => urlencode($this->_req_data['return_url']),
3354
-                    )
3355
-                )
3356
-            );
3357
-        } else {
3358
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3359
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3360
-                $EE_Export = EE_Export::instance($this->_req_data);
3361
-                $EE_Export->report_attendees();
3362
-            }
3363
-        }
3364
-    }
3365
-
3366
-
3367
-
3368
-
3369
-
3370
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3371
-    /**
3372
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3373
-     *
3374
-     * @return void
3375
-     * @throws EE_Error
3376
-     * @throws InvalidArgumentException
3377
-     * @throws InvalidDataTypeException
3378
-     * @throws InvalidInterfaceException
3379
-     * @throws ReflectionException
3380
-     */
3381
-    protected function _duplicate_attendee()
3382
-    {
3383
-        $action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3384
-        // verify we have necessary info
3385
-        if (empty($this->_req_data['_REG_ID'])) {
3386
-            EE_Error::add_error(
3387
-                esc_html__(
3388
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3389
-                    'event_espresso'
3390
-                ),
3391
-                __FILE__,
3392
-                __LINE__,
3393
-                __FUNCTION__
3394
-            );
3395
-            $query_args = array('action' => $action);
3396
-            $this->_redirect_after_action('', '', '', $query_args, true);
3397
-        }
3398
-        // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3399
-        $registration = $this->getRegistrationModel()->get_one_by_ID($this->_req_data['_REG_ID']);
3400
-        $attendee = $registration->attendee();
3401
-        // remove relation of existing attendee on registration
3402
-        $registration->_remove_relation_to($attendee, 'Attendee');
3403
-        // new attendee
3404
-        $new_attendee = clone $attendee;
3405
-        $new_attendee->set('ATT_ID', 0);
3406
-        $new_attendee->save();
3407
-        // add new attendee to reg
3408
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3409
-        EE_Error::add_success(
3410
-            esc_html__(
3411
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3412
-                'event_espresso'
3413
-            )
3414
-        );
3415
-        // redirect to edit page for attendee
3416
-        $query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3417
-        $this->_redirect_after_action('', '', '', $query_args, true);
3418
-    }
3419
-
3420
-
3421
-    /**
3422
-     * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3423
-     *
3424
-     * @param int     $post_id
3425
-     * @param WP_POST $post
3426
-     * @throws DomainException
3427
-     * @throws EE_Error
3428
-     * @throws InvalidArgumentException
3429
-     * @throws InvalidDataTypeException
3430
-     * @throws InvalidInterfaceException
3431
-     * @throws LogicException
3432
-     * @throws InvalidFormSubmissionException
3433
-     * @throws ReflectionException
3434
-     */
3435
-    protected function _insert_update_cpt_item($post_id, $post)
3436
-    {
3437
-        $success = true;
3438
-        $attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3439
-            ? $this->getAttendeeModel()->get_one_by_ID($post_id)
3440
-            : null;
3441
-        // for attendee updates
3442
-        if ($attendee instanceof EE_Attendee) {
3443
-            // note we should only be UPDATING attendees at this point.
3444
-            $updated_fields = array(
3445
-                'ATT_fname'     => $this->_req_data['ATT_fname'],
3446
-                'ATT_lname'     => $this->_req_data['ATT_lname'],
3447
-                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3448
-                'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3449
-                'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3450
-                'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3451
-                'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3452
-                'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3453
-                'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3454
-            );
3455
-            foreach ($updated_fields as $field => $value) {
3456
-                $attendee->set($field, $value);
3457
-            }
3458
-
3459
-            // process contact details metabox form handler (which will also save the attendee)
3460
-            $contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3461
-            $success = $contact_details_form->process($this->_req_data);
3462
-
3463
-            $attendee_update_callbacks = apply_filters(
3464
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3465
-                array()
3466
-            );
3467
-            foreach ($attendee_update_callbacks as $a_callback) {
3468
-                if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3469
-                    throw new EE_Error(
3470
-                        sprintf(
3471
-                            esc_html__(
3472
-                                'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3473
-                                'event_espresso'
3474
-                            ),
3475
-                            $a_callback
3476
-                        )
3477
-                    );
3478
-                }
3479
-            }
3480
-        }
3481
-
3482
-        if ($success === false) {
3483
-            EE_Error::add_error(
3484
-                esc_html__(
3485
-                    'Something went wrong with updating the meta table data for the registration.',
3486
-                    'event_espresso'
3487
-                ),
3488
-                __FILE__,
3489
-                __FUNCTION__,
3490
-                __LINE__
3491
-            );
3492
-        }
3493
-    }
3494
-
3495
-
3496
-    public function trash_cpt_item($post_id)
3497
-    {
3498
-    }
3499
-
3500
-
3501
-    public function delete_cpt_item($post_id)
3502
-    {
3503
-    }
3504
-
3505
-
3506
-    public function restore_cpt_item($post_id)
3507
-    {
3508
-    }
3509
-
3510
-
3511
-    protected function _restore_cpt_item($post_id, $revision_id)
3512
-    {
3513
-    }
3514
-
3515
-
3516
-    /**
3517
-     * @throws EE_Error
3518
-     * @since 4.10.2.p
3519
-     */
3520
-    public function attendee_editor_metaboxes()
3521
-    {
3522
-        $this->verify_cpt_object();
3523
-        remove_meta_box(
3524
-            'postexcerpt',
3525
-            $this->_cpt_routes[ $this->_req_action ],
3526
-            'normal'
3527
-        );
3528
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal', 'core');
3529
-        if (post_type_supports('espresso_attendees', 'excerpt')) {
3530
-            add_meta_box(
3531
-                'postexcerpt',
3532
-                esc_html__('Short Biography', 'event_espresso'),
3533
-                'post_excerpt_meta_box',
3534
-                $this->_cpt_routes[ $this->_req_action ],
3535
-                'normal'
3536
-            );
3537
-        }
3538
-        if (post_type_supports('espresso_attendees', 'comments')) {
3539
-            add_meta_box(
3540
-                'commentsdiv',
3541
-                esc_html__('Notes on the Contact', 'event_espresso'),
3542
-                'post_comment_meta_box',
3543
-                $this->_cpt_routes[ $this->_req_action ],
3544
-                'normal',
3545
-                'core'
3546
-            );
3547
-        }
3548
-        add_meta_box(
3549
-            'attendee_contact_info',
3550
-            esc_html__('Contact Info', 'event_espresso'),
3551
-            array($this, 'attendee_contact_info'),
3552
-            $this->_cpt_routes[ $this->_req_action ],
3553
-            'side',
3554
-            'core'
3555
-        );
3556
-        add_meta_box(
3557
-            'attendee_details_address',
3558
-            esc_html__('Address Details', 'event_espresso'),
3559
-            array($this, 'attendee_address_details'),
3560
-            $this->_cpt_routes[ $this->_req_action ],
3561
-            'normal',
3562
-            'core'
3563
-        );
3564
-        add_meta_box(
3565
-            'attendee_registrations',
3566
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3567
-            array($this, 'attendee_registrations_meta_box'),
3568
-            $this->_cpt_routes[ $this->_req_action ],
3569
-            'normal',
3570
-            'high'
3571
-        );
3572
-    }
3573
-
3574
-
3575
-    /**
3576
-     * Metabox for attendee contact info
3577
-     *
3578
-     * @param  WP_Post $post wp post object
3579
-     * @return string attendee contact info ( and form )
3580
-     * @throws EE_Error
3581
-     * @throws InvalidArgumentException
3582
-     * @throws InvalidDataTypeException
3583
-     * @throws InvalidInterfaceException
3584
-     * @throws LogicException
3585
-     * @throws DomainException
3586
-     */
3587
-    public function attendee_contact_info($post)
3588
-    {
3589
-        // get attendee object ( should already have it )
3590
-        $form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3591
-        $form->enqueueStylesAndScripts();
3592
-        echo $form->display();
3593
-    }
3594
-
3595
-
3596
-    /**
3597
-     * Return form handler for the contact details metabox
3598
-     *
3599
-     * @param EE_Attendee $attendee
3600
-     * @return AttendeeContactDetailsMetaboxFormHandler
3601
-     * @throws DomainException
3602
-     * @throws InvalidArgumentException
3603
-     * @throws InvalidDataTypeException
3604
-     * @throws InvalidInterfaceException
3605
-     */
3606
-    protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3607
-    {
3608
-        return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3609
-    }
3610
-
3611
-
3612
-    /**
3613
-     * Metabox for attendee details
3614
-     *
3615
-     * @param  WP_Post $post wp post object
3616
-     * @throws DomainException
3617
-     */
3618
-    public function attendee_address_details($post)
3619
-    {
3620
-        // get attendee object (should already have it)
3621
-        $this->_template_args['attendee'] = $this->_cpt_model_obj;
3622
-        $this->_template_args['state_html'] = EEH_Form_Fields::generate_form_input(
3623
-            new EE_Question_Form_Input(
3624
-                EE_Question::new_instance(
3625
-                    array(
3626
-                        'QST_ID'           => 0,
3627
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3628
-                        'QST_system'       => 'admin-state',
3629
-                    )
3630
-                ),
3631
-                EE_Answer::new_instance(
3632
-                    array(
3633
-                        'ANS_ID'    => 0,
3634
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3635
-                    )
3636
-                ),
3637
-                array(
3638
-                    'input_id'       => 'STA_ID',
3639
-                    'input_name'     => 'STA_ID',
3640
-                    'input_prefix'   => '',
3641
-                    'append_qstn_id' => false,
3642
-                )
3643
-            )
3644
-        );
3645
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3646
-            new EE_Question_Form_Input(
3647
-                EE_Question::new_instance(
3648
-                    array(
3649
-                        'QST_ID'           => 0,
3650
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3651
-                        'QST_system'       => 'admin-country',
3652
-                    )
3653
-                ),
3654
-                EE_Answer::new_instance(
3655
-                    array(
3656
-                        'ANS_ID'    => 0,
3657
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3658
-                    )
3659
-                ),
3660
-                array(
3661
-                    'input_id'       => 'CNT_ISO',
3662
-                    'input_name'     => 'CNT_ISO',
3663
-                    'input_prefix'   => '',
3664
-                    'append_qstn_id' => false,
3665
-                )
3666
-            )
3667
-        );
3668
-        $template =
3669
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3670
-        EEH_Template::display_template($template, $this->_template_args);
3671
-    }
3672
-
3673
-
3674
-    /**
3675
-     *        _attendee_details
3676
-     *
3677
-     * @access protected
3678
-     * @param $post
3679
-     * @return void
3680
-     * @throws DomainException
3681
-     * @throws EE_Error
3682
-     * @throws InvalidArgumentException
3683
-     * @throws InvalidDataTypeException
3684
-     * @throws InvalidInterfaceException
3685
-     * @throws ReflectionException
3686
-     */
3687
-    public function attendee_registrations_meta_box($post)
3688
-    {
3689
-        $this->_template_args['attendee'] = $this->_cpt_model_obj;
3690
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3691
-        $template =
3692
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3693
-        EEH_Template::display_template($template, $this->_template_args);
3694
-    }
3695
-
3696
-
3697
-    /**
3698
-     * add in the form fields for the attendee edit
3699
-     *
3700
-     * @param  WP_Post $post wp post object
3701
-     * @return string html for new form.
3702
-     * @throws DomainException
3703
-     */
3704
-    public function after_title_form_fields($post)
3705
-    {
3706
-        if ($post->post_type === 'espresso_attendees') {
3707
-            $template = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3708
-            $template_args['attendee'] = $this->_cpt_model_obj;
3709
-            EEH_Template::display_template($template, $template_args);
3710
-        }
3711
-    }
3712
-
3713
-
3714
-    /**
3715
-     *        _trash_or_restore_attendee
3716
-     *
3717
-     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3718
-     * @return void
3719
-     * @throws EE_Error
3720
-     * @throws InvalidArgumentException
3721
-     * @throws InvalidDataTypeException
3722
-     * @throws InvalidInterfaceException
3723
-     * @throws ReflectionException
3724
-     * @access protected
3725
-     */
3726
-    protected function _trash_or_restore_attendees($trash = true)
3727
-    {
3728
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3729
-        $success = 1;
3730
-        // Checkboxes
3731
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3732
-            // if array has more than one element than success message should be plural
3733
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3734
-            // cycle thru checkboxes
3735
-            foreach ($this->_req_data['checkbox'] as $ATT_ID) {
3736
-                $updated = $trash ? $this->getAttendeeModel()->update_by_ID(array('status' => 'trash'), $ATT_ID)
3737
-                    : $this->getAttendeeModel()->update_by_ID(array('status' => 'publish'), $ATT_ID);
3738
-                if (! $updated) {
3739
-                    $success = 0;
3740
-                }
3741
-            }
3742
-        } else {
3743
-            // grab single id and delete
3744
-            $ATT_ID = absint($this->_req_data['ATT_ID']);
3745
-            // get attendee
3746
-            $att = $this->getAttendeeModel()->get_one_by_ID($ATT_ID);
3747
-            $updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3748
-            $updated = $att->save() && $updated;
3749
-            if (! $updated) {
3750
-                $success = 0;
3751
-            }
3752
-        }
3753
-        $what = $success > 1
3754
-            ? esc_html__('Contacts', 'event_espresso')
3755
-            : esc_html__('Contact', 'event_espresso');
3756
-        $action_desc = $trash
3757
-            ? esc_html__('moved to the trash', 'event_espresso')
3758
-            : esc_html__('restored', 'event_espresso');
3759
-        $this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3760
-    }
2897
+		}
2898
+		$template_args = array(
2899
+			'title'                    => '',
2900
+			'content'                  => '',
2901
+			'step_button_text'         => '',
2902
+			'show_notification_toggle' => false,
2903
+		);
2904
+		// to indicate we're processing a new registration
2905
+		$hidden_fields = array(
2906
+			'processing_registration' => array(
2907
+				'type'  => 'hidden',
2908
+				'value' => 0,
2909
+			),
2910
+			'event_id'                => array(
2911
+				'type'  => 'hidden',
2912
+				'value' => $this->_reg_event->ID(),
2913
+			),
2914
+		);
2915
+		// if the cart is empty then we know we're at step one so we'll display ticket selector
2916
+		$cart = EE_Registry::instance()->SSN->cart();
2917
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2918
+		switch ($step) {
2919
+			case 'ticket':
2920
+				$hidden_fields['processing_registration']['value'] = 1;
2921
+				$template_args['title'] = esc_html__(
2922
+					'Step One: Select the Ticket for this registration',
2923
+					'event_espresso'
2924
+				);
2925
+				$template_args['content'] =
2926
+					EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2927
+				$template_args['content'] .= '</div>';
2928
+				$template_args['step_button_text'] = esc_html__(
2929
+					'Add Tickets and Continue to Registrant Details',
2930
+					'event_espresso'
2931
+				);
2932
+				$template_args['show_notification_toggle'] = false;
2933
+				break;
2934
+			case 'questions':
2935
+				$hidden_fields['processing_registration']['value'] = 2;
2936
+				$template_args['title'] = esc_html__(
2937
+					'Step Two: Add Registrant Details for this Registration',
2938
+					'event_espresso'
2939
+				);
2940
+				// in theory we should be able to run EED_SPCO at this point because the cart should have been setup
2941
+				// properly by the first process_reg_step run.
2942
+				$template_args['content'] =
2943
+					EED_Single_Page_Checkout::registration_checkout_for_admin();
2944
+				$template_args['step_button_text'] = esc_html__(
2945
+					'Save Registration and Continue to Details',
2946
+					'event_espresso'
2947
+				);
2948
+				$template_args['show_notification_toggle'] = true;
2949
+				break;
2950
+		}
2951
+		// we come back to the process_registration_step route.
2952
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2953
+		return EEH_Template::display_template(
2954
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2955
+			$template_args,
2956
+			true
2957
+		);
2958
+	}
2959
+
2960
+
2961
+	/**
2962
+	 *        set_reg_event
2963
+	 *
2964
+	 * @access private
2965
+	 * @return bool
2966
+	 * @throws EE_Error
2967
+	 * @throws InvalidArgumentException
2968
+	 * @throws InvalidDataTypeException
2969
+	 * @throws InvalidInterfaceException
2970
+	 */
2971
+	private function _set_reg_event()
2972
+	{
2973
+		if (is_object($this->_reg_event)) {
2974
+			return true;
2975
+		}
2976
+		$EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2977
+		if (! $EVT_ID) {
2978
+			return false;
2979
+		}
2980
+		$this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2981
+		return true;
2982
+	}
2983
+
2984
+
2985
+	/**
2986
+	 * process_reg_step
2987
+	 *
2988
+	 * @access        public
2989
+	 * @return string
2990
+	 * @throws DomainException
2991
+	 * @throws EE_Error
2992
+	 * @throws InvalidArgumentException
2993
+	 * @throws InvalidDataTypeException
2994
+	 * @throws InvalidInterfaceException
2995
+	 * @throws ReflectionException
2996
+	 * @throws RuntimeException
2997
+	 */
2998
+	public function process_reg_step()
2999
+	{
3000
+		EE_System::do_not_cache();
3001
+		$this->_set_reg_event();
3002
+		EE_Registry::instance()->REQ->set_espresso_page(true);
3003
+		EE_Registry::instance()->REQ->set('uts', time());
3004
+		// what step are we on?
3005
+		$cart = EE_Registry::instance()->SSN->cart();
3006
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3007
+		// if doing ajax then we need to verify the nonce
3008
+		if (defined('DOING_AJAX')) {
3009
+			$nonce = isset($this->_req_data[ $this->_req_nonce ])
3010
+				? sanitize_text_field($this->_req_data[ $this->_req_nonce ]) : '';
3011
+			$this->_verify_nonce($nonce, $this->_req_nonce);
3012
+		}
3013
+		switch ($step) {
3014
+			case 'ticket':
3015
+				// process ticket selection
3016
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
3017
+				if ($success) {
3018
+					EE_Error::add_success(
3019
+						esc_html__(
3020
+							'Tickets Selected. Now complete the registration.',
3021
+							'event_espresso'
3022
+						)
3023
+					);
3024
+				} else {
3025
+					$query_args['step_error'] = $this->_req_data['step_error'] = true;
3026
+				}
3027
+				if (defined('DOING_AJAX')) {
3028
+					$this->new_registration(); // display next step
3029
+				} else {
3030
+					$query_args = array(
3031
+						'action'                  => 'new_registration',
3032
+						'processing_registration' => 1,
3033
+						'event_id'                => $this->_reg_event->ID(),
3034
+						'uts'                     => time(),
3035
+					);
3036
+					$this->_redirect_after_action(
3037
+						false,
3038
+						'',
3039
+						'',
3040
+						$query_args,
3041
+						true
3042
+					);
3043
+				}
3044
+				break;
3045
+			case 'questions':
3046
+				if (! isset(
3047
+					$this->_req_data['txn_reg_status_change'],
3048
+					$this->_req_data['txn_reg_status_change']['send_notifications']
3049
+				)
3050
+				) {
3051
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3052
+				}
3053
+				// process registration
3054
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3055
+				if ($cart instanceof EE_Cart) {
3056
+					$grand_total = $cart->get_cart_grand_total();
3057
+					if ($grand_total instanceof EE_Line_Item) {
3058
+						$grand_total->save_this_and_descendants_to_txn();
3059
+					}
3060
+				}
3061
+				if (! $transaction instanceof EE_Transaction) {
3062
+					$query_args = array(
3063
+						'action'                  => 'new_registration',
3064
+						'processing_registration' => 2,
3065
+						'event_id'                => $this->_reg_event->ID(),
3066
+						'uts'                     => time(),
3067
+					);
3068
+					if (defined('DOING_AJAX')) {
3069
+						// display registration form again because there are errors (maybe validation?)
3070
+						$this->new_registration();
3071
+						return;
3072
+					}
3073
+					$this->_redirect_after_action(
3074
+						false,
3075
+						'',
3076
+						'',
3077
+						$query_args,
3078
+						true
3079
+					);
3080
+					return;
3081
+				}
3082
+				// maybe update status, and make sure to save transaction if not done already
3083
+				if (! $transaction->update_status_based_on_total_paid()) {
3084
+					$transaction->save();
3085
+				}
3086
+				EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3087
+				$this->_req_data = array();
3088
+				$query_args = array(
3089
+					'action'        => 'redirect_to_txn',
3090
+					'TXN_ID'        => $transaction->ID(),
3091
+					'EVT_ID'        => $this->_reg_event->ID(),
3092
+					'event_name'    => urlencode($this->_reg_event->name()),
3093
+					'redirect_from' => 'new_registration',
3094
+				);
3095
+				$this->_redirect_after_action(false, '', '', $query_args, true);
3096
+				break;
3097
+		}
3098
+		// what are you looking here for?  Should be nothing to do at this point.
3099
+	}
3100
+
3101
+
3102
+	/**
3103
+	 * redirect_to_txn
3104
+	 *
3105
+	 * @access public
3106
+	 * @return void
3107
+	 * @throws EE_Error
3108
+	 * @throws InvalidArgumentException
3109
+	 * @throws InvalidDataTypeException
3110
+	 * @throws InvalidInterfaceException
3111
+	 * @throws ReflectionException
3112
+	 */
3113
+	public function redirect_to_txn()
3114
+	{
3115
+		EE_System::do_not_cache();
3116
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3117
+		$query_args = array(
3118
+			'action' => 'view_transaction',
3119
+			'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3120
+			'page'   => 'espresso_transactions',
3121
+		);
3122
+		if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3123
+			$query_args['EVT_ID'] = $this->_req_data['EVT_ID'];
3124
+			$query_args['event_name'] = urlencode($this->_req_data['event_name']);
3125
+			$query_args['redirect_from'] = $this->_req_data['redirect_from'];
3126
+		}
3127
+		EE_Error::add_success(
3128
+			esc_html__(
3129
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3130
+				'event_espresso'
3131
+			)
3132
+		);
3133
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3134
+	}
3135
+
3136
+
3137
+	/**
3138
+	 *        generates HTML for the Attendee Contact List
3139
+	 *
3140
+	 * @access protected
3141
+	 * @return void
3142
+	 * @throws DomainException
3143
+	 * @throws EE_Error
3144
+	 */
3145
+	protected function _attendee_contact_list_table()
3146
+	{
3147
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3148
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3149
+		$this->display_admin_list_table_page_with_no_sidebar();
3150
+	}
3151
+
3152
+
3153
+	/**
3154
+	 *        get_attendees
3155
+	 *
3156
+	 * @param      $per_page
3157
+	 * @param bool $count whether to return count or data.
3158
+	 * @param bool $trash
3159
+	 * @return array
3160
+	 * @throws EE_Error
3161
+	 * @throws InvalidArgumentException
3162
+	 * @throws InvalidDataTypeException
3163
+	 * @throws InvalidInterfaceException
3164
+	 * @access public
3165
+	 */
3166
+	public function get_attendees($per_page, $count = false, $trash = false)
3167
+	{
3168
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3169
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3170
+		$this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3171
+		switch ($this->_req_data['orderby']) {
3172
+			case 'ATT_ID':
3173
+				$orderby = 'ATT_ID';
3174
+				break;
3175
+			case 'ATT_fname':
3176
+				$orderby = 'ATT_fname';
3177
+				break;
3178
+			case 'ATT_email':
3179
+				$orderby = 'ATT_email';
3180
+				break;
3181
+			case 'ATT_city':
3182
+				$orderby = 'ATT_city';
3183
+				break;
3184
+			case 'STA_ID':
3185
+				$orderby = 'STA_ID';
3186
+				break;
3187
+			case 'CNT_ID':
3188
+				$orderby = 'CNT_ID';
3189
+				break;
3190
+			case 'Registration_Count':
3191
+				$orderby = 'Registration_Count';
3192
+				break;
3193
+			default:
3194
+				$orderby = 'ATT_lname';
3195
+		}
3196
+		$sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3197
+			? $this->_req_data['order']
3198
+			: 'ASC';
3199
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3200
+			? $this->_req_data['paged']
3201
+			: 1;
3202
+		$per_page = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3203
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3204
+			? $this->_req_data['perpage']
3205
+			: $per_page;
3206
+		$_where = array();
3207
+		if (! empty($this->_req_data['s'])) {
3208
+			$sstr = '%' . $this->_req_data['s'] . '%';
3209
+			$_where['OR'] = array(
3210
+				'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3211
+				'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3212
+				'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3213
+				'ATT_fname'                         => array('LIKE', $sstr),
3214
+				'ATT_lname'                         => array('LIKE', $sstr),
3215
+				'ATT_short_bio'                     => array('LIKE', $sstr),
3216
+				'ATT_email'                         => array('LIKE', $sstr),
3217
+				'ATT_address'                       => array('LIKE', $sstr),
3218
+				'ATT_address2'                      => array('LIKE', $sstr),
3219
+				'ATT_city'                          => array('LIKE', $sstr),
3220
+				'Country.CNT_name'                  => array('LIKE', $sstr),
3221
+				'State.STA_name'                    => array('LIKE', $sstr),
3222
+				'ATT_phone'                         => array('LIKE', $sstr),
3223
+				'Registration.REG_final_price'      => array('LIKE', $sstr),
3224
+				'Registration.REG_code'             => array('LIKE', $sstr),
3225
+				'Registration.REG_group_size'       => array('LIKE', $sstr),
3226
+			);
3227
+		}
3228
+		$offset = ($current_page - 1) * $per_page;
3229
+		$limit = $count ? null : array($offset, $per_page);
3230
+		$query_args = array(
3231
+			$_where,
3232
+			'extra_selects' => array('Registration_Count' => array('Registration.REG_ID', 'count', '%d')),
3233
+			'limit'         => $limit,
3234
+		);
3235
+		if (! $count) {
3236
+			$query_args['order_by'] = array($orderby => $sort);
3237
+		}
3238
+		if ($trash) {
3239
+			$query_args[0]['status'] = array('!=', 'publish');
3240
+			$all_attendees = $count
3241
+				? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3242
+				: $this->getAttendeeModel()->get_all($query_args);
3243
+		} else {
3244
+			$query_args[0]['status'] = array('IN', array('publish'));
3245
+			$all_attendees = $count
3246
+				? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3247
+				: $this->getAttendeeModel()->get_all($query_args);
3248
+		}
3249
+		return $all_attendees;
3250
+	}
3251
+
3252
+
3253
+	/**
3254
+	 * This is just taking care of resending the registration confirmation
3255
+	 *
3256
+	 * @access protected
3257
+	 * @return void
3258
+	 * @throws EE_Error
3259
+	 * @throws InvalidArgumentException
3260
+	 * @throws InvalidDataTypeException
3261
+	 * @throws InvalidInterfaceException
3262
+	 * @throws ReflectionException
3263
+	 */
3264
+	protected function _resend_registration()
3265
+	{
3266
+		$this->_process_resend_registration();
3267
+		$query_args = isset($this->_req_data['redirect_to'])
3268
+			? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3269
+			: array('action' => 'default');
3270
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3271
+	}
3272
+
3273
+	/**
3274
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3275
+	 * to use when selecting registrations
3276
+	 *
3277
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3278
+	 *                                                     the query parameters from the request
3279
+	 * @return void ends the request with a redirect or download
3280
+	 */
3281
+	public function _registrations_report_base($method_name_for_getting_query_params)
3282
+	{
3283
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3284
+			wp_redirect(
3285
+				EE_Admin_Page::add_query_args_and_nonce(
3286
+					array(
3287
+						'page'        => 'espresso_batch',
3288
+						'batch'       => 'file',
3289
+						'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3290
+						'filters'     => urlencode(
3291
+							serialize(
3292
+								$this->$method_name_for_getting_query_params(
3293
+									EEH_Array::is_set(
3294
+										$this->_req_data,
3295
+										'filters',
3296
+										array()
3297
+									)
3298
+								)
3299
+							)
3300
+						),
3301
+						'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3302
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3303
+						'return_url'  => urlencode($this->_req_data['return_url']),
3304
+					)
3305
+				)
3306
+			);
3307
+		} else {
3308
+			$new_request_args = array(
3309
+				'export' => 'report',
3310
+				'action' => 'registrations_report_for_event',
3311
+				'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3312
+			);
3313
+			$this->_req_data = array_merge($this->_req_data, $new_request_args);
3314
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3315
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3316
+				$EE_Export = EE_Export::instance($this->_req_data);
3317
+				$EE_Export->export();
3318
+			}
3319
+		}
3320
+	}
3321
+
3322
+
3323
+	/**
3324
+	 * Creates a registration report using only query parameters in the request
3325
+	 *
3326
+	 * @return void
3327
+	 */
3328
+	public function _registrations_report()
3329
+	{
3330
+		$this->_registrations_report_base('_get_registration_query_parameters');
3331
+	}
3332
+
3333
+
3334
+	public function _contact_list_export()
3335
+	{
3336
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3337
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3338
+			$EE_Export = EE_Export::instance($this->_req_data);
3339
+			$EE_Export->export_attendees();
3340
+		}
3341
+	}
3342
+
3343
+
3344
+	public function _contact_list_report()
3345
+	{
3346
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3347
+			wp_redirect(
3348
+				EE_Admin_Page::add_query_args_and_nonce(
3349
+					array(
3350
+						'page'        => 'espresso_batch',
3351
+						'batch'       => 'file',
3352
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3353
+						'return_url'  => urlencode($this->_req_data['return_url']),
3354
+					)
3355
+				)
3356
+			);
3357
+		} else {
3358
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3359
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3360
+				$EE_Export = EE_Export::instance($this->_req_data);
3361
+				$EE_Export->report_attendees();
3362
+			}
3363
+		}
3364
+	}
3365
+
3366
+
3367
+
3368
+
3369
+
3370
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3371
+	/**
3372
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3373
+	 *
3374
+	 * @return void
3375
+	 * @throws EE_Error
3376
+	 * @throws InvalidArgumentException
3377
+	 * @throws InvalidDataTypeException
3378
+	 * @throws InvalidInterfaceException
3379
+	 * @throws ReflectionException
3380
+	 */
3381
+	protected function _duplicate_attendee()
3382
+	{
3383
+		$action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3384
+		// verify we have necessary info
3385
+		if (empty($this->_req_data['_REG_ID'])) {
3386
+			EE_Error::add_error(
3387
+				esc_html__(
3388
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3389
+					'event_espresso'
3390
+				),
3391
+				__FILE__,
3392
+				__LINE__,
3393
+				__FUNCTION__
3394
+			);
3395
+			$query_args = array('action' => $action);
3396
+			$this->_redirect_after_action('', '', '', $query_args, true);
3397
+		}
3398
+		// okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3399
+		$registration = $this->getRegistrationModel()->get_one_by_ID($this->_req_data['_REG_ID']);
3400
+		$attendee = $registration->attendee();
3401
+		// remove relation of existing attendee on registration
3402
+		$registration->_remove_relation_to($attendee, 'Attendee');
3403
+		// new attendee
3404
+		$new_attendee = clone $attendee;
3405
+		$new_attendee->set('ATT_ID', 0);
3406
+		$new_attendee->save();
3407
+		// add new attendee to reg
3408
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3409
+		EE_Error::add_success(
3410
+			esc_html__(
3411
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3412
+				'event_espresso'
3413
+			)
3414
+		);
3415
+		// redirect to edit page for attendee
3416
+		$query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3417
+		$this->_redirect_after_action('', '', '', $query_args, true);
3418
+	}
3419
+
3420
+
3421
+	/**
3422
+	 * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3423
+	 *
3424
+	 * @param int     $post_id
3425
+	 * @param WP_POST $post
3426
+	 * @throws DomainException
3427
+	 * @throws EE_Error
3428
+	 * @throws InvalidArgumentException
3429
+	 * @throws InvalidDataTypeException
3430
+	 * @throws InvalidInterfaceException
3431
+	 * @throws LogicException
3432
+	 * @throws InvalidFormSubmissionException
3433
+	 * @throws ReflectionException
3434
+	 */
3435
+	protected function _insert_update_cpt_item($post_id, $post)
3436
+	{
3437
+		$success = true;
3438
+		$attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3439
+			? $this->getAttendeeModel()->get_one_by_ID($post_id)
3440
+			: null;
3441
+		// for attendee updates
3442
+		if ($attendee instanceof EE_Attendee) {
3443
+			// note we should only be UPDATING attendees at this point.
3444
+			$updated_fields = array(
3445
+				'ATT_fname'     => $this->_req_data['ATT_fname'],
3446
+				'ATT_lname'     => $this->_req_data['ATT_lname'],
3447
+				'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3448
+				'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3449
+				'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3450
+				'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3451
+				'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3452
+				'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3453
+				'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3454
+			);
3455
+			foreach ($updated_fields as $field => $value) {
3456
+				$attendee->set($field, $value);
3457
+			}
3458
+
3459
+			// process contact details metabox form handler (which will also save the attendee)
3460
+			$contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3461
+			$success = $contact_details_form->process($this->_req_data);
3462
+
3463
+			$attendee_update_callbacks = apply_filters(
3464
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3465
+				array()
3466
+			);
3467
+			foreach ($attendee_update_callbacks as $a_callback) {
3468
+				if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3469
+					throw new EE_Error(
3470
+						sprintf(
3471
+							esc_html__(
3472
+								'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3473
+								'event_espresso'
3474
+							),
3475
+							$a_callback
3476
+						)
3477
+					);
3478
+				}
3479
+			}
3480
+		}
3481
+
3482
+		if ($success === false) {
3483
+			EE_Error::add_error(
3484
+				esc_html__(
3485
+					'Something went wrong with updating the meta table data for the registration.',
3486
+					'event_espresso'
3487
+				),
3488
+				__FILE__,
3489
+				__FUNCTION__,
3490
+				__LINE__
3491
+			);
3492
+		}
3493
+	}
3494
+
3495
+
3496
+	public function trash_cpt_item($post_id)
3497
+	{
3498
+	}
3499
+
3500
+
3501
+	public function delete_cpt_item($post_id)
3502
+	{
3503
+	}
3504
+
3505
+
3506
+	public function restore_cpt_item($post_id)
3507
+	{
3508
+	}
3509
+
3510
+
3511
+	protected function _restore_cpt_item($post_id, $revision_id)
3512
+	{
3513
+	}
3514
+
3515
+
3516
+	/**
3517
+	 * @throws EE_Error
3518
+	 * @since 4.10.2.p
3519
+	 */
3520
+	public function attendee_editor_metaboxes()
3521
+	{
3522
+		$this->verify_cpt_object();
3523
+		remove_meta_box(
3524
+			'postexcerpt',
3525
+			$this->_cpt_routes[ $this->_req_action ],
3526
+			'normal'
3527
+		);
3528
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal', 'core');
3529
+		if (post_type_supports('espresso_attendees', 'excerpt')) {
3530
+			add_meta_box(
3531
+				'postexcerpt',
3532
+				esc_html__('Short Biography', 'event_espresso'),
3533
+				'post_excerpt_meta_box',
3534
+				$this->_cpt_routes[ $this->_req_action ],
3535
+				'normal'
3536
+			);
3537
+		}
3538
+		if (post_type_supports('espresso_attendees', 'comments')) {
3539
+			add_meta_box(
3540
+				'commentsdiv',
3541
+				esc_html__('Notes on the Contact', 'event_espresso'),
3542
+				'post_comment_meta_box',
3543
+				$this->_cpt_routes[ $this->_req_action ],
3544
+				'normal',
3545
+				'core'
3546
+			);
3547
+		}
3548
+		add_meta_box(
3549
+			'attendee_contact_info',
3550
+			esc_html__('Contact Info', 'event_espresso'),
3551
+			array($this, 'attendee_contact_info'),
3552
+			$this->_cpt_routes[ $this->_req_action ],
3553
+			'side',
3554
+			'core'
3555
+		);
3556
+		add_meta_box(
3557
+			'attendee_details_address',
3558
+			esc_html__('Address Details', 'event_espresso'),
3559
+			array($this, 'attendee_address_details'),
3560
+			$this->_cpt_routes[ $this->_req_action ],
3561
+			'normal',
3562
+			'core'
3563
+		);
3564
+		add_meta_box(
3565
+			'attendee_registrations',
3566
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3567
+			array($this, 'attendee_registrations_meta_box'),
3568
+			$this->_cpt_routes[ $this->_req_action ],
3569
+			'normal',
3570
+			'high'
3571
+		);
3572
+	}
3573
+
3574
+
3575
+	/**
3576
+	 * Metabox for attendee contact info
3577
+	 *
3578
+	 * @param  WP_Post $post wp post object
3579
+	 * @return string attendee contact info ( and form )
3580
+	 * @throws EE_Error
3581
+	 * @throws InvalidArgumentException
3582
+	 * @throws InvalidDataTypeException
3583
+	 * @throws InvalidInterfaceException
3584
+	 * @throws LogicException
3585
+	 * @throws DomainException
3586
+	 */
3587
+	public function attendee_contact_info($post)
3588
+	{
3589
+		// get attendee object ( should already have it )
3590
+		$form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3591
+		$form->enqueueStylesAndScripts();
3592
+		echo $form->display();
3593
+	}
3594
+
3595
+
3596
+	/**
3597
+	 * Return form handler for the contact details metabox
3598
+	 *
3599
+	 * @param EE_Attendee $attendee
3600
+	 * @return AttendeeContactDetailsMetaboxFormHandler
3601
+	 * @throws DomainException
3602
+	 * @throws InvalidArgumentException
3603
+	 * @throws InvalidDataTypeException
3604
+	 * @throws InvalidInterfaceException
3605
+	 */
3606
+	protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3607
+	{
3608
+		return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3609
+	}
3610
+
3611
+
3612
+	/**
3613
+	 * Metabox for attendee details
3614
+	 *
3615
+	 * @param  WP_Post $post wp post object
3616
+	 * @throws DomainException
3617
+	 */
3618
+	public function attendee_address_details($post)
3619
+	{
3620
+		// get attendee object (should already have it)
3621
+		$this->_template_args['attendee'] = $this->_cpt_model_obj;
3622
+		$this->_template_args['state_html'] = EEH_Form_Fields::generate_form_input(
3623
+			new EE_Question_Form_Input(
3624
+				EE_Question::new_instance(
3625
+					array(
3626
+						'QST_ID'           => 0,
3627
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3628
+						'QST_system'       => 'admin-state',
3629
+					)
3630
+				),
3631
+				EE_Answer::new_instance(
3632
+					array(
3633
+						'ANS_ID'    => 0,
3634
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3635
+					)
3636
+				),
3637
+				array(
3638
+					'input_id'       => 'STA_ID',
3639
+					'input_name'     => 'STA_ID',
3640
+					'input_prefix'   => '',
3641
+					'append_qstn_id' => false,
3642
+				)
3643
+			)
3644
+		);
3645
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3646
+			new EE_Question_Form_Input(
3647
+				EE_Question::new_instance(
3648
+					array(
3649
+						'QST_ID'           => 0,
3650
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3651
+						'QST_system'       => 'admin-country',
3652
+					)
3653
+				),
3654
+				EE_Answer::new_instance(
3655
+					array(
3656
+						'ANS_ID'    => 0,
3657
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3658
+					)
3659
+				),
3660
+				array(
3661
+					'input_id'       => 'CNT_ISO',
3662
+					'input_name'     => 'CNT_ISO',
3663
+					'input_prefix'   => '',
3664
+					'append_qstn_id' => false,
3665
+				)
3666
+			)
3667
+		);
3668
+		$template =
3669
+			REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3670
+		EEH_Template::display_template($template, $this->_template_args);
3671
+	}
3672
+
3673
+
3674
+	/**
3675
+	 *        _attendee_details
3676
+	 *
3677
+	 * @access protected
3678
+	 * @param $post
3679
+	 * @return void
3680
+	 * @throws DomainException
3681
+	 * @throws EE_Error
3682
+	 * @throws InvalidArgumentException
3683
+	 * @throws InvalidDataTypeException
3684
+	 * @throws InvalidInterfaceException
3685
+	 * @throws ReflectionException
3686
+	 */
3687
+	public function attendee_registrations_meta_box($post)
3688
+	{
3689
+		$this->_template_args['attendee'] = $this->_cpt_model_obj;
3690
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3691
+		$template =
3692
+			REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3693
+		EEH_Template::display_template($template, $this->_template_args);
3694
+	}
3695
+
3696
+
3697
+	/**
3698
+	 * add in the form fields for the attendee edit
3699
+	 *
3700
+	 * @param  WP_Post $post wp post object
3701
+	 * @return string html for new form.
3702
+	 * @throws DomainException
3703
+	 */
3704
+	public function after_title_form_fields($post)
3705
+	{
3706
+		if ($post->post_type === 'espresso_attendees') {
3707
+			$template = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3708
+			$template_args['attendee'] = $this->_cpt_model_obj;
3709
+			EEH_Template::display_template($template, $template_args);
3710
+		}
3711
+	}
3712
+
3713
+
3714
+	/**
3715
+	 *        _trash_or_restore_attendee
3716
+	 *
3717
+	 * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3718
+	 * @return void
3719
+	 * @throws EE_Error
3720
+	 * @throws InvalidArgumentException
3721
+	 * @throws InvalidDataTypeException
3722
+	 * @throws InvalidInterfaceException
3723
+	 * @throws ReflectionException
3724
+	 * @access protected
3725
+	 */
3726
+	protected function _trash_or_restore_attendees($trash = true)
3727
+	{
3728
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3729
+		$success = 1;
3730
+		// Checkboxes
3731
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3732
+			// if array has more than one element than success message should be plural
3733
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3734
+			// cycle thru checkboxes
3735
+			foreach ($this->_req_data['checkbox'] as $ATT_ID) {
3736
+				$updated = $trash ? $this->getAttendeeModel()->update_by_ID(array('status' => 'trash'), $ATT_ID)
3737
+					: $this->getAttendeeModel()->update_by_ID(array('status' => 'publish'), $ATT_ID);
3738
+				if (! $updated) {
3739
+					$success = 0;
3740
+				}
3741
+			}
3742
+		} else {
3743
+			// grab single id and delete
3744
+			$ATT_ID = absint($this->_req_data['ATT_ID']);
3745
+			// get attendee
3746
+			$att = $this->getAttendeeModel()->get_one_by_ID($ATT_ID);
3747
+			$updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3748
+			$updated = $att->save() && $updated;
3749
+			if (! $updated) {
3750
+				$success = 0;
3751
+			}
3752
+		}
3753
+		$what = $success > 1
3754
+			? esc_html__('Contacts', 'event_espresso')
3755
+			: esc_html__('Contact', 'event_espresso');
3756
+		$action_desc = $trash
3757
+			? esc_html__('moved to the trash', 'event_espresso')
3758
+			: esc_html__('restored', 'event_espresso');
3759
+		$this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3760
+	}
3761 3761
 }
Please login to merge, or discard this patch.
Spacing   +97 added lines, -97 removed lines patch added patch discarded remove patch
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
      */
88 88
     protected function getRegistrationModel()
89 89
     {
90
-        if (! $this->registration_model instanceof EEM_Registration) {
90
+        if ( ! $this->registration_model instanceof EEM_Registration) {
91 91
             $this->registration_model = $this->loader->getShared('EEM_Registration');
92 92
         }
93 93
         return $this->registration_model;
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
      */
103 103
     protected function getAttendeeModel()
104 104
     {
105
-        if (! $this->attendee_model instanceof EEM_Attendee) {
105
+        if ( ! $this->attendee_model instanceof EEM_Attendee) {
106 106
             $this->attendee_model = $this->loader->getShared('EEM_Attendee');
107 107
         }
108 108
         return $this->attendee_model;
@@ -118,7 +118,7 @@  discard block
 block discarded – undo
118 118
      */
119 119
     protected function getEventModel()
120 120
     {
121
-        if (! $this->event_model instanceof EEM_Event) {
121
+        if ( ! $this->event_model instanceof EEM_Event) {
122 122
             $this->event_model = $this->loader->getShared('EEM_Event');
123 123
         }
124 124
         return $this->event_model;
@@ -133,7 +133,7 @@  discard block
 block discarded – undo
133 133
      */
134 134
     protected function getStatusModel()
135 135
     {
136
-        if (! $this->status_model instanceof EEM_Status) {
136
+        if ( ! $this->status_model instanceof EEM_Status) {
137 137
             $this->status_model = $this->loader->getShared('EEM_Status');
138 138
         }
139 139
         return $this->status_model;
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
         // when adding a new registration...
146 146
         if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
147 147
             EE_System::do_not_cache();
148
-            if (! isset($this->_req_data['processing_registration'])
148
+            if ( ! isset($this->_req_data['processing_registration'])
149 149
                 || absint($this->_req_data['processing_registration']) !== 1
150 150
             ) {
151 151
                 // and it's NOT the attendee information reg step
@@ -751,7 +751,7 @@  discard block
 block discarded – undo
751 751
         // style
752 752
         wp_register_style(
753 753
             'espresso_reg',
754
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
754
+            REG_ASSETS_URL.'espresso_registrations_admin.css',
755 755
             array('ee-admin-css'),
756 756
             EVENT_ESPRESSO_VERSION
757 757
         );
@@ -759,7 +759,7 @@  discard block
 block discarded – undo
759 759
         // script
760 760
         wp_register_script(
761 761
             'espresso_reg',
762
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
762
+            REG_ASSETS_URL.'espresso_registrations_admin.js',
763 763
             array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
764 764
             EVENT_ESPRESSO_VERSION,
765 765
             true
@@ -783,7 +783,7 @@  discard block
 block discarded – undo
783 783
             'att_publish_text' => sprintf(
784 784
                 /* translators: The date and time */
785 785
                 wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
786
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
786
+                '<b>'.$this->_cpt_model_obj->get_datetime('ATT_created').'</b>'
787 787
             ),
788 788
         );
789 789
         wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
@@ -814,7 +814,7 @@  discard block
 block discarded – undo
814 814
         wp_dequeue_style('espresso_reg');
815 815
         wp_register_style(
816 816
             'espresso_att',
817
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
817
+            REG_ASSETS_URL.'espresso_attendees_admin.css',
818 818
             array('ee-admin-css'),
819 819
             EVENT_ESPRESSO_VERSION
820 820
         );
@@ -826,7 +826,7 @@  discard block
 block discarded – undo
826 826
     {
827 827
         wp_register_script(
828 828
             'ee-spco-for-admin',
829
-            REG_ASSETS_URL . 'spco_for_admin.js',
829
+            REG_ASSETS_URL.'spco_for_admin.js',
830 830
             array('underscore', 'jquery'),
831 831
             EVENT_ESPRESSO_VERSION,
832 832
             true
@@ -1068,7 +1068,7 @@  discard block
 block discarded – undo
1068 1068
         }
1069 1069
         $sc_items = array(
1070 1070
             'approved_status'   => array(
1071
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
1071
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_approved,
1072 1072
                 'desc'  => EEH_Template::pretty_status(
1073 1073
                     EEM_Registration::status_id_approved,
1074 1074
                     false,
@@ -1076,7 +1076,7 @@  discard block
 block discarded – undo
1076 1076
                 ),
1077 1077
             ),
1078 1078
             'pending_status'    => array(
1079
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
1079
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_pending_payment,
1080 1080
                 'desc'  => EEH_Template::pretty_status(
1081 1081
                     EEM_Registration::status_id_pending_payment,
1082 1082
                     false,
@@ -1084,7 +1084,7 @@  discard block
 block discarded – undo
1084 1084
                 ),
1085 1085
             ),
1086 1086
             'wait_list'         => array(
1087
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
1087
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_wait_list,
1088 1088
                 'desc'  => EEH_Template::pretty_status(
1089 1089
                     EEM_Registration::status_id_wait_list,
1090 1090
                     false,
@@ -1092,7 +1092,7 @@  discard block
 block discarded – undo
1092 1092
                 ),
1093 1093
             ),
1094 1094
             'incomplete_status' => array(
1095
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
1095
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_incomplete,
1096 1096
                 'desc'  => EEH_Template::pretty_status(
1097 1097
                     EEM_Registration::status_id_incomplete,
1098 1098
                     false,
@@ -1100,7 +1100,7 @@  discard block
 block discarded – undo
1100 1100
                 ),
1101 1101
             ),
1102 1102
             'not_approved'      => array(
1103
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
1103
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_not_approved,
1104 1104
                 'desc'  => EEH_Template::pretty_status(
1105 1105
                     EEM_Registration::status_id_not_approved,
1106 1106
                     false,
@@ -1108,7 +1108,7 @@  discard block
 block discarded – undo
1108 1108
                 ),
1109 1109
             ),
1110 1110
             'declined_status'   => array(
1111
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
1111
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_declined,
1112 1112
                 'desc'  => EEH_Template::pretty_status(
1113 1113
                     EEM_Registration::status_id_declined,
1114 1114
                     false,
@@ -1116,7 +1116,7 @@  discard block
 block discarded – undo
1116 1116
                 ),
1117 1117
             ),
1118 1118
             'cancelled_status'  => array(
1119
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1119
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_cancelled,
1120 1120
                 'desc'  => EEH_Template::pretty_status(
1121 1121
                     EEM_Registration::status_id_cancelled,
1122 1122
                     false,
@@ -1179,7 +1179,7 @@  discard block
 block discarded – undo
1179 1179
                 $EVT_ID
1180 1180
             )
1181 1181
         ) {
1182
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1182
+            $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
1183 1183
                 'new_registration',
1184 1184
                 'add-registrant',
1185 1185
                 array('event_id' => $EVT_ID),
@@ -1205,7 +1205,7 @@  discard block
 block discarded – undo
1205 1205
         if ($this->_registration instanceof EE_Registration) {
1206 1206
             return true;
1207 1207
         }
1208
-        $REG_ID = (! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1208
+        $REG_ID = ( ! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1209 1209
         if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1210 1210
             return true;
1211 1211
         }
@@ -1286,7 +1286,7 @@  discard block
 block discarded – undo
1286 1286
         /** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1287 1287
         $list_table_query_builder = $this->loader->getNew(
1288 1288
             'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1289
-            [ $request ]
1289
+            [$request]
1290 1290
         );
1291 1291
         return $list_table_query_builder->getQueryParams($per_page, $count);
1292 1292
     }
@@ -1392,7 +1392,7 @@  discard block
 block discarded – undo
1392 1392
                 )
1393 1393
                 : '';
1394 1394
             // grab header
1395
-            $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1395
+            $template_path = REG_TEMPLATE_PATH.'reg_admin_details_header.template.php';
1396 1396
             $this->_template_args['REG_ID'] = $this->_registration->ID();
1397 1397
             $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1398 1398
                 $template_path,
@@ -1544,7 +1544,7 @@  discard block
 block discarded – undo
1544 1544
                                 EEH_HTML::strong(
1545 1545
                                     $this->_registration->pretty_status(),
1546 1546
                                     '',
1547
-                                    'status-' . $this->_registration->status_ID(),
1547
+                                    'status-'.$this->_registration->status_ID(),
1548 1548
                                     'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1549 1549
                                 )
1550 1550
                             )
@@ -1600,14 +1600,14 @@  discard block
 block discarded – undo
1600 1600
     protected function _get_reg_statuses()
1601 1601
     {
1602 1602
         $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1603
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1603
+        unset($reg_status_array[EEM_Registration::status_id_incomplete]);
1604 1604
         // get current reg status
1605 1605
         $current_status = $this->_registration->status_ID();
1606 1606
         // is registration for free event? This will determine whether to display the pending payment option
1607 1607
         if ($current_status !== EEM_Registration::status_id_pending_payment
1608 1608
             && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1609 1609
         ) {
1610
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1610
+            unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1611 1611
         }
1612 1612
         return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1613 1613
     }
@@ -1701,7 +1701,7 @@  discard block
 block discarded – undo
1701 1701
         $success = false;
1702 1702
         // typecast $REG_IDs
1703 1703
         $REG_IDs = (array) $REG_IDs;
1704
-        if (! empty($REG_IDs)) {
1704
+        if ( ! empty($REG_IDs)) {
1705 1705
             $success = true;
1706 1706
             // set default status if none is passed
1707 1707
             $status = $status ? $status : EEM_Registration::status_id_pending_payment;
@@ -1864,7 +1864,7 @@  discard block
 block discarded – undo
1864 1864
             $action,
1865 1865
             $notify
1866 1866
         );
1867
-        $method = $action . '_registration';
1867
+        $method = $action.'_registration';
1868 1868
         if (method_exists($this, $method)) {
1869 1869
             $this->$method($notify);
1870 1870
         }
@@ -2143,7 +2143,7 @@  discard block
 block discarded – undo
2143 2143
         $this->_template_args['REG_ID'] = $this->_registration->ID();
2144 2144
         $this->_template_args['event_id'] = $this->_registration->event_ID();
2145 2145
         $template_path =
2146
-            REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2146
+            REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_details.template.php';
2147 2147
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2148 2148
     }
2149 2149
 
@@ -2180,7 +2180,7 @@  discard block
 block discarded – undo
2180 2180
             $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2181 2181
             $this->_template_args['REG_ID'] = $this->_registration->ID();
2182 2182
             $template_path =
2183
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2183
+                REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_questions.template.php';
2184 2184
             echo EEH_Template::display_template($template_path, $this->_template_args, true);
2185 2185
         }
2186 2186
     }
@@ -2197,7 +2197,7 @@  discard block
 block discarded – undo
2197 2197
     public function form_before_question_group($output)
2198 2198
     {
2199 2199
         EE_Error::doing_it_wrong(
2200
-            __CLASS__ . '::' . __FUNCTION__,
2200
+            __CLASS__.'::'.__FUNCTION__,
2201 2201
             esc_html__(
2202 2202
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2203 2203
                 'event_espresso'
@@ -2222,7 +2222,7 @@  discard block
 block discarded – undo
2222 2222
     public function form_after_question_group($output)
2223 2223
     {
2224 2224
         EE_Error::doing_it_wrong(
2225
-            __CLASS__ . '::' . __FUNCTION__,
2225
+            __CLASS__.'::'.__FUNCTION__,
2226 2226
             esc_html__(
2227 2227
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2228 2228
                 'event_espresso'
@@ -2260,7 +2260,7 @@  discard block
 block discarded – undo
2260 2260
     public function form_form_field_label_wrap($label)
2261 2261
     {
2262 2262
         EE_Error::doing_it_wrong(
2263
-            __CLASS__ . '::' . __FUNCTION__,
2263
+            __CLASS__.'::'.__FUNCTION__,
2264 2264
             esc_html__(
2265 2265
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2266 2266
                 'event_espresso'
@@ -2270,7 +2270,7 @@  discard block
 block discarded – undo
2270 2270
         return '
2271 2271
 			<tr>
2272 2272
 				<th>
2273
-					' . $label . '
2273
+					' . $label.'
2274 2274
 				</th>';
2275 2275
     }
2276 2276
 
@@ -2286,7 +2286,7 @@  discard block
 block discarded – undo
2286 2286
     public function form_form_field_input__wrap($input)
2287 2287
     {
2288 2288
         EE_Error::doing_it_wrong(
2289
-            __CLASS__ . '::' . __FUNCTION__,
2289
+            __CLASS__.'::'.__FUNCTION__,
2290 2290
             esc_html__(
2291 2291
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2292 2292
                 'event_espresso'
@@ -2295,7 +2295,7 @@  discard block
 block discarded – undo
2295 2295
         );
2296 2296
         return '
2297 2297
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2298
-					' . $input . '
2298
+					' . $input.'
2299 2299
 				</td>
2300 2300
 			</tr>';
2301 2301
     }
@@ -2343,8 +2343,8 @@  discard block
 block discarded – undo
2343 2343
      */
2344 2344
     protected function _get_reg_custom_questions_form($REG_ID)
2345 2345
     {
2346
-        if (! $this->_reg_custom_questions_form) {
2347
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2346
+        if ( ! $this->_reg_custom_questions_form) {
2347
+            require_once(REG_ADMIN.'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2348 2348
             $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2349 2349
                 $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2350 2350
             );
@@ -2368,7 +2368,7 @@  discard block
 block discarded – undo
2368 2368
      */
2369 2369
     private function _save_reg_custom_questions_form($REG_ID = false)
2370 2370
     {
2371
-        if (! $REG_ID) {
2371
+        if ( ! $REG_ID) {
2372 2372
             EE_Error::add_error(
2373 2373
                 esc_html__(
2374 2374
                     'An error occurred. No registration ID was received.',
@@ -2460,30 +2460,30 @@  discard block
 block discarded – undo
2460 2460
                 $attendee = $registration->attendee()
2461 2461
                     ? $registration->attendee()
2462 2462
                     : $this->getAttendeeModel()->create_default_object();
2463
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID'] = $registration->status_ID();
2464
-                $this->_template_args['attendees'][ $att_nmbr ]['fname'] = $attendee->fname();
2465
-                $this->_template_args['attendees'][ $att_nmbr ]['lname'] = $attendee->lname();
2466
-                $this->_template_args['attendees'][ $att_nmbr ]['email'] = $attendee->email();
2467
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2468
-                $this->_template_args['attendees'][ $att_nmbr ]['address'] = implode(
2463
+                $this->_template_args['attendees'][$att_nmbr]['STS_ID'] = $registration->status_ID();
2464
+                $this->_template_args['attendees'][$att_nmbr]['fname'] = $attendee->fname();
2465
+                $this->_template_args['attendees'][$att_nmbr]['lname'] = $attendee->lname();
2466
+                $this->_template_args['attendees'][$att_nmbr]['email'] = $attendee->email();
2467
+                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2468
+                $this->_template_args['attendees'][$att_nmbr]['address'] = implode(
2469 2469
                     ', ',
2470 2470
                     $attendee->full_address_as_array()
2471 2471
                 );
2472
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link'] = self::add_query_args_and_nonce(
2472
+                $this->_template_args['attendees'][$att_nmbr]['att_link'] = self::add_query_args_and_nonce(
2473 2473
                     array(
2474 2474
                         'action' => 'edit_attendee',
2475 2475
                         'post'   => $attendee->ID(),
2476 2476
                     ),
2477 2477
                     REG_ADMIN_URL
2478 2478
                 );
2479
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name'] = $registration->event_obj() instanceof EE_Event
2479
+                $this->_template_args['attendees'][$att_nmbr]['event_name'] = $registration->event_obj() instanceof EE_Event
2480 2480
                     ? $registration->event_obj()->name()
2481 2481
                     : '';
2482 2482
                 $att_nmbr++;
2483 2483
             }
2484 2484
             $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2485 2485
         }
2486
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2486
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_attendees.template.php';
2487 2487
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2488 2488
     }
2489 2489
 
@@ -2510,11 +2510,11 @@  discard block
 block discarded – undo
2510 2510
         // now let's determine if this is not the primary registration.  If it isn't then we set the
2511 2511
         // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2512 2512
         // primary registration object (that way we know if we need to show create button or not)
2513
-        if (! $this->_registration->is_primary_registrant()) {
2513
+        if ( ! $this->_registration->is_primary_registrant()) {
2514 2514
             $primary_registration = $this->_registration->get_primary_registration();
2515 2515
             $primary_attendee = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2516 2516
                 : null;
2517
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2517
+            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2518 2518
                 // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2519 2519
                 // custom attendee object so let's not worry about the primary reg.
2520 2520
                 $primary_registration = null;
@@ -2548,7 +2548,7 @@  discard block
 block discarded – undo
2548 2548
             ) : '';
2549 2549
         $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2550 2550
         $this->_template_args['att_check'] = $att_check;
2551
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2551
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_side_meta_box_registrant.template.php';
2552 2552
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2553 2553
     }
2554 2554
 
@@ -2586,7 +2586,7 @@  discard block
 block discarded – undo
2586 2586
         $success = 0;
2587 2587
         $overwrite_msgs = false;
2588 2588
         // Checkboxes
2589
-        if (! is_array($this->_req_data['_REG_ID'])) {
2589
+        if ( ! is_array($this->_req_data['_REG_ID'])) {
2590 2590
             $this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2591 2591
         }
2592 2592
         $reg_count = count($this->_req_data['_REG_ID']);
@@ -2595,7 +2595,7 @@  discard block
 block discarded – undo
2595 2595
             /** @var EE_Registration $REG */
2596 2596
             $REG = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2597 2597
             $payments = $REG->registration_payments();
2598
-            if (! empty($payments)) {
2598
+            if ( ! empty($payments)) {
2599 2599
                 $name = $REG->attendee() instanceof EE_Attendee
2600 2600
                     ? $REG->attendee()->full_name()
2601 2601
                     : esc_html__('Unknown Attendee', 'event_espresso');
@@ -2657,17 +2657,17 @@  discard block
 block discarded – undo
2657 2657
         $REG_MDL = $this->getRegistrationModel();
2658 2658
         $success = 1;
2659 2659
         // Checkboxes
2660
-        if (! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2660
+        if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2661 2661
             // if array has more than one element than success message should be plural
2662 2662
             $success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2663 2663
             // cycle thru checkboxes
2664 2664
             foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2665 2665
                 $REG = $REG_MDL->get_one_by_ID($REG_ID);
2666
-                if (! $REG instanceof EE_Registration) {
2666
+                if ( ! $REG instanceof EE_Registration) {
2667 2667
                     continue;
2668 2668
                 }
2669 2669
                 $deleted = $this->_delete_registration($REG);
2670
-                if (! $deleted) {
2670
+                if ( ! $deleted) {
2671 2671
                     $success = 0;
2672 2672
                 }
2673 2673
             }
@@ -2677,7 +2677,7 @@  discard block
 block discarded – undo
2677 2677
             /** @var EE_Registration $REG */
2678 2678
             $REG = $REG_MDL->get_one_by_ID($REG_ID);
2679 2679
             $deleted = $this->_delete_registration($REG);
2680
-            if (! $deleted) {
2680
+            if ( ! $deleted) {
2681 2681
                 $success = 0;
2682 2682
             }
2683 2683
         }
@@ -2712,7 +2712,7 @@  discard block
 block discarded – undo
2712 2712
         // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2713 2713
         // registrations on the transaction that are NOT trashed.
2714 2714
         $TXN = $REG->get_first_related('Transaction');
2715
-        if (! $TXN instanceof EE_Transaction) {
2715
+        if ( ! $TXN instanceof EE_Transaction) {
2716 2716
             EE_Error::add_error(
2717 2717
                 sprintf(
2718 2718
                     esc_html__(
@@ -2730,11 +2730,11 @@  discard block
 block discarded – undo
2730 2730
         $REGS = $TXN->get_many_related('Registration');
2731 2731
         $all_trashed = true;
2732 2732
         foreach ($REGS as $registration) {
2733
-            if (! $registration->get('REG_deleted')) {
2733
+            if ( ! $registration->get('REG_deleted')) {
2734 2734
                 $all_trashed = false;
2735 2735
             }
2736 2736
         }
2737
-        if (! $all_trashed) {
2737
+        if ( ! $all_trashed) {
2738 2738
             EE_Error::add_error(
2739 2739
                 esc_html__(
2740 2740
                     'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
@@ -2797,7 +2797,7 @@  discard block
 block discarded – undo
2797 2797
      */
2798 2798
     public function new_registration()
2799 2799
     {
2800
-        if (! $this->_set_reg_event()) {
2800
+        if ( ! $this->_set_reg_event()) {
2801 2801
             throw new EE_Error(
2802 2802
                 esc_html__(
2803 2803
                     'Unable to continue with registering because there is no Event ID in the request',
@@ -2807,8 +2807,8 @@  discard block
 block discarded – undo
2807 2807
         }
2808 2808
         EE_Registry::instance()->REQ->set_espresso_page(true);
2809 2809
         // gotta start with a clean slate if we're not coming here via ajax
2810
-        if (! defined('DOING_AJAX')
2811
-            && (! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2810
+        if ( ! defined('DOING_AJAX')
2811
+            && ( ! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2812 2812
         ) {
2813 2813
             EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2814 2814
         }
@@ -2841,7 +2841,7 @@  discard block
 block discarded – undo
2841 2841
         }
2842 2842
         // grab header
2843 2843
         $template_path =
2844
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2844
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee.template.php';
2845 2845
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2846 2846
             $template_path,
2847 2847
             $this->_template_args,
@@ -2882,7 +2882,7 @@  discard block
 block discarded – undo
2882 2882
                 '</b>'
2883 2883
             );
2884 2884
             return '
2885
-	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2885
+	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg.'</p></div>
2886 2886
 	<script >
2887 2887
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
2888 2888
 		// after just adding a new registration... we gotta try to put a stop to that !!!
@@ -2951,7 +2951,7 @@  discard block
 block discarded – undo
2951 2951
         // we come back to the process_registration_step route.
2952 2952
         $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2953 2953
         return EEH_Template::display_template(
2954
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2954
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee_step_content.template.php',
2955 2955
             $template_args,
2956 2956
             true
2957 2957
         );
@@ -2973,8 +2973,8 @@  discard block
 block discarded – undo
2973 2973
         if (is_object($this->_reg_event)) {
2974 2974
             return true;
2975 2975
         }
2976
-        $EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2977
-        if (! $EVT_ID) {
2976
+        $EVT_ID = ( ! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2977
+        if ( ! $EVT_ID) {
2978 2978
             return false;
2979 2979
         }
2980 2980
         $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
@@ -3006,8 +3006,8 @@  discard block
 block discarded – undo
3006 3006
         $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3007 3007
         // if doing ajax then we need to verify the nonce
3008 3008
         if (defined('DOING_AJAX')) {
3009
-            $nonce = isset($this->_req_data[ $this->_req_nonce ])
3010
-                ? sanitize_text_field($this->_req_data[ $this->_req_nonce ]) : '';
3009
+            $nonce = isset($this->_req_data[$this->_req_nonce])
3010
+                ? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
3011 3011
             $this->_verify_nonce($nonce, $this->_req_nonce);
3012 3012
         }
3013 3013
         switch ($step) {
@@ -3043,7 +3043,7 @@  discard block
 block discarded – undo
3043 3043
                 }
3044 3044
                 break;
3045 3045
             case 'questions':
3046
-                if (! isset(
3046
+                if ( ! isset(
3047 3047
                     $this->_req_data['txn_reg_status_change'],
3048 3048
                     $this->_req_data['txn_reg_status_change']['send_notifications']
3049 3049
                 )
@@ -3058,7 +3058,7 @@  discard block
 block discarded – undo
3058 3058
                         $grand_total->save_this_and_descendants_to_txn();
3059 3059
                     }
3060 3060
                 }
3061
-                if (! $transaction instanceof EE_Transaction) {
3061
+                if ( ! $transaction instanceof EE_Transaction) {
3062 3062
                     $query_args = array(
3063 3063
                         'action'                  => 'new_registration',
3064 3064
                         'processing_registration' => 2,
@@ -3080,7 +3080,7 @@  discard block
 block discarded – undo
3080 3080
                     return;
3081 3081
                 }
3082 3082
                 // maybe update status, and make sure to save transaction if not done already
3083
-                if (! $transaction->update_status_based_on_total_paid()) {
3083
+                if ( ! $transaction->update_status_based_on_total_paid()) {
3084 3084
                     $transaction->save();
3085 3085
                 }
3086 3086
                 EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
@@ -3166,7 +3166,7 @@  discard block
 block discarded – undo
3166 3166
     public function get_attendees($per_page, $count = false, $trash = false)
3167 3167
     {
3168 3168
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3169
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3169
+        require_once(REG_ADMIN.'EE_Attendee_Contact_List_Table.class.php');
3170 3170
         $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3171 3171
         switch ($this->_req_data['orderby']) {
3172 3172
             case 'ATT_ID':
@@ -3204,8 +3204,8 @@  discard block
 block discarded – undo
3204 3204
             ? $this->_req_data['perpage']
3205 3205
             : $per_page;
3206 3206
         $_where = array();
3207
-        if (! empty($this->_req_data['s'])) {
3208
-            $sstr = '%' . $this->_req_data['s'] . '%';
3207
+        if ( ! empty($this->_req_data['s'])) {
3208
+            $sstr = '%'.$this->_req_data['s'].'%';
3209 3209
             $_where['OR'] = array(
3210 3210
                 'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3211 3211
                 'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
@@ -3232,7 +3232,7 @@  discard block
 block discarded – undo
3232 3232
             'extra_selects' => array('Registration_Count' => array('Registration.REG_ID', 'count', '%d')),
3233 3233
             'limit'         => $limit,
3234 3234
         );
3235
-        if (! $count) {
3235
+        if ( ! $count) {
3236 3236
             $query_args['order_by'] = array($orderby => $sort);
3237 3237
         }
3238 3238
         if ($trash) {
@@ -3280,7 +3280,7 @@  discard block
 block discarded – undo
3280 3280
      */
3281 3281
     public function _registrations_report_base($method_name_for_getting_query_params)
3282 3282
     {
3283
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3283
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3284 3284
             wp_redirect(
3285 3285
                 EE_Admin_Page::add_query_args_and_nonce(
3286 3286
                     array(
@@ -3311,8 +3311,8 @@  discard block
 block discarded – undo
3311 3311
                 'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3312 3312
             );
3313 3313
             $this->_req_data = array_merge($this->_req_data, $new_request_args);
3314
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3315
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3314
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3315
+                require_once(EE_CLASSES.'EE_Export.class.php');
3316 3316
                 $EE_Export = EE_Export::instance($this->_req_data);
3317 3317
                 $EE_Export->export();
3318 3318
             }
@@ -3333,8 +3333,8 @@  discard block
 block discarded – undo
3333 3333
 
3334 3334
     public function _contact_list_export()
3335 3335
     {
3336
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3337
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3336
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3337
+            require_once(EE_CLASSES.'EE_Export.class.php');
3338 3338
             $EE_Export = EE_Export::instance($this->_req_data);
3339 3339
             $EE_Export->export_attendees();
3340 3340
         }
@@ -3343,7 +3343,7 @@  discard block
 block discarded – undo
3343 3343
 
3344 3344
     public function _contact_list_report()
3345 3345
     {
3346
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3346
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3347 3347
             wp_redirect(
3348 3348
                 EE_Admin_Page::add_query_args_and_nonce(
3349 3349
                     array(
@@ -3355,8 +3355,8 @@  discard block
 block discarded – undo
3355 3355
                 )
3356 3356
             );
3357 3357
         } else {
3358
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3359
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3358
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3359
+                require_once(EE_CLASSES.'EE_Export.class.php');
3360 3360
                 $EE_Export = EE_Export::instance($this->_req_data);
3361 3361
                 $EE_Export->report_attendees();
3362 3362
             }
@@ -3444,7 +3444,7 @@  discard block
 block discarded – undo
3444 3444
             $updated_fields = array(
3445 3445
                 'ATT_fname'     => $this->_req_data['ATT_fname'],
3446 3446
                 'ATT_lname'     => $this->_req_data['ATT_lname'],
3447
-                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3447
+                'ATT_full_name' => $this->_req_data['ATT_fname'].' '.$this->_req_data['ATT_lname'],
3448 3448
                 'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3449 3449
                 'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3450 3450
                 'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
@@ -3522,16 +3522,16 @@  discard block
 block discarded – undo
3522 3522
         $this->verify_cpt_object();
3523 3523
         remove_meta_box(
3524 3524
             'postexcerpt',
3525
-            $this->_cpt_routes[ $this->_req_action ],
3525
+            $this->_cpt_routes[$this->_req_action],
3526 3526
             'normal'
3527 3527
         );
3528
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal', 'core');
3528
+        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal', 'core');
3529 3529
         if (post_type_supports('espresso_attendees', 'excerpt')) {
3530 3530
             add_meta_box(
3531 3531
                 'postexcerpt',
3532 3532
                 esc_html__('Short Biography', 'event_espresso'),
3533 3533
                 'post_excerpt_meta_box',
3534
-                $this->_cpt_routes[ $this->_req_action ],
3534
+                $this->_cpt_routes[$this->_req_action],
3535 3535
                 'normal'
3536 3536
             );
3537 3537
         }
@@ -3540,7 +3540,7 @@  discard block
 block discarded – undo
3540 3540
                 'commentsdiv',
3541 3541
                 esc_html__('Notes on the Contact', 'event_espresso'),
3542 3542
                 'post_comment_meta_box',
3543
-                $this->_cpt_routes[ $this->_req_action ],
3543
+                $this->_cpt_routes[$this->_req_action],
3544 3544
                 'normal',
3545 3545
                 'core'
3546 3546
             );
@@ -3549,7 +3549,7 @@  discard block
 block discarded – undo
3549 3549
             'attendee_contact_info',
3550 3550
             esc_html__('Contact Info', 'event_espresso'),
3551 3551
             array($this, 'attendee_contact_info'),
3552
-            $this->_cpt_routes[ $this->_req_action ],
3552
+            $this->_cpt_routes[$this->_req_action],
3553 3553
             'side',
3554 3554
             'core'
3555 3555
         );
@@ -3557,7 +3557,7 @@  discard block
 block discarded – undo
3557 3557
             'attendee_details_address',
3558 3558
             esc_html__('Address Details', 'event_espresso'),
3559 3559
             array($this, 'attendee_address_details'),
3560
-            $this->_cpt_routes[ $this->_req_action ],
3560
+            $this->_cpt_routes[$this->_req_action],
3561 3561
             'normal',
3562 3562
             'core'
3563 3563
         );
@@ -3565,7 +3565,7 @@  discard block
 block discarded – undo
3565 3565
             'attendee_registrations',
3566 3566
             esc_html__('Registrations for this Contact', 'event_espresso'),
3567 3567
             array($this, 'attendee_registrations_meta_box'),
3568
-            $this->_cpt_routes[ $this->_req_action ],
3568
+            $this->_cpt_routes[$this->_req_action],
3569 3569
             'normal',
3570 3570
             'high'
3571 3571
         );
@@ -3666,7 +3666,7 @@  discard block
 block discarded – undo
3666 3666
             )
3667 3667
         );
3668 3668
         $template =
3669
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3669
+            REG_TEMPLATE_PATH.'attendee_address_details_metabox_content.template.php';
3670 3670
         EEH_Template::display_template($template, $this->_template_args);
3671 3671
     }
3672 3672
 
@@ -3689,7 +3689,7 @@  discard block
 block discarded – undo
3689 3689
         $this->_template_args['attendee'] = $this->_cpt_model_obj;
3690 3690
         $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3691 3691
         $template =
3692
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3692
+            REG_TEMPLATE_PATH.'attendee_registrations_main_meta_box.template.php';
3693 3693
         EEH_Template::display_template($template, $this->_template_args);
3694 3694
     }
3695 3695
 
@@ -3704,7 +3704,7 @@  discard block
 block discarded – undo
3704 3704
     public function after_title_form_fields($post)
3705 3705
     {
3706 3706
         if ($post->post_type === 'espresso_attendees') {
3707
-            $template = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3707
+            $template = REG_TEMPLATE_PATH.'attendee_details_after_title_form_fields.template.php';
3708 3708
             $template_args['attendee'] = $this->_cpt_model_obj;
3709 3709
             EEH_Template::display_template($template, $template_args);
3710 3710
         }
@@ -3728,14 +3728,14 @@  discard block
 block discarded – undo
3728 3728
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3729 3729
         $success = 1;
3730 3730
         // Checkboxes
3731
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3731
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3732 3732
             // if array has more than one element than success message should be plural
3733 3733
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3734 3734
             // cycle thru checkboxes
3735 3735
             foreach ($this->_req_data['checkbox'] as $ATT_ID) {
3736 3736
                 $updated = $trash ? $this->getAttendeeModel()->update_by_ID(array('status' => 'trash'), $ATT_ID)
3737 3737
                     : $this->getAttendeeModel()->update_by_ID(array('status' => 'publish'), $ATT_ID);
3738
-                if (! $updated) {
3738
+                if ( ! $updated) {
3739 3739
                     $success = 0;
3740 3740
                 }
3741 3741
             }
@@ -3746,7 +3746,7 @@  discard block
 block discarded – undo
3746 3746
             $att = $this->getAttendeeModel()->get_one_by_ID($ATT_ID);
3747 3747
             $updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3748 3748
             $updated = $att->save() && $updated;
3749
-            if (! $updated) {
3749
+            if ( ! $updated) {
3750 3750
                 $success = 0;
3751 3751
             }
3752 3752
         }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_CPT.core.php 1 patch
Indentation   +1489 added lines, -1489 removed lines patch added patch discarded remove patch
@@ -27,474 +27,474 @@  discard block
 block discarded – undo
27 27
 {
28 28
 
29 29
 
30
-    /**
31
-     * This gets set in _setup_cpt
32
-     * It will contain the object for the custom post type.
33
-     *
34
-     * @var EE_CPT_Base
35
-     */
36
-    protected $_cpt_object;
37
-
38
-
39
-    /**
40
-     * a boolean flag to set whether the current route is a cpt route or not.
41
-     *
42
-     * @var bool
43
-     */
44
-    protected $_cpt_route = false;
45
-
46
-
47
-    /**
48
-     * This property allows cpt classes to define multiple routes as cpt routes.
49
-     * //in this array we define what the custom post type for this route is.
50
-     * array(
51
-     * 'route_name' => 'custom_post_type_slug'
52
-     * )
53
-     *
54
-     * @var array
55
-     */
56
-    protected $_cpt_routes = array();
57
-
58
-
59
-    /**
60
-     * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
61
-     * in this format:
62
-     * array(
63
-     * 'post_type_slug' => 'edit_route'
64
-     * )
65
-     *
66
-     * @var array
67
-     */
68
-    protected $_cpt_edit_routes = array();
69
-
70
-
71
-    /**
72
-     * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
73
-     * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
74
-     * _cpt_model_names property should be in the following format: array(
75
-     * 'route_defined_by_action_param' => 'Model_Name')
76
-     *
77
-     * @var array $_cpt_model_names
78
-     */
79
-    protected $_cpt_model_names = array();
80
-
81
-
82
-    /**
83
-     * @var EE_CPT_Base
84
-     */
85
-    protected $_cpt_model_obj = false;
86
-
87
-
88
-    /**
89
-     * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
90
-     * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
91
-     * the _register_autosave_containers() method so that we don't override any other containers already registered.
92
-     * Registration of containers should be done before load_page_dependencies() is run.
93
-     *
94
-     * @var array()
95
-     */
96
-    protected $_autosave_containers = array();
97
-    protected $_autosave_fields = array();
98
-
99
-    /**
100
-     * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
101
-     * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
102
-     *
103
-     * @var array
104
-     */
105
-    protected $_pagenow_map;
106
-
107
-
108
-    /**
109
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
110
-     * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
111
-     * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
112
-     * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
113
-     * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
114
-     *
115
-     * @access protected
116
-     * @abstract
117
-     * @param  string      $post_id The ID of the cpt that was saved (so you can link relationally)
118
-     * @param  EE_CPT_Base $post    The post object of the cpt that was saved.
119
-     * @return void
120
-     */
121
-    abstract protected function _insert_update_cpt_item($post_id, $post);
122
-
123
-
124
-    /**
125
-     * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
126
-     *
127
-     * @abstract
128
-     * @access public
129
-     * @param  string $post_id The ID of the cpt that was trashed
130
-     * @return void
131
-     */
132
-    abstract public function trash_cpt_item($post_id);
133
-
134
-
135
-    /**
136
-     * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
137
-     *
138
-     * @param  string $post_id theID of the cpt that was untrashed
139
-     * @return void
140
-     */
141
-    abstract public function restore_cpt_item($post_id);
142
-
143
-
144
-    /**
145
-     * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
146
-     * from the db
147
-     *
148
-     * @param  string $post_id the ID of the cpt that was deleted
149
-     * @return void
150
-     */
151
-    abstract public function delete_cpt_item($post_id);
152
-
153
-
154
-    /**
155
-     * Just utilizing the method EE_Admin exposes for doing things before page setup.
156
-     *
157
-     * @access protected
158
-     * @return void
159
-     */
160
-    protected function _before_page_setup()
161
-    {
162
-        $page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug;
163
-        $this->_cpt_routes = array_merge(
164
-            array(
165
-                'create_new' => $this->page_slug,
166
-                'edit'       => $this->page_slug,
167
-                'trash'      => $this->page_slug,
168
-            ),
169
-            $this->_cpt_routes
170
-        );
171
-        // let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
172
-        $this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[ $this->_req_data['action'] ])
173
-            ? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ])
174
-            : get_post_type_object($page);
175
-        // tweak pagenow for page loading.
176
-        if (! $this->_pagenow_map) {
177
-            $this->_pagenow_map = array(
178
-                'create_new' => 'post-new.php',
179
-                'edit'       => 'post.php',
180
-                'trash'      => 'post.php',
181
-            );
182
-        }
183
-        add_action('current_screen', array($this, 'modify_pagenow'));
184
-        // TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
185
-        // get current page from autosave
186
-        $current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'])
187
-            ? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']
188
-            : null;
189
-        $this->_current_page = isset($this->_req_data['current_page'])
190
-            ? $this->_req_data['current_page']
191
-            : $current_page;
192
-        // autosave... make sure its only for the correct page
193
-        // if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) {
194
-        // setup autosave ajax hook
195
-        // add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented
196
-        // }
197
-    }
198
-
199
-
200
-    /**
201
-     * Simply ensure that we simulate the correct post route for cpt screens
202
-     *
203
-     * @param WP_Screen $current_screen
204
-     * @return void
205
-     */
206
-    public function modify_pagenow($current_screen)
207
-    {
208
-        global $pagenow, $hook_suffix;
209
-        // possibly reset pagenow.
210
-        if (! empty($this->_req_data['page'])
211
-            && $this->_req_data['page'] == $this->page_slug
212
-            && ! empty($this->_req_data['action'])
213
-            && isset($this->_pagenow_map[ $this->_req_data['action'] ])
214
-        ) {
215
-            $pagenow = $this->_pagenow_map[ $this->_req_data['action'] ];
216
-            $hook_suffix = $pagenow;
217
-        }
218
-    }
219
-
220
-
221
-    /**
222
-     * This method is used to register additional autosave containers to the _autosave_containers property.
223
-     *
224
-     * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
225
-     *       automatically register the id for the post metabox as a container.
226
-     * @param  array $ids an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
227
-     *                    you would send along the id of a metabox container.
228
-     * @return void
229
-     */
230
-    protected function _register_autosave_containers($ids)
231
-    {
232
-        $this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
233
-    }
234
-
235
-
236
-    /**
237
-     * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
238
-     * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
239
-     */
240
-    protected function _set_autosave_containers()
241
-    {
242
-        global $wp_meta_boxes;
243
-        $containers = array();
244
-        if (empty($wp_meta_boxes)) {
245
-            return;
246
-        }
247
-        $current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array();
248
-        foreach ($current_metaboxes as $box_context) {
249
-            foreach ($box_context as $box_details) {
250
-                foreach ($box_details as $box) {
251
-                    if (is_array($box) && is_array($box['callback'])
252
-                        && (
253
-                            $box['callback'][0] instanceof EE_Admin_Page
254
-                            || $box['callback'][0] instanceof EE_Admin_Hooks
255
-                        )
256
-                    ) {
257
-                        $containers[] = $box['id'];
258
-                    }
259
-                }
260
-            }
261
-        }
262
-        $this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
263
-        // add hidden inputs container
264
-        $this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
265
-    }
266
-
267
-
268
-    protected function _load_autosave_scripts_styles()
269
-    {
270
-        /*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
30
+	/**
31
+	 * This gets set in _setup_cpt
32
+	 * It will contain the object for the custom post type.
33
+	 *
34
+	 * @var EE_CPT_Base
35
+	 */
36
+	protected $_cpt_object;
37
+
38
+
39
+	/**
40
+	 * a boolean flag to set whether the current route is a cpt route or not.
41
+	 *
42
+	 * @var bool
43
+	 */
44
+	protected $_cpt_route = false;
45
+
46
+
47
+	/**
48
+	 * This property allows cpt classes to define multiple routes as cpt routes.
49
+	 * //in this array we define what the custom post type for this route is.
50
+	 * array(
51
+	 * 'route_name' => 'custom_post_type_slug'
52
+	 * )
53
+	 *
54
+	 * @var array
55
+	 */
56
+	protected $_cpt_routes = array();
57
+
58
+
59
+	/**
60
+	 * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
61
+	 * in this format:
62
+	 * array(
63
+	 * 'post_type_slug' => 'edit_route'
64
+	 * )
65
+	 *
66
+	 * @var array
67
+	 */
68
+	protected $_cpt_edit_routes = array();
69
+
70
+
71
+	/**
72
+	 * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
73
+	 * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
74
+	 * _cpt_model_names property should be in the following format: array(
75
+	 * 'route_defined_by_action_param' => 'Model_Name')
76
+	 *
77
+	 * @var array $_cpt_model_names
78
+	 */
79
+	protected $_cpt_model_names = array();
80
+
81
+
82
+	/**
83
+	 * @var EE_CPT_Base
84
+	 */
85
+	protected $_cpt_model_obj = false;
86
+
87
+
88
+	/**
89
+	 * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
90
+	 * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
91
+	 * the _register_autosave_containers() method so that we don't override any other containers already registered.
92
+	 * Registration of containers should be done before load_page_dependencies() is run.
93
+	 *
94
+	 * @var array()
95
+	 */
96
+	protected $_autosave_containers = array();
97
+	protected $_autosave_fields = array();
98
+
99
+	/**
100
+	 * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
101
+	 * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
102
+	 *
103
+	 * @var array
104
+	 */
105
+	protected $_pagenow_map;
106
+
107
+
108
+	/**
109
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
110
+	 * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
111
+	 * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
112
+	 * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
113
+	 * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
114
+	 *
115
+	 * @access protected
116
+	 * @abstract
117
+	 * @param  string      $post_id The ID of the cpt that was saved (so you can link relationally)
118
+	 * @param  EE_CPT_Base $post    The post object of the cpt that was saved.
119
+	 * @return void
120
+	 */
121
+	abstract protected function _insert_update_cpt_item($post_id, $post);
122
+
123
+
124
+	/**
125
+	 * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
126
+	 *
127
+	 * @abstract
128
+	 * @access public
129
+	 * @param  string $post_id The ID of the cpt that was trashed
130
+	 * @return void
131
+	 */
132
+	abstract public function trash_cpt_item($post_id);
133
+
134
+
135
+	/**
136
+	 * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
137
+	 *
138
+	 * @param  string $post_id theID of the cpt that was untrashed
139
+	 * @return void
140
+	 */
141
+	abstract public function restore_cpt_item($post_id);
142
+
143
+
144
+	/**
145
+	 * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
146
+	 * from the db
147
+	 *
148
+	 * @param  string $post_id the ID of the cpt that was deleted
149
+	 * @return void
150
+	 */
151
+	abstract public function delete_cpt_item($post_id);
152
+
153
+
154
+	/**
155
+	 * Just utilizing the method EE_Admin exposes for doing things before page setup.
156
+	 *
157
+	 * @access protected
158
+	 * @return void
159
+	 */
160
+	protected function _before_page_setup()
161
+	{
162
+		$page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug;
163
+		$this->_cpt_routes = array_merge(
164
+			array(
165
+				'create_new' => $this->page_slug,
166
+				'edit'       => $this->page_slug,
167
+				'trash'      => $this->page_slug,
168
+			),
169
+			$this->_cpt_routes
170
+		);
171
+		// let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
172
+		$this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[ $this->_req_data['action'] ])
173
+			? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ])
174
+			: get_post_type_object($page);
175
+		// tweak pagenow for page loading.
176
+		if (! $this->_pagenow_map) {
177
+			$this->_pagenow_map = array(
178
+				'create_new' => 'post-new.php',
179
+				'edit'       => 'post.php',
180
+				'trash'      => 'post.php',
181
+			);
182
+		}
183
+		add_action('current_screen', array($this, 'modify_pagenow'));
184
+		// TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
185
+		// get current page from autosave
186
+		$current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'])
187
+			? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']
188
+			: null;
189
+		$this->_current_page = isset($this->_req_data['current_page'])
190
+			? $this->_req_data['current_page']
191
+			: $current_page;
192
+		// autosave... make sure its only for the correct page
193
+		// if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) {
194
+		// setup autosave ajax hook
195
+		// add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented
196
+		// }
197
+	}
198
+
199
+
200
+	/**
201
+	 * Simply ensure that we simulate the correct post route for cpt screens
202
+	 *
203
+	 * @param WP_Screen $current_screen
204
+	 * @return void
205
+	 */
206
+	public function modify_pagenow($current_screen)
207
+	{
208
+		global $pagenow, $hook_suffix;
209
+		// possibly reset pagenow.
210
+		if (! empty($this->_req_data['page'])
211
+			&& $this->_req_data['page'] == $this->page_slug
212
+			&& ! empty($this->_req_data['action'])
213
+			&& isset($this->_pagenow_map[ $this->_req_data['action'] ])
214
+		) {
215
+			$pagenow = $this->_pagenow_map[ $this->_req_data['action'] ];
216
+			$hook_suffix = $pagenow;
217
+		}
218
+	}
219
+
220
+
221
+	/**
222
+	 * This method is used to register additional autosave containers to the _autosave_containers property.
223
+	 *
224
+	 * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
225
+	 *       automatically register the id for the post metabox as a container.
226
+	 * @param  array $ids an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
227
+	 *                    you would send along the id of a metabox container.
228
+	 * @return void
229
+	 */
230
+	protected function _register_autosave_containers($ids)
231
+	{
232
+		$this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
233
+	}
234
+
235
+
236
+	/**
237
+	 * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
238
+	 * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
239
+	 */
240
+	protected function _set_autosave_containers()
241
+	{
242
+		global $wp_meta_boxes;
243
+		$containers = array();
244
+		if (empty($wp_meta_boxes)) {
245
+			return;
246
+		}
247
+		$current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array();
248
+		foreach ($current_metaboxes as $box_context) {
249
+			foreach ($box_context as $box_details) {
250
+				foreach ($box_details as $box) {
251
+					if (is_array($box) && is_array($box['callback'])
252
+						&& (
253
+							$box['callback'][0] instanceof EE_Admin_Page
254
+							|| $box['callback'][0] instanceof EE_Admin_Hooks
255
+						)
256
+					) {
257
+						$containers[] = $box['id'];
258
+					}
259
+				}
260
+			}
261
+		}
262
+		$this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
263
+		// add hidden inputs container
264
+		$this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
265
+	}
266
+
267
+
268
+	protected function _load_autosave_scripts_styles()
269
+	{
270
+		/*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
271 271
         wp_enqueue_script('cpt-autosave');/**/ // todo re-enable when we start doing autosave again in 4.2
272 272
 
273
-        // filter _autosave_containers
274
-        $containers = apply_filters(
275
-            'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
276
-            $this->_autosave_containers,
277
-            $this
278
-        );
279
-        $containers = apply_filters(
280
-            'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
281
-            $containers,
282
-            $this
283
-        );
284
-
285
-        wp_localize_script(
286
-            'event_editor_js',
287
-            'EE_AUTOSAVE_IDS',
288
-            $containers
289
-        ); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
290
-
291
-        $unsaved_data_msg = array(
292
-            'eventmsg'     => sprintf(
293
-                __(
294
-                    "The changes you made to this %s will be lost if you navigate away from this page.",
295
-                    'event_espresso'
296
-                ),
297
-                $this->_cpt_object->labels->singular_name
298
-            ),
299
-            'inputChanged' => 0,
300
-        );
301
-        wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
302
-    }
303
-
304
-
305
-    public function load_page_dependencies()
306
-    {
307
-        try {
308
-            $this->_load_page_dependencies();
309
-        } catch (EE_Error $e) {
310
-            $e->get_error();
311
-        }
312
-    }
313
-
314
-
315
-    /**
316
-     * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
317
-     *
318
-     * @access protected
319
-     * @return void
320
-     */
321
-    protected function _load_page_dependencies()
322
-    {
323
-        // we only add stuff if this is a cpt_route!
324
-        if (! $this->_cpt_route) {
325
-            parent::_load_page_dependencies();
326
-            return;
327
-        }
328
-        // now let's do some automatic filters into the wp_system
329
-        // and we'll check to make sure the CHILD class
330
-        // automatically has the required methods in place.
331
-        // the following filters are for setting all the redirects
332
-        // on DEFAULT WP custom post type actions
333
-        // let's add a hidden input to the post-edit form
334
-        // so we know when we have to trigger our custom redirects!
335
-        // Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
336
-        add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input'));
337
-        // inject our Admin page nav tabs...
338
-        // let's make sure the nav tabs are set if they aren't already
339
-        // if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
340
-        add_action('post_edit_form_tag', array($this, 'inject_nav_tabs'));
341
-        // modify the post_updated messages array
342
-        add_action('post_updated_messages', array($this, 'post_update_messages'), 10);
343
-        // add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
344
-        // cpts use the same format for shortlinks as posts!
345
-        add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
346
-        // This basically allows us to change the title of the "publish" metabox area
347
-        // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
348
-        if (! empty($this->_labels['publishbox'])) {
349
-            $box_label = is_array($this->_labels['publishbox'])
350
-                         && isset($this->_labels['publishbox'][ $this->_req_action ])
351
-                ? $this->_labels['publishbox'][ $this->_req_action ]
352
-                : $this->_labels['publishbox'];
353
-            add_meta_box(
354
-                'submitdiv',
355
-                $box_label,
356
-                'post_submit_meta_box',
357
-                $this->_cpt_routes[ $this->_req_action ],
358
-                'side',
359
-                'core'
360
-            );
361
-        }
362
-        // let's add page_templates metabox if this cpt added support for it.
363
-        if ($this->_supports_page_templates($this->_cpt_object->name)) {
364
-            add_meta_box(
365
-                'page_templates',
366
-                __('Page Template', 'event_espresso'),
367
-                array($this, 'page_template_meta_box'),
368
-                $this->_cpt_routes[ $this->_req_action ],
369
-                'side',
370
-                'default'
371
-            );
372
-        }
373
-        // this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
374
-        if (method_exists($this, 'extra_permalink_field_buttons')) {
375
-            add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4);
376
-        }
377
-        // add preview button
378
-        add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4);
379
-        // insert our own post_stati dropdown
380
-        add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10);
381
-        // This allows adding additional information to the publish post submitbox on the wp post edit form
382
-        if (method_exists($this, 'extra_misc_actions_publish_box')) {
383
-            add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10);
384
-        }
385
-        // This allows for adding additional stuff after the title field on the wp post edit form.
386
-        // This is also before the wp_editor for post description field.
387
-        if (method_exists($this, 'edit_form_after_title')) {
388
-            add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10);
389
-        }
390
-        /**
391
-         * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
392
-         */
393
-        add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3);
394
-        parent::_load_page_dependencies();
395
-        // notice we are ALSO going to load the pagenow hook set for this route
396
-        // (see _before_page_setup for the reset of the pagenow global ).
397
-        // This is for any plugins that are doing things properly
398
-        // and hooking into the load page hook for core wp cpt routes.
399
-        global $pagenow;
400
-        add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20);
401
-        do_action('load-' . $pagenow);
402
-        add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
403
-        // we route REALLY early.
404
-        try {
405
-            $this->_route_admin_request();
406
-        } catch (EE_Error $e) {
407
-            $e->get_error();
408
-        }
409
-    }
410
-
411
-
412
-    /**
413
-     * Since we don't want users going to default core wp routes, this will check any wp urls run through the
414
-     * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
415
-     * route instead.
416
-     *
417
-     * @param string $good_protocol_url The escaped url.
418
-     * @param string $original_url      The original url.
419
-     * @param string $_context          The context sent to the esc_url method.
420
-     * @return string possibly a new url for our route.
421
-     */
422
-    public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
423
-    {
424
-        $routes_to_match = array(
425
-            0 => array(
426
-                'edit.php?post_type=espresso_attendees',
427
-                'admin.php?page=espresso_registrations&action=contact_list',
428
-            ),
429
-            1 => array(
430
-                'edit.php?post_type=' . $this->_cpt_object->name,
431
-                'admin.php?page=' . $this->_cpt_object->name,
432
-            ),
433
-        );
434
-        foreach ($routes_to_match as $route_matches) {
435
-            if (strpos($good_protocol_url, $route_matches[0]) !== false) {
436
-                return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
437
-            }
438
-        }
439
-        return $good_protocol_url;
440
-    }
441
-
442
-
443
-    /**
444
-     * Determine whether the current cpt supports page templates or not.
445
-     *
446
-     * @since %VER%
447
-     * @param string $cpt_name The cpt slug we're checking on.
448
-     * @return bool True supported, false not.
449
-     * @throws InvalidArgumentException
450
-     * @throws InvalidDataTypeException
451
-     * @throws InvalidInterfaceException
452
-     */
453
-    private function _supports_page_templates($cpt_name)
454
-    {
455
-        /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
456
-        $custom_post_types = $this->loader->getShared(
457
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
458
-        );
459
-        $cpt_args = $custom_post_types->getDefinitions();
460
-        $cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array();
461
-        $cpt_has_support = ! empty($cpt_args['page_templates']);
462
-
463
-        // if the installed version of WP is > 4.7 we do some additional checks.
464
-        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
465
-            $post_templates = wp_get_theme()->get_post_templates();
466
-            // if there are $post_templates for this cpt, then we return false for this method because
467
-            // that means we aren't going to load our page template manager and leave that up to the native
468
-            // cpt template manager.
469
-            $cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
470
-        }
471
-
472
-        return $cpt_has_support;
473
-    }
474
-
475
-
476
-    /**
477
-     * Callback for the page_templates metabox selector.
478
-     *
479
-     * @since %VER%
480
-     * @return void
481
-     */
482
-    public function page_template_meta_box()
483
-    {
484
-        global $post;
485
-        $template = '';
486
-
487
-        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
488
-            $page_template_count = count(get_page_templates());
489
-        } else {
490
-            $page_template_count = count(get_page_templates($post));
491
-        };
492
-
493
-        if ($page_template_count) {
494
-            $page_template = get_post_meta($post->ID, '_wp_page_template', true);
495
-            $template = ! empty($page_template) ? $page_template : '';
496
-        }
497
-        ?>
273
+		// filter _autosave_containers
274
+		$containers = apply_filters(
275
+			'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
276
+			$this->_autosave_containers,
277
+			$this
278
+		);
279
+		$containers = apply_filters(
280
+			'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
281
+			$containers,
282
+			$this
283
+		);
284
+
285
+		wp_localize_script(
286
+			'event_editor_js',
287
+			'EE_AUTOSAVE_IDS',
288
+			$containers
289
+		); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
290
+
291
+		$unsaved_data_msg = array(
292
+			'eventmsg'     => sprintf(
293
+				__(
294
+					"The changes you made to this %s will be lost if you navigate away from this page.",
295
+					'event_espresso'
296
+				),
297
+				$this->_cpt_object->labels->singular_name
298
+			),
299
+			'inputChanged' => 0,
300
+		);
301
+		wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
302
+	}
303
+
304
+
305
+	public function load_page_dependencies()
306
+	{
307
+		try {
308
+			$this->_load_page_dependencies();
309
+		} catch (EE_Error $e) {
310
+			$e->get_error();
311
+		}
312
+	}
313
+
314
+
315
+	/**
316
+	 * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
317
+	 *
318
+	 * @access protected
319
+	 * @return void
320
+	 */
321
+	protected function _load_page_dependencies()
322
+	{
323
+		// we only add stuff if this is a cpt_route!
324
+		if (! $this->_cpt_route) {
325
+			parent::_load_page_dependencies();
326
+			return;
327
+		}
328
+		// now let's do some automatic filters into the wp_system
329
+		// and we'll check to make sure the CHILD class
330
+		// automatically has the required methods in place.
331
+		// the following filters are for setting all the redirects
332
+		// on DEFAULT WP custom post type actions
333
+		// let's add a hidden input to the post-edit form
334
+		// so we know when we have to trigger our custom redirects!
335
+		// Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
336
+		add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input'));
337
+		// inject our Admin page nav tabs...
338
+		// let's make sure the nav tabs are set if they aren't already
339
+		// if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
340
+		add_action('post_edit_form_tag', array($this, 'inject_nav_tabs'));
341
+		// modify the post_updated messages array
342
+		add_action('post_updated_messages', array($this, 'post_update_messages'), 10);
343
+		// add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
344
+		// cpts use the same format for shortlinks as posts!
345
+		add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
346
+		// This basically allows us to change the title of the "publish" metabox area
347
+		// on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
348
+		if (! empty($this->_labels['publishbox'])) {
349
+			$box_label = is_array($this->_labels['publishbox'])
350
+						 && isset($this->_labels['publishbox'][ $this->_req_action ])
351
+				? $this->_labels['publishbox'][ $this->_req_action ]
352
+				: $this->_labels['publishbox'];
353
+			add_meta_box(
354
+				'submitdiv',
355
+				$box_label,
356
+				'post_submit_meta_box',
357
+				$this->_cpt_routes[ $this->_req_action ],
358
+				'side',
359
+				'core'
360
+			);
361
+		}
362
+		// let's add page_templates metabox if this cpt added support for it.
363
+		if ($this->_supports_page_templates($this->_cpt_object->name)) {
364
+			add_meta_box(
365
+				'page_templates',
366
+				__('Page Template', 'event_espresso'),
367
+				array($this, 'page_template_meta_box'),
368
+				$this->_cpt_routes[ $this->_req_action ],
369
+				'side',
370
+				'default'
371
+			);
372
+		}
373
+		// this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
374
+		if (method_exists($this, 'extra_permalink_field_buttons')) {
375
+			add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4);
376
+		}
377
+		// add preview button
378
+		add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4);
379
+		// insert our own post_stati dropdown
380
+		add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10);
381
+		// This allows adding additional information to the publish post submitbox on the wp post edit form
382
+		if (method_exists($this, 'extra_misc_actions_publish_box')) {
383
+			add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10);
384
+		}
385
+		// This allows for adding additional stuff after the title field on the wp post edit form.
386
+		// This is also before the wp_editor for post description field.
387
+		if (method_exists($this, 'edit_form_after_title')) {
388
+			add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10);
389
+		}
390
+		/**
391
+		 * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
392
+		 */
393
+		add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3);
394
+		parent::_load_page_dependencies();
395
+		// notice we are ALSO going to load the pagenow hook set for this route
396
+		// (see _before_page_setup for the reset of the pagenow global ).
397
+		// This is for any plugins that are doing things properly
398
+		// and hooking into the load page hook for core wp cpt routes.
399
+		global $pagenow;
400
+		add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20);
401
+		do_action('load-' . $pagenow);
402
+		add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
403
+		// we route REALLY early.
404
+		try {
405
+			$this->_route_admin_request();
406
+		} catch (EE_Error $e) {
407
+			$e->get_error();
408
+		}
409
+	}
410
+
411
+
412
+	/**
413
+	 * Since we don't want users going to default core wp routes, this will check any wp urls run through the
414
+	 * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
415
+	 * route instead.
416
+	 *
417
+	 * @param string $good_protocol_url The escaped url.
418
+	 * @param string $original_url      The original url.
419
+	 * @param string $_context          The context sent to the esc_url method.
420
+	 * @return string possibly a new url for our route.
421
+	 */
422
+	public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
423
+	{
424
+		$routes_to_match = array(
425
+			0 => array(
426
+				'edit.php?post_type=espresso_attendees',
427
+				'admin.php?page=espresso_registrations&action=contact_list',
428
+			),
429
+			1 => array(
430
+				'edit.php?post_type=' . $this->_cpt_object->name,
431
+				'admin.php?page=' . $this->_cpt_object->name,
432
+			),
433
+		);
434
+		foreach ($routes_to_match as $route_matches) {
435
+			if (strpos($good_protocol_url, $route_matches[0]) !== false) {
436
+				return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
437
+			}
438
+		}
439
+		return $good_protocol_url;
440
+	}
441
+
442
+
443
+	/**
444
+	 * Determine whether the current cpt supports page templates or not.
445
+	 *
446
+	 * @since %VER%
447
+	 * @param string $cpt_name The cpt slug we're checking on.
448
+	 * @return bool True supported, false not.
449
+	 * @throws InvalidArgumentException
450
+	 * @throws InvalidDataTypeException
451
+	 * @throws InvalidInterfaceException
452
+	 */
453
+	private function _supports_page_templates($cpt_name)
454
+	{
455
+		/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
456
+		$custom_post_types = $this->loader->getShared(
457
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
458
+		);
459
+		$cpt_args = $custom_post_types->getDefinitions();
460
+		$cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array();
461
+		$cpt_has_support = ! empty($cpt_args['page_templates']);
462
+
463
+		// if the installed version of WP is > 4.7 we do some additional checks.
464
+		if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
465
+			$post_templates = wp_get_theme()->get_post_templates();
466
+			// if there are $post_templates for this cpt, then we return false for this method because
467
+			// that means we aren't going to load our page template manager and leave that up to the native
468
+			// cpt template manager.
469
+			$cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
470
+		}
471
+
472
+		return $cpt_has_support;
473
+	}
474
+
475
+
476
+	/**
477
+	 * Callback for the page_templates metabox selector.
478
+	 *
479
+	 * @since %VER%
480
+	 * @return void
481
+	 */
482
+	public function page_template_meta_box()
483
+	{
484
+		global $post;
485
+		$template = '';
486
+
487
+		if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
488
+			$page_template_count = count(get_page_templates());
489
+		} else {
490
+			$page_template_count = count(get_page_templates($post));
491
+		};
492
+
493
+		if ($page_template_count) {
494
+			$page_template = get_post_meta($post->ID, '_wp_page_template', true);
495
+			$template = ! empty($page_template) ? $page_template : '';
496
+		}
497
+		?>
498 498
         <p><strong><?php _e('Template', 'event_espresso') ?></strong></p>
499 499
         <label class="screen-reader-text" for="page_template"><?php _e('Page Template', 'event_espresso') ?></label><select
500 500
         name="page_template" id="page_template">
@@ -502,511 +502,511 @@  discard block
 block discarded – undo
502 502
         <?php page_template_dropdown($template); ?>
503 503
     </select>
504 504
         <?php
505
-    }
506
-
507
-
508
-    /**
509
-     * if this post is a draft or scheduled post then we provide a preview button for user to click
510
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
511
-     *
512
-     * @param  string $return    the current html
513
-     * @param  int    $id        the post id for the page
514
-     * @param  string $new_title What the title is
515
-     * @param  string $new_slug  what the slug is
516
-     * @return string            The new html string for the permalink area
517
-     */
518
-    public function preview_button_html($return, $id, $new_title, $new_slug)
519
-    {
520
-        $post = get_post($id);
521
-        if ('publish' !== get_post_status($post)) {
522
-            $return .= '<span_id="view-post-btn"><a target="_blank" href="'
523
-                       . get_preview_post_link($id)
524
-                       . '" class="button button-small">'
525
-                       . __('Preview', 'event_espresso')
526
-                       . '</a></span>'
527
-                       . "\n";
528
-        }
529
-        return $return;
530
-    }
531
-
532
-
533
-    /**
534
-     * add our custom post stati dropdown on the wp post page for this cpt
535
-     *
536
-     * @return void
537
-     */
538
-    public function custom_post_stati_dropdown()
539
-    {
540
-
541
-        $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
542
-        $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
543
-            ? $statuses[ $this->_cpt_model_obj->status() ]
544
-            : '';
545
-        $template_args = array(
546
-            'cur_status'            => $this->_cpt_model_obj->status(),
547
-            'statuses'              => $statuses,
548
-            'cur_status_label'      => $cur_status_label,
549
-            'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label),
550
-        );
551
-        // we'll add a trash post status (WP doesn't add one for some reason)
552
-        if ($this->_cpt_model_obj->status() === 'trash') {
553
-            $template_args['cur_status_label'] = __('Trashed', 'event_espresso');
554
-            $statuses['trash'] = __('Trashed', 'event_espresso');
555
-            $template_args['statuses'] = $statuses;
556
-        }
557
-
558
-        $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
559
-        EEH_Template::display_template($template, $template_args);
560
-    }
561
-
562
-
563
-    public function setup_autosave_hooks()
564
-    {
565
-        $this->_set_autosave_containers();
566
-        $this->_load_autosave_scripts_styles();
567
-    }
568
-
569
-
570
-    /**
571
-     * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available
572
-     * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
573
-     * for the nonce in here, but then this method looks for two things:
574
-     * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
575
-     * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
576
-     * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
577
-     * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
578
-     * template args.
579
-     *    1. $template_args['error'] = IF there is an error you can add the message in here.
580
-     *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
581
-     *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
582
-     *    $this->_template_args['data']['items'] = array(
583
-     *        'event-datetime-ids' => '1,2,3';
584
-     *    );
585
-     *    Keep in mind the following things:
586
-     *    - "where" index is for the input with the id as that string.
587
-     *    - "what" index is what will be used for the value of that input.
588
-     *
589
-     * @return void
590
-     */
591
-    public function do_extra_autosave_stuff()
592
-    {
593
-        // next let's check for the autosave nonce (we'll use _verify_nonce )
594
-        $nonce = isset($this->_req_data['autosavenonce'])
595
-            ? $this->_req_data['autosavenonce']
596
-            : null;
597
-        $this->_verify_nonce($nonce, 'autosave');
598
-        // make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
599
-        if (! defined('DOING_AUTOSAVE')) {
600
-            define('DOING_AUTOSAVE', true);
601
-        }
602
-        // if we made it here then the nonce checked out.  Let's run our methods and actions
603
-        $autosave = "_ee_autosave_{$this->_current_view}";
604
-        if (method_exists($this, $autosave)) {
605
-            $this->$autosave();
606
-        } else {
607
-            $this->_template_args['success'] = true;
608
-        }
609
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
610
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
611
-        // now let's return json
612
-        $this->_return_json();
613
-    }
614
-
615
-
616
-    /**
617
-     * This takes care of setting up default routes and pages that utilize the core WP admin pages.
618
-     * Child classes can override the defaults (in cases for adding metaboxes etc.)
619
-     * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
620
-     *
621
-     * @access protected
622
-     * @throws EE_Error
623
-     * @return void
624
-     */
625
-    protected function _extend_page_config_for_cpt()
626
-    {
627
-        // before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
628
-        if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) {
629
-            return;
630
-        }
631
-        // set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
632
-        if (! empty($this->_cpt_object)) {
633
-            $this->_page_routes = array_merge(
634
-                array(
635
-                    'create_new' => '_create_new_cpt_item',
636
-                    'edit'       => '_edit_cpt_item',
637
-                ),
638
-                $this->_page_routes
639
-            );
640
-            $this->_page_config = array_merge(
641
-                array(
642
-                    'create_new' => array(
643
-                        'nav'           => array(
644
-                            'label' => $this->_cpt_object->labels->add_new_item,
645
-                            'order' => 5,
646
-                        ),
647
-                        'require_nonce' => false,
648
-                    ),
649
-                    'edit'       => array(
650
-                        'nav'           => array(
651
-                            'label'      => $this->_cpt_object->labels->edit_item,
652
-                            'order'      => 5,
653
-                            'persistent' => false,
654
-                            'url'        => '',
655
-                        ),
656
-                        'require_nonce' => false,
657
-                    ),
658
-                ),
659
-                $this->_page_config
660
-            );
661
-        }
662
-        // load the next section only if this is a matching cpt route as set in the cpt routes array.
663
-        if (! isset($this->_cpt_routes[ $this->_req_action ])) {
664
-            return;
665
-        }
666
-        $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false;
667
-        // add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
668
-        if (empty($this->_cpt_object)) {
669
-            $msg = sprintf(
670
-                __(
671
-                    'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).',
672
-                    'event_espresso'
673
-                ),
674
-                $this->page_slug,
675
-                $this->_req_action,
676
-                get_class($this)
677
-            );
678
-            throw new EE_Error($msg);
679
-        }
680
-        if ($this->_cpt_route) {
681
-            $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
682
-            $this->_set_model_object($id);
683
-        }
684
-    }
685
-
686
-
687
-    /**
688
-     * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
689
-     *
690
-     * @access protected
691
-     * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
692
-     * @param bool   $ignore_route_check
693
-     * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
694
-     * @throws EE_Error
695
-     * @throws InvalidArgumentException
696
-     * @throws InvalidDataTypeException
697
-     * @throws InvalidInterfaceException
698
-     * @throws ReflectionException
699
-     */
700
-    protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
701
-    {
702
-        $model = null;
703
-        if (empty($this->_cpt_model_names)
704
-            || (
705
-                ! $ignore_route_check
706
-                && ! isset($this->_cpt_routes[ $this->_req_action ])
707
-            ) || (
708
-                $this->_cpt_model_obj instanceof EE_CPT_Base
709
-                && $this->_cpt_model_obj->ID() === $id
710
-            )
711
-        ) {
712
-            // get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
713
-            return;
714
-        }
715
-        // if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
716
-        if ($ignore_route_check) {
717
-            $post_type = get_post_type($id);
718
-            /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
719
-            $custom_post_types = $this->loader->getShared(
720
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
721
-            );
722
-            $model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
723
-            if (isset($model_names[ $post_type ])) {
724
-                $model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
725
-            }
726
-        } else {
727
-            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
728
-        }
729
-        if ($model instanceof EEM_Base) {
730
-            $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
731
-        }
732
-        do_action(
733
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
734
-            $this->_cpt_model_obj,
735
-            $req_type
736
-        );
737
-    }
738
-
739
-
740
-    /**
741
-     * admin_init_global
742
-     * This runs all the code that we want executed within the WP admin_init hook.
743
-     * This method executes for ALL EE Admin pages.
744
-     *
745
-     * @access public
746
-     * @return void
747
-     */
748
-    public function admin_init_global()
749
-    {
750
-        $post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null;
751
-        // its possible this is a new save so let's catch that instead
752
-        $post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
753
-        $post_type = $post ? $post->post_type : false;
754
-        $current_route = isset($this->_req_data['current_route'])
755
-            ? $this->_req_data['current_route']
756
-            : 'shouldneverwork';
757
-        $route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
758
-            ? $this->_cpt_routes[ $current_route ]
759
-            : '';
760
-        add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
761
-        add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
762
-        if ($post_type === $route_to_check) {
763
-            add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2);
764
-        }
765
-        // now let's filter redirect if we're on a revision page and the revision is for an event CPT.
766
-        $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
767
-        if (! empty($revision)) {
768
-            $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
769
-            // doing a restore?
770
-            if (! empty($action) && $action === 'restore') {
771
-                // get post for revision
772
-                $rev_post = get_post($revision);
773
-                $rev_parent = get_post($rev_post->post_parent);
774
-                // only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
775
-                if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
776
-                    add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2);
777
-                    // restores of revisions
778
-                    add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2);
779
-                }
780
-            }
781
-        }
782
-        // NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
783
-        if ($post_type && $post_type === $route_to_check) {
784
-            // $post_id, $post
785
-            add_action('save_post', array($this, 'insert_update'), 10, 3);
786
-            // $post_id
787
-            add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10);
788
-            add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10);
789
-            add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10);
790
-            add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10);
791
-        }
792
-    }
793
-
794
-
795
-    /**
796
-     * Callback for the WordPress trashed_post hook.
797
-     * Execute some basic checks before calling the trash_cpt_item declared in the child class.
798
-     *
799
-     * @param int $post_id
800
-     * @throws \EE_Error
801
-     */
802
-    public function before_trash_cpt_item($post_id)
803
-    {
804
-        $this->_set_model_object($post_id, true, 'trash');
805
-        // if our cpt object isn't existent then get out immediately.
806
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
807
-            return;
808
-        }
809
-        $this->trash_cpt_item($post_id);
810
-    }
811
-
812
-
813
-    /**
814
-     * Callback for the WordPress untrashed_post hook.
815
-     * Execute some basic checks before calling the restore_cpt_method in the child class.
816
-     *
817
-     * @param $post_id
818
-     * @throws \EE_Error
819
-     */
820
-    public function before_restore_cpt_item($post_id)
821
-    {
822
-        $this->_set_model_object($post_id, true, 'restore');
823
-        // if our cpt object isn't existent then get out immediately.
824
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
825
-            return;
826
-        }
827
-        $this->restore_cpt_item($post_id);
828
-    }
829
-
830
-
831
-    /**
832
-     * Callback for the WordPress after_delete_post hook.
833
-     * Execute some basic checks before calling the delete_cpt_item method in the child class.
834
-     *
835
-     * @param $post_id
836
-     * @throws \EE_Error
837
-     */
838
-    public function before_delete_cpt_item($post_id)
839
-    {
840
-        $this->_set_model_object($post_id, true, 'delete');
841
-        // if our cpt object isn't existent then get out immediately.
842
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
843
-            return;
844
-        }
845
-        $this->delete_cpt_item($post_id);
846
-    }
847
-
848
-
849
-    /**
850
-     * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
851
-     * accordingly.
852
-     *
853
-     * @return void
854
-     * @throws EE_Error
855
-     * @throws InvalidArgumentException
856
-     * @throws InvalidDataTypeException
857
-     * @throws InvalidInterfaceException
858
-     * @throws ReflectionException
859
-     */
860
-    public function verify_cpt_object()
861
-    {
862
-        $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
863
-        // verify event object
864
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
865
-            throw new EE_Error(
866
-                sprintf(
867
-                    __(
868
-                        'Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
869
-                        'event_espresso'
870
-                    ),
871
-                    $label
872
-                )
873
-            );
874
-        }
875
-        // if auto-draft then throw an error
876
-        if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
877
-            EE_Error::overwrite_errors();
878
-            EE_Error::add_error(
879
-                sprintf(
880
-                    __(
881
-                        'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.',
882
-                        'event_espresso'
883
-                    ),
884
-                    $label
885
-                ),
886
-                __FILE__,
887
-                __FUNCTION__,
888
-                __LINE__
889
-            );
890
-        }
891
-        $admin_config = $this->loader->getShared('EE_Admin_Config');
892
-        if ($admin_config->useAdvancedEditor()) {
893
-            $this->loadEspressoEditorAssetManager();
894
-        }
895
-    }
896
-
897
-
898
-    /**
899
-     * admin_footer_scripts_global
900
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
901
-     * will apply on ALL EE_Admin pages.
902
-     *
903
-     * @access public
904
-     * @return void
905
-     */
906
-    public function admin_footer_scripts_global()
907
-    {
908
-        $this->_add_admin_page_ajax_loading_img();
909
-        $this->_add_admin_page_overlay();
910
-    }
911
-
912
-
913
-    /**
914
-     * add in any global scripts for cpt routes
915
-     *
916
-     * @return void
917
-     */
918
-    public function load_global_scripts_styles()
919
-    {
920
-        parent::load_global_scripts_styles();
921
-        if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
922
-            // setup custom post status object for localize script but only if we've got a cpt object
923
-            $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
924
-            if (! empty($statuses)) {
925
-                // get ALL statuses!
926
-                $statuses = $this->_cpt_model_obj->get_all_post_statuses();
927
-                // setup object
928
-                $ee_cpt_statuses = array();
929
-                foreach ($statuses as $status => $label) {
930
-                    $ee_cpt_statuses[ $status ] = array(
931
-                        'label'      => $label,
932
-                        'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label),
933
-                    );
934
-                }
935
-                wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
936
-            }
937
-        }
938
-    }
939
-
940
-
941
-    /**
942
-     * @throws InvalidArgumentException
943
-     * @throws InvalidDataTypeException
944
-     * @throws InvalidInterfaceException
945
-     */
946
-    private function loadEspressoEditorAssetManager()
947
-    {
948
-        EE_Dependency_Map::register_dependencies(
949
-            'EventEspresso\core\domain\services\assets\EspressoEditorAssetManager',
950
-            array(
951
-                'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
952
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
953
-                'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
954
-            )
955
-        );
956
-        $this->loader->getShared(
957
-            'EventEspresso\core\domain\services\assets\EspressoEditorAssetManager'
958
-        );
959
-        add_action('admin_enqueue_scripts', array($this, 'enqueueEspressoEditorAssets'), 100);
960
-    }
961
-
962
-
963
-    /**
964
-     * enqueue_scripts - Load the scripts and css
965
-     *
966
-     * @return void
967
-     * @throws DomainException
968
-     */
969
-    public function enqueueEspressoEditorAssets()
970
-    {
971
-        wp_enqueue_style(EspressoEditorAssetManager::CSS_HANDLE_EDITOR);
972
-        wp_enqueue_style(EspressoEditorAssetManager::CSS_HANDLE_EDITOR_PROTOTYPE);
973
-        wp_enqueue_script(EspressoEditorAssetManager::JS_HANDLE_EDITOR);
974
-        wp_enqueue_script(EspressoEditorAssetManager::JS_HANDLE_EDITOR_PROTOTYPE);
975
-    }
976
-
977
-    /**
978
-     * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
979
-     * insert/updates
980
-     *
981
-     * @param  int     $post_id ID of post being updated
982
-     * @param  WP_Post $post    Post object from WP
983
-     * @param  bool    $update  Whether this is an update or a new save.
984
-     * @return void
985
-     * @throws \EE_Error
986
-     */
987
-    public function insert_update($post_id, $post, $update)
988
-    {
989
-        // make sure that if this is a revision OR trash action that we don't do any updates!
990
-        if (isset($this->_req_data['action'])
991
-            && (
992
-                $this->_req_data['action'] === 'restore'
993
-                || $this->_req_data['action'] === 'trash'
994
-            )
995
-        ) {
996
-            return;
997
-        }
998
-        $this->_set_model_object($post_id, true, 'insert_update');
999
-        // if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
1000
-        if ($update
1001
-            && (
1002
-                ! $this->_cpt_model_obj instanceof EE_CPT_Base
1003
-                || $this->_cpt_model_obj->ID() !== $post_id
1004
-            )
1005
-        ) {
1006
-            return;
1007
-        }
1008
-        // check for autosave and update our req_data property accordingly.
1009
-        /*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
505
+	}
506
+
507
+
508
+	/**
509
+	 * if this post is a draft or scheduled post then we provide a preview button for user to click
510
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
511
+	 *
512
+	 * @param  string $return    the current html
513
+	 * @param  int    $id        the post id for the page
514
+	 * @param  string $new_title What the title is
515
+	 * @param  string $new_slug  what the slug is
516
+	 * @return string            The new html string for the permalink area
517
+	 */
518
+	public function preview_button_html($return, $id, $new_title, $new_slug)
519
+	{
520
+		$post = get_post($id);
521
+		if ('publish' !== get_post_status($post)) {
522
+			$return .= '<span_id="view-post-btn"><a target="_blank" href="'
523
+					   . get_preview_post_link($id)
524
+					   . '" class="button button-small">'
525
+					   . __('Preview', 'event_espresso')
526
+					   . '</a></span>'
527
+					   . "\n";
528
+		}
529
+		return $return;
530
+	}
531
+
532
+
533
+	/**
534
+	 * add our custom post stati dropdown on the wp post page for this cpt
535
+	 *
536
+	 * @return void
537
+	 */
538
+	public function custom_post_stati_dropdown()
539
+	{
540
+
541
+		$statuses = $this->_cpt_model_obj->get_custom_post_statuses();
542
+		$cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
543
+			? $statuses[ $this->_cpt_model_obj->status() ]
544
+			: '';
545
+		$template_args = array(
546
+			'cur_status'            => $this->_cpt_model_obj->status(),
547
+			'statuses'              => $statuses,
548
+			'cur_status_label'      => $cur_status_label,
549
+			'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label),
550
+		);
551
+		// we'll add a trash post status (WP doesn't add one for some reason)
552
+		if ($this->_cpt_model_obj->status() === 'trash') {
553
+			$template_args['cur_status_label'] = __('Trashed', 'event_espresso');
554
+			$statuses['trash'] = __('Trashed', 'event_espresso');
555
+			$template_args['statuses'] = $statuses;
556
+		}
557
+
558
+		$template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
559
+		EEH_Template::display_template($template, $template_args);
560
+	}
561
+
562
+
563
+	public function setup_autosave_hooks()
564
+	{
565
+		$this->_set_autosave_containers();
566
+		$this->_load_autosave_scripts_styles();
567
+	}
568
+
569
+
570
+	/**
571
+	 * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available
572
+	 * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
573
+	 * for the nonce in here, but then this method looks for two things:
574
+	 * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
575
+	 * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
576
+	 * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
577
+	 * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
578
+	 * template args.
579
+	 *    1. $template_args['error'] = IF there is an error you can add the message in here.
580
+	 *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
581
+	 *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
582
+	 *    $this->_template_args['data']['items'] = array(
583
+	 *        'event-datetime-ids' => '1,2,3';
584
+	 *    );
585
+	 *    Keep in mind the following things:
586
+	 *    - "where" index is for the input with the id as that string.
587
+	 *    - "what" index is what will be used for the value of that input.
588
+	 *
589
+	 * @return void
590
+	 */
591
+	public function do_extra_autosave_stuff()
592
+	{
593
+		// next let's check for the autosave nonce (we'll use _verify_nonce )
594
+		$nonce = isset($this->_req_data['autosavenonce'])
595
+			? $this->_req_data['autosavenonce']
596
+			: null;
597
+		$this->_verify_nonce($nonce, 'autosave');
598
+		// make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
599
+		if (! defined('DOING_AUTOSAVE')) {
600
+			define('DOING_AUTOSAVE', true);
601
+		}
602
+		// if we made it here then the nonce checked out.  Let's run our methods and actions
603
+		$autosave = "_ee_autosave_{$this->_current_view}";
604
+		if (method_exists($this, $autosave)) {
605
+			$this->$autosave();
606
+		} else {
607
+			$this->_template_args['success'] = true;
608
+		}
609
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
610
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
611
+		// now let's return json
612
+		$this->_return_json();
613
+	}
614
+
615
+
616
+	/**
617
+	 * This takes care of setting up default routes and pages that utilize the core WP admin pages.
618
+	 * Child classes can override the defaults (in cases for adding metaboxes etc.)
619
+	 * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
620
+	 *
621
+	 * @access protected
622
+	 * @throws EE_Error
623
+	 * @return void
624
+	 */
625
+	protected function _extend_page_config_for_cpt()
626
+	{
627
+		// before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
628
+		if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) {
629
+			return;
630
+		}
631
+		// set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
632
+		if (! empty($this->_cpt_object)) {
633
+			$this->_page_routes = array_merge(
634
+				array(
635
+					'create_new' => '_create_new_cpt_item',
636
+					'edit'       => '_edit_cpt_item',
637
+				),
638
+				$this->_page_routes
639
+			);
640
+			$this->_page_config = array_merge(
641
+				array(
642
+					'create_new' => array(
643
+						'nav'           => array(
644
+							'label' => $this->_cpt_object->labels->add_new_item,
645
+							'order' => 5,
646
+						),
647
+						'require_nonce' => false,
648
+					),
649
+					'edit'       => array(
650
+						'nav'           => array(
651
+							'label'      => $this->_cpt_object->labels->edit_item,
652
+							'order'      => 5,
653
+							'persistent' => false,
654
+							'url'        => '',
655
+						),
656
+						'require_nonce' => false,
657
+					),
658
+				),
659
+				$this->_page_config
660
+			);
661
+		}
662
+		// load the next section only if this is a matching cpt route as set in the cpt routes array.
663
+		if (! isset($this->_cpt_routes[ $this->_req_action ])) {
664
+			return;
665
+		}
666
+		$this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false;
667
+		// add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
668
+		if (empty($this->_cpt_object)) {
669
+			$msg = sprintf(
670
+				__(
671
+					'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).',
672
+					'event_espresso'
673
+				),
674
+				$this->page_slug,
675
+				$this->_req_action,
676
+				get_class($this)
677
+			);
678
+			throw new EE_Error($msg);
679
+		}
680
+		if ($this->_cpt_route) {
681
+			$id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
682
+			$this->_set_model_object($id);
683
+		}
684
+	}
685
+
686
+
687
+	/**
688
+	 * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
689
+	 *
690
+	 * @access protected
691
+	 * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
692
+	 * @param bool   $ignore_route_check
693
+	 * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
694
+	 * @throws EE_Error
695
+	 * @throws InvalidArgumentException
696
+	 * @throws InvalidDataTypeException
697
+	 * @throws InvalidInterfaceException
698
+	 * @throws ReflectionException
699
+	 */
700
+	protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
701
+	{
702
+		$model = null;
703
+		if (empty($this->_cpt_model_names)
704
+			|| (
705
+				! $ignore_route_check
706
+				&& ! isset($this->_cpt_routes[ $this->_req_action ])
707
+			) || (
708
+				$this->_cpt_model_obj instanceof EE_CPT_Base
709
+				&& $this->_cpt_model_obj->ID() === $id
710
+			)
711
+		) {
712
+			// get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
713
+			return;
714
+		}
715
+		// if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
716
+		if ($ignore_route_check) {
717
+			$post_type = get_post_type($id);
718
+			/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
719
+			$custom_post_types = $this->loader->getShared(
720
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
721
+			);
722
+			$model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
723
+			if (isset($model_names[ $post_type ])) {
724
+				$model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
725
+			}
726
+		} else {
727
+			$model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
728
+		}
729
+		if ($model instanceof EEM_Base) {
730
+			$this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
731
+		}
732
+		do_action(
733
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
734
+			$this->_cpt_model_obj,
735
+			$req_type
736
+		);
737
+	}
738
+
739
+
740
+	/**
741
+	 * admin_init_global
742
+	 * This runs all the code that we want executed within the WP admin_init hook.
743
+	 * This method executes for ALL EE Admin pages.
744
+	 *
745
+	 * @access public
746
+	 * @return void
747
+	 */
748
+	public function admin_init_global()
749
+	{
750
+		$post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null;
751
+		// its possible this is a new save so let's catch that instead
752
+		$post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
753
+		$post_type = $post ? $post->post_type : false;
754
+		$current_route = isset($this->_req_data['current_route'])
755
+			? $this->_req_data['current_route']
756
+			: 'shouldneverwork';
757
+		$route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
758
+			? $this->_cpt_routes[ $current_route ]
759
+			: '';
760
+		add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
761
+		add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
762
+		if ($post_type === $route_to_check) {
763
+			add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2);
764
+		}
765
+		// now let's filter redirect if we're on a revision page and the revision is for an event CPT.
766
+		$revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
767
+		if (! empty($revision)) {
768
+			$action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
769
+			// doing a restore?
770
+			if (! empty($action) && $action === 'restore') {
771
+				// get post for revision
772
+				$rev_post = get_post($revision);
773
+				$rev_parent = get_post($rev_post->post_parent);
774
+				// only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
775
+				if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
776
+					add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2);
777
+					// restores of revisions
778
+					add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2);
779
+				}
780
+			}
781
+		}
782
+		// NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
783
+		if ($post_type && $post_type === $route_to_check) {
784
+			// $post_id, $post
785
+			add_action('save_post', array($this, 'insert_update'), 10, 3);
786
+			// $post_id
787
+			add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10);
788
+			add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10);
789
+			add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10);
790
+			add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10);
791
+		}
792
+	}
793
+
794
+
795
+	/**
796
+	 * Callback for the WordPress trashed_post hook.
797
+	 * Execute some basic checks before calling the trash_cpt_item declared in the child class.
798
+	 *
799
+	 * @param int $post_id
800
+	 * @throws \EE_Error
801
+	 */
802
+	public function before_trash_cpt_item($post_id)
803
+	{
804
+		$this->_set_model_object($post_id, true, 'trash');
805
+		// if our cpt object isn't existent then get out immediately.
806
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
807
+			return;
808
+		}
809
+		$this->trash_cpt_item($post_id);
810
+	}
811
+
812
+
813
+	/**
814
+	 * Callback for the WordPress untrashed_post hook.
815
+	 * Execute some basic checks before calling the restore_cpt_method in the child class.
816
+	 *
817
+	 * @param $post_id
818
+	 * @throws \EE_Error
819
+	 */
820
+	public function before_restore_cpt_item($post_id)
821
+	{
822
+		$this->_set_model_object($post_id, true, 'restore');
823
+		// if our cpt object isn't existent then get out immediately.
824
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
825
+			return;
826
+		}
827
+		$this->restore_cpt_item($post_id);
828
+	}
829
+
830
+
831
+	/**
832
+	 * Callback for the WordPress after_delete_post hook.
833
+	 * Execute some basic checks before calling the delete_cpt_item method in the child class.
834
+	 *
835
+	 * @param $post_id
836
+	 * @throws \EE_Error
837
+	 */
838
+	public function before_delete_cpt_item($post_id)
839
+	{
840
+		$this->_set_model_object($post_id, true, 'delete');
841
+		// if our cpt object isn't existent then get out immediately.
842
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
843
+			return;
844
+		}
845
+		$this->delete_cpt_item($post_id);
846
+	}
847
+
848
+
849
+	/**
850
+	 * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
851
+	 * accordingly.
852
+	 *
853
+	 * @return void
854
+	 * @throws EE_Error
855
+	 * @throws InvalidArgumentException
856
+	 * @throws InvalidDataTypeException
857
+	 * @throws InvalidInterfaceException
858
+	 * @throws ReflectionException
859
+	 */
860
+	public function verify_cpt_object()
861
+	{
862
+		$label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
863
+		// verify event object
864
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
865
+			throw new EE_Error(
866
+				sprintf(
867
+					__(
868
+						'Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
869
+						'event_espresso'
870
+					),
871
+					$label
872
+				)
873
+			);
874
+		}
875
+		// if auto-draft then throw an error
876
+		if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
877
+			EE_Error::overwrite_errors();
878
+			EE_Error::add_error(
879
+				sprintf(
880
+					__(
881
+						'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.',
882
+						'event_espresso'
883
+					),
884
+					$label
885
+				),
886
+				__FILE__,
887
+				__FUNCTION__,
888
+				__LINE__
889
+			);
890
+		}
891
+		$admin_config = $this->loader->getShared('EE_Admin_Config');
892
+		if ($admin_config->useAdvancedEditor()) {
893
+			$this->loadEspressoEditorAssetManager();
894
+		}
895
+	}
896
+
897
+
898
+	/**
899
+	 * admin_footer_scripts_global
900
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
901
+	 * will apply on ALL EE_Admin pages.
902
+	 *
903
+	 * @access public
904
+	 * @return void
905
+	 */
906
+	public function admin_footer_scripts_global()
907
+	{
908
+		$this->_add_admin_page_ajax_loading_img();
909
+		$this->_add_admin_page_overlay();
910
+	}
911
+
912
+
913
+	/**
914
+	 * add in any global scripts for cpt routes
915
+	 *
916
+	 * @return void
917
+	 */
918
+	public function load_global_scripts_styles()
919
+	{
920
+		parent::load_global_scripts_styles();
921
+		if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
922
+			// setup custom post status object for localize script but only if we've got a cpt object
923
+			$statuses = $this->_cpt_model_obj->get_custom_post_statuses();
924
+			if (! empty($statuses)) {
925
+				// get ALL statuses!
926
+				$statuses = $this->_cpt_model_obj->get_all_post_statuses();
927
+				// setup object
928
+				$ee_cpt_statuses = array();
929
+				foreach ($statuses as $status => $label) {
930
+					$ee_cpt_statuses[ $status ] = array(
931
+						'label'      => $label,
932
+						'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label),
933
+					);
934
+				}
935
+				wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
936
+			}
937
+		}
938
+	}
939
+
940
+
941
+	/**
942
+	 * @throws InvalidArgumentException
943
+	 * @throws InvalidDataTypeException
944
+	 * @throws InvalidInterfaceException
945
+	 */
946
+	private function loadEspressoEditorAssetManager()
947
+	{
948
+		EE_Dependency_Map::register_dependencies(
949
+			'EventEspresso\core\domain\services\assets\EspressoEditorAssetManager',
950
+			array(
951
+				'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
952
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
953
+				'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
954
+			)
955
+		);
956
+		$this->loader->getShared(
957
+			'EventEspresso\core\domain\services\assets\EspressoEditorAssetManager'
958
+		);
959
+		add_action('admin_enqueue_scripts', array($this, 'enqueueEspressoEditorAssets'), 100);
960
+	}
961
+
962
+
963
+	/**
964
+	 * enqueue_scripts - Load the scripts and css
965
+	 *
966
+	 * @return void
967
+	 * @throws DomainException
968
+	 */
969
+	public function enqueueEspressoEditorAssets()
970
+	{
971
+		wp_enqueue_style(EspressoEditorAssetManager::CSS_HANDLE_EDITOR);
972
+		wp_enqueue_style(EspressoEditorAssetManager::CSS_HANDLE_EDITOR_PROTOTYPE);
973
+		wp_enqueue_script(EspressoEditorAssetManager::JS_HANDLE_EDITOR);
974
+		wp_enqueue_script(EspressoEditorAssetManager::JS_HANDLE_EDITOR_PROTOTYPE);
975
+	}
976
+
977
+	/**
978
+	 * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
979
+	 * insert/updates
980
+	 *
981
+	 * @param  int     $post_id ID of post being updated
982
+	 * @param  WP_Post $post    Post object from WP
983
+	 * @param  bool    $update  Whether this is an update or a new save.
984
+	 * @return void
985
+	 * @throws \EE_Error
986
+	 */
987
+	public function insert_update($post_id, $post, $update)
988
+	{
989
+		// make sure that if this is a revision OR trash action that we don't do any updates!
990
+		if (isset($this->_req_data['action'])
991
+			&& (
992
+				$this->_req_data['action'] === 'restore'
993
+				|| $this->_req_data['action'] === 'trash'
994
+			)
995
+		) {
996
+			return;
997
+		}
998
+		$this->_set_model_object($post_id, true, 'insert_update');
999
+		// if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
1000
+		if ($update
1001
+			&& (
1002
+				! $this->_cpt_model_obj instanceof EE_CPT_Base
1003
+				|| $this->_cpt_model_obj->ID() !== $post_id
1004
+			)
1005
+		) {
1006
+			return;
1007
+		}
1008
+		// check for autosave and update our req_data property accordingly.
1009
+		/*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
1010 1010
             foreach( (array) $this->_req_data['ee_autosave_data'] as $id => $values ) {
1011 1011
 
1012 1012
                 foreach ( (array) $values as $key => $value ) {
@@ -1016,532 +1016,532 @@  discard block
 block discarded – undo
1016 1016
 
1017 1017
         }/**/ // TODO reactivate after autosave is implemented in 4.2
1018 1018
 
1019
-        // take care of updating any selected page_template IF this cpt supports it.
1020
-        if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
1021
-            // wp version aware.
1022
-            if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
1023
-                $page_templates = wp_get_theme()->get_page_templates();
1024
-            } else {
1025
-                $post->page_template = $this->_req_data['page_template'];
1026
-                $page_templates = wp_get_theme()->get_page_templates($post);
1027
-            }
1028
-            if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) {
1029
-                EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1030
-            } else {
1031
-                update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
1032
-            }
1033
-        }
1034
-        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
1035
-            return;
1036
-        } //TODO we'll remove this after reimplementing autosave in 4.2
1037
-        $this->_insert_update_cpt_item($post_id, $post);
1038
-    }
1039
-
1040
-
1041
-    /**
1042
-     * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
1043
-     * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
1044
-     * so we don't have to check for our CPT.
1045
-     *
1046
-     * @param  int $post_id ID of the post
1047
-     * @return void
1048
-     */
1049
-    public function dont_permanently_delete_ee_cpts($post_id)
1050
-    {
1051
-        // only do this if we're actually processing one of our CPTs
1052
-        // if our cpt object isn't existent then get out immediately.
1053
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1054
-            return;
1055
-        }
1056
-        delete_post_meta($post_id, '_wp_trash_meta_status');
1057
-        delete_post_meta($post_id, '_wp_trash_meta_time');
1058
-        // our cpts may have comments so let's take care of that too
1059
-        delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1060
-    }
1061
-
1062
-
1063
-    /**
1064
-     * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1065
-     * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1066
-     * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1067
-     *
1068
-     * @param  int $post_id     ID of cpt item
1069
-     * @param  int $revision_id ID of revision being restored
1070
-     * @return void
1071
-     */
1072
-    public function restore_revision($post_id, $revision_id)
1073
-    {
1074
-        $this->_restore_cpt_item($post_id, $revision_id);
1075
-        // global action
1076
-        do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1077
-        // class specific action so you can limit hooking into a specific page.
1078
-        do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1079
-    }
1080
-
1081
-
1082
-    /**
1083
-     * @see restore_revision() for details
1084
-     * @param  int $post_id     ID of cpt item
1085
-     * @param  int $revision_id ID of revision for item
1086
-     * @return void
1087
-     */
1088
-    abstract protected function _restore_cpt_item($post_id, $revision_id);
1089
-
1090
-
1091
-    /**
1092
-     * Execution of this method is added to the end of the load_page_dependencies method in the parent
1093
-     * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1094
-     * To fix we have to reset the current_screen using the page_slug
1095
-     * (which is identical - or should be - to our registered_post_type id.)
1096
-     * Also, since the core WP file loads the admin_header.php for WP
1097
-     * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1098
-     * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1099
-     *
1100
-     * @return void
1101
-     */
1102
-    public function modify_current_screen()
1103
-    {
1104
-        // ONLY do this if the current page_route IS a cpt route
1105
-        if (! $this->_cpt_route) {
1106
-            return;
1107
-        }
1108
-        // routing things REALLY early b/c this is a cpt admin page
1109
-        set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1110
-        $this->_current_screen = get_current_screen();
1111
-        $this->_current_screen->base = 'event-espresso';
1112
-        $this->_add_help_tabs(); // we make sure we add any help tabs back in!
1113
-        /*try {
1019
+		// take care of updating any selected page_template IF this cpt supports it.
1020
+		if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
1021
+			// wp version aware.
1022
+			if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
1023
+				$page_templates = wp_get_theme()->get_page_templates();
1024
+			} else {
1025
+				$post->page_template = $this->_req_data['page_template'];
1026
+				$page_templates = wp_get_theme()->get_page_templates($post);
1027
+			}
1028
+			if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) {
1029
+				EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1030
+			} else {
1031
+				update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
1032
+			}
1033
+		}
1034
+		if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
1035
+			return;
1036
+		} //TODO we'll remove this after reimplementing autosave in 4.2
1037
+		$this->_insert_update_cpt_item($post_id, $post);
1038
+	}
1039
+
1040
+
1041
+	/**
1042
+	 * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
1043
+	 * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
1044
+	 * so we don't have to check for our CPT.
1045
+	 *
1046
+	 * @param  int $post_id ID of the post
1047
+	 * @return void
1048
+	 */
1049
+	public function dont_permanently_delete_ee_cpts($post_id)
1050
+	{
1051
+		// only do this if we're actually processing one of our CPTs
1052
+		// if our cpt object isn't existent then get out immediately.
1053
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1054
+			return;
1055
+		}
1056
+		delete_post_meta($post_id, '_wp_trash_meta_status');
1057
+		delete_post_meta($post_id, '_wp_trash_meta_time');
1058
+		// our cpts may have comments so let's take care of that too
1059
+		delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1060
+	}
1061
+
1062
+
1063
+	/**
1064
+	 * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1065
+	 * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1066
+	 * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1067
+	 *
1068
+	 * @param  int $post_id     ID of cpt item
1069
+	 * @param  int $revision_id ID of revision being restored
1070
+	 * @return void
1071
+	 */
1072
+	public function restore_revision($post_id, $revision_id)
1073
+	{
1074
+		$this->_restore_cpt_item($post_id, $revision_id);
1075
+		// global action
1076
+		do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1077
+		// class specific action so you can limit hooking into a specific page.
1078
+		do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1079
+	}
1080
+
1081
+
1082
+	/**
1083
+	 * @see restore_revision() for details
1084
+	 * @param  int $post_id     ID of cpt item
1085
+	 * @param  int $revision_id ID of revision for item
1086
+	 * @return void
1087
+	 */
1088
+	abstract protected function _restore_cpt_item($post_id, $revision_id);
1089
+
1090
+
1091
+	/**
1092
+	 * Execution of this method is added to the end of the load_page_dependencies method in the parent
1093
+	 * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1094
+	 * To fix we have to reset the current_screen using the page_slug
1095
+	 * (which is identical - or should be - to our registered_post_type id.)
1096
+	 * Also, since the core WP file loads the admin_header.php for WP
1097
+	 * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1098
+	 * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1099
+	 *
1100
+	 * @return void
1101
+	 */
1102
+	public function modify_current_screen()
1103
+	{
1104
+		// ONLY do this if the current page_route IS a cpt route
1105
+		if (! $this->_cpt_route) {
1106
+			return;
1107
+		}
1108
+		// routing things REALLY early b/c this is a cpt admin page
1109
+		set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1110
+		$this->_current_screen = get_current_screen();
1111
+		$this->_current_screen->base = 'event-espresso';
1112
+		$this->_add_help_tabs(); // we make sure we add any help tabs back in!
1113
+		/*try {
1114 1114
             $this->_route_admin_request();
1115 1115
         } catch ( EE_Error $e ) {
1116 1116
             $e->get_error();
1117 1117
         }/**/
1118
-    }
1119
-
1120
-
1121
-    /**
1122
-     * This allows child classes to modify the default editor title that appears when people add a new or edit an
1123
-     * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1124
-     * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1125
-     * default to be.
1126
-     *
1127
-     * @param string $title The new title (or existing if there is no editor_title defined)
1128
-     * @return string
1129
-     */
1130
-    public function add_custom_editor_default_title($title)
1131
-    {
1132
-        return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1133
-            ? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1134
-            : $title;
1135
-    }
1136
-
1137
-
1138
-    /**
1139
-     * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1140
-     *
1141
-     * @param string $shortlink   The already generated shortlink
1142
-     * @param int    $id          Post ID for this item
1143
-     * @param string $context     The context for the link
1144
-     * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1145
-     * @return string
1146
-     */
1147
-    public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1148
-    {
1149
-        if (! empty($id) && get_option('permalink_structure') !== '') {
1150
-            $post = get_post($id);
1151
-            if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1152
-                $shortlink = home_url('?p=' . $post->ID);
1153
-            }
1154
-        }
1155
-        return $shortlink;
1156
-    }
1157
-
1158
-
1159
-    /**
1160
-     * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1161
-     * already run in modify_current_screen())
1162
-     *
1163
-     * @return void
1164
-     */
1165
-    public function route_admin_request()
1166
-    {
1167
-        if ($this->_cpt_route) {
1168
-            return;
1169
-        }
1170
-        try {
1171
-            $this->_route_admin_request();
1172
-        } catch (EE_Error $e) {
1173
-            $e->get_error();
1174
-        }
1175
-    }
1176
-
1177
-
1178
-    /**
1179
-     * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1180
-     *
1181
-     * @return void
1182
-     */
1183
-    public function cpt_post_form_hidden_input()
1184
-    {
1185
-        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1186
-        // we're also going to add the route value and the current page so we can direct autosave parsing correctly
1187
-        echo '<div id="ee-cpt-hidden-inputs">';
1188
-        echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1189
-        echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1190
-        echo '</div>';
1191
-    }
1192
-
1193
-
1194
-    /**
1195
-     * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1196
-     *
1197
-     * @param  string $location Original location url
1198
-     * @param  int    $status   Status for http header
1199
-     * @return string           new (or original) url to redirect to.
1200
-     */
1201
-    public function revision_redirect($location, $status)
1202
-    {
1203
-        // get revision
1204
-        $rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1205
-        // can't do anything without revision so let's get out if not present
1206
-        if (empty($rev_id)) {
1207
-            return $location;
1208
-        }
1209
-        // get rev_post_data
1210
-        $rev = get_post($rev_id);
1211
-        $admin_url = $this->_admin_base_url;
1212
-        $query_args = array(
1213
-            'action'   => 'edit',
1214
-            'post'     => $rev->post_parent,
1215
-            'revision' => $rev_id,
1216
-            'message'  => 5,
1217
-        );
1218
-        $this->_process_notices($query_args, true);
1219
-        return self::add_query_args_and_nonce($query_args, $admin_url);
1220
-    }
1221
-
1222
-
1223
-    /**
1224
-     * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1225
-     *
1226
-     * @param  string $link    the original generated link
1227
-     * @param  int    $id      post id
1228
-     * @param  string $context optional, defaults to display.  How to write the '&'
1229
-     * @return string          the link
1230
-     */
1231
-    public function modify_edit_post_link($link, $id, $context)
1232
-    {
1233
-        $post = get_post($id);
1234
-        if (! isset($this->_req_data['action'])
1235
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1236
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1237
-        ) {
1238
-            return $link;
1239
-        }
1240
-        $query_args = array(
1241
-            'action' => isset($this->_cpt_edit_routes[ $post->post_type ])
1242
-                ? $this->_cpt_edit_routes[ $post->post_type ]
1243
-                : 'edit',
1244
-            'post'   => $id,
1245
-        );
1246
-        return self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1247
-    }
1248
-
1249
-
1250
-    /**
1251
-     * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1252
-     * our routes.
1253
-     *
1254
-     * @param  string $delete_link  original delete link
1255
-     * @param  int    $post_id      id of cpt object
1256
-     * @param  bool   $force_delete whether this is forcing a hard delete instead of trash
1257
-     * @return string new delete link
1258
-     * @throws EE_Error
1259
-     */
1260
-    public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1261
-    {
1262
-        $post = get_post($post_id);
1263
-
1264
-        if (empty($this->_req_data['action'])
1265
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1266
-            || ! $post instanceof WP_Post
1267
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1268
-        ) {
1269
-            return $delete_link;
1270
-        }
1271
-        $this->_set_model_object($post->ID, true);
1272
-
1273
-        // returns something like `trash_event` or `trash_attendee` or `trash_venue`
1274
-        $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1275
-
1276
-        return EE_Admin_Page::add_query_args_and_nonce(
1277
-            array(
1278
-                'page'   => $this->_req_data['page'],
1279
-                'action' => $action,
1280
-                $this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1281
-                         => $post->ID,
1282
-            ),
1283
-            admin_url()
1284
-        );
1285
-    }
1286
-
1287
-
1288
-    /**
1289
-     * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1290
-     * so that we can hijack the default redirect locations for wp custom post types
1291
-     * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1292
-     *
1293
-     * @param  string $location This is the incoming currently set redirect location
1294
-     * @param  string $post_id  This is the 'ID' value of the wp_posts table
1295
-     * @return string           the new location to redirect to
1296
-     */
1297
-    public function cpt_post_location_redirect($location, $post_id)
1298
-    {
1299
-        // we DO have a match so let's setup the url
1300
-        // we have to get the post to determine our route
1301
-        $post = get_post($post_id);
1302
-        $edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1303
-        // shared query_args
1304
-        $query_args = array('action' => $edit_route, 'post' => $post_id);
1305
-        $admin_url = $this->_admin_base_url;
1306
-        if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1307
-            $status = get_post_status($post_id);
1308
-            if (isset($this->_req_data['publish'])) {
1309
-                switch ($status) {
1310
-                    case 'pending':
1311
-                        $message = 8;
1312
-                        break;
1313
-                    case 'future':
1314
-                        $message = 9;
1315
-                        break;
1316
-                    default:
1317
-                        $message = 6;
1318
-                }
1319
-            } else {
1320
-                $message = 'draft' === $status ? 10 : 1;
1321
-            }
1322
-        } elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1323
-            $message = 2;
1324
-        } elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1325
-            $message = 3;
1326
-        } elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1327
-            $message = 7;
1328
-        } else {
1329
-            $message = 4;
1330
-        }
1331
-        // change the message if the post type is not viewable on the frontend
1332
-        $this->_cpt_object = get_post_type_object($post->post_type);
1333
-        $message = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1334
-        $query_args = array_merge(array('message' => $message), $query_args);
1335
-        $this->_process_notices($query_args, true);
1336
-        return self::add_query_args_and_nonce($query_args, $admin_url);
1337
-    }
1338
-
1339
-
1340
-    /**
1341
-     * This method is called to inject nav tabs on core WP cpt pages
1342
-     *
1343
-     * @access public
1344
-     * @return void
1345
-     */
1346
-    public function inject_nav_tabs()
1347
-    {
1348
-        // can we hijack and insert the nav_tabs?
1349
-        $nav_tabs = $this->_get_main_nav_tabs();
1350
-        // first close off existing form tag
1351
-        $html = '>';
1352
-        $html .= $nav_tabs;
1353
-        // now let's handle the remaining tag ( missing ">" is CORRECT )
1354
-        $html .= '<span></span';
1355
-        echo $html;
1356
-    }
1357
-
1358
-
1359
-    /**
1360
-     * This just sets up the post update messages when an update form is loaded
1361
-     *
1362
-     * @access public
1363
-     * @param  array $messages the original messages array
1364
-     * @return array           the new messages array
1365
-     */
1366
-    public function post_update_messages($messages)
1367
-    {
1368
-        global $post;
1369
-        $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1370
-        $id = empty($id) && is_object($post) ? $post->ID : null;
1371
-        /*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1118
+	}
1119
+
1120
+
1121
+	/**
1122
+	 * This allows child classes to modify the default editor title that appears when people add a new or edit an
1123
+	 * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1124
+	 * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1125
+	 * default to be.
1126
+	 *
1127
+	 * @param string $title The new title (or existing if there is no editor_title defined)
1128
+	 * @return string
1129
+	 */
1130
+	public function add_custom_editor_default_title($title)
1131
+	{
1132
+		return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1133
+			? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1134
+			: $title;
1135
+	}
1136
+
1137
+
1138
+	/**
1139
+	 * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1140
+	 *
1141
+	 * @param string $shortlink   The already generated shortlink
1142
+	 * @param int    $id          Post ID for this item
1143
+	 * @param string $context     The context for the link
1144
+	 * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1145
+	 * @return string
1146
+	 */
1147
+	public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1148
+	{
1149
+		if (! empty($id) && get_option('permalink_structure') !== '') {
1150
+			$post = get_post($id);
1151
+			if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1152
+				$shortlink = home_url('?p=' . $post->ID);
1153
+			}
1154
+		}
1155
+		return $shortlink;
1156
+	}
1157
+
1158
+
1159
+	/**
1160
+	 * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1161
+	 * already run in modify_current_screen())
1162
+	 *
1163
+	 * @return void
1164
+	 */
1165
+	public function route_admin_request()
1166
+	{
1167
+		if ($this->_cpt_route) {
1168
+			return;
1169
+		}
1170
+		try {
1171
+			$this->_route_admin_request();
1172
+		} catch (EE_Error $e) {
1173
+			$e->get_error();
1174
+		}
1175
+	}
1176
+
1177
+
1178
+	/**
1179
+	 * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1180
+	 *
1181
+	 * @return void
1182
+	 */
1183
+	public function cpt_post_form_hidden_input()
1184
+	{
1185
+		echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1186
+		// we're also going to add the route value and the current page so we can direct autosave parsing correctly
1187
+		echo '<div id="ee-cpt-hidden-inputs">';
1188
+		echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1189
+		echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1190
+		echo '</div>';
1191
+	}
1192
+
1193
+
1194
+	/**
1195
+	 * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1196
+	 *
1197
+	 * @param  string $location Original location url
1198
+	 * @param  int    $status   Status for http header
1199
+	 * @return string           new (or original) url to redirect to.
1200
+	 */
1201
+	public function revision_redirect($location, $status)
1202
+	{
1203
+		// get revision
1204
+		$rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1205
+		// can't do anything without revision so let's get out if not present
1206
+		if (empty($rev_id)) {
1207
+			return $location;
1208
+		}
1209
+		// get rev_post_data
1210
+		$rev = get_post($rev_id);
1211
+		$admin_url = $this->_admin_base_url;
1212
+		$query_args = array(
1213
+			'action'   => 'edit',
1214
+			'post'     => $rev->post_parent,
1215
+			'revision' => $rev_id,
1216
+			'message'  => 5,
1217
+		);
1218
+		$this->_process_notices($query_args, true);
1219
+		return self::add_query_args_and_nonce($query_args, $admin_url);
1220
+	}
1221
+
1222
+
1223
+	/**
1224
+	 * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1225
+	 *
1226
+	 * @param  string $link    the original generated link
1227
+	 * @param  int    $id      post id
1228
+	 * @param  string $context optional, defaults to display.  How to write the '&'
1229
+	 * @return string          the link
1230
+	 */
1231
+	public function modify_edit_post_link($link, $id, $context)
1232
+	{
1233
+		$post = get_post($id);
1234
+		if (! isset($this->_req_data['action'])
1235
+			|| ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1236
+			|| $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1237
+		) {
1238
+			return $link;
1239
+		}
1240
+		$query_args = array(
1241
+			'action' => isset($this->_cpt_edit_routes[ $post->post_type ])
1242
+				? $this->_cpt_edit_routes[ $post->post_type ]
1243
+				: 'edit',
1244
+			'post'   => $id,
1245
+		);
1246
+		return self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1247
+	}
1248
+
1249
+
1250
+	/**
1251
+	 * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1252
+	 * our routes.
1253
+	 *
1254
+	 * @param  string $delete_link  original delete link
1255
+	 * @param  int    $post_id      id of cpt object
1256
+	 * @param  bool   $force_delete whether this is forcing a hard delete instead of trash
1257
+	 * @return string new delete link
1258
+	 * @throws EE_Error
1259
+	 */
1260
+	public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1261
+	{
1262
+		$post = get_post($post_id);
1263
+
1264
+		if (empty($this->_req_data['action'])
1265
+			|| ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1266
+			|| ! $post instanceof WP_Post
1267
+			|| $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1268
+		) {
1269
+			return $delete_link;
1270
+		}
1271
+		$this->_set_model_object($post->ID, true);
1272
+
1273
+		// returns something like `trash_event` or `trash_attendee` or `trash_venue`
1274
+		$action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1275
+
1276
+		return EE_Admin_Page::add_query_args_and_nonce(
1277
+			array(
1278
+				'page'   => $this->_req_data['page'],
1279
+				'action' => $action,
1280
+				$this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1281
+						 => $post->ID,
1282
+			),
1283
+			admin_url()
1284
+		);
1285
+	}
1286
+
1287
+
1288
+	/**
1289
+	 * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1290
+	 * so that we can hijack the default redirect locations for wp custom post types
1291
+	 * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1292
+	 *
1293
+	 * @param  string $location This is the incoming currently set redirect location
1294
+	 * @param  string $post_id  This is the 'ID' value of the wp_posts table
1295
+	 * @return string           the new location to redirect to
1296
+	 */
1297
+	public function cpt_post_location_redirect($location, $post_id)
1298
+	{
1299
+		// we DO have a match so let's setup the url
1300
+		// we have to get the post to determine our route
1301
+		$post = get_post($post_id);
1302
+		$edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1303
+		// shared query_args
1304
+		$query_args = array('action' => $edit_route, 'post' => $post_id);
1305
+		$admin_url = $this->_admin_base_url;
1306
+		if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1307
+			$status = get_post_status($post_id);
1308
+			if (isset($this->_req_data['publish'])) {
1309
+				switch ($status) {
1310
+					case 'pending':
1311
+						$message = 8;
1312
+						break;
1313
+					case 'future':
1314
+						$message = 9;
1315
+						break;
1316
+					default:
1317
+						$message = 6;
1318
+				}
1319
+			} else {
1320
+				$message = 'draft' === $status ? 10 : 1;
1321
+			}
1322
+		} elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1323
+			$message = 2;
1324
+		} elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1325
+			$message = 3;
1326
+		} elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1327
+			$message = 7;
1328
+		} else {
1329
+			$message = 4;
1330
+		}
1331
+		// change the message if the post type is not viewable on the frontend
1332
+		$this->_cpt_object = get_post_type_object($post->post_type);
1333
+		$message = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1334
+		$query_args = array_merge(array('message' => $message), $query_args);
1335
+		$this->_process_notices($query_args, true);
1336
+		return self::add_query_args_and_nonce($query_args, $admin_url);
1337
+	}
1338
+
1339
+
1340
+	/**
1341
+	 * This method is called to inject nav tabs on core WP cpt pages
1342
+	 *
1343
+	 * @access public
1344
+	 * @return void
1345
+	 */
1346
+	public function inject_nav_tabs()
1347
+	{
1348
+		// can we hijack and insert the nav_tabs?
1349
+		$nav_tabs = $this->_get_main_nav_tabs();
1350
+		// first close off existing form tag
1351
+		$html = '>';
1352
+		$html .= $nav_tabs;
1353
+		// now let's handle the remaining tag ( missing ">" is CORRECT )
1354
+		$html .= '<span></span';
1355
+		echo $html;
1356
+	}
1357
+
1358
+
1359
+	/**
1360
+	 * This just sets up the post update messages when an update form is loaded
1361
+	 *
1362
+	 * @access public
1363
+	 * @param  array $messages the original messages array
1364
+	 * @return array           the new messages array
1365
+	 */
1366
+	public function post_update_messages($messages)
1367
+	{
1368
+		global $post;
1369
+		$id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1370
+		$id = empty($id) && is_object($post) ? $post->ID : null;
1371
+		/*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1372 1372
 
1373 1373
         $route_to_check = $post_type && isset( $this->_cpt_routes[$current_route]) ? $this->_cpt_routes[$current_route] : '';/**/
1374
-        $messages[ $post->post_type ] = array(
1375
-            0  => '', // Unused. Messages start at index 1.
1376
-            1  => sprintf(
1377
-                __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1378
-                $this->_cpt_object->labels->singular_name,
1379
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1380
-                '</a>'
1381
-            ),
1382
-            2  => __('Custom field updated', 'event_espresso'),
1383
-            3  => __('Custom field deleted.', 'event_espresso'),
1384
-            4  => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1385
-            5  => isset($_GET['revision']) ? sprintf(
1386
-                __('%s restored to revision from %s', 'event_espresso'),
1387
-                $this->_cpt_object->labels->singular_name,
1388
-                wp_post_revision_title((int) $_GET['revision'], false)
1389
-            )
1390
-                : false,
1391
-            6  => sprintf(
1392
-                __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1393
-                $this->_cpt_object->labels->singular_name,
1394
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1395
-                '</a>'
1396
-            ),
1397
-            7  => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1398
-            8  => sprintf(
1399
-                __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1400
-                $this->_cpt_object->labels->singular_name,
1401
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1402
-                '</a>'
1403
-            ),
1404
-            9  => sprintf(
1405
-                __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1406
-                $this->_cpt_object->labels->singular_name,
1407
-                '<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1408
-                '<a target="_blank" href="' . esc_url(get_permalink($id)),
1409
-                '</a>'
1410
-            ),
1411
-            10 => sprintf(
1412
-                __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1413
-                $this->_cpt_object->labels->singular_name,
1414
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1415
-                '</a>'
1416
-            ),
1417
-        );
1418
-        return $messages;
1419
-    }
1420
-
1421
-
1422
-    /**
1423
-     * default method for the 'create_new' route for cpt admin pages.
1424
-     * For reference what to include in here, see wp-admin/post-new.php
1425
-     *
1426
-     * @access  protected
1427
-     * @return void
1428
-     */
1429
-    protected function _create_new_cpt_item()
1430
-    {
1431
-        // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1432
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1433
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1434
-        $post_type_object = $this->_cpt_object;
1435
-        $title = $post_type_object->labels->add_new_item;
1436
-        $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1437
-        add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1438
-        // modify the default editor title field with default title.
1439
-        add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1440
-        $this->loadEditorTemplate(true);
1441
-    }
1442
-
1443
-
1444
-    /**
1445
-     * Enqueues auto-save and loads the editor template
1446
-     *
1447
-     * @param bool $creating
1448
-     */
1449
-    private function loadEditorTemplate($creating = true)
1450
-    {
1451
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1452
-        // these vars are used by the template
1453
-        $editing = true;
1454
-        $post_ID = $post->ID;
1455
-        if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1456
-            // only enqueue autosave when creating event (necessary to get permalink/url generated)
1457
-            // otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1458
-            if ($creating) {
1459
-                wp_enqueue_script('autosave');
1460
-            } else {
1461
-                if (isset($this->_cpt_routes[ $this->_req_data['action'] ])
1462
-                    && ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1463
-                ) {
1464
-                    $create_new_action = apply_filters(
1465
-                        'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1466
-                        'create_new',
1467
-                        $this
1468
-                    );
1469
-                    $post_new_file = EE_Admin_Page::add_query_args_and_nonce(
1470
-                        array(
1471
-                            'action' => $create_new_action,
1472
-                            'page'   => $this->page_slug,
1473
-                        ),
1474
-                        'admin.php'
1475
-                    );
1476
-                }
1477
-            }
1478
-            include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1479
-        }
1480
-    }
1481
-
1482
-
1483
-    public function add_new_admin_page_global()
1484
-    {
1485
-        $admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1486
-        ?>
1374
+		$messages[ $post->post_type ] = array(
1375
+			0  => '', // Unused. Messages start at index 1.
1376
+			1  => sprintf(
1377
+				__('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1378
+				$this->_cpt_object->labels->singular_name,
1379
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1380
+				'</a>'
1381
+			),
1382
+			2  => __('Custom field updated', 'event_espresso'),
1383
+			3  => __('Custom field deleted.', 'event_espresso'),
1384
+			4  => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1385
+			5  => isset($_GET['revision']) ? sprintf(
1386
+				__('%s restored to revision from %s', 'event_espresso'),
1387
+				$this->_cpt_object->labels->singular_name,
1388
+				wp_post_revision_title((int) $_GET['revision'], false)
1389
+			)
1390
+				: false,
1391
+			6  => sprintf(
1392
+				__('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1393
+				$this->_cpt_object->labels->singular_name,
1394
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1395
+				'</a>'
1396
+			),
1397
+			7  => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1398
+			8  => sprintf(
1399
+				__('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1400
+				$this->_cpt_object->labels->singular_name,
1401
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1402
+				'</a>'
1403
+			),
1404
+			9  => sprintf(
1405
+				__('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1406
+				$this->_cpt_object->labels->singular_name,
1407
+				'<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1408
+				'<a target="_blank" href="' . esc_url(get_permalink($id)),
1409
+				'</a>'
1410
+			),
1411
+			10 => sprintf(
1412
+				__('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1413
+				$this->_cpt_object->labels->singular_name,
1414
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1415
+				'</a>'
1416
+			),
1417
+		);
1418
+		return $messages;
1419
+	}
1420
+
1421
+
1422
+	/**
1423
+	 * default method for the 'create_new' route for cpt admin pages.
1424
+	 * For reference what to include in here, see wp-admin/post-new.php
1425
+	 *
1426
+	 * @access  protected
1427
+	 * @return void
1428
+	 */
1429
+	protected function _create_new_cpt_item()
1430
+	{
1431
+		// gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1432
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1433
+		$post_type = $this->_cpt_routes[ $this->_req_action ];
1434
+		$post_type_object = $this->_cpt_object;
1435
+		$title = $post_type_object->labels->add_new_item;
1436
+		$post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1437
+		add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1438
+		// modify the default editor title field with default title.
1439
+		add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1440
+		$this->loadEditorTemplate(true);
1441
+	}
1442
+
1443
+
1444
+	/**
1445
+	 * Enqueues auto-save and loads the editor template
1446
+	 *
1447
+	 * @param bool $creating
1448
+	 */
1449
+	private function loadEditorTemplate($creating = true)
1450
+	{
1451
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1452
+		// these vars are used by the template
1453
+		$editing = true;
1454
+		$post_ID = $post->ID;
1455
+		if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1456
+			// only enqueue autosave when creating event (necessary to get permalink/url generated)
1457
+			// otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1458
+			if ($creating) {
1459
+				wp_enqueue_script('autosave');
1460
+			} else {
1461
+				if (isset($this->_cpt_routes[ $this->_req_data['action'] ])
1462
+					&& ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1463
+				) {
1464
+					$create_new_action = apply_filters(
1465
+						'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1466
+						'create_new',
1467
+						$this
1468
+					);
1469
+					$post_new_file = EE_Admin_Page::add_query_args_and_nonce(
1470
+						array(
1471
+							'action' => $create_new_action,
1472
+							'page'   => $this->page_slug,
1473
+						),
1474
+						'admin.php'
1475
+					);
1476
+				}
1477
+			}
1478
+			include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1479
+		}
1480
+	}
1481
+
1482
+
1483
+	public function add_new_admin_page_global()
1484
+	{
1485
+		$admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1486
+		?>
1487 1487
         <script type="text/javascript">
1488 1488
             adminpage = '<?php echo $admin_page; ?>';
1489 1489
         </script>
1490 1490
         <?php
1491
-    }
1492
-
1493
-
1494
-    /**
1495
-     * default method for the 'edit' route for cpt admin pages
1496
-     * For reference on what to put in here, refer to wp-admin/post.php
1497
-     *
1498
-     * @access protected
1499
-     * @return string   template for edit cpt form
1500
-     */
1501
-    protected function _edit_cpt_item()
1502
-    {
1503
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1504
-        $post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1505
-        $post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1506
-        if (empty($post)) {
1507
-            wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'event_espresso'));
1508
-        }
1509
-        if (! empty($_GET['get-post-lock'])) {
1510
-            wp_set_post_lock($post_id);
1511
-            wp_redirect(get_edit_post_link($post_id, 'url'));
1512
-            exit();
1513
-        }
1514
-
1515
-        // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1516
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1517
-        $post_type_object = $this->_cpt_object;
1518
-
1519
-        if (! wp_check_post_lock($post->ID)) {
1520
-            wp_set_post_lock($post->ID);
1521
-        }
1522
-        add_action('admin_footer', '_admin_notice_post_locked');
1523
-        if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1524
-            wp_enqueue_script('admin-comments');
1525
-            enqueue_comment_hotkeys_js();
1526
-        }
1527
-        add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1528
-        // modify the default editor title field with default title.
1529
-        add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1530
-        $this->loadEditorTemplate(false);
1531
-    }
1532
-
1533
-
1534
-
1535
-    /**
1536
-     * some getters
1537
-     */
1538
-    /**
1539
-     * This returns the protected _cpt_model_obj property
1540
-     *
1541
-     * @return EE_CPT_Base
1542
-     */
1543
-    public function get_cpt_model_obj()
1544
-    {
1545
-        return $this->_cpt_model_obj;
1546
-    }
1491
+	}
1492
+
1493
+
1494
+	/**
1495
+	 * default method for the 'edit' route for cpt admin pages
1496
+	 * For reference on what to put in here, refer to wp-admin/post.php
1497
+	 *
1498
+	 * @access protected
1499
+	 * @return string   template for edit cpt form
1500
+	 */
1501
+	protected function _edit_cpt_item()
1502
+	{
1503
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1504
+		$post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1505
+		$post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1506
+		if (empty($post)) {
1507
+			wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'event_espresso'));
1508
+		}
1509
+		if (! empty($_GET['get-post-lock'])) {
1510
+			wp_set_post_lock($post_id);
1511
+			wp_redirect(get_edit_post_link($post_id, 'url'));
1512
+			exit();
1513
+		}
1514
+
1515
+		// template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1516
+		$post_type = $this->_cpt_routes[ $this->_req_action ];
1517
+		$post_type_object = $this->_cpt_object;
1518
+
1519
+		if (! wp_check_post_lock($post->ID)) {
1520
+			wp_set_post_lock($post->ID);
1521
+		}
1522
+		add_action('admin_footer', '_admin_notice_post_locked');
1523
+		if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1524
+			wp_enqueue_script('admin-comments');
1525
+			enqueue_comment_hotkeys_js();
1526
+		}
1527
+		add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1528
+		// modify the default editor title field with default title.
1529
+		add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1530
+		$this->loadEditorTemplate(false);
1531
+	}
1532
+
1533
+
1534
+
1535
+	/**
1536
+	 * some getters
1537
+	 */
1538
+	/**
1539
+	 * This returns the protected _cpt_model_obj property
1540
+	 *
1541
+	 * @return EE_CPT_Base
1542
+	 */
1543
+	public function get_cpt_model_obj()
1544
+	{
1545
+		return $this->_cpt_model_obj;
1546
+	}
1547 1547
 }
Please login to merge, or discard this patch.