Completed
Branch BUG/paypal-express-and-plus-si... (e7d603)
by
unknown
26:58 queued 17:36
created
caffeinated/payment_methods/Aim/EEG_Aim.gateway.php 4 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,5 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-use EventEspresso\core\services\formatters\AsciiOnly;
4 3
 use EventEspresso\core\services\loaders\LoaderFactory;
5 4
 
6 5
 /**
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -216,7 +216,7 @@  discard block
 block discarded – undo
216 216
                     $line_item->unit_price(),
217 217
                     'N'
218 218
                 );
219
-                $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', ';
219
+                $order_description .= $this->prepareStringForAuthnet($line_item->desc()).', ';
220 220
             }
221 221
             foreach ($total_line_item->tax_descendants() as $tax_line_item) {
222 222
                 $this->addLineItem(
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
         // invoice_num would be nice to have it be unique per SPCO page-load, that way if users
255 255
         // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page
256 256
         // in which case, we need to generate teh invoice num per request right here...
257
-        $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
257
+        $this->setField('invoice_num', wp_generate_password(12, false)); // $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
258 258
         // tell AIM that any duplicates sent in the next 5 minutes are to be ignored
259 259
         $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS);
260 260
 
@@ -265,7 +265,7 @@  discard block
 block discarded – undo
265 265
         // Capture response
266 266
         $this->type = "AUTH_CAPTURE";
267 267
         $response = $this->_sendRequest($payment);
268
-        if (! empty($response)) {
268
+        if ( ! empty($response)) {
269 269
             if ($response->error_message) {
270 270
                 $payment->set_status($this->_pay_model->failed_status());
271 271
                 $payment->set_gateway_response($response->error_message);
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
     protected function _set_sensitive_billing_data($billing_info)
312 312
     {
313 313
         $this->setField('card_num', $billing_info['credit_card']);
314
-        $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']);
314
+        $this->setField('exp_date', $billing_info['exp_month'].$billing_info['exp_year']);
315 315
         $this->setField('card_code', $billing_info['cvv']);
316 316
     }
317 317
 
@@ -351,7 +351,7 @@  discard block
 block discarded – undo
351 351
     protected function setField($name, $value)
352 352
     {
353 353
         if (in_array($name, $this->_all_aim_fields)) {
354
-            $this->_x_post_fields[ $name ] = $value;
354
+            $this->_x_post_fields[$name] = $value;
355 355
         } else {
356 356
             throw new AuthorizeNetException("Error: no field $name exists in the AIM API.
357 357
             To set a custom field use setCustomField('field','value') instead.");
@@ -371,11 +371,11 @@  discard block
 block discarded – undo
371 371
         $this->_x_post_fields['tran_key'] = $this->_transaction_key;
372 372
         $x_keys = array();
373 373
         foreach ($this->_x_post_fields as $key => $value) {
374
-            $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value));
374
+            $x_keys[] = "x_$key=".urlencode($this->_get_unsupported_character_remover()->format($value));
375 375
         }
376 376
         // Add line items
377 377
         foreach ($this->_additional_line_items as $key => $value) {
378
-            $x_keys[] =  "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value));
378
+            $x_keys[] = "x_line_item=".urlencode($this->_get_unsupported_character_remover()->format($value));
379 379
         }
380 380
         $this->_log_clean_request($x_keys, $payment);
381 381
         $post_url = $this->_get_server_url();
@@ -387,7 +387,7 @@  discard block
 block discarded – undo
387 387
         curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
388 388
         curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);
389 389
         if ($this->VERIFY_PEER) {
390
-            curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem');
390
+            curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__).'/ssl/cert.pem');
391 391
         } else {
392 392
             curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
393 393
         }
@@ -399,7 +399,7 @@  discard block
 block discarded – undo
399 399
         $response = curl_exec($curl_request);
400 400
 
401 401
         curl_close($curl_request);
402
-        $response_obj =  new EE_AuthorizeNetAIM_Response($response);
402
+        $response_obj = new EE_AuthorizeNetAIM_Response($response);
403 403
 
404 404
         return $this->_log_and_clean_response($response_obj, $payment);
405 405
     }
@@ -419,7 +419,7 @@  discard block
 block discarded – undo
419 419
                 if (strpos($keyvaltogether, $key) === 0) {
420 420
                     // found it at the first character
421 421
                     // so its one of them
422
-                    unset($request_array[ $index ]);
422
+                    unset($request_array[$index]);
423 423
                 }
424 424
             }
425 425
         }
@@ -560,7 +560,7 @@  discard block
 block discarded – undo
560 560
             // Split Array
561 561
             $this->response = $response;
562 562
             if ($encap_char) {
563
-                $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1));
563
+                $this->_response_array = explode($encap_char.$delimiter.$encap_char, substr($response, 1, -1));
564 564
             } else {
565 565
                 $this->_response_array = explode($delimiter, $response);
566 566
             }
@@ -642,7 +642,7 @@  discard block
 block discarded – undo
642 642
     }
643 643
 }
644 644
 
645
-if (! class_exists('AuthorizeNetException')) {
645
+if ( ! class_exists('AuthorizeNetException')) {
646 646
     /**
647 647
      * Class AuthorizeNetException
648 648
      *
Please login to merge, or discard this patch.
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -362,7 +362,7 @@  discard block
 block discarded – undo
362 362
     /**
363 363
      * Posts the request to AuthorizeNet & returns response.
364 364
      *
365
-     * @param $payment
365
+     * @param EEI_Payment $payment
366 366
      * @return \EE_AuthorizeNetAIM_Response
367 367
      */
368 368
     private function _sendRequest($payment)
@@ -451,7 +451,7 @@  discard block
 block discarded – undo
451 451
     /**
452 452
      * Removes characters Authorize.net doesn't handle well.
453 453
      * @since 4.9.82.p
454
-     * @param $text
454
+     * @param string $text
455 455
      * @return string
456 456
      */
457 457
     private function prepareStringForAuthnet($text)
Please login to merge, or discard this patch.
Indentation   +620 added lines, -620 removed lines patch added patch discarded remove patch
@@ -26,442 +26,442 @@  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 $_server;
38
-
39
-    protected $_currencies_supported = array(
40
-        'AUD',
41
-        'USD',
42
-        'CAD',
43
-        'EUR',
44
-        'GBP',
45
-        'NZD',
46
-    );
47
-
48
-    /**
49
-     * Whether to send test transactions (even to live site)
50
-     *
51
-     * @var boolean
52
-     */
53
-    protected $_test_transactions;
54
-
55
-    private $VERIFY_PEER = false;
56
-
57
-    private $_x_post_fields = array(
58
-        "version"        => "3.1",
59
-        "delim_char"     => ",",
60
-        "delim_data"     => "TRUE",
61
-        "relay_response" => "FALSE",
62
-        "encap_char"     => "|",
63
-    );
64
-
65
-    private $_additional_line_items = array();
66
-
67
-    /**
68
-     * A list of all fields in the AIM API.
69
-     * Used to warn user if they try to set a field not offered in the API.
70
-     */
71
-    private $_all_aim_fields = array(
72
-        "address",
73
-        "allow_partial_auth",
74
-        "amount",
75
-        "auth_code",
76
-        "authentication_indicator",
77
-        "bank_aba_code",
78
-        "bank_acct_name",
79
-        "bank_acct_num",
80
-        "bank_acct_type",
81
-        "bank_check_number",
82
-        "bank_name",
83
-        "card_code",
84
-        "card_num",
85
-        "cardholder_authentication_value",
86
-        "city",
87
-        "company",
88
-        "country",
89
-        "cust_id",
90
-        "customer_ip",
91
-        "delim_char",
92
-        "delim_data",
93
-        "description",
94
-        "duplicate_window",
95
-        "duty",
96
-        "echeck_type",
97
-        "email",
98
-        "email_customer",
99
-        "encap_char",
100
-        "exp_date",
101
-        "fax",
102
-        "first_name",
103
-        "footer_email_receipt",
104
-        "freight",
105
-        "header_email_receipt",
106
-        "invoice_num",
107
-        "last_name",
108
-        "line_item",
109
-        "login",
110
-        "method",
111
-        "phone",
112
-        "po_num",
113
-        "recurring_billing",
114
-        "relay_response",
115
-        "ship_to_address",
116
-        "ship_to_city",
117
-        "ship_to_company",
118
-        "ship_to_country",
119
-        "ship_to_first_name",
120
-        "ship_to_last_name",
121
-        "ship_to_state",
122
-        "ship_to_zip",
123
-        "split_tender_id",
124
-        "state",
125
-        "tax",
126
-        "tax_exempt",
127
-        "test_request",
128
-        "tran_key",
129
-        "trans_id",
130
-        "type",
131
-        "version",
132
-        "zip",
133
-        "solution_id",
134
-        "currency_code"
135
-    );
136
-
137
-
138
-    /**
139
-     * Gets the URL where the request should go. This is filterable
140
-     *
141
-     * @return string
142
-     */
143
-    protected function _get_server_url()
144
-    {
145
-        return apply_filters(
146
-            'FHEE__EEG_Aim___get_server_url',
147
-            $this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL,
148
-            $this
149
-        );
150
-    }
151
-
152
-
153
-    /**
154
-     * TEMPORARY CALLBACK! Do not use
155
-     * Callback which filters the server url. This is added so site admins can revert to using
156
-     * the old AIM server in case Akamai service breaks their integration.
157
-     * Using Akamai will, however, be mandatory on June 30th 2016 Authorize.net
158
-     * (see http://www.authorize.net/support/akamaifaqs/#firewall?utm_campaign=April%202016%20Technical%20Updates%20for%20Merchants.html&utm_medium=email&utm_source=Eloqua&elqTrackId=46103bdc375c411a979c2f658fc99074&elq=7026706360154fee9b6d588b27d8eb6a&elqaid=506&elqat=1&elqCampaignId=343)
159
-     * Once that happens, this will be obsolete and WILL BE REMOVED.
160
-     *
161
-     * @param string $url
162
-     * @param EEG_Aim $gateway_object
163
-     * @return string
164
-     */
165
-    public function possibly_use_deprecated_aim_server($url, EEG_Aim $gateway_object)
166
-    {
167
-        if ($gateway_object->_server === 'authorize.net' && ! $gateway_object->_debug_mode) {
168
-            return 'https://secure.authorize.net/gateway/transact.dll';
169
-        } else {
170
-            return $url;
171
-        }
172
-    }
173
-
174
-
175
-    /**
176
-     * Asks the gateway to do whatever it does to process the payment. Onsite gateways will
177
-     * usually send a request directly to the payment provider and update the payment's status based on that;
178
-     * whereas offsite gateways will usually just update the payment with the URL and query parameters to use
179
-     * for sending the request via http_remote_request()
180
-     *
181
-     * @param EEI_Payment $payment
182
-     * @param array $billing_info {
183
-     *  @type $credit_card string
184
-     *  @type $cvv string
185
-     *  @type $exp_month string
186
-     *  @type $exp_year string
187
-     *  @see parent::do_direct_payment
188
-     * }
189
-     * @return EEI_Payment updated
190
-     */
191
-    public function do_direct_payment($payment, $billing_info = null)
192
-    {
193
-        add_filter('FHEE__EEG_Aim___get_server_url', array($this, 'possibly_use_deprecated_aim_server'), 10, 2);
194
-        // Enable test mode if needed
195
-        // 4007000000027  <-- test successful visa
196
-        // 4222222222222  <-- test failure card number
197
-
198
-        $item_num = 1;
199
-        $transaction = $payment->transaction();
200
-        $gateway_formatter = $this->_get_gateway_formatter();
201
-        $order_description = $this->prepareStringForAuthnet($gateway_formatter->formatOrderDescription($payment));
202
-        $primary_registrant = $transaction->primary_registration();
203
-        // if we're are charging for the full amount, show the normal line items
204
-        // and the itemized total adds up properly
205
-        if ($this->_can_easily_itemize_transaction_for($payment)) {
206
-            $total_line_item = $transaction->total_line_item();
207
-            foreach ($total_line_item->get_items() as $line_item) {
208
-                if ($line_item->quantity() == 0) {
209
-                    continue;
210
-                }
211
-                $this->addLineItem(
212
-                    $item_num++,
213
-                    $gateway_formatter->formatLineItemName($line_item, $payment),
214
-                    $gateway_formatter->formatLineItemDesc($line_item, $payment),
215
-                    $line_item->quantity(),
216
-                    $line_item->unit_price(),
217
-                    'N'
218
-                );
219
-                $order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', ';
220
-            }
221
-            foreach ($total_line_item->tax_descendants() as $tax_line_item) {
222
-                $this->addLineItem(
223
-                    $item_num++,
224
-                    $tax_line_item->name(),
225
-                    $tax_line_item->desc(),
226
-                    1,
227
-                    $tax_line_item->total(),
228
-                    'N'
229
-                );
230
-            }
231
-        }
232
-
233
-        // start transaction
234
-        // if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id
235
-        $partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363';
236
-        $this->setField('solution_id', $partner_id);
237
-        $this->setField('amount', $gateway_formatter->formatCurrency($payment->amount()));
238
-        $this->setField('description', substr(rtrim($order_description, ', '), 0, 255));
239
-        $this->_set_sensitive_billing_data($billing_info);
240
-        $this->setField('first_name', $billing_info['first_name']);
241
-        $this->setField('last_name', $billing_info['last_name']);
242
-        $this->setField('email', $billing_info['email']);
243
-        $this->setField('company', $billing_info['company']);
244
-        $this->setField('address', $billing_info['address'].' '.$billing_info['address2']);
245
-        $this->setField('city', $billing_info['city']);
246
-        $this->setField('state', $billing_info['state']);
247
-        $this->setField('country', $billing_info['country']);
248
-        $this->setField('zip', $billing_info['zip']);
249
-        $this->setField('fax', $billing_info['fax']);
250
-        $this->setField('cust_id', $primary_registrant->ID());
251
-        $this->setField('phone', $billing_info['phone']);
252
-        $currency_config = LoaderFactory::getLoader()->load('EE_Currency_Config');
253
-        $this->setField('currency_code', $currency_config->code);
254
-        // invoice_num would be nice to have it be unique per SPCO page-load, that way if users
255
-        // press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page
256
-        // in which case, we need to generate teh invoice num per request right here...
257
-        $this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
258
-        // tell AIM that any duplicates sent in the next 5 minutes are to be ignored
259
-        $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS);
260
-
261
-        if ($this->_test_transactions) {
262
-            $this->test_request = "true";
263
-        }
264
-
265
-        // Capture response
266
-        $this->type = "AUTH_CAPTURE";
267
-        $response = $this->_sendRequest($payment);
268
-        if (! empty($response)) {
269
-            if ($response->error_message) {
270
-                $payment->set_status($this->_pay_model->failed_status());
271
-                $payment->set_gateway_response($response->error_message);
272
-            } else {
273
-                $payment_status = $response->approved
274
-                    ? $this->_pay_model->approved_status()
275
-                    : $this->_pay_model->declined_status();
276
-                $payment->set_status($payment_status);
277
-                // make sure we interpret the AMT as a float, not an international string (where periods are thousand separators)
278
-                $payment->set_amount((float) $response->amount);
279
-                $payment->set_gateway_response(
280
-                    sprintf(
281
-                        esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'),
282
-                        $response->response_reason_text,
283
-                        $response->response_reason_code
284
-                    )
285
-                );
286
-                if ($this->_debug_mode) {
287
-                    $txn_id = $response->invoice_number;
288
-                } else {
289
-                    $txn_id = $response->transaction_id;
290
-                }
291
-                $payment->set_txn_id_chq_nmbr($txn_id);
292
-            }
293
-            $payment->set_extra_accntng($primary_registrant->reg_code());
294
-            $payment->set_details(print_r($response, true));
295
-        } else {
296
-            $payment->set_status($this->_pay_model->failed_status());
297
-            $payment->set_gateway_response(__("There was no response from Authorize.net", 'event_espresso'));
298
-            $payment->set_details(print_r($response, true));
299
-        }
300
-        return $payment;
301
-    }
302
-
303
-
304
-    /**
305
-     * Sets billing data for the upcoming request to AIM that is considered sensitive;
306
-     * also this method can be overridden by children classes to easily change
307
-     * what billing data gets sent
308
-     *
309
-     * @param array $billing_info
310
-     */
311
-    protected function _set_sensitive_billing_data($billing_info)
312
-    {
313
-        $this->setField('card_num', $billing_info['credit_card']);
314
-        $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']);
315
-        $this->setField('card_code', $billing_info['cvv']);
316
-    }
317
-
318
-
319
-    /**
320
-     * Add a line item.
321
-     *
322
-     * @param string $item_id
323
-     * @param string $item_name
324
-     * @param string $item_description
325
-     * @param string $item_quantity
326
-     * @param string $item_unit_price
327
-     * @param string $item_taxable
328
-     */
329
-    public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable)
330
-    {
331
-        $args = array(
332
-            substr($item_id, 0, 31),
333
-            substr($this->prepareStringForAuthnet($item_name), 0, 31),
334
-            substr($this->prepareStringForAuthnet($item_description), 0, 255),
335
-            number_format(abs($item_quantity), 2, '.', ''),
336
-            number_format(abs($item_unit_price), 2, '.', ''),
337
-            $item_taxable === 'N' ? 'N' : 'Y'
338
-        );
339
-        $this->_additional_line_items[] = implode('<|>', $args);
340
-    }
341
-
342
-
343
-    /**
344
-     * Set an individual name/value pair. This will append x_ to the name
345
-     * before posting.
346
-     *
347
-     * @param string $name
348
-     * @param string $value
349
-     * @throws AuthorizeNetException
350
-     */
351
-    protected function setField($name, $value)
352
-    {
353
-        if (in_array($name, $this->_all_aim_fields)) {
354
-            $this->_x_post_fields[ $name ] = $value;
355
-        } else {
356
-            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 $_server;
38
+
39
+	protected $_currencies_supported = array(
40
+		'AUD',
41
+		'USD',
42
+		'CAD',
43
+		'EUR',
44
+		'GBP',
45
+		'NZD',
46
+	);
47
+
48
+	/**
49
+	 * Whether to send test transactions (even to live site)
50
+	 *
51
+	 * @var boolean
52
+	 */
53
+	protected $_test_transactions;
54
+
55
+	private $VERIFY_PEER = false;
56
+
57
+	private $_x_post_fields = array(
58
+		"version"        => "3.1",
59
+		"delim_char"     => ",",
60
+		"delim_data"     => "TRUE",
61
+		"relay_response" => "FALSE",
62
+		"encap_char"     => "|",
63
+	);
64
+
65
+	private $_additional_line_items = array();
66
+
67
+	/**
68
+	 * A list of all fields in the AIM API.
69
+	 * Used to warn user if they try to set a field not offered in the API.
70
+	 */
71
+	private $_all_aim_fields = array(
72
+		"address",
73
+		"allow_partial_auth",
74
+		"amount",
75
+		"auth_code",
76
+		"authentication_indicator",
77
+		"bank_aba_code",
78
+		"bank_acct_name",
79
+		"bank_acct_num",
80
+		"bank_acct_type",
81
+		"bank_check_number",
82
+		"bank_name",
83
+		"card_code",
84
+		"card_num",
85
+		"cardholder_authentication_value",
86
+		"city",
87
+		"company",
88
+		"country",
89
+		"cust_id",
90
+		"customer_ip",
91
+		"delim_char",
92
+		"delim_data",
93
+		"description",
94
+		"duplicate_window",
95
+		"duty",
96
+		"echeck_type",
97
+		"email",
98
+		"email_customer",
99
+		"encap_char",
100
+		"exp_date",
101
+		"fax",
102
+		"first_name",
103
+		"footer_email_receipt",
104
+		"freight",
105
+		"header_email_receipt",
106
+		"invoice_num",
107
+		"last_name",
108
+		"line_item",
109
+		"login",
110
+		"method",
111
+		"phone",
112
+		"po_num",
113
+		"recurring_billing",
114
+		"relay_response",
115
+		"ship_to_address",
116
+		"ship_to_city",
117
+		"ship_to_company",
118
+		"ship_to_country",
119
+		"ship_to_first_name",
120
+		"ship_to_last_name",
121
+		"ship_to_state",
122
+		"ship_to_zip",
123
+		"split_tender_id",
124
+		"state",
125
+		"tax",
126
+		"tax_exempt",
127
+		"test_request",
128
+		"tran_key",
129
+		"trans_id",
130
+		"type",
131
+		"version",
132
+		"zip",
133
+		"solution_id",
134
+		"currency_code"
135
+	);
136
+
137
+
138
+	/**
139
+	 * Gets the URL where the request should go. This is filterable
140
+	 *
141
+	 * @return string
142
+	 */
143
+	protected function _get_server_url()
144
+	{
145
+		return apply_filters(
146
+			'FHEE__EEG_Aim___get_server_url',
147
+			$this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL,
148
+			$this
149
+		);
150
+	}
151
+
152
+
153
+	/**
154
+	 * TEMPORARY CALLBACK! Do not use
155
+	 * Callback which filters the server url. This is added so site admins can revert to using
156
+	 * the old AIM server in case Akamai service breaks their integration.
157
+	 * Using Akamai will, however, be mandatory on June 30th 2016 Authorize.net
158
+	 * (see http://www.authorize.net/support/akamaifaqs/#firewall?utm_campaign=April%202016%20Technical%20Updates%20for%20Merchants.html&utm_medium=email&utm_source=Eloqua&elqTrackId=46103bdc375c411a979c2f658fc99074&elq=7026706360154fee9b6d588b27d8eb6a&elqaid=506&elqat=1&elqCampaignId=343)
159
+	 * Once that happens, this will be obsolete and WILL BE REMOVED.
160
+	 *
161
+	 * @param string $url
162
+	 * @param EEG_Aim $gateway_object
163
+	 * @return string
164
+	 */
165
+	public function possibly_use_deprecated_aim_server($url, EEG_Aim $gateway_object)
166
+	{
167
+		if ($gateway_object->_server === 'authorize.net' && ! $gateway_object->_debug_mode) {
168
+			return 'https://secure.authorize.net/gateway/transact.dll';
169
+		} else {
170
+			return $url;
171
+		}
172
+	}
173
+
174
+
175
+	/**
176
+	 * Asks the gateway to do whatever it does to process the payment. Onsite gateways will
177
+	 * usually send a request directly to the payment provider and update the payment's status based on that;
178
+	 * whereas offsite gateways will usually just update the payment with the URL and query parameters to use
179
+	 * for sending the request via http_remote_request()
180
+	 *
181
+	 * @param EEI_Payment $payment
182
+	 * @param array $billing_info {
183
+	 *  @type $credit_card string
184
+	 *  @type $cvv string
185
+	 *  @type $exp_month string
186
+	 *  @type $exp_year string
187
+	 *  @see parent::do_direct_payment
188
+	 * }
189
+	 * @return EEI_Payment updated
190
+	 */
191
+	public function do_direct_payment($payment, $billing_info = null)
192
+	{
193
+		add_filter('FHEE__EEG_Aim___get_server_url', array($this, 'possibly_use_deprecated_aim_server'), 10, 2);
194
+		// Enable test mode if needed
195
+		// 4007000000027  <-- test successful visa
196
+		// 4222222222222  <-- test failure card number
197
+
198
+		$item_num = 1;
199
+		$transaction = $payment->transaction();
200
+		$gateway_formatter = $this->_get_gateway_formatter();
201
+		$order_description = $this->prepareStringForAuthnet($gateway_formatter->formatOrderDescription($payment));
202
+		$primary_registrant = $transaction->primary_registration();
203
+		// if we're are charging for the full amount, show the normal line items
204
+		// and the itemized total adds up properly
205
+		if ($this->_can_easily_itemize_transaction_for($payment)) {
206
+			$total_line_item = $transaction->total_line_item();
207
+			foreach ($total_line_item->get_items() as $line_item) {
208
+				if ($line_item->quantity() == 0) {
209
+					continue;
210
+				}
211
+				$this->addLineItem(
212
+					$item_num++,
213
+					$gateway_formatter->formatLineItemName($line_item, $payment),
214
+					$gateway_formatter->formatLineItemDesc($line_item, $payment),
215
+					$line_item->quantity(),
216
+					$line_item->unit_price(),
217
+					'N'
218
+				);
219
+				$order_description .= $this->prepareStringForAuthnet($line_item->desc()) . ', ';
220
+			}
221
+			foreach ($total_line_item->tax_descendants() as $tax_line_item) {
222
+				$this->addLineItem(
223
+					$item_num++,
224
+					$tax_line_item->name(),
225
+					$tax_line_item->desc(),
226
+					1,
227
+					$tax_line_item->total(),
228
+					'N'
229
+				);
230
+			}
231
+		}
232
+
233
+		// start transaction
234
+		// if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id
235
+		$partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363';
236
+		$this->setField('solution_id', $partner_id);
237
+		$this->setField('amount', $gateway_formatter->formatCurrency($payment->amount()));
238
+		$this->setField('description', substr(rtrim($order_description, ', '), 0, 255));
239
+		$this->_set_sensitive_billing_data($billing_info);
240
+		$this->setField('first_name', $billing_info['first_name']);
241
+		$this->setField('last_name', $billing_info['last_name']);
242
+		$this->setField('email', $billing_info['email']);
243
+		$this->setField('company', $billing_info['company']);
244
+		$this->setField('address', $billing_info['address'].' '.$billing_info['address2']);
245
+		$this->setField('city', $billing_info['city']);
246
+		$this->setField('state', $billing_info['state']);
247
+		$this->setField('country', $billing_info['country']);
248
+		$this->setField('zip', $billing_info['zip']);
249
+		$this->setField('fax', $billing_info['fax']);
250
+		$this->setField('cust_id', $primary_registrant->ID());
251
+		$this->setField('phone', $billing_info['phone']);
252
+		$currency_config = LoaderFactory::getLoader()->load('EE_Currency_Config');
253
+		$this->setField('currency_code', $currency_config->code);
254
+		// invoice_num would be nice to have it be unique per SPCO page-load, that way if users
255
+		// press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page
256
+		// in which case, we need to generate teh invoice num per request right here...
257
+		$this->setField('invoice_num', wp_generate_password(12, false));// $billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
258
+		// tell AIM that any duplicates sent in the next 5 minutes are to be ignored
259
+		$this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS);
260
+
261
+		if ($this->_test_transactions) {
262
+			$this->test_request = "true";
263
+		}
264
+
265
+		// Capture response
266
+		$this->type = "AUTH_CAPTURE";
267
+		$response = $this->_sendRequest($payment);
268
+		if (! empty($response)) {
269
+			if ($response->error_message) {
270
+				$payment->set_status($this->_pay_model->failed_status());
271
+				$payment->set_gateway_response($response->error_message);
272
+			} else {
273
+				$payment_status = $response->approved
274
+					? $this->_pay_model->approved_status()
275
+					: $this->_pay_model->declined_status();
276
+				$payment->set_status($payment_status);
277
+				// make sure we interpret the AMT as a float, not an international string (where periods are thousand separators)
278
+				$payment->set_amount((float) $response->amount);
279
+				$payment->set_gateway_response(
280
+					sprintf(
281
+						esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'),
282
+						$response->response_reason_text,
283
+						$response->response_reason_code
284
+					)
285
+				);
286
+				if ($this->_debug_mode) {
287
+					$txn_id = $response->invoice_number;
288
+				} else {
289
+					$txn_id = $response->transaction_id;
290
+				}
291
+				$payment->set_txn_id_chq_nmbr($txn_id);
292
+			}
293
+			$payment->set_extra_accntng($primary_registrant->reg_code());
294
+			$payment->set_details(print_r($response, true));
295
+		} else {
296
+			$payment->set_status($this->_pay_model->failed_status());
297
+			$payment->set_gateway_response(__("There was no response from Authorize.net", 'event_espresso'));
298
+			$payment->set_details(print_r($response, true));
299
+		}
300
+		return $payment;
301
+	}
302
+
303
+
304
+	/**
305
+	 * Sets billing data for the upcoming request to AIM that is considered sensitive;
306
+	 * also this method can be overridden by children classes to easily change
307
+	 * what billing data gets sent
308
+	 *
309
+	 * @param array $billing_info
310
+	 */
311
+	protected function _set_sensitive_billing_data($billing_info)
312
+	{
313
+		$this->setField('card_num', $billing_info['credit_card']);
314
+		$this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']);
315
+		$this->setField('card_code', $billing_info['cvv']);
316
+	}
317
+
318
+
319
+	/**
320
+	 * Add a line item.
321
+	 *
322
+	 * @param string $item_id
323
+	 * @param string $item_name
324
+	 * @param string $item_description
325
+	 * @param string $item_quantity
326
+	 * @param string $item_unit_price
327
+	 * @param string $item_taxable
328
+	 */
329
+	public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable)
330
+	{
331
+		$args = array(
332
+			substr($item_id, 0, 31),
333
+			substr($this->prepareStringForAuthnet($item_name), 0, 31),
334
+			substr($this->prepareStringForAuthnet($item_description), 0, 255),
335
+			number_format(abs($item_quantity), 2, '.', ''),
336
+			number_format(abs($item_unit_price), 2, '.', ''),
337
+			$item_taxable === 'N' ? 'N' : 'Y'
338
+		);
339
+		$this->_additional_line_items[] = implode('<|>', $args);
340
+	}
341
+
342
+
343
+	/**
344
+	 * Set an individual name/value pair. This will append x_ to the name
345
+	 * before posting.
346
+	 *
347
+	 * @param string $name
348
+	 * @param string $value
349
+	 * @throws AuthorizeNetException
350
+	 */
351
+	protected function setField($name, $value)
352
+	{
353
+		if (in_array($name, $this->_all_aim_fields)) {
354
+			$this->_x_post_fields[ $name ] = $value;
355
+		} else {
356
+			throw new AuthorizeNetException("Error: no field $name exists in the AIM API.
357 357
             To set a custom field use setCustomField('field','value') instead.");
358
-        }
359
-    }
360
-
361
-
362
-    /**
363
-     * Posts the request to AuthorizeNet & returns response.
364
-     *
365
-     * @param $payment
366
-     * @return \EE_AuthorizeNetAIM_Response
367
-     */
368
-    private function _sendRequest($payment)
369
-    {
370
-        $this->_x_post_fields['login'] = $this->_login_id;
371
-        $this->_x_post_fields['tran_key'] = $this->_transaction_key;
372
-        $x_keys = array();
373
-        foreach ($this->_x_post_fields as $key => $value) {
374
-            $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value));
375
-        }
376
-        // Add line items
377
-        foreach ($this->_additional_line_items as $key => $value) {
378
-            $x_keys[] =  "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value));
379
-        }
380
-        $this->_log_clean_request($x_keys, $payment);
381
-        $post_url = $this->_get_server_url();
382
-        $curl_request = curl_init($post_url);
383
-        $post_body = implode("&", $x_keys);
384
-        curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body);
385
-        curl_setopt($curl_request, CURLOPT_HEADER, 0);
386
-        curl_setopt($curl_request, CURLOPT_TIMEOUT, 45);
387
-        curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
388
-        curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);
389
-        if ($this->VERIFY_PEER) {
390
-            curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem');
391
-        } else {
392
-            curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
393
-        }
394
-
395
-        if (preg_match('/xml/', $post_url)) {
396
-            curl_setopt($curl_request, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
397
-        }
398
-
399
-        $response = curl_exec($curl_request);
400
-
401
-        curl_close($curl_request);
402
-        $response_obj =  new EE_AuthorizeNetAIM_Response($response);
403
-
404
-        return $this->_log_and_clean_response($response_obj, $payment);
405
-    }
406
-
407
-
408
-    /**
409
-     * Logs the clean data only
410
-     *
411
-     * @param array $request_array
412
-     * @param EEI_Payment $payment
413
-     */
414
-    protected function _log_clean_request($request_array, $payment)
415
-    {
416
-        $keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date');
417
-        foreach ($request_array as $index => $keyvaltogether) {
418
-            foreach ($keys_to_filter_out as $key) {
419
-                if (strpos($keyvaltogether, $key) === 0) {
420
-                    // found it at the first character
421
-                    // so its one of them
422
-                    unset($request_array[ $index ]);
423
-                }
424
-            }
425
-        }
426
-        $this->log(
427
-            array(
428
-                'AIM Request sent:' => $request_array,
429
-                'Server URL'        => $this->_get_server_url()
430
-            ),
431
-            $payment
432
-        );
433
-    }
434
-
435
-
436
-
437
-    /**
438
-     * Logs the response and cleans it
439
-     *
440
-     * @param EE_AuthorizeNetAIM_Response $response_obj
441
-     * @param EE_Payment                  $payment
442
-     * @return \EE_AuthorizeNetAIM_Response
443
-     */
444
-    private function _log_and_clean_response($response_obj, $payment)
445
-    {
446
-        $response_obj->account_number = '';
447
-        $this->log(array('AIM Response received:' => (array) $response_obj), $payment);
448
-        return $response_obj;
449
-    }
450
-
451
-    /**
452
-     * Removes characters Authorize.net doesn't handle well.
453
-     * @since 4.9.82.p
454
-     * @param $text
455
-     * @return string
456
-     */
457
-    private function prepareStringForAuthnet($text)
458
-    {
459
-        return str_replace(
460
-            '\'',
461
-            '',
462
-            $text
463
-        );
464
-    }
358
+		}
359
+	}
360
+
361
+
362
+	/**
363
+	 * Posts the request to AuthorizeNet & returns response.
364
+	 *
365
+	 * @param $payment
366
+	 * @return \EE_AuthorizeNetAIM_Response
367
+	 */
368
+	private function _sendRequest($payment)
369
+	{
370
+		$this->_x_post_fields['login'] = $this->_login_id;
371
+		$this->_x_post_fields['tran_key'] = $this->_transaction_key;
372
+		$x_keys = array();
373
+		foreach ($this->_x_post_fields as $key => $value) {
374
+			$x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value));
375
+		}
376
+		// Add line items
377
+		foreach ($this->_additional_line_items as $key => $value) {
378
+			$x_keys[] =  "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value));
379
+		}
380
+		$this->_log_clean_request($x_keys, $payment);
381
+		$post_url = $this->_get_server_url();
382
+		$curl_request = curl_init($post_url);
383
+		$post_body = implode("&", $x_keys);
384
+		curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body);
385
+		curl_setopt($curl_request, CURLOPT_HEADER, 0);
386
+		curl_setopt($curl_request, CURLOPT_TIMEOUT, 45);
387
+		curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
388
+		curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);
389
+		if ($this->VERIFY_PEER) {
390
+			curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem');
391
+		} else {
392
+			curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
393
+		}
394
+
395
+		if (preg_match('/xml/', $post_url)) {
396
+			curl_setopt($curl_request, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
397
+		}
398
+
399
+		$response = curl_exec($curl_request);
400
+
401
+		curl_close($curl_request);
402
+		$response_obj =  new EE_AuthorizeNetAIM_Response($response);
403
+
404
+		return $this->_log_and_clean_response($response_obj, $payment);
405
+	}
406
+
407
+
408
+	/**
409
+	 * Logs the clean data only
410
+	 *
411
+	 * @param array $request_array
412
+	 * @param EEI_Payment $payment
413
+	 */
414
+	protected function _log_clean_request($request_array, $payment)
415
+	{
416
+		$keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date');
417
+		foreach ($request_array as $index => $keyvaltogether) {
418
+			foreach ($keys_to_filter_out as $key) {
419
+				if (strpos($keyvaltogether, $key) === 0) {
420
+					// found it at the first character
421
+					// so its one of them
422
+					unset($request_array[ $index ]);
423
+				}
424
+			}
425
+		}
426
+		$this->log(
427
+			array(
428
+				'AIM Request sent:' => $request_array,
429
+				'Server URL'        => $this->_get_server_url()
430
+			),
431
+			$payment
432
+		);
433
+	}
434
+
435
+
436
+
437
+	/**
438
+	 * Logs the response and cleans it
439
+	 *
440
+	 * @param EE_AuthorizeNetAIM_Response $response_obj
441
+	 * @param EE_Payment                  $payment
442
+	 * @return \EE_AuthorizeNetAIM_Response
443
+	 */
444
+	private function _log_and_clean_response($response_obj, $payment)
445
+	{
446
+		$response_obj->account_number = '';
447
+		$this->log(array('AIM Response received:' => (array) $response_obj), $payment);
448
+		return $response_obj;
449
+	}
450
+
451
+	/**
452
+	 * Removes characters Authorize.net doesn't handle well.
453
+	 * @since 4.9.82.p
454
+	 * @param $text
455
+	 * @return string
456
+	 */
457
+	private function prepareStringForAuthnet($text)
458
+	{
459
+		return str_replace(
460
+			'\'',
461
+			'',
462
+			$text
463
+		);
464
+	}
465 465
 }
466 466
 
467 467
 
@@ -477,192 +477,192 @@  discard block
 block discarded – undo
477 477
 class EE_AuthorizeNetAIM_Response
478 478
 {
479 479
 
480
-    const APPROVED = '1';
481
-    const DECLINED = '2';
482
-    const ERROR = '3';
483
-    const HELD = '4';
484
-
485
-    protected $_x_post_fields = array(
486
-        "version"        => "3.1",
487
-        "delim_char"     => ",",
488
-        "delim_data"     => "TRUE",
489
-        "relay_response" => "FALSE",
490
-        "encap_char"     => "|",
491
-    );
492
-    public $approved;
493
-    public $declined;
494
-    public $error;
495
-    public $held;
496
-    public $response_code;
497
-    public $response_subcode;
498
-    public $response_reason_code;
499
-    public $response_reason_text;
500
-    public $authorization_code;
501
-    public $avs_response;
502
-    public $transaction_id;
503
-    public $invoice_number;
504
-    public $description;
505
-    public $amount;
506
-    public $method;
507
-    public $transaction_type;
508
-    public $customer_id;
509
-    public $first_name;
510
-    public $last_name;
511
-    public $company;
512
-    public $address;
513
-    public $city;
514
-    public $state;
515
-    public $zip_code;
516
-    public $country;
517
-    public $phone;
518
-    public $fax;
519
-    public $email_address;
520
-    public $ship_to_first_name;
521
-    public $ship_to_last_name;
522
-    public $ship_to_company;
523
-    public $ship_to_address;
524
-    public $ship_to_city;
525
-    public $ship_to_state;
526
-    public $ship_to_zip_code;
527
-    public $ship_to_country;
528
-    public $tax;
529
-    public $duty;
530
-    public $freight;
531
-    public $tax_exempt;
532
-    public $purchase_order_number;
533
-    public $md5_hash;
534
-    public $card_code_response;
535
-    public $cavv_response; // cardholder_authentication_verification_response
536
-    public $account_number;
537
-    public $card_type;
538
-    public $split_tender_id;
539
-    public $requested_amount;
540
-    public $balance_on_card;
541
-    public $response; // The response string from AuthorizeNet.
542
-    public $error_message;
543
-    private $_response_array = array(); // An array with the split response.
544
-
545
-
546
-    /**
547
-     * Constructor. Parses the AuthorizeNet response string
548
-     *
549
-     * @param string $response The response from the AuthNet server.
550
-     * @var string   $delimiter The delimiter used (default is ",")
551
-     * @var string   $encap_char The encap_char used (default is "|")
552
-     * @var array    $custom_fields Any custom fields set in the request.
553
-     */
554
-
555
-    public function __construct($response)
556
-    {
557
-        $encap_char = $this->_x_post_fields['encap_char'];
558
-        $delimiter = $this->_x_post_fields['delim_char'];
559
-        if ($response) {
560
-            // Split Array
561
-            $this->response = $response;
562
-            if ($encap_char) {
563
-                $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1));
564
-            } else {
565
-                $this->_response_array = explode($delimiter, $response);
566
-            }
567
-
568
-            /**
569
-             * If AuthorizeNet doesn't return a delimited response.
570
-             */
571
-            if (count($this->_response_array) < 10) {
572
-                $this->approved = false;
573
-                $this->error = true;
574
-                $this->error_message = sprintf(
575
-                    esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'),
576
-                    esc_html($response)
577
-                );
578
-                return;
579
-            }
580
-
581
-
582
-
583
-            // Set all fields
584
-            $this->response_code = $this->_response_array[0];
585
-            $this->response_subcode = $this->_response_array[1];
586
-            $this->response_reason_code = $this->_response_array[2];
587
-            $this->response_reason_text = $this->_response_array[3];
588
-            $this->authorization_code = $this->_response_array[4];
589
-            $this->avs_response = $this->_response_array[5];
590
-            $this->transaction_id = $this->_response_array[6];
591
-            $this->invoice_number = $this->_response_array[7];
592
-            $this->description = $this->_response_array[8];
593
-            $this->amount = $this->_response_array[9];
594
-            $this->method = $this->_response_array[10];
595
-            $this->transaction_type = $this->_response_array[11];
596
-            $this->customer_id = $this->_response_array[12];
597
-            $this->first_name = $this->_response_array[13];
598
-            $this->last_name = $this->_response_array[14];
599
-            $this->company = $this->_response_array[15];
600
-            $this->address = $this->_response_array[16];
601
-            $this->city = $this->_response_array[17];
602
-            $this->state = $this->_response_array[18];
603
-            $this->zip_code = $this->_response_array[19];
604
-            $this->country = $this->_response_array[20];
605
-            $this->phone = $this->_response_array[21];
606
-            $this->fax = $this->_response_array[22];
607
-            $this->email_address = $this->_response_array[23];
608
-            $this->ship_to_first_name = $this->_response_array[24];
609
-            $this->ship_to_last_name = $this->_response_array[25];
610
-            $this->ship_to_company = $this->_response_array[26];
611
-            $this->ship_to_address = $this->_response_array[27];
612
-            $this->ship_to_city = $this->_response_array[28];
613
-            $this->ship_to_state = $this->_response_array[29];
614
-            $this->ship_to_zip_code = $this->_response_array[30];
615
-            $this->ship_to_country = $this->_response_array[31];
616
-            $this->tax = $this->_response_array[32];
617
-            $this->duty = $this->_response_array[33];
618
-            $this->freight = $this->_response_array[34];
619
-            $this->tax_exempt = $this->_response_array[35];
620
-            $this->purchase_order_number = $this->_response_array[36];
621
-            $this->md5_hash = $this->_response_array[37];
622
-            $this->card_code_response = $this->_response_array[38];
623
-            $this->cavv_response = $this->_response_array[39];
624
-            $this->account_number = $this->_response_array[50];
625
-            $this->card_type = $this->_response_array[51];
626
-            $this->split_tender_id = $this->_response_array[52];
627
-            $this->requested_amount = $this->_response_array[53];
628
-            $this->balance_on_card = $this->_response_array[54];
629
-
630
-            $this->approved = ($this->response_code === self::APPROVED);
631
-            $this->declined = ($this->response_code === self::DECLINED);
632
-            $this->error = ($this->response_code === self::ERROR);
633
-            $this->held = ($this->response_code === self::HELD);
634
-        } else {
635
-            $this->approved = false;
636
-            $this->error = true;
637
-            $this->error_message = esc_html__(
638
-                'Error connecting to Authorize.net',
639
-                'event_espresso'
640
-            );
641
-        }
642
-    }
480
+	const APPROVED = '1';
481
+	const DECLINED = '2';
482
+	const ERROR = '3';
483
+	const HELD = '4';
484
+
485
+	protected $_x_post_fields = array(
486
+		"version"        => "3.1",
487
+		"delim_char"     => ",",
488
+		"delim_data"     => "TRUE",
489
+		"relay_response" => "FALSE",
490
+		"encap_char"     => "|",
491
+	);
492
+	public $approved;
493
+	public $declined;
494
+	public $error;
495
+	public $held;
496
+	public $response_code;
497
+	public $response_subcode;
498
+	public $response_reason_code;
499
+	public $response_reason_text;
500
+	public $authorization_code;
501
+	public $avs_response;
502
+	public $transaction_id;
503
+	public $invoice_number;
504
+	public $description;
505
+	public $amount;
506
+	public $method;
507
+	public $transaction_type;
508
+	public $customer_id;
509
+	public $first_name;
510
+	public $last_name;
511
+	public $company;
512
+	public $address;
513
+	public $city;
514
+	public $state;
515
+	public $zip_code;
516
+	public $country;
517
+	public $phone;
518
+	public $fax;
519
+	public $email_address;
520
+	public $ship_to_first_name;
521
+	public $ship_to_last_name;
522
+	public $ship_to_company;
523
+	public $ship_to_address;
524
+	public $ship_to_city;
525
+	public $ship_to_state;
526
+	public $ship_to_zip_code;
527
+	public $ship_to_country;
528
+	public $tax;
529
+	public $duty;
530
+	public $freight;
531
+	public $tax_exempt;
532
+	public $purchase_order_number;
533
+	public $md5_hash;
534
+	public $card_code_response;
535
+	public $cavv_response; // cardholder_authentication_verification_response
536
+	public $account_number;
537
+	public $card_type;
538
+	public $split_tender_id;
539
+	public $requested_amount;
540
+	public $balance_on_card;
541
+	public $response; // The response string from AuthorizeNet.
542
+	public $error_message;
543
+	private $_response_array = array(); // An array with the split response.
544
+
545
+
546
+	/**
547
+	 * Constructor. Parses the AuthorizeNet response string
548
+	 *
549
+	 * @param string $response The response from the AuthNet server.
550
+	 * @var string   $delimiter The delimiter used (default is ",")
551
+	 * @var string   $encap_char The encap_char used (default is "|")
552
+	 * @var array    $custom_fields Any custom fields set in the request.
553
+	 */
554
+
555
+	public function __construct($response)
556
+	{
557
+		$encap_char = $this->_x_post_fields['encap_char'];
558
+		$delimiter = $this->_x_post_fields['delim_char'];
559
+		if ($response) {
560
+			// Split Array
561
+			$this->response = $response;
562
+			if ($encap_char) {
563
+				$this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1));
564
+			} else {
565
+				$this->_response_array = explode($delimiter, $response);
566
+			}
567
+
568
+			/**
569
+			 * If AuthorizeNet doesn't return a delimited response.
570
+			 */
571
+			if (count($this->_response_array) < 10) {
572
+				$this->approved = false;
573
+				$this->error = true;
574
+				$this->error_message = sprintf(
575
+					esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'),
576
+					esc_html($response)
577
+				);
578
+				return;
579
+			}
580
+
581
+
582
+
583
+			// Set all fields
584
+			$this->response_code = $this->_response_array[0];
585
+			$this->response_subcode = $this->_response_array[1];
586
+			$this->response_reason_code = $this->_response_array[2];
587
+			$this->response_reason_text = $this->_response_array[3];
588
+			$this->authorization_code = $this->_response_array[4];
589
+			$this->avs_response = $this->_response_array[5];
590
+			$this->transaction_id = $this->_response_array[6];
591
+			$this->invoice_number = $this->_response_array[7];
592
+			$this->description = $this->_response_array[8];
593
+			$this->amount = $this->_response_array[9];
594
+			$this->method = $this->_response_array[10];
595
+			$this->transaction_type = $this->_response_array[11];
596
+			$this->customer_id = $this->_response_array[12];
597
+			$this->first_name = $this->_response_array[13];
598
+			$this->last_name = $this->_response_array[14];
599
+			$this->company = $this->_response_array[15];
600
+			$this->address = $this->_response_array[16];
601
+			$this->city = $this->_response_array[17];
602
+			$this->state = $this->_response_array[18];
603
+			$this->zip_code = $this->_response_array[19];
604
+			$this->country = $this->_response_array[20];
605
+			$this->phone = $this->_response_array[21];
606
+			$this->fax = $this->_response_array[22];
607
+			$this->email_address = $this->_response_array[23];
608
+			$this->ship_to_first_name = $this->_response_array[24];
609
+			$this->ship_to_last_name = $this->_response_array[25];
610
+			$this->ship_to_company = $this->_response_array[26];
611
+			$this->ship_to_address = $this->_response_array[27];
612
+			$this->ship_to_city = $this->_response_array[28];
613
+			$this->ship_to_state = $this->_response_array[29];
614
+			$this->ship_to_zip_code = $this->_response_array[30];
615
+			$this->ship_to_country = $this->_response_array[31];
616
+			$this->tax = $this->_response_array[32];
617
+			$this->duty = $this->_response_array[33];
618
+			$this->freight = $this->_response_array[34];
619
+			$this->tax_exempt = $this->_response_array[35];
620
+			$this->purchase_order_number = $this->_response_array[36];
621
+			$this->md5_hash = $this->_response_array[37];
622
+			$this->card_code_response = $this->_response_array[38];
623
+			$this->cavv_response = $this->_response_array[39];
624
+			$this->account_number = $this->_response_array[50];
625
+			$this->card_type = $this->_response_array[51];
626
+			$this->split_tender_id = $this->_response_array[52];
627
+			$this->requested_amount = $this->_response_array[53];
628
+			$this->balance_on_card = $this->_response_array[54];
629
+
630
+			$this->approved = ($this->response_code === self::APPROVED);
631
+			$this->declined = ($this->response_code === self::DECLINED);
632
+			$this->error = ($this->response_code === self::ERROR);
633
+			$this->held = ($this->response_code === self::HELD);
634
+		} else {
635
+			$this->approved = false;
636
+			$this->error = true;
637
+			$this->error_message = esc_html__(
638
+				'Error connecting to Authorize.net',
639
+				'event_espresso'
640
+			);
641
+		}
642
+	}
643 643
 }
644 644
 
645 645
 if (! class_exists('AuthorizeNetException')) {
646
-    /**
647
-     * Class AuthorizeNetException
648
-     *
649
-     * @package    AuthorizeNet
650
-     */
651
-    class AuthorizeNetException extends Exception
652
-    {
653
-
654
-        /**
655
-         * Construct the exception. Note: The message is NOT binary safe.
656
-         *
657
-         * @link http://php.net/manual/en/exception.construct.php
658
-         * @param string $message [optional] The Exception message to throw.
659
-         * @param int $code [optional] The Exception code.
660
-         * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0
661
-         * @since 5.1.0
662
-         */
663
-        public function __construct($message = "", $code = 0, Exception $previous = null)
664
-        {
665
-            parent::__construct($message, $code, $previous);
666
-        }
667
-    }
646
+	/**
647
+	 * Class AuthorizeNetException
648
+	 *
649
+	 * @package    AuthorizeNet
650
+	 */
651
+	class AuthorizeNetException extends Exception
652
+	{
653
+
654
+		/**
655
+		 * Construct the exception. Note: The message is NOT binary safe.
656
+		 *
657
+		 * @link http://php.net/manual/en/exception.construct.php
658
+		 * @param string $message [optional] The Exception message to throw.
659
+		 * @param int $code [optional] The Exception code.
660
+		 * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0
661
+		 * @since 5.1.0
662
+		 */
663
+		public function __construct($message = "", $code = 0, Exception $previous = null)
664
+		{
665
+			parent::__construct($message, $code, $previous);
666
+		}
667
+	}
668 668
 }
Please login to merge, or discard this patch.
core/libraries/shortcodes/EE_Event_List_Shortcodes.lib.php 1 patch
Indentation   +135 added lines, -135 removed lines patch added patch discarded remove patch
@@ -21,139 +21,139 @@
 block discarded – undo
21 21
 class EE_Event_List_Shortcodes extends EE_Shortcodes
22 22
 {
23 23
 
24
-    public function __construct()
25
-    {
26
-        parent::__construct();
27
-    }
28
-
29
-
30
-    protected function _init_props()
31
-    {
32
-        $this->label = __('Event List Shortcodes', 'event_espresso');
33
-        $this->description = __('All shortcodes specific to event lists', 'event_espresso');
34
-        $this->_shortcodes = array(
35
-            '[EVENT_LIST]' => __('Will output a list of events', 'event_espresso'),
36
-        );
37
-    }
38
-
39
-
40
-    protected function _parser($shortcode)
41
-    {
42
-        switch ($shortcode) {
43
-            case '[EVENT_LIST]':
44
-                return $this->_get_event_list();
45
-                break;
46
-        }
47
-    }
48
-
49
-
50
-    /**
51
-     * figure out what the incoming data is and then return the appropriate parsed value.
52
-     *
53
-     * @return string
54
-     */
55
-    private function _get_event_list()
56
-    {
57
-        $this->_validate_list_requirements();
58
-
59
-        if ($this->_data['data'] instanceof EE_Messages_Addressee) {
60
-            return $this->_get_event_list_for_main();
61
-        } elseif ($this->_data['data'] instanceof EE_Registration) {
62
-            return $this->_get_event_list_for_registration();
63
-        } // prevent recursive loop
64
-        else {
65
-            return '';
66
-        }
67
-    }
68
-
69
-
70
-    /**
71
-     * This returns the parsed event list for main template
72
-     *
73
-     * @return string
74
-     */
75
-    private function _get_event_list_for_main()
76
-    {
77
-
78
-        $valid_shortcodes = array(
79
-            'event',
80
-            'attendee_list',
81
-            'ticket_list',
82
-            'datetime_list',
83
-            'venue',
84
-            'attendee',
85
-            'recipient_list',
86
-            'recipient_details',
87
-            'primary_registration_list',
88
-            'primary_registration_details',
89
-            'event_author',
90
-            'organization',
91
-        );
92
-        $template = $this->_data['template'];
93
-        $data = $this->_data['data'];
94
-        $events = '';
95
-
96
-        // now we need to loop through the events array in EE_Messages_Addressee and send data to the EE_Parser helper.
97
-        foreach ($data->events as $event) {
98
-            $events .= $this->_shortcode_helper->parse_event_list_template(
99
-                $template,
100
-                $event['event'],
101
-                $valid_shortcodes,
102
-                $this->_extra_data
103
-            );
104
-        }
105
-        return $events;
106
-    }
107
-
108
-
109
-    /**
110
-     * This returns the parsed event list for an attendee
111
-     *
112
-     * @return string
113
-     */
114
-    private function _get_event_list_for_registration()
115
-    {
116
-        $valid_shortcodes = array(
117
-            'event',
118
-            'ticket_list',
119
-            'datetime_list',
120
-            'attendee',
121
-            'event_author',
122
-            'recipient_details',
123
-            'recipient_list',
124
-            'venue',
125
-            'organization',
126
-        );
127
-        $template = is_array($this->_data['template']) && isset($this->_data['template']['event_list'])
128
-            ? $this->_data['template']['event_list'] : $this->_extra_data['template']['event_list'];
129
-        $registration = $this->_data['data'];
130
-
131
-        // let's remove any existing [ATTENDEE_LIST] shortcode from the event list template so that we don't get recursion.
132
-        $template = str_replace('[ATTENDEE_LIST]', '', $template);
133
-
134
-        // here we're setting up the events for the event_list template for THIS registration.
135
-        $evt_result = '';
136
-        $all_events = $this->_get_events_from_registration($registration);
137
-
138
-        // we're NOT going to prepare a list of attendees this time around
139
-        $events = '';
140
-
141
-        foreach ((array) $all_events as $event) {
142
-            $events .= $this->_shortcode_helper->parse_event_list_template(
143
-                $template,
144
-                $event,
145
-                $valid_shortcodes,
146
-                $this->_extra_data
147
-            );
148
-        }
149
-
150
-        return $events;
151
-    }
152
-
153
-
154
-    private function _get_events_from_registration(EE_Registration $registration)
155
-    {
156
-        return isset($this->_extra_data['data']->registrations)
157
-            ? array($this->_extra_data['data']->registrations[ $registration->ID() ]['evt_obj']) : array();
158
-    }
24
+	public function __construct()
25
+	{
26
+		parent::__construct();
27
+	}
28
+
29
+
30
+	protected function _init_props()
31
+	{
32
+		$this->label = __('Event List Shortcodes', 'event_espresso');
33
+		$this->description = __('All shortcodes specific to event lists', 'event_espresso');
34
+		$this->_shortcodes = array(
35
+			'[EVENT_LIST]' => __('Will output a list of events', 'event_espresso'),
36
+		);
37
+	}
38
+
39
+
40
+	protected function _parser($shortcode)
41
+	{
42
+		switch ($shortcode) {
43
+			case '[EVENT_LIST]':
44
+				return $this->_get_event_list();
45
+				break;
46
+		}
47
+	}
48
+
49
+
50
+	/**
51
+	 * figure out what the incoming data is and then return the appropriate parsed value.
52
+	 *
53
+	 * @return string
54
+	 */
55
+	private function _get_event_list()
56
+	{
57
+		$this->_validate_list_requirements();
58
+
59
+		if ($this->_data['data'] instanceof EE_Messages_Addressee) {
60
+			return $this->_get_event_list_for_main();
61
+		} elseif ($this->_data['data'] instanceof EE_Registration) {
62
+			return $this->_get_event_list_for_registration();
63
+		} // prevent recursive loop
64
+		else {
65
+			return '';
66
+		}
67
+	}
68
+
69
+
70
+	/**
71
+	 * This returns the parsed event list for main template
72
+	 *
73
+	 * @return string
74
+	 */
75
+	private function _get_event_list_for_main()
76
+	{
77
+
78
+		$valid_shortcodes = array(
79
+			'event',
80
+			'attendee_list',
81
+			'ticket_list',
82
+			'datetime_list',
83
+			'venue',
84
+			'attendee',
85
+			'recipient_list',
86
+			'recipient_details',
87
+			'primary_registration_list',
88
+			'primary_registration_details',
89
+			'event_author',
90
+			'organization',
91
+		);
92
+		$template = $this->_data['template'];
93
+		$data = $this->_data['data'];
94
+		$events = '';
95
+
96
+		// now we need to loop through the events array in EE_Messages_Addressee and send data to the EE_Parser helper.
97
+		foreach ($data->events as $event) {
98
+			$events .= $this->_shortcode_helper->parse_event_list_template(
99
+				$template,
100
+				$event['event'],
101
+				$valid_shortcodes,
102
+				$this->_extra_data
103
+			);
104
+		}
105
+		return $events;
106
+	}
107
+
108
+
109
+	/**
110
+	 * This returns the parsed event list for an attendee
111
+	 *
112
+	 * @return string
113
+	 */
114
+	private function _get_event_list_for_registration()
115
+	{
116
+		$valid_shortcodes = array(
117
+			'event',
118
+			'ticket_list',
119
+			'datetime_list',
120
+			'attendee',
121
+			'event_author',
122
+			'recipient_details',
123
+			'recipient_list',
124
+			'venue',
125
+			'organization',
126
+		);
127
+		$template = is_array($this->_data['template']) && isset($this->_data['template']['event_list'])
128
+			? $this->_data['template']['event_list'] : $this->_extra_data['template']['event_list'];
129
+		$registration = $this->_data['data'];
130
+
131
+		// let's remove any existing [ATTENDEE_LIST] shortcode from the event list template so that we don't get recursion.
132
+		$template = str_replace('[ATTENDEE_LIST]', '', $template);
133
+
134
+		// here we're setting up the events for the event_list template for THIS registration.
135
+		$evt_result = '';
136
+		$all_events = $this->_get_events_from_registration($registration);
137
+
138
+		// we're NOT going to prepare a list of attendees this time around
139
+		$events = '';
140
+
141
+		foreach ((array) $all_events as $event) {
142
+			$events .= $this->_shortcode_helper->parse_event_list_template(
143
+				$template,
144
+				$event,
145
+				$valid_shortcodes,
146
+				$this->_extra_data
147
+			);
148
+		}
149
+
150
+		return $events;
151
+	}
152
+
153
+
154
+	private function _get_events_from_registration(EE_Registration $registration)
155
+	{
156
+		return isset($this->_extra_data['data']->registrations)
157
+			? array($this->_extra_data['data']->registrations[ $registration->ID() ]['evt_obj']) : array();
158
+	}
159 159
 }
Please login to merge, or discard this patch.
core/domain/services/contexts/RequestTypeContextDetector.php 1 patch
Indentation   +177 added lines, -177 removed lines patch added patch discarded remove patch
@@ -18,181 +18,181 @@
 block discarded – undo
18 18
 class RequestTypeContextDetector
19 19
 {
20 20
 
21
-    /**
22
-     * @var RequestTypeContextFactoryInterface $factory
23
-     */
24
-    private $factory;
25
-
26
-    /**
27
-     * @var RequestInterface $request
28
-     */
29
-    private $request;
30
-
31
-    /**
32
-     * @var array $globalRouteConditions
33
-     */
34
-    private $globalRouteConditions;
35
-
36
-
37
-    /**
38
-     * RequestTypeContextDetector constructor.
39
-     *
40
-     * @param RequestInterface                   $request
41
-     * @param RequestTypeContextFactoryInterface $factory
42
-     * @param array                              $globalRouteConditions an array for injecting values that would
43
-     *                                                                  otherwise be defined as global constants
44
-     *                                                                  or other global variables for the current
45
-     *                                                                  request route such as DOING_AJAX
46
-     */
47
-    public function __construct(
48
-        RequestInterface $request,
49
-        RequestTypeContextFactoryInterface $factory,
50
-        array $globalRouteConditions = array()
51
-    ) {
52
-        $this->request = $request;
53
-        $this->factory = $factory;
54
-        $this->globalRouteConditions = $globalRouteConditions;
55
-    }
56
-
57
-
58
-    /**
59
-     * @return mixed
60
-     */
61
-    private function getGlobalRouteCondition($globalRouteCondition, $default)
62
-    {
63
-        return isset($this->globalRouteConditions[ $globalRouteCondition ])
64
-            ? $this->globalRouteConditions[ $globalRouteCondition ]
65
-            : $default;
66
-    }
67
-
68
-
69
-    /**
70
-     * @return RequestTypeContext
71
-     * @throws InvalidArgumentException
72
-     */
73
-    public function detectRequestTypeContext()
74
-    {
75
-        // Detect error scrapes
76
-        if ($this->request->getRequestParam('wp_scrape_key') !== null
77
-            && $this->request->getRequestParam('wp_scrape_nonce') !== null
78
-        ) {
79
-            return $this->factory->create(RequestTypeContext::WP_SCRAPE);
80
-        }
81
-        // Detect EE REST API
82
-        if ($this->isEspressoRestApiRequest()) {
83
-            return $this->factory->create(RequestTypeContext::API);
84
-        }
85
-        // Detect WP REST API
86
-        if ($this->isWordPressRestApiRequest()) {
87
-            return $this->factory->create(RequestTypeContext::WP_API);
88
-        }
89
-        // Detect AJAX
90
-        if ($this->getGlobalRouteCondition('DOING_AJAX', false)) {
91
-            if (filter_var($this->request->getRequestParam('ee_front_ajax'), FILTER_VALIDATE_BOOLEAN)) {
92
-                return $this->factory->create(RequestTypeContext::AJAX_FRONT);
93
-            }
94
-            if (filter_var($this->request->getRequestParam('ee_admin_ajax'), FILTER_VALIDATE_BOOLEAN)) {
95
-                return $this->factory->create(RequestTypeContext::AJAX_ADMIN);
96
-            }
97
-            if ($this->request->getRequestParam('action') === 'heartbeat') {
98
-                return $this->factory->create(RequestTypeContext::AJAX_HEARTBEAT);
99
-            }
100
-            return $this->factory->create(RequestTypeContext::AJAX_OTHER);
101
-        }
102
-        // Detect WP_Cron
103
-        if ($this->isCronRequest()) {
104
-            return $this->factory->create(RequestTypeContext::CRON);
105
-        }
106
-        // Detect command line requests
107
-        if ($this->getGlobalRouteCondition('WP_CLI', false)) {
108
-            return $this->factory->create(RequestTypeContext::CLI);
109
-        }
110
-        // detect WordPress admin (ie: "Dashboard")
111
-        if ($this->getGlobalRouteCondition('is_admin', false)) {
112
-            return $this->factory->create(RequestTypeContext::ADMIN);
113
-        }
114
-        // Detect iFrames
115
-        if ($this->isIframeRoute()) {
116
-            return $this->factory->create(RequestTypeContext::IFRAME);
117
-        }
118
-        // Detect Feeds
119
-        if ($this->isFeedRequest()) {
120
-            return $this->factory->create(RequestTypeContext::FEED);
121
-        }
122
-        // and by process of elimination...
123
-        return $this->factory->create(RequestTypeContext::FRONTEND);
124
-    }
125
-
126
-
127
-    /**
128
-     * @return bool
129
-     */
130
-    private function isEspressoRestApiRequest()
131
-    {
132
-        // Check for URLs like http://mysite.com/?rest_route=/ee... and http://mysite.com/wp-json/ee/...
133
-        return strpos(
134
-            $this->request->getRequestParam('rest_route', false),
135
-            '/' . Domain::API_NAMESPACE
136
-        ) === 0
137
-            || $this->uriPathMatches(trim(rest_get_url_prefix(), '/') . '/' . Domain::API_NAMESPACE);
138
-    }
139
-
140
-
141
-
142
-    /**
143
-     * @return bool
144
-     */
145
-    private function isWordPressRestApiRequest()
146
-    {
147
-        // Check for URLs like http://mysite.com/?rest_route=/.. and http://mysite.com/wp-json/...
148
-        return $this->request->getRequestParam('rest_route', false)
149
-            || $this->uriPathMatches(trim(rest_get_url_prefix(), '/'));
150
-    }
151
-
152
-
153
-    /**
154
-     * @return bool
155
-     */
156
-    private function isCronRequest()
157
-    {
158
-        return $this->uriPathMatches('wp-cron.php');
159
-    }
160
-
161
-
162
-    /**
163
-     * @return bool
164
-     */
165
-    private function isFeedRequest()
166
-    {
167
-        return $this->uriPathMatches('feed');
168
-    }
169
-
170
-
171
-    /**
172
-     * @param string $component
173
-     * @return bool
174
-     */
175
-    private function uriPathMatches($component)
176
-    {
177
-        $request_uri = $this->request->requestUri(true);
178
-        $parts = explode('?', $request_uri);
179
-        $path = trim(reset($parts), '/');
180
-        return strpos($path, $component) === 0;
181
-    }
182
-
183
-
184
-    /**
185
-     * @return bool
186
-     */
187
-    private function isIframeRoute()
188
-    {
189
-        $is_iframe_route = apply_filters(
190
-            'FHEE__EventEspresso_core_domain_services_contexts_RequestTypeContextDetector__isIframeRoute',
191
-            $this->request->getRequestParam('event_list', '') === 'iframe'
192
-            || $this->request->getRequestParam('ticket_selector', '') === 'iframe'
193
-            || $this->request->getRequestParam('calendar', '') === 'iframe',
194
-            $this
195
-        );
196
-        return filter_var($is_iframe_route, FILTER_VALIDATE_BOOLEAN);
197
-    }
21
+	/**
22
+	 * @var RequestTypeContextFactoryInterface $factory
23
+	 */
24
+	private $factory;
25
+
26
+	/**
27
+	 * @var RequestInterface $request
28
+	 */
29
+	private $request;
30
+
31
+	/**
32
+	 * @var array $globalRouteConditions
33
+	 */
34
+	private $globalRouteConditions;
35
+
36
+
37
+	/**
38
+	 * RequestTypeContextDetector constructor.
39
+	 *
40
+	 * @param RequestInterface                   $request
41
+	 * @param RequestTypeContextFactoryInterface $factory
42
+	 * @param array                              $globalRouteConditions an array for injecting values that would
43
+	 *                                                                  otherwise be defined as global constants
44
+	 *                                                                  or other global variables for the current
45
+	 *                                                                  request route such as DOING_AJAX
46
+	 */
47
+	public function __construct(
48
+		RequestInterface $request,
49
+		RequestTypeContextFactoryInterface $factory,
50
+		array $globalRouteConditions = array()
51
+	) {
52
+		$this->request = $request;
53
+		$this->factory = $factory;
54
+		$this->globalRouteConditions = $globalRouteConditions;
55
+	}
56
+
57
+
58
+	/**
59
+	 * @return mixed
60
+	 */
61
+	private function getGlobalRouteCondition($globalRouteCondition, $default)
62
+	{
63
+		return isset($this->globalRouteConditions[ $globalRouteCondition ])
64
+			? $this->globalRouteConditions[ $globalRouteCondition ]
65
+			: $default;
66
+	}
67
+
68
+
69
+	/**
70
+	 * @return RequestTypeContext
71
+	 * @throws InvalidArgumentException
72
+	 */
73
+	public function detectRequestTypeContext()
74
+	{
75
+		// Detect error scrapes
76
+		if ($this->request->getRequestParam('wp_scrape_key') !== null
77
+			&& $this->request->getRequestParam('wp_scrape_nonce') !== null
78
+		) {
79
+			return $this->factory->create(RequestTypeContext::WP_SCRAPE);
80
+		}
81
+		// Detect EE REST API
82
+		if ($this->isEspressoRestApiRequest()) {
83
+			return $this->factory->create(RequestTypeContext::API);
84
+		}
85
+		// Detect WP REST API
86
+		if ($this->isWordPressRestApiRequest()) {
87
+			return $this->factory->create(RequestTypeContext::WP_API);
88
+		}
89
+		// Detect AJAX
90
+		if ($this->getGlobalRouteCondition('DOING_AJAX', false)) {
91
+			if (filter_var($this->request->getRequestParam('ee_front_ajax'), FILTER_VALIDATE_BOOLEAN)) {
92
+				return $this->factory->create(RequestTypeContext::AJAX_FRONT);
93
+			}
94
+			if (filter_var($this->request->getRequestParam('ee_admin_ajax'), FILTER_VALIDATE_BOOLEAN)) {
95
+				return $this->factory->create(RequestTypeContext::AJAX_ADMIN);
96
+			}
97
+			if ($this->request->getRequestParam('action') === 'heartbeat') {
98
+				return $this->factory->create(RequestTypeContext::AJAX_HEARTBEAT);
99
+			}
100
+			return $this->factory->create(RequestTypeContext::AJAX_OTHER);
101
+		}
102
+		// Detect WP_Cron
103
+		if ($this->isCronRequest()) {
104
+			return $this->factory->create(RequestTypeContext::CRON);
105
+		}
106
+		// Detect command line requests
107
+		if ($this->getGlobalRouteCondition('WP_CLI', false)) {
108
+			return $this->factory->create(RequestTypeContext::CLI);
109
+		}
110
+		// detect WordPress admin (ie: "Dashboard")
111
+		if ($this->getGlobalRouteCondition('is_admin', false)) {
112
+			return $this->factory->create(RequestTypeContext::ADMIN);
113
+		}
114
+		// Detect iFrames
115
+		if ($this->isIframeRoute()) {
116
+			return $this->factory->create(RequestTypeContext::IFRAME);
117
+		}
118
+		// Detect Feeds
119
+		if ($this->isFeedRequest()) {
120
+			return $this->factory->create(RequestTypeContext::FEED);
121
+		}
122
+		// and by process of elimination...
123
+		return $this->factory->create(RequestTypeContext::FRONTEND);
124
+	}
125
+
126
+
127
+	/**
128
+	 * @return bool
129
+	 */
130
+	private function isEspressoRestApiRequest()
131
+	{
132
+		// Check for URLs like http://mysite.com/?rest_route=/ee... and http://mysite.com/wp-json/ee/...
133
+		return strpos(
134
+			$this->request->getRequestParam('rest_route', false),
135
+			'/' . Domain::API_NAMESPACE
136
+		) === 0
137
+			|| $this->uriPathMatches(trim(rest_get_url_prefix(), '/') . '/' . Domain::API_NAMESPACE);
138
+	}
139
+
140
+
141
+
142
+	/**
143
+	 * @return bool
144
+	 */
145
+	private function isWordPressRestApiRequest()
146
+	{
147
+		// Check for URLs like http://mysite.com/?rest_route=/.. and http://mysite.com/wp-json/...
148
+		return $this->request->getRequestParam('rest_route', false)
149
+			|| $this->uriPathMatches(trim(rest_get_url_prefix(), '/'));
150
+	}
151
+
152
+
153
+	/**
154
+	 * @return bool
155
+	 */
156
+	private function isCronRequest()
157
+	{
158
+		return $this->uriPathMatches('wp-cron.php');
159
+	}
160
+
161
+
162
+	/**
163
+	 * @return bool
164
+	 */
165
+	private function isFeedRequest()
166
+	{
167
+		return $this->uriPathMatches('feed');
168
+	}
169
+
170
+
171
+	/**
172
+	 * @param string $component
173
+	 * @return bool
174
+	 */
175
+	private function uriPathMatches($component)
176
+	{
177
+		$request_uri = $this->request->requestUri(true);
178
+		$parts = explode('?', $request_uri);
179
+		$path = trim(reset($parts), '/');
180
+		return strpos($path, $component) === 0;
181
+	}
182
+
183
+
184
+	/**
185
+	 * @return bool
186
+	 */
187
+	private function isIframeRoute()
188
+	{
189
+		$is_iframe_route = apply_filters(
190
+			'FHEE__EventEspresso_core_domain_services_contexts_RequestTypeContextDetector__isIframeRoute',
191
+			$this->request->getRequestParam('event_list', '') === 'iframe'
192
+			|| $this->request->getRequestParam('ticket_selector', '') === 'iframe'
193
+			|| $this->request->getRequestParam('calendar', '') === 'iframe',
194
+			$this
195
+		);
196
+		return filter_var($is_iframe_route, FILTER_VALIDATE_BOOLEAN);
197
+	}
198 198
 }
Please login to merge, or discard this patch.
core/services/request/Request.php 1 patch
Indentation   +636 added lines, -636 removed lines patch added patch discarded remove patch
@@ -17,640 +17,640 @@
 block discarded – undo
17 17
 class Request implements InterminableInterface, RequestInterface, ReservedInstanceInterface
18 18
 {
19 19
 
20
-    /**
21
-     * $_GET parameters
22
-     *
23
-     * @var array $get
24
-     */
25
-    private $get;
26
-
27
-    /**
28
-     * $_POST parameters
29
-     *
30
-     * @var array $post
31
-     */
32
-    private $post;
33
-
34
-    /**
35
-     * $_COOKIE parameters
36
-     *
37
-     * @var array $cookie
38
-     */
39
-    private $cookie;
40
-
41
-    /**
42
-     * $_SERVER parameters
43
-     *
44
-     * @var array $server
45
-     */
46
-    private $server;
47
-
48
-    /**
49
-     * $_FILES parameters
50
-     *
51
-     * @var array $files
52
-     */
53
-    private $files;
54
-
55
-    /**
56
-     * $_REQUEST parameters
57
-     *
58
-     * @var array $request
59
-     */
60
-    private $request;
61
-
62
-    /**
63
-     * @var RequestTypeContextCheckerInterface
64
-     */
65
-    private $request_type;
66
-
67
-    /**
68
-     * IP address for request
69
-     *
70
-     * @var string $ip_address
71
-     */
72
-    private $ip_address;
73
-
74
-    /**
75
-     * @var string $user_agent
76
-     */
77
-    private $user_agent;
78
-
79
-    /**
80
-     * true if current user appears to be some kind of bot
81
-     *
82
-     * @var bool $is_bot
83
-     */
84
-    private $is_bot;
85
-
86
-
87
-    /**
88
-     * @param array $get
89
-     * @param array $post
90
-     * @param array $cookie
91
-     * @param array $server
92
-     * @param array $files
93
-     */
94
-    public function __construct(array $get, array $post, array $cookie, array $server, array $files = array())
95
-    {
96
-        // grab request vars
97
-        $this->get = $get;
98
-        $this->post = $post;
99
-        $this->cookie = $cookie;
100
-        $this->server = $server;
101
-        $this->files = $files;
102
-        $this->request = array_merge($this->get, $this->post);
103
-        $this->ip_address = $this->visitorIp();
104
-    }
105
-
106
-
107
-    /**
108
-     * @param RequestTypeContextCheckerInterface $type
109
-     */
110
-    public function setRequestTypeContextChecker(RequestTypeContextCheckerInterface $type)
111
-    {
112
-        $this->request_type = $type;
113
-    }
114
-
115
-
116
-    /**
117
-     * @return array
118
-     */
119
-    public function getParams()
120
-    {
121
-        return $this->get;
122
-    }
123
-
124
-
125
-    /**
126
-     * @return array
127
-     */
128
-    public function postParams()
129
-    {
130
-        return $this->post;
131
-    }
132
-
133
-
134
-    /**
135
-     * @return array
136
-     */
137
-    public function cookieParams()
138
-    {
139
-        return $this->cookie;
140
-    }
141
-
142
-
143
-    /**
144
-     * @return array
145
-     */
146
-    public function serverParams()
147
-    {
148
-        return $this->server;
149
-    }
150
-
151
-
152
-    /**
153
-     * @return array
154
-     */
155
-    public function filesParams()
156
-    {
157
-        return $this->files;
158
-    }
159
-
160
-
161
-    /**
162
-     * returns contents of $_REQUEST
163
-     *
164
-     * @return array
165
-     */
166
-    public function requestParams()
167
-    {
168
-        return $this->request;
169
-    }
170
-
171
-
172
-    /**
173
-     * @param      $key
174
-     * @param      $value
175
-     * @param bool $override_ee
176
-     * @return    void
177
-     */
178
-    public function setRequestParam($key, $value, $override_ee = false)
179
-    {
180
-        // don't allow "ee" to be overwritten unless explicitly instructed to do so
181
-        if ($key !== 'ee'
182
-            || ($key === 'ee' && empty($this->request['ee']))
183
-            || ($key === 'ee' && ! empty($this->request['ee']) && $override_ee)
184
-        ) {
185
-            $this->request[ $key ] = $value;
186
-        }
187
-    }
188
-
189
-
190
-    /**
191
-     * returns   the value for a request param if the given key exists
192
-     *
193
-     * @param       $key
194
-     * @param null  $default
195
-     * @return mixed
196
-     */
197
-    public function getRequestParam($key, $default = null)
198
-    {
199
-        return $this->requestParameterDrillDown($key, $default, 'get');
200
-    }
201
-
202
-
203
-    /**
204
-     * check if param exists
205
-     *
206
-     * @param       $key
207
-     * @return bool
208
-     */
209
-    public function requestParamIsSet($key)
210
-    {
211
-        return $this->requestParameterDrillDown($key);
212
-    }
213
-
214
-
215
-    /**
216
-     * check if a request parameter exists whose key that matches the supplied wildcard pattern
217
-     * and return the value for the first match found
218
-     * wildcards can be either of the following:
219
-     *      ? to represent a single character of any type
220
-     *      * to represent one or more characters of any type
221
-     *
222
-     * @param string     $pattern
223
-     * @param null|mixed $default
224
-     * @return mixed
225
-     */
226
-    public function getMatch($pattern, $default = null)
227
-    {
228
-        return $this->requestParameterDrillDown($pattern, $default, 'match');
229
-    }
230
-
231
-
232
-    /**
233
-     * check if a request parameter exists whose key matches the supplied wildcard pattern
234
-     * wildcards can be either of the following:
235
-     *      ? to represent a single character of any type
236
-     *      * to represent one or more characters of any type
237
-     * returns true if a match is found or false if not
238
-     *
239
-     * @param string $pattern
240
-     * @return bool
241
-     */
242
-    public function matches($pattern)
243
-    {
244
-        return $this->requestParameterDrillDown($pattern, null, 'match') !== null;
245
-    }
246
-
247
-
248
-    /**
249
-     * @see https://stackoverflow.com/questions/6163055/php-string-matching-with-wildcard
250
-     * @param string $pattern               A string including wildcards to be converted to a regex pattern
251
-     *                                      and used to search through the current request's parameter keys
252
-     * @param array  $request_params        The array of request parameters to search through
253
-     * @param mixed  $default               [optional] The value to be returned if no match is found.
254
-     *                                      Default is null
255
-     * @param string $return                [optional] Controls what kind of value is returned.
256
-     *                                      Options are:
257
-     *                                      'bool' will return true or false if match is found or not
258
-     *                                      'key' will return the first key found that matches the supplied pattern
259
-     *                                      'value' will return the value for the first request parameter
260
-     *                                      whose key matches the supplied pattern
261
-     *                                      Default is 'value'
262
-     * @return boolean|string
263
-     */
264
-    private function match($pattern, array $request_params, $default = null, $return = 'value')
265
-    {
266
-        $return = in_array($return, array('bool', 'key', 'value'), true)
267
-            ? $return
268
-            : 'is_set';
269
-        // replace wildcard chars with regex chars
270
-        $pattern = str_replace(
271
-            array("\*", "\?"),
272
-            array('.*', '.'),
273
-            preg_quote($pattern, '/')
274
-        );
275
-        foreach ($request_params as $key => $request_param) {
276
-            if (preg_match('/^' . $pattern . '$/is', $key)) {
277
-                // return value for request param
278
-                if ($return === 'value') {
279
-                    return $request_params[ $key ];
280
-                }
281
-                // or actual key or true just to indicate it was found
282
-                return $return === 'key' ? $key : true;
283
-            }
284
-        }
285
-        // match not found so return default value or false
286
-        return $return === 'value' ? $default : false;
287
-    }
288
-
289
-
290
-    /**
291
-     * the supplied key can be a simple string to represent a "top-level" request parameter
292
-     * or represent a key for a request parameter that is nested deeper within the request parameter array,
293
-     * by using square brackets to surround keys for deeper array elements.
294
-     * For example :
295
-     * if the supplied $key was: "first[second][third]"
296
-     * then this will attempt to drill down into the request parameter array to find a value.
297
-     * Given the following request parameters:
298
-     *  array(
299
-     *      'first' => array(
300
-     *          'second' => array(
301
-     *              'third' => 'has a value'
302
-     *          )
303
-     *      )
304
-     *  )
305
-     * would return true if default parameters were set
306
-     *
307
-     * @param string $callback
308
-     * @param        $key
309
-     * @param null   $default
310
-     * @param array  $request_params
311
-     * @return bool|mixed|null
312
-     */
313
-    private function requestParameterDrillDown(
314
-        $key,
315
-        $default = null,
316
-        $callback = 'is_set',
317
-        array $request_params = array()
318
-    ) {
319
-        $callback = in_array($callback, array('is_set', 'get', 'match'), true)
320
-            ? $callback
321
-            : 'is_set';
322
-        $request_params = ! empty($request_params)
323
-            ? $request_params
324
-            : $this->request;
325
-        // does incoming key represent an array like 'first[second][third]'  ?
326
-        if (strpos($key, '[') !== false) {
327
-            // turn it into an actual array
328
-            $key = str_replace(']', '', $key);
329
-            $keys = explode('[', $key);
330
-            $key = array_shift($keys);
331
-            if ($callback === 'match') {
332
-                $real_key = $this->match($key, $request_params, $default, 'key');
333
-                $key = $real_key ? $real_key : $key;
334
-            }
335
-            // check if top level key exists
336
-            if (isset($request_params[ $key ])) {
337
-                // build a new key to pass along like: 'second[third]'
338
-                // or just 'second' depending on depth of keys
339
-                $key_string = array_shift($keys);
340
-                if (! empty($keys)) {
341
-                    $key_string .= '[' . implode('][', $keys) . ']';
342
-                }
343
-                return $this->requestParameterDrillDown(
344
-                    $key_string,
345
-                    $default,
346
-                    $callback,
347
-                    $request_params[ $key ]
348
-                );
349
-            }
350
-        }
351
-        if ($callback === 'is_set') {
352
-            return isset($request_params[ $key ]);
353
-        }
354
-        if ($callback === 'match') {
355
-            return $this->match($key, $request_params, $default);
356
-        }
357
-        return isset($request_params[ $key ])
358
-            ? $request_params[ $key ]
359
-            : $default;
360
-    }
361
-
362
-
363
-    /**
364
-     * remove param
365
-     *
366
-     * @param      $key
367
-     * @param bool $unset_from_global_too
368
-     */
369
-    public function unSetRequestParam($key, $unset_from_global_too = false)
370
-    {
371
-        unset($this->request[ $key ]);
372
-        if ($unset_from_global_too) {
373
-            unset($_REQUEST[ $key ]);
374
-        }
375
-    }
376
-
377
-
378
-    /**
379
-     * @return string
380
-     */
381
-    public function ipAddress()
382
-    {
383
-        return $this->ip_address;
384
-    }
385
-
386
-
387
-    /**
388
-     * attempt to get IP address of current visitor from server
389
-     * plz see: http://stackoverflow.com/a/2031935/1475279
390
-     *
391
-     * @access public
392
-     * @return string
393
-     */
394
-    private function visitorIp()
395
-    {
396
-        $visitor_ip = '0.0.0.0';
397
-        $server_keys = array(
398
-            'HTTP_CLIENT_IP',
399
-            'HTTP_X_FORWARDED_FOR',
400
-            'HTTP_X_FORWARDED',
401
-            'HTTP_X_CLUSTER_CLIENT_IP',
402
-            'HTTP_FORWARDED_FOR',
403
-            'HTTP_FORWARDED',
404
-            'REMOTE_ADDR',
405
-        );
406
-        foreach ($server_keys as $key) {
407
-            if (isset($this->server[ $key ])) {
408
-                foreach (array_map('trim', explode(',', $this->server[ $key ])) as $ip) {
409
-                    if ($ip === '127.0.0.1' || filter_var($ip, FILTER_VALIDATE_IP) !== false) {
410
-                        $visitor_ip = $ip;
411
-                    }
412
-                }
413
-            }
414
-        }
415
-        return $visitor_ip;
416
-    }
417
-
418
-
419
-    /**
420
-     * Gets the request's literal URI. Related to `requestUriAfterSiteHomeUri`, see its description for a comparison.
421
-     * @param boolean $relativeToWpRoot If home_url() is "http://mysite.com/wp/", and a request comes to
422
-     *                                  "http://mysite.com/wp/wp-json", setting $relativeToWpRoot=true will return
423
-     *                                  "/wp-json", whereas $relativeToWpRoot=false will return "/wp/wp-json/".
424
-     * @return string
425
-     */
426
-    public function requestUri($relativeToWpRoot = false)
427
-    {
428
-        $request_uri = filter_input(
429
-            INPUT_SERVER,
430
-            'REQUEST_URI',
431
-            FILTER_SANITIZE_URL,
432
-            FILTER_NULL_ON_FAILURE
433
-        );
434
-        if (empty($request_uri)) {
435
-            // fallback sanitization if the above fails
436
-            $request_uri = wp_sanitize_redirect($this->server['REQUEST_URI']);
437
-        }
438
-        if ($relativeToWpRoot) {
439
-            $home_path = untrailingslashit(
440
-                parse_url(
441
-                    home_url(),
442
-                    PHP_URL_PATH
443
-                )
444
-            );
445
-            $request_uri = str_replace(
446
-                $home_path,
447
-                '',
448
-                $request_uri
449
-            );
450
-        }
451
-        return $request_uri;
452
-    }
453
-
454
-    /**
455
-     * @return string
456
-     */
457
-    public function userAgent()
458
-    {
459
-        return $this->user_agent;
460
-    }
461
-
462
-
463
-    /**
464
-     * @param string $user_agent
465
-     */
466
-    public function setUserAgent($user_agent = '')
467
-    {
468
-        if ($user_agent === '' || ! is_string($user_agent)) {
469
-            $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? (string) esc_attr($_SERVER['HTTP_USER_AGENT']) : '';
470
-        }
471
-        $this->user_agent = $user_agent;
472
-    }
473
-
474
-
475
-    /**
476
-     * @return bool
477
-     */
478
-    public function isBot()
479
-    {
480
-        return $this->is_bot;
481
-    }
482
-
483
-
484
-    /**
485
-     * @param bool $is_bot
486
-     */
487
-    public function setIsBot($is_bot)
488
-    {
489
-        $this->is_bot = filter_var($is_bot, FILTER_VALIDATE_BOOLEAN);
490
-    }
491
-
492
-
493
-    /**
494
-     * @return bool
495
-     */
496
-    public function isActivation()
497
-    {
498
-        return $this->request_type->isActivation();
499
-    }
500
-
501
-
502
-    /**
503
-     * @param $is_activation
504
-     * @return bool
505
-     */
506
-    public function setIsActivation($is_activation)
507
-    {
508
-        return $this->request_type->setIsActivation($is_activation);
509
-    }
510
-
511
-
512
-    /**
513
-     * @return bool
514
-     */
515
-    public function isAdmin()
516
-    {
517
-        return $this->request_type->isAdmin();
518
-    }
519
-
520
-
521
-    /**
522
-     * @return bool
523
-     */
524
-    public function isAdminAjax()
525
-    {
526
-        return $this->request_type->isAdminAjax();
527
-    }
528
-
529
-
530
-    /**
531
-     * @return bool
532
-     */
533
-    public function isAjax()
534
-    {
535
-        return $this->request_type->isAjax();
536
-    }
537
-
538
-
539
-    /**
540
-     * @return bool
541
-     */
542
-    public function isEeAjax()
543
-    {
544
-        return $this->request_type->isEeAjax();
545
-    }
546
-
547
-
548
-    /**
549
-     * @return bool
550
-     */
551
-    public function isOtherAjax()
552
-    {
553
-        return $this->request_type->isOtherAjax();
554
-    }
555
-
556
-
557
-    /**
558
-     * @return bool
559
-     */
560
-    public function isApi()
561
-    {
562
-        return $this->request_type->isApi();
563
-    }
564
-
565
-
566
-    /**
567
-     * @return bool
568
-     */
569
-    public function isCli()
570
-    {
571
-        return $this->request_type->isCli();
572
-    }
573
-
574
-
575
-    /**
576
-     * @return bool
577
-     */
578
-    public function isCron()
579
-    {
580
-        return $this->request_type->isCron();
581
-    }
582
-
583
-
584
-    /**
585
-     * @return bool
586
-     */
587
-    public function isFeed()
588
-    {
589
-        return $this->request_type->isFeed();
590
-    }
591
-
592
-
593
-    /**
594
-     * @return bool
595
-     */
596
-    public function isFrontend()
597
-    {
598
-        return $this->request_type->isFrontend();
599
-    }
600
-
601
-
602
-    /**
603
-     * @return bool
604
-     */
605
-    public function isFrontAjax()
606
-    {
607
-        return $this->request_type->isFrontAjax();
608
-    }
609
-
610
-
611
-    /**
612
-     * @return bool
613
-     */
614
-    public function isIframe()
615
-    {
616
-        return $this->request_type->isIframe();
617
-    }
618
-
619
-
620
-    /**
621
-     * @return bool
622
-     */
623
-    public function isWordPressApi()
624
-    {
625
-        return $this->request_type->isWordPressApi();
626
-    }
627
-
628
-
629
-
630
-    /**
631
-     * @return bool
632
-     */
633
-    public function isWordPressHeartbeat()
634
-    {
635
-        return $this->request_type->isWordPressHeartbeat();
636
-    }
637
-
638
-
639
-
640
-    /**
641
-     * @return bool
642
-     */
643
-    public function isWordPressScrape()
644
-    {
645
-        return $this->request_type->isWordPressScrape();
646
-    }
647
-
648
-
649
-    /**
650
-     * @return string
651
-     */
652
-    public function slug()
653
-    {
654
-        return $this->request_type->slug();
655
-    }
20
+	/**
21
+	 * $_GET parameters
22
+	 *
23
+	 * @var array $get
24
+	 */
25
+	private $get;
26
+
27
+	/**
28
+	 * $_POST parameters
29
+	 *
30
+	 * @var array $post
31
+	 */
32
+	private $post;
33
+
34
+	/**
35
+	 * $_COOKIE parameters
36
+	 *
37
+	 * @var array $cookie
38
+	 */
39
+	private $cookie;
40
+
41
+	/**
42
+	 * $_SERVER parameters
43
+	 *
44
+	 * @var array $server
45
+	 */
46
+	private $server;
47
+
48
+	/**
49
+	 * $_FILES parameters
50
+	 *
51
+	 * @var array $files
52
+	 */
53
+	private $files;
54
+
55
+	/**
56
+	 * $_REQUEST parameters
57
+	 *
58
+	 * @var array $request
59
+	 */
60
+	private $request;
61
+
62
+	/**
63
+	 * @var RequestTypeContextCheckerInterface
64
+	 */
65
+	private $request_type;
66
+
67
+	/**
68
+	 * IP address for request
69
+	 *
70
+	 * @var string $ip_address
71
+	 */
72
+	private $ip_address;
73
+
74
+	/**
75
+	 * @var string $user_agent
76
+	 */
77
+	private $user_agent;
78
+
79
+	/**
80
+	 * true if current user appears to be some kind of bot
81
+	 *
82
+	 * @var bool $is_bot
83
+	 */
84
+	private $is_bot;
85
+
86
+
87
+	/**
88
+	 * @param array $get
89
+	 * @param array $post
90
+	 * @param array $cookie
91
+	 * @param array $server
92
+	 * @param array $files
93
+	 */
94
+	public function __construct(array $get, array $post, array $cookie, array $server, array $files = array())
95
+	{
96
+		// grab request vars
97
+		$this->get = $get;
98
+		$this->post = $post;
99
+		$this->cookie = $cookie;
100
+		$this->server = $server;
101
+		$this->files = $files;
102
+		$this->request = array_merge($this->get, $this->post);
103
+		$this->ip_address = $this->visitorIp();
104
+	}
105
+
106
+
107
+	/**
108
+	 * @param RequestTypeContextCheckerInterface $type
109
+	 */
110
+	public function setRequestTypeContextChecker(RequestTypeContextCheckerInterface $type)
111
+	{
112
+		$this->request_type = $type;
113
+	}
114
+
115
+
116
+	/**
117
+	 * @return array
118
+	 */
119
+	public function getParams()
120
+	{
121
+		return $this->get;
122
+	}
123
+
124
+
125
+	/**
126
+	 * @return array
127
+	 */
128
+	public function postParams()
129
+	{
130
+		return $this->post;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @return array
136
+	 */
137
+	public function cookieParams()
138
+	{
139
+		return $this->cookie;
140
+	}
141
+
142
+
143
+	/**
144
+	 * @return array
145
+	 */
146
+	public function serverParams()
147
+	{
148
+		return $this->server;
149
+	}
150
+
151
+
152
+	/**
153
+	 * @return array
154
+	 */
155
+	public function filesParams()
156
+	{
157
+		return $this->files;
158
+	}
159
+
160
+
161
+	/**
162
+	 * returns contents of $_REQUEST
163
+	 *
164
+	 * @return array
165
+	 */
166
+	public function requestParams()
167
+	{
168
+		return $this->request;
169
+	}
170
+
171
+
172
+	/**
173
+	 * @param      $key
174
+	 * @param      $value
175
+	 * @param bool $override_ee
176
+	 * @return    void
177
+	 */
178
+	public function setRequestParam($key, $value, $override_ee = false)
179
+	{
180
+		// don't allow "ee" to be overwritten unless explicitly instructed to do so
181
+		if ($key !== 'ee'
182
+			|| ($key === 'ee' && empty($this->request['ee']))
183
+			|| ($key === 'ee' && ! empty($this->request['ee']) && $override_ee)
184
+		) {
185
+			$this->request[ $key ] = $value;
186
+		}
187
+	}
188
+
189
+
190
+	/**
191
+	 * returns   the value for a request param if the given key exists
192
+	 *
193
+	 * @param       $key
194
+	 * @param null  $default
195
+	 * @return mixed
196
+	 */
197
+	public function getRequestParam($key, $default = null)
198
+	{
199
+		return $this->requestParameterDrillDown($key, $default, 'get');
200
+	}
201
+
202
+
203
+	/**
204
+	 * check if param exists
205
+	 *
206
+	 * @param       $key
207
+	 * @return bool
208
+	 */
209
+	public function requestParamIsSet($key)
210
+	{
211
+		return $this->requestParameterDrillDown($key);
212
+	}
213
+
214
+
215
+	/**
216
+	 * check if a request parameter exists whose key that matches the supplied wildcard pattern
217
+	 * and return the value for the first match found
218
+	 * wildcards can be either of the following:
219
+	 *      ? to represent a single character of any type
220
+	 *      * to represent one or more characters of any type
221
+	 *
222
+	 * @param string     $pattern
223
+	 * @param null|mixed $default
224
+	 * @return mixed
225
+	 */
226
+	public function getMatch($pattern, $default = null)
227
+	{
228
+		return $this->requestParameterDrillDown($pattern, $default, 'match');
229
+	}
230
+
231
+
232
+	/**
233
+	 * check if a request parameter exists whose key matches the supplied wildcard pattern
234
+	 * wildcards can be either of the following:
235
+	 *      ? to represent a single character of any type
236
+	 *      * to represent one or more characters of any type
237
+	 * returns true if a match is found or false if not
238
+	 *
239
+	 * @param string $pattern
240
+	 * @return bool
241
+	 */
242
+	public function matches($pattern)
243
+	{
244
+		return $this->requestParameterDrillDown($pattern, null, 'match') !== null;
245
+	}
246
+
247
+
248
+	/**
249
+	 * @see https://stackoverflow.com/questions/6163055/php-string-matching-with-wildcard
250
+	 * @param string $pattern               A string including wildcards to be converted to a regex pattern
251
+	 *                                      and used to search through the current request's parameter keys
252
+	 * @param array  $request_params        The array of request parameters to search through
253
+	 * @param mixed  $default               [optional] The value to be returned if no match is found.
254
+	 *                                      Default is null
255
+	 * @param string $return                [optional] Controls what kind of value is returned.
256
+	 *                                      Options are:
257
+	 *                                      'bool' will return true or false if match is found or not
258
+	 *                                      'key' will return the first key found that matches the supplied pattern
259
+	 *                                      'value' will return the value for the first request parameter
260
+	 *                                      whose key matches the supplied pattern
261
+	 *                                      Default is 'value'
262
+	 * @return boolean|string
263
+	 */
264
+	private function match($pattern, array $request_params, $default = null, $return = 'value')
265
+	{
266
+		$return = in_array($return, array('bool', 'key', 'value'), true)
267
+			? $return
268
+			: 'is_set';
269
+		// replace wildcard chars with regex chars
270
+		$pattern = str_replace(
271
+			array("\*", "\?"),
272
+			array('.*', '.'),
273
+			preg_quote($pattern, '/')
274
+		);
275
+		foreach ($request_params as $key => $request_param) {
276
+			if (preg_match('/^' . $pattern . '$/is', $key)) {
277
+				// return value for request param
278
+				if ($return === 'value') {
279
+					return $request_params[ $key ];
280
+				}
281
+				// or actual key or true just to indicate it was found
282
+				return $return === 'key' ? $key : true;
283
+			}
284
+		}
285
+		// match not found so return default value or false
286
+		return $return === 'value' ? $default : false;
287
+	}
288
+
289
+
290
+	/**
291
+	 * the supplied key can be a simple string to represent a "top-level" request parameter
292
+	 * or represent a key for a request parameter that is nested deeper within the request parameter array,
293
+	 * by using square brackets to surround keys for deeper array elements.
294
+	 * For example :
295
+	 * if the supplied $key was: "first[second][third]"
296
+	 * then this will attempt to drill down into the request parameter array to find a value.
297
+	 * Given the following request parameters:
298
+	 *  array(
299
+	 *      'first' => array(
300
+	 *          'second' => array(
301
+	 *              'third' => 'has a value'
302
+	 *          )
303
+	 *      )
304
+	 *  )
305
+	 * would return true if default parameters were set
306
+	 *
307
+	 * @param string $callback
308
+	 * @param        $key
309
+	 * @param null   $default
310
+	 * @param array  $request_params
311
+	 * @return bool|mixed|null
312
+	 */
313
+	private function requestParameterDrillDown(
314
+		$key,
315
+		$default = null,
316
+		$callback = 'is_set',
317
+		array $request_params = array()
318
+	) {
319
+		$callback = in_array($callback, array('is_set', 'get', 'match'), true)
320
+			? $callback
321
+			: 'is_set';
322
+		$request_params = ! empty($request_params)
323
+			? $request_params
324
+			: $this->request;
325
+		// does incoming key represent an array like 'first[second][third]'  ?
326
+		if (strpos($key, '[') !== false) {
327
+			// turn it into an actual array
328
+			$key = str_replace(']', '', $key);
329
+			$keys = explode('[', $key);
330
+			$key = array_shift($keys);
331
+			if ($callback === 'match') {
332
+				$real_key = $this->match($key, $request_params, $default, 'key');
333
+				$key = $real_key ? $real_key : $key;
334
+			}
335
+			// check if top level key exists
336
+			if (isset($request_params[ $key ])) {
337
+				// build a new key to pass along like: 'second[third]'
338
+				// or just 'second' depending on depth of keys
339
+				$key_string = array_shift($keys);
340
+				if (! empty($keys)) {
341
+					$key_string .= '[' . implode('][', $keys) . ']';
342
+				}
343
+				return $this->requestParameterDrillDown(
344
+					$key_string,
345
+					$default,
346
+					$callback,
347
+					$request_params[ $key ]
348
+				);
349
+			}
350
+		}
351
+		if ($callback === 'is_set') {
352
+			return isset($request_params[ $key ]);
353
+		}
354
+		if ($callback === 'match') {
355
+			return $this->match($key, $request_params, $default);
356
+		}
357
+		return isset($request_params[ $key ])
358
+			? $request_params[ $key ]
359
+			: $default;
360
+	}
361
+
362
+
363
+	/**
364
+	 * remove param
365
+	 *
366
+	 * @param      $key
367
+	 * @param bool $unset_from_global_too
368
+	 */
369
+	public function unSetRequestParam($key, $unset_from_global_too = false)
370
+	{
371
+		unset($this->request[ $key ]);
372
+		if ($unset_from_global_too) {
373
+			unset($_REQUEST[ $key ]);
374
+		}
375
+	}
376
+
377
+
378
+	/**
379
+	 * @return string
380
+	 */
381
+	public function ipAddress()
382
+	{
383
+		return $this->ip_address;
384
+	}
385
+
386
+
387
+	/**
388
+	 * attempt to get IP address of current visitor from server
389
+	 * plz see: http://stackoverflow.com/a/2031935/1475279
390
+	 *
391
+	 * @access public
392
+	 * @return string
393
+	 */
394
+	private function visitorIp()
395
+	{
396
+		$visitor_ip = '0.0.0.0';
397
+		$server_keys = array(
398
+			'HTTP_CLIENT_IP',
399
+			'HTTP_X_FORWARDED_FOR',
400
+			'HTTP_X_FORWARDED',
401
+			'HTTP_X_CLUSTER_CLIENT_IP',
402
+			'HTTP_FORWARDED_FOR',
403
+			'HTTP_FORWARDED',
404
+			'REMOTE_ADDR',
405
+		);
406
+		foreach ($server_keys as $key) {
407
+			if (isset($this->server[ $key ])) {
408
+				foreach (array_map('trim', explode(',', $this->server[ $key ])) as $ip) {
409
+					if ($ip === '127.0.0.1' || filter_var($ip, FILTER_VALIDATE_IP) !== false) {
410
+						$visitor_ip = $ip;
411
+					}
412
+				}
413
+			}
414
+		}
415
+		return $visitor_ip;
416
+	}
417
+
418
+
419
+	/**
420
+	 * Gets the request's literal URI. Related to `requestUriAfterSiteHomeUri`, see its description for a comparison.
421
+	 * @param boolean $relativeToWpRoot If home_url() is "http://mysite.com/wp/", and a request comes to
422
+	 *                                  "http://mysite.com/wp/wp-json", setting $relativeToWpRoot=true will return
423
+	 *                                  "/wp-json", whereas $relativeToWpRoot=false will return "/wp/wp-json/".
424
+	 * @return string
425
+	 */
426
+	public function requestUri($relativeToWpRoot = false)
427
+	{
428
+		$request_uri = filter_input(
429
+			INPUT_SERVER,
430
+			'REQUEST_URI',
431
+			FILTER_SANITIZE_URL,
432
+			FILTER_NULL_ON_FAILURE
433
+		);
434
+		if (empty($request_uri)) {
435
+			// fallback sanitization if the above fails
436
+			$request_uri = wp_sanitize_redirect($this->server['REQUEST_URI']);
437
+		}
438
+		if ($relativeToWpRoot) {
439
+			$home_path = untrailingslashit(
440
+				parse_url(
441
+					home_url(),
442
+					PHP_URL_PATH
443
+				)
444
+			);
445
+			$request_uri = str_replace(
446
+				$home_path,
447
+				'',
448
+				$request_uri
449
+			);
450
+		}
451
+		return $request_uri;
452
+	}
453
+
454
+	/**
455
+	 * @return string
456
+	 */
457
+	public function userAgent()
458
+	{
459
+		return $this->user_agent;
460
+	}
461
+
462
+
463
+	/**
464
+	 * @param string $user_agent
465
+	 */
466
+	public function setUserAgent($user_agent = '')
467
+	{
468
+		if ($user_agent === '' || ! is_string($user_agent)) {
469
+			$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? (string) esc_attr($_SERVER['HTTP_USER_AGENT']) : '';
470
+		}
471
+		$this->user_agent = $user_agent;
472
+	}
473
+
474
+
475
+	/**
476
+	 * @return bool
477
+	 */
478
+	public function isBot()
479
+	{
480
+		return $this->is_bot;
481
+	}
482
+
483
+
484
+	/**
485
+	 * @param bool $is_bot
486
+	 */
487
+	public function setIsBot($is_bot)
488
+	{
489
+		$this->is_bot = filter_var($is_bot, FILTER_VALIDATE_BOOLEAN);
490
+	}
491
+
492
+
493
+	/**
494
+	 * @return bool
495
+	 */
496
+	public function isActivation()
497
+	{
498
+		return $this->request_type->isActivation();
499
+	}
500
+
501
+
502
+	/**
503
+	 * @param $is_activation
504
+	 * @return bool
505
+	 */
506
+	public function setIsActivation($is_activation)
507
+	{
508
+		return $this->request_type->setIsActivation($is_activation);
509
+	}
510
+
511
+
512
+	/**
513
+	 * @return bool
514
+	 */
515
+	public function isAdmin()
516
+	{
517
+		return $this->request_type->isAdmin();
518
+	}
519
+
520
+
521
+	/**
522
+	 * @return bool
523
+	 */
524
+	public function isAdminAjax()
525
+	{
526
+		return $this->request_type->isAdminAjax();
527
+	}
528
+
529
+
530
+	/**
531
+	 * @return bool
532
+	 */
533
+	public function isAjax()
534
+	{
535
+		return $this->request_type->isAjax();
536
+	}
537
+
538
+
539
+	/**
540
+	 * @return bool
541
+	 */
542
+	public function isEeAjax()
543
+	{
544
+		return $this->request_type->isEeAjax();
545
+	}
546
+
547
+
548
+	/**
549
+	 * @return bool
550
+	 */
551
+	public function isOtherAjax()
552
+	{
553
+		return $this->request_type->isOtherAjax();
554
+	}
555
+
556
+
557
+	/**
558
+	 * @return bool
559
+	 */
560
+	public function isApi()
561
+	{
562
+		return $this->request_type->isApi();
563
+	}
564
+
565
+
566
+	/**
567
+	 * @return bool
568
+	 */
569
+	public function isCli()
570
+	{
571
+		return $this->request_type->isCli();
572
+	}
573
+
574
+
575
+	/**
576
+	 * @return bool
577
+	 */
578
+	public function isCron()
579
+	{
580
+		return $this->request_type->isCron();
581
+	}
582
+
583
+
584
+	/**
585
+	 * @return bool
586
+	 */
587
+	public function isFeed()
588
+	{
589
+		return $this->request_type->isFeed();
590
+	}
591
+
592
+
593
+	/**
594
+	 * @return bool
595
+	 */
596
+	public function isFrontend()
597
+	{
598
+		return $this->request_type->isFrontend();
599
+	}
600
+
601
+
602
+	/**
603
+	 * @return bool
604
+	 */
605
+	public function isFrontAjax()
606
+	{
607
+		return $this->request_type->isFrontAjax();
608
+	}
609
+
610
+
611
+	/**
612
+	 * @return bool
613
+	 */
614
+	public function isIframe()
615
+	{
616
+		return $this->request_type->isIframe();
617
+	}
618
+
619
+
620
+	/**
621
+	 * @return bool
622
+	 */
623
+	public function isWordPressApi()
624
+	{
625
+		return $this->request_type->isWordPressApi();
626
+	}
627
+
628
+
629
+
630
+	/**
631
+	 * @return bool
632
+	 */
633
+	public function isWordPressHeartbeat()
634
+	{
635
+		return $this->request_type->isWordPressHeartbeat();
636
+	}
637
+
638
+
639
+
640
+	/**
641
+	 * @return bool
642
+	 */
643
+	public function isWordPressScrape()
644
+	{
645
+		return $this->request_type->isWordPressScrape();
646
+	}
647
+
648
+
649
+	/**
650
+	 * @return string
651
+	 */
652
+	public function slug()
653
+	{
654
+		return $this->request_type->slug();
655
+	}
656 656
 }
Please login to merge, or discard this patch.
core/services/request/RequestInterface.php 1 patch
Indentation   +123 added lines, -123 removed lines patch added patch discarded remove patch
@@ -16,146 +16,146 @@
 block discarded – undo
16 16
 interface RequestInterface extends RequestTypeContextCheckerInterface
17 17
 {
18 18
 
19
-    /**
20
-     * @param RequestTypeContextCheckerInterface $type
21
-     */
22
-    public function setRequestTypeContextChecker(RequestTypeContextCheckerInterface $type);
23
-
24
-    /**
25
-     * @return array
26
-     */
27
-    public function getParams();
28
-
29
-
30
-    /**
31
-     * @return array
32
-     */
33
-    public function postParams();
34
-
35
-
36
-    /**
37
-     * @return array
38
-     */
39
-    public function cookieParams();
40
-
41
-
42
-    /**
43
-     * @return array
44
-     */
45
-    public function serverParams();
46
-
47
-
48
-    /**
49
-     * @return array
50
-     */
51
-    public function filesParams();
19
+	/**
20
+	 * @param RequestTypeContextCheckerInterface $type
21
+	 */
22
+	public function setRequestTypeContextChecker(RequestTypeContextCheckerInterface $type);
23
+
24
+	/**
25
+	 * @return array
26
+	 */
27
+	public function getParams();
28
+
29
+
30
+	/**
31
+	 * @return array
32
+	 */
33
+	public function postParams();
34
+
35
+
36
+	/**
37
+	 * @return array
38
+	 */
39
+	public function cookieParams();
40
+
41
+
42
+	/**
43
+	 * @return array
44
+	 */
45
+	public function serverParams();
46
+
47
+
48
+	/**
49
+	 * @return array
50
+	 */
51
+	public function filesParams();
52 52
 
53 53
 
54
-    /**
55
-     * returns contents of $_REQUEST
56
-     *
57
-     * @return array
58
-     */
59
-    public function requestParams();
54
+	/**
55
+	 * returns contents of $_REQUEST
56
+	 *
57
+	 * @return array
58
+	 */
59
+	public function requestParams();
60 60
 
61 61
 
62
-    /**
63
-     * @param string $key
64
-     * @param string $value
65
-     * @param bool   $override_ee
66
-     * @return    void
67
-     */
68
-    public function setRequestParam($key, $value, $override_ee = false);
62
+	/**
63
+	 * @param string $key
64
+	 * @param string $value
65
+	 * @param bool   $override_ee
66
+	 * @return    void
67
+	 */
68
+	public function setRequestParam($key, $value, $override_ee = false);
69 69
 
70 70
 
71
-    /**
72
-     * returns the value for a request param if the given key exists
73
-     *
74
-     * @param string $key
75
-     * @param null   $default
76
-     * @return mixed
77
-     */
78
-    public function getRequestParam($key, $default = null);
71
+	/**
72
+	 * returns the value for a request param if the given key exists
73
+	 *
74
+	 * @param string $key
75
+	 * @param null   $default
76
+	 * @return mixed
77
+	 */
78
+	public function getRequestParam($key, $default = null);
79 79
 
80 80
 
81
-    /**
82
-     * check if param exists
83
-     *
84
-     * @param string $key
85
-     * @return bool
86
-     */
87
-    public function requestParamIsSet($key);
81
+	/**
82
+	 * check if param exists
83
+	 *
84
+	 * @param string $key
85
+	 * @return bool
86
+	 */
87
+	public function requestParamIsSet($key);
88 88
 
89 89
 
90
-    /**
91
-     * check if a request parameter exists whose key that matches the supplied wildcard pattern
92
-     * and return the value for the first match found
93
-     * wildcards can be either of the following:
94
-     *      ? to represent a single character of any type
95
-     *      * to represent one or more characters of any type
96
-     *
97
-     * @param string     $pattern
98
-     * @param null|mixed $default
99
-     * @return false|int
100
-     */
101
-    public function getMatch($pattern, $default = null);
90
+	/**
91
+	 * check if a request parameter exists whose key that matches the supplied wildcard pattern
92
+	 * and return the value for the first match found
93
+	 * wildcards can be either of the following:
94
+	 *      ? to represent a single character of any type
95
+	 *      * to represent one or more characters of any type
96
+	 *
97
+	 * @param string     $pattern
98
+	 * @param null|mixed $default
99
+	 * @return false|int
100
+	 */
101
+	public function getMatch($pattern, $default = null);
102 102
 
103 103
 
104
-    /**
105
-     * check if a request parameter exists whose key matches the supplied wildcard pattern
106
-     * wildcards can be either of the following:
107
-     *      ? to represent a single character of any type
108
-     *      * to represent one or more characters of any type
109
-     * returns true if a match is found or false if not
110
-     *
111
-     * @param string $pattern
112
-     * @return false|int
113
-     */
114
-    public function matches($pattern);
104
+	/**
105
+	 * check if a request parameter exists whose key matches the supplied wildcard pattern
106
+	 * wildcards can be either of the following:
107
+	 *      ? to represent a single character of any type
108
+	 *      * to represent one or more characters of any type
109
+	 * returns true if a match is found or false if not
110
+	 *
111
+	 * @param string $pattern
112
+	 * @return false|int
113
+	 */
114
+	public function matches($pattern);
115 115
 
116 116
 
117
-    /**
118
-     * remove param
119
-     *
120
-     * @param string $key
121
-     * @param bool   $unset_from_global_too
122
-     */
123
-    public function unSetRequestParam($key, $unset_from_global_too = false);
117
+	/**
118
+	 * remove param
119
+	 *
120
+	 * @param string $key
121
+	 * @param bool   $unset_from_global_too
122
+	 */
123
+	public function unSetRequestParam($key, $unset_from_global_too = false);
124 124
 
125 125
 
126
-    /**
127
-     * @return string
128
-     */
129
-    public function ipAddress();
126
+	/**
127
+	 * @return string
128
+	 */
129
+	public function ipAddress();
130 130
 
131 131
 
132
-    /**
133
-     * @param boolean $relativeToWpRoot whether to return the uri relative to WordPress' home URL, or not.
134
-     * @return string
135
-     */
136
-    public function requestUri($relativeToWpRoot = false);
137
-
132
+	/**
133
+	 * @param boolean $relativeToWpRoot whether to return the uri relative to WordPress' home URL, or not.
134
+	 * @return string
135
+	 */
136
+	public function requestUri($relativeToWpRoot = false);
137
+
138 138
 
139
-    /**
140
-     * @return string
141
-     */
142
-    public function userAgent();
143
-
144
-
145
-    /**
146
-     * @param string $user_agent
147
-     */
148
-    public function setUserAgent($user_agent = '');
149
-
150
-
151
-    /**
152
-     * @return bool
153
-     */
154
-    public function isBot();
155
-
156
-
157
-    /**
158
-     * @param bool $is_bot
159
-     */
160
-    public function setIsBot($is_bot);
139
+	/**
140
+	 * @return string
141
+	 */
142
+	public function userAgent();
143
+
144
+
145
+	/**
146
+	 * @param string $user_agent
147
+	 */
148
+	public function setUserAgent($user_agent = '');
149
+
150
+
151
+	/**
152
+	 * @return bool
153
+	 */
154
+	public function isBot();
155
+
156
+
157
+	/**
158
+	 * @param bool $is_bot
159
+	 */
160
+	public function setIsBot($is_bot);
161 161
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Event.class.php 1 patch
Indentation   +1353 added lines, -1353 removed lines patch added patch discarded remove patch
@@ -13,1357 +13,1357 @@
 block discarded – undo
13 13
 class EE_Event extends EE_CPT_Base implements EEI_Line_Item_Object, EEI_Admin_Links, EEI_Has_Icon, EEI_Event
14 14
 {
15 15
 
16
-    /**
17
-     * cached value for the the logical active status for the event
18
-     *
19
-     * @see get_active_status()
20
-     * @var string
21
-     */
22
-    protected $_active_status = '';
23
-
24
-    /**
25
-     * This is just used for caching the Primary Datetime for the Event on initial retrieval
26
-     *
27
-     * @var EE_Datetime
28
-     */
29
-    protected $_Primary_Datetime;
30
-
31
-    /**
32
-     * @var EventSpacesCalculator $available_spaces_calculator
33
-     */
34
-    protected $available_spaces_calculator;
35
-
36
-
37
-    /**
38
-     * @param array  $props_n_values          incoming values
39
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
40
-     *                                        used.)
41
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
42
-     *                                        date_format and the second value is the time format
43
-     * @return EE_Event
44
-     * @throws EE_Error
45
-     */
46
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
47
-    {
48
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
49
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
50
-    }
51
-
52
-
53
-    /**
54
-     * @param array  $props_n_values  incoming values from the database
55
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
56
-     *                                the website will be used.
57
-     * @return EE_Event
58
-     * @throws EE_Error
59
-     */
60
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
61
-    {
62
-        return new self($props_n_values, true, $timezone);
63
-    }
64
-
65
-
66
-    /**
67
-     * @return EventSpacesCalculator
68
-     * @throws \EE_Error
69
-     */
70
-    public function getAvailableSpacesCalculator()
71
-    {
72
-        if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
73
-            $this->available_spaces_calculator = new EventSpacesCalculator($this);
74
-        }
75
-        return $this->available_spaces_calculator;
76
-    }
77
-
78
-
79
-    /**
80
-     * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
81
-     *
82
-     * @param string $field_name
83
-     * @param mixed  $field_value
84
-     * @param bool   $use_default
85
-     * @throws EE_Error
86
-     */
87
-    public function set($field_name, $field_value, $use_default = false)
88
-    {
89
-        switch ($field_name) {
90
-            case 'status':
91
-                $this->set_status($field_value, $use_default);
92
-                break;
93
-            default:
94
-                parent::set($field_name, $field_value, $use_default);
95
-        }
96
-    }
97
-
98
-
99
-    /**
100
-     *    set_status
101
-     * Checks if event status is being changed to SOLD OUT
102
-     * and updates event meta data with previous event status
103
-     * so that we can revert things if/when the event is no longer sold out
104
-     *
105
-     * @access public
106
-     * @param string $new_status
107
-     * @param bool   $use_default
108
-     * @return void
109
-     * @throws EE_Error
110
-     */
111
-    public function set_status($new_status = null, $use_default = false)
112
-    {
113
-        // if nothing is set, and we aren't explicitly wanting to reset the status, then just leave
114
-        if (empty($new_status) && ! $use_default) {
115
-            return;
116
-        }
117
-        // get current Event status
118
-        $old_status = $this->status();
119
-        // if status has changed
120
-        if ($old_status !== $new_status) {
121
-            // TO sold_out
122
-            if ($new_status === EEM_Event::sold_out) {
123
-                // save the previous event status so that we can revert if the event is no longer sold out
124
-                $this->add_post_meta('_previous_event_status', $old_status);
125
-                do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
126
-                // OR FROM  sold_out
127
-            } elseif ($old_status === EEM_Event::sold_out) {
128
-                $this->delete_post_meta('_previous_event_status');
129
-                do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
130
-            }
131
-            // clear out the active status so that it gets reset the next time it is requested
132
-            $this->_active_status = null;
133
-            // update status
134
-            parent::set('status', $new_status, $use_default);
135
-            do_action('AHEE__EE_Event__set_status__after_update', $this);
136
-            return;
137
-        }
138
-        // even though the old value matches the new value, it's still good to
139
-        // allow the parent set method to have a say
140
-        parent::set('status', $new_status, $use_default);
141
-    }
142
-
143
-
144
-    /**
145
-     * Gets all the datetimes for this event
146
-     *
147
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
148
-     * @return EE_Base_Class[]|EE_Datetime[]
149
-     * @throws EE_Error
150
-     */
151
-    public function datetimes($query_params = array())
152
-    {
153
-        return $this->get_many_related('Datetime', $query_params);
154
-    }
155
-
156
-
157
-    /**
158
-     * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
159
-     *
160
-     * @return EE_Base_Class[]|EE_Datetime[]
161
-     * @throws EE_Error
162
-     */
163
-    public function datetimes_in_chronological_order()
164
-    {
165
-        return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
166
-    }
167
-
168
-
169
-    /**
170
-     * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
171
-     * @darren, we should probably UNSET timezone on the EEM_Datetime model
172
-     * after running our query, so that this timezone isn't set for EVERY query
173
-     * on EEM_Datetime for the rest of the request, no?
174
-     *
175
-     * @param boolean $show_expired whether or not to include expired events
176
-     * @param boolean $show_deleted whether or not to include deleted events
177
-     * @param null    $limit
178
-     * @return EE_Datetime[]
179
-     * @throws EE_Error
180
-     */
181
-    public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
182
-    {
183
-        return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
184
-            $this->ID(),
185
-            $show_expired,
186
-            $show_deleted,
187
-            $limit
188
-        );
189
-    }
190
-
191
-
192
-    /**
193
-     * Returns one related datetime. Mostly only used by some legacy code.
194
-     *
195
-     * @return EE_Base_Class|EE_Datetime
196
-     * @throws EE_Error
197
-     */
198
-    public function first_datetime()
199
-    {
200
-        return $this->get_first_related('Datetime');
201
-    }
202
-
203
-
204
-    /**
205
-     * Returns the 'primary' datetime for the event
206
-     *
207
-     * @param bool $try_to_exclude_expired
208
-     * @param bool $try_to_exclude_deleted
209
-     * @return EE_Datetime
210
-     * @throws EE_Error
211
-     */
212
-    public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
213
-    {
214
-        if (! empty($this->_Primary_Datetime)) {
215
-            return $this->_Primary_Datetime;
216
-        }
217
-        $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
218
-            $this->ID(),
219
-            $try_to_exclude_expired,
220
-            $try_to_exclude_deleted
221
-        );
222
-        return $this->_Primary_Datetime;
223
-    }
224
-
225
-
226
-    /**
227
-     * Gets all the tickets available for purchase of this event
228
-     *
229
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
230
-     * @return EE_Base_Class[]|EE_Ticket[]
231
-     * @throws EE_Error
232
-     */
233
-    public function tickets($query_params = array())
234
-    {
235
-        // first get all datetimes
236
-        $datetimes = $this->datetimes_ordered();
237
-        if (! $datetimes) {
238
-            return array();
239
-        }
240
-        $datetime_ids = array();
241
-        foreach ($datetimes as $datetime) {
242
-            $datetime_ids[] = $datetime->ID();
243
-        }
244
-        $where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
245
-        // if incoming $query_params has where conditions let's merge but not override existing.
246
-        if (is_array($query_params) && isset($query_params[0])) {
247
-            $where_params = array_merge($query_params[0], $where_params);
248
-            unset($query_params[0]);
249
-        }
250
-        // now add $where_params to $query_params
251
-        $query_params[0] = $where_params;
252
-        return EEM_Ticket::instance()->get_all($query_params);
253
-    }
254
-
255
-
256
-    /**
257
-     * get all unexpired untrashed tickets
258
-     *
259
-     * @return EE_Ticket[]
260
-     * @throws EE_Error
261
-     */
262
-    public function active_tickets()
263
-    {
264
-        return $this->tickets(
265
-            array(
266
-                array(
267
-                    'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
268
-                    'TKT_deleted'  => false,
269
-                ),
270
-            )
271
-        );
272
-    }
273
-
274
-
275
-    /**
276
-     * @return bool
277
-     * @throws EE_Error
278
-     */
279
-    public function additional_limit()
280
-    {
281
-        return $this->get('EVT_additional_limit');
282
-    }
283
-
284
-
285
-    /**
286
-     * @return bool
287
-     * @throws EE_Error
288
-     */
289
-    public function allow_overflow()
290
-    {
291
-        return $this->get('EVT_allow_overflow');
292
-    }
293
-
294
-
295
-    /**
296
-     * @return bool
297
-     * @throws EE_Error
298
-     */
299
-    public function created()
300
-    {
301
-        return $this->get('EVT_created');
302
-    }
303
-
304
-
305
-    /**
306
-     * @return bool
307
-     * @throws EE_Error
308
-     */
309
-    public function description()
310
-    {
311
-        return $this->get('EVT_desc');
312
-    }
313
-
314
-
315
-    /**
316
-     * Runs do_shortcode and wpautop on the description
317
-     *
318
-     * @return string of html
319
-     * @throws EE_Error
320
-     */
321
-    public function description_filtered()
322
-    {
323
-        return $this->get_pretty('EVT_desc');
324
-    }
325
-
326
-
327
-    /**
328
-     * @return bool
329
-     * @throws EE_Error
330
-     */
331
-    public function display_description()
332
-    {
333
-        return $this->get('EVT_display_desc');
334
-    }
335
-
336
-
337
-    /**
338
-     * @return bool
339
-     * @throws EE_Error
340
-     */
341
-    public function display_ticket_selector()
342
-    {
343
-        return (bool) $this->get('EVT_display_ticket_selector');
344
-    }
345
-
346
-
347
-    /**
348
-     * @return bool
349
-     * @throws EE_Error
350
-     */
351
-    public function external_url()
352
-    {
353
-        return $this->get('EVT_external_URL');
354
-    }
355
-
356
-
357
-    /**
358
-     * @return bool
359
-     * @throws EE_Error
360
-     */
361
-    public function member_only()
362
-    {
363
-        return $this->get('EVT_member_only');
364
-    }
365
-
366
-
367
-    /**
368
-     * @return bool
369
-     * @throws EE_Error
370
-     */
371
-    public function phone()
372
-    {
373
-        return $this->get('EVT_phone');
374
-    }
375
-
376
-
377
-    /**
378
-     * @return bool
379
-     * @throws EE_Error
380
-     */
381
-    public function modified()
382
-    {
383
-        return $this->get('EVT_modified');
384
-    }
385
-
386
-
387
-    /**
388
-     * @return bool
389
-     * @throws EE_Error
390
-     */
391
-    public function name()
392
-    {
393
-        return $this->get('EVT_name');
394
-    }
395
-
396
-
397
-    /**
398
-     * @return bool
399
-     * @throws EE_Error
400
-     */
401
-    public function order()
402
-    {
403
-        return $this->get('EVT_order');
404
-    }
405
-
406
-
407
-    /**
408
-     * @return bool|string
409
-     * @throws EE_Error
410
-     */
411
-    public function default_registration_status()
412
-    {
413
-        $event_default_registration_status = $this->get('EVT_default_registration_status');
414
-        return ! empty($event_default_registration_status)
415
-            ? $event_default_registration_status
416
-            : EE_Registry::instance()->CFG->registration->default_STS_ID;
417
-    }
418
-
419
-
420
-    /**
421
-     * @param int  $num_words
422
-     * @param null $more
423
-     * @param bool $not_full_desc
424
-     * @return bool|string
425
-     * @throws EE_Error
426
-     */
427
-    public function short_description($num_words = 55, $more = null, $not_full_desc = false)
428
-    {
429
-        $short_desc = $this->get('EVT_short_desc');
430
-        if (! empty($short_desc) || $not_full_desc) {
431
-            return $short_desc;
432
-        }
433
-        $full_desc = $this->get('EVT_desc');
434
-        return wp_trim_words($full_desc, $num_words, $more);
435
-    }
436
-
437
-
438
-    /**
439
-     * @return bool
440
-     * @throws EE_Error
441
-     */
442
-    public function slug()
443
-    {
444
-        return $this->get('EVT_slug');
445
-    }
446
-
447
-
448
-    /**
449
-     * @return bool
450
-     * @throws EE_Error
451
-     */
452
-    public function timezone_string()
453
-    {
454
-        return $this->get('EVT_timezone_string');
455
-    }
456
-
457
-
458
-    /**
459
-     * @return bool
460
-     * @throws EE_Error
461
-     */
462
-    public function visible_on()
463
-    {
464
-        return $this->get('EVT_visible_on');
465
-    }
466
-
467
-
468
-    /**
469
-     * @return int
470
-     * @throws EE_Error
471
-     */
472
-    public function wp_user()
473
-    {
474
-        return $this->get('EVT_wp_user');
475
-    }
476
-
477
-
478
-    /**
479
-     * @return bool
480
-     * @throws EE_Error
481
-     */
482
-    public function donations()
483
-    {
484
-        return $this->get('EVT_donations');
485
-    }
486
-
487
-
488
-    /**
489
-     * @param $limit
490
-     * @throws EE_Error
491
-     */
492
-    public function set_additional_limit($limit)
493
-    {
494
-        $this->set('EVT_additional_limit', $limit);
495
-    }
496
-
497
-
498
-    /**
499
-     * @param $created
500
-     * @throws EE_Error
501
-     */
502
-    public function set_created($created)
503
-    {
504
-        $this->set('EVT_created', $created);
505
-    }
506
-
507
-
508
-    /**
509
-     * @param $desc
510
-     * @throws EE_Error
511
-     */
512
-    public function set_description($desc)
513
-    {
514
-        $this->set('EVT_desc', $desc);
515
-    }
516
-
517
-
518
-    /**
519
-     * @param $display_desc
520
-     * @throws EE_Error
521
-     */
522
-    public function set_display_description($display_desc)
523
-    {
524
-        $this->set('EVT_display_desc', $display_desc);
525
-    }
526
-
527
-
528
-    /**
529
-     * @param $display_ticket_selector
530
-     * @throws EE_Error
531
-     */
532
-    public function set_display_ticket_selector($display_ticket_selector)
533
-    {
534
-        $this->set('EVT_display_ticket_selector', $display_ticket_selector);
535
-    }
536
-
537
-
538
-    /**
539
-     * @param $external_url
540
-     * @throws EE_Error
541
-     */
542
-    public function set_external_url($external_url)
543
-    {
544
-        $this->set('EVT_external_URL', $external_url);
545
-    }
546
-
547
-
548
-    /**
549
-     * @param $member_only
550
-     * @throws EE_Error
551
-     */
552
-    public function set_member_only($member_only)
553
-    {
554
-        $this->set('EVT_member_only', $member_only);
555
-    }
556
-
557
-
558
-    /**
559
-     * @param $event_phone
560
-     * @throws EE_Error
561
-     */
562
-    public function set_event_phone($event_phone)
563
-    {
564
-        $this->set('EVT_phone', $event_phone);
565
-    }
566
-
567
-
568
-    /**
569
-     * @param $modified
570
-     * @throws EE_Error
571
-     */
572
-    public function set_modified($modified)
573
-    {
574
-        $this->set('EVT_modified', $modified);
575
-    }
576
-
577
-
578
-    /**
579
-     * @param $name
580
-     * @throws EE_Error
581
-     */
582
-    public function set_name($name)
583
-    {
584
-        $this->set('EVT_name', $name);
585
-    }
586
-
587
-
588
-    /**
589
-     * @param $order
590
-     * @throws EE_Error
591
-     */
592
-    public function set_order($order)
593
-    {
594
-        $this->set('EVT_order', $order);
595
-    }
596
-
597
-
598
-    /**
599
-     * @param $short_desc
600
-     * @throws EE_Error
601
-     */
602
-    public function set_short_description($short_desc)
603
-    {
604
-        $this->set('EVT_short_desc', $short_desc);
605
-    }
606
-
607
-
608
-    /**
609
-     * @param $slug
610
-     * @throws EE_Error
611
-     */
612
-    public function set_slug($slug)
613
-    {
614
-        $this->set('EVT_slug', $slug);
615
-    }
616
-
617
-
618
-    /**
619
-     * @param $timezone_string
620
-     * @throws EE_Error
621
-     */
622
-    public function set_timezone_string($timezone_string)
623
-    {
624
-        $this->set('EVT_timezone_string', $timezone_string);
625
-    }
626
-
627
-
628
-    /**
629
-     * @param $visible_on
630
-     * @throws EE_Error
631
-     */
632
-    public function set_visible_on($visible_on)
633
-    {
634
-        $this->set('EVT_visible_on', $visible_on);
635
-    }
636
-
637
-
638
-    /**
639
-     * @param $wp_user
640
-     * @throws EE_Error
641
-     */
642
-    public function set_wp_user($wp_user)
643
-    {
644
-        $this->set('EVT_wp_user', $wp_user);
645
-    }
646
-
647
-
648
-    /**
649
-     * @param $default_registration_status
650
-     * @throws EE_Error
651
-     */
652
-    public function set_default_registration_status($default_registration_status)
653
-    {
654
-        $this->set('EVT_default_registration_status', $default_registration_status);
655
-    }
656
-
657
-
658
-    /**
659
-     * @param $donations
660
-     * @throws EE_Error
661
-     */
662
-    public function set_donations($donations)
663
-    {
664
-        $this->set('EVT_donations', $donations);
665
-    }
666
-
667
-
668
-    /**
669
-     * Adds a venue to this event
670
-     *
671
-     * @param EE_Venue /int $venue_id_or_obj
672
-     * @return EE_Base_Class|EE_Venue
673
-     * @throws EE_Error
674
-     */
675
-    public function add_venue($venue_id_or_obj)
676
-    {
677
-        return $this->_add_relation_to($venue_id_or_obj, 'Venue');
678
-    }
679
-
680
-
681
-    /**
682
-     * Removes a venue from the event
683
-     *
684
-     * @param EE_Venue /int $venue_id_or_obj
685
-     * @return EE_Base_Class|EE_Venue
686
-     * @throws EE_Error
687
-     */
688
-    public function remove_venue($venue_id_or_obj)
689
-    {
690
-        return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
691
-    }
692
-
693
-
694
-    /**
695
-     * Gets all the venues related ot the event. May provide additional $query_params if desired
696
-     *
697
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
698
-     * @return EE_Base_Class[]|EE_Venue[]
699
-     * @throws EE_Error
700
-     */
701
-    public function venues($query_params = array())
702
-    {
703
-        return $this->get_many_related('Venue', $query_params);
704
-    }
705
-
706
-
707
-    /**
708
-     * check if event id is present and if event is published
709
-     *
710
-     * @access public
711
-     * @return boolean true yes, false no
712
-     * @throws EE_Error
713
-     */
714
-    private function _has_ID_and_is_published()
715
-    {
716
-        // first check if event id is present and not NULL,
717
-        // then check if this event is published (or any of the equivalent "published" statuses)
718
-        return
719
-            $this->ID() && $this->ID() !== null
720
-            && (
721
-                $this->status() === 'publish'
722
-                || $this->status() === EEM_Event::sold_out
723
-                || $this->status() === EEM_Event::postponed
724
-                || $this->status() === EEM_Event::cancelled
725
-            );
726
-    }
727
-
728
-
729
-    /**
730
-     * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
731
-     *
732
-     * @access public
733
-     * @return boolean true yes, false no
734
-     * @throws EE_Error
735
-     */
736
-    public function is_upcoming()
737
-    {
738
-        // check if event id is present and if this event is published
739
-        if ($this->is_inactive()) {
740
-            return false;
741
-        }
742
-        // set initial value
743
-        $upcoming = false;
744
-        // next let's get all datetimes and loop through them
745
-        $datetimes = $this->datetimes_in_chronological_order();
746
-        foreach ($datetimes as $datetime) {
747
-            if ($datetime instanceof EE_Datetime) {
748
-                // if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
749
-                if ($datetime->is_expired()) {
750
-                    continue;
751
-                }
752
-                // if this dtt is active then we return false.
753
-                if ($datetime->is_active()) {
754
-                    return false;
755
-                }
756
-                // otherwise let's check upcoming status
757
-                $upcoming = $datetime->is_upcoming();
758
-            }
759
-        }
760
-        return $upcoming;
761
-    }
762
-
763
-
764
-    /**
765
-     * @return bool
766
-     * @throws EE_Error
767
-     */
768
-    public function is_active()
769
-    {
770
-        // check if event id is present and if this event is published
771
-        if ($this->is_inactive()) {
772
-            return false;
773
-        }
774
-        // set initial value
775
-        $active = false;
776
-        // next let's get all datetimes and loop through them
777
-        $datetimes = $this->datetimes_in_chronological_order();
778
-        foreach ($datetimes as $datetime) {
779
-            if ($datetime instanceof EE_Datetime) {
780
-                // if this dtt is expired then we continue cause one of the other datetimes might be active.
781
-                if ($datetime->is_expired()) {
782
-                    continue;
783
-                }
784
-                // if this dtt is upcoming then we return false.
785
-                if ($datetime->is_upcoming()) {
786
-                    return false;
787
-                }
788
-                // otherwise let's check active status
789
-                $active = $datetime->is_active();
790
-            }
791
-        }
792
-        return $active;
793
-    }
794
-
795
-
796
-    /**
797
-     * @return bool
798
-     * @throws EE_Error
799
-     */
800
-    public function is_expired()
801
-    {
802
-        // check if event id is present and if this event is published
803
-        if ($this->is_inactive()) {
804
-            return false;
805
-        }
806
-        // set initial value
807
-        $expired = false;
808
-        // first let's get all datetimes and loop through them
809
-        $datetimes = $this->datetimes_in_chronological_order();
810
-        foreach ($datetimes as $datetime) {
811
-            if ($datetime instanceof EE_Datetime) {
812
-                // if this dtt is upcoming or active then we return false.
813
-                if ($datetime->is_upcoming() || $datetime->is_active()) {
814
-                    return false;
815
-                }
816
-                // otherwise let's check active status
817
-                $expired = $datetime->is_expired();
818
-            }
819
-        }
820
-        return $expired;
821
-    }
822
-
823
-
824
-    /**
825
-     * @return bool
826
-     * @throws EE_Error
827
-     */
828
-    public function is_inactive()
829
-    {
830
-        // check if event id is present and if this event is published
831
-        if ($this->_has_ID_and_is_published()) {
832
-            return false;
833
-        }
834
-        return true;
835
-    }
836
-
837
-
838
-    /**
839
-     * calculate spaces remaining based on "saleable" tickets
840
-     *
841
-     * @param array $tickets
842
-     * @param bool  $filtered
843
-     * @return int|float
844
-     * @throws EE_Error
845
-     * @throws DomainException
846
-     * @throws UnexpectedEntityException
847
-     */
848
-    public function spaces_remaining($tickets = array(), $filtered = true)
849
-    {
850
-        $this->getAvailableSpacesCalculator()->setActiveTickets($tickets);
851
-        $spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining();
852
-        return $filtered
853
-            ? apply_filters(
854
-                'FHEE_EE_Event__spaces_remaining',
855
-                $spaces_remaining,
856
-                $this,
857
-                $tickets
858
-            )
859
-            : $spaces_remaining;
860
-    }
861
-
862
-
863
-    /**
864
-     *    perform_sold_out_status_check
865
-     *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
866
-     *    available... if NOT, then the event status will get toggled to 'sold_out'
867
-     *
868
-     * @return bool    return the ACTUAL sold out state.
869
-     * @throws EE_Error
870
-     * @throws DomainException
871
-     * @throws UnexpectedEntityException
872
-     */
873
-    public function perform_sold_out_status_check()
874
-    {
875
-        // get all tickets
876
-        $tickets = $this->tickets(
877
-            array(
878
-                'default_where_conditions' => 'none',
879
-                'order_by' => array('TKT_qty' => 'ASC'),
880
-            )
881
-        );
882
-        $all_expired = true;
883
-        foreach ($tickets as $ticket) {
884
-            if (! $ticket->is_expired()) {
885
-                $all_expired = false;
886
-                break;
887
-            }
888
-        }
889
-        // if all the tickets are just expired, then don't update the event status to sold out
890
-        if ($all_expired) {
891
-            return true;
892
-        }
893
-        $spaces_remaining = $this->spaces_remaining($tickets);
894
-        if ($spaces_remaining < 1) {
895
-            if ($this->status() !== EEM_Event::post_status_private) {
896
-                $this->set_status(EEM_Event::sold_out);
897
-                $this->save();
898
-            }
899
-            $sold_out = true;
900
-        } else {
901
-            $sold_out = false;
902
-            // was event previously marked as sold out ?
903
-            if ($this->status() === EEM_Event::sold_out) {
904
-                // revert status to previous value, if it was set
905
-                $previous_event_status = $this->get_post_meta('_previous_event_status', true);
906
-                if ($previous_event_status) {
907
-                    $this->set_status($previous_event_status);
908
-                    $this->save();
909
-                }
910
-            }
911
-        }
912
-        do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets);
913
-        return $sold_out;
914
-    }
915
-
916
-
917
-    /**
918
-     * This returns the total remaining spaces for sale on this event.
919
-     *
920
-     * @uses EE_Event::total_available_spaces()
921
-     * @return float|int
922
-     * @throws EE_Error
923
-     * @throws DomainException
924
-     * @throws UnexpectedEntityException
925
-     */
926
-    public function spaces_remaining_for_sale()
927
-    {
928
-        return $this->total_available_spaces(true);
929
-    }
930
-
931
-
932
-    /**
933
-     * This returns the total spaces available for an event
934
-     * while considering all the qtys on the tickets and the reg limits
935
-     * on the datetimes attached to this event.
936
-     *
937
-     * @param   bool $consider_sold Whether to consider any tickets that have already sold in our calculation.
938
-     *                              If this is false, then we return the most tickets that could ever be sold
939
-     *                              for this event with the datetime and tickets setup on the event under optimal
940
-     *                              selling conditions.  Otherwise we return a live calculation of spaces available
941
-     *                              based on tickets sold.  Depending on setup and stage of sales, this
942
-     *                              may appear to equal remaining tickets.  However, the more tickets are
943
-     *                              sold out, the more accurate the "live" total is.
944
-     * @return float|int
945
-     * @throws EE_Error
946
-     * @throws DomainException
947
-     * @throws UnexpectedEntityException
948
-     */
949
-    public function total_available_spaces($consider_sold = false)
950
-    {
951
-        $spaces_available = $consider_sold
952
-            ? $this->getAvailableSpacesCalculator()->spacesRemaining()
953
-            : $this->getAvailableSpacesCalculator()->totalSpacesAvailable();
954
-        return apply_filters(
955
-            'FHEE_EE_Event__total_available_spaces__spaces_available',
956
-            $spaces_available,
957
-            $this,
958
-            $this->getAvailableSpacesCalculator()->getDatetimes(),
959
-            $this->getAvailableSpacesCalculator()->getActiveTickets()
960
-        );
961
-    }
962
-
963
-
964
-    /**
965
-     * Checks if the event is set to sold out
966
-     *
967
-     * @param  bool $actual whether or not to perform calculations to not only figure the
968
-     *                      actual status but also to flip the status if necessary to sold
969
-     *                      out If false, we just check the existing status of the event
970
-     * @return boolean
971
-     * @throws EE_Error
972
-     */
973
-    public function is_sold_out($actual = false)
974
-    {
975
-        if (! $actual) {
976
-            return $this->status() === EEM_Event::sold_out;
977
-        }
978
-        return $this->perform_sold_out_status_check();
979
-    }
980
-
981
-
982
-    /**
983
-     * Checks if the event is marked as postponed
984
-     *
985
-     * @return boolean
986
-     */
987
-    public function is_postponed()
988
-    {
989
-        return $this->status() === EEM_Event::postponed;
990
-    }
991
-
992
-
993
-    /**
994
-     * Checks if the event is marked as cancelled
995
-     *
996
-     * @return boolean
997
-     */
998
-    public function is_cancelled()
999
-    {
1000
-        return $this->status() === EEM_Event::cancelled;
1001
-    }
1002
-
1003
-
1004
-    /**
1005
-     * Get the logical active status in a hierarchical order for all the datetimes.  Note
1006
-     * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1007
-     * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1008
-     * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1009
-     * the event is considered expired.
1010
-     * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1011
-     * status set on the EVENT when it is not published and thus is done
1012
-     *
1013
-     * @param bool $reset
1014
-     * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1015
-     * @throws EE_Error
1016
-     */
1017
-    public function get_active_status($reset = false)
1018
-    {
1019
-        // if the active status has already been set, then just use that value (unless we are resetting it)
1020
-        if (! empty($this->_active_status) && ! $reset) {
1021
-            return $this->_active_status;
1022
-        }
1023
-        // first check if event id is present on this object
1024
-        if (! $this->ID()) {
1025
-            return false;
1026
-        }
1027
-        $where_params_for_event = array(array('EVT_ID' => $this->ID()));
1028
-        // if event is published:
1029
-        if ($this->status() === EEM_Event::post_status_publish || $this->status() === EEM_Event::post_status_private) {
1030
-            // active?
1031
-            if (EEM_Datetime::instance()->get_datetime_count_for_status(
1032
-                EE_Datetime::active,
1033
-                $where_params_for_event
1034
-            ) > 0) {
1035
-                $this->_active_status = EE_Datetime::active;
1036
-            } else {
1037
-                // upcoming?
1038
-                if (EEM_Datetime::instance()->get_datetime_count_for_status(
1039
-                    EE_Datetime::upcoming,
1040
-                    $where_params_for_event
1041
-                ) > 0) {
1042
-                    $this->_active_status = EE_Datetime::upcoming;
1043
-                } else {
1044
-                    // expired?
1045
-                    if (EEM_Datetime::instance()->get_datetime_count_for_status(
1046
-                        EE_Datetime::expired,
1047
-                        $where_params_for_event
1048
-                    ) > 0
1049
-                    ) {
1050
-                        $this->_active_status = EE_Datetime::expired;
1051
-                    } else {
1052
-                        // it would be odd if things make it this far because it basically means there are no datetime's
1053
-                        // attached to the event.  So in this case it will just be considered inactive.
1054
-                        $this->_active_status = EE_Datetime::inactive;
1055
-                    }
1056
-                }
1057
-            }
1058
-        } else {
1059
-            // the event is not published, so let's just set it's active status according to its' post status
1060
-            switch ($this->status()) {
1061
-                case EEM_Event::sold_out:
1062
-                    $this->_active_status = EE_Datetime::sold_out;
1063
-                    break;
1064
-                case EEM_Event::cancelled:
1065
-                    $this->_active_status = EE_Datetime::cancelled;
1066
-                    break;
1067
-                case EEM_Event::postponed:
1068
-                    $this->_active_status = EE_Datetime::postponed;
1069
-                    break;
1070
-                default:
1071
-                    $this->_active_status = EE_Datetime::inactive;
1072
-            }
1073
-        }
1074
-        return $this->_active_status;
1075
-    }
1076
-
1077
-
1078
-    /**
1079
-     *    pretty_active_status
1080
-     *
1081
-     * @access public
1082
-     * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1083
-     * @return mixed void|string
1084
-     * @throws EE_Error
1085
-     */
1086
-    public function pretty_active_status($echo = true)
1087
-    {
1088
-        $active_status = $this->get_active_status();
1089
-        $status = '<span class="ee-status event-active-status-'
1090
-                  . $active_status
1091
-                  . '">'
1092
-                  . EEH_Template::pretty_status($active_status, false, 'sentence')
1093
-                  . '</span>';
1094
-        if ($echo) {
1095
-            echo $status;
1096
-            return '';
1097
-        }
1098
-        return $status;
1099
-    }
1100
-
1101
-
1102
-    /**
1103
-     * @return bool|int
1104
-     * @throws EE_Error
1105
-     */
1106
-    public function get_number_of_tickets_sold()
1107
-    {
1108
-        $tkt_sold = 0;
1109
-        if (! $this->ID()) {
1110
-            return 0;
1111
-        }
1112
-        $datetimes = $this->datetimes();
1113
-        foreach ($datetimes as $datetime) {
1114
-            if ($datetime instanceof EE_Datetime) {
1115
-                $tkt_sold += $datetime->sold();
1116
-            }
1117
-        }
1118
-        return $tkt_sold;
1119
-    }
1120
-
1121
-
1122
-    /**
1123
-     * This just returns a count of all the registrations for this event
1124
-     *
1125
-     * @access  public
1126
-     * @return int
1127
-     * @throws EE_Error
1128
-     */
1129
-    public function get_count_of_all_registrations()
1130
-    {
1131
-        return EEM_Event::instance()->count_related($this, 'Registration');
1132
-    }
1133
-
1134
-
1135
-    /**
1136
-     * This returns the ticket with the earliest start time that is
1137
-     * available for this event (across all datetimes attached to the event)
1138
-     *
1139
-     * @return EE_Base_Class|EE_Ticket|null
1140
-     * @throws EE_Error
1141
-     */
1142
-    public function get_ticket_with_earliest_start_time()
1143
-    {
1144
-        $where['Datetime.EVT_ID'] = $this->ID();
1145
-        $query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1146
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1147
-    }
1148
-
1149
-
1150
-    /**
1151
-     * This returns the ticket with the latest end time that is available
1152
-     * for this event (across all datetimes attached to the event)
1153
-     *
1154
-     * @return EE_Base_Class|EE_Ticket|null
1155
-     * @throws EE_Error
1156
-     */
1157
-    public function get_ticket_with_latest_end_time()
1158
-    {
1159
-        $where['Datetime.EVT_ID'] = $this->ID();
1160
-        $query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1161
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1162
-    }
1163
-
1164
-
1165
-    /**
1166
-     * This returns the number of different ticket types currently on sale for this event.
1167
-     *
1168
-     * @return int
1169
-     * @throws EE_Error
1170
-     */
1171
-    public function countTicketsOnSale()
1172
-    {
1173
-        $where = array(
1174
-            'Datetime.EVT_ID' => $this->ID(),
1175
-            'TKT_start_date'  => array('<', time()),
1176
-            'TKT_end_date'    => array('>', time()),
1177
-        );
1178
-        return EEM_Ticket::instance()->count(array($where));
1179
-    }
1180
-
1181
-
1182
-    /**
1183
-     * This returns whether there are any tickets on sale for this event.
1184
-     *
1185
-     * @return bool true = YES tickets on sale.
1186
-     * @throws EE_Error
1187
-     */
1188
-    public function tickets_on_sale()
1189
-    {
1190
-        return $this->countTicketsOnSale() > 0;
1191
-    }
1192
-
1193
-
1194
-    /**
1195
-     * Gets the URL for viewing this event on the front-end. Overrides parent
1196
-     * to check for an external URL first
1197
-     *
1198
-     * @return string
1199
-     * @throws EE_Error
1200
-     */
1201
-    public function get_permalink()
1202
-    {
1203
-        if ($this->external_url()) {
1204
-            return $this->external_url();
1205
-        }
1206
-        return parent::get_permalink();
1207
-    }
1208
-
1209
-
1210
-    /**
1211
-     * Gets the first term for 'espresso_event_categories' we can find
1212
-     *
1213
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1214
-     * @return EE_Base_Class|EE_Term|null
1215
-     * @throws EE_Error
1216
-     */
1217
-    public function first_event_category($query_params = array())
1218
-    {
1219
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1220
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1221
-        return EEM_Term::instance()->get_one($query_params);
1222
-    }
1223
-
1224
-
1225
-    /**
1226
-     * Gets all terms for 'espresso_event_categories' we can find
1227
-     *
1228
-     * @param array $query_params
1229
-     * @return EE_Base_Class[]|EE_Term[]
1230
-     * @throws EE_Error
1231
-     */
1232
-    public function get_all_event_categories($query_params = array())
1233
-    {
1234
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1235
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1236
-        return EEM_Term::instance()->get_all($query_params);
1237
-    }
1238
-
1239
-
1240
-    /**
1241
-     * Adds a question group to this event
1242
-     *
1243
-     * @param EE_Question_Group|int $question_group_id_or_obj
1244
-     * @param bool                  $for_primary if true, the question group will be added for the primary
1245
-     *                                           registrant, if false will be added for others. default: false
1246
-     * @return EE_Base_Class|EE_Question_Group
1247
-     * @throws EE_Error
1248
-     */
1249
-    public function add_question_group($question_group_id_or_obj, $for_primary = false)
1250
-    {
1251
-        $extra = $for_primary
1252
-            ? array('EQG_primary' => 1)
1253
-            : array();
1254
-        return $this->_add_relation_to($question_group_id_or_obj, 'Question_Group', $extra);
1255
-    }
1256
-
1257
-
1258
-    /**
1259
-     * Removes a question group from the event
1260
-     *
1261
-     * @param EE_Question_Group|int $question_group_id_or_obj
1262
-     * @param bool                  $for_primary if true, the question group will be removed from the primary
1263
-     *                                           registrant, if false will be removed from others. default: false
1264
-     * @return EE_Base_Class|EE_Question_Group
1265
-     * @throws EE_Error
1266
-     */
1267
-    public function remove_question_group($question_group_id_or_obj, $for_primary = false)
1268
-    {
1269
-        $where = $for_primary
1270
-            ? array('EQG_primary' => 1)
1271
-            : array();
1272
-        return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group', $where);
1273
-    }
1274
-
1275
-
1276
-    /**
1277
-     * Gets all the question groups, ordering them by QSG_order ascending
1278
-     *
1279
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1280
-     * @return EE_Base_Class[]|EE_Question_Group[]
1281
-     * @throws EE_Error
1282
-     */
1283
-    public function question_groups($query_params = array())
1284
-    {
1285
-        $query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1286
-        return $this->get_many_related('Question_Group', $query_params);
1287
-    }
1288
-
1289
-
1290
-    /**
1291
-     * Implementation for EEI_Has_Icon interface method.
1292
-     *
1293
-     * @see EEI_Visual_Representation for comments
1294
-     * @return string
1295
-     */
1296
-    public function get_icon()
1297
-    {
1298
-        return '<span class="dashicons dashicons-flag"></span>';
1299
-    }
1300
-
1301
-
1302
-    /**
1303
-     * Implementation for EEI_Admin_Links interface method.
1304
-     *
1305
-     * @see EEI_Admin_Links for comments
1306
-     * @return string
1307
-     * @throws EE_Error
1308
-     */
1309
-    public function get_admin_details_link()
1310
-    {
1311
-        return $this->get_admin_edit_link();
1312
-    }
1313
-
1314
-
1315
-    /**
1316
-     * Implementation for EEI_Admin_Links interface method.
1317
-     *
1318
-     * @see EEI_Admin_Links for comments
1319
-     * @return string
1320
-     * @throws EE_Error
1321
-     */
1322
-    public function get_admin_edit_link()
1323
-    {
1324
-        return EEH_URL::add_query_args_and_nonce(
1325
-            array(
1326
-                'page'   => 'espresso_events',
1327
-                'action' => 'edit',
1328
-                'post'   => $this->ID(),
1329
-            ),
1330
-            admin_url('admin.php')
1331
-        );
1332
-    }
1333
-
1334
-
1335
-    /**
1336
-     * Implementation for EEI_Admin_Links interface method.
1337
-     *
1338
-     * @see EEI_Admin_Links for comments
1339
-     * @return string
1340
-     */
1341
-    public function get_admin_settings_link()
1342
-    {
1343
-        return EEH_URL::add_query_args_and_nonce(
1344
-            array(
1345
-                'page'   => 'espresso_events',
1346
-                'action' => 'default_event_settings',
1347
-            ),
1348
-            admin_url('admin.php')
1349
-        );
1350
-    }
1351
-
1352
-
1353
-    /**
1354
-     * Implementation for EEI_Admin_Links interface method.
1355
-     *
1356
-     * @see EEI_Admin_Links for comments
1357
-     * @return string
1358
-     */
1359
-    public function get_admin_overview_link()
1360
-    {
1361
-        return EEH_URL::add_query_args_and_nonce(
1362
-            array(
1363
-                'page'   => 'espresso_events',
1364
-                'action' => 'default',
1365
-            ),
1366
-            admin_url('admin.php')
1367
-        );
1368
-    }
16
+	/**
17
+	 * cached value for the the logical active status for the event
18
+	 *
19
+	 * @see get_active_status()
20
+	 * @var string
21
+	 */
22
+	protected $_active_status = '';
23
+
24
+	/**
25
+	 * This is just used for caching the Primary Datetime for the Event on initial retrieval
26
+	 *
27
+	 * @var EE_Datetime
28
+	 */
29
+	protected $_Primary_Datetime;
30
+
31
+	/**
32
+	 * @var EventSpacesCalculator $available_spaces_calculator
33
+	 */
34
+	protected $available_spaces_calculator;
35
+
36
+
37
+	/**
38
+	 * @param array  $props_n_values          incoming values
39
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
40
+	 *                                        used.)
41
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
42
+	 *                                        date_format and the second value is the time format
43
+	 * @return EE_Event
44
+	 * @throws EE_Error
45
+	 */
46
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
47
+	{
48
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
49
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
50
+	}
51
+
52
+
53
+	/**
54
+	 * @param array  $props_n_values  incoming values from the database
55
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
56
+	 *                                the website will be used.
57
+	 * @return EE_Event
58
+	 * @throws EE_Error
59
+	 */
60
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
61
+	{
62
+		return new self($props_n_values, true, $timezone);
63
+	}
64
+
65
+
66
+	/**
67
+	 * @return EventSpacesCalculator
68
+	 * @throws \EE_Error
69
+	 */
70
+	public function getAvailableSpacesCalculator()
71
+	{
72
+		if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
73
+			$this->available_spaces_calculator = new EventSpacesCalculator($this);
74
+		}
75
+		return $this->available_spaces_calculator;
76
+	}
77
+
78
+
79
+	/**
80
+	 * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
81
+	 *
82
+	 * @param string $field_name
83
+	 * @param mixed  $field_value
84
+	 * @param bool   $use_default
85
+	 * @throws EE_Error
86
+	 */
87
+	public function set($field_name, $field_value, $use_default = false)
88
+	{
89
+		switch ($field_name) {
90
+			case 'status':
91
+				$this->set_status($field_value, $use_default);
92
+				break;
93
+			default:
94
+				parent::set($field_name, $field_value, $use_default);
95
+		}
96
+	}
97
+
98
+
99
+	/**
100
+	 *    set_status
101
+	 * Checks if event status is being changed to SOLD OUT
102
+	 * and updates event meta data with previous event status
103
+	 * so that we can revert things if/when the event is no longer sold out
104
+	 *
105
+	 * @access public
106
+	 * @param string $new_status
107
+	 * @param bool   $use_default
108
+	 * @return void
109
+	 * @throws EE_Error
110
+	 */
111
+	public function set_status($new_status = null, $use_default = false)
112
+	{
113
+		// if nothing is set, and we aren't explicitly wanting to reset the status, then just leave
114
+		if (empty($new_status) && ! $use_default) {
115
+			return;
116
+		}
117
+		// get current Event status
118
+		$old_status = $this->status();
119
+		// if status has changed
120
+		if ($old_status !== $new_status) {
121
+			// TO sold_out
122
+			if ($new_status === EEM_Event::sold_out) {
123
+				// save the previous event status so that we can revert if the event is no longer sold out
124
+				$this->add_post_meta('_previous_event_status', $old_status);
125
+				do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
126
+				// OR FROM  sold_out
127
+			} elseif ($old_status === EEM_Event::sold_out) {
128
+				$this->delete_post_meta('_previous_event_status');
129
+				do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
130
+			}
131
+			// clear out the active status so that it gets reset the next time it is requested
132
+			$this->_active_status = null;
133
+			// update status
134
+			parent::set('status', $new_status, $use_default);
135
+			do_action('AHEE__EE_Event__set_status__after_update', $this);
136
+			return;
137
+		}
138
+		// even though the old value matches the new value, it's still good to
139
+		// allow the parent set method to have a say
140
+		parent::set('status', $new_status, $use_default);
141
+	}
142
+
143
+
144
+	/**
145
+	 * Gets all the datetimes for this event
146
+	 *
147
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
148
+	 * @return EE_Base_Class[]|EE_Datetime[]
149
+	 * @throws EE_Error
150
+	 */
151
+	public function datetimes($query_params = array())
152
+	{
153
+		return $this->get_many_related('Datetime', $query_params);
154
+	}
155
+
156
+
157
+	/**
158
+	 * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
159
+	 *
160
+	 * @return EE_Base_Class[]|EE_Datetime[]
161
+	 * @throws EE_Error
162
+	 */
163
+	public function datetimes_in_chronological_order()
164
+	{
165
+		return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
166
+	}
167
+
168
+
169
+	/**
170
+	 * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
171
+	 * @darren, we should probably UNSET timezone on the EEM_Datetime model
172
+	 * after running our query, so that this timezone isn't set for EVERY query
173
+	 * on EEM_Datetime for the rest of the request, no?
174
+	 *
175
+	 * @param boolean $show_expired whether or not to include expired events
176
+	 * @param boolean $show_deleted whether or not to include deleted events
177
+	 * @param null    $limit
178
+	 * @return EE_Datetime[]
179
+	 * @throws EE_Error
180
+	 */
181
+	public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
182
+	{
183
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
184
+			$this->ID(),
185
+			$show_expired,
186
+			$show_deleted,
187
+			$limit
188
+		);
189
+	}
190
+
191
+
192
+	/**
193
+	 * Returns one related datetime. Mostly only used by some legacy code.
194
+	 *
195
+	 * @return EE_Base_Class|EE_Datetime
196
+	 * @throws EE_Error
197
+	 */
198
+	public function first_datetime()
199
+	{
200
+		return $this->get_first_related('Datetime');
201
+	}
202
+
203
+
204
+	/**
205
+	 * Returns the 'primary' datetime for the event
206
+	 *
207
+	 * @param bool $try_to_exclude_expired
208
+	 * @param bool $try_to_exclude_deleted
209
+	 * @return EE_Datetime
210
+	 * @throws EE_Error
211
+	 */
212
+	public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
213
+	{
214
+		if (! empty($this->_Primary_Datetime)) {
215
+			return $this->_Primary_Datetime;
216
+		}
217
+		$this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
218
+			$this->ID(),
219
+			$try_to_exclude_expired,
220
+			$try_to_exclude_deleted
221
+		);
222
+		return $this->_Primary_Datetime;
223
+	}
224
+
225
+
226
+	/**
227
+	 * Gets all the tickets available for purchase of this event
228
+	 *
229
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
230
+	 * @return EE_Base_Class[]|EE_Ticket[]
231
+	 * @throws EE_Error
232
+	 */
233
+	public function tickets($query_params = array())
234
+	{
235
+		// first get all datetimes
236
+		$datetimes = $this->datetimes_ordered();
237
+		if (! $datetimes) {
238
+			return array();
239
+		}
240
+		$datetime_ids = array();
241
+		foreach ($datetimes as $datetime) {
242
+			$datetime_ids[] = $datetime->ID();
243
+		}
244
+		$where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
245
+		// if incoming $query_params has where conditions let's merge but not override existing.
246
+		if (is_array($query_params) && isset($query_params[0])) {
247
+			$where_params = array_merge($query_params[0], $where_params);
248
+			unset($query_params[0]);
249
+		}
250
+		// now add $where_params to $query_params
251
+		$query_params[0] = $where_params;
252
+		return EEM_Ticket::instance()->get_all($query_params);
253
+	}
254
+
255
+
256
+	/**
257
+	 * get all unexpired untrashed tickets
258
+	 *
259
+	 * @return EE_Ticket[]
260
+	 * @throws EE_Error
261
+	 */
262
+	public function active_tickets()
263
+	{
264
+		return $this->tickets(
265
+			array(
266
+				array(
267
+					'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
268
+					'TKT_deleted'  => false,
269
+				),
270
+			)
271
+		);
272
+	}
273
+
274
+
275
+	/**
276
+	 * @return bool
277
+	 * @throws EE_Error
278
+	 */
279
+	public function additional_limit()
280
+	{
281
+		return $this->get('EVT_additional_limit');
282
+	}
283
+
284
+
285
+	/**
286
+	 * @return bool
287
+	 * @throws EE_Error
288
+	 */
289
+	public function allow_overflow()
290
+	{
291
+		return $this->get('EVT_allow_overflow');
292
+	}
293
+
294
+
295
+	/**
296
+	 * @return bool
297
+	 * @throws EE_Error
298
+	 */
299
+	public function created()
300
+	{
301
+		return $this->get('EVT_created');
302
+	}
303
+
304
+
305
+	/**
306
+	 * @return bool
307
+	 * @throws EE_Error
308
+	 */
309
+	public function description()
310
+	{
311
+		return $this->get('EVT_desc');
312
+	}
313
+
314
+
315
+	/**
316
+	 * Runs do_shortcode and wpautop on the description
317
+	 *
318
+	 * @return string of html
319
+	 * @throws EE_Error
320
+	 */
321
+	public function description_filtered()
322
+	{
323
+		return $this->get_pretty('EVT_desc');
324
+	}
325
+
326
+
327
+	/**
328
+	 * @return bool
329
+	 * @throws EE_Error
330
+	 */
331
+	public function display_description()
332
+	{
333
+		return $this->get('EVT_display_desc');
334
+	}
335
+
336
+
337
+	/**
338
+	 * @return bool
339
+	 * @throws EE_Error
340
+	 */
341
+	public function display_ticket_selector()
342
+	{
343
+		return (bool) $this->get('EVT_display_ticket_selector');
344
+	}
345
+
346
+
347
+	/**
348
+	 * @return bool
349
+	 * @throws EE_Error
350
+	 */
351
+	public function external_url()
352
+	{
353
+		return $this->get('EVT_external_URL');
354
+	}
355
+
356
+
357
+	/**
358
+	 * @return bool
359
+	 * @throws EE_Error
360
+	 */
361
+	public function member_only()
362
+	{
363
+		return $this->get('EVT_member_only');
364
+	}
365
+
366
+
367
+	/**
368
+	 * @return bool
369
+	 * @throws EE_Error
370
+	 */
371
+	public function phone()
372
+	{
373
+		return $this->get('EVT_phone');
374
+	}
375
+
376
+
377
+	/**
378
+	 * @return bool
379
+	 * @throws EE_Error
380
+	 */
381
+	public function modified()
382
+	{
383
+		return $this->get('EVT_modified');
384
+	}
385
+
386
+
387
+	/**
388
+	 * @return bool
389
+	 * @throws EE_Error
390
+	 */
391
+	public function name()
392
+	{
393
+		return $this->get('EVT_name');
394
+	}
395
+
396
+
397
+	/**
398
+	 * @return bool
399
+	 * @throws EE_Error
400
+	 */
401
+	public function order()
402
+	{
403
+		return $this->get('EVT_order');
404
+	}
405
+
406
+
407
+	/**
408
+	 * @return bool|string
409
+	 * @throws EE_Error
410
+	 */
411
+	public function default_registration_status()
412
+	{
413
+		$event_default_registration_status = $this->get('EVT_default_registration_status');
414
+		return ! empty($event_default_registration_status)
415
+			? $event_default_registration_status
416
+			: EE_Registry::instance()->CFG->registration->default_STS_ID;
417
+	}
418
+
419
+
420
+	/**
421
+	 * @param int  $num_words
422
+	 * @param null $more
423
+	 * @param bool $not_full_desc
424
+	 * @return bool|string
425
+	 * @throws EE_Error
426
+	 */
427
+	public function short_description($num_words = 55, $more = null, $not_full_desc = false)
428
+	{
429
+		$short_desc = $this->get('EVT_short_desc');
430
+		if (! empty($short_desc) || $not_full_desc) {
431
+			return $short_desc;
432
+		}
433
+		$full_desc = $this->get('EVT_desc');
434
+		return wp_trim_words($full_desc, $num_words, $more);
435
+	}
436
+
437
+
438
+	/**
439
+	 * @return bool
440
+	 * @throws EE_Error
441
+	 */
442
+	public function slug()
443
+	{
444
+		return $this->get('EVT_slug');
445
+	}
446
+
447
+
448
+	/**
449
+	 * @return bool
450
+	 * @throws EE_Error
451
+	 */
452
+	public function timezone_string()
453
+	{
454
+		return $this->get('EVT_timezone_string');
455
+	}
456
+
457
+
458
+	/**
459
+	 * @return bool
460
+	 * @throws EE_Error
461
+	 */
462
+	public function visible_on()
463
+	{
464
+		return $this->get('EVT_visible_on');
465
+	}
466
+
467
+
468
+	/**
469
+	 * @return int
470
+	 * @throws EE_Error
471
+	 */
472
+	public function wp_user()
473
+	{
474
+		return $this->get('EVT_wp_user');
475
+	}
476
+
477
+
478
+	/**
479
+	 * @return bool
480
+	 * @throws EE_Error
481
+	 */
482
+	public function donations()
483
+	{
484
+		return $this->get('EVT_donations');
485
+	}
486
+
487
+
488
+	/**
489
+	 * @param $limit
490
+	 * @throws EE_Error
491
+	 */
492
+	public function set_additional_limit($limit)
493
+	{
494
+		$this->set('EVT_additional_limit', $limit);
495
+	}
496
+
497
+
498
+	/**
499
+	 * @param $created
500
+	 * @throws EE_Error
501
+	 */
502
+	public function set_created($created)
503
+	{
504
+		$this->set('EVT_created', $created);
505
+	}
506
+
507
+
508
+	/**
509
+	 * @param $desc
510
+	 * @throws EE_Error
511
+	 */
512
+	public function set_description($desc)
513
+	{
514
+		$this->set('EVT_desc', $desc);
515
+	}
516
+
517
+
518
+	/**
519
+	 * @param $display_desc
520
+	 * @throws EE_Error
521
+	 */
522
+	public function set_display_description($display_desc)
523
+	{
524
+		$this->set('EVT_display_desc', $display_desc);
525
+	}
526
+
527
+
528
+	/**
529
+	 * @param $display_ticket_selector
530
+	 * @throws EE_Error
531
+	 */
532
+	public function set_display_ticket_selector($display_ticket_selector)
533
+	{
534
+		$this->set('EVT_display_ticket_selector', $display_ticket_selector);
535
+	}
536
+
537
+
538
+	/**
539
+	 * @param $external_url
540
+	 * @throws EE_Error
541
+	 */
542
+	public function set_external_url($external_url)
543
+	{
544
+		$this->set('EVT_external_URL', $external_url);
545
+	}
546
+
547
+
548
+	/**
549
+	 * @param $member_only
550
+	 * @throws EE_Error
551
+	 */
552
+	public function set_member_only($member_only)
553
+	{
554
+		$this->set('EVT_member_only', $member_only);
555
+	}
556
+
557
+
558
+	/**
559
+	 * @param $event_phone
560
+	 * @throws EE_Error
561
+	 */
562
+	public function set_event_phone($event_phone)
563
+	{
564
+		$this->set('EVT_phone', $event_phone);
565
+	}
566
+
567
+
568
+	/**
569
+	 * @param $modified
570
+	 * @throws EE_Error
571
+	 */
572
+	public function set_modified($modified)
573
+	{
574
+		$this->set('EVT_modified', $modified);
575
+	}
576
+
577
+
578
+	/**
579
+	 * @param $name
580
+	 * @throws EE_Error
581
+	 */
582
+	public function set_name($name)
583
+	{
584
+		$this->set('EVT_name', $name);
585
+	}
586
+
587
+
588
+	/**
589
+	 * @param $order
590
+	 * @throws EE_Error
591
+	 */
592
+	public function set_order($order)
593
+	{
594
+		$this->set('EVT_order', $order);
595
+	}
596
+
597
+
598
+	/**
599
+	 * @param $short_desc
600
+	 * @throws EE_Error
601
+	 */
602
+	public function set_short_description($short_desc)
603
+	{
604
+		$this->set('EVT_short_desc', $short_desc);
605
+	}
606
+
607
+
608
+	/**
609
+	 * @param $slug
610
+	 * @throws EE_Error
611
+	 */
612
+	public function set_slug($slug)
613
+	{
614
+		$this->set('EVT_slug', $slug);
615
+	}
616
+
617
+
618
+	/**
619
+	 * @param $timezone_string
620
+	 * @throws EE_Error
621
+	 */
622
+	public function set_timezone_string($timezone_string)
623
+	{
624
+		$this->set('EVT_timezone_string', $timezone_string);
625
+	}
626
+
627
+
628
+	/**
629
+	 * @param $visible_on
630
+	 * @throws EE_Error
631
+	 */
632
+	public function set_visible_on($visible_on)
633
+	{
634
+		$this->set('EVT_visible_on', $visible_on);
635
+	}
636
+
637
+
638
+	/**
639
+	 * @param $wp_user
640
+	 * @throws EE_Error
641
+	 */
642
+	public function set_wp_user($wp_user)
643
+	{
644
+		$this->set('EVT_wp_user', $wp_user);
645
+	}
646
+
647
+
648
+	/**
649
+	 * @param $default_registration_status
650
+	 * @throws EE_Error
651
+	 */
652
+	public function set_default_registration_status($default_registration_status)
653
+	{
654
+		$this->set('EVT_default_registration_status', $default_registration_status);
655
+	}
656
+
657
+
658
+	/**
659
+	 * @param $donations
660
+	 * @throws EE_Error
661
+	 */
662
+	public function set_donations($donations)
663
+	{
664
+		$this->set('EVT_donations', $donations);
665
+	}
666
+
667
+
668
+	/**
669
+	 * Adds a venue to this event
670
+	 *
671
+	 * @param EE_Venue /int $venue_id_or_obj
672
+	 * @return EE_Base_Class|EE_Venue
673
+	 * @throws EE_Error
674
+	 */
675
+	public function add_venue($venue_id_or_obj)
676
+	{
677
+		return $this->_add_relation_to($venue_id_or_obj, 'Venue');
678
+	}
679
+
680
+
681
+	/**
682
+	 * Removes a venue from the event
683
+	 *
684
+	 * @param EE_Venue /int $venue_id_or_obj
685
+	 * @return EE_Base_Class|EE_Venue
686
+	 * @throws EE_Error
687
+	 */
688
+	public function remove_venue($venue_id_or_obj)
689
+	{
690
+		return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
691
+	}
692
+
693
+
694
+	/**
695
+	 * Gets all the venues related ot the event. May provide additional $query_params if desired
696
+	 *
697
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
698
+	 * @return EE_Base_Class[]|EE_Venue[]
699
+	 * @throws EE_Error
700
+	 */
701
+	public function venues($query_params = array())
702
+	{
703
+		return $this->get_many_related('Venue', $query_params);
704
+	}
705
+
706
+
707
+	/**
708
+	 * check if event id is present and if event is published
709
+	 *
710
+	 * @access public
711
+	 * @return boolean true yes, false no
712
+	 * @throws EE_Error
713
+	 */
714
+	private function _has_ID_and_is_published()
715
+	{
716
+		// first check if event id is present and not NULL,
717
+		// then check if this event is published (or any of the equivalent "published" statuses)
718
+		return
719
+			$this->ID() && $this->ID() !== null
720
+			&& (
721
+				$this->status() === 'publish'
722
+				|| $this->status() === EEM_Event::sold_out
723
+				|| $this->status() === EEM_Event::postponed
724
+				|| $this->status() === EEM_Event::cancelled
725
+			);
726
+	}
727
+
728
+
729
+	/**
730
+	 * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
731
+	 *
732
+	 * @access public
733
+	 * @return boolean true yes, false no
734
+	 * @throws EE_Error
735
+	 */
736
+	public function is_upcoming()
737
+	{
738
+		// check if event id is present and if this event is published
739
+		if ($this->is_inactive()) {
740
+			return false;
741
+		}
742
+		// set initial value
743
+		$upcoming = false;
744
+		// next let's get all datetimes and loop through them
745
+		$datetimes = $this->datetimes_in_chronological_order();
746
+		foreach ($datetimes as $datetime) {
747
+			if ($datetime instanceof EE_Datetime) {
748
+				// if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
749
+				if ($datetime->is_expired()) {
750
+					continue;
751
+				}
752
+				// if this dtt is active then we return false.
753
+				if ($datetime->is_active()) {
754
+					return false;
755
+				}
756
+				// otherwise let's check upcoming status
757
+				$upcoming = $datetime->is_upcoming();
758
+			}
759
+		}
760
+		return $upcoming;
761
+	}
762
+
763
+
764
+	/**
765
+	 * @return bool
766
+	 * @throws EE_Error
767
+	 */
768
+	public function is_active()
769
+	{
770
+		// check if event id is present and if this event is published
771
+		if ($this->is_inactive()) {
772
+			return false;
773
+		}
774
+		// set initial value
775
+		$active = false;
776
+		// next let's get all datetimes and loop through them
777
+		$datetimes = $this->datetimes_in_chronological_order();
778
+		foreach ($datetimes as $datetime) {
779
+			if ($datetime instanceof EE_Datetime) {
780
+				// if this dtt is expired then we continue cause one of the other datetimes might be active.
781
+				if ($datetime->is_expired()) {
782
+					continue;
783
+				}
784
+				// if this dtt is upcoming then we return false.
785
+				if ($datetime->is_upcoming()) {
786
+					return false;
787
+				}
788
+				// otherwise let's check active status
789
+				$active = $datetime->is_active();
790
+			}
791
+		}
792
+		return $active;
793
+	}
794
+
795
+
796
+	/**
797
+	 * @return bool
798
+	 * @throws EE_Error
799
+	 */
800
+	public function is_expired()
801
+	{
802
+		// check if event id is present and if this event is published
803
+		if ($this->is_inactive()) {
804
+			return false;
805
+		}
806
+		// set initial value
807
+		$expired = false;
808
+		// first let's get all datetimes and loop through them
809
+		$datetimes = $this->datetimes_in_chronological_order();
810
+		foreach ($datetimes as $datetime) {
811
+			if ($datetime instanceof EE_Datetime) {
812
+				// if this dtt is upcoming or active then we return false.
813
+				if ($datetime->is_upcoming() || $datetime->is_active()) {
814
+					return false;
815
+				}
816
+				// otherwise let's check active status
817
+				$expired = $datetime->is_expired();
818
+			}
819
+		}
820
+		return $expired;
821
+	}
822
+
823
+
824
+	/**
825
+	 * @return bool
826
+	 * @throws EE_Error
827
+	 */
828
+	public function is_inactive()
829
+	{
830
+		// check if event id is present and if this event is published
831
+		if ($this->_has_ID_and_is_published()) {
832
+			return false;
833
+		}
834
+		return true;
835
+	}
836
+
837
+
838
+	/**
839
+	 * calculate spaces remaining based on "saleable" tickets
840
+	 *
841
+	 * @param array $tickets
842
+	 * @param bool  $filtered
843
+	 * @return int|float
844
+	 * @throws EE_Error
845
+	 * @throws DomainException
846
+	 * @throws UnexpectedEntityException
847
+	 */
848
+	public function spaces_remaining($tickets = array(), $filtered = true)
849
+	{
850
+		$this->getAvailableSpacesCalculator()->setActiveTickets($tickets);
851
+		$spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining();
852
+		return $filtered
853
+			? apply_filters(
854
+				'FHEE_EE_Event__spaces_remaining',
855
+				$spaces_remaining,
856
+				$this,
857
+				$tickets
858
+			)
859
+			: $spaces_remaining;
860
+	}
861
+
862
+
863
+	/**
864
+	 *    perform_sold_out_status_check
865
+	 *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
866
+	 *    available... if NOT, then the event status will get toggled to 'sold_out'
867
+	 *
868
+	 * @return bool    return the ACTUAL sold out state.
869
+	 * @throws EE_Error
870
+	 * @throws DomainException
871
+	 * @throws UnexpectedEntityException
872
+	 */
873
+	public function perform_sold_out_status_check()
874
+	{
875
+		// get all tickets
876
+		$tickets = $this->tickets(
877
+			array(
878
+				'default_where_conditions' => 'none',
879
+				'order_by' => array('TKT_qty' => 'ASC'),
880
+			)
881
+		);
882
+		$all_expired = true;
883
+		foreach ($tickets as $ticket) {
884
+			if (! $ticket->is_expired()) {
885
+				$all_expired = false;
886
+				break;
887
+			}
888
+		}
889
+		// if all the tickets are just expired, then don't update the event status to sold out
890
+		if ($all_expired) {
891
+			return true;
892
+		}
893
+		$spaces_remaining = $this->spaces_remaining($tickets);
894
+		if ($spaces_remaining < 1) {
895
+			if ($this->status() !== EEM_Event::post_status_private) {
896
+				$this->set_status(EEM_Event::sold_out);
897
+				$this->save();
898
+			}
899
+			$sold_out = true;
900
+		} else {
901
+			$sold_out = false;
902
+			// was event previously marked as sold out ?
903
+			if ($this->status() === EEM_Event::sold_out) {
904
+				// revert status to previous value, if it was set
905
+				$previous_event_status = $this->get_post_meta('_previous_event_status', true);
906
+				if ($previous_event_status) {
907
+					$this->set_status($previous_event_status);
908
+					$this->save();
909
+				}
910
+			}
911
+		}
912
+		do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets);
913
+		return $sold_out;
914
+	}
915
+
916
+
917
+	/**
918
+	 * This returns the total remaining spaces for sale on this event.
919
+	 *
920
+	 * @uses EE_Event::total_available_spaces()
921
+	 * @return float|int
922
+	 * @throws EE_Error
923
+	 * @throws DomainException
924
+	 * @throws UnexpectedEntityException
925
+	 */
926
+	public function spaces_remaining_for_sale()
927
+	{
928
+		return $this->total_available_spaces(true);
929
+	}
930
+
931
+
932
+	/**
933
+	 * This returns the total spaces available for an event
934
+	 * while considering all the qtys on the tickets and the reg limits
935
+	 * on the datetimes attached to this event.
936
+	 *
937
+	 * @param   bool $consider_sold Whether to consider any tickets that have already sold in our calculation.
938
+	 *                              If this is false, then we return the most tickets that could ever be sold
939
+	 *                              for this event with the datetime and tickets setup on the event under optimal
940
+	 *                              selling conditions.  Otherwise we return a live calculation of spaces available
941
+	 *                              based on tickets sold.  Depending on setup and stage of sales, this
942
+	 *                              may appear to equal remaining tickets.  However, the more tickets are
943
+	 *                              sold out, the more accurate the "live" total is.
944
+	 * @return float|int
945
+	 * @throws EE_Error
946
+	 * @throws DomainException
947
+	 * @throws UnexpectedEntityException
948
+	 */
949
+	public function total_available_spaces($consider_sold = false)
950
+	{
951
+		$spaces_available = $consider_sold
952
+			? $this->getAvailableSpacesCalculator()->spacesRemaining()
953
+			: $this->getAvailableSpacesCalculator()->totalSpacesAvailable();
954
+		return apply_filters(
955
+			'FHEE_EE_Event__total_available_spaces__spaces_available',
956
+			$spaces_available,
957
+			$this,
958
+			$this->getAvailableSpacesCalculator()->getDatetimes(),
959
+			$this->getAvailableSpacesCalculator()->getActiveTickets()
960
+		);
961
+	}
962
+
963
+
964
+	/**
965
+	 * Checks if the event is set to sold out
966
+	 *
967
+	 * @param  bool $actual whether or not to perform calculations to not only figure the
968
+	 *                      actual status but also to flip the status if necessary to sold
969
+	 *                      out If false, we just check the existing status of the event
970
+	 * @return boolean
971
+	 * @throws EE_Error
972
+	 */
973
+	public function is_sold_out($actual = false)
974
+	{
975
+		if (! $actual) {
976
+			return $this->status() === EEM_Event::sold_out;
977
+		}
978
+		return $this->perform_sold_out_status_check();
979
+	}
980
+
981
+
982
+	/**
983
+	 * Checks if the event is marked as postponed
984
+	 *
985
+	 * @return boolean
986
+	 */
987
+	public function is_postponed()
988
+	{
989
+		return $this->status() === EEM_Event::postponed;
990
+	}
991
+
992
+
993
+	/**
994
+	 * Checks if the event is marked as cancelled
995
+	 *
996
+	 * @return boolean
997
+	 */
998
+	public function is_cancelled()
999
+	{
1000
+		return $this->status() === EEM_Event::cancelled;
1001
+	}
1002
+
1003
+
1004
+	/**
1005
+	 * Get the logical active status in a hierarchical order for all the datetimes.  Note
1006
+	 * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1007
+	 * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1008
+	 * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1009
+	 * the event is considered expired.
1010
+	 * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1011
+	 * status set on the EVENT when it is not published and thus is done
1012
+	 *
1013
+	 * @param bool $reset
1014
+	 * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1015
+	 * @throws EE_Error
1016
+	 */
1017
+	public function get_active_status($reset = false)
1018
+	{
1019
+		// if the active status has already been set, then just use that value (unless we are resetting it)
1020
+		if (! empty($this->_active_status) && ! $reset) {
1021
+			return $this->_active_status;
1022
+		}
1023
+		// first check if event id is present on this object
1024
+		if (! $this->ID()) {
1025
+			return false;
1026
+		}
1027
+		$where_params_for_event = array(array('EVT_ID' => $this->ID()));
1028
+		// if event is published:
1029
+		if ($this->status() === EEM_Event::post_status_publish || $this->status() === EEM_Event::post_status_private) {
1030
+			// active?
1031
+			if (EEM_Datetime::instance()->get_datetime_count_for_status(
1032
+				EE_Datetime::active,
1033
+				$where_params_for_event
1034
+			) > 0) {
1035
+				$this->_active_status = EE_Datetime::active;
1036
+			} else {
1037
+				// upcoming?
1038
+				if (EEM_Datetime::instance()->get_datetime_count_for_status(
1039
+					EE_Datetime::upcoming,
1040
+					$where_params_for_event
1041
+				) > 0) {
1042
+					$this->_active_status = EE_Datetime::upcoming;
1043
+				} else {
1044
+					// expired?
1045
+					if (EEM_Datetime::instance()->get_datetime_count_for_status(
1046
+						EE_Datetime::expired,
1047
+						$where_params_for_event
1048
+					) > 0
1049
+					) {
1050
+						$this->_active_status = EE_Datetime::expired;
1051
+					} else {
1052
+						// it would be odd if things make it this far because it basically means there are no datetime's
1053
+						// attached to the event.  So in this case it will just be considered inactive.
1054
+						$this->_active_status = EE_Datetime::inactive;
1055
+					}
1056
+				}
1057
+			}
1058
+		} else {
1059
+			// the event is not published, so let's just set it's active status according to its' post status
1060
+			switch ($this->status()) {
1061
+				case EEM_Event::sold_out:
1062
+					$this->_active_status = EE_Datetime::sold_out;
1063
+					break;
1064
+				case EEM_Event::cancelled:
1065
+					$this->_active_status = EE_Datetime::cancelled;
1066
+					break;
1067
+				case EEM_Event::postponed:
1068
+					$this->_active_status = EE_Datetime::postponed;
1069
+					break;
1070
+				default:
1071
+					$this->_active_status = EE_Datetime::inactive;
1072
+			}
1073
+		}
1074
+		return $this->_active_status;
1075
+	}
1076
+
1077
+
1078
+	/**
1079
+	 *    pretty_active_status
1080
+	 *
1081
+	 * @access public
1082
+	 * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1083
+	 * @return mixed void|string
1084
+	 * @throws EE_Error
1085
+	 */
1086
+	public function pretty_active_status($echo = true)
1087
+	{
1088
+		$active_status = $this->get_active_status();
1089
+		$status = '<span class="ee-status event-active-status-'
1090
+				  . $active_status
1091
+				  . '">'
1092
+				  . EEH_Template::pretty_status($active_status, false, 'sentence')
1093
+				  . '</span>';
1094
+		if ($echo) {
1095
+			echo $status;
1096
+			return '';
1097
+		}
1098
+		return $status;
1099
+	}
1100
+
1101
+
1102
+	/**
1103
+	 * @return bool|int
1104
+	 * @throws EE_Error
1105
+	 */
1106
+	public function get_number_of_tickets_sold()
1107
+	{
1108
+		$tkt_sold = 0;
1109
+		if (! $this->ID()) {
1110
+			return 0;
1111
+		}
1112
+		$datetimes = $this->datetimes();
1113
+		foreach ($datetimes as $datetime) {
1114
+			if ($datetime instanceof EE_Datetime) {
1115
+				$tkt_sold += $datetime->sold();
1116
+			}
1117
+		}
1118
+		return $tkt_sold;
1119
+	}
1120
+
1121
+
1122
+	/**
1123
+	 * This just returns a count of all the registrations for this event
1124
+	 *
1125
+	 * @access  public
1126
+	 * @return int
1127
+	 * @throws EE_Error
1128
+	 */
1129
+	public function get_count_of_all_registrations()
1130
+	{
1131
+		return EEM_Event::instance()->count_related($this, 'Registration');
1132
+	}
1133
+
1134
+
1135
+	/**
1136
+	 * This returns the ticket with the earliest start time that is
1137
+	 * available for this event (across all datetimes attached to the event)
1138
+	 *
1139
+	 * @return EE_Base_Class|EE_Ticket|null
1140
+	 * @throws EE_Error
1141
+	 */
1142
+	public function get_ticket_with_earliest_start_time()
1143
+	{
1144
+		$where['Datetime.EVT_ID'] = $this->ID();
1145
+		$query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1146
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1147
+	}
1148
+
1149
+
1150
+	/**
1151
+	 * This returns the ticket with the latest end time that is available
1152
+	 * for this event (across all datetimes attached to the event)
1153
+	 *
1154
+	 * @return EE_Base_Class|EE_Ticket|null
1155
+	 * @throws EE_Error
1156
+	 */
1157
+	public function get_ticket_with_latest_end_time()
1158
+	{
1159
+		$where['Datetime.EVT_ID'] = $this->ID();
1160
+		$query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1161
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1162
+	}
1163
+
1164
+
1165
+	/**
1166
+	 * This returns the number of different ticket types currently on sale for this event.
1167
+	 *
1168
+	 * @return int
1169
+	 * @throws EE_Error
1170
+	 */
1171
+	public function countTicketsOnSale()
1172
+	{
1173
+		$where = array(
1174
+			'Datetime.EVT_ID' => $this->ID(),
1175
+			'TKT_start_date'  => array('<', time()),
1176
+			'TKT_end_date'    => array('>', time()),
1177
+		);
1178
+		return EEM_Ticket::instance()->count(array($where));
1179
+	}
1180
+
1181
+
1182
+	/**
1183
+	 * This returns whether there are any tickets on sale for this event.
1184
+	 *
1185
+	 * @return bool true = YES tickets on sale.
1186
+	 * @throws EE_Error
1187
+	 */
1188
+	public function tickets_on_sale()
1189
+	{
1190
+		return $this->countTicketsOnSale() > 0;
1191
+	}
1192
+
1193
+
1194
+	/**
1195
+	 * Gets the URL for viewing this event on the front-end. Overrides parent
1196
+	 * to check for an external URL first
1197
+	 *
1198
+	 * @return string
1199
+	 * @throws EE_Error
1200
+	 */
1201
+	public function get_permalink()
1202
+	{
1203
+		if ($this->external_url()) {
1204
+			return $this->external_url();
1205
+		}
1206
+		return parent::get_permalink();
1207
+	}
1208
+
1209
+
1210
+	/**
1211
+	 * Gets the first term for 'espresso_event_categories' we can find
1212
+	 *
1213
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1214
+	 * @return EE_Base_Class|EE_Term|null
1215
+	 * @throws EE_Error
1216
+	 */
1217
+	public function first_event_category($query_params = array())
1218
+	{
1219
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1220
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1221
+		return EEM_Term::instance()->get_one($query_params);
1222
+	}
1223
+
1224
+
1225
+	/**
1226
+	 * Gets all terms for 'espresso_event_categories' we can find
1227
+	 *
1228
+	 * @param array $query_params
1229
+	 * @return EE_Base_Class[]|EE_Term[]
1230
+	 * @throws EE_Error
1231
+	 */
1232
+	public function get_all_event_categories($query_params = array())
1233
+	{
1234
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1235
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1236
+		return EEM_Term::instance()->get_all($query_params);
1237
+	}
1238
+
1239
+
1240
+	/**
1241
+	 * Adds a question group to this event
1242
+	 *
1243
+	 * @param EE_Question_Group|int $question_group_id_or_obj
1244
+	 * @param bool                  $for_primary if true, the question group will be added for the primary
1245
+	 *                                           registrant, if false will be added for others. default: false
1246
+	 * @return EE_Base_Class|EE_Question_Group
1247
+	 * @throws EE_Error
1248
+	 */
1249
+	public function add_question_group($question_group_id_or_obj, $for_primary = false)
1250
+	{
1251
+		$extra = $for_primary
1252
+			? array('EQG_primary' => 1)
1253
+			: array();
1254
+		return $this->_add_relation_to($question_group_id_or_obj, 'Question_Group', $extra);
1255
+	}
1256
+
1257
+
1258
+	/**
1259
+	 * Removes a question group from the event
1260
+	 *
1261
+	 * @param EE_Question_Group|int $question_group_id_or_obj
1262
+	 * @param bool                  $for_primary if true, the question group will be removed from the primary
1263
+	 *                                           registrant, if false will be removed from others. default: false
1264
+	 * @return EE_Base_Class|EE_Question_Group
1265
+	 * @throws EE_Error
1266
+	 */
1267
+	public function remove_question_group($question_group_id_or_obj, $for_primary = false)
1268
+	{
1269
+		$where = $for_primary
1270
+			? array('EQG_primary' => 1)
1271
+			: array();
1272
+		return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group', $where);
1273
+	}
1274
+
1275
+
1276
+	/**
1277
+	 * Gets all the question groups, ordering them by QSG_order ascending
1278
+	 *
1279
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1280
+	 * @return EE_Base_Class[]|EE_Question_Group[]
1281
+	 * @throws EE_Error
1282
+	 */
1283
+	public function question_groups($query_params = array())
1284
+	{
1285
+		$query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1286
+		return $this->get_many_related('Question_Group', $query_params);
1287
+	}
1288
+
1289
+
1290
+	/**
1291
+	 * Implementation for EEI_Has_Icon interface method.
1292
+	 *
1293
+	 * @see EEI_Visual_Representation for comments
1294
+	 * @return string
1295
+	 */
1296
+	public function get_icon()
1297
+	{
1298
+		return '<span class="dashicons dashicons-flag"></span>';
1299
+	}
1300
+
1301
+
1302
+	/**
1303
+	 * Implementation for EEI_Admin_Links interface method.
1304
+	 *
1305
+	 * @see EEI_Admin_Links for comments
1306
+	 * @return string
1307
+	 * @throws EE_Error
1308
+	 */
1309
+	public function get_admin_details_link()
1310
+	{
1311
+		return $this->get_admin_edit_link();
1312
+	}
1313
+
1314
+
1315
+	/**
1316
+	 * Implementation for EEI_Admin_Links interface method.
1317
+	 *
1318
+	 * @see EEI_Admin_Links for comments
1319
+	 * @return string
1320
+	 * @throws EE_Error
1321
+	 */
1322
+	public function get_admin_edit_link()
1323
+	{
1324
+		return EEH_URL::add_query_args_and_nonce(
1325
+			array(
1326
+				'page'   => 'espresso_events',
1327
+				'action' => 'edit',
1328
+				'post'   => $this->ID(),
1329
+			),
1330
+			admin_url('admin.php')
1331
+		);
1332
+	}
1333
+
1334
+
1335
+	/**
1336
+	 * Implementation for EEI_Admin_Links interface method.
1337
+	 *
1338
+	 * @see EEI_Admin_Links for comments
1339
+	 * @return string
1340
+	 */
1341
+	public function get_admin_settings_link()
1342
+	{
1343
+		return EEH_URL::add_query_args_and_nonce(
1344
+			array(
1345
+				'page'   => 'espresso_events',
1346
+				'action' => 'default_event_settings',
1347
+			),
1348
+			admin_url('admin.php')
1349
+		);
1350
+	}
1351
+
1352
+
1353
+	/**
1354
+	 * Implementation for EEI_Admin_Links interface method.
1355
+	 *
1356
+	 * @see EEI_Admin_Links for comments
1357
+	 * @return string
1358
+	 */
1359
+	public function get_admin_overview_link()
1360
+	{
1361
+		return EEH_URL::add_query_args_and_nonce(
1362
+			array(
1363
+				'page'   => 'espresso_events',
1364
+				'action' => 'default',
1365
+			),
1366
+			admin_url('admin.php')
1367
+		);
1368
+	}
1369 1369
 }
Please login to merge, or discard this patch.
core/libraries/shortcodes/EE_Organization_Shortcodes.lib.php 1 patch
Indentation   +135 added lines, -135 removed lines patch added patch discarded remove patch
@@ -19,139 +19,139 @@
 block discarded – undo
19 19
 {
20 20
 
21 21
 
22
-    public function __construct()
23
-    {
24
-        parent::__construct();
25
-    }
26
-
27
-
28
-    protected function _init_props()
29
-    {
30
-        $this->label = esc_html__('Organization Shortcodes', 'event_espresso');
31
-        $this->description = esc_html__('All shortcodes specific to organization related data', 'event_espresso');
32
-        $this->_shortcodes = array(
33
-            '[COMPANY]'          => esc_html__('Event organization name', 'event_espresso'),
34
-            '[CO_ADD1]'          => esc_html__('Address 1 value for the organization', 'event_espresso'),
35
-            '[CO_ADD2]'          => esc_html__('Address 2 value for the organization', 'event_espresso'),
36
-            '[CO_CITY]'          => esc_html__('City the organization is in', 'event_espresso'),
37
-            '[CO_STATE]'         => esc_html__('State the organization is located in', 'event_espresso'),
38
-            '[CO_ZIP]'           => esc_html__('The zip code for the organization', 'event_espresso'),
39
-            '[CO_LOGO]'          => esc_html__('The logo image for the organization', 'event_espresso'),
40
-            '[CO_EMAIL]'         => esc_html__('The primary email address for the organization', 'event_espresso'),
41
-            '[CO_PHONE]'         => esc_html__('The phone number for the organization', 'event_espresso'),
42
-            '[CO_LOGO_URL]'      => esc_html__(
43
-                'Just the link to the image used as the logo for the organization',
44
-                'event_espresso'
45
-            ),
46
-            '[CO_FACEBOOK_URL]'  => esc_html__('Link to organization Facebook page', 'event_espresso'),
47
-            '[CO_TWITTER_URL]'   => esc_html__('Link to organization Twitter page', 'event_espresso'),
48
-            '[CO_PINTEREST_URL]' => esc_html__('Link to organization Pinterest page', 'event_espresso'),
49
-            '[CO_GOOGLE_URL]'    => esc_html__('Link to organization Google page', 'event_espresso'),
50
-            '[CO_LINKEDIN_URL]'  => esc_html__('Link to organization LinkedIn page', 'event_espresso'),
51
-            '[CO_INSTAGRAM_URL]' => esc_html__('Link to organization Instagram page', 'event_espresso'),
52
-            '[CO_TAX_NUMBER_*]'  => sprintf(
53
-                esc_html__(
54
-                    'This is the shortcode used for displaying any tax number for the company.  %1$sNote: This is a special dynamic shortcode.%2$s You can use the "prefix" parameter to indicate what the prefix for this tax number is.  It defaults to "VAT/Tax Number:".  To change this prefix you do the following format for this shortcode:  [CO_TAX_NUMBER_* prefix="GST: "] and that will output: GST: 12345t56.  Also take note that if you have NO number in your settings, the prefix is not output either.',
55
-                    'event_espresso'
56
-                ),
57
-                '<strong>',
58
-                '</strong>'
59
-            ),
60
-        );
61
-    }
62
-
63
-
64
-    protected function _parser($shortcode)
65
-    {
66
-
67
-        switch ($shortcode) {
68
-            case '[COMPANY]':
69
-                return EE_Registry::instance()->CFG->organization->get_pretty('name');
70
-                break;
71
-
72
-            case '[CO_ADD1]':
73
-                return EE_Registry::instance()->CFG->organization->get_pretty('address_1');
74
-                break;
75
-
76
-            case '[CO_ADD2]':
77
-                return EE_Registry::instance()->CFG->organization->get_pretty('address_2');
78
-                break;
79
-
80
-            case '[CO_CITY]':
81
-                return EE_Registry::instance()->CFG->organization->get_pretty('city');
82
-                break;
83
-
84
-            case '[CO_STATE]':
85
-                $state = EE_Registry::instance()->load_model('State')->get_one_by_ID(
86
-                    EE_Registry::instance()->CFG->organization->STA_ID
87
-                );
88
-                return $state instanceof EE_State ? $state->name() : '';
89
-                break;
90
-
91
-            case '[CO_ZIP]':
92
-                return EE_Registry::instance()->CFG->organization->get_pretty('zip');
93
-                break;
94
-
95
-            case '[CO_EMAIL]':
96
-                return EE_Registry::instance()->CFG->organization->get_pretty('email');
97
-                break;
98
-
99
-            case '[CO_PHONE]':
100
-                return EE_Registry::instance()->CFG->organization->get_pretty('phone');
101
-                break;
102
-
103
-            case '[CO_LOGO]':
104
-                return '<img src="'
105
-                       . EE_Registry::instance()->CFG->organization->get_pretty(
106
-                           'logo_url'
107
-                       ) . '" id="headerImage" />';
108
-                break;
109
-
110
-            case '[CO_LOGO_URL]':
111
-                return EE_Registry::instance()->CFG->organization->get_pretty('logo_url');
112
-                break;
113
-
114
-            case '[CO_FACEBOOK_URL]':
115
-                return EE_Registry::instance()->CFG->organization->get_pretty('facebook');
116
-                break;
117
-
118
-            case '[CO_TWITTER_URL]':
119
-                return EE_Registry::instance()->CFG->organization->get_pretty('twitter');
120
-                break;
121
-
122
-            case '[CO_PINTEREST_URL]':
123
-                return EE_Registry::instance()->CFG->organization->get_pretty('pinterest');
124
-                break;
125
-
126
-            case '[CO_LINKEDIN_URL]':
127
-                return EE_Registry::instance()->CFG->organization->get_pretty('linkedin');
128
-                break;
129
-
130
-            case '[CO_GOOGLE_URL]':
131
-                return EE_Registry::instance()->CFG->organization->get_pretty('google');
132
-                break;
133
-
134
-            case '[CO_INSTAGRAM_URL]':
135
-                return EE_Registry::instance()->CFG->organization->get_pretty('instagram');
136
-                break;
137
-        }
138
-
139
-        // also allow for parameter shortcode
140
-        if (strpos($shortcode, '[CO_TAX_NUMBER_*') !== false) {
141
-            // first see if there is any company tax number set and bail early if not
142
-            $tax_number = EE_Registry::instance()->CFG->organization->vat;
143
-            if (empty($tax_number)) {
144
-                return '';
145
-            }
146
-
147
-            // see if there are any attributes.
148
-            $attrs = $this->_get_shortcode_attrs($shortcode);
149
-
150
-            // set custom attrs if present (or default)
151
-            $prefix = isset($attrs['prefix']) ? $attrs['prefix'] : esc_html__('VAT/Tax Number: ', 'event_espresso');
152
-            return $prefix . $tax_number;
153
-        }
154
-
155
-        return '';
156
-    }
22
+	public function __construct()
23
+	{
24
+		parent::__construct();
25
+	}
26
+
27
+
28
+	protected function _init_props()
29
+	{
30
+		$this->label = esc_html__('Organization Shortcodes', 'event_espresso');
31
+		$this->description = esc_html__('All shortcodes specific to organization related data', 'event_espresso');
32
+		$this->_shortcodes = array(
33
+			'[COMPANY]'          => esc_html__('Event organization name', 'event_espresso'),
34
+			'[CO_ADD1]'          => esc_html__('Address 1 value for the organization', 'event_espresso'),
35
+			'[CO_ADD2]'          => esc_html__('Address 2 value for the organization', 'event_espresso'),
36
+			'[CO_CITY]'          => esc_html__('City the organization is in', 'event_espresso'),
37
+			'[CO_STATE]'         => esc_html__('State the organization is located in', 'event_espresso'),
38
+			'[CO_ZIP]'           => esc_html__('The zip code for the organization', 'event_espresso'),
39
+			'[CO_LOGO]'          => esc_html__('The logo image for the organization', 'event_espresso'),
40
+			'[CO_EMAIL]'         => esc_html__('The primary email address for the organization', 'event_espresso'),
41
+			'[CO_PHONE]'         => esc_html__('The phone number for the organization', 'event_espresso'),
42
+			'[CO_LOGO_URL]'      => esc_html__(
43
+				'Just the link to the image used as the logo for the organization',
44
+				'event_espresso'
45
+			),
46
+			'[CO_FACEBOOK_URL]'  => esc_html__('Link to organization Facebook page', 'event_espresso'),
47
+			'[CO_TWITTER_URL]'   => esc_html__('Link to organization Twitter page', 'event_espresso'),
48
+			'[CO_PINTEREST_URL]' => esc_html__('Link to organization Pinterest page', 'event_espresso'),
49
+			'[CO_GOOGLE_URL]'    => esc_html__('Link to organization Google page', 'event_espresso'),
50
+			'[CO_LINKEDIN_URL]'  => esc_html__('Link to organization LinkedIn page', 'event_espresso'),
51
+			'[CO_INSTAGRAM_URL]' => esc_html__('Link to organization Instagram page', 'event_espresso'),
52
+			'[CO_TAX_NUMBER_*]'  => sprintf(
53
+				esc_html__(
54
+					'This is the shortcode used for displaying any tax number for the company.  %1$sNote: This is a special dynamic shortcode.%2$s You can use the "prefix" parameter to indicate what the prefix for this tax number is.  It defaults to "VAT/Tax Number:".  To change this prefix you do the following format for this shortcode:  [CO_TAX_NUMBER_* prefix="GST: "] and that will output: GST: 12345t56.  Also take note that if you have NO number in your settings, the prefix is not output either.',
55
+					'event_espresso'
56
+				),
57
+				'<strong>',
58
+				'</strong>'
59
+			),
60
+		);
61
+	}
62
+
63
+
64
+	protected function _parser($shortcode)
65
+	{
66
+
67
+		switch ($shortcode) {
68
+			case '[COMPANY]':
69
+				return EE_Registry::instance()->CFG->organization->get_pretty('name');
70
+				break;
71
+
72
+			case '[CO_ADD1]':
73
+				return EE_Registry::instance()->CFG->organization->get_pretty('address_1');
74
+				break;
75
+
76
+			case '[CO_ADD2]':
77
+				return EE_Registry::instance()->CFG->organization->get_pretty('address_2');
78
+				break;
79
+
80
+			case '[CO_CITY]':
81
+				return EE_Registry::instance()->CFG->organization->get_pretty('city');
82
+				break;
83
+
84
+			case '[CO_STATE]':
85
+				$state = EE_Registry::instance()->load_model('State')->get_one_by_ID(
86
+					EE_Registry::instance()->CFG->organization->STA_ID
87
+				);
88
+				return $state instanceof EE_State ? $state->name() : '';
89
+				break;
90
+
91
+			case '[CO_ZIP]':
92
+				return EE_Registry::instance()->CFG->organization->get_pretty('zip');
93
+				break;
94
+
95
+			case '[CO_EMAIL]':
96
+				return EE_Registry::instance()->CFG->organization->get_pretty('email');
97
+				break;
98
+
99
+			case '[CO_PHONE]':
100
+				return EE_Registry::instance()->CFG->organization->get_pretty('phone');
101
+				break;
102
+
103
+			case '[CO_LOGO]':
104
+				return '<img src="'
105
+					   . EE_Registry::instance()->CFG->organization->get_pretty(
106
+						   'logo_url'
107
+					   ) . '" id="headerImage" />';
108
+				break;
109
+
110
+			case '[CO_LOGO_URL]':
111
+				return EE_Registry::instance()->CFG->organization->get_pretty('logo_url');
112
+				break;
113
+
114
+			case '[CO_FACEBOOK_URL]':
115
+				return EE_Registry::instance()->CFG->organization->get_pretty('facebook');
116
+				break;
117
+
118
+			case '[CO_TWITTER_URL]':
119
+				return EE_Registry::instance()->CFG->organization->get_pretty('twitter');
120
+				break;
121
+
122
+			case '[CO_PINTEREST_URL]':
123
+				return EE_Registry::instance()->CFG->organization->get_pretty('pinterest');
124
+				break;
125
+
126
+			case '[CO_LINKEDIN_URL]':
127
+				return EE_Registry::instance()->CFG->organization->get_pretty('linkedin');
128
+				break;
129
+
130
+			case '[CO_GOOGLE_URL]':
131
+				return EE_Registry::instance()->CFG->organization->get_pretty('google');
132
+				break;
133
+
134
+			case '[CO_INSTAGRAM_URL]':
135
+				return EE_Registry::instance()->CFG->organization->get_pretty('instagram');
136
+				break;
137
+		}
138
+
139
+		// also allow for parameter shortcode
140
+		if (strpos($shortcode, '[CO_TAX_NUMBER_*') !== false) {
141
+			// first see if there is any company tax number set and bail early if not
142
+			$tax_number = EE_Registry::instance()->CFG->organization->vat;
143
+			if (empty($tax_number)) {
144
+				return '';
145
+			}
146
+
147
+			// see if there are any attributes.
148
+			$attrs = $this->_get_shortcode_attrs($shortcode);
149
+
150
+			// set custom attrs if present (or default)
151
+			$prefix = isset($attrs['prefix']) ? $attrs['prefix'] : esc_html__('VAT/Tax Number: ', 'event_espresso');
152
+			return $prefix . $tax_number;
153
+		}
154
+
155
+		return '';
156
+	}
157 157
 }
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.9.83.rc.000');
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.9.83.rc.000');
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.
core/services/assets/Registry.php 1 patch
Indentation   +731 added lines, -731 removed lines patch added patch discarded remove patch
@@ -27,742 +27,742 @@
 block discarded – undo
27 27
 class Registry
28 28
 {
29 29
 
30
-    const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json';
31
-
32
-    /**
33
-     * @var AssetCollection $assets
34
-     */
35
-    protected $assets;
36
-
37
-    /**
38
-     * @var I18nRegistry
39
-     */
40
-    private $i18n_registry;
41
-
42
-    /**
43
-     * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
44
-     *
45
-     * @var array
46
-     */
47
-    protected $jsdata = array();
48
-
49
-    /**
50
-     * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
51
-     * page source.
52
-     *
53
-     * @var array
54
-     */
55
-    private $script_handles_with_data = array();
56
-
57
-
58
-    /**
59
-     * Holds the manifest data obtained from registered manifest files.
60
-     * Manifests are maps of asset chunk name to actual built asset file names.
61
-     * Shape of this array is:
62
-     * array(
63
-     *  'some_namespace_slug' => array(
64
-     *      'some_chunk_name' => array(
65
-     *          'js' => 'filename.js'
66
-     *          'css' => 'filename.js'
67
-     *      ),
68
-     *      'url_base' => 'https://baseurl.com/to/assets
69
-     *  )
70
-     * )
71
-     *
72
-     * @var array
73
-     */
74
-    private $manifest_data = array();
75
-
76
-
77
-    /**
78
-     * Holds any dependency data obtained from registered dependency map json.
79
-     * Dependency map json is generated via the @wordpress/dependency-extraction-webpack-plugin via the webpack config.
80
-     * @see https://github.com/WordPress/gutenberg/tree/master/packages/dependency-extraction-webpack-plugin
81
-     *
82
-     * @var array
83
-     */
84
-    private $dependencies_data = [];
85
-
86
-
87
-    /**
88
-     * This is a known array of possible wp css handles that correspond to what may be exposed as dependencies in our
89
-     * build process.  Currently the dependency export process in webpack does not consider css imports, so we derive
90
-     * them via the js dependencies (WP uses the same handle for both js and css). This is a list of known handles that
91
-     * are used for both js and css.
92
-     * @var array
93
-     */
94
-    private $wp_css_handle_dependencies = [
95
-        'wp-components',
96
-        'wp-block-editor',
97
-        'wp-block-library',
98
-        'wp-edit-post',
99
-        'wp-edit-widgets',
100
-        'wp-editor',
101
-        'wp-format-library',
102
-        'wp-list-reusable-blocks',
103
-        'wp-nux',
104
-    ];
105
-
106
-
107
-    /**
108
-     * Registry constructor.
109
-     * Hooking into WP actions for script registry.
110
-     *
111
-     * @param AssetCollection      $assets
112
-     * @param I18nRegistry         $i18n_registry
113
-     * @throws InvalidArgumentException
114
-     * @throws InvalidDataTypeException
115
-     * @throws InvalidInterfaceException
116
-     */
117
-    public function __construct(AssetCollection $assets, I18nRegistry $i18n_registry)
118
-    {
119
-        $this->assets = $assets;
120
-        $this->i18n_registry = $i18n_registry;
121
-        add_action('wp_enqueue_scripts', array($this, 'registerManifestFiles'), 1);
122
-        add_action('admin_enqueue_scripts', array($this, 'registerManifestFiles'), 1);
123
-        add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3);
124
-        add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3);
125
-        add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 4);
126
-        add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 4);
127
-        add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
128
-        add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
129
-    }
130
-
131
-
132
-    /**
133
-     * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n
134
-     * translation handling.
135
-     *
136
-     * @return I18nRegistry
137
-     */
138
-    public function getI18nRegistry()
139
-    {
140
-        return $this->i18n_registry;
141
-    }
142
-
143
-
144
-    /**
145
-     * Callback for the wp_enqueue_scripts actions used to register assets.
146
-     *
147
-     * @since 4.9.62.p
148
-     * @throws Exception
149
-     */
150
-    public function registerScriptsAndStyles()
151
-    {
152
-        try {
153
-            $this->registerScripts($this->assets->getJavascriptAssets());
154
-            $this->registerStyles($this->assets->getStylesheetAssets());
155
-        } catch (Exception $exception) {
156
-            new ExceptionStackTraceDisplay($exception);
157
-        }
158
-    }
159
-
160
-
161
-    /**
162
-     * Registers JS assets with WP core
163
-     *
164
-     * @since 4.9.62.p
165
-     * @param JavascriptAsset[] $scripts
166
-     * @throws AssetRegistrationException
167
-     * @throws InvalidDataTypeException
168
-     */
169
-    public function registerScripts(array $scripts)
170
-    {
171
-        foreach ($scripts as $script) {
172
-            // skip to next script if this has already been done
173
-            if ($script->isRegistered()) {
174
-                continue;
175
-            }
176
-            do_action(
177
-                'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script',
178
-                $script
179
-            );
180
-            $registered = wp_register_script(
181
-                $script->handle(),
182
-                $script->source(),
183
-                $script->dependencies(),
184
-                $script->version(),
185
-                $script->loadInFooter()
186
-            );
187
-            if (! $registered && $this->debug()) {
188
-                throw new AssetRegistrationException($script->handle());
189
-            }
190
-            $script->setRegistered($registered);
191
-            if ($script->requiresTranslation()) {
192
-                $this->registerTranslation($script->handle());
193
-            }
194
-            do_action(
195
-                'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script',
196
-                $script
197
-            );
198
-        }
199
-    }
200
-
201
-
202
-    /**
203
-     * Registers CSS assets with WP core
204
-     *
205
-     * @since 4.9.62.p
206
-     * @param StylesheetAsset[] $styles
207
-     * @throws InvalidDataTypeException
208
-     */
209
-    public function registerStyles(array $styles)
210
-    {
211
-        foreach ($styles as $style) {
212
-            // skip to next style if this has already been done
213
-            if ($style->isRegistered()) {
214
-                continue;
215
-            }
216
-            do_action(
217
-                'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style',
218
-                $style
219
-            );
220
-            wp_register_style(
221
-                $style->handle(),
222
-                $style->source(),
223
-                $style->dependencies(),
224
-                $style->version(),
225
-                $style->media()
226
-            );
227
-            $style->setRegistered();
228
-            do_action(
229
-                'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style',
230
-                $style
231
-            );
232
-        }
233
-    }
234
-
235
-
236
-    /**
237
-     * Call back for the script print in frontend and backend.
238
-     * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
239
-     *
240
-     * @since 4.9.31.rc.015
241
-     */
242
-    public function enqueueData()
243
-    {
244
-        $this->removeAlreadyRegisteredDataForScriptHandles();
245
-        wp_add_inline_script(
246
-            'eejs-core',
247
-            'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)),
248
-            'before'
249
-        );
250
-        $scripts = $this->assets->getJavascriptAssetsWithData();
251
-        foreach ($scripts as $script) {
252
-            $this->addRegisteredScriptHandlesWithData($script->handle());
253
-            if ($script->hasInlineDataCallback()) {
254
-                $localize = $script->inlineDataCallback();
255
-                $localize();
256
-            }
257
-        }
258
-    }
259
-
260
-
261
-    /**
262
-     * Used to add data to eejs.data object.
263
-     * Note:  Overriding existing data is not allowed.
264
-     * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
265
-     * If the data you add is something like this:
266
-     *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
267
-     * It will be exposed in the page source as:
268
-     *  eejs.data.my_plugin_data.foo == gar
269
-     *
270
-     * @param string       $key   Key used to access your data
271
-     * @param string|array $value Value to attach to key
272
-     * @throws InvalidArgumentException
273
-     */
274
-    public function addData($key, $value)
275
-    {
276
-        if ($this->verifyDataNotExisting($key)) {
277
-            $this->jsdata[ $key ] = $value;
278
-        }
279
-    }
280
-
281
-
282
-    /**
283
-     * Similar to addData except this allows for users to push values to an existing key where the values on key are
284
-     * elements in an array.
285
-     *
286
-     * When you use this method, the value you include will be merged with the array on $key.
287
-     * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript
288
-     * object like this, eejs.data.test = [ my_data,
289
-     * ]
290
-     * If there has already been a scalar value attached to the data object given key (via addData for instance), then
291
-     * this will throw an exception.
292
-     *
293
-     * Caution: Only add data using this method if you are okay with the potential for additional data added on the same
294
-     * key potentially overriding the existing data on merge (specifically with associative arrays).
295
-     *
296
-     * @param string       $key   Key to attach data to.
297
-     * @param string|array $value Value being registered.
298
-     * @throws InvalidArgumentException
299
-     */
300
-    public function pushData($key, $value)
301
-    {
302
-        if (isset($this->jsdata[ $key ])
303
-            && ! is_array($this->jsdata[ $key ])
304
-        ) {
305
-            if (! $this->debug()) {
306
-                return;
307
-            }
308
-            throw new InvalidArgumentException(
309
-                sprintf(
310
-                    __(
311
-                        'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
30
+	const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json';
31
+
32
+	/**
33
+	 * @var AssetCollection $assets
34
+	 */
35
+	protected $assets;
36
+
37
+	/**
38
+	 * @var I18nRegistry
39
+	 */
40
+	private $i18n_registry;
41
+
42
+	/**
43
+	 * This holds the jsdata data object that will be exposed on pages that enqueue the `eejs-core` script.
44
+	 *
45
+	 * @var array
46
+	 */
47
+	protected $jsdata = array();
48
+
49
+	/**
50
+	 * This keeps track of all scripts with registered data.  It is used to prevent duplicate data objects setup in the
51
+	 * page source.
52
+	 *
53
+	 * @var array
54
+	 */
55
+	private $script_handles_with_data = array();
56
+
57
+
58
+	/**
59
+	 * Holds the manifest data obtained from registered manifest files.
60
+	 * Manifests are maps of asset chunk name to actual built asset file names.
61
+	 * Shape of this array is:
62
+	 * array(
63
+	 *  'some_namespace_slug' => array(
64
+	 *      'some_chunk_name' => array(
65
+	 *          'js' => 'filename.js'
66
+	 *          'css' => 'filename.js'
67
+	 *      ),
68
+	 *      'url_base' => 'https://baseurl.com/to/assets
69
+	 *  )
70
+	 * )
71
+	 *
72
+	 * @var array
73
+	 */
74
+	private $manifest_data = array();
75
+
76
+
77
+	/**
78
+	 * Holds any dependency data obtained from registered dependency map json.
79
+	 * Dependency map json is generated via the @wordpress/dependency-extraction-webpack-plugin via the webpack config.
80
+	 * @see https://github.com/WordPress/gutenberg/tree/master/packages/dependency-extraction-webpack-plugin
81
+	 *
82
+	 * @var array
83
+	 */
84
+	private $dependencies_data = [];
85
+
86
+
87
+	/**
88
+	 * This is a known array of possible wp css handles that correspond to what may be exposed as dependencies in our
89
+	 * build process.  Currently the dependency export process in webpack does not consider css imports, so we derive
90
+	 * them via the js dependencies (WP uses the same handle for both js and css). This is a list of known handles that
91
+	 * are used for both js and css.
92
+	 * @var array
93
+	 */
94
+	private $wp_css_handle_dependencies = [
95
+		'wp-components',
96
+		'wp-block-editor',
97
+		'wp-block-library',
98
+		'wp-edit-post',
99
+		'wp-edit-widgets',
100
+		'wp-editor',
101
+		'wp-format-library',
102
+		'wp-list-reusable-blocks',
103
+		'wp-nux',
104
+	];
105
+
106
+
107
+	/**
108
+	 * Registry constructor.
109
+	 * Hooking into WP actions for script registry.
110
+	 *
111
+	 * @param AssetCollection      $assets
112
+	 * @param I18nRegistry         $i18n_registry
113
+	 * @throws InvalidArgumentException
114
+	 * @throws InvalidDataTypeException
115
+	 * @throws InvalidInterfaceException
116
+	 */
117
+	public function __construct(AssetCollection $assets, I18nRegistry $i18n_registry)
118
+	{
119
+		$this->assets = $assets;
120
+		$this->i18n_registry = $i18n_registry;
121
+		add_action('wp_enqueue_scripts', array($this, 'registerManifestFiles'), 1);
122
+		add_action('admin_enqueue_scripts', array($this, 'registerManifestFiles'), 1);
123
+		add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3);
124
+		add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 3);
125
+		add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 4);
126
+		add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 4);
127
+		add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1);
128
+		add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1);
129
+	}
130
+
131
+
132
+	/**
133
+	 * For classes that have Registry as a dependency, this provides a handy way to register script handles for i18n
134
+	 * translation handling.
135
+	 *
136
+	 * @return I18nRegistry
137
+	 */
138
+	public function getI18nRegistry()
139
+	{
140
+		return $this->i18n_registry;
141
+	}
142
+
143
+
144
+	/**
145
+	 * Callback for the wp_enqueue_scripts actions used to register assets.
146
+	 *
147
+	 * @since 4.9.62.p
148
+	 * @throws Exception
149
+	 */
150
+	public function registerScriptsAndStyles()
151
+	{
152
+		try {
153
+			$this->registerScripts($this->assets->getJavascriptAssets());
154
+			$this->registerStyles($this->assets->getStylesheetAssets());
155
+		} catch (Exception $exception) {
156
+			new ExceptionStackTraceDisplay($exception);
157
+		}
158
+	}
159
+
160
+
161
+	/**
162
+	 * Registers JS assets with WP core
163
+	 *
164
+	 * @since 4.9.62.p
165
+	 * @param JavascriptAsset[] $scripts
166
+	 * @throws AssetRegistrationException
167
+	 * @throws InvalidDataTypeException
168
+	 */
169
+	public function registerScripts(array $scripts)
170
+	{
171
+		foreach ($scripts as $script) {
172
+			// skip to next script if this has already been done
173
+			if ($script->isRegistered()) {
174
+				continue;
175
+			}
176
+			do_action(
177
+				'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script',
178
+				$script
179
+			);
180
+			$registered = wp_register_script(
181
+				$script->handle(),
182
+				$script->source(),
183
+				$script->dependencies(),
184
+				$script->version(),
185
+				$script->loadInFooter()
186
+			);
187
+			if (! $registered && $this->debug()) {
188
+				throw new AssetRegistrationException($script->handle());
189
+			}
190
+			$script->setRegistered($registered);
191
+			if ($script->requiresTranslation()) {
192
+				$this->registerTranslation($script->handle());
193
+			}
194
+			do_action(
195
+				'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script',
196
+				$script
197
+			);
198
+		}
199
+	}
200
+
201
+
202
+	/**
203
+	 * Registers CSS assets with WP core
204
+	 *
205
+	 * @since 4.9.62.p
206
+	 * @param StylesheetAsset[] $styles
207
+	 * @throws InvalidDataTypeException
208
+	 */
209
+	public function registerStyles(array $styles)
210
+	{
211
+		foreach ($styles as $style) {
212
+			// skip to next style if this has already been done
213
+			if ($style->isRegistered()) {
214
+				continue;
215
+			}
216
+			do_action(
217
+				'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style',
218
+				$style
219
+			);
220
+			wp_register_style(
221
+				$style->handle(),
222
+				$style->source(),
223
+				$style->dependencies(),
224
+				$style->version(),
225
+				$style->media()
226
+			);
227
+			$style->setRegistered();
228
+			do_action(
229
+				'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style',
230
+				$style
231
+			);
232
+		}
233
+	}
234
+
235
+
236
+	/**
237
+	 * Call back for the script print in frontend and backend.
238
+	 * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point.
239
+	 *
240
+	 * @since 4.9.31.rc.015
241
+	 */
242
+	public function enqueueData()
243
+	{
244
+		$this->removeAlreadyRegisteredDataForScriptHandles();
245
+		wp_add_inline_script(
246
+			'eejs-core',
247
+			'var eejsdata=' . wp_json_encode(array('data' => $this->jsdata)),
248
+			'before'
249
+		);
250
+		$scripts = $this->assets->getJavascriptAssetsWithData();
251
+		foreach ($scripts as $script) {
252
+			$this->addRegisteredScriptHandlesWithData($script->handle());
253
+			if ($script->hasInlineDataCallback()) {
254
+				$localize = $script->inlineDataCallback();
255
+				$localize();
256
+			}
257
+		}
258
+	}
259
+
260
+
261
+	/**
262
+	 * Used to add data to eejs.data object.
263
+	 * Note:  Overriding existing data is not allowed.
264
+	 * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript.
265
+	 * If the data you add is something like this:
266
+	 *  $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) );
267
+	 * It will be exposed in the page source as:
268
+	 *  eejs.data.my_plugin_data.foo == gar
269
+	 *
270
+	 * @param string       $key   Key used to access your data
271
+	 * @param string|array $value Value to attach to key
272
+	 * @throws InvalidArgumentException
273
+	 */
274
+	public function addData($key, $value)
275
+	{
276
+		if ($this->verifyDataNotExisting($key)) {
277
+			$this->jsdata[ $key ] = $value;
278
+		}
279
+	}
280
+
281
+
282
+	/**
283
+	 * Similar to addData except this allows for users to push values to an existing key where the values on key are
284
+	 * elements in an array.
285
+	 *
286
+	 * When you use this method, the value you include will be merged with the array on $key.
287
+	 * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript
288
+	 * object like this, eejs.data.test = [ my_data,
289
+	 * ]
290
+	 * If there has already been a scalar value attached to the data object given key (via addData for instance), then
291
+	 * this will throw an exception.
292
+	 *
293
+	 * Caution: Only add data using this method if you are okay with the potential for additional data added on the same
294
+	 * key potentially overriding the existing data on merge (specifically with associative arrays).
295
+	 *
296
+	 * @param string       $key   Key to attach data to.
297
+	 * @param string|array $value Value being registered.
298
+	 * @throws InvalidArgumentException
299
+	 */
300
+	public function pushData($key, $value)
301
+	{
302
+		if (isset($this->jsdata[ $key ])
303
+			&& ! is_array($this->jsdata[ $key ])
304
+		) {
305
+			if (! $this->debug()) {
306
+				return;
307
+			}
308
+			throw new InvalidArgumentException(
309
+				sprintf(
310
+					__(
311
+						'The value for %1$s is already set and it is not an array. The %2$s method can only be used to
312 312
                          push values to this data element when it is an array.',
313
-                        'event_espresso'
314
-                    ),
315
-                    $key,
316
-                    __METHOD__
317
-                )
318
-            );
319
-        }
320
-        if ( ! isset( $this->jsdata[ $key ] ) ) {
321
-            $this->jsdata[ $key ] = is_array($value) ? $value : [$value];
322
-        } else {
323
-            $this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value);
324
-        }
325
-    }
326
-
327
-
328
-    /**
329
-     * Used to set content used by javascript for a template.
330
-     * Note: Overrides of existing registered templates are not allowed.
331
-     *
332
-     * @param string $template_reference
333
-     * @param string $template_content
334
-     * @throws InvalidArgumentException
335
-     */
336
-    public function addTemplate($template_reference, $template_content)
337
-    {
338
-        if (! isset($this->jsdata['templates'])) {
339
-            $this->jsdata['templates'] = array();
340
-        }
341
-        //no overrides allowed.
342
-        if (isset($this->jsdata['templates'][ $template_reference ])) {
343
-            if (! $this->debug()) {
344
-                return;
345
-            }
346
-            throw new InvalidArgumentException(
347
-                sprintf(
348
-                    __(
349
-                        'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
350
-                        'event_espresso'
351
-                    ),
352
-                    $template_reference
353
-                )
354
-            );
355
-        }
356
-        $this->jsdata['templates'][ $template_reference ] = $template_content;
357
-    }
358
-
359
-
360
-    /**
361
-     * Retrieve the template content already registered for the given reference.
362
-     *
363
-     * @param string $template_reference
364
-     * @return string
365
-     */
366
-    public function getTemplate($template_reference)
367
-    {
368
-        return isset($this->jsdata['templates'][ $template_reference ])
369
-            ? $this->jsdata['templates'][ $template_reference ]
370
-            : '';
371
-    }
372
-
373
-
374
-    /**
375
-     * Retrieve registered data.
376
-     *
377
-     * @param string $key Name of key to attach data to.
378
-     * @return mixed                If there is no for the given key, then false is returned.
379
-     */
380
-    public function getData($key)
381
-    {
382
-        return isset($this->jsdata[ $key ])
383
-            ? $this->jsdata[ $key ]
384
-            : false;
385
-    }
386
-
387
-
388
-    /**
389
-     * Verifies whether the given data exists already on the jsdata array.
390
-     * Overriding data is not allowed.
391
-     *
392
-     * @param string $key Index for data.
393
-     * @return bool        If valid then return true.
394
-     * @throws InvalidArgumentException if data already exists.
395
-     */
396
-    protected function verifyDataNotExisting($key)
397
-    {
398
-        if (isset($this->jsdata[ $key ])) {
399
-            if (! $this->debug()) {
400
-                return false;
401
-            }
402
-            if (is_array($this->jsdata[ $key ])) {
403
-                throw new InvalidArgumentException(
404
-                    sprintf(
405
-                        __(
406
-                            'The value for %1$s already exists in the Registry::eejs object.
313
+						'event_espresso'
314
+					),
315
+					$key,
316
+					__METHOD__
317
+				)
318
+			);
319
+		}
320
+		if ( ! isset( $this->jsdata[ $key ] ) ) {
321
+			$this->jsdata[ $key ] = is_array($value) ? $value : [$value];
322
+		} else {
323
+			$this->jsdata[ $key ] = array_merge( $this->jsdata[$key], (array) $value);
324
+		}
325
+	}
326
+
327
+
328
+	/**
329
+	 * Used to set content used by javascript for a template.
330
+	 * Note: Overrides of existing registered templates are not allowed.
331
+	 *
332
+	 * @param string $template_reference
333
+	 * @param string $template_content
334
+	 * @throws InvalidArgumentException
335
+	 */
336
+	public function addTemplate($template_reference, $template_content)
337
+	{
338
+		if (! isset($this->jsdata['templates'])) {
339
+			$this->jsdata['templates'] = array();
340
+		}
341
+		//no overrides allowed.
342
+		if (isset($this->jsdata['templates'][ $template_reference ])) {
343
+			if (! $this->debug()) {
344
+				return;
345
+			}
346
+			throw new InvalidArgumentException(
347
+				sprintf(
348
+					__(
349
+						'The %1$s key already exists for the templates array in the js data array.  No overrides are allowed.',
350
+						'event_espresso'
351
+					),
352
+					$template_reference
353
+				)
354
+			);
355
+		}
356
+		$this->jsdata['templates'][ $template_reference ] = $template_content;
357
+	}
358
+
359
+
360
+	/**
361
+	 * Retrieve the template content already registered for the given reference.
362
+	 *
363
+	 * @param string $template_reference
364
+	 * @return string
365
+	 */
366
+	public function getTemplate($template_reference)
367
+	{
368
+		return isset($this->jsdata['templates'][ $template_reference ])
369
+			? $this->jsdata['templates'][ $template_reference ]
370
+			: '';
371
+	}
372
+
373
+
374
+	/**
375
+	 * Retrieve registered data.
376
+	 *
377
+	 * @param string $key Name of key to attach data to.
378
+	 * @return mixed                If there is no for the given key, then false is returned.
379
+	 */
380
+	public function getData($key)
381
+	{
382
+		return isset($this->jsdata[ $key ])
383
+			? $this->jsdata[ $key ]
384
+			: false;
385
+	}
386
+
387
+
388
+	/**
389
+	 * Verifies whether the given data exists already on the jsdata array.
390
+	 * Overriding data is not allowed.
391
+	 *
392
+	 * @param string $key Index for data.
393
+	 * @return bool        If valid then return true.
394
+	 * @throws InvalidArgumentException if data already exists.
395
+	 */
396
+	protected function verifyDataNotExisting($key)
397
+	{
398
+		if (isset($this->jsdata[ $key ])) {
399
+			if (! $this->debug()) {
400
+				return false;
401
+			}
402
+			if (is_array($this->jsdata[ $key ])) {
403
+				throw new InvalidArgumentException(
404
+					sprintf(
405
+						__(
406
+							'The value for %1$s already exists in the Registry::eejs object.
407 407
                             Overrides are not allowed. Since the value of this data is an array, you may want to use the
408 408
                             %2$s method to push your value to the array.',
409
-                            'event_espresso'
410
-                        ),
411
-                        $key,
412
-                        'pushData()'
413
-                    )
414
-                );
415
-            }
416
-            throw new InvalidArgumentException(
417
-                sprintf(
418
-                    __(
419
-                        'The value for %1$s already exists in the Registry::eejs object. Overrides are not
409
+							'event_espresso'
410
+						),
411
+						$key,
412
+						'pushData()'
413
+					)
414
+				);
415
+			}
416
+			throw new InvalidArgumentException(
417
+				sprintf(
418
+					__(
419
+						'The value for %1$s already exists in the Registry::eejs object. Overrides are not
420 420
                         allowed.  Consider attaching your value to a different key',
421
-                        'event_espresso'
422
-                    ),
423
-                    $key
424
-                )
425
-            );
426
-        }
427
-        return true;
428
-    }
429
-
430
-
431
-    /**
432
-     * Get the actual asset path for asset manifests.
433
-     * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned.
434
-     *
435
-     * @param string $namespace  The namespace associated with the manifest file hosting the map of chunk_name to actual
436
-     *                           asset file location.
437
-     * @param string $chunk_name
438
-     * @param string $asset_type
439
-     * @return string
440
-     * @since 4.9.59.p
441
-     */
442
-    public function getAssetUrl($namespace, $chunk_name, $asset_type)
443
-    {
444
-        $url = isset(
445
-            $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ],
446
-            $this->manifest_data[ $namespace ]['url_base']
447
-        )
448
-            ? $this->manifest_data[ $namespace ]['url_base']
449
-              . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ]
450
-            : $chunk_name;
451
-
452
-        return apply_filters(
453
-            'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl',
454
-            $url,
455
-            $namespace,
456
-            $chunk_name,
457
-            $asset_type
458
-        );
459
-    }
460
-
461
-
462
-
463
-    /**
464
-     * Return the url to a js file for the given namespace and chunk name.
465
-     *
466
-     * @param string $namespace
467
-     * @param string $chunk_name
468
-     * @return string
469
-     */
470
-    public function getJsUrl($namespace, $chunk_name)
471
-    {
472
-        return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS);
473
-    }
474
-
475
-
476
-    /**
477
-     * Return the url to a css file for the given namespace and chunk name.
478
-     *
479
-     * @param string $namespace
480
-     * @param string $chunk_name
481
-     * @return string
482
-     */
483
-    public function getCssUrl($namespace, $chunk_name)
484
-    {
485
-        return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS);
486
-    }
487
-
488
-
489
-    /**
490
-     * Return the dependencies for a given asset $chunk_name
491
-     *
492
-     * @param string $namespace
493
-     * @param string $chunk_name
494
-     * @param string $asset_type
495
-     * @return array
496
-     * @since 4.9.82.p
497
-     */
498
-    private function getDependenciesForAsset($namespace, $chunk_name, $asset_type)
499
-    {
500
-        $asset_index = $chunk_name . '.' . $asset_type;
501
-        if (! isset( $this->dependencies_data[ $namespace ][ $asset_index ])) {
502
-            $path = isset($this->manifest_data[ $namespace ]['path'])
503
-                ? $this->manifest_data[ $namespace ]['path']
504
-                : '';
505
-            $dependencies_index = $chunk_name . '.' . Asset::TYPE_JSON;
506
-            $file_path = isset($this->manifest_data[ $namespace ][ $dependencies_index ])
507
-                ? $path . $this->manifest_data[ $namespace ][ $dependencies_index ]
508
-                :
509
-                '';
510
-            $this->dependencies_data[ $namespace ][ $asset_index ] = $file_path !== '' && file_exists($file_path)
511
-                ? $this->getDependenciesForAssetType($namespace, $asset_type, $file_path, $chunk_name)
512
-                : [];
513
-        }
514
-        return $this->dependencies_data[ $namespace ][ $asset_index ];
515
-    }
516
-
517
-
518
-    /**
519
-     * Return dependencies according to asset type.
520
-     *
521
-     * For css assets, this filters the auto generated dependencies by css type.
522
-     *
523
-     * @param string $namespace
524
-     * @param string $asset_type
525
-     * @param string $file_path
526
-     * @param string $chunk_name
527
-     * @return array
528
-     * @since 4.9.82.p
529
-     */
530
-    private function getDependenciesForAssetType($namespace, $asset_type, $file_path, $chunk_name)
531
-    {
532
-        $asset_dependencies = json_decode(file_get_contents($file_path), true);
533
-        if ($asset_type === Asset::TYPE_JS) {
534
-            return $chunk_name === 'eejs-core' ? $asset_dependencies : array_merge(
535
-                $asset_dependencies,
536
-                [ CoreAssetManager::JS_HANDLE_JS_CORE ]
537
-            );
538
-        }
539
-        // for css we need to make sure there is actually a css file related to this chunk.
540
-        if (isset($this->manifest_data[ $namespace ])) {
541
-            // array of css chunk files for ee.
542
-            $css_chunks = array_map(
543
-                function ($value) {
544
-                    return str_replace('.css', '', $value);
545
-                },
546
-                array_filter(
547
-                    array_keys($this->manifest_data[ $namespace ]),
548
-                    function ($value) {
549
-                        return strpos($value, '.css') !== false;
550
-                    }
551
-                )
552
-            );
553
-            // add known wp chunks with css
554
-            $css_chunks = array_merge( $css_chunks, $this->wp_css_handle_dependencies);
555
-            // flip for easier search
556
-            $css_chunks = array_flip($css_chunks);
557
-            // now let's filter the dependencies for the incoming chunk to actual chunks that have styles
558
-            return array_filter(
559
-                $asset_dependencies,
560
-                function ($chunk_name) use ($css_chunks) {
561
-                    return isset($css_chunks[ $chunk_name ]);
562
-                }
563
-            );
564
-        }
565
-        return [];
566
-    }
567
-
568
-
569
-    /**
570
-     * Get the dependencies array for the given js asset chunk name
571
-     *
572
-     * @param string $namespace
573
-     * @param string $chunk_name
574
-     * @return array
575
-     * @since 4.9.82.p
576
-     */
577
-    public function getJsDependencies($namespace, $chunk_name)
578
-    {
579
-        return $this->getDependenciesForAsset($namespace, $chunk_name, Asset::TYPE_JS);
580
-    }
581
-
582
-
583
-    /**
584
-     * Get the dependencies array for the given css asset chunk name
585
-     *
586
-     * @param string $namespace
587
-     * @param string $chunk_name
588
-     * @return array
589
-     * @since 4.9.82.p
590
-     */
591
-    public function getCssDependencies($namespace, $chunk_name)
592
-    {
593
-        return $this->getDependenciesForAsset($namespace, $chunk_name, Asset::TYPE_CSS);
594
-    }
595
-
596
-
597
-    /**
598
-     * @since 4.9.62.p
599
-     * @throws InvalidArgumentException
600
-     * @throws InvalidFilePathException
601
-     */
602
-    public function registerManifestFiles()
603
-    {
604
-        $manifest_files = $this->assets->getManifestFiles();
605
-        foreach ($manifest_files as $manifest_file) {
606
-            $this->registerManifestFile(
607
-                $manifest_file->assetNamespace(),
608
-                $manifest_file->urlBase(),
609
-                $manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST,
610
-                $manifest_file->filepath()
611
-            );
612
-        }
613
-    }
614
-
615
-
616
-    /**
617
-     * Used to register a js/css manifest file with the registered_manifest_files property.
618
-     *
619
-     * @param string $namespace     Provided to associate the manifest file with a specific namespace.
620
-     * @param string $url_base      The url base for the manifest file location.
621
-     * @param string $manifest_file The absolute path to the manifest file.
622
-     * @param string $manifest_file_path  The path to the folder containing the manifest file. If not provided will be
623
-     *                                    default to `plugin_root/assets/dist`.
624
-     * @throws InvalidArgumentException
625
-     * @throws InvalidFilePathException
626
-     * @since 4.9.59.p
627
-     */
628
-    public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '')
629
-    {
630
-        if (isset($this->manifest_data[ $namespace ])) {
631
-            if (! $this->debug()) {
632
-                return;
633
-            }
634
-            throw new InvalidArgumentException(
635
-                sprintf(
636
-                    esc_html__(
637
-                        'The namespace for this manifest file has already been registered, choose a namespace other than %s',
638
-                        'event_espresso'
639
-                    ),
640
-                    $namespace
641
-                )
642
-            );
643
-        }
644
-        if (filter_var($url_base, FILTER_VALIDATE_URL) === false) {
645
-            if (is_admin()) {
646
-                EE_Error::add_error(
647
-                    sprintf(
648
-                        esc_html__(
649
-                            'The url given for %1$s assets is invalid.  The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant',
650
-                            'event_espresso'
651
-                        ),
652
-                        'Event Espresso',
653
-                        $url_base,
654
-                        'plugins_url',
655
-                        'WP_PLUGIN_URL'
656
-                    ),
657
-                    __FILE__,
658
-                    __FUNCTION__,
659
-                    __LINE__
660
-                );
661
-            }
662
-            return;
663
-        }
664
-        $this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file);
665
-        if (! isset($this->manifest_data[ $namespace ]['url_base'])) {
666
-            $this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base);
667
-        }
668
-        if (! isset($this->manifest_data[ $namespace ]['path'])) {
669
-            $this->manifest_data[ $namespace ]['path'] = $manifest_file_path;
670
-        }
671
-    }
672
-
673
-
674
-    /**
675
-     * Decodes json from the provided manifest file.
676
-     *
677
-     * @since 4.9.59.p
678
-     * @param string $manifest_file Path to manifest file.
679
-     * @return array
680
-     * @throws InvalidFilePathException
681
-     */
682
-    private function decodeManifestFile($manifest_file)
683
-    {
684
-        if (! file_exists($manifest_file)) {
685
-            throw new InvalidFilePathException($manifest_file);
686
-        }
687
-        return json_decode(file_get_contents($manifest_file), true);
688
-    }
689
-
690
-
691
-    /**
692
-     * This is used to set registered script handles that have data.
693
-     *
694
-     * @param string $script_handle
695
-     */
696
-    private function addRegisteredScriptHandlesWithData($script_handle)
697
-    {
698
-        $this->script_handles_with_data[ $script_handle ] = $script_handle;
699
-    }
700
-
701
-
702
-    /**i
421
+						'event_espresso'
422
+					),
423
+					$key
424
+				)
425
+			);
426
+		}
427
+		return true;
428
+	}
429
+
430
+
431
+	/**
432
+	 * Get the actual asset path for asset manifests.
433
+	 * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned.
434
+	 *
435
+	 * @param string $namespace  The namespace associated with the manifest file hosting the map of chunk_name to actual
436
+	 *                           asset file location.
437
+	 * @param string $chunk_name
438
+	 * @param string $asset_type
439
+	 * @return string
440
+	 * @since 4.9.59.p
441
+	 */
442
+	public function getAssetUrl($namespace, $chunk_name, $asset_type)
443
+	{
444
+		$url = isset(
445
+			$this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ],
446
+			$this->manifest_data[ $namespace ]['url_base']
447
+		)
448
+			? $this->manifest_data[ $namespace ]['url_base']
449
+			  . $this->manifest_data[ $namespace ][ $chunk_name . '.' . $asset_type ]
450
+			: $chunk_name;
451
+
452
+		return apply_filters(
453
+			'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl',
454
+			$url,
455
+			$namespace,
456
+			$chunk_name,
457
+			$asset_type
458
+		);
459
+	}
460
+
461
+
462
+
463
+	/**
464
+	 * Return the url to a js file for the given namespace and chunk name.
465
+	 *
466
+	 * @param string $namespace
467
+	 * @param string $chunk_name
468
+	 * @return string
469
+	 */
470
+	public function getJsUrl($namespace, $chunk_name)
471
+	{
472
+		return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS);
473
+	}
474
+
475
+
476
+	/**
477
+	 * Return the url to a css file for the given namespace and chunk name.
478
+	 *
479
+	 * @param string $namespace
480
+	 * @param string $chunk_name
481
+	 * @return string
482
+	 */
483
+	public function getCssUrl($namespace, $chunk_name)
484
+	{
485
+		return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS);
486
+	}
487
+
488
+
489
+	/**
490
+	 * Return the dependencies for a given asset $chunk_name
491
+	 *
492
+	 * @param string $namespace
493
+	 * @param string $chunk_name
494
+	 * @param string $asset_type
495
+	 * @return array
496
+	 * @since 4.9.82.p
497
+	 */
498
+	private function getDependenciesForAsset($namespace, $chunk_name, $asset_type)
499
+	{
500
+		$asset_index = $chunk_name . '.' . $asset_type;
501
+		if (! isset( $this->dependencies_data[ $namespace ][ $asset_index ])) {
502
+			$path = isset($this->manifest_data[ $namespace ]['path'])
503
+				? $this->manifest_data[ $namespace ]['path']
504
+				: '';
505
+			$dependencies_index = $chunk_name . '.' . Asset::TYPE_JSON;
506
+			$file_path = isset($this->manifest_data[ $namespace ][ $dependencies_index ])
507
+				? $path . $this->manifest_data[ $namespace ][ $dependencies_index ]
508
+				:
509
+				'';
510
+			$this->dependencies_data[ $namespace ][ $asset_index ] = $file_path !== '' && file_exists($file_path)
511
+				? $this->getDependenciesForAssetType($namespace, $asset_type, $file_path, $chunk_name)
512
+				: [];
513
+		}
514
+		return $this->dependencies_data[ $namespace ][ $asset_index ];
515
+	}
516
+
517
+
518
+	/**
519
+	 * Return dependencies according to asset type.
520
+	 *
521
+	 * For css assets, this filters the auto generated dependencies by css type.
522
+	 *
523
+	 * @param string $namespace
524
+	 * @param string $asset_type
525
+	 * @param string $file_path
526
+	 * @param string $chunk_name
527
+	 * @return array
528
+	 * @since 4.9.82.p
529
+	 */
530
+	private function getDependenciesForAssetType($namespace, $asset_type, $file_path, $chunk_name)
531
+	{
532
+		$asset_dependencies = json_decode(file_get_contents($file_path), true);
533
+		if ($asset_type === Asset::TYPE_JS) {
534
+			return $chunk_name === 'eejs-core' ? $asset_dependencies : array_merge(
535
+				$asset_dependencies,
536
+				[ CoreAssetManager::JS_HANDLE_JS_CORE ]
537
+			);
538
+		}
539
+		// for css we need to make sure there is actually a css file related to this chunk.
540
+		if (isset($this->manifest_data[ $namespace ])) {
541
+			// array of css chunk files for ee.
542
+			$css_chunks = array_map(
543
+				function ($value) {
544
+					return str_replace('.css', '', $value);
545
+				},
546
+				array_filter(
547
+					array_keys($this->manifest_data[ $namespace ]),
548
+					function ($value) {
549
+						return strpos($value, '.css') !== false;
550
+					}
551
+				)
552
+			);
553
+			// add known wp chunks with css
554
+			$css_chunks = array_merge( $css_chunks, $this->wp_css_handle_dependencies);
555
+			// flip for easier search
556
+			$css_chunks = array_flip($css_chunks);
557
+			// now let's filter the dependencies for the incoming chunk to actual chunks that have styles
558
+			return array_filter(
559
+				$asset_dependencies,
560
+				function ($chunk_name) use ($css_chunks) {
561
+					return isset($css_chunks[ $chunk_name ]);
562
+				}
563
+			);
564
+		}
565
+		return [];
566
+	}
567
+
568
+
569
+	/**
570
+	 * Get the dependencies array for the given js asset chunk name
571
+	 *
572
+	 * @param string $namespace
573
+	 * @param string $chunk_name
574
+	 * @return array
575
+	 * @since 4.9.82.p
576
+	 */
577
+	public function getJsDependencies($namespace, $chunk_name)
578
+	{
579
+		return $this->getDependenciesForAsset($namespace, $chunk_name, Asset::TYPE_JS);
580
+	}
581
+
582
+
583
+	/**
584
+	 * Get the dependencies array for the given css asset chunk name
585
+	 *
586
+	 * @param string $namespace
587
+	 * @param string $chunk_name
588
+	 * @return array
589
+	 * @since 4.9.82.p
590
+	 */
591
+	public function getCssDependencies($namespace, $chunk_name)
592
+	{
593
+		return $this->getDependenciesForAsset($namespace, $chunk_name, Asset::TYPE_CSS);
594
+	}
595
+
596
+
597
+	/**
598
+	 * @since 4.9.62.p
599
+	 * @throws InvalidArgumentException
600
+	 * @throws InvalidFilePathException
601
+	 */
602
+	public function registerManifestFiles()
603
+	{
604
+		$manifest_files = $this->assets->getManifestFiles();
605
+		foreach ($manifest_files as $manifest_file) {
606
+			$this->registerManifestFile(
607
+				$manifest_file->assetNamespace(),
608
+				$manifest_file->urlBase(),
609
+				$manifest_file->filepath() . Registry::FILE_NAME_BUILD_MANIFEST,
610
+				$manifest_file->filepath()
611
+			);
612
+		}
613
+	}
614
+
615
+
616
+	/**
617
+	 * Used to register a js/css manifest file with the registered_manifest_files property.
618
+	 *
619
+	 * @param string $namespace     Provided to associate the manifest file with a specific namespace.
620
+	 * @param string $url_base      The url base for the manifest file location.
621
+	 * @param string $manifest_file The absolute path to the manifest file.
622
+	 * @param string $manifest_file_path  The path to the folder containing the manifest file. If not provided will be
623
+	 *                                    default to `plugin_root/assets/dist`.
624
+	 * @throws InvalidArgumentException
625
+	 * @throws InvalidFilePathException
626
+	 * @since 4.9.59.p
627
+	 */
628
+	public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '')
629
+	{
630
+		if (isset($this->manifest_data[ $namespace ])) {
631
+			if (! $this->debug()) {
632
+				return;
633
+			}
634
+			throw new InvalidArgumentException(
635
+				sprintf(
636
+					esc_html__(
637
+						'The namespace for this manifest file has already been registered, choose a namespace other than %s',
638
+						'event_espresso'
639
+					),
640
+					$namespace
641
+				)
642
+			);
643
+		}
644
+		if (filter_var($url_base, FILTER_VALIDATE_URL) === false) {
645
+			if (is_admin()) {
646
+				EE_Error::add_error(
647
+					sprintf(
648
+						esc_html__(
649
+							'The url given for %1$s assets is invalid.  The url provided was: "%2$s". This usually happens when another plugin or theme on a site is using the "%3$s" filter or has an invalid url set for the "%4$s" constant',
650
+							'event_espresso'
651
+						),
652
+						'Event Espresso',
653
+						$url_base,
654
+						'plugins_url',
655
+						'WP_PLUGIN_URL'
656
+					),
657
+					__FILE__,
658
+					__FUNCTION__,
659
+					__LINE__
660
+				);
661
+			}
662
+			return;
663
+		}
664
+		$this->manifest_data[ $namespace ] = $this->decodeManifestFile($manifest_file);
665
+		if (! isset($this->manifest_data[ $namespace ]['url_base'])) {
666
+			$this->manifest_data[ $namespace ]['url_base'] = trailingslashit($url_base);
667
+		}
668
+		if (! isset($this->manifest_data[ $namespace ]['path'])) {
669
+			$this->manifest_data[ $namespace ]['path'] = $manifest_file_path;
670
+		}
671
+	}
672
+
673
+
674
+	/**
675
+	 * Decodes json from the provided manifest file.
676
+	 *
677
+	 * @since 4.9.59.p
678
+	 * @param string $manifest_file Path to manifest file.
679
+	 * @return array
680
+	 * @throws InvalidFilePathException
681
+	 */
682
+	private function decodeManifestFile($manifest_file)
683
+	{
684
+		if (! file_exists($manifest_file)) {
685
+			throw new InvalidFilePathException($manifest_file);
686
+		}
687
+		return json_decode(file_get_contents($manifest_file), true);
688
+	}
689
+
690
+
691
+	/**
692
+	 * This is used to set registered script handles that have data.
693
+	 *
694
+	 * @param string $script_handle
695
+	 */
696
+	private function addRegisteredScriptHandlesWithData($script_handle)
697
+	{
698
+		$this->script_handles_with_data[ $script_handle ] = $script_handle;
699
+	}
700
+
701
+
702
+	/**i
703 703
      * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the
704 704
      * Dependency stored in WP_Scripts if its set.
705 705
      */
706
-    private function removeAlreadyRegisteredDataForScriptHandles()
707
-    {
708
-        if (empty($this->script_handles_with_data)) {
709
-            return;
710
-        }
711
-        foreach ($this->script_handles_with_data as $script_handle) {
712
-            $this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
713
-        }
714
-    }
715
-
716
-
717
-    /**
718
-     * Removes any data dependency registered in WP_Scripts if its set.
719
-     *
720
-     * @param string $script_handle
721
-     */
722
-    private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
723
-    {
724
-        if (isset($this->script_handles_with_data[ $script_handle ])) {
725
-            global $wp_scripts;
726
-            $unset_handle = false;
727
-            if ($wp_scripts->get_data($script_handle, 'data')) {
728
-                unset($wp_scripts->registered[ $script_handle ]->extra['data']);
729
-                $unset_handle = true;
730
-            }
731
-            //deal with inline_scripts
732
-            if ($wp_scripts->get_data($script_handle, 'before')) {
733
-                unset($wp_scripts->registered[ $script_handle ]->extra['before']);
734
-                $unset_handle = true;
735
-            }
736
-            if ($wp_scripts->get_data($script_handle, 'after')) {
737
-                unset($wp_scripts->registered[ $script_handle ]->extra['after']);
738
-            }
739
-            if ($unset_handle) {
740
-                unset($this->script_handles_with_data[ $script_handle ]);
741
-            }
742
-        }
743
-    }
744
-
745
-
746
-    /**
747
-     * register translations for a registered script
748
-     *
749
-     * @param string $handle
750
-     */
751
-    public function registerTranslation($handle)
752
-    {
753
-        $this->i18n_registry->registerScriptI18n($handle);
754
-    }
755
-
756
-
757
-    /**
758
-     * @since 4.9.63.p
759
-     * @return bool
760
-     */
761
-    private function debug()
762
-    {
763
-        return apply_filters(
764
-            'FHEE__EventEspresso_core_services_assets_Registry__debug',
765
-            defined('EE_DEBUG') && EE_DEBUG
766
-        );
767
-    }
706
+	private function removeAlreadyRegisteredDataForScriptHandles()
707
+	{
708
+		if (empty($this->script_handles_with_data)) {
709
+			return;
710
+		}
711
+		foreach ($this->script_handles_with_data as $script_handle) {
712
+			$this->removeAlreadyRegisteredDataForScriptHandle($script_handle);
713
+		}
714
+	}
715
+
716
+
717
+	/**
718
+	 * Removes any data dependency registered in WP_Scripts if its set.
719
+	 *
720
+	 * @param string $script_handle
721
+	 */
722
+	private function removeAlreadyRegisteredDataForScriptHandle($script_handle)
723
+	{
724
+		if (isset($this->script_handles_with_data[ $script_handle ])) {
725
+			global $wp_scripts;
726
+			$unset_handle = false;
727
+			if ($wp_scripts->get_data($script_handle, 'data')) {
728
+				unset($wp_scripts->registered[ $script_handle ]->extra['data']);
729
+				$unset_handle = true;
730
+			}
731
+			//deal with inline_scripts
732
+			if ($wp_scripts->get_data($script_handle, 'before')) {
733
+				unset($wp_scripts->registered[ $script_handle ]->extra['before']);
734
+				$unset_handle = true;
735
+			}
736
+			if ($wp_scripts->get_data($script_handle, 'after')) {
737
+				unset($wp_scripts->registered[ $script_handle ]->extra['after']);
738
+			}
739
+			if ($unset_handle) {
740
+				unset($this->script_handles_with_data[ $script_handle ]);
741
+			}
742
+		}
743
+	}
744
+
745
+
746
+	/**
747
+	 * register translations for a registered script
748
+	 *
749
+	 * @param string $handle
750
+	 */
751
+	public function registerTranslation($handle)
752
+	{
753
+		$this->i18n_registry->registerScriptI18n($handle);
754
+	}
755
+
756
+
757
+	/**
758
+	 * @since 4.9.63.p
759
+	 * @return bool
760
+	 */
761
+	private function debug()
762
+	{
763
+		return apply_filters(
764
+			'FHEE__EventEspresso_core_services_assets_Registry__debug',
765
+			defined('EE_DEBUG') && EE_DEBUG
766
+		);
767
+	}
768 768
 }
Please login to merge, or discard this patch.