Completed
Branch FIX/fatal-error-in-ProcessTick... (711b33)
by
unknown
24:40 queued 16:48
created
caffeinated/payment_methods/Paypal_Pro/EEG_Paypal_Pro.gateway.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -450,7 +450,7 @@
 block discarded – undo
450 450
 
451 451
 
452 452
     /**
453
-     * @param $Request
453
+     * @param string $Request
454 454
      * @return mixed
455 455
      */
456 456
     private function _CURLRequest($Request)
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -77,13 +77,13 @@  discard block
 block discarded – undo
77 77
     public function do_direct_payment($payment, $billing_info = null)
78 78
     {
79 79
         $transaction = $payment->transaction();
80
-        if (! $transaction instanceof EEI_Transaction) {
80
+        if ( ! $transaction instanceof EEI_Transaction) {
81 81
             throw new EE_Error(
82 82
                 esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
83 83
             );
84 84
         }
85 85
         $primary_registrant = $transaction->primary_registration();
86
-        if (! $primary_registrant instanceof EEI_Registration) {
86
+        if ( ! $primary_registrant instanceof EEI_Registration) {
87 87
             throw new EE_Error(
88 88
                 esc_html__(
89 89
                     'No primary registration on transaction while paying with PayPal Pro.',
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
             );
93 93
         }
94 94
         $attendee = $primary_registrant->attendee();
95
-        if (! $attendee instanceof EEI_Attendee) {
95
+        if ( ! $attendee instanceof EEI_Attendee) {
96 96
             throw new EE_Error(
97 97
                 esc_html__(
98 98
                     'No attendee on primary registration while paying with PayPal Pro.',
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
             // Required.  Credit card number.  No spaces or punctuation.
190 190
             'acct'           => $billing_info['credit_card'],
191 191
             // Required.  Credit card expiration date.  Format is MMYYYY
192
-            'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
192
+            'expdate'        => $billing_info['exp_month'].$billing_info['exp_year'],
193 193
             // Requirements determined by your PayPal account settings.  Security digits for credit card.
194 194
             'cvv2'           => $billing_info['cvv'],
195 195
         );
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
         $ShippingAddress = array(
242 242
             'shiptoname'     => substr($use_registration_address_info
243 243
                 ? $attendee->full_name()
244
-                : $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
244
+                : $billing_info['first_name'].' '.$billing_info['last_name'], 0, 32),
245 245
             'shiptostreet'   => substr($use_registration_address_info
246 246
                 ? $attendee->address()
247 247
                 : $billing_info['address'], 0, 100),
@@ -270,7 +270,7 @@  discard block
 block discarded – undo
270 270
             'currencycode' => $payment->currency_code(),
271 271
             // Required if you include itemized cart details. (L_AMTn, etc.)
272 272
             // Subtotal of items not including S&H, or tax.
273
-            'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
273
+            'itemamt'      => $gateway_formatter->formatCurrency($item_amount), //
274 274
             // Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
275 275
             'shippingamt'  => '',
276 276
             // Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
@@ -283,10 +283,10 @@  discard block
 block discarded – undo
283 283
             // Free-form field for your own use.  256 char max.
284 284
             'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
285 285
             // Your own invoice or tracking number
286
-            'invnum'       => wp_generate_password(12, false),// $transaction->ID(),
286
+            'invnum'       => wp_generate_password(12, false), // $transaction->ID(),
287 287
             // URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
288 288
             'notifyurl'    => '',
289
-            'buttonsource' => 'EventEspresso_SP',// EE will blow up if you change this
289
+            'buttonsource' => 'EventEspresso_SP', // EE will blow up if you change this
290 290
         );
291 291
         // Wrap all data arrays into a single, "master" array which will be passed into the class function.
292 292
         $PayPalRequestData = array(
@@ -396,52 +396,52 @@  discard block
 block discarded – undo
396 396
         // DP Fields
397 397
         $DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
398 398
         foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
399
-            $DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
399
+            $DPFieldsNVP .= '&'.strtoupper($DPFieldsVar).'='.urlencode($DPFieldsVal);
400 400
         }
401 401
         // CC Details Fields
402 402
         $CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
403 403
         foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
404
-            $CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
404
+            $CCDetailsNVP .= '&'.strtoupper($CCDetailsVar).'='.urlencode($CCDetailsVal);
405 405
         }
406 406
         // PayerInfo Type Fields
407 407
         $PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
408 408
         foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
409
-            $PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
409
+            $PayerInfoNVP .= '&'.strtoupper($PayerInfoVar).'='.urlencode($PayerInfoVal);
410 410
         }
411 411
         // Payer Name Fields
412 412
         $PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
413 413
         foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
414
-            $PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
414
+            $PayerNameNVP .= '&'.strtoupper($PayerNameVar).'='.urlencode($PayerNameVal);
415 415
         }
416 416
         // Address Fields (Billing)
417 417
         $BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
418 418
         foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
419
-            $BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
419
+            $BillingAddressNVP .= '&'.strtoupper($BillingAddressVar).'='.urlencode($BillingAddressVal);
420 420
         }
421 421
         // Payment Details Type Fields
422 422
         $PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
423 423
         foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
424
-            $PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
424
+            $PaymentDetailsNVP .= '&'.strtoupper($PaymentDetailsVar).'='.urlencode($PaymentDetailsVal);
425 425
         }
426 426
         // Payment Details Item Type Fields
427 427
         $OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
428 428
         $n = 0;
429 429
         foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
430
-            $CurrentItem = $OrderItems[ $OrderItemsVar ];
430
+            $CurrentItem = $OrderItems[$OrderItemsVar];
431 431
             foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
432
-                $OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
432
+                $OrderItemsNVP .= '&'.strtoupper($CurrentItemVar).$n.'='.urlencode($CurrentItemVal);
433 433
             }
434 434
             $n++;
435 435
         }
436 436
         // Ship To Address Fields
437 437
         $ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
438 438
         foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
439
-            $ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
439
+            $ShippingAddressNVP .= '&'.strtoupper($ShippingAddressVar).'='.urlencode($ShippingAddressVal);
440 440
         }
441 441
         // 3D Secure Fields
442 442
         $Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
443 443
         foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
444
-            $Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
444
+            $Secure3DNVP .= '&'.strtoupper($Secure3DVar).'='.urlencode($Secure3DVal);
445 445
         }
446 446
         // Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
447 447
         $NVPRequest = 'USER='
@@ -512,7 +512,7 @@  discard block
 block discarded – undo
512 512
             $valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
513 513
             $valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
514 514
             // decoding the response
515
-            $proArray[ $keyval ] = urldecode($valval);
515
+            $proArray[$keyval] = urldecode($valval);
516 516
             $NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
517 517
         }
518 518
         return $proArray;
@@ -545,16 +545,16 @@  discard block
 block discarded – undo
545 545
     {
546 546
         $Errors = array();
547 547
         $n = 0;
548
-        while (isset($DataArray[ 'L_ERRORCODE' . $n . '' ])) {
549
-            $LErrorCode = isset($DataArray[ 'L_ERRORCODE' . $n . '' ]) ? $DataArray[ 'L_ERRORCODE' . $n . '' ] : '';
550
-            $LShortMessage = isset($DataArray[ 'L_SHORTMESSAGE' . $n . '' ])
551
-                ? $DataArray[ 'L_SHORTMESSAGE' . $n . '' ]
548
+        while (isset($DataArray['L_ERRORCODE'.$n.''])) {
549
+            $LErrorCode = isset($DataArray['L_ERRORCODE'.$n.'']) ? $DataArray['L_ERRORCODE'.$n.''] : '';
550
+            $LShortMessage = isset($DataArray['L_SHORTMESSAGE'.$n.''])
551
+                ? $DataArray['L_SHORTMESSAGE'.$n.'']
552 552
                 : '';
553
-            $LLongMessage = isset($DataArray[ 'L_LONGMESSAGE' . $n . '' ])
554
-                ? $DataArray[ 'L_LONGMESSAGE' . $n . '' ]
553
+            $LLongMessage = isset($DataArray['L_LONGMESSAGE'.$n.''])
554
+                ? $DataArray['L_LONGMESSAGE'.$n.'']
555 555
                 : '';
556
-            $LSeverityCode = isset($DataArray[ 'L_SEVERITYCODE' . $n . '' ])
557
-                ? $DataArray[ 'L_SEVERITYCODE' . $n . '' ]
556
+            $LSeverityCode = isset($DataArray['L_SEVERITYCODE'.$n.''])
557
+                ? $DataArray['L_SEVERITYCODE'.$n.'']
558 558
                 : '';
559 559
             $CurrentItem = array(
560 560
                 'L_ERRORCODE'    => $LErrorCode,
@@ -581,7 +581,7 @@  discard block
 block discarded – undo
581 581
     {
582 582
         $error = '';
583 583
         foreach ($Errors as $ErrorVar => $ErrorVal) {
584
-            $CurrentError = $Errors[ $ErrorVar ];
584
+            $CurrentError = $Errors[$ErrorVar];
585 585
             foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
586 586
                 $CurrentVarName = '';
587 587
                 if ($CurrentErrorVar == 'L_ERRORCODE') {
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
                 } elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
594 594
                     $CurrentVarName = 'Severity Code';
595 595
                 }
596
-                $error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
596
+                $error .= '<br />'.$CurrentVarName.': '.$CurrentErrorVal;
597 597
             }
598 598
         }
599 599
         return $error;
Please login to merge, or discard this patch.
Indentation   +602 added lines, -602 removed lines patch added patch discarded remove patch
@@ -11,606 +11,606 @@
 block discarded – undo
11 11
 class EEG_Paypal_Pro extends EE_Onsite_Gateway
12 12
 {
13 13
 
14
-    /**
15
-     * @var $_paypal_api_username string
16
-     */
17
-    protected $_api_username = null;
18
-
19
-    /**
20
-     * @var $_api_password string
21
-     */
22
-    protected $_api_password = null;
23
-
24
-    /**
25
-     * @var $_api_signature string
26
-     */
27
-    protected $_api_signature = null;
28
-
29
-    /**
30
-     * @var $_credit_card_types array with the keys for credit card types accepted on this account
31
-     */
32
-    protected $_credit_card_types    = null;
33
-
34
-    protected $_currencies_supported = array(
35
-        'USD',
36
-        'GBP',
37
-        'CAD',
38
-        'AUD',
39
-        'BRL',
40
-        'CHF',
41
-        'CZK',
42
-        'DKK',
43
-        'EUR',
44
-        'HKD',
45
-        'HUF',
46
-        'ILS',
47
-        'JPY',
48
-        'MXN',
49
-        'MYR',
50
-        'NOK',
51
-        'NZD',
52
-        'PHP',
53
-        'PLN',
54
-        'SEK',
55
-        'SGD',
56
-        'THB',
57
-        'TRY',
58
-        'TWD',
59
-        'RUB',
60
-        'INR',
61
-    );
62
-
63
-
64
-
65
-    /**
66
-     * @param EEI_Payment $payment
67
-     * @param array       $billing_info {
68
-     * @type string $credit_card
69
-     * @type string $credit_card_type
70
-     * @type string $exp_month always 2 characters
71
-     * @type string $exp_year always 4 characters
72
-     * @type string $cvv
73
-     * }
74
-     * @see      parent::do_direct_payment for more info
75
-     * @return EE_Payment|EEI_Payment
76
-     * @throws EE_Error
77
-     */
78
-    public function do_direct_payment($payment, $billing_info = null)
79
-    {
80
-        $transaction = $payment->transaction();
81
-        if (! $transaction instanceof EEI_Transaction) {
82
-            throw new EE_Error(
83
-                esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
84
-            );
85
-        }
86
-        $primary_registrant = $transaction->primary_registration();
87
-        if (! $primary_registrant instanceof EEI_Registration) {
88
-            throw new EE_Error(
89
-                esc_html__(
90
-                    'No primary registration on transaction while paying with PayPal Pro.',
91
-                    'event_espresso'
92
-                )
93
-            );
94
-        }
95
-        $attendee = $primary_registrant->attendee();
96
-        if (! $attendee instanceof EEI_Attendee) {
97
-            throw new EE_Error(
98
-                esc_html__(
99
-                    'No attendee on primary registration while paying with PayPal Pro.',
100
-                    'event_espresso'
101
-                )
102
-            );
103
-        }
104
-        $gateway_formatter = $this->_get_gateway_formatter();
105
-        $order_description = substr($gateway_formatter->formatOrderDescription($payment), 0, 127);
106
-        // charge for the full amount. Show itemized list
107
-        if ($this->_money->compare_floats($payment->amount(), $transaction->total(), '==')) {
108
-            $item_num = 1;
109
-            $total_line_item = $transaction->total_line_item();
110
-            $order_items = array();
111
-            foreach ($total_line_item->get_items() as $line_item) {
112
-                // ignore line items with a quantity of 0
113
-                if ($line_item->quantity() == 0) {
114
-                    continue;
115
-                }
116
-                // For percent items, whose unit_price is 0, use the total instead.
117
-                if ($line_item->is_percent()) {
118
-                    $unit_price = $line_item->total();
119
-                    $line_item_quantity = 1;
120
-                } else {
121
-                    $unit_price = $line_item->unit_price();
122
-                    $line_item_quantity = $line_item->quantity();
123
-                }
124
-                $item = array(
125
-                    // Item Name.  127 char max.
126
-                    'l_name'                 => substr(
127
-                        $gateway_formatter->formatLineItemName($line_item, $payment),
128
-                        0,
129
-                        127
130
-                    ),
131
-                    // Item description.  127 char max.
132
-                    'l_desc'                 => substr(
133
-                        $gateway_formatter->formatLineItemDesc($line_item, $payment),
134
-                        0,
135
-                        127
136
-                    ),
137
-                    // Cost of individual item.
138
-                    'l_amt'                  => $unit_price,
139
-                    // Item Number.  127 char max.
140
-                    'l_number'               => $item_num++,
141
-                    // Item quantity.  Must be any positive integer.
142
-                    'l_qty'                  => $line_item_quantity,
143
-                    // Item's sales tax amount.
144
-                    'l_taxamt'               => '',
145
-                    // eBay auction number of item.
146
-                    'l_ebayitemnumber'       => '',
147
-                    // eBay transaction ID of purchased item.
148
-                    'l_ebayitemauctiontxnid' => '',
149
-                    // eBay order ID for the item.
150
-                    'l_ebayitemorderid'      => '',
151
-                );
152
-                // add to array of all items
153
-                array_push($order_items, $item);
154
-            }
155
-            $item_amount = $total_line_item->get_items_total();
156
-            $tax_amount = $total_line_item->get_total_tax();
157
-        } else {
158
-            $order_items = array();
159
-            $item_amount = $payment->amount();
160
-            $tax_amount = 0;
161
-            array_push($order_items, array(
162
-                // Item Name.  127 char max.
163
-                'l_name'   => substr(
164
-                    $gateway_formatter->formatPartialPaymentLineItemName($payment),
165
-                    0,
166
-                    127
167
-                ),
168
-                // Item description.  127 char max.
169
-                'l_desc'   => substr(
170
-                    $gateway_formatter->formatPartialPaymentLineItemDesc($payment),
171
-                    0,
172
-                    127
173
-                ),
174
-                // Cost of individual item.
175
-                'l_amt'    => $payment->amount(),
176
-                // Item Number.  127 char max.
177
-                'l_number' => 1,
178
-                // Item quantity.  Must be any positive integer.
179
-                'l_qty'    => 1,
180
-            ));
181
-        }
182
-        // Populate data arrays with order data.
183
-        $DPFields = array(
184
-            // How you want to obtain payment ?
185
-            // Authorization indicates the payment is a basic auth subject to settlement with Auth & Capture.
186
-            // Sale indicates that this is a final sale for which you are requesting payment.  Default is Sale.
187
-            'paymentaction'    => 'Sale',
188
-            // Required.  IP address of the payer's browser.
189
-            'ipaddress'        => $_SERVER['REMOTE_ADDR'],
190
-            // Flag to determine whether you want the results returned by FMF.  1 or 0.  Default is 0.
191
-            'returnfmfdetails' => '1',
192
-        );
193
-        $CCDetails = array(
194
-            // Required. Type of credit card.  Visa, MasterCard, Discover, Amex, Maestro, Solo.
195
-            // If Maestro or Solo, the currency code must be GBP.
196
-            //  In addition, either start date or issue number must be specified.
197
-            'creditcardtype' => $billing_info['credit_card_type'],
198
-            // Required.  Credit card number.  No spaces or punctuation.
199
-            'acct'           => $billing_info['credit_card'],
200
-            // Required.  Credit card expiration date.  Format is MMYYYY
201
-            'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
202
-            // Requirements determined by your PayPal account settings.  Security digits for credit card.
203
-            'cvv2'           => $billing_info['cvv'],
204
-        );
205
-        $PayerInfo = array(
206
-            // Email address of payer.
207
-            'email'       => $billing_info['email'],
208
-            // Unique PayPal customer ID for payer.
209
-            'payerid'     => '',
210
-            // Status of payer.  Values are verified or unverified
211
-            'payerstatus' => '',
212
-            // Payer's business name.
213
-            'business'    => '',
214
-        );
215
-        $PayerName = array(
216
-            // Payer's salutation.  20 char max.
217
-            'salutation' => '',
218
-            // Payer's first name.  25 char max.
219
-            'firstname'  => substr($billing_info['first_name'], 0, 25),
220
-            // Payer's middle name.  25 char max.
221
-            'middlename' => '',
222
-            // Payer's last name.  25 char max.
223
-            'lastname'   => substr($billing_info['last_name'], 0, 25),
224
-            // Payer's suffix.  12 char max.
225
-            'suffix'     => '',
226
-        );
227
-        $BillingAddress = array(
228
-            // Required.  First street address.
229
-            'street'      => $billing_info['address'],
230
-            // Second street address.
231
-            'street2'     => $billing_info['address2'],
232
-            // Required.  Name of City.
233
-            'city'        => $billing_info['city'],
234
-            // Required. Name of State or Province.
235
-            'state'       => substr($billing_info['state'], 0, 40),
236
-            // Required.  Country code.
237
-            'countrycode' => $billing_info['country'],
238
-            // Required.  Postal code of payer.
239
-            'zip'         => $billing_info['zip'],
240
-        );
241
-        // check if the registration info contains the needed fields for paypal pro
242
-        // (see https://developer.paypal.com/docs/classic/api/merchant/DoDirectPayment_API_Operation_NVP/)
243
-        if ($attendee->address() && $attendee->city() && $attendee->country_ID()) {
244
-            $use_registration_address_info = true;
245
-        } else {
246
-            $use_registration_address_info = false;
247
-        }
248
-        // so if the attendee has enough data to fill out PayPal Pro's shipping info, use it.
249
-        // If not, use the billing info again
250
-        $ShippingAddress = array(
251
-            'shiptoname'     => substr($use_registration_address_info
252
-                ? $attendee->full_name()
253
-                : $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
254
-            'shiptostreet'   => substr($use_registration_address_info
255
-                ? $attendee->address()
256
-                : $billing_info['address'], 0, 100),
257
-            'shiptostreet2'  => substr($use_registration_address_info
258
-                ? $attendee->address2() : $billing_info['address2'], 0, 100),
259
-            'shiptocity'     => substr($use_registration_address_info
260
-                ? $attendee->city()
261
-                : $billing_info['city'], 0, 40),
262
-            'state'          => substr($use_registration_address_info
263
-                ? $attendee->state_name()
264
-                : $billing_info['state'], 0, 40),
265
-            'shiptocountry'  => $use_registration_address_info
266
-                ? $attendee->country_ID()
267
-                : $billing_info['country'],
268
-            'shiptozip'      => substr($use_registration_address_info
269
-                ? $attendee->zip()
270
-                : $billing_info['zip'], 0, 20),
271
-            'shiptophonenum' => substr($use_registration_address_info
272
-                ? $attendee->phone()
273
-                : $billing_info['phone'], 0, 20),
274
-        );
275
-        $PaymentDetails = array(
276
-            // Required.  Total amount of order, including shipping, handling, and tax.
277
-            'amt'          => $gateway_formatter->formatCurrency($payment->amount()),
278
-            // Required.  Three-letter currency code.  Default is USD.
279
-            'currencycode' => $payment->currency_code(),
280
-            // Required if you include itemized cart details. (L_AMTn, etc.)
281
-            // Subtotal of items not including S&H, or tax.
282
-            'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
283
-            // Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
284
-            'shippingamt'  => '',
285
-            // Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
286
-            'handlingamt'  => '',
287
-            // Required if you specify itemized cart tax details.
288
-            // Sum of tax for all items on the order.  Total sales tax.
289
-            'taxamt'       => $gateway_formatter->formatCurrency($tax_amount),
290
-            // Description of the order the customer is purchasing.  127 char max.
291
-            'desc'         => $order_description,
292
-            // Free-form field for your own use.  256 char max.
293
-            'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
294
-            // Your own invoice or tracking number
295
-            'invnum'       => wp_generate_password(12, false),// $transaction->ID(),
296
-            // URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
297
-            'notifyurl'    => '',
298
-            'buttonsource' => 'EventEspresso_SP',// EE will blow up if you change this
299
-        );
300
-        // Wrap all data arrays into a single, "master" array which will be passed into the class function.
301
-        $PayPalRequestData = array(
302
-            'DPFields'        => $DPFields,
303
-            'CCDetails'       => $CCDetails,
304
-            'PayerInfo'       => $PayerInfo,
305
-            'PayerName'       => $PayerName,
306
-            'BillingAddress'  => $BillingAddress,
307
-            'ShippingAddress' => $ShippingAddress,
308
-            'PaymentDetails'  => $PaymentDetails,
309
-            'OrderItems'      => $order_items,
310
-        );
311
-        $this->_log_clean_request($PayPalRequestData, $payment);
312
-        try {
313
-            $PayPalResult = $this->prep_and_curl_request($PayPalRequestData);
314
-            // remove PCI-sensitive data so it doesn't get stored
315
-            $PayPalResult = $this->_log_clean_response($PayPalResult, $payment);
316
-            if (isset($PayPalResult['L_ERRORCODE0']) && $PayPalResult['L_ERRORCODE0'] === '10002') {
317
-                $message = esc_html__('PayPal did not accept your API username, password, or signature. Please double-check these credentials and if debug mode is on.', 'event_espresso');
318
-            } elseif (isset($PayPalResult['L_LONGMESSAGE0'])) {
319
-                $message = $PayPalResult['L_LONGMESSAGE0'];
320
-            } else {
321
-                $message = $PayPalResult['ACK'];
322
-            }
323
-            if (empty($PayPalResult['RAWRESPONSE'])) {
324
-                $payment->set_status($this->_pay_model->failed_status());
325
-                $payment->set_gateway_response(__('No response received from Paypal Pro', 'event_espresso'));
326
-                $payment->set_details($PayPalResult);
327
-            } else {
328
-                if ($this->_APICallSuccessful($PayPalResult)) {
329
-                    $payment->set_status($this->_pay_model->approved_status());
330
-                } else {
331
-                    $payment->set_status($this->_pay_model->declined_status());
332
-                }
333
-                // make sure we interpret the AMT as a float, not an international string
334
-                // (where periods are thousand separators)
335
-                $payment->set_amount(isset($PayPalResult['AMT']) ? floatval($PayPalResult['AMT']) : 0);
336
-                $payment->set_gateway_response($message);
337
-                $payment->set_txn_id_chq_nmbr(isset($PayPalResult['TRANSACTIONID'])
338
-                    ? $PayPalResult['TRANSACTIONID']
339
-                    : null);
340
-                $primary_registration_code = $primary_registrant instanceof EE_Registration
341
-                    ? $primary_registrant->reg_code()
342
-                    : '';
343
-                $payment->set_extra_accntng($primary_registration_code);
344
-                $payment->set_details($PayPalResult);
345
-            }
346
-        } catch (Exception $e) {
347
-            $payment->set_status($this->_pay_model->failed_status());
348
-            $payment->set_gateway_response($e->getMessage());
349
-        }
350
-        // $payment->set_status( $this->_pay_model->declined_status() );
351
-        // $payment->set_gateway_response( '' );
352
-        return $payment;
353
-    }
354
-
355
-
356
-
357
-    /**
358
-     * CLeans out sensitive CC data and then logs it, and returns the cleaned request
359
-     *
360
-     * @param array       $request
361
-     * @param EEI_Payment $payment
362
-     * @return void
363
-     */
364
-    private function _log_clean_request($request, $payment)
365
-    {
366
-        $cleaned_request_data = $request;
367
-        unset($cleaned_request_data['CCDetails']['acct']);
368
-        unset($cleaned_request_data['CCDetails']['cvv2']);
369
-        unset($cleaned_request_data['CCDetails']['expdate']);
370
-        $this->log(array('Paypal Request' => $cleaned_request_data), $payment);
371
-    }
372
-
373
-
374
-
375
-    /**
376
-     * Cleans the response, logs it, and returns it
377
-     *
378
-     * @param array       $response
379
-     * @param EEI_Payment $payment
380
-     * @return array cleaned
381
-     */
382
-    private function _log_clean_response($response, $payment)
383
-    {
384
-        unset($response['REQUESTDATA']['CREDITCARDTYPE']);
385
-        unset($response['REQUESTDATA']['ACCT']);
386
-        unset($response['REQUESTDATA']['EXPDATE']);
387
-        unset($response['REQUESTDATA']['CVV2']);
388
-        unset($response['RAWREQUEST']);
389
-        $this->log(array('Paypal Response' => $response), $payment);
390
-        return $response;
391
-    }
392
-
393
-
394
-
395
-    /**
396
-     * @param $DataArray
397
-     * @return array
398
-     */
399
-    private function prep_and_curl_request($DataArray)
400
-    {
401
-        // Create empty holders for each portion of the NVP string
402
-        $DPFieldsNVP = '&METHOD=DoDirectPayment&BUTTONSOURCE=AngellEYE_PHP_Class_DDP';
403
-        $CCDetailsNVP = '';
404
-        $PayerInfoNVP = '';
405
-        $PayerNameNVP = '';
406
-        $BillingAddressNVP = '';
407
-        $ShippingAddressNVP = '';
408
-        $PaymentDetailsNVP = '';
409
-        $OrderItemsNVP = '';
410
-        $Secure3DNVP = '';
411
-        // DP Fields
412
-        $DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
413
-        foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
414
-            $DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
415
-        }
416
-        // CC Details Fields
417
-        $CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
418
-        foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
419
-            $CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
420
-        }
421
-        // PayerInfo Type Fields
422
-        $PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
423
-        foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
424
-            $PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
425
-        }
426
-        // Payer Name Fields
427
-        $PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
428
-        foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
429
-            $PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
430
-        }
431
-        // Address Fields (Billing)
432
-        $BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
433
-        foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
434
-            $BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
435
-        }
436
-        // Payment Details Type Fields
437
-        $PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
438
-        foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
439
-            $PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
440
-        }
441
-        // Payment Details Item Type Fields
442
-        $OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
443
-        $n = 0;
444
-        foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
445
-            $CurrentItem = $OrderItems[ $OrderItemsVar ];
446
-            foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
447
-                $OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
448
-            }
449
-            $n++;
450
-        }
451
-        // Ship To Address Fields
452
-        $ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
453
-        foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
454
-            $ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
455
-        }
456
-        // 3D Secure Fields
457
-        $Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
458
-        foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
459
-            $Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
460
-        }
461
-        // Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
462
-        $NVPRequest = 'USER='
463
-                      . $this->_api_username
464
-                      . '&PWD='
465
-                      . $this->_api_password
466
-                      . '&VERSION=64.0'
467
-                      . '&SIGNATURE='
468
-                      . $this->_api_signature
469
-                      . $DPFieldsNVP
470
-                      . $CCDetailsNVP
471
-                      . $PayerInfoNVP
472
-                      . $PayerNameNVP
473
-                      . $BillingAddressNVP
474
-                      . $PaymentDetailsNVP
475
-                      . $OrderItemsNVP
476
-                      . $ShippingAddressNVP
477
-                      . $Secure3DNVP;
478
-        $NVPResponse = $this->_CURLRequest($NVPRequest);
479
-        $NVPRequestArray = $this->_NVPToArray($NVPRequest);
480
-        $NVPResponseArray = $this->_NVPToArray($NVPResponse);
481
-        $Errors = $this->_GetErrors($NVPResponseArray);
482
-        $NVPResponseArray['ERRORS'] = $Errors;
483
-        $NVPResponseArray['REQUESTDATA'] = $NVPRequestArray;
484
-        $NVPResponseArray['RAWREQUEST'] = $NVPRequest;
485
-        $NVPResponseArray['RAWRESPONSE'] = $NVPResponse;
486
-        return $NVPResponseArray;
487
-    }
488
-
489
-
490
-
491
-    /**
492
-     * @param $Request
493
-     * @return mixed
494
-     */
495
-    private function _CURLRequest($Request)
496
-    {
497
-        $EndPointURL = $this->_debug_mode ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
498
-        $curl = curl_init();
499
-        curl_setopt($curl, CURLOPT_VERBOSE, apply_filters('FHEE__EEG_Paypal_Pro__CurlRequest__CURLOPT_VERBOSE', true));
500
-        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
501
-        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
502
-        curl_setopt($curl, CURLOPT_URL, $EndPointURL);
503
-        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
504
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
505
-        curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
506
-        // execute the curl POST
507
-        $Response = curl_exec($curl);
508
-        curl_close($curl);
509
-        return $Response;
510
-    }
511
-
512
-
513
-
514
-    /**
515
-     * @param $NVPString
516
-     * @return array
517
-     */
518
-    private function _NVPToArray($NVPString)
519
-    {
520
-        // prepare responses into array
521
-        $proArray = array();
522
-        while (strlen($NVPString)) {
523
-            // name
524
-            $keypos = strpos($NVPString, '=');
525
-            $keyval = substr($NVPString, 0, $keypos);
526
-            // value
527
-            $valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
528
-            $valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
529
-            // decoding the response
530
-            $proArray[ $keyval ] = urldecode($valval);
531
-            $NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
532
-        }
533
-        return $proArray;
534
-    }
535
-
536
-
537
-
538
-    /**
539
-     * @param array $PayPalResult
540
-     * @return bool
541
-     */
542
-    private function _APICallSuccessful($PayPalResult)
543
-    {
544
-        $approved = false;
545
-        // check main response message from PayPal
546
-        if (isset($PayPalResult['ACK']) && ! empty($PayPalResult['ACK'])) {
547
-            $ack = strtoupper($PayPalResult['ACK']);
548
-            $approved = ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING' || $ack == 'PARTIALSUCCESS') ? true : false;
549
-        }
550
-        return $approved;
551
-    }
552
-
553
-
554
-
555
-    /**
556
-     * @param $DataArray
557
-     * @return array
558
-     */
559
-    private function _GetErrors($DataArray)
560
-    {
561
-        $Errors = array();
562
-        $n = 0;
563
-        while (isset($DataArray[ 'L_ERRORCODE' . $n . '' ])) {
564
-            $LErrorCode = isset($DataArray[ 'L_ERRORCODE' . $n . '' ]) ? $DataArray[ 'L_ERRORCODE' . $n . '' ] : '';
565
-            $LShortMessage = isset($DataArray[ 'L_SHORTMESSAGE' . $n . '' ])
566
-                ? $DataArray[ 'L_SHORTMESSAGE' . $n . '' ]
567
-                : '';
568
-            $LLongMessage = isset($DataArray[ 'L_LONGMESSAGE' . $n . '' ])
569
-                ? $DataArray[ 'L_LONGMESSAGE' . $n . '' ]
570
-                : '';
571
-            $LSeverityCode = isset($DataArray[ 'L_SEVERITYCODE' . $n . '' ])
572
-                ? $DataArray[ 'L_SEVERITYCODE' . $n . '' ]
573
-                : '';
574
-            $CurrentItem = array(
575
-                'L_ERRORCODE'    => $LErrorCode,
576
-                'L_SHORTMESSAGE' => $LShortMessage,
577
-                'L_LONGMESSAGE'  => $LLongMessage,
578
-                'L_SEVERITYCODE' => $LSeverityCode,
579
-            );
580
-            array_push($Errors, $CurrentItem);
581
-            $n++;
582
-        }
583
-        return $Errors;
584
-    }
585
-
586
-
587
-
588
-    /**
589
-     *        nothing to see here...  move along....
590
-     *
591
-     * @access protected
592
-     * @param $Errors
593
-     * @return string
594
-     */
595
-    private function _DisplayErrors($Errors)
596
-    {
597
-        $error = '';
598
-        foreach ($Errors as $ErrorVar => $ErrorVal) {
599
-            $CurrentError = $Errors[ $ErrorVar ];
600
-            foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
601
-                $CurrentVarName = '';
602
-                if ($CurrentErrorVar == 'L_ERRORCODE') {
603
-                    $CurrentVarName = 'Error Code';
604
-                } elseif ($CurrentErrorVar == 'L_SHORTMESSAGE') {
605
-                    $CurrentVarName = 'Short Message';
606
-                } elseif ($CurrentErrorVar == 'L_LONGMESSAGE') {
607
-                    $CurrentVarName = 'Long Message';
608
-                } elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
609
-                    $CurrentVarName = 'Severity Code';
610
-                }
611
-                $error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
612
-            }
613
-        }
614
-        return $error;
615
-    }
14
+	/**
15
+	 * @var $_paypal_api_username string
16
+	 */
17
+	protected $_api_username = null;
18
+
19
+	/**
20
+	 * @var $_api_password string
21
+	 */
22
+	protected $_api_password = null;
23
+
24
+	/**
25
+	 * @var $_api_signature string
26
+	 */
27
+	protected $_api_signature = null;
28
+
29
+	/**
30
+	 * @var $_credit_card_types array with the keys for credit card types accepted on this account
31
+	 */
32
+	protected $_credit_card_types    = null;
33
+
34
+	protected $_currencies_supported = array(
35
+		'USD',
36
+		'GBP',
37
+		'CAD',
38
+		'AUD',
39
+		'BRL',
40
+		'CHF',
41
+		'CZK',
42
+		'DKK',
43
+		'EUR',
44
+		'HKD',
45
+		'HUF',
46
+		'ILS',
47
+		'JPY',
48
+		'MXN',
49
+		'MYR',
50
+		'NOK',
51
+		'NZD',
52
+		'PHP',
53
+		'PLN',
54
+		'SEK',
55
+		'SGD',
56
+		'THB',
57
+		'TRY',
58
+		'TWD',
59
+		'RUB',
60
+		'INR',
61
+	);
62
+
63
+
64
+
65
+	/**
66
+	 * @param EEI_Payment $payment
67
+	 * @param array       $billing_info {
68
+	 * @type string $credit_card
69
+	 * @type string $credit_card_type
70
+	 * @type string $exp_month always 2 characters
71
+	 * @type string $exp_year always 4 characters
72
+	 * @type string $cvv
73
+	 * }
74
+	 * @see      parent::do_direct_payment for more info
75
+	 * @return EE_Payment|EEI_Payment
76
+	 * @throws EE_Error
77
+	 */
78
+	public function do_direct_payment($payment, $billing_info = null)
79
+	{
80
+		$transaction = $payment->transaction();
81
+		if (! $transaction instanceof EEI_Transaction) {
82
+			throw new EE_Error(
83
+				esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
84
+			);
85
+		}
86
+		$primary_registrant = $transaction->primary_registration();
87
+		if (! $primary_registrant instanceof EEI_Registration) {
88
+			throw new EE_Error(
89
+				esc_html__(
90
+					'No primary registration on transaction while paying with PayPal Pro.',
91
+					'event_espresso'
92
+				)
93
+			);
94
+		}
95
+		$attendee = $primary_registrant->attendee();
96
+		if (! $attendee instanceof EEI_Attendee) {
97
+			throw new EE_Error(
98
+				esc_html__(
99
+					'No attendee on primary registration while paying with PayPal Pro.',
100
+					'event_espresso'
101
+				)
102
+			);
103
+		}
104
+		$gateway_formatter = $this->_get_gateway_formatter();
105
+		$order_description = substr($gateway_formatter->formatOrderDescription($payment), 0, 127);
106
+		// charge for the full amount. Show itemized list
107
+		if ($this->_money->compare_floats($payment->amount(), $transaction->total(), '==')) {
108
+			$item_num = 1;
109
+			$total_line_item = $transaction->total_line_item();
110
+			$order_items = array();
111
+			foreach ($total_line_item->get_items() as $line_item) {
112
+				// ignore line items with a quantity of 0
113
+				if ($line_item->quantity() == 0) {
114
+					continue;
115
+				}
116
+				// For percent items, whose unit_price is 0, use the total instead.
117
+				if ($line_item->is_percent()) {
118
+					$unit_price = $line_item->total();
119
+					$line_item_quantity = 1;
120
+				} else {
121
+					$unit_price = $line_item->unit_price();
122
+					$line_item_quantity = $line_item->quantity();
123
+				}
124
+				$item = array(
125
+					// Item Name.  127 char max.
126
+					'l_name'                 => substr(
127
+						$gateway_formatter->formatLineItemName($line_item, $payment),
128
+						0,
129
+						127
130
+					),
131
+					// Item description.  127 char max.
132
+					'l_desc'                 => substr(
133
+						$gateway_formatter->formatLineItemDesc($line_item, $payment),
134
+						0,
135
+						127
136
+					),
137
+					// Cost of individual item.
138
+					'l_amt'                  => $unit_price,
139
+					// Item Number.  127 char max.
140
+					'l_number'               => $item_num++,
141
+					// Item quantity.  Must be any positive integer.
142
+					'l_qty'                  => $line_item_quantity,
143
+					// Item's sales tax amount.
144
+					'l_taxamt'               => '',
145
+					// eBay auction number of item.
146
+					'l_ebayitemnumber'       => '',
147
+					// eBay transaction ID of purchased item.
148
+					'l_ebayitemauctiontxnid' => '',
149
+					// eBay order ID for the item.
150
+					'l_ebayitemorderid'      => '',
151
+				);
152
+				// add to array of all items
153
+				array_push($order_items, $item);
154
+			}
155
+			$item_amount = $total_line_item->get_items_total();
156
+			$tax_amount = $total_line_item->get_total_tax();
157
+		} else {
158
+			$order_items = array();
159
+			$item_amount = $payment->amount();
160
+			$tax_amount = 0;
161
+			array_push($order_items, array(
162
+				// Item Name.  127 char max.
163
+				'l_name'   => substr(
164
+					$gateway_formatter->formatPartialPaymentLineItemName($payment),
165
+					0,
166
+					127
167
+				),
168
+				// Item description.  127 char max.
169
+				'l_desc'   => substr(
170
+					$gateway_formatter->formatPartialPaymentLineItemDesc($payment),
171
+					0,
172
+					127
173
+				),
174
+				// Cost of individual item.
175
+				'l_amt'    => $payment->amount(),
176
+				// Item Number.  127 char max.
177
+				'l_number' => 1,
178
+				// Item quantity.  Must be any positive integer.
179
+				'l_qty'    => 1,
180
+			));
181
+		}
182
+		// Populate data arrays with order data.
183
+		$DPFields = array(
184
+			// How you want to obtain payment ?
185
+			// Authorization indicates the payment is a basic auth subject to settlement with Auth & Capture.
186
+			// Sale indicates that this is a final sale for which you are requesting payment.  Default is Sale.
187
+			'paymentaction'    => 'Sale',
188
+			// Required.  IP address of the payer's browser.
189
+			'ipaddress'        => $_SERVER['REMOTE_ADDR'],
190
+			// Flag to determine whether you want the results returned by FMF.  1 or 0.  Default is 0.
191
+			'returnfmfdetails' => '1',
192
+		);
193
+		$CCDetails = array(
194
+			// Required. Type of credit card.  Visa, MasterCard, Discover, Amex, Maestro, Solo.
195
+			// If Maestro or Solo, the currency code must be GBP.
196
+			//  In addition, either start date or issue number must be specified.
197
+			'creditcardtype' => $billing_info['credit_card_type'],
198
+			// Required.  Credit card number.  No spaces or punctuation.
199
+			'acct'           => $billing_info['credit_card'],
200
+			// Required.  Credit card expiration date.  Format is MMYYYY
201
+			'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
202
+			// Requirements determined by your PayPal account settings.  Security digits for credit card.
203
+			'cvv2'           => $billing_info['cvv'],
204
+		);
205
+		$PayerInfo = array(
206
+			// Email address of payer.
207
+			'email'       => $billing_info['email'],
208
+			// Unique PayPal customer ID for payer.
209
+			'payerid'     => '',
210
+			// Status of payer.  Values are verified or unverified
211
+			'payerstatus' => '',
212
+			// Payer's business name.
213
+			'business'    => '',
214
+		);
215
+		$PayerName = array(
216
+			// Payer's salutation.  20 char max.
217
+			'salutation' => '',
218
+			// Payer's first name.  25 char max.
219
+			'firstname'  => substr($billing_info['first_name'], 0, 25),
220
+			// Payer's middle name.  25 char max.
221
+			'middlename' => '',
222
+			// Payer's last name.  25 char max.
223
+			'lastname'   => substr($billing_info['last_name'], 0, 25),
224
+			// Payer's suffix.  12 char max.
225
+			'suffix'     => '',
226
+		);
227
+		$BillingAddress = array(
228
+			// Required.  First street address.
229
+			'street'      => $billing_info['address'],
230
+			// Second street address.
231
+			'street2'     => $billing_info['address2'],
232
+			// Required.  Name of City.
233
+			'city'        => $billing_info['city'],
234
+			// Required. Name of State or Province.
235
+			'state'       => substr($billing_info['state'], 0, 40),
236
+			// Required.  Country code.
237
+			'countrycode' => $billing_info['country'],
238
+			// Required.  Postal code of payer.
239
+			'zip'         => $billing_info['zip'],
240
+		);
241
+		// check if the registration info contains the needed fields for paypal pro
242
+		// (see https://developer.paypal.com/docs/classic/api/merchant/DoDirectPayment_API_Operation_NVP/)
243
+		if ($attendee->address() && $attendee->city() && $attendee->country_ID()) {
244
+			$use_registration_address_info = true;
245
+		} else {
246
+			$use_registration_address_info = false;
247
+		}
248
+		// so if the attendee has enough data to fill out PayPal Pro's shipping info, use it.
249
+		// If not, use the billing info again
250
+		$ShippingAddress = array(
251
+			'shiptoname'     => substr($use_registration_address_info
252
+				? $attendee->full_name()
253
+				: $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
254
+			'shiptostreet'   => substr($use_registration_address_info
255
+				? $attendee->address()
256
+				: $billing_info['address'], 0, 100),
257
+			'shiptostreet2'  => substr($use_registration_address_info
258
+				? $attendee->address2() : $billing_info['address2'], 0, 100),
259
+			'shiptocity'     => substr($use_registration_address_info
260
+				? $attendee->city()
261
+				: $billing_info['city'], 0, 40),
262
+			'state'          => substr($use_registration_address_info
263
+				? $attendee->state_name()
264
+				: $billing_info['state'], 0, 40),
265
+			'shiptocountry'  => $use_registration_address_info
266
+				? $attendee->country_ID()
267
+				: $billing_info['country'],
268
+			'shiptozip'      => substr($use_registration_address_info
269
+				? $attendee->zip()
270
+				: $billing_info['zip'], 0, 20),
271
+			'shiptophonenum' => substr($use_registration_address_info
272
+				? $attendee->phone()
273
+				: $billing_info['phone'], 0, 20),
274
+		);
275
+		$PaymentDetails = array(
276
+			// Required.  Total amount of order, including shipping, handling, and tax.
277
+			'amt'          => $gateway_formatter->formatCurrency($payment->amount()),
278
+			// Required.  Three-letter currency code.  Default is USD.
279
+			'currencycode' => $payment->currency_code(),
280
+			// Required if you include itemized cart details. (L_AMTn, etc.)
281
+			// Subtotal of items not including S&H, or tax.
282
+			'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
283
+			// Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
284
+			'shippingamt'  => '',
285
+			// Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
286
+			'handlingamt'  => '',
287
+			// Required if you specify itemized cart tax details.
288
+			// Sum of tax for all items on the order.  Total sales tax.
289
+			'taxamt'       => $gateway_formatter->formatCurrency($tax_amount),
290
+			// Description of the order the customer is purchasing.  127 char max.
291
+			'desc'         => $order_description,
292
+			// Free-form field for your own use.  256 char max.
293
+			'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
294
+			// Your own invoice or tracking number
295
+			'invnum'       => wp_generate_password(12, false),// $transaction->ID(),
296
+			// URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
297
+			'notifyurl'    => '',
298
+			'buttonsource' => 'EventEspresso_SP',// EE will blow up if you change this
299
+		);
300
+		// Wrap all data arrays into a single, "master" array which will be passed into the class function.
301
+		$PayPalRequestData = array(
302
+			'DPFields'        => $DPFields,
303
+			'CCDetails'       => $CCDetails,
304
+			'PayerInfo'       => $PayerInfo,
305
+			'PayerName'       => $PayerName,
306
+			'BillingAddress'  => $BillingAddress,
307
+			'ShippingAddress' => $ShippingAddress,
308
+			'PaymentDetails'  => $PaymentDetails,
309
+			'OrderItems'      => $order_items,
310
+		);
311
+		$this->_log_clean_request($PayPalRequestData, $payment);
312
+		try {
313
+			$PayPalResult = $this->prep_and_curl_request($PayPalRequestData);
314
+			// remove PCI-sensitive data so it doesn't get stored
315
+			$PayPalResult = $this->_log_clean_response($PayPalResult, $payment);
316
+			if (isset($PayPalResult['L_ERRORCODE0']) && $PayPalResult['L_ERRORCODE0'] === '10002') {
317
+				$message = esc_html__('PayPal did not accept your API username, password, or signature. Please double-check these credentials and if debug mode is on.', 'event_espresso');
318
+			} elseif (isset($PayPalResult['L_LONGMESSAGE0'])) {
319
+				$message = $PayPalResult['L_LONGMESSAGE0'];
320
+			} else {
321
+				$message = $PayPalResult['ACK'];
322
+			}
323
+			if (empty($PayPalResult['RAWRESPONSE'])) {
324
+				$payment->set_status($this->_pay_model->failed_status());
325
+				$payment->set_gateway_response(__('No response received from Paypal Pro', 'event_espresso'));
326
+				$payment->set_details($PayPalResult);
327
+			} else {
328
+				if ($this->_APICallSuccessful($PayPalResult)) {
329
+					$payment->set_status($this->_pay_model->approved_status());
330
+				} else {
331
+					$payment->set_status($this->_pay_model->declined_status());
332
+				}
333
+				// make sure we interpret the AMT as a float, not an international string
334
+				// (where periods are thousand separators)
335
+				$payment->set_amount(isset($PayPalResult['AMT']) ? floatval($PayPalResult['AMT']) : 0);
336
+				$payment->set_gateway_response($message);
337
+				$payment->set_txn_id_chq_nmbr(isset($PayPalResult['TRANSACTIONID'])
338
+					? $PayPalResult['TRANSACTIONID']
339
+					: null);
340
+				$primary_registration_code = $primary_registrant instanceof EE_Registration
341
+					? $primary_registrant->reg_code()
342
+					: '';
343
+				$payment->set_extra_accntng($primary_registration_code);
344
+				$payment->set_details($PayPalResult);
345
+			}
346
+		} catch (Exception $e) {
347
+			$payment->set_status($this->_pay_model->failed_status());
348
+			$payment->set_gateway_response($e->getMessage());
349
+		}
350
+		// $payment->set_status( $this->_pay_model->declined_status() );
351
+		// $payment->set_gateway_response( '' );
352
+		return $payment;
353
+	}
354
+
355
+
356
+
357
+	/**
358
+	 * CLeans out sensitive CC data and then logs it, and returns the cleaned request
359
+	 *
360
+	 * @param array       $request
361
+	 * @param EEI_Payment $payment
362
+	 * @return void
363
+	 */
364
+	private function _log_clean_request($request, $payment)
365
+	{
366
+		$cleaned_request_data = $request;
367
+		unset($cleaned_request_data['CCDetails']['acct']);
368
+		unset($cleaned_request_data['CCDetails']['cvv2']);
369
+		unset($cleaned_request_data['CCDetails']['expdate']);
370
+		$this->log(array('Paypal Request' => $cleaned_request_data), $payment);
371
+	}
372
+
373
+
374
+
375
+	/**
376
+	 * Cleans the response, logs it, and returns it
377
+	 *
378
+	 * @param array       $response
379
+	 * @param EEI_Payment $payment
380
+	 * @return array cleaned
381
+	 */
382
+	private function _log_clean_response($response, $payment)
383
+	{
384
+		unset($response['REQUESTDATA']['CREDITCARDTYPE']);
385
+		unset($response['REQUESTDATA']['ACCT']);
386
+		unset($response['REQUESTDATA']['EXPDATE']);
387
+		unset($response['REQUESTDATA']['CVV2']);
388
+		unset($response['RAWREQUEST']);
389
+		$this->log(array('Paypal Response' => $response), $payment);
390
+		return $response;
391
+	}
392
+
393
+
394
+
395
+	/**
396
+	 * @param $DataArray
397
+	 * @return array
398
+	 */
399
+	private function prep_and_curl_request($DataArray)
400
+	{
401
+		// Create empty holders for each portion of the NVP string
402
+		$DPFieldsNVP = '&METHOD=DoDirectPayment&BUTTONSOURCE=AngellEYE_PHP_Class_DDP';
403
+		$CCDetailsNVP = '';
404
+		$PayerInfoNVP = '';
405
+		$PayerNameNVP = '';
406
+		$BillingAddressNVP = '';
407
+		$ShippingAddressNVP = '';
408
+		$PaymentDetailsNVP = '';
409
+		$OrderItemsNVP = '';
410
+		$Secure3DNVP = '';
411
+		// DP Fields
412
+		$DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
413
+		foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
414
+			$DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
415
+		}
416
+		// CC Details Fields
417
+		$CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
418
+		foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
419
+			$CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
420
+		}
421
+		// PayerInfo Type Fields
422
+		$PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
423
+		foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
424
+			$PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
425
+		}
426
+		// Payer Name Fields
427
+		$PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
428
+		foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
429
+			$PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
430
+		}
431
+		// Address Fields (Billing)
432
+		$BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
433
+		foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
434
+			$BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
435
+		}
436
+		// Payment Details Type Fields
437
+		$PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
438
+		foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
439
+			$PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
440
+		}
441
+		// Payment Details Item Type Fields
442
+		$OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
443
+		$n = 0;
444
+		foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
445
+			$CurrentItem = $OrderItems[ $OrderItemsVar ];
446
+			foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
447
+				$OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
448
+			}
449
+			$n++;
450
+		}
451
+		// Ship To Address Fields
452
+		$ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
453
+		foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
454
+			$ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
455
+		}
456
+		// 3D Secure Fields
457
+		$Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
458
+		foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
459
+			$Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
460
+		}
461
+		// Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
462
+		$NVPRequest = 'USER='
463
+					  . $this->_api_username
464
+					  . '&PWD='
465
+					  . $this->_api_password
466
+					  . '&VERSION=64.0'
467
+					  . '&SIGNATURE='
468
+					  . $this->_api_signature
469
+					  . $DPFieldsNVP
470
+					  . $CCDetailsNVP
471
+					  . $PayerInfoNVP
472
+					  . $PayerNameNVP
473
+					  . $BillingAddressNVP
474
+					  . $PaymentDetailsNVP
475
+					  . $OrderItemsNVP
476
+					  . $ShippingAddressNVP
477
+					  . $Secure3DNVP;
478
+		$NVPResponse = $this->_CURLRequest($NVPRequest);
479
+		$NVPRequestArray = $this->_NVPToArray($NVPRequest);
480
+		$NVPResponseArray = $this->_NVPToArray($NVPResponse);
481
+		$Errors = $this->_GetErrors($NVPResponseArray);
482
+		$NVPResponseArray['ERRORS'] = $Errors;
483
+		$NVPResponseArray['REQUESTDATA'] = $NVPRequestArray;
484
+		$NVPResponseArray['RAWREQUEST'] = $NVPRequest;
485
+		$NVPResponseArray['RAWRESPONSE'] = $NVPResponse;
486
+		return $NVPResponseArray;
487
+	}
488
+
489
+
490
+
491
+	/**
492
+	 * @param $Request
493
+	 * @return mixed
494
+	 */
495
+	private function _CURLRequest($Request)
496
+	{
497
+		$EndPointURL = $this->_debug_mode ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
498
+		$curl = curl_init();
499
+		curl_setopt($curl, CURLOPT_VERBOSE, apply_filters('FHEE__EEG_Paypal_Pro__CurlRequest__CURLOPT_VERBOSE', true));
500
+		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
501
+		curl_setopt($curl, CURLOPT_TIMEOUT, 60);
502
+		curl_setopt($curl, CURLOPT_URL, $EndPointURL);
503
+		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
504
+		curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
505
+		curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
506
+		// execute the curl POST
507
+		$Response = curl_exec($curl);
508
+		curl_close($curl);
509
+		return $Response;
510
+	}
511
+
512
+
513
+
514
+	/**
515
+	 * @param $NVPString
516
+	 * @return array
517
+	 */
518
+	private function _NVPToArray($NVPString)
519
+	{
520
+		// prepare responses into array
521
+		$proArray = array();
522
+		while (strlen($NVPString)) {
523
+			// name
524
+			$keypos = strpos($NVPString, '=');
525
+			$keyval = substr($NVPString, 0, $keypos);
526
+			// value
527
+			$valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
528
+			$valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
529
+			// decoding the response
530
+			$proArray[ $keyval ] = urldecode($valval);
531
+			$NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
532
+		}
533
+		return $proArray;
534
+	}
535
+
536
+
537
+
538
+	/**
539
+	 * @param array $PayPalResult
540
+	 * @return bool
541
+	 */
542
+	private function _APICallSuccessful($PayPalResult)
543
+	{
544
+		$approved = false;
545
+		// check main response message from PayPal
546
+		if (isset($PayPalResult['ACK']) && ! empty($PayPalResult['ACK'])) {
547
+			$ack = strtoupper($PayPalResult['ACK']);
548
+			$approved = ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING' || $ack == 'PARTIALSUCCESS') ? true : false;
549
+		}
550
+		return $approved;
551
+	}
552
+
553
+
554
+
555
+	/**
556
+	 * @param $DataArray
557
+	 * @return array
558
+	 */
559
+	private function _GetErrors($DataArray)
560
+	{
561
+		$Errors = array();
562
+		$n = 0;
563
+		while (isset($DataArray[ 'L_ERRORCODE' . $n . '' ])) {
564
+			$LErrorCode = isset($DataArray[ 'L_ERRORCODE' . $n . '' ]) ? $DataArray[ 'L_ERRORCODE' . $n . '' ] : '';
565
+			$LShortMessage = isset($DataArray[ 'L_SHORTMESSAGE' . $n . '' ])
566
+				? $DataArray[ 'L_SHORTMESSAGE' . $n . '' ]
567
+				: '';
568
+			$LLongMessage = isset($DataArray[ 'L_LONGMESSAGE' . $n . '' ])
569
+				? $DataArray[ 'L_LONGMESSAGE' . $n . '' ]
570
+				: '';
571
+			$LSeverityCode = isset($DataArray[ 'L_SEVERITYCODE' . $n . '' ])
572
+				? $DataArray[ 'L_SEVERITYCODE' . $n . '' ]
573
+				: '';
574
+			$CurrentItem = array(
575
+				'L_ERRORCODE'    => $LErrorCode,
576
+				'L_SHORTMESSAGE' => $LShortMessage,
577
+				'L_LONGMESSAGE'  => $LLongMessage,
578
+				'L_SEVERITYCODE' => $LSeverityCode,
579
+			);
580
+			array_push($Errors, $CurrentItem);
581
+			$n++;
582
+		}
583
+		return $Errors;
584
+	}
585
+
586
+
587
+
588
+	/**
589
+	 *        nothing to see here...  move along....
590
+	 *
591
+	 * @access protected
592
+	 * @param $Errors
593
+	 * @return string
594
+	 */
595
+	private function _DisplayErrors($Errors)
596
+	{
597
+		$error = '';
598
+		foreach ($Errors as $ErrorVar => $ErrorVal) {
599
+			$CurrentError = $Errors[ $ErrorVar ];
600
+			foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
601
+				$CurrentVarName = '';
602
+				if ($CurrentErrorVar == 'L_ERRORCODE') {
603
+					$CurrentVarName = 'Error Code';
604
+				} elseif ($CurrentErrorVar == 'L_SHORTMESSAGE') {
605
+					$CurrentVarName = 'Short Message';
606
+				} elseif ($CurrentErrorVar == 'L_LONGMESSAGE') {
607
+					$CurrentVarName = 'Long Message';
608
+				} elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
609
+					$CurrentVarName = 'Severity Code';
610
+				}
611
+				$error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
612
+			}
613
+		}
614
+		return $error;
615
+	}
616 616
 }
Please login to merge, or discard this patch.
core/EE_Error.core.php 3 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -73,7 +73,7 @@  discard block
 block discarded – undo
73 73
     /**
74 74
      *    error_handler
75 75
      *
76
-     * @param $code
76
+     * @param integer $code
77 77
      * @param $message
78 78
      * @param $file
79 79
      * @param $line
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
     /**
178 178
      * _format_error
179 179
      *
180
-     * @param $code
180
+     * @param string $code
181 181
      * @param $message
182 182
      * @param $file
183 183
      * @param $line
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
 
211 211
 
212 212
     /**
213
-     * @return void
213
+     * @return string|null
214 214
      * @throws EE_Error
215 215
      * @throws ReflectionException
216 216
      */
Please login to merge, or discard this patch.
Indentation   +1126 added lines, -1126 removed lines patch added patch discarded remove patch
@@ -10,8 +10,8 @@  discard block
 block discarded – undo
10 10
 // if you're a dev and want to receive all errors via email
11 11
 // add this to your wp-config.php: define( 'EE_ERROR_EMAILS', TRUE );
12 12
 if (defined('WP_DEBUG') && WP_DEBUG === true && defined('EE_ERROR_EMAILS') && EE_ERROR_EMAILS === true) {
13
-    set_error_handler(array('EE_Error', 'error_handler'));
14
-    register_shutdown_function(array('EE_Error', 'fatal_error_handler'));
13
+	set_error_handler(array('EE_Error', 'error_handler'));
14
+	register_shutdown_function(array('EE_Error', 'fatal_error_handler'));
15 15
 }
16 16
 
17 17
 
@@ -25,251 +25,251 @@  discard block
 block discarded – undo
25 25
 class EE_Error extends Exception
26 26
 {
27 27
 
28
-    const OPTIONS_KEY_NOTICES = 'ee_notices';
29
-
30
-
31
-    /**
32
-     * name of the file to log exceptions to
33
-     *
34
-     * @var string
35
-     */
36
-    private static $_exception_log_file = 'espresso_error_log.txt';
37
-
38
-    /**
39
-     *    stores details for all exception
40
-     *
41
-     * @var array
42
-     */
43
-    private static $_all_exceptions = array();
44
-
45
-    /**
46
-     *    tracks number of errors
47
-     *
48
-     * @var int
49
-     */
50
-    private static $_error_count = 0;
51
-
52
-    /**
53
-     * @var array $_espresso_notices
54
-     */
55
-    private static $_espresso_notices = array('success' => false, 'errors' => false, 'attention' => false);
56
-
57
-
58
-    /**
59
-     * @override default exception handling
60
-     * @param string         $message
61
-     * @param int            $code
62
-     * @param Exception|null $previous
63
-     */
64
-    public function __construct($message, $code = 0, Exception $previous = null)
65
-    {
66
-        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
67
-            parent::__construct($message, $code);
68
-        } else {
69
-            parent::__construct($message, $code, $previous);
70
-        }
71
-    }
72
-
73
-
74
-    /**
75
-     *    error_handler
76
-     *
77
-     * @param $code
78
-     * @param $message
79
-     * @param $file
80
-     * @param $line
81
-     * @return void
82
-     */
83
-    public static function error_handler($code, $message, $file, $line)
84
-    {
85
-        $type = EE_Error::error_type($code);
86
-        $site = site_url();
87
-        switch ($site) {
88
-            case 'http://ee4.eventespresso.com/':
89
-            case 'http://ee4decaf.eventespresso.com/':
90
-            case 'http://ee4hf.eventespresso.com/':
91
-            case 'http://ee4a.eventespresso.com/':
92
-            case 'http://ee4ad.eventespresso.com/':
93
-            case 'http://ee4b.eventespresso.com/':
94
-            case 'http://ee4bd.eventespresso.com/':
95
-            case 'http://ee4d.eventespresso.com/':
96
-            case 'http://ee4dd.eventespresso.com/':
97
-                $to = '[email protected]';
98
-                break;
99
-            default:
100
-                $to = get_option('admin_email');
101
-        }
102
-        $subject = $type . ' ' . $message . ' in ' . EVENT_ESPRESSO_VERSION . ' on ' . site_url();
103
-        $msg = EE_Error::_format_error($type, $message, $file, $line);
104
-        if (function_exists('wp_mail')) {
105
-            add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type'));
106
-            wp_mail($to, $subject, $msg);
107
-        }
108
-        echo '<div id="message" class="espresso-notices error"><p>';
109
-        echo $type . ': ' . $message . '<br />' . $file . ' line ' . $line;
110
-        echo '<br /></p></div>';
111
-    }
112
-
113
-
114
-    /**
115
-     * error_type
116
-     * http://www.php.net/manual/en/errorfunc.constants.php#109430
117
-     *
118
-     * @param $code
119
-     * @return string
120
-     */
121
-    public static function error_type($code)
122
-    {
123
-        switch ($code) {
124
-            case E_ERROR: // 1 //
125
-                return 'E_ERROR';
126
-            case E_WARNING: // 2 //
127
-                return 'E_WARNING';
128
-            case E_PARSE: // 4 //
129
-                return 'E_PARSE';
130
-            case E_NOTICE: // 8 //
131
-                return 'E_NOTICE';
132
-            case E_CORE_ERROR: // 16 //
133
-                return 'E_CORE_ERROR';
134
-            case E_CORE_WARNING: // 32 //
135
-                return 'E_CORE_WARNING';
136
-            case E_COMPILE_ERROR: // 64 //
137
-                return 'E_COMPILE_ERROR';
138
-            case E_COMPILE_WARNING: // 128 //
139
-                return 'E_COMPILE_WARNING';
140
-            case E_USER_ERROR: // 256 //
141
-                return 'E_USER_ERROR';
142
-            case E_USER_WARNING: // 512 //
143
-                return 'E_USER_WARNING';
144
-            case E_USER_NOTICE: // 1024 //
145
-                return 'E_USER_NOTICE';
146
-            case E_STRICT: // 2048 //
147
-                return 'E_STRICT';
148
-            case E_RECOVERABLE_ERROR: // 4096 //
149
-                return 'E_RECOVERABLE_ERROR';
150
-            case E_DEPRECATED: // 8192 //
151
-                return 'E_DEPRECATED';
152
-            case E_USER_DEPRECATED: // 16384 //
153
-                return 'E_USER_DEPRECATED';
154
-            case E_ALL: // 16384 //
155
-                return 'E_ALL';
156
-        }
157
-        return '';
158
-    }
159
-
160
-
161
-    /**
162
-     *    fatal_error_handler
163
-     *
164
-     * @return void
165
-     */
166
-    public static function fatal_error_handler()
167
-    {
168
-        $last_error = error_get_last();
169
-        if ($last_error['type'] === E_ERROR) {
170
-            EE_Error::error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
171
-        }
172
-    }
173
-
174
-
175
-    /**
176
-     * _format_error
177
-     *
178
-     * @param $code
179
-     * @param $message
180
-     * @param $file
181
-     * @param $line
182
-     * @return string
183
-     */
184
-    private static function _format_error($code, $message, $file, $line)
185
-    {
186
-        $html = "<table cellpadding='5'><thead bgcolor='#f8f8f8'><th>Item</th><th align='left'>Details</th></thead><tbody>";
187
-        $html .= "<tr valign='top'><td><b>Code</b></td><td>$code</td></tr>";
188
-        $html .= "<tr valign='top'><td><b>Error</b></td><td>$message</td></tr>";
189
-        $html .= "<tr valign='top'><td><b>File</b></td><td>$file</td></tr>";
190
-        $html .= "<tr valign='top'><td><b>Line</b></td><td>$line</td></tr>";
191
-        $html .= '</tbody></table>';
192
-        return $html;
193
-    }
194
-
195
-
196
-    /**
197
-     * set_content_type
198
-     *
199
-     * @param $content_type
200
-     * @return string
201
-     */
202
-    public static function set_content_type($content_type)
203
-    {
204
-        return 'text/html';
205
-    }
206
-
207
-
208
-    /**
209
-     * @return void
210
-     * @throws EE_Error
211
-     * @throws ReflectionException
212
-     */
213
-    public function get_error()
214
-    {
215
-        if (apply_filters('FHEE__EE_Error__get_error__show_normal_exceptions', false)) {
216
-            throw $this;
217
-        }
218
-        // get separate user and developer messages if they exist
219
-        $msg = explode('||', $this->getMessage());
220
-        $user_msg = $msg[0];
221
-        $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0];
222
-        $msg = WP_DEBUG ? $dev_msg : $user_msg;
223
-        // add details to _all_exceptions array
224
-        $x_time = time();
225
-        self::$_all_exceptions[ $x_time ]['name'] = get_class($this);
226
-        self::$_all_exceptions[ $x_time ]['file'] = $this->getFile();
227
-        self::$_all_exceptions[ $x_time ]['line'] = $this->getLine();
228
-        self::$_all_exceptions[ $x_time ]['msg'] = $msg;
229
-        self::$_all_exceptions[ $x_time ]['code'] = $this->getCode();
230
-        self::$_all_exceptions[ $x_time ]['trace'] = $this->getTrace();
231
-        self::$_all_exceptions[ $x_time ]['string'] = $this->getTraceAsString();
232
-        self::$_error_count++;
233
-        // add_action( 'shutdown', array( $this, 'display_errors' ));
234
-        $this->display_errors();
235
-    }
236
-
237
-
238
-    /**
239
-     * @param bool   $check_stored
240
-     * @param string $type_to_check
241
-     * @return bool
242
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
243
-     * @throws \InvalidArgumentException
244
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
245
-     * @throws InvalidInterfaceException
246
-     */
247
-    public static function has_error($check_stored = false, $type_to_check = 'errors')
248
-    {
249
-        $has_error = isset(self::$_espresso_notices[ $type_to_check ])
250
-                     && ! empty(self::$_espresso_notices[ $type_to_check ])
251
-            ? true
252
-            : false;
253
-        if ($check_stored && ! $has_error) {
254
-            $notices = EE_Error::getStoredNotices();
255
-            foreach ($notices as $type => $notice) {
256
-                if ($type === $type_to_check && $notice) {
257
-                    return true;
258
-                }
259
-            }
260
-        }
261
-        return $has_error;
262
-    }
263
-
264
-
265
-    /**
266
-     * @echo string
267
-     * @throws \ReflectionException
268
-     */
269
-    public function display_errors()
270
-    {
271
-        $trace_details = '';
272
-        $output = '
28
+	const OPTIONS_KEY_NOTICES = 'ee_notices';
29
+
30
+
31
+	/**
32
+	 * name of the file to log exceptions to
33
+	 *
34
+	 * @var string
35
+	 */
36
+	private static $_exception_log_file = 'espresso_error_log.txt';
37
+
38
+	/**
39
+	 *    stores details for all exception
40
+	 *
41
+	 * @var array
42
+	 */
43
+	private static $_all_exceptions = array();
44
+
45
+	/**
46
+	 *    tracks number of errors
47
+	 *
48
+	 * @var int
49
+	 */
50
+	private static $_error_count = 0;
51
+
52
+	/**
53
+	 * @var array $_espresso_notices
54
+	 */
55
+	private static $_espresso_notices = array('success' => false, 'errors' => false, 'attention' => false);
56
+
57
+
58
+	/**
59
+	 * @override default exception handling
60
+	 * @param string         $message
61
+	 * @param int            $code
62
+	 * @param Exception|null $previous
63
+	 */
64
+	public function __construct($message, $code = 0, Exception $previous = null)
65
+	{
66
+		if (version_compare(PHP_VERSION, '5.3.0', '<')) {
67
+			parent::__construct($message, $code);
68
+		} else {
69
+			parent::__construct($message, $code, $previous);
70
+		}
71
+	}
72
+
73
+
74
+	/**
75
+	 *    error_handler
76
+	 *
77
+	 * @param $code
78
+	 * @param $message
79
+	 * @param $file
80
+	 * @param $line
81
+	 * @return void
82
+	 */
83
+	public static function error_handler($code, $message, $file, $line)
84
+	{
85
+		$type = EE_Error::error_type($code);
86
+		$site = site_url();
87
+		switch ($site) {
88
+			case 'http://ee4.eventespresso.com/':
89
+			case 'http://ee4decaf.eventespresso.com/':
90
+			case 'http://ee4hf.eventespresso.com/':
91
+			case 'http://ee4a.eventespresso.com/':
92
+			case 'http://ee4ad.eventespresso.com/':
93
+			case 'http://ee4b.eventespresso.com/':
94
+			case 'http://ee4bd.eventespresso.com/':
95
+			case 'http://ee4d.eventespresso.com/':
96
+			case 'http://ee4dd.eventespresso.com/':
97
+				$to = '[email protected]';
98
+				break;
99
+			default:
100
+				$to = get_option('admin_email');
101
+		}
102
+		$subject = $type . ' ' . $message . ' in ' . EVENT_ESPRESSO_VERSION . ' on ' . site_url();
103
+		$msg = EE_Error::_format_error($type, $message, $file, $line);
104
+		if (function_exists('wp_mail')) {
105
+			add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type'));
106
+			wp_mail($to, $subject, $msg);
107
+		}
108
+		echo '<div id="message" class="espresso-notices error"><p>';
109
+		echo $type . ': ' . $message . '<br />' . $file . ' line ' . $line;
110
+		echo '<br /></p></div>';
111
+	}
112
+
113
+
114
+	/**
115
+	 * error_type
116
+	 * http://www.php.net/manual/en/errorfunc.constants.php#109430
117
+	 *
118
+	 * @param $code
119
+	 * @return string
120
+	 */
121
+	public static function error_type($code)
122
+	{
123
+		switch ($code) {
124
+			case E_ERROR: // 1 //
125
+				return 'E_ERROR';
126
+			case E_WARNING: // 2 //
127
+				return 'E_WARNING';
128
+			case E_PARSE: // 4 //
129
+				return 'E_PARSE';
130
+			case E_NOTICE: // 8 //
131
+				return 'E_NOTICE';
132
+			case E_CORE_ERROR: // 16 //
133
+				return 'E_CORE_ERROR';
134
+			case E_CORE_WARNING: // 32 //
135
+				return 'E_CORE_WARNING';
136
+			case E_COMPILE_ERROR: // 64 //
137
+				return 'E_COMPILE_ERROR';
138
+			case E_COMPILE_WARNING: // 128 //
139
+				return 'E_COMPILE_WARNING';
140
+			case E_USER_ERROR: // 256 //
141
+				return 'E_USER_ERROR';
142
+			case E_USER_WARNING: // 512 //
143
+				return 'E_USER_WARNING';
144
+			case E_USER_NOTICE: // 1024 //
145
+				return 'E_USER_NOTICE';
146
+			case E_STRICT: // 2048 //
147
+				return 'E_STRICT';
148
+			case E_RECOVERABLE_ERROR: // 4096 //
149
+				return 'E_RECOVERABLE_ERROR';
150
+			case E_DEPRECATED: // 8192 //
151
+				return 'E_DEPRECATED';
152
+			case E_USER_DEPRECATED: // 16384 //
153
+				return 'E_USER_DEPRECATED';
154
+			case E_ALL: // 16384 //
155
+				return 'E_ALL';
156
+		}
157
+		return '';
158
+	}
159
+
160
+
161
+	/**
162
+	 *    fatal_error_handler
163
+	 *
164
+	 * @return void
165
+	 */
166
+	public static function fatal_error_handler()
167
+	{
168
+		$last_error = error_get_last();
169
+		if ($last_error['type'] === E_ERROR) {
170
+			EE_Error::error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
171
+		}
172
+	}
173
+
174
+
175
+	/**
176
+	 * _format_error
177
+	 *
178
+	 * @param $code
179
+	 * @param $message
180
+	 * @param $file
181
+	 * @param $line
182
+	 * @return string
183
+	 */
184
+	private static function _format_error($code, $message, $file, $line)
185
+	{
186
+		$html = "<table cellpadding='5'><thead bgcolor='#f8f8f8'><th>Item</th><th align='left'>Details</th></thead><tbody>";
187
+		$html .= "<tr valign='top'><td><b>Code</b></td><td>$code</td></tr>";
188
+		$html .= "<tr valign='top'><td><b>Error</b></td><td>$message</td></tr>";
189
+		$html .= "<tr valign='top'><td><b>File</b></td><td>$file</td></tr>";
190
+		$html .= "<tr valign='top'><td><b>Line</b></td><td>$line</td></tr>";
191
+		$html .= '</tbody></table>';
192
+		return $html;
193
+	}
194
+
195
+
196
+	/**
197
+	 * set_content_type
198
+	 *
199
+	 * @param $content_type
200
+	 * @return string
201
+	 */
202
+	public static function set_content_type($content_type)
203
+	{
204
+		return 'text/html';
205
+	}
206
+
207
+
208
+	/**
209
+	 * @return void
210
+	 * @throws EE_Error
211
+	 * @throws ReflectionException
212
+	 */
213
+	public function get_error()
214
+	{
215
+		if (apply_filters('FHEE__EE_Error__get_error__show_normal_exceptions', false)) {
216
+			throw $this;
217
+		}
218
+		// get separate user and developer messages if they exist
219
+		$msg = explode('||', $this->getMessage());
220
+		$user_msg = $msg[0];
221
+		$dev_msg = isset($msg[1]) ? $msg[1] : $msg[0];
222
+		$msg = WP_DEBUG ? $dev_msg : $user_msg;
223
+		// add details to _all_exceptions array
224
+		$x_time = time();
225
+		self::$_all_exceptions[ $x_time ]['name'] = get_class($this);
226
+		self::$_all_exceptions[ $x_time ]['file'] = $this->getFile();
227
+		self::$_all_exceptions[ $x_time ]['line'] = $this->getLine();
228
+		self::$_all_exceptions[ $x_time ]['msg'] = $msg;
229
+		self::$_all_exceptions[ $x_time ]['code'] = $this->getCode();
230
+		self::$_all_exceptions[ $x_time ]['trace'] = $this->getTrace();
231
+		self::$_all_exceptions[ $x_time ]['string'] = $this->getTraceAsString();
232
+		self::$_error_count++;
233
+		// add_action( 'shutdown', array( $this, 'display_errors' ));
234
+		$this->display_errors();
235
+	}
236
+
237
+
238
+	/**
239
+	 * @param bool   $check_stored
240
+	 * @param string $type_to_check
241
+	 * @return bool
242
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
243
+	 * @throws \InvalidArgumentException
244
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
245
+	 * @throws InvalidInterfaceException
246
+	 */
247
+	public static function has_error($check_stored = false, $type_to_check = 'errors')
248
+	{
249
+		$has_error = isset(self::$_espresso_notices[ $type_to_check ])
250
+					 && ! empty(self::$_espresso_notices[ $type_to_check ])
251
+			? true
252
+			: false;
253
+		if ($check_stored && ! $has_error) {
254
+			$notices = EE_Error::getStoredNotices();
255
+			foreach ($notices as $type => $notice) {
256
+				if ($type === $type_to_check && $notice) {
257
+					return true;
258
+				}
259
+			}
260
+		}
261
+		return $has_error;
262
+	}
263
+
264
+
265
+	/**
266
+	 * @echo string
267
+	 * @throws \ReflectionException
268
+	 */
269
+	public function display_errors()
270
+	{
271
+		$trace_details = '';
272
+		$output = '
273 273
 <style type="text/css">
274 274
 	#ee-error-message {
275 275
 		max-width:90% !important;
@@ -325,21 +325,21 @@  discard block
 block discarded – undo
325 325
 	}
326 326
 </style>
327 327
 <div id="ee-error-message" class="error">';
328
-        if (! WP_DEBUG) {
329
-            $output .= '
328
+		if (! WP_DEBUG) {
329
+			$output .= '
330 330
 	<p>';
331
-        }
332
-        // cycle thru errors
333
-        foreach (self::$_all_exceptions as $time => $ex) {
334
-            $error_code = '';
335
-            // process trace info
336
-            if (empty($ex['trace'])) {
337
-                $trace_details .= __(
338
-                    'Sorry, but no trace information was available for this exception.',
339
-                    'event_espresso'
340
-                );
341
-            } else {
342
-                $trace_details .= '
331
+		}
332
+		// cycle thru errors
333
+		foreach (self::$_all_exceptions as $time => $ex) {
334
+			$error_code = '';
335
+			// process trace info
336
+			if (empty($ex['trace'])) {
337
+				$trace_details .= __(
338
+					'Sorry, but no trace information was available for this exception.',
339
+					'event_espresso'
340
+				);
341
+			} else {
342
+				$trace_details .= '
343 343
 			<div id="ee-trace-details">
344 344
 			<table width="100%" border="0" cellpadding="5" cellspacing="0">
345 345
 				<tr>
@@ -349,43 +349,43 @@  discard block
 block discarded – undo
349 349
 					<th scope="col" align="left">Class</th>
350 350
 					<th scope="col" align="left">Method( arguments )</th>
351 351
 				</tr>';
352
-                $last_on_stack = count($ex['trace']) - 1;
353
-                // reverse array so that stack is in proper chronological order
354
-                $sorted_trace = array_reverse($ex['trace']);
355
-                foreach ($sorted_trace as $nmbr => $trace) {
356
-                    $file = isset($trace['file']) ? $trace['file'] : '';
357
-                    $class = isset($trace['class']) ? $trace['class'] : '';
358
-                    $type = isset($trace['type']) ? $trace['type'] : '';
359
-                    $function = isset($trace['function']) ? $trace['function'] : '';
360
-                    $args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : '';
361
-                    $line = isset($trace['line']) ? $trace['line'] : '';
362
-                    $zebra = ($nmbr % 2) ? ' odd' : '';
363
-                    if (empty($file) && ! empty($class)) {
364
-                        $a = new ReflectionClass($class);
365
-                        $file = $a->getFileName();
366
-                        if (empty($line) && ! empty($function)) {
367
-                            try {
368
-                                // if $function is a closure, this throws an exception
369
-                                $b = new ReflectionMethod($class, $function);
370
-                                $line = $b->getStartLine();
371
-                            } catch (Exception $closure_exception) {
372
-                                $line = 'unknown';
373
-                            }
374
-                        }
375
-                    }
376
-                    if ($nmbr === $last_on_stack) {
377
-                        $file = $ex['file'] !== '' ? $ex['file'] : $file;
378
-                        $line = $ex['line'] !== '' ? $ex['line'] : $line;
379
-                        $error_code = self::generate_error_code($file, $trace['function'], $line);
380
-                    }
381
-                    $nmbr_dsply = ! empty($nmbr) ? $nmbr : '&nbsp;';
382
-                    $line_dsply = ! empty($line) ? $line : '&nbsp;';
383
-                    $file_dsply = ! empty($file) ? $file : '&nbsp;';
384
-                    $class_dsply = ! empty($class) ? $class : '&nbsp;';
385
-                    $type_dsply = ! empty($type) ? $type : '&nbsp;';
386
-                    $function_dsply = ! empty($function) ? $function : '&nbsp;';
387
-                    $args_dsply = ! empty($args) ? '( ' . $args . ' )' : '';
388
-                    $trace_details .= '
352
+				$last_on_stack = count($ex['trace']) - 1;
353
+				// reverse array so that stack is in proper chronological order
354
+				$sorted_trace = array_reverse($ex['trace']);
355
+				foreach ($sorted_trace as $nmbr => $trace) {
356
+					$file = isset($trace['file']) ? $trace['file'] : '';
357
+					$class = isset($trace['class']) ? $trace['class'] : '';
358
+					$type = isset($trace['type']) ? $trace['type'] : '';
359
+					$function = isset($trace['function']) ? $trace['function'] : '';
360
+					$args = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : '';
361
+					$line = isset($trace['line']) ? $trace['line'] : '';
362
+					$zebra = ($nmbr % 2) ? ' odd' : '';
363
+					if (empty($file) && ! empty($class)) {
364
+						$a = new ReflectionClass($class);
365
+						$file = $a->getFileName();
366
+						if (empty($line) && ! empty($function)) {
367
+							try {
368
+								// if $function is a closure, this throws an exception
369
+								$b = new ReflectionMethod($class, $function);
370
+								$line = $b->getStartLine();
371
+							} catch (Exception $closure_exception) {
372
+								$line = 'unknown';
373
+							}
374
+						}
375
+					}
376
+					if ($nmbr === $last_on_stack) {
377
+						$file = $ex['file'] !== '' ? $ex['file'] : $file;
378
+						$line = $ex['line'] !== '' ? $ex['line'] : $line;
379
+						$error_code = self::generate_error_code($file, $trace['function'], $line);
380
+					}
381
+					$nmbr_dsply = ! empty($nmbr) ? $nmbr : '&nbsp;';
382
+					$line_dsply = ! empty($line) ? $line : '&nbsp;';
383
+					$file_dsply = ! empty($file) ? $file : '&nbsp;';
384
+					$class_dsply = ! empty($class) ? $class : '&nbsp;';
385
+					$type_dsply = ! empty($type) ? $type : '&nbsp;';
386
+					$function_dsply = ! empty($function) ? $function : '&nbsp;';
387
+					$args_dsply = ! empty($args) ? '( ' . $args . ' )' : '';
388
+					$trace_details .= '
389 389
 					<tr>
390 390
 						<td align="right" class="' . $zebra . '">' . $nmbr_dsply . '</td>
391 391
 						<td align="right" class="' . $zebra . '">' . $line_dsply . '</td>
@@ -393,626 +393,626 @@  discard block
 block discarded – undo
393 393
 						<td align="left" class="' . $zebra . '">' . $class_dsply . '</td>
394 394
 						<td align="left" class="' . $zebra . '">' . $type_dsply . $function_dsply . $args_dsply . '</td>
395 395
 					</tr>';
396
-                }
397
-                $trace_details .= '
396
+				}
397
+				$trace_details .= '
398 398
 			 </table>
399 399
 			</div>';
400
-            }
401
-            $ex['code'] = $ex['code'] ? $ex['code'] : $error_code;
402
-            // add generic non-identifying messages for non-privileged users
403
-            if (! WP_DEBUG) {
404
-                $output .= '<span class="ee-error-user-msg-spn">'
405
-                           . trim($ex['msg'])
406
-                           . '</span> &nbsp; <sup>'
407
-                           . $ex['code']
408
-                           . '</sup><br />';
409
-            } else {
410
-                // or helpful developer messages if debugging is on
411
-                $output .= '
400
+			}
401
+			$ex['code'] = $ex['code'] ? $ex['code'] : $error_code;
402
+			// add generic non-identifying messages for non-privileged users
403
+			if (! WP_DEBUG) {
404
+				$output .= '<span class="ee-error-user-msg-spn">'
405
+						   . trim($ex['msg'])
406
+						   . '</span> &nbsp; <sup>'
407
+						   . $ex['code']
408
+						   . '</sup><br />';
409
+			} else {
410
+				// or helpful developer messages if debugging is on
411
+				$output .= '
412 412
 		<div class="ee-error-dev-msg-dv">
413 413
 			<p class="ee-error-dev-msg-pg">
414 414
 				<strong class="ee-error-dev-msg-str">An '
415
-                           . $ex['name']
416
-                           . ' exception was thrown!</strong>  &nbsp; <span>code: '
417
-                           . $ex['code']
418
-                           . '</span><br />
415
+						   . $ex['name']
416
+						   . ' exception was thrown!</strong>  &nbsp; <span>code: '
417
+						   . $ex['code']
418
+						   . '</span><br />
419 419
 				<span class="big-text">"'
420
-                           . trim($ex['msg'])
421
-                           . '"</span><br/>
420
+						   . trim($ex['msg'])
421
+						   . '"</span><br/>
422 422
 				<a id="display-ee-error-trace-'
423
-                           . self::$_error_count
424
-                           . $time
425
-                           . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-'
426
-                           . self::$_error_count
427
-                           . $time
428
-                           . '">
423
+						   . self::$_error_count
424
+						   . $time
425
+						   . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-'
426
+						   . self::$_error_count
427
+						   . $time
428
+						   . '">
429 429
 					'
430
-                           . __('click to view backtrace and class/method details', 'event_espresso')
431
-                           . '
430
+						   . __('click to view backtrace and class/method details', 'event_espresso')
431
+						   . '
432 432
 				</a><br />
433 433
 				<span class="small-text lt-grey-text">'
434
-                           . $ex['file']
435
-                           . ' &nbsp; ( line no: '
436
-                           . $ex['line']
437
-                           . ' )</span>
434
+						   . $ex['file']
435
+						   . ' &nbsp; ( line no: '
436
+						   . $ex['line']
437
+						   . ' )</span>
438 438
 			</p>
439 439
 			<div id="ee-error-trace-'
440
-                           . self::$_error_count
441
-                           . $time
442
-                           . '-dv" class="ee-error-trace-dv" style="display: none;">
440
+						   . self::$_error_count
441
+						   . $time
442
+						   . '-dv" class="ee-error-trace-dv" style="display: none;">
443 443
 				'
444
-                           . $trace_details;
445
-                if (! empty($class)) {
446
-                    $output .= '
444
+						   . $trace_details;
445
+				if (! empty($class)) {
446
+					$output .= '
447 447
 				<div style="padding:3px; margin:0 0 1em; border:1px solid #666; background:#fff; border-radius:3px;">
448 448
 					<div style="padding:1em 2em; border:1px solid #666; background:#f9f9f9;">
449 449
 						<h3>Class Details</h3>';
450
-                    $a = new ReflectionClass($class);
451
-                    $output .= '
450
+					$a = new ReflectionClass($class);
451
+					$output .= '
452 452
 						<pre>' . $a . '</pre>
453 453
 					</div>
454 454
 				</div>';
455
-                }
456
-                $output .= '
455
+				}
456
+				$output .= '
457 457
 			</div>
458 458
 		</div>
459 459
 		<br />';
460
-            }
461
-            $this->write_to_error_log($time, $ex);
462
-        }
463
-        // remove last linebreak
464
-        $output = substr($output, 0, -6);
465
-        if (! WP_DEBUG) {
466
-            $output .= '
460
+			}
461
+			$this->write_to_error_log($time, $ex);
462
+		}
463
+		// remove last linebreak
464
+		$output = substr($output, 0, -6);
465
+		if (! WP_DEBUG) {
466
+			$output .= '
467 467
 	</p>';
468
-        }
469
-        $output .= '
468
+		}
469
+		$output .= '
470 470
 </div>';
471
-        $output .= self::_print_scripts(true);
472
-        if (defined('DOING_AJAX')) {
473
-            echo wp_json_encode(array('error' => $output));
474
-            exit();
475
-        }
476
-        echo $output;
477
-        die();
478
-    }
479
-
480
-
481
-    /**
482
-     *    generate string from exception trace args
483
-     *
484
-     * @param array $arguments
485
-     * @param bool  $array
486
-     * @return string
487
-     */
488
-    private function _convert_args_to_string($arguments = array(), $array = false)
489
-    {
490
-        $arg_string = '';
491
-        if (! empty($arguments)) {
492
-            $args = array();
493
-            foreach ($arguments as $arg) {
494
-                if (! empty($arg)) {
495
-                    if (is_string($arg)) {
496
-                        $args[] = " '" . $arg . "'";
497
-                    } elseif (is_array($arg)) {
498
-                        $args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true);
499
-                    } elseif ($arg === null) {
500
-                        $args[] = ' NULL';
501
-                    } elseif (is_bool($arg)) {
502
-                        $args[] = ($arg) ? ' TRUE' : ' FALSE';
503
-                    } elseif (is_object($arg)) {
504
-                        $args[] = ' OBJECT ' . get_class($arg);
505
-                    } elseif (is_resource($arg)) {
506
-                        $args[] = get_resource_type($arg);
507
-                    } else {
508
-                        $args[] = $arg;
509
-                    }
510
-                }
511
-            }
512
-            $arg_string = implode(', ', $args);
513
-        }
514
-        if ($array) {
515
-            $arg_string .= ' )';
516
-        }
517
-        return $arg_string;
518
-    }
519
-
520
-
521
-    /**
522
-     *    add error message
523
-     *
524
-     * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
525
-     *                            separate messages for user || dev
526
-     * @param        string $file the file that the error occurred in - just use __FILE__
527
-     * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
528
-     * @param        string $line the line number where the error occurred - just use __LINE__
529
-     * @return        void
530
-     */
531
-    public static function add_error($msg = null, $file = null, $func = null, $line = null)
532
-    {
533
-        self::_add_notice('errors', $msg, $file, $func, $line);
534
-        self::$_error_count++;
535
-    }
536
-
537
-
538
-    /**
539
-     * If WP_DEBUG is active, throws an exception. If WP_DEBUG is off, just
540
-     * adds an error
541
-     *
542
-     * @param string $msg
543
-     * @param string $file
544
-     * @param string $func
545
-     * @param string $line
546
-     * @throws EE_Error
547
-     */
548
-    public static function throw_exception_if_debugging($msg = null, $file = null, $func = null, $line = null)
549
-    {
550
-        if (WP_DEBUG) {
551
-            throw new EE_Error($msg);
552
-        }
553
-        EE_Error::add_error($msg, $file, $func, $line);
554
-    }
555
-
556
-
557
-    /**
558
-     *    add success message
559
-     *
560
-     * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
561
-     *                            separate messages for user || dev
562
-     * @param        string $file the file that the error occurred in - just use __FILE__
563
-     * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
564
-     * @param        string $line the line number where the error occurred - just use __LINE__
565
-     * @return        void
566
-     */
567
-    public static function add_success($msg = null, $file = null, $func = null, $line = null)
568
-    {
569
-        self::_add_notice('success', $msg, $file, $func, $line);
570
-    }
571
-
572
-
573
-    /**
574
-     *    add attention message
575
-     *
576
-     * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
577
-     *                            separate messages for user || dev
578
-     * @param        string $file the file that the error occurred in - just use __FILE__
579
-     * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
580
-     * @param        string $line the line number where the error occurred - just use __LINE__
581
-     * @return        void
582
-     */
583
-    public static function add_attention($msg = null, $file = null, $func = null, $line = null)
584
-    {
585
-        self::_add_notice('attention', $msg, $file, $func, $line);
586
-    }
587
-
588
-
589
-    /**
590
-     * @param string $type whether the message is for a success or error notification
591
-     * @param string $msg  the message to display to users or developers
592
-     *                     - adding a double pipe || (OR) creates separate messages for user || dev
593
-     * @param string $file the file that the error occurred in - just use __FILE__
594
-     * @param string $func the function/method that the error occurred in - just use __FUNCTION__
595
-     * @param string $line the line number where the error occurred - just use __LINE__
596
-     * @return void
597
-     */
598
-    private static function _add_notice($type = 'success', $msg = '', $file = '', $func = '', $line = '')
599
-    {
600
-        if (empty($msg)) {
601
-            EE_Error::doing_it_wrong(
602
-                'EE_Error::add_' . $type . '()',
603
-                sprintf(
604
-                    __(
605
-                        'Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d',
606
-                        'event_espresso'
607
-                    ),
608
-                    $type,
609
-                    $file,
610
-                    $line
611
-                ),
612
-                EVENT_ESPRESSO_VERSION
613
-            );
614
-        }
615
-        if ($type === 'errors' && (empty($file) || empty($func) || empty($line))) {
616
-            EE_Error::doing_it_wrong(
617
-                'EE_Error::add_error()',
618
-                __(
619
-                    'You need to provide the file name, function name, and line number that the error occurred on in order to better assist with debugging.',
620
-                    'event_espresso'
621
-                ),
622
-                EVENT_ESPRESSO_VERSION
623
-            );
624
-        }
625
-        // get separate user and developer messages if they exist
626
-        $msg = explode('||', $msg);
627
-        $user_msg = $msg[0];
628
-        $dev_msg = isset($msg[1]) ? $msg[1] : $msg[0];
629
-        /**
630
-         * Do an action so other code can be triggered when a notice is created
631
-         *
632
-         * @param string $type     can be 'errors', 'attention', or 'success'
633
-         * @param string $user_msg message displayed to user when WP_DEBUG is off
634
-         * @param string $user_msg message displayed to user when WP_DEBUG is on
635
-         * @param string $file     file where error was generated
636
-         * @param string $func     function where error was generated
637
-         * @param string $line     line where error was generated
638
-         */
639
-        do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line);
640
-        $msg = WP_DEBUG ? $dev_msg : $user_msg;
641
-        // add notice if message exists
642
-        if (! empty($msg)) {
643
-            // get error code
644
-            $notice_code = EE_Error::generate_error_code($file, $func, $line);
645
-            if (WP_DEBUG && $type === 'errors') {
646
-                $msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>';
647
-            }
648
-            // add notice. Index by code if it's not blank
649
-            if ($notice_code) {
650
-                self::$_espresso_notices[ $type ][ $notice_code ] = $msg;
651
-            } else {
652
-                self::$_espresso_notices[ $type ][] = $msg;
653
-            }
654
-            add_action('wp_footer', array('EE_Error', 'enqueue_error_scripts'), 1);
655
-        }
656
-    }
657
-
658
-
659
-    /**
660
-     * in some case it may be necessary to overwrite the existing success messages
661
-     *
662
-     * @return        void
663
-     */
664
-    public static function overwrite_success()
665
-    {
666
-        self::$_espresso_notices['success'] = false;
667
-    }
668
-
669
-
670
-    /**
671
-     * in some case it may be necessary to overwrite the existing attention messages
672
-     *
673
-     * @return void
674
-     */
675
-    public static function overwrite_attention()
676
-    {
677
-        self::$_espresso_notices['attention'] = false;
678
-    }
679
-
680
-
681
-    /**
682
-     * in some case it may be necessary to overwrite the existing error messages
683
-     *
684
-     * @return void
685
-     */
686
-    public static function overwrite_errors()
687
-    {
688
-        self::$_espresso_notices['errors'] = false;
689
-    }
690
-
691
-
692
-    /**
693
-     * @return void
694
-     */
695
-    public static function reset_notices()
696
-    {
697
-        self::$_espresso_notices['success'] = false;
698
-        self::$_espresso_notices['attention'] = false;
699
-        self::$_espresso_notices['errors'] = false;
700
-    }
701
-
702
-
703
-    /**
704
-     * @return int
705
-     */
706
-    public static function has_notices()
707
-    {
708
-        $has_notices = 0;
709
-        // check for success messages
710
-        $has_notices = self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])
711
-            ? 3
712
-            : $has_notices;
713
-        // check for attention messages
714
-        $has_notices = self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])
715
-            ? 2
716
-            : $has_notices;
717
-        // check for error messages
718
-        $has_notices = self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])
719
-            ? 1
720
-            : $has_notices;
721
-        return $has_notices;
722
-    }
723
-
724
-
725
-    /**
726
-     * This simply returns non formatted error notices as they were sent into the EE_Error object.
727
-     *
728
-     * @since 4.9.0
729
-     * @return array
730
-     */
731
-    public static function get_vanilla_notices()
732
-    {
733
-        return array(
734
-            'success'   => isset(self::$_espresso_notices['success'])
735
-                ? self::$_espresso_notices['success']
736
-                : array(),
737
-            'attention' => isset(self::$_espresso_notices['attention'])
738
-                ? self::$_espresso_notices['attention']
739
-                : array(),
740
-            'errors'    => isset(self::$_espresso_notices['errors'])
741
-                ? self::$_espresso_notices['errors']
742
-                : array(),
743
-        );
744
-    }
745
-
746
-
747
-    /**
748
-     * @return array
749
-     * @throws InvalidArgumentException
750
-     * @throws InvalidDataTypeException
751
-     * @throws InvalidInterfaceException
752
-     */
753
-    public static function getStoredNotices()
754
-    {
755
-        if ($user_id = get_current_user_id()) {
756
-            // get notices for logged in user
757
-            $notices = get_user_option(EE_Error::OPTIONS_KEY_NOTICES, $user_id);
758
-            return is_array($notices) ? $notices : array();
759
-        }
760
-        if (EE_Session::isLoadedAndActive()) {
761
-            // get notices for user currently engaged in a session
762
-            $session_data = EE_Session::instance()->get_session_data(EE_Error::OPTIONS_KEY_NOTICES);
763
-            return is_array($session_data) ? $session_data : array();
764
-        }
765
-        // get global notices and hope they apply to the current site visitor
766
-        $notices = get_option(EE_Error::OPTIONS_KEY_NOTICES, array());
767
-        return is_array($notices) ? $notices : array();
768
-    }
769
-
770
-
771
-    /**
772
-     * @param array $notices
773
-     * @return bool
774
-     * @throws InvalidArgumentException
775
-     * @throws InvalidDataTypeException
776
-     * @throws InvalidInterfaceException
777
-     */
778
-    public static function storeNotices(array $notices)
779
-    {
780
-        if ($user_id = get_current_user_id()) {
781
-            // store notices for logged in user
782
-            return (bool) update_user_option(
783
-                $user_id,
784
-                EE_Error::OPTIONS_KEY_NOTICES,
785
-                $notices
786
-            );
787
-        }
788
-        if (EE_Session::isLoadedAndActive()) {
789
-            // store notices for user currently engaged in a session
790
-            return EE_Session::instance()->set_session_data(
791
-                array(EE_Error::OPTIONS_KEY_NOTICES => $notices)
792
-            );
793
-        }
794
-        // store global notices and hope they apply to the same site visitor on the next request
795
-        return update_option(EE_Error::OPTIONS_KEY_NOTICES, $notices);
796
-    }
797
-
798
-
799
-    /**
800
-     * @return bool|TRUE
801
-     * @throws InvalidArgumentException
802
-     * @throws InvalidDataTypeException
803
-     * @throws InvalidInterfaceException
804
-     */
805
-    public static function clearNotices()
806
-    {
807
-        if ($user_id = get_current_user_id()) {
808
-            // clear notices for logged in user
809
-            return (bool) update_user_option(
810
-                $user_id,
811
-                EE_Error::OPTIONS_KEY_NOTICES,
812
-                array()
813
-            );
814
-        }
815
-        if (EE_Session::isLoadedAndActive()) {
816
-            // clear notices for user currently engaged in a session
817
-            return EE_Session::instance()->reset_data(EE_Error::OPTIONS_KEY_NOTICES);
818
-        }
819
-        // clear global notices and hope none belonged to some for some other site visitor
820
-        return update_option(EE_Error::OPTIONS_KEY_NOTICES, array());
821
-    }
822
-
823
-
824
-    /**
825
-     * saves notices to the db for retrieval on next request
826
-     *
827
-     * @return void
828
-     * @throws InvalidArgumentException
829
-     * @throws InvalidDataTypeException
830
-     * @throws InvalidInterfaceException
831
-     */
832
-    public static function stashNoticesBeforeRedirect()
833
-    {
834
-        EE_Error::get_notices(false, true);
835
-    }
836
-
837
-
838
-    /**
839
-     * compile all error or success messages into one string
840
-     *
841
-     * @see EE_Error::get_raw_notices if you want the raw notices without any preparations made to them
842
-     * @param boolean $format_output            whether or not to format the messages for display in the WP admin
843
-     * @param boolean $save_to_transient        whether or not to save notices to the db for retrieval on next request
844
-     *                                          - ONLY do this just before redirecting
845
-     * @param boolean $remove_empty             whether or not to unset empty messages
846
-     * @return array
847
-     * @throws InvalidArgumentException
848
-     * @throws InvalidDataTypeException
849
-     * @throws InvalidInterfaceException
850
-     */
851
-    public static function get_notices($format_output = true, $save_to_transient = false, $remove_empty = true)
852
-    {
853
-        $success_messages = '';
854
-        $attention_messages = '';
855
-        $error_messages = '';
856
-        // either save notices to the db
857
-        if ($save_to_transient || isset($_REQUEST['activate-selected'])) {
858
-            self::$_espresso_notices = array_merge(
859
-                EE_Error::getStoredNotices(),
860
-                self::$_espresso_notices
861
-            );
862
-            EE_Error::storeNotices(self::$_espresso_notices);
863
-            return array();
864
-        }
865
-        $print_scripts = EE_Error::combineExistingAndNewNotices();
866
-        // check for success messages
867
-        if (self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])) {
868
-            // combine messages
869
-            $success_messages .= implode(self::$_espresso_notices['success'], '<br />');
870
-            $print_scripts = true;
871
-        }
872
-        // check for attention messages
873
-        if (self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])) {
874
-            // combine messages
875
-            $attention_messages .= implode(self::$_espresso_notices['attention'], '<br />');
876
-            $print_scripts = true;
877
-        }
878
-        // check for error messages
879
-        if (self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])) {
880
-            $error_messages .= count(self::$_espresso_notices['errors']) > 1
881
-                ? __('The following errors have occurred:<br />', 'event_espresso')
882
-                : __('An error has occurred:<br />', 'event_espresso');
883
-            // combine messages
884
-            $error_messages .= implode(self::$_espresso_notices['errors'], '<br />');
885
-            $print_scripts = true;
886
-        }
887
-        if ($format_output) {
888
-            $notices = EE_Error::formatNoticesOutput(
889
-                $success_messages,
890
-                $attention_messages,
891
-                $error_messages
892
-            );
893
-        } else {
894
-            $notices = array(
895
-                'success'   => $success_messages,
896
-                'attention' => $attention_messages,
897
-                'errors'    => $error_messages,
898
-            );
899
-            if ($remove_empty) {
900
-                // remove empty notices
901
-                foreach ($notices as $type => $notice) {
902
-                    if (empty($notice)) {
903
-                        unset($notices[ $type ]);
904
-                    }
905
-                }
906
-            }
907
-        }
908
-        if ($print_scripts) {
909
-            self::_print_scripts();
910
-        }
911
-        return $notices;
912
-    }
913
-
914
-
915
-    /**
916
-     * @return bool
917
-     * @throws InvalidArgumentException
918
-     * @throws InvalidDataTypeException
919
-     * @throws InvalidInterfaceException
920
-     */
921
-    private static function combineExistingAndNewNotices()
922
-    {
923
-        $print_scripts = false;
924
-        // grab any notices that have been previously saved
925
-        $notices = EE_Error::getStoredNotices();
926
-        if (! empty($notices)) {
927
-            foreach ($notices as $type => $notice) {
928
-                if (is_array($notice) && ! empty($notice)) {
929
-                    // make sure that existing notice type is an array
930
-                    self::$_espresso_notices[ $type ] = is_array(self::$_espresso_notices[ $type ])
931
-                                                        && ! empty(self::$_espresso_notices[ $type ])
932
-                        ? self::$_espresso_notices[ $type ]
933
-                        : array();
934
-                    // add newly created notices to existing ones
935
-                    self::$_espresso_notices[ $type ] += $notice;
936
-                    $print_scripts = true;
937
-                }
938
-            }
939
-            // now clear any stored notices
940
-            EE_Error::clearNotices();
941
-        }
942
-        return $print_scripts;
943
-    }
944
-
945
-
946
-    /**
947
-     * @param string $success_messages
948
-     * @param string $attention_messages
949
-     * @param string $error_messages
950
-     * @return string
951
-     */
952
-    private static function formatNoticesOutput($success_messages, $attention_messages, $error_messages)
953
-    {
954
-        $notices = '<div id="espresso-notices">';
955
-        $close = is_admin()
956
-            ? ''
957
-            : '<a class="close-espresso-notice hide-if-no-js"><span class="dashicons dashicons-no"/></a>';
958
-        if ($success_messages !== '') {
959
-            $css_id = is_admin() ? 'ee-success-message' : 'espresso-notices-success';
960
-            $css_class = is_admin() ? 'updated fade' : 'success fade-away';
961
-            // showMessage( $success_messages );
962
-            $notices .= '<div id="' . $css_id . '" '
963
-                        . 'class="espresso-notices ' . $css_class . '" '
964
-                        . 'style="display:none;">'
965
-                        . '<p>' . $success_messages . '</p>'
966
-                        . $close
967
-                        . '</div>';
968
-        }
969
-        if ($attention_messages !== '') {
970
-            $css_id = is_admin() ? 'ee-attention-message' : 'espresso-notices-attention';
971
-            $css_class = is_admin() ? 'updated ee-notices-attention' : 'attention fade-away';
972
-            // showMessage( $error_messages, TRUE );
973
-            $notices .= '<div id="' . $css_id . '" '
974
-                        . 'class="espresso-notices ' . $css_class . '" '
975
-                        . 'style="display:none;">'
976
-                        . '<p>' . $attention_messages . '</p>'
977
-                        . $close
978
-                        . '</div>';
979
-        }
980
-        if ($error_messages !== '') {
981
-            $css_id = is_admin() ? 'ee-error-message' : 'espresso-notices-error';
982
-            $css_class = is_admin() ? 'error' : 'error fade-away';
983
-            // showMessage( $error_messages, TRUE );
984
-            $notices .= '<div id="' . $css_id . '" '
985
-                        . 'class="espresso-notices ' . $css_class . '" '
986
-                        . 'style="display:none;">'
987
-                        . '<p>' . $error_messages . '</p>'
988
-                        . $close
989
-                        . '</div>';
990
-        }
991
-        $notices .= '</div>';
992
-        return $notices;
993
-    }
994
-
995
-
996
-    /**
997
-     * _print_scripts
998
-     *
999
-     * @param    bool $force_print
1000
-     * @return    string
1001
-     */
1002
-    private static function _print_scripts($force_print = false)
1003
-    {
1004
-        if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
1005
-            if (wp_script_is('ee_error_js', 'registered')) {
1006
-                wp_enqueue_style('espresso_default');
1007
-                wp_enqueue_style('espresso_custom_css');
1008
-                wp_enqueue_script('ee_error_js');
1009
-            }
1010
-            if (wp_script_is('ee_error_js', 'enqueued')) {
1011
-                wp_localize_script('ee_error_js', 'ee_settings', array('wp_debug' => WP_DEBUG));
1012
-                return '';
1013
-            }
1014
-        } else {
1015
-            return '
471
+		$output .= self::_print_scripts(true);
472
+		if (defined('DOING_AJAX')) {
473
+			echo wp_json_encode(array('error' => $output));
474
+			exit();
475
+		}
476
+		echo $output;
477
+		die();
478
+	}
479
+
480
+
481
+	/**
482
+	 *    generate string from exception trace args
483
+	 *
484
+	 * @param array $arguments
485
+	 * @param bool  $array
486
+	 * @return string
487
+	 */
488
+	private function _convert_args_to_string($arguments = array(), $array = false)
489
+	{
490
+		$arg_string = '';
491
+		if (! empty($arguments)) {
492
+			$args = array();
493
+			foreach ($arguments as $arg) {
494
+				if (! empty($arg)) {
495
+					if (is_string($arg)) {
496
+						$args[] = " '" . $arg . "'";
497
+					} elseif (is_array($arg)) {
498
+						$args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true);
499
+					} elseif ($arg === null) {
500
+						$args[] = ' NULL';
501
+					} elseif (is_bool($arg)) {
502
+						$args[] = ($arg) ? ' TRUE' : ' FALSE';
503
+					} elseif (is_object($arg)) {
504
+						$args[] = ' OBJECT ' . get_class($arg);
505
+					} elseif (is_resource($arg)) {
506
+						$args[] = get_resource_type($arg);
507
+					} else {
508
+						$args[] = $arg;
509
+					}
510
+				}
511
+			}
512
+			$arg_string = implode(', ', $args);
513
+		}
514
+		if ($array) {
515
+			$arg_string .= ' )';
516
+		}
517
+		return $arg_string;
518
+	}
519
+
520
+
521
+	/**
522
+	 *    add error message
523
+	 *
524
+	 * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
525
+	 *                            separate messages for user || dev
526
+	 * @param        string $file the file that the error occurred in - just use __FILE__
527
+	 * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
528
+	 * @param        string $line the line number where the error occurred - just use __LINE__
529
+	 * @return        void
530
+	 */
531
+	public static function add_error($msg = null, $file = null, $func = null, $line = null)
532
+	{
533
+		self::_add_notice('errors', $msg, $file, $func, $line);
534
+		self::$_error_count++;
535
+	}
536
+
537
+
538
+	/**
539
+	 * If WP_DEBUG is active, throws an exception. If WP_DEBUG is off, just
540
+	 * adds an error
541
+	 *
542
+	 * @param string $msg
543
+	 * @param string $file
544
+	 * @param string $func
545
+	 * @param string $line
546
+	 * @throws EE_Error
547
+	 */
548
+	public static function throw_exception_if_debugging($msg = null, $file = null, $func = null, $line = null)
549
+	{
550
+		if (WP_DEBUG) {
551
+			throw new EE_Error($msg);
552
+		}
553
+		EE_Error::add_error($msg, $file, $func, $line);
554
+	}
555
+
556
+
557
+	/**
558
+	 *    add success message
559
+	 *
560
+	 * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
561
+	 *                            separate messages for user || dev
562
+	 * @param        string $file the file that the error occurred in - just use __FILE__
563
+	 * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
564
+	 * @param        string $line the line number where the error occurred - just use __LINE__
565
+	 * @return        void
566
+	 */
567
+	public static function add_success($msg = null, $file = null, $func = null, $line = null)
568
+	{
569
+		self::_add_notice('success', $msg, $file, $func, $line);
570
+	}
571
+
572
+
573
+	/**
574
+	 *    add attention message
575
+	 *
576
+	 * @param        string $msg  the message to display to users or developers - adding a double pipe || (OR) creates
577
+	 *                            separate messages for user || dev
578
+	 * @param        string $file the file that the error occurred in - just use __FILE__
579
+	 * @param        string $func the function/method that the error occurred in - just use __FUNCTION__
580
+	 * @param        string $line the line number where the error occurred - just use __LINE__
581
+	 * @return        void
582
+	 */
583
+	public static function add_attention($msg = null, $file = null, $func = null, $line = null)
584
+	{
585
+		self::_add_notice('attention', $msg, $file, $func, $line);
586
+	}
587
+
588
+
589
+	/**
590
+	 * @param string $type whether the message is for a success or error notification
591
+	 * @param string $msg  the message to display to users or developers
592
+	 *                     - adding a double pipe || (OR) creates separate messages for user || dev
593
+	 * @param string $file the file that the error occurred in - just use __FILE__
594
+	 * @param string $func the function/method that the error occurred in - just use __FUNCTION__
595
+	 * @param string $line the line number where the error occurred - just use __LINE__
596
+	 * @return void
597
+	 */
598
+	private static function _add_notice($type = 'success', $msg = '', $file = '', $func = '', $line = '')
599
+	{
600
+		if (empty($msg)) {
601
+			EE_Error::doing_it_wrong(
602
+				'EE_Error::add_' . $type . '()',
603
+				sprintf(
604
+					__(
605
+						'Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d',
606
+						'event_espresso'
607
+					),
608
+					$type,
609
+					$file,
610
+					$line
611
+				),
612
+				EVENT_ESPRESSO_VERSION
613
+			);
614
+		}
615
+		if ($type === 'errors' && (empty($file) || empty($func) || empty($line))) {
616
+			EE_Error::doing_it_wrong(
617
+				'EE_Error::add_error()',
618
+				__(
619
+					'You need to provide the file name, function name, and line number that the error occurred on in order to better assist with debugging.',
620
+					'event_espresso'
621
+				),
622
+				EVENT_ESPRESSO_VERSION
623
+			);
624
+		}
625
+		// get separate user and developer messages if they exist
626
+		$msg = explode('||', $msg);
627
+		$user_msg = $msg[0];
628
+		$dev_msg = isset($msg[1]) ? $msg[1] : $msg[0];
629
+		/**
630
+		 * Do an action so other code can be triggered when a notice is created
631
+		 *
632
+		 * @param string $type     can be 'errors', 'attention', or 'success'
633
+		 * @param string $user_msg message displayed to user when WP_DEBUG is off
634
+		 * @param string $user_msg message displayed to user when WP_DEBUG is on
635
+		 * @param string $file     file where error was generated
636
+		 * @param string $func     function where error was generated
637
+		 * @param string $line     line where error was generated
638
+		 */
639
+		do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line);
640
+		$msg = WP_DEBUG ? $dev_msg : $user_msg;
641
+		// add notice if message exists
642
+		if (! empty($msg)) {
643
+			// get error code
644
+			$notice_code = EE_Error::generate_error_code($file, $func, $line);
645
+			if (WP_DEBUG && $type === 'errors') {
646
+				$msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>';
647
+			}
648
+			// add notice. Index by code if it's not blank
649
+			if ($notice_code) {
650
+				self::$_espresso_notices[ $type ][ $notice_code ] = $msg;
651
+			} else {
652
+				self::$_espresso_notices[ $type ][] = $msg;
653
+			}
654
+			add_action('wp_footer', array('EE_Error', 'enqueue_error_scripts'), 1);
655
+		}
656
+	}
657
+
658
+
659
+	/**
660
+	 * in some case it may be necessary to overwrite the existing success messages
661
+	 *
662
+	 * @return        void
663
+	 */
664
+	public static function overwrite_success()
665
+	{
666
+		self::$_espresso_notices['success'] = false;
667
+	}
668
+
669
+
670
+	/**
671
+	 * in some case it may be necessary to overwrite the existing attention messages
672
+	 *
673
+	 * @return void
674
+	 */
675
+	public static function overwrite_attention()
676
+	{
677
+		self::$_espresso_notices['attention'] = false;
678
+	}
679
+
680
+
681
+	/**
682
+	 * in some case it may be necessary to overwrite the existing error messages
683
+	 *
684
+	 * @return void
685
+	 */
686
+	public static function overwrite_errors()
687
+	{
688
+		self::$_espresso_notices['errors'] = false;
689
+	}
690
+
691
+
692
+	/**
693
+	 * @return void
694
+	 */
695
+	public static function reset_notices()
696
+	{
697
+		self::$_espresso_notices['success'] = false;
698
+		self::$_espresso_notices['attention'] = false;
699
+		self::$_espresso_notices['errors'] = false;
700
+	}
701
+
702
+
703
+	/**
704
+	 * @return int
705
+	 */
706
+	public static function has_notices()
707
+	{
708
+		$has_notices = 0;
709
+		// check for success messages
710
+		$has_notices = self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])
711
+			? 3
712
+			: $has_notices;
713
+		// check for attention messages
714
+		$has_notices = self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])
715
+			? 2
716
+			: $has_notices;
717
+		// check for error messages
718
+		$has_notices = self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])
719
+			? 1
720
+			: $has_notices;
721
+		return $has_notices;
722
+	}
723
+
724
+
725
+	/**
726
+	 * This simply returns non formatted error notices as they were sent into the EE_Error object.
727
+	 *
728
+	 * @since 4.9.0
729
+	 * @return array
730
+	 */
731
+	public static function get_vanilla_notices()
732
+	{
733
+		return array(
734
+			'success'   => isset(self::$_espresso_notices['success'])
735
+				? self::$_espresso_notices['success']
736
+				: array(),
737
+			'attention' => isset(self::$_espresso_notices['attention'])
738
+				? self::$_espresso_notices['attention']
739
+				: array(),
740
+			'errors'    => isset(self::$_espresso_notices['errors'])
741
+				? self::$_espresso_notices['errors']
742
+				: array(),
743
+		);
744
+	}
745
+
746
+
747
+	/**
748
+	 * @return array
749
+	 * @throws InvalidArgumentException
750
+	 * @throws InvalidDataTypeException
751
+	 * @throws InvalidInterfaceException
752
+	 */
753
+	public static function getStoredNotices()
754
+	{
755
+		if ($user_id = get_current_user_id()) {
756
+			// get notices for logged in user
757
+			$notices = get_user_option(EE_Error::OPTIONS_KEY_NOTICES, $user_id);
758
+			return is_array($notices) ? $notices : array();
759
+		}
760
+		if (EE_Session::isLoadedAndActive()) {
761
+			// get notices for user currently engaged in a session
762
+			$session_data = EE_Session::instance()->get_session_data(EE_Error::OPTIONS_KEY_NOTICES);
763
+			return is_array($session_data) ? $session_data : array();
764
+		}
765
+		// get global notices and hope they apply to the current site visitor
766
+		$notices = get_option(EE_Error::OPTIONS_KEY_NOTICES, array());
767
+		return is_array($notices) ? $notices : array();
768
+	}
769
+
770
+
771
+	/**
772
+	 * @param array $notices
773
+	 * @return bool
774
+	 * @throws InvalidArgumentException
775
+	 * @throws InvalidDataTypeException
776
+	 * @throws InvalidInterfaceException
777
+	 */
778
+	public static function storeNotices(array $notices)
779
+	{
780
+		if ($user_id = get_current_user_id()) {
781
+			// store notices for logged in user
782
+			return (bool) update_user_option(
783
+				$user_id,
784
+				EE_Error::OPTIONS_KEY_NOTICES,
785
+				$notices
786
+			);
787
+		}
788
+		if (EE_Session::isLoadedAndActive()) {
789
+			// store notices for user currently engaged in a session
790
+			return EE_Session::instance()->set_session_data(
791
+				array(EE_Error::OPTIONS_KEY_NOTICES => $notices)
792
+			);
793
+		}
794
+		// store global notices and hope they apply to the same site visitor on the next request
795
+		return update_option(EE_Error::OPTIONS_KEY_NOTICES, $notices);
796
+	}
797
+
798
+
799
+	/**
800
+	 * @return bool|TRUE
801
+	 * @throws InvalidArgumentException
802
+	 * @throws InvalidDataTypeException
803
+	 * @throws InvalidInterfaceException
804
+	 */
805
+	public static function clearNotices()
806
+	{
807
+		if ($user_id = get_current_user_id()) {
808
+			// clear notices for logged in user
809
+			return (bool) update_user_option(
810
+				$user_id,
811
+				EE_Error::OPTIONS_KEY_NOTICES,
812
+				array()
813
+			);
814
+		}
815
+		if (EE_Session::isLoadedAndActive()) {
816
+			// clear notices for user currently engaged in a session
817
+			return EE_Session::instance()->reset_data(EE_Error::OPTIONS_KEY_NOTICES);
818
+		}
819
+		// clear global notices and hope none belonged to some for some other site visitor
820
+		return update_option(EE_Error::OPTIONS_KEY_NOTICES, array());
821
+	}
822
+
823
+
824
+	/**
825
+	 * saves notices to the db for retrieval on next request
826
+	 *
827
+	 * @return void
828
+	 * @throws InvalidArgumentException
829
+	 * @throws InvalidDataTypeException
830
+	 * @throws InvalidInterfaceException
831
+	 */
832
+	public static function stashNoticesBeforeRedirect()
833
+	{
834
+		EE_Error::get_notices(false, true);
835
+	}
836
+
837
+
838
+	/**
839
+	 * compile all error or success messages into one string
840
+	 *
841
+	 * @see EE_Error::get_raw_notices if you want the raw notices without any preparations made to them
842
+	 * @param boolean $format_output            whether or not to format the messages for display in the WP admin
843
+	 * @param boolean $save_to_transient        whether or not to save notices to the db for retrieval on next request
844
+	 *                                          - ONLY do this just before redirecting
845
+	 * @param boolean $remove_empty             whether or not to unset empty messages
846
+	 * @return array
847
+	 * @throws InvalidArgumentException
848
+	 * @throws InvalidDataTypeException
849
+	 * @throws InvalidInterfaceException
850
+	 */
851
+	public static function get_notices($format_output = true, $save_to_transient = false, $remove_empty = true)
852
+	{
853
+		$success_messages = '';
854
+		$attention_messages = '';
855
+		$error_messages = '';
856
+		// either save notices to the db
857
+		if ($save_to_transient || isset($_REQUEST['activate-selected'])) {
858
+			self::$_espresso_notices = array_merge(
859
+				EE_Error::getStoredNotices(),
860
+				self::$_espresso_notices
861
+			);
862
+			EE_Error::storeNotices(self::$_espresso_notices);
863
+			return array();
864
+		}
865
+		$print_scripts = EE_Error::combineExistingAndNewNotices();
866
+		// check for success messages
867
+		if (self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])) {
868
+			// combine messages
869
+			$success_messages .= implode(self::$_espresso_notices['success'], '<br />');
870
+			$print_scripts = true;
871
+		}
872
+		// check for attention messages
873
+		if (self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])) {
874
+			// combine messages
875
+			$attention_messages .= implode(self::$_espresso_notices['attention'], '<br />');
876
+			$print_scripts = true;
877
+		}
878
+		// check for error messages
879
+		if (self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])) {
880
+			$error_messages .= count(self::$_espresso_notices['errors']) > 1
881
+				? __('The following errors have occurred:<br />', 'event_espresso')
882
+				: __('An error has occurred:<br />', 'event_espresso');
883
+			// combine messages
884
+			$error_messages .= implode(self::$_espresso_notices['errors'], '<br />');
885
+			$print_scripts = true;
886
+		}
887
+		if ($format_output) {
888
+			$notices = EE_Error::formatNoticesOutput(
889
+				$success_messages,
890
+				$attention_messages,
891
+				$error_messages
892
+			);
893
+		} else {
894
+			$notices = array(
895
+				'success'   => $success_messages,
896
+				'attention' => $attention_messages,
897
+				'errors'    => $error_messages,
898
+			);
899
+			if ($remove_empty) {
900
+				// remove empty notices
901
+				foreach ($notices as $type => $notice) {
902
+					if (empty($notice)) {
903
+						unset($notices[ $type ]);
904
+					}
905
+				}
906
+			}
907
+		}
908
+		if ($print_scripts) {
909
+			self::_print_scripts();
910
+		}
911
+		return $notices;
912
+	}
913
+
914
+
915
+	/**
916
+	 * @return bool
917
+	 * @throws InvalidArgumentException
918
+	 * @throws InvalidDataTypeException
919
+	 * @throws InvalidInterfaceException
920
+	 */
921
+	private static function combineExistingAndNewNotices()
922
+	{
923
+		$print_scripts = false;
924
+		// grab any notices that have been previously saved
925
+		$notices = EE_Error::getStoredNotices();
926
+		if (! empty($notices)) {
927
+			foreach ($notices as $type => $notice) {
928
+				if (is_array($notice) && ! empty($notice)) {
929
+					// make sure that existing notice type is an array
930
+					self::$_espresso_notices[ $type ] = is_array(self::$_espresso_notices[ $type ])
931
+														&& ! empty(self::$_espresso_notices[ $type ])
932
+						? self::$_espresso_notices[ $type ]
933
+						: array();
934
+					// add newly created notices to existing ones
935
+					self::$_espresso_notices[ $type ] += $notice;
936
+					$print_scripts = true;
937
+				}
938
+			}
939
+			// now clear any stored notices
940
+			EE_Error::clearNotices();
941
+		}
942
+		return $print_scripts;
943
+	}
944
+
945
+
946
+	/**
947
+	 * @param string $success_messages
948
+	 * @param string $attention_messages
949
+	 * @param string $error_messages
950
+	 * @return string
951
+	 */
952
+	private static function formatNoticesOutput($success_messages, $attention_messages, $error_messages)
953
+	{
954
+		$notices = '<div id="espresso-notices">';
955
+		$close = is_admin()
956
+			? ''
957
+			: '<a class="close-espresso-notice hide-if-no-js"><span class="dashicons dashicons-no"/></a>';
958
+		if ($success_messages !== '') {
959
+			$css_id = is_admin() ? 'ee-success-message' : 'espresso-notices-success';
960
+			$css_class = is_admin() ? 'updated fade' : 'success fade-away';
961
+			// showMessage( $success_messages );
962
+			$notices .= '<div id="' . $css_id . '" '
963
+						. 'class="espresso-notices ' . $css_class . '" '
964
+						. 'style="display:none;">'
965
+						. '<p>' . $success_messages . '</p>'
966
+						. $close
967
+						. '</div>';
968
+		}
969
+		if ($attention_messages !== '') {
970
+			$css_id = is_admin() ? 'ee-attention-message' : 'espresso-notices-attention';
971
+			$css_class = is_admin() ? 'updated ee-notices-attention' : 'attention fade-away';
972
+			// showMessage( $error_messages, TRUE );
973
+			$notices .= '<div id="' . $css_id . '" '
974
+						. 'class="espresso-notices ' . $css_class . '" '
975
+						. 'style="display:none;">'
976
+						. '<p>' . $attention_messages . '</p>'
977
+						. $close
978
+						. '</div>';
979
+		}
980
+		if ($error_messages !== '') {
981
+			$css_id = is_admin() ? 'ee-error-message' : 'espresso-notices-error';
982
+			$css_class = is_admin() ? 'error' : 'error fade-away';
983
+			// showMessage( $error_messages, TRUE );
984
+			$notices .= '<div id="' . $css_id . '" '
985
+						. 'class="espresso-notices ' . $css_class . '" '
986
+						. 'style="display:none;">'
987
+						. '<p>' . $error_messages . '</p>'
988
+						. $close
989
+						. '</div>';
990
+		}
991
+		$notices .= '</div>';
992
+		return $notices;
993
+	}
994
+
995
+
996
+	/**
997
+	 * _print_scripts
998
+	 *
999
+	 * @param    bool $force_print
1000
+	 * @return    string
1001
+	 */
1002
+	private static function _print_scripts($force_print = false)
1003
+	{
1004
+		if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
1005
+			if (wp_script_is('ee_error_js', 'registered')) {
1006
+				wp_enqueue_style('espresso_default');
1007
+				wp_enqueue_style('espresso_custom_css');
1008
+				wp_enqueue_script('ee_error_js');
1009
+			}
1010
+			if (wp_script_is('ee_error_js', 'enqueued')) {
1011
+				wp_localize_script('ee_error_js', 'ee_settings', array('wp_debug' => WP_DEBUG));
1012
+				return '';
1013
+			}
1014
+		} else {
1015
+			return '
1016 1016
 <script>
1017 1017
 /* <![CDATA[ */
1018 1018
 var ee_settings = {"wp_debug":"' . WP_DEBUG . '"};
@@ -1022,221 +1022,221 @@  discard block
 block discarded – undo
1022 1022
 <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
1023 1023
 <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
1024 1024
 ';
1025
-        }
1026
-        return '';
1027
-    }
1028
-
1029
-
1030
-    /**
1031
-     * @return void
1032
-     */
1033
-    public static function enqueue_error_scripts()
1034
-    {
1035
-        self::_print_scripts();
1036
-    }
1037
-
1038
-
1039
-    /**
1040
-     * create error code from filepath, function name,
1041
-     * and line number where exception or error was thrown
1042
-     *
1043
-     * @param string $file
1044
-     * @param string $func
1045
-     * @param string $line
1046
-     * @return string
1047
-     */
1048
-    public static function generate_error_code($file = '', $func = '', $line = '')
1049
-    {
1050
-        $file = explode('.', basename($file));
1051
-        $error_code = ! empty($file[0]) ? $file[0] : '';
1052
-        $error_code .= ! empty($func) ? ' - ' . $func : '';
1053
-        $error_code .= ! empty($line) ? ' - ' . $line : '';
1054
-        return $error_code;
1055
-    }
1056
-
1057
-
1058
-    /**
1059
-     * write exception details to log file
1060
-     * Since 4.9.53.rc.006 this writes to the standard PHP log file, not EE's custom log file
1061
-     *
1062
-     * @param int   $time
1063
-     * @param array $ex
1064
-     * @param bool  $clear
1065
-     * @return void
1066
-     */
1067
-    public function write_to_error_log($time = 0, $ex = array(), $clear = false)
1068
-    {
1069
-        if (empty($ex)) {
1070
-            return;
1071
-        }
1072
-        if (! $time) {
1073
-            $time = time();
1074
-        }
1075
-        $exception_log = '----------------------------------------------------------------------------------------'
1076
-                         . PHP_EOL;
1077
-        $exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
1078
-        $exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
1079
-        $exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
1080
-        $exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
1081
-        $exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
1082
-        $exception_log .= 'Stack trace: ' . PHP_EOL;
1083
-        $exception_log .= $ex['string'] . PHP_EOL;
1084
-        $exception_log .= '----------------------------------------------------------------------------------------'
1085
-                          . PHP_EOL;
1086
-        try {
1087
-            error_log($exception_log);
1088
-        } catch (EE_Error $e) {
1089
-            EE_Error::add_error(
1090
-                sprintf(
1091
-                    __(
1092
-                        'Event Espresso error logging could not be setup because: %s',
1093
-                        'event_espresso'
1094
-                    ),
1095
-                    $e->getMessage()
1096
-                )
1097
-            );
1098
-        }
1099
-    }
1100
-
1101
-
1102
-    /**
1103
-     * This is just a wrapper for the EEH_Debug_Tools::instance()->doing_it_wrong() method.
1104
-     * doing_it_wrong() is used in those cases where a normal PHP error won't get thrown,
1105
-     * but the code execution is done in a manner that could lead to unexpected results
1106
-     * (i.e. running to early, or too late in WP or EE loading process).
1107
-     * A good test for knowing whether to use this method is:
1108
-     * 1. Is there going to be a PHP error if something isn't setup/used correctly?
1109
-     * Yes -> use EE_Error::add_error() or throw new EE_Error()
1110
-     * 2. If this is loaded before something else, it won't break anything,
1111
-     * but just wont' do what its supposed to do? Yes -> use EE_Error::doing_it_wrong()
1112
-     *
1113
-     * @uses   constant WP_DEBUG test if wp_debug is on or not
1114
-     * @param string $function      The function that was called
1115
-     * @param string $message       A message explaining what has been done incorrectly
1116
-     * @param string $version       The version of Event Espresso where the error was added
1117
-     * @param string $applies_when  a version string for when you want the doing_it_wrong notice to begin appearing
1118
-     *                              for a deprecated function. This allows deprecation to occur during one version,
1119
-     *                              but not have any notices appear until a later version. This allows developers
1120
-     *                              extra time to update their code before notices appear.
1121
-     * @param int    $error_type
1122
-     */
1123
-    public static function doing_it_wrong(
1124
-        $function,
1125
-        $message,
1126
-        $version,
1127
-        $applies_when = '',
1128
-        $error_type = null
1129
-    ) {
1130
-        if (defined('WP_DEBUG') && WP_DEBUG) {
1131
-            EEH_Debug_Tools::instance()->doing_it_wrong($function, $message, $version, $applies_when, $error_type);
1132
-        }
1133
-    }
1134
-
1135
-
1136
-    /**
1137
-     * Like get_notices, but returns an array of all the notices of the given type.
1138
-     *
1139
-     * @return array {
1140
-     * @type array $success   all the success messages
1141
-     * @type array $errors    all the error messages
1142
-     * @type array $attention all the attention messages
1143
-     * }
1144
-     */
1145
-    public static function get_raw_notices()
1146
-    {
1147
-        return self::$_espresso_notices;
1148
-    }
1149
-
1150
-
1151
-    /**
1152
-     * @deprecated 4.9.27
1153
-     * @param string $pan_name     the name, or key of the Persistent Admin Notice to be stored
1154
-     * @param string $pan_message  the message to be stored persistently until dismissed
1155
-     * @param bool   $force_update allows one to enforce the reappearance of a persistent message.
1156
-     * @return void
1157
-     * @throws InvalidDataTypeException
1158
-     */
1159
-    public static function add_persistent_admin_notice($pan_name = '', $pan_message, $force_update = false)
1160
-    {
1161
-        new PersistentAdminNotice(
1162
-            $pan_name,
1163
-            $pan_message,
1164
-            $force_update
1165
-        );
1166
-        EE_Error::doing_it_wrong(
1167
-            __METHOD__,
1168
-            sprintf(
1169
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1170
-                '\EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
1171
-            ),
1172
-            '4.9.27'
1173
-        );
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * @deprecated 4.9.27
1179
-     * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
1180
-     * @param bool   $purge
1181
-     * @param bool   $return
1182
-     * @throws DomainException
1183
-     * @throws InvalidInterfaceException
1184
-     * @throws InvalidDataTypeException
1185
-     * @throws ServiceNotFoundException
1186
-     * @throws InvalidArgumentException
1187
-     */
1188
-    public static function dismiss_persistent_admin_notice($pan_name = '', $purge = false, $return = false)
1189
-    {
1190
-        /** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
1191
-        $persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
1192
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1193
-        );
1194
-        $persistent_admin_notice_manager->dismissNotice($pan_name, $purge, $return);
1195
-        EE_Error::doing_it_wrong(
1196
-            __METHOD__,
1197
-            sprintf(
1198
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1199
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1200
-            ),
1201
-            '4.9.27'
1202
-        );
1203
-    }
1204
-
1205
-
1206
-    /**
1207
-     * @deprecated 4.9.27
1208
-     * @param  string $pan_name    the name, or key of the Persistent Admin Notice to be stored
1209
-     * @param  string $pan_message the message to be stored persistently until dismissed
1210
-     * @param  string $return_url  URL to go back to after nag notice is dismissed
1211
-     */
1212
-    public static function display_persistent_admin_notices($pan_name = '', $pan_message = '', $return_url = '')
1213
-    {
1214
-        EE_Error::doing_it_wrong(
1215
-            __METHOD__,
1216
-            sprintf(
1217
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1218
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1219
-            ),
1220
-            '4.9.27'
1221
-        );
1222
-    }
1223
-
1224
-
1225
-    /**
1226
-     * @deprecated 4.9.27
1227
-     * @param string $return_url
1228
-     */
1229
-    public static function get_persistent_admin_notices($return_url = '')
1230
-    {
1231
-        EE_Error::doing_it_wrong(
1232
-            __METHOD__,
1233
-            sprintf(
1234
-                __('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1235
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1236
-            ),
1237
-            '4.9.27'
1238
-        );
1239
-    }
1025
+		}
1026
+		return '';
1027
+	}
1028
+
1029
+
1030
+	/**
1031
+	 * @return void
1032
+	 */
1033
+	public static function enqueue_error_scripts()
1034
+	{
1035
+		self::_print_scripts();
1036
+	}
1037
+
1038
+
1039
+	/**
1040
+	 * create error code from filepath, function name,
1041
+	 * and line number where exception or error was thrown
1042
+	 *
1043
+	 * @param string $file
1044
+	 * @param string $func
1045
+	 * @param string $line
1046
+	 * @return string
1047
+	 */
1048
+	public static function generate_error_code($file = '', $func = '', $line = '')
1049
+	{
1050
+		$file = explode('.', basename($file));
1051
+		$error_code = ! empty($file[0]) ? $file[0] : '';
1052
+		$error_code .= ! empty($func) ? ' - ' . $func : '';
1053
+		$error_code .= ! empty($line) ? ' - ' . $line : '';
1054
+		return $error_code;
1055
+	}
1056
+
1057
+
1058
+	/**
1059
+	 * write exception details to log file
1060
+	 * Since 4.9.53.rc.006 this writes to the standard PHP log file, not EE's custom log file
1061
+	 *
1062
+	 * @param int   $time
1063
+	 * @param array $ex
1064
+	 * @param bool  $clear
1065
+	 * @return void
1066
+	 */
1067
+	public function write_to_error_log($time = 0, $ex = array(), $clear = false)
1068
+	{
1069
+		if (empty($ex)) {
1070
+			return;
1071
+		}
1072
+		if (! $time) {
1073
+			$time = time();
1074
+		}
1075
+		$exception_log = '----------------------------------------------------------------------------------------'
1076
+						 . PHP_EOL;
1077
+		$exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
1078
+		$exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
1079
+		$exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
1080
+		$exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
1081
+		$exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
1082
+		$exception_log .= 'Stack trace: ' . PHP_EOL;
1083
+		$exception_log .= $ex['string'] . PHP_EOL;
1084
+		$exception_log .= '----------------------------------------------------------------------------------------'
1085
+						  . PHP_EOL;
1086
+		try {
1087
+			error_log($exception_log);
1088
+		} catch (EE_Error $e) {
1089
+			EE_Error::add_error(
1090
+				sprintf(
1091
+					__(
1092
+						'Event Espresso error logging could not be setup because: %s',
1093
+						'event_espresso'
1094
+					),
1095
+					$e->getMessage()
1096
+				)
1097
+			);
1098
+		}
1099
+	}
1100
+
1101
+
1102
+	/**
1103
+	 * This is just a wrapper for the EEH_Debug_Tools::instance()->doing_it_wrong() method.
1104
+	 * doing_it_wrong() is used in those cases where a normal PHP error won't get thrown,
1105
+	 * but the code execution is done in a manner that could lead to unexpected results
1106
+	 * (i.e. running to early, or too late in WP or EE loading process).
1107
+	 * A good test for knowing whether to use this method is:
1108
+	 * 1. Is there going to be a PHP error if something isn't setup/used correctly?
1109
+	 * Yes -> use EE_Error::add_error() or throw new EE_Error()
1110
+	 * 2. If this is loaded before something else, it won't break anything,
1111
+	 * but just wont' do what its supposed to do? Yes -> use EE_Error::doing_it_wrong()
1112
+	 *
1113
+	 * @uses   constant WP_DEBUG test if wp_debug is on or not
1114
+	 * @param string $function      The function that was called
1115
+	 * @param string $message       A message explaining what has been done incorrectly
1116
+	 * @param string $version       The version of Event Espresso where the error was added
1117
+	 * @param string $applies_when  a version string for when you want the doing_it_wrong notice to begin appearing
1118
+	 *                              for a deprecated function. This allows deprecation to occur during one version,
1119
+	 *                              but not have any notices appear until a later version. This allows developers
1120
+	 *                              extra time to update their code before notices appear.
1121
+	 * @param int    $error_type
1122
+	 */
1123
+	public static function doing_it_wrong(
1124
+		$function,
1125
+		$message,
1126
+		$version,
1127
+		$applies_when = '',
1128
+		$error_type = null
1129
+	) {
1130
+		if (defined('WP_DEBUG') && WP_DEBUG) {
1131
+			EEH_Debug_Tools::instance()->doing_it_wrong($function, $message, $version, $applies_when, $error_type);
1132
+		}
1133
+	}
1134
+
1135
+
1136
+	/**
1137
+	 * Like get_notices, but returns an array of all the notices of the given type.
1138
+	 *
1139
+	 * @return array {
1140
+	 * @type array $success   all the success messages
1141
+	 * @type array $errors    all the error messages
1142
+	 * @type array $attention all the attention messages
1143
+	 * }
1144
+	 */
1145
+	public static function get_raw_notices()
1146
+	{
1147
+		return self::$_espresso_notices;
1148
+	}
1149
+
1150
+
1151
+	/**
1152
+	 * @deprecated 4.9.27
1153
+	 * @param string $pan_name     the name, or key of the Persistent Admin Notice to be stored
1154
+	 * @param string $pan_message  the message to be stored persistently until dismissed
1155
+	 * @param bool   $force_update allows one to enforce the reappearance of a persistent message.
1156
+	 * @return void
1157
+	 * @throws InvalidDataTypeException
1158
+	 */
1159
+	public static function add_persistent_admin_notice($pan_name = '', $pan_message, $force_update = false)
1160
+	{
1161
+		new PersistentAdminNotice(
1162
+			$pan_name,
1163
+			$pan_message,
1164
+			$force_update
1165
+		);
1166
+		EE_Error::doing_it_wrong(
1167
+			__METHOD__,
1168
+			sprintf(
1169
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1170
+				'\EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
1171
+			),
1172
+			'4.9.27'
1173
+		);
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * @deprecated 4.9.27
1179
+	 * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
1180
+	 * @param bool   $purge
1181
+	 * @param bool   $return
1182
+	 * @throws DomainException
1183
+	 * @throws InvalidInterfaceException
1184
+	 * @throws InvalidDataTypeException
1185
+	 * @throws ServiceNotFoundException
1186
+	 * @throws InvalidArgumentException
1187
+	 */
1188
+	public static function dismiss_persistent_admin_notice($pan_name = '', $purge = false, $return = false)
1189
+	{
1190
+		/** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
1191
+		$persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
1192
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1193
+		);
1194
+		$persistent_admin_notice_manager->dismissNotice($pan_name, $purge, $return);
1195
+		EE_Error::doing_it_wrong(
1196
+			__METHOD__,
1197
+			sprintf(
1198
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1199
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1200
+			),
1201
+			'4.9.27'
1202
+		);
1203
+	}
1204
+
1205
+
1206
+	/**
1207
+	 * @deprecated 4.9.27
1208
+	 * @param  string $pan_name    the name, or key of the Persistent Admin Notice to be stored
1209
+	 * @param  string $pan_message the message to be stored persistently until dismissed
1210
+	 * @param  string $return_url  URL to go back to after nag notice is dismissed
1211
+	 */
1212
+	public static function display_persistent_admin_notices($pan_name = '', $pan_message = '', $return_url = '')
1213
+	{
1214
+		EE_Error::doing_it_wrong(
1215
+			__METHOD__,
1216
+			sprintf(
1217
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1218
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1219
+			),
1220
+			'4.9.27'
1221
+		);
1222
+	}
1223
+
1224
+
1225
+	/**
1226
+	 * @deprecated 4.9.27
1227
+	 * @param string $return_url
1228
+	 */
1229
+	public static function get_persistent_admin_notices($return_url = '')
1230
+	{
1231
+		EE_Error::doing_it_wrong(
1232
+			__METHOD__,
1233
+			sprintf(
1234
+				__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1235
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1236
+			),
1237
+			'4.9.27'
1238
+		);
1239
+	}
1240 1240
 }
1241 1241
 
1242 1242
 // end of Class EE_Exceptions
@@ -1249,27 +1249,27 @@  discard block
 block discarded – undo
1249 1249
  */
1250 1250
 function espresso_error_enqueue_scripts()
1251 1251
 {
1252
-    // js for error handling
1253
-    wp_register_script(
1254
-        'espresso_core',
1255
-        EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
1256
-        array('jquery'),
1257
-        EVENT_ESPRESSO_VERSION,
1258
-        false
1259
-    );
1260
-    wp_register_script(
1261
-        'ee_error_js',
1262
-        EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
1263
-        array('espresso_core'),
1264
-        EVENT_ESPRESSO_VERSION,
1265
-        false
1266
-    );
1252
+	// js for error handling
1253
+	wp_register_script(
1254
+		'espresso_core',
1255
+		EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
1256
+		array('jquery'),
1257
+		EVENT_ESPRESSO_VERSION,
1258
+		false
1259
+	);
1260
+	wp_register_script(
1261
+		'ee_error_js',
1262
+		EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
1263
+		array('espresso_core'),
1264
+		EVENT_ESPRESSO_VERSION,
1265
+		false
1266
+	);
1267 1267
 }
1268 1268
 
1269 1269
 if (is_admin()) {
1270
-    add_action('admin_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1270
+	add_action('admin_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1271 1271
 } else {
1272
-    add_action('wp_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1272
+	add_action('wp_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1273 1273
 }
1274 1274
 
1275 1275
 
Please login to merge, or discard this patch.
Spacing   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -99,14 +99,14 @@  discard block
 block discarded – undo
99 99
             default:
100 100
                 $to = get_option('admin_email');
101 101
         }
102
-        $subject = $type . ' ' . $message . ' in ' . EVENT_ESPRESSO_VERSION . ' on ' . site_url();
102
+        $subject = $type.' '.$message.' in '.EVENT_ESPRESSO_VERSION.' on '.site_url();
103 103
         $msg = EE_Error::_format_error($type, $message, $file, $line);
104 104
         if (function_exists('wp_mail')) {
105 105
             add_filter('wp_mail_content_type', array('EE_Error', 'set_content_type'));
106 106
             wp_mail($to, $subject, $msg);
107 107
         }
108 108
         echo '<div id="message" class="espresso-notices error"><p>';
109
-        echo $type . ': ' . $message . '<br />' . $file . ' line ' . $line;
109
+        echo $type.': '.$message.'<br />'.$file.' line '.$line;
110 110
         echo '<br /></p></div>';
111 111
     }
112 112
 
@@ -222,13 +222,13 @@  discard block
 block discarded – undo
222 222
         $msg = WP_DEBUG ? $dev_msg : $user_msg;
223 223
         // add details to _all_exceptions array
224 224
         $x_time = time();
225
-        self::$_all_exceptions[ $x_time ]['name'] = get_class($this);
226
-        self::$_all_exceptions[ $x_time ]['file'] = $this->getFile();
227
-        self::$_all_exceptions[ $x_time ]['line'] = $this->getLine();
228
-        self::$_all_exceptions[ $x_time ]['msg'] = $msg;
229
-        self::$_all_exceptions[ $x_time ]['code'] = $this->getCode();
230
-        self::$_all_exceptions[ $x_time ]['trace'] = $this->getTrace();
231
-        self::$_all_exceptions[ $x_time ]['string'] = $this->getTraceAsString();
225
+        self::$_all_exceptions[$x_time]['name'] = get_class($this);
226
+        self::$_all_exceptions[$x_time]['file'] = $this->getFile();
227
+        self::$_all_exceptions[$x_time]['line'] = $this->getLine();
228
+        self::$_all_exceptions[$x_time]['msg'] = $msg;
229
+        self::$_all_exceptions[$x_time]['code'] = $this->getCode();
230
+        self::$_all_exceptions[$x_time]['trace'] = $this->getTrace();
231
+        self::$_all_exceptions[$x_time]['string'] = $this->getTraceAsString();
232 232
         self::$_error_count++;
233 233
         // add_action( 'shutdown', array( $this, 'display_errors' ));
234 234
         $this->display_errors();
@@ -246,8 +246,8 @@  discard block
 block discarded – undo
246 246
      */
247 247
     public static function has_error($check_stored = false, $type_to_check = 'errors')
248 248
     {
249
-        $has_error = isset(self::$_espresso_notices[ $type_to_check ])
250
-                     && ! empty(self::$_espresso_notices[ $type_to_check ])
249
+        $has_error = isset(self::$_espresso_notices[$type_to_check])
250
+                     && ! empty(self::$_espresso_notices[$type_to_check])
251 251
             ? true
252 252
             : false;
253 253
         if ($check_stored && ! $has_error) {
@@ -325,7 +325,7 @@  discard block
 block discarded – undo
325 325
 	}
326 326
 </style>
327 327
 <div id="ee-error-message" class="error">';
328
-        if (! WP_DEBUG) {
328
+        if ( ! WP_DEBUG) {
329 329
             $output .= '
330 330
 	<p>';
331 331
         }
@@ -384,14 +384,14 @@  discard block
 block discarded – undo
384 384
                     $class_dsply = ! empty($class) ? $class : '&nbsp;';
385 385
                     $type_dsply = ! empty($type) ? $type : '&nbsp;';
386 386
                     $function_dsply = ! empty($function) ? $function : '&nbsp;';
387
-                    $args_dsply = ! empty($args) ? '( ' . $args . ' )' : '';
387
+                    $args_dsply = ! empty($args) ? '( '.$args.' )' : '';
388 388
                     $trace_details .= '
389 389
 					<tr>
390
-						<td align="right" class="' . $zebra . '">' . $nmbr_dsply . '</td>
391
-						<td align="right" class="' . $zebra . '">' . $line_dsply . '</td>
392
-						<td align="left" class="' . $zebra . '">' . $file_dsply . '</td>
393
-						<td align="left" class="' . $zebra . '">' . $class_dsply . '</td>
394
-						<td align="left" class="' . $zebra . '">' . $type_dsply . $function_dsply . $args_dsply . '</td>
390
+						<td align="right" class="' . $zebra.'">'.$nmbr_dsply.'</td>
391
+						<td align="right" class="' . $zebra.'">'.$line_dsply.'</td>
392
+						<td align="left" class="' . $zebra.'">'.$file_dsply.'</td>
393
+						<td align="left" class="' . $zebra.'">'.$class_dsply.'</td>
394
+						<td align="left" class="' . $zebra.'">'.$type_dsply.$function_dsply.$args_dsply.'</td>
395 395
 					</tr>';
396 396
                 }
397 397
                 $trace_details .= '
@@ -400,7 +400,7 @@  discard block
 block discarded – undo
400 400
             }
401 401
             $ex['code'] = $ex['code'] ? $ex['code'] : $error_code;
402 402
             // add generic non-identifying messages for non-privileged users
403
-            if (! WP_DEBUG) {
403
+            if ( ! WP_DEBUG) {
404 404
                 $output .= '<span class="ee-error-user-msg-spn">'
405 405
                            . trim($ex['msg'])
406 406
                            . '</span> &nbsp; <sup>'
@@ -442,14 +442,14 @@  discard block
 block discarded – undo
442 442
                            . '-dv" class="ee-error-trace-dv" style="display: none;">
443 443
 				'
444 444
                            . $trace_details;
445
-                if (! empty($class)) {
445
+                if ( ! empty($class)) {
446 446
                     $output .= '
447 447
 				<div style="padding:3px; margin:0 0 1em; border:1px solid #666; background:#fff; border-radius:3px;">
448 448
 					<div style="padding:1em 2em; border:1px solid #666; background:#f9f9f9;">
449 449
 						<h3>Class Details</h3>';
450 450
                     $a = new ReflectionClass($class);
451 451
                     $output .= '
452
-						<pre>' . $a . '</pre>
452
+						<pre>' . $a.'</pre>
453 453
 					</div>
454 454
 				</div>';
455 455
                 }
@@ -462,7 +462,7 @@  discard block
 block discarded – undo
462 462
         }
463 463
         // remove last linebreak
464 464
         $output = substr($output, 0, -6);
465
-        if (! WP_DEBUG) {
465
+        if ( ! WP_DEBUG) {
466 466
             $output .= '
467 467
 	</p>';
468 468
         }
@@ -488,20 +488,20 @@  discard block
 block discarded – undo
488 488
     private function _convert_args_to_string($arguments = array(), $array = false)
489 489
     {
490 490
         $arg_string = '';
491
-        if (! empty($arguments)) {
491
+        if ( ! empty($arguments)) {
492 492
             $args = array();
493 493
             foreach ($arguments as $arg) {
494
-                if (! empty($arg)) {
494
+                if ( ! empty($arg)) {
495 495
                     if (is_string($arg)) {
496
-                        $args[] = " '" . $arg . "'";
496
+                        $args[] = " '".$arg."'";
497 497
                     } elseif (is_array($arg)) {
498
-                        $args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true);
498
+                        $args[] = 'ARRAY('.$this->_convert_args_to_string($arg, true);
499 499
                     } elseif ($arg === null) {
500 500
                         $args[] = ' NULL';
501 501
                     } elseif (is_bool($arg)) {
502 502
                         $args[] = ($arg) ? ' TRUE' : ' FALSE';
503 503
                     } elseif (is_object($arg)) {
504
-                        $args[] = ' OBJECT ' . get_class($arg);
504
+                        $args[] = ' OBJECT '.get_class($arg);
505 505
                     } elseif (is_resource($arg)) {
506 506
                         $args[] = get_resource_type($arg);
507 507
                     } else {
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
     {
600 600
         if (empty($msg)) {
601 601
             EE_Error::doing_it_wrong(
602
-                'EE_Error::add_' . $type . '()',
602
+                'EE_Error::add_'.$type.'()',
603 603
                 sprintf(
604 604
                     __(
605 605
                         'Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d',
@@ -639,17 +639,17 @@  discard block
 block discarded – undo
639 639
         do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line);
640 640
         $msg = WP_DEBUG ? $dev_msg : $user_msg;
641 641
         // add notice if message exists
642
-        if (! empty($msg)) {
642
+        if ( ! empty($msg)) {
643 643
             // get error code
644 644
             $notice_code = EE_Error::generate_error_code($file, $func, $line);
645 645
             if (WP_DEBUG && $type === 'errors') {
646
-                $msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>';
646
+                $msg .= '<br/><span class="tiny-text">'.$notice_code.'</span>';
647 647
             }
648 648
             // add notice. Index by code if it's not blank
649 649
             if ($notice_code) {
650
-                self::$_espresso_notices[ $type ][ $notice_code ] = $msg;
650
+                self::$_espresso_notices[$type][$notice_code] = $msg;
651 651
             } else {
652
-                self::$_espresso_notices[ $type ][] = $msg;
652
+                self::$_espresso_notices[$type][] = $msg;
653 653
             }
654 654
             add_action('wp_footer', array('EE_Error', 'enqueue_error_scripts'), 1);
655 655
         }
@@ -900,7 +900,7 @@  discard block
 block discarded – undo
900 900
                 // remove empty notices
901 901
                 foreach ($notices as $type => $notice) {
902 902
                     if (empty($notice)) {
903
-                        unset($notices[ $type ]);
903
+                        unset($notices[$type]);
904 904
                     }
905 905
                 }
906 906
             }
@@ -923,16 +923,16 @@  discard block
 block discarded – undo
923 923
         $print_scripts = false;
924 924
         // grab any notices that have been previously saved
925 925
         $notices = EE_Error::getStoredNotices();
926
-        if (! empty($notices)) {
926
+        if ( ! empty($notices)) {
927 927
             foreach ($notices as $type => $notice) {
928 928
                 if (is_array($notice) && ! empty($notice)) {
929 929
                     // make sure that existing notice type is an array
930
-                    self::$_espresso_notices[ $type ] = is_array(self::$_espresso_notices[ $type ])
931
-                                                        && ! empty(self::$_espresso_notices[ $type ])
932
-                        ? self::$_espresso_notices[ $type ]
930
+                    self::$_espresso_notices[$type] = is_array(self::$_espresso_notices[$type])
931
+                                                        && ! empty(self::$_espresso_notices[$type])
932
+                        ? self::$_espresso_notices[$type]
933 933
                         : array();
934 934
                     // add newly created notices to existing ones
935
-                    self::$_espresso_notices[ $type ] += $notice;
935
+                    self::$_espresso_notices[$type] += $notice;
936 936
                     $print_scripts = true;
937 937
                 }
938 938
             }
@@ -959,10 +959,10 @@  discard block
 block discarded – undo
959 959
             $css_id = is_admin() ? 'ee-success-message' : 'espresso-notices-success';
960 960
             $css_class = is_admin() ? 'updated fade' : 'success fade-away';
961 961
             // showMessage( $success_messages );
962
-            $notices .= '<div id="' . $css_id . '" '
963
-                        . 'class="espresso-notices ' . $css_class . '" '
962
+            $notices .= '<div id="'.$css_id.'" '
963
+                        . 'class="espresso-notices '.$css_class.'" '
964 964
                         . 'style="display:none;">'
965
-                        . '<p>' . $success_messages . '</p>'
965
+                        . '<p>'.$success_messages.'</p>'
966 966
                         . $close
967 967
                         . '</div>';
968 968
         }
@@ -970,10 +970,10 @@  discard block
 block discarded – undo
970 970
             $css_id = is_admin() ? 'ee-attention-message' : 'espresso-notices-attention';
971 971
             $css_class = is_admin() ? 'updated ee-notices-attention' : 'attention fade-away';
972 972
             // showMessage( $error_messages, TRUE );
973
-            $notices .= '<div id="' . $css_id . '" '
974
-                        . 'class="espresso-notices ' . $css_class . '" '
973
+            $notices .= '<div id="'.$css_id.'" '
974
+                        . 'class="espresso-notices '.$css_class.'" '
975 975
                         . 'style="display:none;">'
976
-                        . '<p>' . $attention_messages . '</p>'
976
+                        . '<p>'.$attention_messages.'</p>'
977 977
                         . $close
978 978
                         . '</div>';
979 979
         }
@@ -981,10 +981,10 @@  discard block
 block discarded – undo
981 981
             $css_id = is_admin() ? 'ee-error-message' : 'espresso-notices-error';
982 982
             $css_class = is_admin() ? 'error' : 'error fade-away';
983 983
             // showMessage( $error_messages, TRUE );
984
-            $notices .= '<div id="' . $css_id . '" '
985
-                        . 'class="espresso-notices ' . $css_class . '" '
984
+            $notices .= '<div id="'.$css_id.'" '
985
+                        . 'class="espresso-notices '.$css_class.'" '
986 986
                         . 'style="display:none;">'
987
-                        . '<p>' . $error_messages . '</p>'
987
+                        . '<p>'.$error_messages.'</p>'
988 988
                         . $close
989 989
                         . '</div>';
990 990
         }
@@ -1001,7 +1001,7 @@  discard block
 block discarded – undo
1001 1001
      */
1002 1002
     private static function _print_scripts($force_print = false)
1003 1003
     {
1004
-        if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
1004
+        if ( ! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
1005 1005
             if (wp_script_is('ee_error_js', 'registered')) {
1006 1006
                 wp_enqueue_style('espresso_default');
1007 1007
                 wp_enqueue_style('espresso_custom_css');
@@ -1015,12 +1015,12 @@  discard block
 block discarded – undo
1015 1015
             return '
1016 1016
 <script>
1017 1017
 /* <![CDATA[ */
1018
-var ee_settings = {"wp_debug":"' . WP_DEBUG . '"};
1018
+var ee_settings = {"wp_debug":"' . WP_DEBUG.'"};
1019 1019
 /* ]]> */
1020 1020
 </script>
1021
-<script src="' . includes_url() . 'js/jquery/jquery.js" type="text/javascript"></script>
1022
-<script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
1023
-<script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
1021
+<script src="' . includes_url().'js/jquery/jquery.js" type="text/javascript"></script>
1022
+<script src="' . EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js'.'?ver='.espresso_version().'" type="text/javascript"></script>
1023
+<script src="' . EE_GLOBAL_ASSETS_URL.'scripts/EE_Error.js'.'?ver='.espresso_version().'" type="text/javascript"></script>
1024 1024
 ';
1025 1025
         }
1026 1026
         return '';
@@ -1049,8 +1049,8 @@  discard block
 block discarded – undo
1049 1049
     {
1050 1050
         $file = explode('.', basename($file));
1051 1051
         $error_code = ! empty($file[0]) ? $file[0] : '';
1052
-        $error_code .= ! empty($func) ? ' - ' . $func : '';
1053
-        $error_code .= ! empty($line) ? ' - ' . $line : '';
1052
+        $error_code .= ! empty($func) ? ' - '.$func : '';
1053
+        $error_code .= ! empty($line) ? ' - '.$line : '';
1054 1054
         return $error_code;
1055 1055
     }
1056 1056
 
@@ -1069,18 +1069,18 @@  discard block
 block discarded – undo
1069 1069
         if (empty($ex)) {
1070 1070
             return;
1071 1071
         }
1072
-        if (! $time) {
1072
+        if ( ! $time) {
1073 1073
             $time = time();
1074 1074
         }
1075 1075
         $exception_log = '----------------------------------------------------------------------------------------'
1076 1076
                          . PHP_EOL;
1077
-        $exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
1078
-        $exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
1079
-        $exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
1080
-        $exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
1081
-        $exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
1082
-        $exception_log .= 'Stack trace: ' . PHP_EOL;
1083
-        $exception_log .= $ex['string'] . PHP_EOL;
1077
+        $exception_log .= '['.date('Y-m-d H:i:s', $time).']  Exception Details'.PHP_EOL;
1078
+        $exception_log .= 'Message: '.$ex['msg'].PHP_EOL;
1079
+        $exception_log .= 'Code: '.$ex['code'].PHP_EOL;
1080
+        $exception_log .= 'File: '.$ex['file'].PHP_EOL;
1081
+        $exception_log .= 'Line No: '.$ex['line'].PHP_EOL;
1082
+        $exception_log .= 'Stack trace: '.PHP_EOL;
1083
+        $exception_log .= $ex['string'].PHP_EOL;
1084 1084
         $exception_log .= '----------------------------------------------------------------------------------------'
1085 1085
                           . PHP_EOL;
1086 1086
         try {
@@ -1252,14 +1252,14 @@  discard block
 block discarded – undo
1252 1252
     // js for error handling
1253 1253
     wp_register_script(
1254 1254
         'espresso_core',
1255
-        EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
1255
+        EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js',
1256 1256
         array('jquery'),
1257 1257
         EVENT_ESPRESSO_VERSION,
1258 1258
         false
1259 1259
     );
1260 1260
     wp_register_script(
1261 1261
         'ee_error_js',
1262
-        EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
1262
+        EE_GLOBAL_ASSETS_URL.'scripts/EE_Error.js',
1263 1263
         array('espresso_core'),
1264 1264
         EVENT_ESPRESSO_VERSION,
1265 1265
         false
Please login to merge, or discard this patch.
core/EE_Encryption.core.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -396,7 +396,7 @@
 block discarded – undo
396 396
 
397 397
     /**
398 398
      * @see http://stackoverflow.com/questions/2556345/detect-base64-encoding-in-php#30231906
399
-     * @param $string
399
+     * @param string $string
400 400
      * @return bool
401 401
      */
402 402
     protected function valid_base_64($string)
Please login to merge, or discard this patch.
Indentation   +671 added lines, -671 removed lines patch added patch discarded remove patch
@@ -26,675 +26,675 @@
 block discarded – undo
26 26
 class EE_Encryption implements InterminableInterface
27 27
 {
28 28
 
29
-    /**
30
-     * key used for saving the encryption key to the wp_options table
31
-     */
32
-    const ENCRYPTION_OPTION_KEY = 'ee_encryption_key';
33
-
34
-    /**
35
-     * the OPENSSL cipher method used
36
-     */
37
-    const OPENSSL_CIPHER_METHOD = 'AES-128-CBC';
38
-
39
-    /**
40
-     * WP "options_name" used to store a verified available cipher method
41
-     */
42
-    const OPENSSL_CIPHER_METHOD_OPTION_NAME = 'ee_openssl_cipher_method';
43
-
44
-    /**
45
-     * the OPENSSL digest method used
46
-     */
47
-    const OPENSSL_DIGEST_METHOD = 'sha512';
48
-
49
-    /**
50
-     * separates the encrypted text from the initialization vector
51
-     */
52
-    const OPENSSL_IV_DELIMITER = ':iv:';
53
-
54
-    /**
55
-     * appended to text encrypted using the acme encryption
56
-     */
57
-    const ACME_ENCRYPTION_FLAG = '::ae';
58
-
59
-
60
-    /**
61
-     * instance of the EE_Encryption object
62
-     */
63
-    protected static $_instance;
64
-
65
-    /**
66
-     * @var string $_encryption_key
67
-     */
68
-    protected $_encryption_key;
69
-
70
-    /**
71
-     * @var string $cipher_method
72
-     */
73
-    private $cipher_method = '';
74
-
75
-    /**
76
-     * @var array $cipher_methods
77
-     */
78
-    private $cipher_methods = array();
79
-
80
-    /**
81
-     * @var array $digest_methods
82
-     */
83
-    private $digest_methods = array();
84
-
85
-    /**
86
-     * @var boolean $_use_openssl_encrypt
87
-     */
88
-    protected $_use_openssl_encrypt = false;
89
-
90
-    /**
91
-     * @var boolean $_use_mcrypt
92
-     */
93
-    protected $_use_mcrypt = false;
94
-
95
-    /**
96
-     * @var boolean $_use_base64_encode
97
-     */
98
-    protected $_use_base64_encode = false;
99
-
100
-
101
-    /**
102
-     * protected constructor to prevent direct creation
103
-     */
104
-    protected function __construct()
105
-    {
106
-        if (! defined('ESPRESSO_ENCRYPT')) {
107
-            define('ESPRESSO_ENCRYPT', true);
108
-        }
109
-        if (extension_loaded('openssl')) {
110
-            $this->_use_openssl_encrypt = true;
111
-        } elseif (extension_loaded('mcrypt')) {
112
-            $this->_use_mcrypt = true;
113
-        }
114
-        if (function_exists('base64_encode')) {
115
-            $this->_use_base64_encode = true;
116
-        }
117
-    }
118
-
119
-
120
-    /**
121
-     * singleton method used to instantiate class object
122
-     *
123
-     * @return EE_Encryption
124
-     */
125
-    public static function instance()
126
-    {
127
-        // check if class object is instantiated
128
-        if (! EE_Encryption::$_instance instanceof EE_Encryption) {
129
-            EE_Encryption::$_instance = new self();
130
-        }
131
-        return EE_Encryption::$_instance;
132
-    }
133
-
134
-
135
-    /**
136
-     * get encryption key
137
-     *
138
-     * @return string
139
-     */
140
-    public function get_encryption_key()
141
-    {
142
-        // if encryption key has not been set
143
-        if (empty($this->_encryption_key)) {
144
-            // retrieve encryption_key from db
145
-            $this->_encryption_key = get_option(EE_Encryption::ENCRYPTION_OPTION_KEY, '');
146
-            // WHAT?? No encryption_key in the db ??
147
-            if ($this->_encryption_key === '') {
148
-                // let's make one. And md5 it to make it just the right size for a key
149
-                $new_key = md5($this->generate_random_string());
150
-                // now save it to the db for later
151
-                add_option(EE_Encryption::ENCRYPTION_OPTION_KEY, $new_key);
152
-                // here's the key - FINALLY !
153
-                $this->_encryption_key = $new_key;
154
-            }
155
-        }
156
-        return $this->_encryption_key;
157
-    }
158
-
159
-
160
-    /**
161
-     * encrypts data
162
-     *
163
-     * @param string $text_string - the text to be encrypted
164
-     * @return string
165
-     * @throws RuntimeException
166
-     */
167
-    public function encrypt($text_string = '')
168
-    {
169
-        // you give me nothing??? GET OUT !
170
-        if (empty($text_string)) {
171
-            return $text_string;
172
-        }
173
-        if ($this->_use_openssl_encrypt) {
174
-            $encrypted_text = $this->openssl_encrypt($text_string);
175
-        } else {
176
-            $encrypted_text = $this->acme_encrypt($text_string);
177
-        }
178
-        return $encrypted_text;
179
-    }
180
-
181
-
182
-    /**
183
-     * decrypts data
184
-     *
185
-     * @param string $encrypted_text - the text to be decrypted
186
-     * @return string
187
-     * @throws RuntimeException
188
-     */
189
-    public function decrypt($encrypted_text = '')
190
-    {
191
-        // you give me nothing??? GET OUT !
192
-        if (empty($encrypted_text)) {
193
-            return $encrypted_text;
194
-        }
195
-        // if PHP's mcrypt functions are installed then we'll use them
196
-        if ($this->_use_openssl_encrypt) {
197
-            $decrypted_text = $this->openssl_decrypt($encrypted_text);
198
-        } else {
199
-            $decrypted_text = $this->acme_decrypt($encrypted_text);
200
-        }
201
-        return $decrypted_text;
202
-    }
203
-
204
-
205
-    /**
206
-     * encodes string with PHP's base64 encoding
207
-     *
208
-     * @see http://php.net/manual/en/function.base64-encode.php
209
-     * @param string $text_string the text to be encoded
210
-     * @return string
211
-     */
212
-    public function base64_string_encode($text_string = '')
213
-    {
214
-        // you give me nothing??? GET OUT !
215
-        if (empty($text_string) || ! $this->_use_base64_encode) {
216
-            return $text_string;
217
-        }
218
-        // encode
219
-        return base64_encode($text_string);
220
-    }
221
-
222
-
223
-    /**
224
-     * decodes string that has been encoded with PHP's base64 encoding
225
-     *
226
-     * @see http://php.net/manual/en/function.base64-encode.php
227
-     * @param string $encoded_string the text to be decoded
228
-     * @return string
229
-     * @throws RuntimeException
230
-     */
231
-    public function base64_string_decode($encoded_string = '')
232
-    {
233
-        // you give me nothing??? GET OUT !
234
-        if (empty($encoded_string) || ! $this->valid_base_64($encoded_string)) {
235
-            return $encoded_string;
236
-        }
237
-        // decode
238
-        $decoded_string = base64_decode($encoded_string);
239
-        if ($decoded_string === false) {
240
-            throw new RuntimeException(
241
-                esc_html__('Base 64 decoding failed.', 'event_espresso')
242
-            );
243
-        }
244
-        return $decoded_string;
245
-    }
246
-
247
-
248
-    /**
249
-     * encodes  url string with PHP's base64 encoding
250
-     *
251
-     * @see http://php.net/manual/en/function.base64-encode.php
252
-     * @param string $text_string the text to be encoded
253
-     * @return string
254
-     */
255
-    public function base64_url_encode($text_string = '')
256
-    {
257
-        // you give me nothing??? GET OUT !
258
-        if (empty($text_string) || ! $this->_use_base64_encode) {
259
-            return $text_string;
260
-        }
261
-        // encode
262
-        $encoded_string = base64_encode($text_string);
263
-        // remove chars to make encoding more URL friendly
264
-        return strtr($encoded_string, '+/=', '-_,');
265
-    }
266
-
267
-
268
-    /**
269
-     * decodes  url string that has been encoded with PHP's base64 encoding
270
-     *
271
-     * @see http://php.net/manual/en/function.base64-encode.php
272
-     * @param string $encoded_string the text to be decoded
273
-     * @return string
274
-     * @throws RuntimeException
275
-     */
276
-    public function base64_url_decode($encoded_string = '')
277
-    {
278
-        // you give me nothing??? GET OUT !
279
-        if (empty($encoded_string) || ! $this->valid_base_64($encoded_string)) {
280
-            return $encoded_string;
281
-        }
282
-        // replace previously removed characters
283
-        $encoded_string = strtr($encoded_string, '-_,', '+/=');
284
-        // decode
285
-        $decoded_string = base64_decode($encoded_string);
286
-        if ($decoded_string === false) {
287
-            throw new RuntimeException(
288
-                esc_html__('Base 64 decoding failed.', 'event_espresso')
289
-            );
290
-        }
291
-        return $decoded_string;
292
-    }
293
-
294
-
295
-    /**
296
-     * encrypts data using PHP's openssl functions
297
-     *
298
-     * @param string $text_string the text to be encrypted
299
-     * @param string $cipher_method
300
-     * @param string $encryption_key
301
-     * @return string
302
-     * @throws RuntimeException
303
-     */
304
-    protected function openssl_encrypt(
305
-        $text_string = '',
306
-        $cipher_method = EE_Encryption::OPENSSL_CIPHER_METHOD,
307
-        $encryption_key = ''
308
-    ) {
309
-        // you give me nothing??? GET OUT !
310
-        if (empty($text_string)) {
311
-            return $text_string;
312
-        }
313
-        $this->cipher_method = $this->getCipherMethod($cipher_method);
314
-        // get initialization vector size
315
-        $iv_size = openssl_cipher_iv_length($this->cipher_method);
316
-        // generate initialization vector.
317
-        // The second parameter ("crypto_strong") is passed by reference,
318
-        // and is used to determines if the algorithm used was "cryptographically strong"
319
-        // openssl_random_pseudo_bytes() will toggle it to either true or false
320
-        $iv = openssl_random_pseudo_bytes($iv_size, $is_strong);
321
-        if ($iv === false || $is_strong === false) {
322
-            throw new RuntimeException(
323
-                esc_html__('Failed to generate OpenSSL initialization vector.', 'event_espresso')
324
-            );
325
-        }
326
-        // encrypt it
327
-        $encrypted_text = openssl_encrypt(
328
-            $text_string,
329
-            $this->cipher_method,
330
-            $this->getDigestHashValue(EE_Encryption::OPENSSL_DIGEST_METHOD, $encryption_key),
331
-            0,
332
-            $iv
333
-        );
334
-        // append the initialization vector
335
-        $encrypted_text .= EE_Encryption::OPENSSL_IV_DELIMITER . $iv;
336
-        // trim and maybe encode
337
-        return $this->_use_base64_encode
338
-            ? trim(base64_encode($encrypted_text))
339
-            : trim($encrypted_text);
340
-    }
341
-
342
-
343
-    /**
344
-     * Returns a cipher method that has been verified to work.
345
-     * First checks if the cached cipher has been set already and if so, returns that.
346
-     * Then tests the incoming default and returns that if it's good.
347
-     * If not, then it retrieves the previously tested and saved cipher method.
348
-     * But if that doesn't exist, then calls getAvailableCipherMethod()
349
-     * to see what is available on the server, and returns the results.
350
-     *
351
-     * @param string $cipher_method
352
-     * @return string
353
-     * @throws RuntimeException
354
-     */
355
-    protected function getCipherMethod($cipher_method = EE_Encryption::OPENSSL_CIPHER_METHOD)
356
-    {
357
-        if ($this->cipher_method !== '') {
358
-            return $this->cipher_method;
359
-        }
360
-        // verify that the default cipher method can produce an initialization vector
361
-        if (openssl_cipher_iv_length($cipher_method) === false) {
362
-            // nope? okay let's get what we found in the past to work
363
-            $cipher_method = get_option(EE_Encryption::OPENSSL_CIPHER_METHOD_OPTION_NAME, '');
364
-            // oops... haven't tested available cipher methods yet
365
-            if ($cipher_method === '' || openssl_cipher_iv_length($cipher_method) === false) {
366
-                $cipher_method = $this->getAvailableCipherMethod($cipher_method);
367
-            }
368
-        }
369
-        return $cipher_method;
370
-    }
371
-
372
-
373
-    /**
374
-     * @param string $cipher_method
375
-     * @return string
376
-     * @throws \RuntimeException
377
-     */
378
-    protected function getAvailableCipherMethod($cipher_method)
379
-    {
380
-        // verify that the incoming cipher method can produce an initialization vector
381
-        if (openssl_cipher_iv_length($cipher_method) === false) {
382
-            // nope? then check the next cipher in the list of available cipher methods
383
-            $cipher_method = next($this->cipher_methods);
384
-            // what? there's no list? then generate that list and cache it,
385
-            if (empty($this->cipher_methods)) {
386
-                $this->cipher_methods = openssl_get_cipher_methods();
387
-                // then grab the first item from the list
388
-                $cipher_method = reset($this->cipher_methods);
389
-            }
390
-            if ($cipher_method === false) {
391
-                throw new RuntimeException(
392
-                    esc_html__(
393
-                        'OpenSSL support appears to be enabled on the server, but no cipher methods are available. Please contact the server administrator.',
394
-                        'event_espresso'
395
-                    )
396
-                );
397
-            }
398
-            // verify that the next cipher method works
399
-            return $this->getAvailableCipherMethod($cipher_method);
400
-        }
401
-        // if we've gotten this far, then we found an available cipher method that works
402
-        // so save that for next time
403
-        update_option(
404
-            EE_Encryption::OPENSSL_CIPHER_METHOD_OPTION_NAME,
405
-            $cipher_method
406
-        );
407
-        return $cipher_method;
408
-    }
409
-
410
-
411
-    /**
412
-     * decrypts data that has been encrypted with PHP's openssl functions
413
-     *
414
-     * @param string $encrypted_text the text to be decrypted
415
-     * @param string $cipher_method
416
-     * @param string $encryption_key
417
-     * @return string
418
-     * @throws RuntimeException
419
-     */
420
-    protected function openssl_decrypt(
421
-        $encrypted_text = '',
422
-        $cipher_method = EE_Encryption::OPENSSL_CIPHER_METHOD,
423
-        $encryption_key = ''
424
-    ) {
425
-        // you give me nothing??? GET OUT !
426
-        if (empty($encrypted_text)) {
427
-            return $encrypted_text;
428
-        }
429
-        // decode
430
-        $encrypted_text = $this->valid_base_64($encrypted_text)
431
-            ? $this->base64_url_decode($encrypted_text)
432
-            : $encrypted_text;
433
-        $encrypted_components = explode(
434
-            EE_Encryption::OPENSSL_IV_DELIMITER,
435
-            $encrypted_text,
436
-            2
437
-        );
438
-        // check that iv exists, and if not, maybe text was encoded using mcrypt?
439
-        if ($this->_use_mcrypt && ! isset($encrypted_components[1])) {
440
-            return $this->m_decrypt($encrypted_text);
441
-        }
442
-        // decrypt it
443
-        $decrypted_text = openssl_decrypt(
444
-            $encrypted_components[0],
445
-            $this->getCipherMethod($cipher_method),
446
-            $this->getDigestHashValue(EE_Encryption::OPENSSL_DIGEST_METHOD, $encryption_key),
447
-            0,
448
-            $encrypted_components[1]
449
-        );
450
-        $decrypted_text = trim($decrypted_text);
451
-        return $decrypted_text;
452
-    }
453
-
454
-
455
-    /**
456
-     * Computes the digest hash value using the specified digest method.
457
-     * If that digest method fails to produce a valid hash value,
458
-     * then we'll grab the next digest method and recursively try again until something works.
459
-     *
460
-     * @param string $digest_method
461
-     * @param string $encryption_key
462
-     * @return string
463
-     * @throws RuntimeException
464
-     */
465
-    protected function getDigestHashValue($digest_method = EE_Encryption::OPENSSL_DIGEST_METHOD, $encryption_key = '')
466
-    {
467
-        $encryption_key = $encryption_key !== ''
468
-            ? $encryption_key
469
-            : $this->get_encryption_key();
470
-        $digest_hash_value = openssl_digest($encryption_key, $digest_method);
471
-        if ($digest_hash_value === false) {
472
-            return $this->getDigestHashValue($this->getDigestMethod());
473
-        }
474
-        return $digest_hash_value;
475
-    }
476
-
477
-
478
-    /**
479
-     * Returns the NEXT element in the $digest_methods array.
480
-     * If the $digest_methods array is empty, then we populate it
481
-     * with the available values returned from openssl_get_md_methods().
482
-     *
483
-     * @return string
484
-     * @throws \RuntimeException
485
-     */
486
-    protected function getDigestMethod()
487
-    {
488
-        $digest_method = prev($this->digest_methods);
489
-        if (empty($this->digest_methods)) {
490
-            $this->digest_methods = openssl_get_md_methods();
491
-            $digest_method = end($this->digest_methods);
492
-        }
493
-        if ($digest_method === false) {
494
-            throw new RuntimeException(
495
-                esc_html__(
496
-                    'OpenSSL support appears to be enabled on the server, but no digest methods are available. Please contact the server administrator.',
497
-                    'event_espresso'
498
-                )
499
-            );
500
-        }
501
-        return $digest_method;
502
-    }
503
-
504
-
505
-    /**
506
-     * encrypts data for acme servers that didn't bother to install PHP mcrypt
507
-     *
508
-     * @see http://stackoverflow.com/questions/800922/how-to-encrypt-string-without-mcrypt-library-in-php
509
-     * @param string $text_string the text to be decrypted
510
-     * @return string
511
-     */
512
-    protected function acme_encrypt($text_string = '')
513
-    {
514
-        // you give me nothing??? GET OUT !
515
-        if (empty($text_string)) {
516
-            return $text_string;
517
-        }
518
-        $key_bits = str_split(
519
-            str_pad(
520
-                '',
521
-                strlen($text_string),
522
-                $this->get_encryption_key(),
523
-                STR_PAD_RIGHT
524
-            )
525
-        );
526
-        $string_bits = str_split($text_string);
527
-        foreach ($string_bits as $k => $v) {
528
-            $temp = ord($v) + ord($key_bits[ $k ]);
529
-            $string_bits[ $k ] = chr($temp > 255 ? ($temp - 256) : $temp);
530
-        }
531
-        $encrypted_text = implode('', $string_bits);
532
-        $encrypted_text .= EE_Encryption::ACME_ENCRYPTION_FLAG;
533
-        return $this->_use_base64_encode
534
-            ? base64_encode($encrypted_text)
535
-            : $encrypted_text;
536
-    }
537
-
538
-
539
-    /**
540
-     * decrypts data for acme servers that didn't bother to install PHP mcrypt
541
-     *
542
-     * @see http://stackoverflow.com/questions/800922/how-to-encrypt-string-without-mcrypt-library-in-php
543
-     * @param string $encrypted_text the text to be decrypted
544
-     * @return string
545
-     * @throws RuntimeException
546
-     */
547
-    protected function acme_decrypt($encrypted_text = '')
548
-    {
549
-        // you give me nothing??? GET OUT !
550
-        if (empty($encrypted_text)) {
551
-            return $encrypted_text;
552
-        }
553
-        // decode the data ?
554
-        $encrypted_text = $this->valid_base_64($encrypted_text)
555
-            ? $this->base64_url_decode($encrypted_text)
556
-            : $encrypted_text;
557
-        if ($this->_use_mcrypt
558
-            && strpos($encrypted_text, EE_Encryption::ACME_ENCRYPTION_FLAG) === false
559
-        ) {
560
-            return $this->m_decrypt($encrypted_text);
561
-        }
562
-        $encrypted_text = substr($encrypted_text, 0, -4);
563
-        $key_bits = str_split(
564
-            str_pad(
565
-                '',
566
-                strlen($encrypted_text),
567
-                $this->get_encryption_key(),
568
-                STR_PAD_RIGHT
569
-            )
570
-        );
571
-        $string_bits = str_split($encrypted_text);
572
-        foreach ($string_bits as $k => $v) {
573
-            $temp = ord($v) - ord($key_bits[ $k ]);
574
-            $string_bits[ $k ] = chr($temp < 0 ? ($temp + 256) : $temp);
575
-        }
576
-        return implode('', $string_bits);
577
-    }
578
-
579
-
580
-    /**
581
-     * @see http://stackoverflow.com/questions/2556345/detect-base64-encoding-in-php#30231906
582
-     * @param $string
583
-     * @return bool
584
-     */
585
-    protected function valid_base_64($string)
586
-    {
587
-        // ensure data is a string
588
-        if (! is_string($string) || ! $this->_use_base64_encode) {
589
-            return false;
590
-        }
591
-        $decoded = base64_decode($string, true);
592
-        // Check if there is no invalid character in string
593
-        if (! preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) {
594
-            return false;
595
-        }
596
-        // Decode the string in strict mode and send the response
597
-        if (! base64_decode($string, true)) {
598
-            return false;
599
-        }
600
-        // Encode and compare it to original one
601
-        return base64_encode($decoded) === $string;
602
-    }
603
-
604
-
605
-    /**
606
-     * generate random string
607
-     *
608
-     * @see http://stackoverflow.com/questions/637278/what-is-the-best-way-to-generate-a-random-key-within-php
609
-     * @param int $length number of characters for random string
610
-     * @return string
611
-     */
612
-    public function generate_random_string($length = 40)
613
-    {
614
-        $iterations = ceil($length / 40);
615
-        $random_string = '';
616
-        for ($i = 0; $i < $iterations; $i++) {
617
-            $random_string .= sha1(microtime(true) . mt_rand(10000, 90000));
618
-        }
619
-        $random_string = substr($random_string, 0, $length);
620
-        return $random_string;
621
-    }
622
-
623
-
624
-    /**
625
-     * encrypts data using PHP's mcrypt functions
626
-     *
627
-     * @deprecated 4.9.39
628
-     * @param string $text_string
629
-     * @internal   param $string - the text to be encrypted
630
-     * @return string
631
-     * @throws RuntimeException
632
-     */
633
-    protected function m_encrypt($text_string = '')
634
-    {
635
-        // you give me nothing??? GET OUT !
636
-        if (empty($text_string)) {
637
-            return $text_string;
638
-        }
639
-        // get the initialization vector size
640
-        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
641
-        // initialization vector
642
-        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
643
-        if ($iv === false) {
644
-            throw new RuntimeException(
645
-                esc_html__('Failed to generate mcrypt initialization vector.', 'event_espresso')
646
-            );
647
-        }
648
-        // encrypt it
649
-        $encrypted_text = mcrypt_encrypt(
650
-            MCRYPT_RIJNDAEL_256,
651
-            $this->get_encryption_key(),
652
-            $text_string,
653
-            MCRYPT_MODE_ECB,
654
-            $iv
655
-        );
656
-        // trim and maybe encode
657
-        return $this->_use_base64_encode
658
-            ? trim(base64_encode($encrypted_text))
659
-            : trim($encrypted_text);
660
-    }
661
-
662
-
663
-    /**
664
-     * decrypts data that has been encrypted with PHP's mcrypt functions
665
-     *
666
-     * @deprecated 4.9.39
667
-     * @param string $encrypted_text the text to be decrypted
668
-     * @return string
669
-     * @throws RuntimeException
670
-     */
671
-    protected function m_decrypt($encrypted_text = '')
672
-    {
673
-        // you give me nothing??? GET OUT !
674
-        if (empty($encrypted_text)) {
675
-            return $encrypted_text;
676
-        }
677
-        // decode
678
-        $encrypted_text = $this->valid_base_64($encrypted_text)
679
-            ? $this->base64_url_decode($encrypted_text)
680
-            : $encrypted_text;
681
-        // get the initialization vector size
682
-        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
683
-        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
684
-        if ($iv === false) {
685
-            throw new RuntimeException(
686
-                esc_html__('Failed to generate mcrypt initialization vector.', 'event_espresso')
687
-            );
688
-        }
689
-        // decrypt it
690
-        $decrypted_text = mcrypt_decrypt(
691
-            MCRYPT_RIJNDAEL_256,
692
-            $this->get_encryption_key(),
693
-            $encrypted_text,
694
-            MCRYPT_MODE_ECB,
695
-            $iv
696
-        );
697
-        $decrypted_text = trim($decrypted_text);
698
-        return $decrypted_text;
699
-    }
29
+	/**
30
+	 * key used for saving the encryption key to the wp_options table
31
+	 */
32
+	const ENCRYPTION_OPTION_KEY = 'ee_encryption_key';
33
+
34
+	/**
35
+	 * the OPENSSL cipher method used
36
+	 */
37
+	const OPENSSL_CIPHER_METHOD = 'AES-128-CBC';
38
+
39
+	/**
40
+	 * WP "options_name" used to store a verified available cipher method
41
+	 */
42
+	const OPENSSL_CIPHER_METHOD_OPTION_NAME = 'ee_openssl_cipher_method';
43
+
44
+	/**
45
+	 * the OPENSSL digest method used
46
+	 */
47
+	const OPENSSL_DIGEST_METHOD = 'sha512';
48
+
49
+	/**
50
+	 * separates the encrypted text from the initialization vector
51
+	 */
52
+	const OPENSSL_IV_DELIMITER = ':iv:';
53
+
54
+	/**
55
+	 * appended to text encrypted using the acme encryption
56
+	 */
57
+	const ACME_ENCRYPTION_FLAG = '::ae';
58
+
59
+
60
+	/**
61
+	 * instance of the EE_Encryption object
62
+	 */
63
+	protected static $_instance;
64
+
65
+	/**
66
+	 * @var string $_encryption_key
67
+	 */
68
+	protected $_encryption_key;
69
+
70
+	/**
71
+	 * @var string $cipher_method
72
+	 */
73
+	private $cipher_method = '';
74
+
75
+	/**
76
+	 * @var array $cipher_methods
77
+	 */
78
+	private $cipher_methods = array();
79
+
80
+	/**
81
+	 * @var array $digest_methods
82
+	 */
83
+	private $digest_methods = array();
84
+
85
+	/**
86
+	 * @var boolean $_use_openssl_encrypt
87
+	 */
88
+	protected $_use_openssl_encrypt = false;
89
+
90
+	/**
91
+	 * @var boolean $_use_mcrypt
92
+	 */
93
+	protected $_use_mcrypt = false;
94
+
95
+	/**
96
+	 * @var boolean $_use_base64_encode
97
+	 */
98
+	protected $_use_base64_encode = false;
99
+
100
+
101
+	/**
102
+	 * protected constructor to prevent direct creation
103
+	 */
104
+	protected function __construct()
105
+	{
106
+		if (! defined('ESPRESSO_ENCRYPT')) {
107
+			define('ESPRESSO_ENCRYPT', true);
108
+		}
109
+		if (extension_loaded('openssl')) {
110
+			$this->_use_openssl_encrypt = true;
111
+		} elseif (extension_loaded('mcrypt')) {
112
+			$this->_use_mcrypt = true;
113
+		}
114
+		if (function_exists('base64_encode')) {
115
+			$this->_use_base64_encode = true;
116
+		}
117
+	}
118
+
119
+
120
+	/**
121
+	 * singleton method used to instantiate class object
122
+	 *
123
+	 * @return EE_Encryption
124
+	 */
125
+	public static function instance()
126
+	{
127
+		// check if class object is instantiated
128
+		if (! EE_Encryption::$_instance instanceof EE_Encryption) {
129
+			EE_Encryption::$_instance = new self();
130
+		}
131
+		return EE_Encryption::$_instance;
132
+	}
133
+
134
+
135
+	/**
136
+	 * get encryption key
137
+	 *
138
+	 * @return string
139
+	 */
140
+	public function get_encryption_key()
141
+	{
142
+		// if encryption key has not been set
143
+		if (empty($this->_encryption_key)) {
144
+			// retrieve encryption_key from db
145
+			$this->_encryption_key = get_option(EE_Encryption::ENCRYPTION_OPTION_KEY, '');
146
+			// WHAT?? No encryption_key in the db ??
147
+			if ($this->_encryption_key === '') {
148
+				// let's make one. And md5 it to make it just the right size for a key
149
+				$new_key = md5($this->generate_random_string());
150
+				// now save it to the db for later
151
+				add_option(EE_Encryption::ENCRYPTION_OPTION_KEY, $new_key);
152
+				// here's the key - FINALLY !
153
+				$this->_encryption_key = $new_key;
154
+			}
155
+		}
156
+		return $this->_encryption_key;
157
+	}
158
+
159
+
160
+	/**
161
+	 * encrypts data
162
+	 *
163
+	 * @param string $text_string - the text to be encrypted
164
+	 * @return string
165
+	 * @throws RuntimeException
166
+	 */
167
+	public function encrypt($text_string = '')
168
+	{
169
+		// you give me nothing??? GET OUT !
170
+		if (empty($text_string)) {
171
+			return $text_string;
172
+		}
173
+		if ($this->_use_openssl_encrypt) {
174
+			$encrypted_text = $this->openssl_encrypt($text_string);
175
+		} else {
176
+			$encrypted_text = $this->acme_encrypt($text_string);
177
+		}
178
+		return $encrypted_text;
179
+	}
180
+
181
+
182
+	/**
183
+	 * decrypts data
184
+	 *
185
+	 * @param string $encrypted_text - the text to be decrypted
186
+	 * @return string
187
+	 * @throws RuntimeException
188
+	 */
189
+	public function decrypt($encrypted_text = '')
190
+	{
191
+		// you give me nothing??? GET OUT !
192
+		if (empty($encrypted_text)) {
193
+			return $encrypted_text;
194
+		}
195
+		// if PHP's mcrypt functions are installed then we'll use them
196
+		if ($this->_use_openssl_encrypt) {
197
+			$decrypted_text = $this->openssl_decrypt($encrypted_text);
198
+		} else {
199
+			$decrypted_text = $this->acme_decrypt($encrypted_text);
200
+		}
201
+		return $decrypted_text;
202
+	}
203
+
204
+
205
+	/**
206
+	 * encodes string with PHP's base64 encoding
207
+	 *
208
+	 * @see http://php.net/manual/en/function.base64-encode.php
209
+	 * @param string $text_string the text to be encoded
210
+	 * @return string
211
+	 */
212
+	public function base64_string_encode($text_string = '')
213
+	{
214
+		// you give me nothing??? GET OUT !
215
+		if (empty($text_string) || ! $this->_use_base64_encode) {
216
+			return $text_string;
217
+		}
218
+		// encode
219
+		return base64_encode($text_string);
220
+	}
221
+
222
+
223
+	/**
224
+	 * decodes string that has been encoded with PHP's base64 encoding
225
+	 *
226
+	 * @see http://php.net/manual/en/function.base64-encode.php
227
+	 * @param string $encoded_string the text to be decoded
228
+	 * @return string
229
+	 * @throws RuntimeException
230
+	 */
231
+	public function base64_string_decode($encoded_string = '')
232
+	{
233
+		// you give me nothing??? GET OUT !
234
+		if (empty($encoded_string) || ! $this->valid_base_64($encoded_string)) {
235
+			return $encoded_string;
236
+		}
237
+		// decode
238
+		$decoded_string = base64_decode($encoded_string);
239
+		if ($decoded_string === false) {
240
+			throw new RuntimeException(
241
+				esc_html__('Base 64 decoding failed.', 'event_espresso')
242
+			);
243
+		}
244
+		return $decoded_string;
245
+	}
246
+
247
+
248
+	/**
249
+	 * encodes  url string with PHP's base64 encoding
250
+	 *
251
+	 * @see http://php.net/manual/en/function.base64-encode.php
252
+	 * @param string $text_string the text to be encoded
253
+	 * @return string
254
+	 */
255
+	public function base64_url_encode($text_string = '')
256
+	{
257
+		// you give me nothing??? GET OUT !
258
+		if (empty($text_string) || ! $this->_use_base64_encode) {
259
+			return $text_string;
260
+		}
261
+		// encode
262
+		$encoded_string = base64_encode($text_string);
263
+		// remove chars to make encoding more URL friendly
264
+		return strtr($encoded_string, '+/=', '-_,');
265
+	}
266
+
267
+
268
+	/**
269
+	 * decodes  url string that has been encoded with PHP's base64 encoding
270
+	 *
271
+	 * @see http://php.net/manual/en/function.base64-encode.php
272
+	 * @param string $encoded_string the text to be decoded
273
+	 * @return string
274
+	 * @throws RuntimeException
275
+	 */
276
+	public function base64_url_decode($encoded_string = '')
277
+	{
278
+		// you give me nothing??? GET OUT !
279
+		if (empty($encoded_string) || ! $this->valid_base_64($encoded_string)) {
280
+			return $encoded_string;
281
+		}
282
+		// replace previously removed characters
283
+		$encoded_string = strtr($encoded_string, '-_,', '+/=');
284
+		// decode
285
+		$decoded_string = base64_decode($encoded_string);
286
+		if ($decoded_string === false) {
287
+			throw new RuntimeException(
288
+				esc_html__('Base 64 decoding failed.', 'event_espresso')
289
+			);
290
+		}
291
+		return $decoded_string;
292
+	}
293
+
294
+
295
+	/**
296
+	 * encrypts data using PHP's openssl functions
297
+	 *
298
+	 * @param string $text_string the text to be encrypted
299
+	 * @param string $cipher_method
300
+	 * @param string $encryption_key
301
+	 * @return string
302
+	 * @throws RuntimeException
303
+	 */
304
+	protected function openssl_encrypt(
305
+		$text_string = '',
306
+		$cipher_method = EE_Encryption::OPENSSL_CIPHER_METHOD,
307
+		$encryption_key = ''
308
+	) {
309
+		// you give me nothing??? GET OUT !
310
+		if (empty($text_string)) {
311
+			return $text_string;
312
+		}
313
+		$this->cipher_method = $this->getCipherMethod($cipher_method);
314
+		// get initialization vector size
315
+		$iv_size = openssl_cipher_iv_length($this->cipher_method);
316
+		// generate initialization vector.
317
+		// The second parameter ("crypto_strong") is passed by reference,
318
+		// and is used to determines if the algorithm used was "cryptographically strong"
319
+		// openssl_random_pseudo_bytes() will toggle it to either true or false
320
+		$iv = openssl_random_pseudo_bytes($iv_size, $is_strong);
321
+		if ($iv === false || $is_strong === false) {
322
+			throw new RuntimeException(
323
+				esc_html__('Failed to generate OpenSSL initialization vector.', 'event_espresso')
324
+			);
325
+		}
326
+		// encrypt it
327
+		$encrypted_text = openssl_encrypt(
328
+			$text_string,
329
+			$this->cipher_method,
330
+			$this->getDigestHashValue(EE_Encryption::OPENSSL_DIGEST_METHOD, $encryption_key),
331
+			0,
332
+			$iv
333
+		);
334
+		// append the initialization vector
335
+		$encrypted_text .= EE_Encryption::OPENSSL_IV_DELIMITER . $iv;
336
+		// trim and maybe encode
337
+		return $this->_use_base64_encode
338
+			? trim(base64_encode($encrypted_text))
339
+			: trim($encrypted_text);
340
+	}
341
+
342
+
343
+	/**
344
+	 * Returns a cipher method that has been verified to work.
345
+	 * First checks if the cached cipher has been set already and if so, returns that.
346
+	 * Then tests the incoming default and returns that if it's good.
347
+	 * If not, then it retrieves the previously tested and saved cipher method.
348
+	 * But if that doesn't exist, then calls getAvailableCipherMethod()
349
+	 * to see what is available on the server, and returns the results.
350
+	 *
351
+	 * @param string $cipher_method
352
+	 * @return string
353
+	 * @throws RuntimeException
354
+	 */
355
+	protected function getCipherMethod($cipher_method = EE_Encryption::OPENSSL_CIPHER_METHOD)
356
+	{
357
+		if ($this->cipher_method !== '') {
358
+			return $this->cipher_method;
359
+		}
360
+		// verify that the default cipher method can produce an initialization vector
361
+		if (openssl_cipher_iv_length($cipher_method) === false) {
362
+			// nope? okay let's get what we found in the past to work
363
+			$cipher_method = get_option(EE_Encryption::OPENSSL_CIPHER_METHOD_OPTION_NAME, '');
364
+			// oops... haven't tested available cipher methods yet
365
+			if ($cipher_method === '' || openssl_cipher_iv_length($cipher_method) === false) {
366
+				$cipher_method = $this->getAvailableCipherMethod($cipher_method);
367
+			}
368
+		}
369
+		return $cipher_method;
370
+	}
371
+
372
+
373
+	/**
374
+	 * @param string $cipher_method
375
+	 * @return string
376
+	 * @throws \RuntimeException
377
+	 */
378
+	protected function getAvailableCipherMethod($cipher_method)
379
+	{
380
+		// verify that the incoming cipher method can produce an initialization vector
381
+		if (openssl_cipher_iv_length($cipher_method) === false) {
382
+			// nope? then check the next cipher in the list of available cipher methods
383
+			$cipher_method = next($this->cipher_methods);
384
+			// what? there's no list? then generate that list and cache it,
385
+			if (empty($this->cipher_methods)) {
386
+				$this->cipher_methods = openssl_get_cipher_methods();
387
+				// then grab the first item from the list
388
+				$cipher_method = reset($this->cipher_methods);
389
+			}
390
+			if ($cipher_method === false) {
391
+				throw new RuntimeException(
392
+					esc_html__(
393
+						'OpenSSL support appears to be enabled on the server, but no cipher methods are available. Please contact the server administrator.',
394
+						'event_espresso'
395
+					)
396
+				);
397
+			}
398
+			// verify that the next cipher method works
399
+			return $this->getAvailableCipherMethod($cipher_method);
400
+		}
401
+		// if we've gotten this far, then we found an available cipher method that works
402
+		// so save that for next time
403
+		update_option(
404
+			EE_Encryption::OPENSSL_CIPHER_METHOD_OPTION_NAME,
405
+			$cipher_method
406
+		);
407
+		return $cipher_method;
408
+	}
409
+
410
+
411
+	/**
412
+	 * decrypts data that has been encrypted with PHP's openssl functions
413
+	 *
414
+	 * @param string $encrypted_text the text to be decrypted
415
+	 * @param string $cipher_method
416
+	 * @param string $encryption_key
417
+	 * @return string
418
+	 * @throws RuntimeException
419
+	 */
420
+	protected function openssl_decrypt(
421
+		$encrypted_text = '',
422
+		$cipher_method = EE_Encryption::OPENSSL_CIPHER_METHOD,
423
+		$encryption_key = ''
424
+	) {
425
+		// you give me nothing??? GET OUT !
426
+		if (empty($encrypted_text)) {
427
+			return $encrypted_text;
428
+		}
429
+		// decode
430
+		$encrypted_text = $this->valid_base_64($encrypted_text)
431
+			? $this->base64_url_decode($encrypted_text)
432
+			: $encrypted_text;
433
+		$encrypted_components = explode(
434
+			EE_Encryption::OPENSSL_IV_DELIMITER,
435
+			$encrypted_text,
436
+			2
437
+		);
438
+		// check that iv exists, and if not, maybe text was encoded using mcrypt?
439
+		if ($this->_use_mcrypt && ! isset($encrypted_components[1])) {
440
+			return $this->m_decrypt($encrypted_text);
441
+		}
442
+		// decrypt it
443
+		$decrypted_text = openssl_decrypt(
444
+			$encrypted_components[0],
445
+			$this->getCipherMethod($cipher_method),
446
+			$this->getDigestHashValue(EE_Encryption::OPENSSL_DIGEST_METHOD, $encryption_key),
447
+			0,
448
+			$encrypted_components[1]
449
+		);
450
+		$decrypted_text = trim($decrypted_text);
451
+		return $decrypted_text;
452
+	}
453
+
454
+
455
+	/**
456
+	 * Computes the digest hash value using the specified digest method.
457
+	 * If that digest method fails to produce a valid hash value,
458
+	 * then we'll grab the next digest method and recursively try again until something works.
459
+	 *
460
+	 * @param string $digest_method
461
+	 * @param string $encryption_key
462
+	 * @return string
463
+	 * @throws RuntimeException
464
+	 */
465
+	protected function getDigestHashValue($digest_method = EE_Encryption::OPENSSL_DIGEST_METHOD, $encryption_key = '')
466
+	{
467
+		$encryption_key = $encryption_key !== ''
468
+			? $encryption_key
469
+			: $this->get_encryption_key();
470
+		$digest_hash_value = openssl_digest($encryption_key, $digest_method);
471
+		if ($digest_hash_value === false) {
472
+			return $this->getDigestHashValue($this->getDigestMethod());
473
+		}
474
+		return $digest_hash_value;
475
+	}
476
+
477
+
478
+	/**
479
+	 * Returns the NEXT element in the $digest_methods array.
480
+	 * If the $digest_methods array is empty, then we populate it
481
+	 * with the available values returned from openssl_get_md_methods().
482
+	 *
483
+	 * @return string
484
+	 * @throws \RuntimeException
485
+	 */
486
+	protected function getDigestMethod()
487
+	{
488
+		$digest_method = prev($this->digest_methods);
489
+		if (empty($this->digest_methods)) {
490
+			$this->digest_methods = openssl_get_md_methods();
491
+			$digest_method = end($this->digest_methods);
492
+		}
493
+		if ($digest_method === false) {
494
+			throw new RuntimeException(
495
+				esc_html__(
496
+					'OpenSSL support appears to be enabled on the server, but no digest methods are available. Please contact the server administrator.',
497
+					'event_espresso'
498
+				)
499
+			);
500
+		}
501
+		return $digest_method;
502
+	}
503
+
504
+
505
+	/**
506
+	 * encrypts data for acme servers that didn't bother to install PHP mcrypt
507
+	 *
508
+	 * @see http://stackoverflow.com/questions/800922/how-to-encrypt-string-without-mcrypt-library-in-php
509
+	 * @param string $text_string the text to be decrypted
510
+	 * @return string
511
+	 */
512
+	protected function acme_encrypt($text_string = '')
513
+	{
514
+		// you give me nothing??? GET OUT !
515
+		if (empty($text_string)) {
516
+			return $text_string;
517
+		}
518
+		$key_bits = str_split(
519
+			str_pad(
520
+				'',
521
+				strlen($text_string),
522
+				$this->get_encryption_key(),
523
+				STR_PAD_RIGHT
524
+			)
525
+		);
526
+		$string_bits = str_split($text_string);
527
+		foreach ($string_bits as $k => $v) {
528
+			$temp = ord($v) + ord($key_bits[ $k ]);
529
+			$string_bits[ $k ] = chr($temp > 255 ? ($temp - 256) : $temp);
530
+		}
531
+		$encrypted_text = implode('', $string_bits);
532
+		$encrypted_text .= EE_Encryption::ACME_ENCRYPTION_FLAG;
533
+		return $this->_use_base64_encode
534
+			? base64_encode($encrypted_text)
535
+			: $encrypted_text;
536
+	}
537
+
538
+
539
+	/**
540
+	 * decrypts data for acme servers that didn't bother to install PHP mcrypt
541
+	 *
542
+	 * @see http://stackoverflow.com/questions/800922/how-to-encrypt-string-without-mcrypt-library-in-php
543
+	 * @param string $encrypted_text the text to be decrypted
544
+	 * @return string
545
+	 * @throws RuntimeException
546
+	 */
547
+	protected function acme_decrypt($encrypted_text = '')
548
+	{
549
+		// you give me nothing??? GET OUT !
550
+		if (empty($encrypted_text)) {
551
+			return $encrypted_text;
552
+		}
553
+		// decode the data ?
554
+		$encrypted_text = $this->valid_base_64($encrypted_text)
555
+			? $this->base64_url_decode($encrypted_text)
556
+			: $encrypted_text;
557
+		if ($this->_use_mcrypt
558
+			&& strpos($encrypted_text, EE_Encryption::ACME_ENCRYPTION_FLAG) === false
559
+		) {
560
+			return $this->m_decrypt($encrypted_text);
561
+		}
562
+		$encrypted_text = substr($encrypted_text, 0, -4);
563
+		$key_bits = str_split(
564
+			str_pad(
565
+				'',
566
+				strlen($encrypted_text),
567
+				$this->get_encryption_key(),
568
+				STR_PAD_RIGHT
569
+			)
570
+		);
571
+		$string_bits = str_split($encrypted_text);
572
+		foreach ($string_bits as $k => $v) {
573
+			$temp = ord($v) - ord($key_bits[ $k ]);
574
+			$string_bits[ $k ] = chr($temp < 0 ? ($temp + 256) : $temp);
575
+		}
576
+		return implode('', $string_bits);
577
+	}
578
+
579
+
580
+	/**
581
+	 * @see http://stackoverflow.com/questions/2556345/detect-base64-encoding-in-php#30231906
582
+	 * @param $string
583
+	 * @return bool
584
+	 */
585
+	protected function valid_base_64($string)
586
+	{
587
+		// ensure data is a string
588
+		if (! is_string($string) || ! $this->_use_base64_encode) {
589
+			return false;
590
+		}
591
+		$decoded = base64_decode($string, true);
592
+		// Check if there is no invalid character in string
593
+		if (! preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) {
594
+			return false;
595
+		}
596
+		// Decode the string in strict mode and send the response
597
+		if (! base64_decode($string, true)) {
598
+			return false;
599
+		}
600
+		// Encode and compare it to original one
601
+		return base64_encode($decoded) === $string;
602
+	}
603
+
604
+
605
+	/**
606
+	 * generate random string
607
+	 *
608
+	 * @see http://stackoverflow.com/questions/637278/what-is-the-best-way-to-generate-a-random-key-within-php
609
+	 * @param int $length number of characters for random string
610
+	 * @return string
611
+	 */
612
+	public function generate_random_string($length = 40)
613
+	{
614
+		$iterations = ceil($length / 40);
615
+		$random_string = '';
616
+		for ($i = 0; $i < $iterations; $i++) {
617
+			$random_string .= sha1(microtime(true) . mt_rand(10000, 90000));
618
+		}
619
+		$random_string = substr($random_string, 0, $length);
620
+		return $random_string;
621
+	}
622
+
623
+
624
+	/**
625
+	 * encrypts data using PHP's mcrypt functions
626
+	 *
627
+	 * @deprecated 4.9.39
628
+	 * @param string $text_string
629
+	 * @internal   param $string - the text to be encrypted
630
+	 * @return string
631
+	 * @throws RuntimeException
632
+	 */
633
+	protected function m_encrypt($text_string = '')
634
+	{
635
+		// you give me nothing??? GET OUT !
636
+		if (empty($text_string)) {
637
+			return $text_string;
638
+		}
639
+		// get the initialization vector size
640
+		$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
641
+		// initialization vector
642
+		$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
643
+		if ($iv === false) {
644
+			throw new RuntimeException(
645
+				esc_html__('Failed to generate mcrypt initialization vector.', 'event_espresso')
646
+			);
647
+		}
648
+		// encrypt it
649
+		$encrypted_text = mcrypt_encrypt(
650
+			MCRYPT_RIJNDAEL_256,
651
+			$this->get_encryption_key(),
652
+			$text_string,
653
+			MCRYPT_MODE_ECB,
654
+			$iv
655
+		);
656
+		// trim and maybe encode
657
+		return $this->_use_base64_encode
658
+			? trim(base64_encode($encrypted_text))
659
+			: trim($encrypted_text);
660
+	}
661
+
662
+
663
+	/**
664
+	 * decrypts data that has been encrypted with PHP's mcrypt functions
665
+	 *
666
+	 * @deprecated 4.9.39
667
+	 * @param string $encrypted_text the text to be decrypted
668
+	 * @return string
669
+	 * @throws RuntimeException
670
+	 */
671
+	protected function m_decrypt($encrypted_text = '')
672
+	{
673
+		// you give me nothing??? GET OUT !
674
+		if (empty($encrypted_text)) {
675
+			return $encrypted_text;
676
+		}
677
+		// decode
678
+		$encrypted_text = $this->valid_base_64($encrypted_text)
679
+			? $this->base64_url_decode($encrypted_text)
680
+			: $encrypted_text;
681
+		// get the initialization vector size
682
+		$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
683
+		$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
684
+		if ($iv === false) {
685
+			throw new RuntimeException(
686
+				esc_html__('Failed to generate mcrypt initialization vector.', 'event_espresso')
687
+			);
688
+		}
689
+		// decrypt it
690
+		$decrypted_text = mcrypt_decrypt(
691
+			MCRYPT_RIJNDAEL_256,
692
+			$this->get_encryption_key(),
693
+			$encrypted_text,
694
+			MCRYPT_MODE_ECB,
695
+			$iv
696
+		);
697
+		$decrypted_text = trim($decrypted_text);
698
+		return $decrypted_text;
699
+	}
700 700
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
      */
104 104
     protected function __construct()
105 105
     {
106
-        if (! defined('ESPRESSO_ENCRYPT')) {
106
+        if ( ! defined('ESPRESSO_ENCRYPT')) {
107 107
             define('ESPRESSO_ENCRYPT', true);
108 108
         }
109 109
         if (extension_loaded('openssl')) {
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
     public static function instance()
126 126
     {
127 127
         // check if class object is instantiated
128
-        if (! EE_Encryption::$_instance instanceof EE_Encryption) {
128
+        if ( ! EE_Encryption::$_instance instanceof EE_Encryption) {
129 129
             EE_Encryption::$_instance = new self();
130 130
         }
131 131
         return EE_Encryption::$_instance;
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
             $iv
333 333
         );
334 334
         // append the initialization vector
335
-        $encrypted_text .= EE_Encryption::OPENSSL_IV_DELIMITER . $iv;
335
+        $encrypted_text .= EE_Encryption::OPENSSL_IV_DELIMITER.$iv;
336 336
         // trim and maybe encode
337 337
         return $this->_use_base64_encode
338 338
             ? trim(base64_encode($encrypted_text))
@@ -525,8 +525,8 @@  discard block
 block discarded – undo
525 525
         );
526 526
         $string_bits = str_split($text_string);
527 527
         foreach ($string_bits as $k => $v) {
528
-            $temp = ord($v) + ord($key_bits[ $k ]);
529
-            $string_bits[ $k ] = chr($temp > 255 ? ($temp - 256) : $temp);
528
+            $temp = ord($v) + ord($key_bits[$k]);
529
+            $string_bits[$k] = chr($temp > 255 ? ($temp - 256) : $temp);
530 530
         }
531 531
         $encrypted_text = implode('', $string_bits);
532 532
         $encrypted_text .= EE_Encryption::ACME_ENCRYPTION_FLAG;
@@ -570,8 +570,8 @@  discard block
 block discarded – undo
570 570
         );
571 571
         $string_bits = str_split($encrypted_text);
572 572
         foreach ($string_bits as $k => $v) {
573
-            $temp = ord($v) - ord($key_bits[ $k ]);
574
-            $string_bits[ $k ] = chr($temp < 0 ? ($temp + 256) : $temp);
573
+            $temp = ord($v) - ord($key_bits[$k]);
574
+            $string_bits[$k] = chr($temp < 0 ? ($temp + 256) : $temp);
575 575
         }
576 576
         return implode('', $string_bits);
577 577
     }
@@ -585,16 +585,16 @@  discard block
 block discarded – undo
585 585
     protected function valid_base_64($string)
586 586
     {
587 587
         // ensure data is a string
588
-        if (! is_string($string) || ! $this->_use_base64_encode) {
588
+        if ( ! is_string($string) || ! $this->_use_base64_encode) {
589 589
             return false;
590 590
         }
591 591
         $decoded = base64_decode($string, true);
592 592
         // Check if there is no invalid character in string
593
-        if (! preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) {
593
+        if ( ! preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) {
594 594
             return false;
595 595
         }
596 596
         // Decode the string in strict mode and send the response
597
-        if (! base64_decode($string, true)) {
597
+        if ( ! base64_decode($string, true)) {
598 598
             return false;
599 599
         }
600 600
         // Encode and compare it to original one
@@ -614,7 +614,7 @@  discard block
 block discarded – undo
614 614
         $iterations = ceil($length / 40);
615 615
         $random_string = '';
616 616
         for ($i = 0; $i < $iterations; $i++) {
617
-            $random_string .= sha1(microtime(true) . mt_rand(10000, 90000));
617
+            $random_string .= sha1(microtime(true).mt_rand(10000, 90000));
618 618
         }
619 619
         $random_string = substr($random_string, 0, $length);
620 620
         return $random_string;
Please login to merge, or discard this patch.
core/libraries/form_sections/form_handlers/SequentialStepFormManager.php 4 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -203,7 +203,7 @@  discard block
 block discarded – undo
203 203
 
204 204
 
205 205
     /**
206
-     * @param $default_form_step
206
+     * @param string $default_form_step
207 207
      * @throws InvalidDataTypeException
208 208
      */
209 209
     protected function setDefaultFormStep($default_form_step)
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
 
243 243
 
244 244
     /**
245
-     * @return object|SequentialStepFormInterface
245
+     * @return SequentialStepForm
246 246
      * @throws InvalidFormHandlerException
247 247
      */
248 248
     public function getCurrentStep()
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
      */
142 142
     protected function setBaseUrl($base_url)
143 143
     {
144
-        if (! is_string($base_url)) {
144
+        if ( ! is_string($base_url)) {
145 145
             throw new InvalidDataTypeException('$base_url', $base_url, 'string');
146 146
         }
147 147
         if (empty($base_url)) {
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
      */
173 173
     public function setFormStepUrlKey($form_step_url_key = 'ee-form-step')
174 174
     {
175
-        if (! is_string($form_step_url_key)) {
175
+        if ( ! is_string($form_step_url_key)) {
176 176
             throw new InvalidDataTypeException('$form_step_key', $form_step_url_key, 'string');
177 177
         }
178 178
         $this->form_step_url_key = ! empty($form_step_url_key) ? $form_step_url_key : 'ee-form-step';
@@ -194,7 +194,7 @@  discard block
 block discarded – undo
194 194
      */
195 195
     protected function setDefaultFormStep($default_form_step)
196 196
     {
197
-        if (! is_string($default_form_step)) {
197
+        if ( ! is_string($default_form_step)) {
198 198
             throw new InvalidDataTypeException('$default_form_step', $default_form_step, 'string');
199 199
         }
200 200
         $this->default_form_step = $default_form_step;
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
     protected function setCurrentStepFromRequest()
210 210
     {
211 211
         $current_step_slug = $this->request()->get($this->formStepUrlKey(), $this->defaultFormStep());
212
-        if (! $this->form_steps->setCurrent($current_step_slug)) {
212
+        if ( ! $this->form_steps->setCurrent($current_step_slug)) {
213 213
             throw new InvalidIdentifierException(
214 214
                 $current_step_slug,
215 215
                 $this->defaultFormStep(),
@@ -231,7 +231,7 @@  discard block
 block discarded – undo
231 231
      */
232 232
     public function getCurrentStep()
233 233
     {
234
-        if (! $this->form_steps->current() instanceof SequentialStepForm) {
234
+        if ( ! $this->form_steps->current() instanceof SequentialStepForm) {
235 235
             throw new InvalidFormHandlerException($this->form_steps->current());
236 236
         }
237 237
         return $this->form_steps->current();
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
      */
245 245
     public function formAction()
246 246
     {
247
-        if (! is_string($this->form_action) || empty($this->form_action)) {
247
+        if ( ! is_string($this->form_action) || empty($this->form_action)) {
248 248
             $this->form_action = $this->baseUrl();
249 249
         }
250 250
         return $this->form_action;
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
      */
258 258
     public function setFormAction($form_action)
259 259
     {
260
-        if (! is_string($form_action)) {
260
+        if ( ! is_string($form_action)) {
261 261
             throw new InvalidDataTypeException('$form_action', $form_action, 'string');
262 262
         }
263 263
         $this->form_action = $form_action;
@@ -271,7 +271,7 @@  discard block
 block discarded – undo
271 271
      */
272 272
     public function addFormActionArgs($form_action_args = array())
273 273
     {
274
-        if (! is_array($form_action_args)) {
274
+        if ( ! is_array($form_action_args)) {
275 275
             throw new InvalidDataTypeException('$form_action_args', $form_action_args, 'array');
276 276
         }
277 277
         $form_action_args = ! empty($form_action_args)
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
     protected function getProgressStepsCollection()
337 337
     {
338 338
         static $collection = null;
339
-        if (! $collection instanceof ProgressStepCollection) {
339
+        if ( ! $collection instanceof ProgressStepCollection) {
340 340
             $collection = new ProgressStepCollection();
341 341
         }
342 342
         return $collection;
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
         /** @var SequentialStepForm $form_step */
359 359
         foreach ($this->form_steps as $form_step) {
360 360
             // is this step active ?
361
-            if (! $form_step->initialize()) {
361
+            if ( ! $form_step->initialize()) {
362 362
                 continue;
363 363
             }
364 364
             $progress_steps_collection->add(
@@ -427,7 +427,7 @@  discard block
 block discarded – undo
427 427
     {
428 428
         $form_step = $this->buildCurrentStepForm();
429 429
         // no displayable content ? then skip straight to processing
430
-        if (! $form_step->displayable()) {
430
+        if ( ! $form_step->displayable()) {
431 431
             $this->addFormActionArgs();
432 432
             $form_step->setFormAction($this->formAction());
433 433
             wp_safe_redirect($form_step->formAction());
@@ -503,7 +503,7 @@  discard block
 block discarded – undo
503 503
     public function displayProgressSteps($return_as_string = true)
504 504
     {
505 505
         $form_step = $this->getCurrentStep();
506
-        if (! $form_step->displayable()) {
506
+        if ( ! $form_step->displayable()) {
507 507
             return '';
508 508
         }
509 509
         $progress_steps = apply_filters(
Please login to merge, or discard this patch.
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -4,7 +4,6 @@
 block discarded – undo
4 4
 
5 5
 use EE_Error;
6 6
 use EE_Request;
7
-use EventEspresso\core\exceptions\ExceptionStackTraceDisplay;
8 7
 use EventEspresso\core\exceptions\InvalidClassException;
9 8
 use EventEspresso\core\exceptions\InvalidDataTypeException;
10 9
 use EventEspresso\core\exceptions\InvalidEntityException;
Please login to merge, or discard this patch.
Indentation   +580 added lines, -580 removed lines patch added patch discarded remove patch
@@ -29,584 +29,584 @@
 block discarded – undo
29 29
 abstract class SequentialStepFormManager
30 30
 {
31 31
 
32
-    /**
33
-     * a simplified URL with no form related parameters
34
-     * that will be used to build the form's redirect URLs
35
-     *
36
-     * @var string $base_url
37
-     */
38
-    private $base_url = '';
39
-
40
-    /**
41
-     * the key used for the URL param that denotes the current form step
42
-     * defaults to 'ee-form-step'
43
-     *
44
-     * @var string $form_step_url_key
45
-     */
46
-    private $form_step_url_key = '';
47
-
48
-    /**
49
-     * @var string $default_form_step
50
-     */
51
-    private $default_form_step = '';
52
-
53
-    /**
54
-     * @var string $form_action
55
-     */
56
-    private $form_action;
57
-
58
-    /**
59
-     * value of one of the string constant above
60
-     *
61
-     * @var string $form_config
62
-     */
63
-    private $form_config;
64
-
65
-    /**
66
-     * @var string $progress_step_style
67
-     */
68
-    private $progress_step_style = '';
69
-
70
-    /**
71
-     * @var EE_Request $request
72
-     */
73
-    private $request;
74
-
75
-    /**
76
-     * @var Collection $form_steps
77
-     */
78
-    protected $form_steps;
79
-
80
-    /**
81
-     * @var ProgressStepManager $progress_step_manager
82
-     */
83
-    protected $progress_step_manager;
84
-
85
-
86
-    /**
87
-     * @return Collection|null
88
-     */
89
-    abstract protected function getFormStepsCollection();
90
-
91
-    // phpcs:disable PEAR.Functions.ValidDefaultValue.NotAtEnd
92
-    /**
93
-     * StepsManager constructor
94
-     *
95
-     * @param string     $base_url
96
-     * @param string     $default_form_step
97
-     * @param string     $form_action
98
-     * @param string     $form_config
99
-     * @param EE_Request $request
100
-     * @param string     $progress_step_style
101
-     * @throws InvalidDataTypeException
102
-     * @throws InvalidArgumentException
103
-     */
104
-    public function __construct(
105
-        $base_url,
106
-        $default_form_step,
107
-        $form_action = '',
108
-        $form_config = FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
109
-        $progress_step_style = 'number_bubbles',
110
-        EE_Request $request
111
-    ) {
112
-        $this->setBaseUrl($base_url);
113
-        $this->setDefaultFormStep($default_form_step);
114
-        $this->setFormAction($form_action);
115
-        $this->setFormConfig($form_config);
116
-        $this->setProgressStepStyle($progress_step_style);
117
-        $this->request = $request;
118
-    }
119
-
120
-
121
-    /**
122
-     * @return string
123
-     * @throws InvalidFormHandlerException
124
-     */
125
-    public function baseUrl()
126
-    {
127
-        if (strpos($this->base_url, $this->getCurrentStep()->slug()) === false) {
128
-            add_query_arg(
129
-                array($this->form_step_url_key => $this->getCurrentStep()->slug()),
130
-                $this->base_url
131
-            );
132
-        }
133
-        return $this->base_url;
134
-    }
135
-
136
-
137
-    /**
138
-     * @param string $base_url
139
-     * @throws InvalidDataTypeException
140
-     * @throws InvalidArgumentException
141
-     */
142
-    protected function setBaseUrl($base_url)
143
-    {
144
-        if (! is_string($base_url)) {
145
-            throw new InvalidDataTypeException('$base_url', $base_url, 'string');
146
-        }
147
-        if (empty($base_url)) {
148
-            throw new InvalidArgumentException(
149
-                esc_html__('The base URL can not be an empty string.', 'event_espresso')
150
-            );
151
-        }
152
-        $this->base_url = $base_url;
153
-    }
154
-
155
-
156
-    /**
157
-     * @return string
158
-     * @throws InvalidDataTypeException
159
-     */
160
-    public function formStepUrlKey()
161
-    {
162
-        if (empty($this->form_step_url_key)) {
163
-            $this->setFormStepUrlKey();
164
-        }
165
-        return $this->form_step_url_key;
166
-    }
167
-
168
-
169
-    /**
170
-     * @param string $form_step_url_key
171
-     * @throws InvalidDataTypeException
172
-     */
173
-    public function setFormStepUrlKey($form_step_url_key = 'ee-form-step')
174
-    {
175
-        if (! is_string($form_step_url_key)) {
176
-            throw new InvalidDataTypeException('$form_step_key', $form_step_url_key, 'string');
177
-        }
178
-        $this->form_step_url_key = ! empty($form_step_url_key) ? $form_step_url_key : 'ee-form-step';
179
-    }
180
-
181
-
182
-    /**
183
-     * @return string
184
-     */
185
-    public function defaultFormStep()
186
-    {
187
-        return $this->default_form_step;
188
-    }
189
-
190
-
191
-    /**
192
-     * @param $default_form_step
193
-     * @throws InvalidDataTypeException
194
-     */
195
-    protected function setDefaultFormStep($default_form_step)
196
-    {
197
-        if (! is_string($default_form_step)) {
198
-            throw new InvalidDataTypeException('$default_form_step', $default_form_step, 'string');
199
-        }
200
-        $this->default_form_step = $default_form_step;
201
-    }
202
-
203
-
204
-    /**
205
-     * @return void
206
-     * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
207
-     * @throws InvalidDataTypeException
208
-     */
209
-    protected function setCurrentStepFromRequest()
210
-    {
211
-        $current_step_slug = $this->request()->get($this->formStepUrlKey(), $this->defaultFormStep());
212
-        if (! $this->form_steps->setCurrent($current_step_slug)) {
213
-            throw new InvalidIdentifierException(
214
-                $current_step_slug,
215
-                $this->defaultFormStep(),
216
-                $message = sprintf(
217
-                    esc_html__(
218
-                        'The "%1$s" form step could not be set.',
219
-                        'event_espresso'
220
-                    ),
221
-                    $current_step_slug
222
-                )
223
-            );
224
-        }
225
-    }
226
-
227
-
228
-    /**
229
-     * @return object|SequentialStepFormInterface
230
-     * @throws InvalidFormHandlerException
231
-     */
232
-    public function getCurrentStep()
233
-    {
234
-        if (! $this->form_steps->current() instanceof SequentialStepForm) {
235
-            throw new InvalidFormHandlerException($this->form_steps->current());
236
-        }
237
-        return $this->form_steps->current();
238
-    }
239
-
240
-
241
-    /**
242
-     * @return string
243
-     * @throws InvalidFormHandlerException
244
-     */
245
-    public function formAction()
246
-    {
247
-        if (! is_string($this->form_action) || empty($this->form_action)) {
248
-            $this->form_action = $this->baseUrl();
249
-        }
250
-        return $this->form_action;
251
-    }
252
-
253
-
254
-    /**
255
-     * @param string $form_action
256
-     * @throws InvalidDataTypeException
257
-     */
258
-    public function setFormAction($form_action)
259
-    {
260
-        if (! is_string($form_action)) {
261
-            throw new InvalidDataTypeException('$form_action', $form_action, 'string');
262
-        }
263
-        $this->form_action = $form_action;
264
-    }
265
-
266
-
267
-    /**
268
-     * @param array $form_action_args
269
-     * @throws InvalidDataTypeException
270
-     * @throws InvalidFormHandlerException
271
-     */
272
-    public function addFormActionArgs($form_action_args = array())
273
-    {
274
-        if (! is_array($form_action_args)) {
275
-            throw new InvalidDataTypeException('$form_action_args', $form_action_args, 'array');
276
-        }
277
-        $form_action_args = ! empty($form_action_args)
278
-            ? $form_action_args
279
-            : array($this->formStepUrlKey() => $this->form_steps->current()->slug());
280
-        $this->getCurrentStep()->setFormAction(
281
-            add_query_arg($form_action_args, $this->formAction())
282
-        );
283
-        $this->form_action = $this->getCurrentStep()->formAction();
284
-    }
285
-
286
-
287
-    /**
288
-     * @return string
289
-     */
290
-    public function formConfig()
291
-    {
292
-        return $this->form_config;
293
-    }
294
-
295
-
296
-    /**
297
-     * @param string $form_config
298
-     */
299
-    public function setFormConfig($form_config)
300
-    {
301
-        $this->form_config = $form_config;
302
-    }
303
-
304
-
305
-    /**
306
-     * @return string
307
-     */
308
-    public function progressStepStyle()
309
-    {
310
-        return $this->progress_step_style;
311
-    }
312
-
313
-
314
-    /**
315
-     * @param string $progress_step_style
316
-     */
317
-    public function setProgressStepStyle($progress_step_style)
318
-    {
319
-        $this->progress_step_style = $progress_step_style;
320
-    }
321
-
322
-
323
-    /**
324
-     * @return EE_Request
325
-     */
326
-    public function request()
327
-    {
328
-        return $this->request;
329
-    }
330
-
331
-
332
-    /**
333
-     * @return Collection|null
334
-     * @throws InvalidInterfaceException
335
-     */
336
-    protected function getProgressStepsCollection()
337
-    {
338
-        static $collection = null;
339
-        if (! $collection instanceof ProgressStepCollection) {
340
-            $collection = new ProgressStepCollection();
341
-        }
342
-        return $collection;
343
-    }
344
-
345
-
346
-    /**
347
-     * @param Collection $progress_steps_collection
348
-     * @return ProgressStepManager
349
-     * @throws InvalidInterfaceException
350
-     * @throws InvalidClassException
351
-     * @throws InvalidDataTypeException
352
-     * @throws InvalidEntityException
353
-     * @throws InvalidFormHandlerException
354
-     */
355
-    protected function generateProgressSteps(Collection $progress_steps_collection)
356
-    {
357
-        $current_step = $this->getCurrentStep();
358
-        /** @var SequentialStepForm $form_step */
359
-        foreach ($this->form_steps as $form_step) {
360
-            // is this step active ?
361
-            if (! $form_step->initialize()) {
362
-                continue;
363
-            }
364
-            $progress_steps_collection->add(
365
-                new ProgressStep(
366
-                    $form_step->order(),
367
-                    $form_step->slug(),
368
-                    $form_step->slug(),
369
-                    $form_step->formName()
370
-                ),
371
-                $form_step->slug()
372
-            );
373
-        }
374
-        // set collection pointer back to current step
375
-        $this->form_steps->setCurrentUsingObject($current_step);
376
-        return new ProgressStepManager(
377
-            $this->progressStepStyle(),
378
-            $this->defaultFormStep(),
379
-            $this->formStepUrlKey(),
380
-            $progress_steps_collection
381
-        );
382
-    }
383
-
384
-
385
-    /**
386
-     * @throws InvalidClassException
387
-     * @throws InvalidDataTypeException
388
-     * @throws InvalidEntityException
389
-     * @throws InvalidIdentifierException
390
-     * @throws InvalidInterfaceException
391
-     * @throws InvalidArgumentException
392
-     * @throws InvalidFormHandlerException
393
-     */
394
-    public function buildForm()
395
-    {
396
-        $this->buildCurrentStepFormForDisplay();
397
-    }
398
-
399
-
400
-    /**
401
-     * @param array $form_data
402
-     * @throws InvalidArgumentException
403
-     * @throws InvalidClassException
404
-     * @throws InvalidDataTypeException
405
-     * @throws InvalidEntityException
406
-     * @throws InvalidFormHandlerException
407
-     * @throws InvalidIdentifierException
408
-     * @throws InvalidInterfaceException
409
-     */
410
-    public function processForm($form_data = array())
411
-    {
412
-        $this->buildCurrentStepFormForProcessing();
413
-        $this->processCurrentStepForm($form_data);
414
-    }
415
-
416
-
417
-    /**
418
-     * @throws InvalidClassException
419
-     * @throws InvalidDataTypeException
420
-     * @throws InvalidEntityException
421
-     * @throws InvalidInterfaceException
422
-     * @throws InvalidIdentifierException
423
-     * @throws InvalidArgumentException
424
-     * @throws InvalidFormHandlerException
425
-     */
426
-    public function buildCurrentStepFormForDisplay()
427
-    {
428
-        $form_step = $this->buildCurrentStepForm();
429
-        // no displayable content ? then skip straight to processing
430
-        if (! $form_step->displayable()) {
431
-            $this->addFormActionArgs();
432
-            $form_step->setFormAction($this->formAction());
433
-            wp_safe_redirect($form_step->formAction());
434
-        }
435
-    }
436
-
437
-
438
-    /**
439
-     * @throws InvalidClassException
440
-     * @throws InvalidDataTypeException
441
-     * @throws InvalidEntityException
442
-     * @throws InvalidInterfaceException
443
-     * @throws InvalidIdentifierException
444
-     * @throws InvalidArgumentException
445
-     * @throws InvalidFormHandlerException
446
-     */
447
-    public function buildCurrentStepFormForProcessing()
448
-    {
449
-        $this->buildCurrentStepForm(false);
450
-    }
451
-
452
-
453
-    /**
454
-     * @param bool $for_display
455
-     * @return SequentialStepFormInterface
456
-     * @throws InvalidArgumentException
457
-     * @throws InvalidClassException
458
-     * @throws InvalidDataTypeException
459
-     * @throws InvalidEntityException
460
-     * @throws InvalidFormHandlerException
461
-     * @throws InvalidIdentifierException
462
-     * @throws InvalidInterfaceException
463
-     */
464
-    private function buildCurrentStepForm($for_display = true)
465
-    {
466
-        $this->form_steps = $this->getFormStepsCollection();
467
-        $this->setCurrentStepFromRequest();
468
-        $form_step = $this->getCurrentStep();
469
-        if ($form_step->submitBtnText() === esc_html__('Submit', 'event_espresso')) {
470
-            $form_step->setSubmitBtnText(esc_html__('Next Step', 'event_espresso'));
471
-        }
472
-        if ($for_display && $form_step->displayable()) {
473
-            $this->progress_step_manager = $this->generateProgressSteps(
474
-                $this->getProgressStepsCollection()
475
-            );
476
-            $this->progress_step_manager->setCurrentStep(
477
-                $form_step->slug()
478
-            );
479
-            // mark all previous progress steps as completed
480
-            $this->progress_step_manager->setPreviousStepsCompleted();
481
-            $this->progress_step_manager->enqueueStylesAndScripts();
482
-            $this->addFormActionArgs();
483
-            $form_step->setFormAction($this->formAction());
484
-        } else {
485
-            $form_step->setRedirectUrl($this->baseUrl());
486
-            $form_step->addRedirectArgs(
487
-                array($this->formStepUrlKey() => $this->form_steps->current()->slug())
488
-            );
489
-        }
490
-        $form_step->generate();
491
-        if ($for_display) {
492
-            $form_step->enqueueStylesAndScripts();
493
-        }
494
-        return $form_step;
495
-    }
496
-
497
-
498
-    /**
499
-     * @param bool $return_as_string
500
-     * @return string
501
-     * @throws InvalidFormHandlerException
502
-     */
503
-    public function displayProgressSteps($return_as_string = true)
504
-    {
505
-        $form_step = $this->getCurrentStep();
506
-        if (! $form_step->displayable()) {
507
-            return '';
508
-        }
509
-        $progress_steps = apply_filters(
510
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_SequentialStepFormManager__displayProgressSteps__before_steps',
511
-            ''
512
-        );
513
-        $progress_steps .= $this->progress_step_manager->displaySteps();
514
-        $progress_steps .= apply_filters(
515
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_SequentialStepFormManager__displayProgressSteps__after_steps',
516
-            ''
517
-        );
518
-        if ($return_as_string) {
519
-            return $progress_steps;
520
-        }
521
-        echo $progress_steps;
522
-        return '';
523
-    }
524
-
525
-
526
-    /**
527
-     * @param bool $return_as_string
528
-     * @return string
529
-     * @throws InvalidFormHandlerException
530
-     */
531
-    public function displayCurrentStepForm($return_as_string = true)
532
-    {
533
-        if ($return_as_string) {
534
-            return $this->getCurrentStep()->display();
535
-        }
536
-        echo $this->getCurrentStep()->display();
537
-        return '';
538
-    }
539
-
540
-
541
-    /**
542
-     * @param array $form_data
543
-     * @return void
544
-     * @throws InvalidArgumentException
545
-     * @throws InvalidDataTypeException
546
-     * @throws InvalidFormHandlerException
547
-     */
548
-    public function processCurrentStepForm($form_data = array())
549
-    {
550
-        // grab instance of current step because after calling next() below,
551
-        // any calls to getCurrentStep() will return the "next" step because we advanced
552
-        $current_step = $this->getCurrentStep();
553
-        try {
554
-            // form processing should either throw exceptions or return true
555
-            $current_step->process($form_data);
556
-        } catch (Exception $e) {
557
-            // something went wrong, convert the Exception to an EE_Error
558
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
559
-            // prevent redirect to next step or other if exception was thrown
560
-            if ($current_step->redirectTo() === SequentialStepForm::REDIRECT_TO_NEXT_STEP
561
-                || $current_step->redirectTo() === SequentialStepForm::REDIRECT_TO_OTHER
562
-            ) {
563
-                $current_step->setRedirectTo(SequentialStepForm::REDIRECT_TO_CURRENT_STEP);
564
-            }
565
-        }
566
-        // save notices to a transient so that when we redirect back
567
-        // to the display portion for this step
568
-        // those notices can be displayed
569
-        EE_Error::get_notices(false, true);
570
-        $this->redirectForm($current_step);
571
-    }
572
-
573
-
574
-    /**
575
-     * handles where to go to next
576
-     *
577
-     * @param SequentialStepFormInterface $current_step
578
-     * @throws InvalidArgumentException
579
-     * @throws InvalidDataTypeException
580
-     * @throws InvalidFormHandlerException
581
-     */
582
-    public function redirectForm(SequentialStepFormInterface $current_step)
583
-    {
584
-        $redirect_step = $current_step;
585
-        switch ($current_step->redirectTo()) {
586
-            case SequentialStepForm::REDIRECT_TO_OTHER:
587
-                // going somewhere else, so just check out now
588
-                wp_safe_redirect($redirect_step->redirectUrl());
589
-                exit();
590
-                break;
591
-            case SequentialStepForm::REDIRECT_TO_PREV_STEP:
592
-                $redirect_step = $this->form_steps->previous();
593
-                break;
594
-            case SequentialStepForm::REDIRECT_TO_NEXT_STEP:
595
-                $this->form_steps->next();
596
-                if ($this->form_steps->valid()) {
597
-                    $redirect_step = $this->form_steps->current();
598
-                }
599
-                break;
600
-            case SequentialStepForm::REDIRECT_TO_CURRENT_STEP:
601
-            default:
602
-                // $redirect_step is already set
603
-        }
604
-        $current_step->setRedirectUrl($this->baseUrl());
605
-        $current_step->addRedirectArgs(
606
-            // use the slug for whatever step we are redirecting too
607
-            array($this->formStepUrlKey() => $redirect_step->slug())
608
-        );
609
-        wp_safe_redirect($current_step->redirectUrl());
610
-        exit();
611
-    }
32
+	/**
33
+	 * a simplified URL with no form related parameters
34
+	 * that will be used to build the form's redirect URLs
35
+	 *
36
+	 * @var string $base_url
37
+	 */
38
+	private $base_url = '';
39
+
40
+	/**
41
+	 * the key used for the URL param that denotes the current form step
42
+	 * defaults to 'ee-form-step'
43
+	 *
44
+	 * @var string $form_step_url_key
45
+	 */
46
+	private $form_step_url_key = '';
47
+
48
+	/**
49
+	 * @var string $default_form_step
50
+	 */
51
+	private $default_form_step = '';
52
+
53
+	/**
54
+	 * @var string $form_action
55
+	 */
56
+	private $form_action;
57
+
58
+	/**
59
+	 * value of one of the string constant above
60
+	 *
61
+	 * @var string $form_config
62
+	 */
63
+	private $form_config;
64
+
65
+	/**
66
+	 * @var string $progress_step_style
67
+	 */
68
+	private $progress_step_style = '';
69
+
70
+	/**
71
+	 * @var EE_Request $request
72
+	 */
73
+	private $request;
74
+
75
+	/**
76
+	 * @var Collection $form_steps
77
+	 */
78
+	protected $form_steps;
79
+
80
+	/**
81
+	 * @var ProgressStepManager $progress_step_manager
82
+	 */
83
+	protected $progress_step_manager;
84
+
85
+
86
+	/**
87
+	 * @return Collection|null
88
+	 */
89
+	abstract protected function getFormStepsCollection();
90
+
91
+	// phpcs:disable PEAR.Functions.ValidDefaultValue.NotAtEnd
92
+	/**
93
+	 * StepsManager constructor
94
+	 *
95
+	 * @param string     $base_url
96
+	 * @param string     $default_form_step
97
+	 * @param string     $form_action
98
+	 * @param string     $form_config
99
+	 * @param EE_Request $request
100
+	 * @param string     $progress_step_style
101
+	 * @throws InvalidDataTypeException
102
+	 * @throws InvalidArgumentException
103
+	 */
104
+	public function __construct(
105
+		$base_url,
106
+		$default_form_step,
107
+		$form_action = '',
108
+		$form_config = FormHandler::ADD_FORM_TAGS_AND_SUBMIT,
109
+		$progress_step_style = 'number_bubbles',
110
+		EE_Request $request
111
+	) {
112
+		$this->setBaseUrl($base_url);
113
+		$this->setDefaultFormStep($default_form_step);
114
+		$this->setFormAction($form_action);
115
+		$this->setFormConfig($form_config);
116
+		$this->setProgressStepStyle($progress_step_style);
117
+		$this->request = $request;
118
+	}
119
+
120
+
121
+	/**
122
+	 * @return string
123
+	 * @throws InvalidFormHandlerException
124
+	 */
125
+	public function baseUrl()
126
+	{
127
+		if (strpos($this->base_url, $this->getCurrentStep()->slug()) === false) {
128
+			add_query_arg(
129
+				array($this->form_step_url_key => $this->getCurrentStep()->slug()),
130
+				$this->base_url
131
+			);
132
+		}
133
+		return $this->base_url;
134
+	}
135
+
136
+
137
+	/**
138
+	 * @param string $base_url
139
+	 * @throws InvalidDataTypeException
140
+	 * @throws InvalidArgumentException
141
+	 */
142
+	protected function setBaseUrl($base_url)
143
+	{
144
+		if (! is_string($base_url)) {
145
+			throw new InvalidDataTypeException('$base_url', $base_url, 'string');
146
+		}
147
+		if (empty($base_url)) {
148
+			throw new InvalidArgumentException(
149
+				esc_html__('The base URL can not be an empty string.', 'event_espresso')
150
+			);
151
+		}
152
+		$this->base_url = $base_url;
153
+	}
154
+
155
+
156
+	/**
157
+	 * @return string
158
+	 * @throws InvalidDataTypeException
159
+	 */
160
+	public function formStepUrlKey()
161
+	{
162
+		if (empty($this->form_step_url_key)) {
163
+			$this->setFormStepUrlKey();
164
+		}
165
+		return $this->form_step_url_key;
166
+	}
167
+
168
+
169
+	/**
170
+	 * @param string $form_step_url_key
171
+	 * @throws InvalidDataTypeException
172
+	 */
173
+	public function setFormStepUrlKey($form_step_url_key = 'ee-form-step')
174
+	{
175
+		if (! is_string($form_step_url_key)) {
176
+			throw new InvalidDataTypeException('$form_step_key', $form_step_url_key, 'string');
177
+		}
178
+		$this->form_step_url_key = ! empty($form_step_url_key) ? $form_step_url_key : 'ee-form-step';
179
+	}
180
+
181
+
182
+	/**
183
+	 * @return string
184
+	 */
185
+	public function defaultFormStep()
186
+	{
187
+		return $this->default_form_step;
188
+	}
189
+
190
+
191
+	/**
192
+	 * @param $default_form_step
193
+	 * @throws InvalidDataTypeException
194
+	 */
195
+	protected function setDefaultFormStep($default_form_step)
196
+	{
197
+		if (! is_string($default_form_step)) {
198
+			throw new InvalidDataTypeException('$default_form_step', $default_form_step, 'string');
199
+		}
200
+		$this->default_form_step = $default_form_step;
201
+	}
202
+
203
+
204
+	/**
205
+	 * @return void
206
+	 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
207
+	 * @throws InvalidDataTypeException
208
+	 */
209
+	protected function setCurrentStepFromRequest()
210
+	{
211
+		$current_step_slug = $this->request()->get($this->formStepUrlKey(), $this->defaultFormStep());
212
+		if (! $this->form_steps->setCurrent($current_step_slug)) {
213
+			throw new InvalidIdentifierException(
214
+				$current_step_slug,
215
+				$this->defaultFormStep(),
216
+				$message = sprintf(
217
+					esc_html__(
218
+						'The "%1$s" form step could not be set.',
219
+						'event_espresso'
220
+					),
221
+					$current_step_slug
222
+				)
223
+			);
224
+		}
225
+	}
226
+
227
+
228
+	/**
229
+	 * @return object|SequentialStepFormInterface
230
+	 * @throws InvalidFormHandlerException
231
+	 */
232
+	public function getCurrentStep()
233
+	{
234
+		if (! $this->form_steps->current() instanceof SequentialStepForm) {
235
+			throw new InvalidFormHandlerException($this->form_steps->current());
236
+		}
237
+		return $this->form_steps->current();
238
+	}
239
+
240
+
241
+	/**
242
+	 * @return string
243
+	 * @throws InvalidFormHandlerException
244
+	 */
245
+	public function formAction()
246
+	{
247
+		if (! is_string($this->form_action) || empty($this->form_action)) {
248
+			$this->form_action = $this->baseUrl();
249
+		}
250
+		return $this->form_action;
251
+	}
252
+
253
+
254
+	/**
255
+	 * @param string $form_action
256
+	 * @throws InvalidDataTypeException
257
+	 */
258
+	public function setFormAction($form_action)
259
+	{
260
+		if (! is_string($form_action)) {
261
+			throw new InvalidDataTypeException('$form_action', $form_action, 'string');
262
+		}
263
+		$this->form_action = $form_action;
264
+	}
265
+
266
+
267
+	/**
268
+	 * @param array $form_action_args
269
+	 * @throws InvalidDataTypeException
270
+	 * @throws InvalidFormHandlerException
271
+	 */
272
+	public function addFormActionArgs($form_action_args = array())
273
+	{
274
+		if (! is_array($form_action_args)) {
275
+			throw new InvalidDataTypeException('$form_action_args', $form_action_args, 'array');
276
+		}
277
+		$form_action_args = ! empty($form_action_args)
278
+			? $form_action_args
279
+			: array($this->formStepUrlKey() => $this->form_steps->current()->slug());
280
+		$this->getCurrentStep()->setFormAction(
281
+			add_query_arg($form_action_args, $this->formAction())
282
+		);
283
+		$this->form_action = $this->getCurrentStep()->formAction();
284
+	}
285
+
286
+
287
+	/**
288
+	 * @return string
289
+	 */
290
+	public function formConfig()
291
+	{
292
+		return $this->form_config;
293
+	}
294
+
295
+
296
+	/**
297
+	 * @param string $form_config
298
+	 */
299
+	public function setFormConfig($form_config)
300
+	{
301
+		$this->form_config = $form_config;
302
+	}
303
+
304
+
305
+	/**
306
+	 * @return string
307
+	 */
308
+	public function progressStepStyle()
309
+	{
310
+		return $this->progress_step_style;
311
+	}
312
+
313
+
314
+	/**
315
+	 * @param string $progress_step_style
316
+	 */
317
+	public function setProgressStepStyle($progress_step_style)
318
+	{
319
+		$this->progress_step_style = $progress_step_style;
320
+	}
321
+
322
+
323
+	/**
324
+	 * @return EE_Request
325
+	 */
326
+	public function request()
327
+	{
328
+		return $this->request;
329
+	}
330
+
331
+
332
+	/**
333
+	 * @return Collection|null
334
+	 * @throws InvalidInterfaceException
335
+	 */
336
+	protected function getProgressStepsCollection()
337
+	{
338
+		static $collection = null;
339
+		if (! $collection instanceof ProgressStepCollection) {
340
+			$collection = new ProgressStepCollection();
341
+		}
342
+		return $collection;
343
+	}
344
+
345
+
346
+	/**
347
+	 * @param Collection $progress_steps_collection
348
+	 * @return ProgressStepManager
349
+	 * @throws InvalidInterfaceException
350
+	 * @throws InvalidClassException
351
+	 * @throws InvalidDataTypeException
352
+	 * @throws InvalidEntityException
353
+	 * @throws InvalidFormHandlerException
354
+	 */
355
+	protected function generateProgressSteps(Collection $progress_steps_collection)
356
+	{
357
+		$current_step = $this->getCurrentStep();
358
+		/** @var SequentialStepForm $form_step */
359
+		foreach ($this->form_steps as $form_step) {
360
+			// is this step active ?
361
+			if (! $form_step->initialize()) {
362
+				continue;
363
+			}
364
+			$progress_steps_collection->add(
365
+				new ProgressStep(
366
+					$form_step->order(),
367
+					$form_step->slug(),
368
+					$form_step->slug(),
369
+					$form_step->formName()
370
+				),
371
+				$form_step->slug()
372
+			);
373
+		}
374
+		// set collection pointer back to current step
375
+		$this->form_steps->setCurrentUsingObject($current_step);
376
+		return new ProgressStepManager(
377
+			$this->progressStepStyle(),
378
+			$this->defaultFormStep(),
379
+			$this->formStepUrlKey(),
380
+			$progress_steps_collection
381
+		);
382
+	}
383
+
384
+
385
+	/**
386
+	 * @throws InvalidClassException
387
+	 * @throws InvalidDataTypeException
388
+	 * @throws InvalidEntityException
389
+	 * @throws InvalidIdentifierException
390
+	 * @throws InvalidInterfaceException
391
+	 * @throws InvalidArgumentException
392
+	 * @throws InvalidFormHandlerException
393
+	 */
394
+	public function buildForm()
395
+	{
396
+		$this->buildCurrentStepFormForDisplay();
397
+	}
398
+
399
+
400
+	/**
401
+	 * @param array $form_data
402
+	 * @throws InvalidArgumentException
403
+	 * @throws InvalidClassException
404
+	 * @throws InvalidDataTypeException
405
+	 * @throws InvalidEntityException
406
+	 * @throws InvalidFormHandlerException
407
+	 * @throws InvalidIdentifierException
408
+	 * @throws InvalidInterfaceException
409
+	 */
410
+	public function processForm($form_data = array())
411
+	{
412
+		$this->buildCurrentStepFormForProcessing();
413
+		$this->processCurrentStepForm($form_data);
414
+	}
415
+
416
+
417
+	/**
418
+	 * @throws InvalidClassException
419
+	 * @throws InvalidDataTypeException
420
+	 * @throws InvalidEntityException
421
+	 * @throws InvalidInterfaceException
422
+	 * @throws InvalidIdentifierException
423
+	 * @throws InvalidArgumentException
424
+	 * @throws InvalidFormHandlerException
425
+	 */
426
+	public function buildCurrentStepFormForDisplay()
427
+	{
428
+		$form_step = $this->buildCurrentStepForm();
429
+		// no displayable content ? then skip straight to processing
430
+		if (! $form_step->displayable()) {
431
+			$this->addFormActionArgs();
432
+			$form_step->setFormAction($this->formAction());
433
+			wp_safe_redirect($form_step->formAction());
434
+		}
435
+	}
436
+
437
+
438
+	/**
439
+	 * @throws InvalidClassException
440
+	 * @throws InvalidDataTypeException
441
+	 * @throws InvalidEntityException
442
+	 * @throws InvalidInterfaceException
443
+	 * @throws InvalidIdentifierException
444
+	 * @throws InvalidArgumentException
445
+	 * @throws InvalidFormHandlerException
446
+	 */
447
+	public function buildCurrentStepFormForProcessing()
448
+	{
449
+		$this->buildCurrentStepForm(false);
450
+	}
451
+
452
+
453
+	/**
454
+	 * @param bool $for_display
455
+	 * @return SequentialStepFormInterface
456
+	 * @throws InvalidArgumentException
457
+	 * @throws InvalidClassException
458
+	 * @throws InvalidDataTypeException
459
+	 * @throws InvalidEntityException
460
+	 * @throws InvalidFormHandlerException
461
+	 * @throws InvalidIdentifierException
462
+	 * @throws InvalidInterfaceException
463
+	 */
464
+	private function buildCurrentStepForm($for_display = true)
465
+	{
466
+		$this->form_steps = $this->getFormStepsCollection();
467
+		$this->setCurrentStepFromRequest();
468
+		$form_step = $this->getCurrentStep();
469
+		if ($form_step->submitBtnText() === esc_html__('Submit', 'event_espresso')) {
470
+			$form_step->setSubmitBtnText(esc_html__('Next Step', 'event_espresso'));
471
+		}
472
+		if ($for_display && $form_step->displayable()) {
473
+			$this->progress_step_manager = $this->generateProgressSteps(
474
+				$this->getProgressStepsCollection()
475
+			);
476
+			$this->progress_step_manager->setCurrentStep(
477
+				$form_step->slug()
478
+			);
479
+			// mark all previous progress steps as completed
480
+			$this->progress_step_manager->setPreviousStepsCompleted();
481
+			$this->progress_step_manager->enqueueStylesAndScripts();
482
+			$this->addFormActionArgs();
483
+			$form_step->setFormAction($this->formAction());
484
+		} else {
485
+			$form_step->setRedirectUrl($this->baseUrl());
486
+			$form_step->addRedirectArgs(
487
+				array($this->formStepUrlKey() => $this->form_steps->current()->slug())
488
+			);
489
+		}
490
+		$form_step->generate();
491
+		if ($for_display) {
492
+			$form_step->enqueueStylesAndScripts();
493
+		}
494
+		return $form_step;
495
+	}
496
+
497
+
498
+	/**
499
+	 * @param bool $return_as_string
500
+	 * @return string
501
+	 * @throws InvalidFormHandlerException
502
+	 */
503
+	public function displayProgressSteps($return_as_string = true)
504
+	{
505
+		$form_step = $this->getCurrentStep();
506
+		if (! $form_step->displayable()) {
507
+			return '';
508
+		}
509
+		$progress_steps = apply_filters(
510
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_SequentialStepFormManager__displayProgressSteps__before_steps',
511
+			''
512
+		);
513
+		$progress_steps .= $this->progress_step_manager->displaySteps();
514
+		$progress_steps .= apply_filters(
515
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_SequentialStepFormManager__displayProgressSteps__after_steps',
516
+			''
517
+		);
518
+		if ($return_as_string) {
519
+			return $progress_steps;
520
+		}
521
+		echo $progress_steps;
522
+		return '';
523
+	}
524
+
525
+
526
+	/**
527
+	 * @param bool $return_as_string
528
+	 * @return string
529
+	 * @throws InvalidFormHandlerException
530
+	 */
531
+	public function displayCurrentStepForm($return_as_string = true)
532
+	{
533
+		if ($return_as_string) {
534
+			return $this->getCurrentStep()->display();
535
+		}
536
+		echo $this->getCurrentStep()->display();
537
+		return '';
538
+	}
539
+
540
+
541
+	/**
542
+	 * @param array $form_data
543
+	 * @return void
544
+	 * @throws InvalidArgumentException
545
+	 * @throws InvalidDataTypeException
546
+	 * @throws InvalidFormHandlerException
547
+	 */
548
+	public function processCurrentStepForm($form_data = array())
549
+	{
550
+		// grab instance of current step because after calling next() below,
551
+		// any calls to getCurrentStep() will return the "next" step because we advanced
552
+		$current_step = $this->getCurrentStep();
553
+		try {
554
+			// form processing should either throw exceptions or return true
555
+			$current_step->process($form_data);
556
+		} catch (Exception $e) {
557
+			// something went wrong, convert the Exception to an EE_Error
558
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
559
+			// prevent redirect to next step or other if exception was thrown
560
+			if ($current_step->redirectTo() === SequentialStepForm::REDIRECT_TO_NEXT_STEP
561
+				|| $current_step->redirectTo() === SequentialStepForm::REDIRECT_TO_OTHER
562
+			) {
563
+				$current_step->setRedirectTo(SequentialStepForm::REDIRECT_TO_CURRENT_STEP);
564
+			}
565
+		}
566
+		// save notices to a transient so that when we redirect back
567
+		// to the display portion for this step
568
+		// those notices can be displayed
569
+		EE_Error::get_notices(false, true);
570
+		$this->redirectForm($current_step);
571
+	}
572
+
573
+
574
+	/**
575
+	 * handles where to go to next
576
+	 *
577
+	 * @param SequentialStepFormInterface $current_step
578
+	 * @throws InvalidArgumentException
579
+	 * @throws InvalidDataTypeException
580
+	 * @throws InvalidFormHandlerException
581
+	 */
582
+	public function redirectForm(SequentialStepFormInterface $current_step)
583
+	{
584
+		$redirect_step = $current_step;
585
+		switch ($current_step->redirectTo()) {
586
+			case SequentialStepForm::REDIRECT_TO_OTHER:
587
+				// going somewhere else, so just check out now
588
+				wp_safe_redirect($redirect_step->redirectUrl());
589
+				exit();
590
+				break;
591
+			case SequentialStepForm::REDIRECT_TO_PREV_STEP:
592
+				$redirect_step = $this->form_steps->previous();
593
+				break;
594
+			case SequentialStepForm::REDIRECT_TO_NEXT_STEP:
595
+				$this->form_steps->next();
596
+				if ($this->form_steps->valid()) {
597
+					$redirect_step = $this->form_steps->current();
598
+				}
599
+				break;
600
+			case SequentialStepForm::REDIRECT_TO_CURRENT_STEP:
601
+			default:
602
+				// $redirect_step is already set
603
+		}
604
+		$current_step->setRedirectUrl($this->baseUrl());
605
+		$current_step->addRedirectArgs(
606
+			// use the slug for whatever step we are redirecting too
607
+			array($this->formStepUrlKey() => $redirect_step->slug())
608
+		);
609
+		wp_safe_redirect($current_step->redirectUrl());
610
+		exit();
611
+	}
612 612
 }
Please login to merge, or discard this patch.
acceptance_tests/Helpers/TicketSelector.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -15,7 +15,7 @@
 block discarded – undo
15 15
     /**
16 16
      * Use to select a quantity from the first ticket for the given event (so this can be used on a event archive page).
17 17
      * @param int|string $event_id
18
-     * @param int|string $quantity
18
+     * @param integer $quantity
19 19
      */
20 20
     public function selectQuantityOfFirstTicketForEventId($event_id, $quantity = 1)
21 21
     {
Please login to merge, or discard this patch.
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -12,23 +12,23 @@
 block discarded – undo
12 12
 trait TicketSelector
13 13
 {
14 14
 
15
-    /**
16
-     * Use to select a quantity from the first ticket for the given event (so this can be used on a event archive page).
17
-     * @param int|string $event_id
18
-     * @param int|string $quantity
19
-     */
20
-    public function selectQuantityOfFirstTicketForEventId($event_id, $quantity = 1)
21
-    {
22
-        $this->actor()->selectOption(TicketSelectorElements::ticketOptionByEventIdSelector($event_id), $quantity);
23
-    }
15
+	/**
16
+	 * Use to select a quantity from the first ticket for the given event (so this can be used on a event archive page).
17
+	 * @param int|string $event_id
18
+	 * @param int|string $quantity
19
+	 */
20
+	public function selectQuantityOfFirstTicketForEventId($event_id, $quantity = 1)
21
+	{
22
+		$this->actor()->selectOption(TicketSelectorElements::ticketOptionByEventIdSelector($event_id), $quantity);
23
+	}
24 24
 
25 25
 
26
-    /**
27
-     * Used to submit the ticket selection for the given event id (so this can be used on an event archive page).
28
-     * @param int|string $event_id
29
-     */
30
-    public function submitTicketSelectionsForEventId($event_id)
31
-    {
32
-        $this->actor()->click(TicketSelectorElements::ticketSelectionSubmitSelectorByEventId($event_id));
33
-    }
26
+	/**
27
+	 * Used to submit the ticket selection for the given event id (so this can be used on an event archive page).
28
+	 * @param int|string $event_id
29
+	 */
30
+	public function submitTicketSelectionsForEventId($event_id)
31
+	{
32
+		$this->actor()->click(TicketSelectorElements::ticketSelectionSubmitSelectorByEventId($event_id));
33
+	}
34 34
 }
35 35
\ No newline at end of file
Please login to merge, or discard this patch.
acceptance_tests/Page/MessagesAdmin.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -103,8 +103,8 @@
 block discarded – undo
103 103
     public static function editMessageTemplateClassByMessageType($message_type_slug, $context = '')
104 104
     {
105 105
         return $context
106
-            ? '.' . $message_type_slug . '-' . $context . '-edit-link'
107
-            : '.' . $message_type_slug . '-edit-link';
106
+            ? '.'.$message_type_slug.'-'.$context.'-edit-link'
107
+            : '.'.$message_type_slug.'-edit-link';
108 108
     }
109 109
 
110 110
 
Please login to merge, or discard this patch.
Indentation   +267 added lines, -267 removed lines patch added patch discarded remove patch
@@ -14,292 +14,292 @@
 block discarded – undo
14 14
 class MessagesAdmin extends CoreAdmin
15 15
 {
16 16
 
17
-    /**
18
-     * Context slug for the admin messages context.
19
-     */
20
-    const ADMIN_CONTEXT_SLUG = 'admin';
17
+	/**
18
+	 * Context slug for the admin messages context.
19
+	 */
20
+	const ADMIN_CONTEXT_SLUG = 'admin';
21 21
 
22
-    /**
23
-     * Context slug for the primary attendee messages context
24
-     */
25
-    const PRIMARY_ATTENDEE_CONTEXT_SLUG = 'primary_attendee';
22
+	/**
23
+	 * Context slug for the primary attendee messages context
24
+	 */
25
+	const PRIMARY_ATTENDEE_CONTEXT_SLUG = 'primary_attendee';
26 26
 
27 27
 
28
-    /**
29
-     * Context slug for the attendee messages context
30
-     */
31
-    const ATTENDEE_CONTEXT_SLUG = 'attendee';
28
+	/**
29
+	 * Context slug for the attendee messages context
30
+	 */
31
+	const ATTENDEE_CONTEXT_SLUG = 'attendee';
32 32
 
33 33
 
34
-    /**
35
-     * Status reference for the EEM_Message::status_sent status.
36
-     */
37
-    const MESSAGE_STATUS_SENT = 'MSN';
34
+	/**
35
+	 * Status reference for the EEM_Message::status_sent status.
36
+	 */
37
+	const MESSAGE_STATUS_SENT = 'MSN';
38 38
 
39 39
 
40
-    /**
41
-     * Message type slug for the Payment Failed message type
42
-     */
43
-    const PAYMENT_FAILED_MESSAGE_TYPE_SLUG = 'payment_failed';
40
+	/**
41
+	 * Message type slug for the Payment Failed message type
42
+	 */
43
+	const PAYMENT_FAILED_MESSAGE_TYPE_SLUG = 'payment_failed';
44 44
 
45 45
 
46
-    /**
47
-     * Message type slug for the Registration Pending Payment message type
48
-     */
49
-    const MESSAGE_TYPE_PENDING_PAYMENT = 'pending_approval';
46
+	/**
47
+	 * Message type slug for the Registration Pending Payment message type
48
+	 */
49
+	const MESSAGE_TYPE_PENDING_PAYMENT = 'pending_approval';
50 50
 
51 51
 
52
-    /**
53
-     * Selector for the Global Messages "Send on same request" field in the Messages Settings tab.
54
-     */
55
-    const GLOBAL_MESSAGES_SETTINGS_ON_REQUEST_SELECTION_SELECTOR =
56
-        '#global_messages_settings-do-messages-on-same-request';
52
+	/**
53
+	 * Selector for the Global Messages "Send on same request" field in the Messages Settings tab.
54
+	 */
55
+	const GLOBAL_MESSAGES_SETTINGS_ON_REQUEST_SELECTION_SELECTOR =
56
+		'#global_messages_settings-do-messages-on-same-request';
57 57
 
58 58
 
59
-    /**
60
-     * Selector for the Global Messages Settings submit button in the Messages Settings tab.
61
-     */
62
-    const GLOBAL_MESSAGES_SETTINGS_SUBMIT_SELECTOR = '#global_messages_settings-update-settings-submit';
59
+	/**
60
+	 * Selector for the Global Messages Settings submit button in the Messages Settings tab.
61
+	 */
62
+	const GLOBAL_MESSAGES_SETTINGS_SUBMIT_SELECTOR = '#global_messages_settings-update-settings-submit';
63 63
 
64 64
 
65
-    /**
66
-     * This is the container where active message types for a messenger are found/dragged to.
67
-     */
68
-    const MESSAGES_SETTINGS_ACTIVE_MESSAGE_TYPES_CONTAINER_SELECTOR = '#active-message-types';
65
+	/**
66
+	 * This is the container where active message types for a messenger are found/dragged to.
67
+	 */
68
+	const MESSAGES_SETTINGS_ACTIVE_MESSAGE_TYPES_CONTAINER_SELECTOR = '#active-message-types';
69 69
 
70 70
 
71
-    /**
72
-     * Locator for the context switcher selector on the Message Template Editor page.
73
-     */
74
-    const MESSAGES_CONTEXT_SWITCHER_SELECTOR = "//form[@id='ee-msg-context-switcher-frm']/select";
71
+	/**
72
+	 * Locator for the context switcher selector on the Message Template Editor page.
73
+	 */
74
+	const MESSAGES_CONTEXT_SWITCHER_SELECTOR = "//form[@id='ee-msg-context-switcher-frm']/select";
75 75
 
76 76
 
77
-    /**
78
-     * Locator for the context switcher submit button in the Message Template Editor page.
79
-     */
80
-    const MESSAGES_CONTEXT_SWITCHER_BUTTON_SELECTOR = "#submit-msg-context-switcher-sbmt";
77
+	/**
78
+	 * Locator for the context switcher submit button in the Message Template Editor page.
79
+	 */
80
+	const MESSAGES_CONTEXT_SWITCHER_BUTTON_SELECTOR = "#submit-msg-context-switcher-sbmt";
81 81
 
82 82
 
83
-    /**
84
-     * Locator for the dialog container used for housing viewed messages in the message activity list table.
85
-     */
86
-    const MESSAGES_LIST_TABLE_VIEW_MESSAGE_DIALOG_CONTAINER_SELECTOR = '.ee-admin-dialog-container-inner-content';
87
-
88
-
89
-    /**
90
-     * Returns the selector for the on/off toggle for context on the message template editor.
91
-     */
92
-    const MESSAGES_CONTEXT_ACTIVE_STATE_TOGGLE =
93
-        "//div[@class='activate_context_on_off_toggle_container']/div[@class='switch']/label";
94
-
95
-
96
-    const SELECTOR_LINK_FINALIZE_PAYMENT_PENDING_PAYMENT_MESSAGE = "//td/p[@class='callout']/a";
97
-
98
-
99
-
100
-    /**
101
-     * @param string $additional_params Any additional request parameters for the generated url should be included as
102
-     *                                  a string.
103
-     * @return string
104
-     */
105
-    public static function messageActivityListTableUrl($additional_params = '')
106
-    {
107
-        return self::adminUrl('espresso_messages', 'default', $additional_params);
108
-    }
109
-
110
-
111
-    /**
112
-     * @param string $additional_params Any additional request parameters for the generated url should be included as
113
-     *                                  a string.
114
-     * @return string
115
-     */
116
-    public static function defaultMessageTemplateListTableUrl($additional_params = '')
117
-    {
118
-        return self::adminUrl('espresso_messages', 'global_mtps', $additional_params);
119
-    }
120
-
121
-
122
-    /**
123
-     * @param string $additional_params Any additional request parameters for the generated url should be included as
124
-     *                                  a string.
125
-     * @return string
126
-     */
127
-    public static function customMessageTemplateListTableUrl($additional_params = '')
128
-    {
129
-        return self::adminUrl('espresso_messages', 'custom_mtps', $additional_params);
130
-    }
131
-
132
-
133
-    /**
134
-     * @return string
135
-     */
136
-    public static function messageSettingsUrl()
137
-    {
138
-        return self::adminUrl('espresso_messages', 'settings');
139
-    }
140
-
141
-
142
-
143
-    public static function draggableSettingsBoxSelectorForMessageTypeAndMessenger(
144
-        $message_type_slug,
145
-        $messenger_slug = 'email'
146
-    ) {
147
-        return "#$message_type_slug-messagetype-$messenger_slug";
148
-    }
149
-
150
-
151
-    /**
152
-     * @param string $message_type_slug
153
-     * @param string $context
154
-     * @return string
155
-     */
156
-    public static function editMessageTemplateClassByMessageType($message_type_slug, $context = '')
157
-    {
158
-        return $context
159
-            ? '.' . $message_type_slug . '-' . $context . '-edit-link'
160
-            : '.' . $message_type_slug . '-edit-link';
161
-    }
162
-
163
-
164
-    /**
165
-     * Selector for (a) specific table cell(s) in the Messages Activity list table for the given parameters.
166
-     *
167
-     * @param        $field
168
-     * @param        $message_type_label
169
-     * @param string $message_status
170
-     * @param string $messenger
171
-     * @param string $context
172
-     * @param string $table_cell_content_for_field
173
-     * @param int    $number_in_set   It's possible that the given parameters could match multiple items in the view.
174
-     *                                This allows you to indicate which item from the set to match.  If this is set to 0
175
-     *                                then all matches for the locator will be returned.
176
-     * @return string
177
-     * @throws \InvalidArgumentException
178
-     */
179
-    public static function messagesActivityListTableCellSelectorFor(
180
-        $field,
181
-        $message_type_label,
182
-        $message_status = self::MESSAGE_STATUS_SENT,
183
-        $messenger = 'Email',
184
-        $context = 'Event Admin',
185
-        $table_cell_content_for_field = '',
186
-        $number_in_set = 1
187
-    ) {
188
-        $selector = "//tbody[@id='the-list']";
189
-        $selector .= "//tr[contains(@class, 'msg-status-$message_status')]"
190
-                     . "//td[contains(@class, 'message_type') and text()='$message_type_label']";
191
-        if ($messenger) {
192
-            $selector .= "/ancestor::tr/td[contains(@class, 'messenger') and text()='$messenger']";
193
-        }
194
-        $selector .= "/ancestor::tr/td[contains(@class, 'column-context') and text()='$context']";
195
-        $selector .= $table_cell_content_for_field
196
-            ? "/ancestor::tr/td[contains(@class, 'column-$field') and text()='$table_cell_content_for_field']"
197
-            : "/ancestor::tr/td[contains(@class, 'column-$field')]";
198
-        return $number_in_set > 0 ? Locator::elementAt($selector, $number_in_set) : $selector;
199
-    }
200
-
201
-
202
-    /**
203
-     * Selector for the Create Custom button found in the message template list table.
204
-     * @param string $message_type_label
205
-     * @param string $messenger_label
206
-     * @return string
207
-     */
208
-    public static function createCustomButtonForMessageTypeAndMessenger($message_type_label, $messenger_label)
209
-    {
210
-        $selector = "//tr/td[contains(@class, 'message_type') and text()='$message_type_label']"
211
-                    . "//ancestor::tr/td[contains(@class, 'messenger') and contains(., '$messenger_label')]"
212
-                    . "//ancestor::tr/td/a[@class='button button-small']";
213
-        return $selector;
214
-    }
215
-
216
-
217
-    /**
218
-     * Note, this could potentially match multiple buttons in the view so the selector is intentionally restricted to
219
-     * the FIRST match (which will be the latest message sent if the table is default sorted).
220
-     *
221
-     * @param string $message_type_label    The visible message type label for the row you want to match
222
-     * @param string $message_status        The status of the message for the row you want to match.
223
-     * @param string $messenger             The visible messenger label for the row you want to match.
224
-     * @param string $context               The visible context label for the row you want to match.
225
-     * @param int    $number_in_set         It's possible that the given parameters could match multiple items in the
226
-     *                                      view. This allows you to indicate which item from the set to match.
227
-     * @return string
228
-     * @throws \InvalidArgumentException
229
-     */
230
-    public static function messagesActivityListTableViewButtonSelectorFor(
231
-        $message_type_label,
232
-        $message_status = self::MESSAGE_STATUS_SENT,
233
-        $messenger = 'Email',
234
-        $context = 'Event Admin',
235
-        $number_in_set = 1
236
-    ) {
237
-        $selector = self::messagesActivityListTableCellSelectorFor(
238
-            'action',
239
-            $message_type_label,
240
-            $message_status,
241
-            $messenger,
242
-            $context,
243
-            '',
244
-            $number_in_set
245
-        );
246
-        $selector .= "/a/span[contains(@class, 'ee-message-action-link-view')"
247
-                     . " and not(contains(@class, 'ee-message-action-link-view_transaction'))]";
248
-        return $selector;
249
-    }
250
-
251
-
252
-    /**
253
-     * Locator for the delete action link for a message item in the message activity list table.
254
-     * Note: The link is not visible by default, so the column would need hovered over for the link to appear.
255
-     *
256
-     * @param        $message_type_label
257
-     * @param string $message_status
258
-     * @param string $messenger
259
-     * @param string $context
260
-     * @param int    $number_in_set
261
-     * @return string
262
-     * @throws \InvalidArgumentException
263
-     */
264
-    public static function messagesActivityListTableDeleteActionSelectorFor(
265
-        $message_type_label,
266
-        $message_status = self::MESSAGE_STATUS_SENT,
267
-        $messenger = 'Email',
268
-        $context = 'Event Admin',
269
-        $number_in_set = 1
270
-    ) {
271
-        $selector = self::messagesActivityListTableCellSelectorFor(
272
-            'to',
273
-            $message_type_label,
274
-            $message_status,
275
-            $messenger,
276
-            $context,
277
-            '',
278
-            $number_in_set
279
-        );
280
-        $selector .= "/div/span[@class='delete']/a";
281
-        return $selector;
282
-    }
283
-
284
-
285
-
286
-    /**
287
-     * Returns the input selector for a given field in the message template editor.
288
-     * Assumes one is already viewing the Message Template Editor.
289
-     * @param string     $field
290
-     * @return string
291
-     */
292
-    public static function messageInputFieldSelectorFor($field)
293
-    {
294
-        return "//div[@id='post-body']//input[@id='$field-content']";
295
-    }
296
-
297
-
298
-    /**
299
-     * Wrapper for self::messageInputFieldSelectorFor('to') that takes care of getting the input for the To field.
300
-     */
301
-    public static function messageTemplateToFieldSelector()
302
-    {
303
-        return self::messageInputFieldSelectorFor('to');
304
-    }
83
+	/**
84
+	 * Locator for the dialog container used for housing viewed messages in the message activity list table.
85
+	 */
86
+	const MESSAGES_LIST_TABLE_VIEW_MESSAGE_DIALOG_CONTAINER_SELECTOR = '.ee-admin-dialog-container-inner-content';
87
+
88
+
89
+	/**
90
+	 * Returns the selector for the on/off toggle for context on the message template editor.
91
+	 */
92
+	const MESSAGES_CONTEXT_ACTIVE_STATE_TOGGLE =
93
+		"//div[@class='activate_context_on_off_toggle_container']/div[@class='switch']/label";
94
+
95
+
96
+	const SELECTOR_LINK_FINALIZE_PAYMENT_PENDING_PAYMENT_MESSAGE = "//td/p[@class='callout']/a";
97
+
98
+
99
+
100
+	/**
101
+	 * @param string $additional_params Any additional request parameters for the generated url should be included as
102
+	 *                                  a string.
103
+	 * @return string
104
+	 */
105
+	public static function messageActivityListTableUrl($additional_params = '')
106
+	{
107
+		return self::adminUrl('espresso_messages', 'default', $additional_params);
108
+	}
109
+
110
+
111
+	/**
112
+	 * @param string $additional_params Any additional request parameters for the generated url should be included as
113
+	 *                                  a string.
114
+	 * @return string
115
+	 */
116
+	public static function defaultMessageTemplateListTableUrl($additional_params = '')
117
+	{
118
+		return self::adminUrl('espresso_messages', 'global_mtps', $additional_params);
119
+	}
120
+
121
+
122
+	/**
123
+	 * @param string $additional_params Any additional request parameters for the generated url should be included as
124
+	 *                                  a string.
125
+	 * @return string
126
+	 */
127
+	public static function customMessageTemplateListTableUrl($additional_params = '')
128
+	{
129
+		return self::adminUrl('espresso_messages', 'custom_mtps', $additional_params);
130
+	}
131
+
132
+
133
+	/**
134
+	 * @return string
135
+	 */
136
+	public static function messageSettingsUrl()
137
+	{
138
+		return self::adminUrl('espresso_messages', 'settings');
139
+	}
140
+
141
+
142
+
143
+	public static function draggableSettingsBoxSelectorForMessageTypeAndMessenger(
144
+		$message_type_slug,
145
+		$messenger_slug = 'email'
146
+	) {
147
+		return "#$message_type_slug-messagetype-$messenger_slug";
148
+	}
149
+
150
+
151
+	/**
152
+	 * @param string $message_type_slug
153
+	 * @param string $context
154
+	 * @return string
155
+	 */
156
+	public static function editMessageTemplateClassByMessageType($message_type_slug, $context = '')
157
+	{
158
+		return $context
159
+			? '.' . $message_type_slug . '-' . $context . '-edit-link'
160
+			: '.' . $message_type_slug . '-edit-link';
161
+	}
162
+
163
+
164
+	/**
165
+	 * Selector for (a) specific table cell(s) in the Messages Activity list table for the given parameters.
166
+	 *
167
+	 * @param        $field
168
+	 * @param        $message_type_label
169
+	 * @param string $message_status
170
+	 * @param string $messenger
171
+	 * @param string $context
172
+	 * @param string $table_cell_content_for_field
173
+	 * @param int    $number_in_set   It's possible that the given parameters could match multiple items in the view.
174
+	 *                                This allows you to indicate which item from the set to match.  If this is set to 0
175
+	 *                                then all matches for the locator will be returned.
176
+	 * @return string
177
+	 * @throws \InvalidArgumentException
178
+	 */
179
+	public static function messagesActivityListTableCellSelectorFor(
180
+		$field,
181
+		$message_type_label,
182
+		$message_status = self::MESSAGE_STATUS_SENT,
183
+		$messenger = 'Email',
184
+		$context = 'Event Admin',
185
+		$table_cell_content_for_field = '',
186
+		$number_in_set = 1
187
+	) {
188
+		$selector = "//tbody[@id='the-list']";
189
+		$selector .= "//tr[contains(@class, 'msg-status-$message_status')]"
190
+					 . "//td[contains(@class, 'message_type') and text()='$message_type_label']";
191
+		if ($messenger) {
192
+			$selector .= "/ancestor::tr/td[contains(@class, 'messenger') and text()='$messenger']";
193
+		}
194
+		$selector .= "/ancestor::tr/td[contains(@class, 'column-context') and text()='$context']";
195
+		$selector .= $table_cell_content_for_field
196
+			? "/ancestor::tr/td[contains(@class, 'column-$field') and text()='$table_cell_content_for_field']"
197
+			: "/ancestor::tr/td[contains(@class, 'column-$field')]";
198
+		return $number_in_set > 0 ? Locator::elementAt($selector, $number_in_set) : $selector;
199
+	}
200
+
201
+
202
+	/**
203
+	 * Selector for the Create Custom button found in the message template list table.
204
+	 * @param string $message_type_label
205
+	 * @param string $messenger_label
206
+	 * @return string
207
+	 */
208
+	public static function createCustomButtonForMessageTypeAndMessenger($message_type_label, $messenger_label)
209
+	{
210
+		$selector = "//tr/td[contains(@class, 'message_type') and text()='$message_type_label']"
211
+					. "//ancestor::tr/td[contains(@class, 'messenger') and contains(., '$messenger_label')]"
212
+					. "//ancestor::tr/td/a[@class='button button-small']";
213
+		return $selector;
214
+	}
215
+
216
+
217
+	/**
218
+	 * Note, this could potentially match multiple buttons in the view so the selector is intentionally restricted to
219
+	 * the FIRST match (which will be the latest message sent if the table is default sorted).
220
+	 *
221
+	 * @param string $message_type_label    The visible message type label for the row you want to match
222
+	 * @param string $message_status        The status of the message for the row you want to match.
223
+	 * @param string $messenger             The visible messenger label for the row you want to match.
224
+	 * @param string $context               The visible context label for the row you want to match.
225
+	 * @param int    $number_in_set         It's possible that the given parameters could match multiple items in the
226
+	 *                                      view. This allows you to indicate which item from the set to match.
227
+	 * @return string
228
+	 * @throws \InvalidArgumentException
229
+	 */
230
+	public static function messagesActivityListTableViewButtonSelectorFor(
231
+		$message_type_label,
232
+		$message_status = self::MESSAGE_STATUS_SENT,
233
+		$messenger = 'Email',
234
+		$context = 'Event Admin',
235
+		$number_in_set = 1
236
+	) {
237
+		$selector = self::messagesActivityListTableCellSelectorFor(
238
+			'action',
239
+			$message_type_label,
240
+			$message_status,
241
+			$messenger,
242
+			$context,
243
+			'',
244
+			$number_in_set
245
+		);
246
+		$selector .= "/a/span[contains(@class, 'ee-message-action-link-view')"
247
+					 . " and not(contains(@class, 'ee-message-action-link-view_transaction'))]";
248
+		return $selector;
249
+	}
250
+
251
+
252
+	/**
253
+	 * Locator for the delete action link for a message item in the message activity list table.
254
+	 * Note: The link is not visible by default, so the column would need hovered over for the link to appear.
255
+	 *
256
+	 * @param        $message_type_label
257
+	 * @param string $message_status
258
+	 * @param string $messenger
259
+	 * @param string $context
260
+	 * @param int    $number_in_set
261
+	 * @return string
262
+	 * @throws \InvalidArgumentException
263
+	 */
264
+	public static function messagesActivityListTableDeleteActionSelectorFor(
265
+		$message_type_label,
266
+		$message_status = self::MESSAGE_STATUS_SENT,
267
+		$messenger = 'Email',
268
+		$context = 'Event Admin',
269
+		$number_in_set = 1
270
+	) {
271
+		$selector = self::messagesActivityListTableCellSelectorFor(
272
+			'to',
273
+			$message_type_label,
274
+			$message_status,
275
+			$messenger,
276
+			$context,
277
+			'',
278
+			$number_in_set
279
+		);
280
+		$selector .= "/div/span[@class='delete']/a";
281
+		return $selector;
282
+	}
283
+
284
+
285
+
286
+	/**
287
+	 * Returns the input selector for a given field in the message template editor.
288
+	 * Assumes one is already viewing the Message Template Editor.
289
+	 * @param string     $field
290
+	 * @return string
291
+	 */
292
+	public static function messageInputFieldSelectorFor($field)
293
+	{
294
+		return "//div[@id='post-body']//input[@id='$field-content']";
295
+	}
296
+
297
+
298
+	/**
299
+	 * Wrapper for self::messageInputFieldSelectorFor('to') that takes care of getting the input for the To field.
300
+	 */
301
+	public static function messageTemplateToFieldSelector()
302
+	{
303
+		return self::messageInputFieldSelectorFor('to');
304
+	}
305 305
 }
306 306
\ No newline at end of file
Please login to merge, or discard this patch.
core/db_models/EEM_Registration.model.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -467,7 +467,7 @@
 block discarded – undo
467 467
      * @param    int $ATT_ID
468 468
      * @param    int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the
469 469
      *                         attendee number is required
470
-     * @return        mixed        array on success, FALSE on fail
470
+     * @return        null|EE_Base_Class        array on success, FALSE on fail
471 471
      * @throws EE_Error
472 472
      */
473 473
     public function get_registration_for_transaction_attendee($TXN_ID = 0, $ATT_ID = 0, $att_nmbr = 0)
Please login to merge, or discard this patch.
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -1,5 +1,4 @@
 block discarded – undo
1 1
 <?php
2
-use EventEspresso\core\exceptions\InvalidIdentifierException;
3 2
 use EventEspresso\core\exceptions\InvalidStatusException;
4 3
 use EventEspresso\core\services\database\TableAnalysis;
5 4
 
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -369,14 +369,14 @@  discard block
 block discarded – undo
369 369
         // and the table hasn't actually been created, this could have an error
370 370
         /** @type WPDB $wpdb */
371 371
         global $wpdb;
372
-        if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) {
372
+        if ($this->_get_table_analysis()->tableExists($wpdb->prefix.'esp_status')) {
373 373
             $results = $wpdb->get_results(
374 374
                 "SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'"
375 375
             );
376 376
             self::$_reg_status = array();
377 377
             foreach ($results as $status) {
378
-                if (!in_array($status->STS_ID, $exclude, true)) {
379
-                    self::$_reg_status[ $status->STS_ID ] = $status->STS_code;
378
+                if ( ! in_array($status->STS_ID, $exclude, true)) {
379
+                    self::$_reg_status[$status->STS_ID] = $status->STS_code;
380 380
                 }
381 381
             }
382 382
         }
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
      */
434 434
     public function get_all_registrations_for_attendee($ATT_ID = 0)
435 435
     {
436
-        if (!$ATT_ID) {
436
+        if ( ! $ATT_ID) {
437 437
             return null;
438 438
         }
439 439
         return $this->get_all(array(array('ATT_ID' => $ATT_ID)));
@@ -450,7 +450,7 @@  discard block
 block discarded – undo
450 450
      */
451 451
     public function get_registration_for_reg_url_link($REG_url_link)
452 452
     {
453
-        if (!$REG_url_link) {
453
+        if ( ! $REG_url_link) {
454 454
             return null;
455 455
         }
456 456
         return $this->get_one(array(array('REG_url_link' => $REG_url_link)));
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
             'REG_date' => array('>=', $sql_date),
502 502
             'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
503 503
         );
504
-        if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
504
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
505 505
             $where['Event.EVT_wp_user'] = get_current_user_id();
506 506
         }
507 507
         $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date');
@@ -513,7 +513,7 @@  discard block
 block discarded – undo
513 513
             ),
514 514
             OBJECT,
515 515
             array(
516
-                'regDate' => array('DATE(' . $query_interval . ')', '%s'),
516
+                'regDate' => array('DATE('.$query_interval.')', '%s'),
517 517
                 'total' => array('count(REG_ID)', '%d'),
518 518
             )
519 519
         );
@@ -533,7 +533,7 @@  discard block
 block discarded – undo
533 533
     public function get_registrations_per_day_and_per_status_report($period = '-1 month')
534 534
     {
535 535
         global $wpdb;
536
-        $registration_table = $wpdb->prefix . 'esp_registration';
536
+        $registration_table = $wpdb->prefix.'esp_registration';
537 537
         $event_table = $wpdb->posts;
538 538
         $sql_date = date('Y-m-d H:i:s', strtotime($period));
539 539
         // prepare the query interval for displaying offset
@@ -542,9 +542,9 @@  discard block
 block discarded – undo
542 542
         $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} ";
543 543
         $inner_where = ' WHERE';
544 544
         // exclude events not authored by user if permissions in effect
545
-        if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
545
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
546 546
             $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
547
-            $inner_where .= ' post_author = ' . get_current_user_id() . ' AND';
547
+            $inner_where .= ' post_author = '.get_current_user_id().' AND';
548 548
         }
549 549
         $inner_where .= " REG_date >= '{$sql_date}'";
550 550
         $inner_date_query .= $inner_where;
@@ -567,7 +567,7 @@  discard block
 block discarded – undo
567 567
         // setup the joins
568 568
         $join .= implode(' LEFT JOIN ', $join_parts);
569 569
         // now let's put it all together
570
-        $query = $select . $join . ' GROUP BY Registration_REG_date';
570
+        $query = $select.$join.' GROUP BY Registration_REG_date';
571 571
         // and execute it
572 572
         return $wpdb->get_results($query, ARRAY_A);
573 573
     }
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
             'REG_date' => array('>=', $date_sql),
594 594
             'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
595 595
         );
596
-        if (!EE_Registry::instance()->CAP->current_user_can(
596
+        if ( ! EE_Registry::instance()->CAP->current_user_can(
597 597
             'ee_read_others_registrations',
598 598
             'reg_per_event_report'
599 599
         )
@@ -629,16 +629,16 @@  discard block
 block discarded – undo
629 629
     public function get_registrations_per_event_and_per_status_report($period = '-1 month')
630 630
     {
631 631
         global $wpdb;
632
-        $registration_table = $wpdb->prefix . 'esp_registration';
632
+        $registration_table = $wpdb->prefix.'esp_registration';
633 633
         $event_table = $wpdb->posts;
634 634
         $sql_date = date('Y-m-d H:i:s', strtotime($period));
635 635
         // inner date query
636 636
         $inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table ";
637 637
         $inner_where = ' WHERE';
638 638
         // exclude events not authored by user if permissions in effect
639
-        if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
639
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
640 640
             $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
641
-            $inner_where .= ' post_author = ' . get_current_user_id() . ' AND';
641
+            $inner_where .= ' post_author = '.get_current_user_id().' AND';
642 642
         }
643 643
         $inner_where .= " REG_date >= '{$sql_date}'";
644 644
         $inner_date_query .= $inner_where;
@@ -661,7 +661,7 @@  discard block
 block discarded – undo
661 661
         // setup remaining joins
662 662
         $join .= implode(' LEFT JOIN ', $join_parts);
663 663
         // now put it all together
664
-        $query = $select . $join . ' GROUP BY Registration_Event';
664
+        $query = $select.$join.' GROUP BY Registration_Event';
665 665
         // and execute
666 666
         return $wpdb->get_results($query, ARRAY_A);
667 667
     }
@@ -676,7 +676,7 @@  discard block
 block discarded – undo
676 676
      */
677 677
     public function get_primary_registration_for_transaction_ID($TXN_ID = 0)
678 678
     {
679
-        if (!$TXN_ID) {
679
+        if ( ! $TXN_ID) {
680 680
             return null;
681 681
         }
682 682
         return $this->get_one(array(
@@ -745,11 +745,11 @@  discard block
 block discarded – undo
745 745
         $query = $wpdb->prepare(
746 746
             'SELECT '
747 747
             . 'COUNT( DISTINCT checkins.REG_ID ) '
748
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
748
+            . 'FROM '.EEM_Checkin::instance()->table().' AS checkins INNER JOIN'
749 749
             . '( SELECT '
750 750
             . 'max( CHK_timestamp ) AS latest_checkin, '
751 751
             . 'REG_ID AS REG_ID '
752
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' '
752
+            . 'FROM '.EEM_Checkin::instance()->table().' '
753 753
             . 'WHERE DTT_ID=%d '
754 754
             . 'GROUP BY REG_ID'
755 755
             . ') AS most_recent_checkin_per_reg '
@@ -779,12 +779,12 @@  discard block
 block discarded – undo
779 779
         $query = $wpdb->prepare(
780 780
             'SELECT '
781 781
             . 'COUNT( DISTINCT checkins.REG_ID ) '
782
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
782
+            . 'FROM '.EEM_Checkin::instance()->table().' AS checkins INNER JOIN'
783 783
             . '( SELECT '
784 784
             . 'max( CHK_timestamp ) AS latest_checkin, '
785 785
             . 'REG_ID AS REG_ID '
786
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c '
787
-            . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d '
786
+            . 'FROM '.EEM_Checkin::instance()->table().' AS c '
787
+            . 'INNER JOIN '.EEM_Datetime::instance()->table().' AS d '
788 788
             . 'ON c.DTT_ID=d.DTT_ID '
789 789
             . 'WHERE d.EVT_ID=%d '
790 790
             . 'GROUP BY REG_ID'
@@ -813,7 +813,7 @@  discard block
 block discarded – undo
813 813
     {
814 814
         // first do a native wp_query to get the latest REG_ID's matching these attendees.
815 815
         global $wpdb;
816
-        $registration_table = $wpdb->prefix . 'esp_registration';
816
+        $registration_table = $wpdb->prefix.'esp_registration';
817 817
         $attendee_table = $wpdb->posts;
818 818
         $attendee_ids = is_array($attendee_ids)
819 819
             ? array_map('absint', $attendee_ids)
@@ -868,7 +868,7 @@  discard block
 block discarded – undo
868 868
     public function event_reg_count_for_statuses($EVT_ID, $statuses = array())
869 869
     {
870 870
         $EVT_ID = absint($EVT_ID);
871
-        if (! $EVT_ID) {
871
+        if ( ! $EVT_ID) {
872 872
             throw new InvalidArgumentException(
873 873
                 esc_html__('An invalid Event ID was supplied.', 'event_espresso')
874 874
             );
@@ -877,7 +877,7 @@  discard block
 block discarded – undo
877 877
         $statuses = ! empty($statuses) ? $statuses : array(EEM_Registration::status_id_approved);
878 878
         $valid_reg_statuses = EEM_Registration::reg_statuses();
879 879
         foreach ($statuses as $status) {
880
-            if (! in_array($status, $valid_reg_statuses, true)) {
880
+            if ( ! in_array($status, $valid_reg_statuses, true)) {
881 881
                 throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso'));
882 882
             }
883 883
         }
Please login to merge, or discard this patch.
Indentation   +866 added lines, -866 removed lines patch added patch discarded remove patch
@@ -13,815 +13,815 @@  discard block
 block discarded – undo
13 13
 class EEM_Registration extends EEM_Soft_Delete_Base
14 14
 {
15 15
 
16
-    /**
17
-     * @var EEM_Registration $_instance
18
-     */
19
-    protected static $_instance;
20
-
21
-    /**
22
-     * Keys are the status IDs for registrations (eg, RAP, RCN, etc), and the values
23
-     * are status codes (eg, approved, cancelled, etc)
24
-     *
25
-     * @var array
26
-     */
27
-    private static $_reg_status;
28
-
29
-    /**
30
-     * The value of REG_count for a primary registrant
31
-     */
32
-    const PRIMARY_REGISTRANT_COUNT = 1;
33
-
34
-    /**
35
-     * Status ID (STS_ID on esp_status table) to indicate an INCOMPLETE registration.
36
-     * Initial status for registrations when they are first created
37
-     * Payments are NOT allowed.
38
-     * Automatically toggled to whatever the default Event registration status is upon completion of the attendee
39
-     * information reg step NO space reserved. Registration is NOT active
40
-     */
41
-    const status_id_incomplete = 'RIC';
42
-
43
-    /**
44
-     * Status ID (STS_ID on esp_status table) to indicate an UNAPPROVED registration.
45
-     * Payments are NOT allowed.
46
-     * Event Admin must manually toggle STS_ID for it to change
47
-     * No space reserved.
48
-     * Registration is active
49
-     */
50
-    const status_id_not_approved = 'RNA';
51
-
52
-    /**
53
-     * Status ID (STS_ID on esp_status table) to indicate registration is PENDING_PAYMENT .
54
-     * Payments are allowed.
55
-     * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee
56
-     * No space reserved.
57
-     * Registration is active
58
-     */
59
-    const status_id_pending_payment = 'RPP';
60
-
61
-    /**
62
-     * Status ID (STS_ID on esp_status table) to indicate registration is on the WAIT_LIST .
63
-     * Payments are allowed.
64
-     * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee
65
-     * No space reserved.
66
-     * Registration is active
67
-     */
68
-    const status_id_wait_list = 'RWL';
69
-
70
-    /**
71
-     * Status ID (STS_ID on esp_status table) to indicate an APPROVED registration.
72
-     * the TXN may or may not be completed ( paid in full )
73
-     * Payments are allowed.
74
-     * A space IS reserved.
75
-     * Registration is active
76
-     */
77
-    const status_id_approved = 'RAP';
78
-
79
-    /**
80
-     * Status ID (STS_ID on esp_status table) to indicate a registration was CANCELLED by the attendee.
81
-     * Payments are NOT allowed.
82
-     * NO space reserved.
83
-     * Registration is NOT active
84
-     */
85
-    const status_id_cancelled = 'RCN';
86
-
87
-    /**
88
-     * Status ID (STS_ID on esp_status table) to indicate a registration was DECLINED by the Event Admin
89
-     * Payments are NOT allowed.
90
-     * No space reserved.
91
-     * Registration is NOT active
92
-     */
93
-    const status_id_declined = 'RDC';
94
-
95
-    /**
96
-     * @var TableAnalysis $table_analysis
97
-     */
98
-    protected $_table_analysis;
99
-
100
-
101
-    /**
102
-     *    private constructor to prevent direct creation
103
-     *
104
-     * @Constructor
105
-     * @access protected
106
-     * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any
107
-     *                         incoming timezone data that gets saved). Note this just sends the timezone info to the
108
-     *                         date time model field objects.  Default is NULL (and will be assumed using the set
109
-     *                         timezone in the 'timezone_string' wp option)
110
-     * @throws EE_Error
111
-     */
112
-    protected function __construct($timezone = null)
113
-    {
114
-        $this->_table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
115
-        $this->singular_item = esc_html__('Registration', 'event_espresso');
116
-        $this->plural_item = esc_html__('Registrations', 'event_espresso');
117
-        $this->_tables = array(
118
-            'Registration' => new EE_Primary_Table('esp_registration', 'REG_ID'),
119
-        );
120
-        $this->_fields = array(
121
-            'Registration' => array(
122
-                'REG_ID' => new EE_Primary_Key_Int_Field(
123
-                    'REG_ID',
124
-                    esc_html__('Registration ID', 'event_espresso')
125
-                ),
126
-                'EVT_ID' => new EE_Foreign_Key_Int_Field(
127
-                    'EVT_ID',
128
-                    esc_html__('Event ID', 'event_espresso'),
129
-                    false,
130
-                    0,
131
-                    'Event'
132
-                ),
133
-                'ATT_ID' => new EE_Foreign_Key_Int_Field(
134
-                    'ATT_ID',
135
-                    esc_html__('Attendee ID', 'event_espresso'),
136
-                    false,
137
-                    0,
138
-                    'Attendee'
139
-                ),
140
-                'TXN_ID' => new EE_Foreign_Key_Int_Field(
141
-                    'TXN_ID',
142
-                    esc_html__('Transaction ID', 'event_espresso'),
143
-                    false,
144
-                    0,
145
-                    'Transaction'
146
-                ),
147
-                'TKT_ID' => new EE_Foreign_Key_Int_Field(
148
-                    'TKT_ID',
149
-                    esc_html__('Ticket ID', 'event_espresso'),
150
-                    false,
151
-                    0,
152
-                    'Ticket'
153
-                ),
154
-                'STS_ID' => new EE_Foreign_Key_String_Field(
155
-                    'STS_ID',
156
-                    esc_html__('Status ID', 'event_espresso'),
157
-                    false,
158
-                    EEM_Registration::status_id_incomplete,
159
-                    'Status'
160
-                ),
161
-                'REG_date' => new EE_Datetime_Field(
162
-                    'REG_date',
163
-                    esc_html__('Time registration occurred', 'event_espresso'),
164
-                    false,
165
-                    EE_Datetime_Field::now,
166
-                    $timezone
167
-                ),
168
-                'REG_final_price' => new EE_Money_Field(
169
-                    'REG_final_price',
170
-                    esc_html__('Registration\'s share of the transaction total', 'event_espresso'),
171
-                    false,
172
-                    0
173
-                ),
174
-                'REG_paid' => new EE_Money_Field(
175
-                    'REG_paid',
176
-                    esc_html__('Amount paid to date towards registration', 'event_espresso'),
177
-                    false,
178
-                    0
179
-                ),
180
-                'REG_session' => new EE_Plain_Text_Field(
181
-                    'REG_session',
182
-                    esc_html__('Session ID of registration', 'event_espresso'),
183
-                    false,
184
-                    ''
185
-                ),
186
-                'REG_code' => new EE_Plain_Text_Field(
187
-                    'REG_code',
188
-                    esc_html__('Unique Code for this registration', 'event_espresso'),
189
-                    false,
190
-                    ''
191
-                ),
192
-                'REG_url_link' => new EE_Plain_Text_Field(
193
-                    'REG_url_link',
194
-                    esc_html__('String to be used in URL for identifying registration', 'event_espresso'),
195
-                    false,
196
-                    ''
197
-                ),
198
-                'REG_count' => new EE_Integer_Field(
199
-                    'REG_count',
200
-                    esc_html__('Count of this registration in the group registration ', 'event_espresso'),
201
-                    true,
202
-                    1
203
-                ),
204
-                'REG_group_size' => new EE_Integer_Field(
205
-                    'REG_group_size',
206
-                    esc_html__('Number of registrations on this group', 'event_espresso'),
207
-                    false,
208
-                    1
209
-                ),
210
-                'REG_att_is_going' => new EE_Boolean_Field(
211
-                    'REG_att_is_going',
212
-                    esc_html__('Flag indicating the registrant plans on attending', 'event_espresso'),
213
-                    false,
214
-                    false
215
-                ),
216
-                'REG_deleted' => new EE_Trashed_Flag_Field(
217
-                    'REG_deleted',
218
-                    esc_html__('Flag indicating if registration has been archived or not.', 'event_espresso'),
219
-                    false,
220
-                    false
221
-                ),
222
-            ),
223
-        );
224
-        $this->_model_relations = array(
225
-            'Event' => new EE_Belongs_To_Relation(),
226
-            'Attendee' => new EE_Belongs_To_Relation(),
227
-            'Transaction' => new EE_Belongs_To_Relation(),
228
-            'Ticket' => new EE_Belongs_To_Relation(),
229
-            'Status' => new EE_Belongs_To_Relation(),
230
-            'Answer' => new EE_Has_Many_Relation(),
231
-            'Checkin' => new EE_Has_Many_Relation(),
232
-            'Registration_Payment' => new EE_Has_Many_Relation(),
233
-            'Payment' => new EE_HABTM_Relation('Registration_Payment'),
234
-            'Message' => new EE_Has_Many_Any_Relation(false)
235
-            // allow deletes even if there are messages in the queue related
236
-        );
237
-        $this->_model_chain_to_wp_user = 'Event';
238
-        parent::__construct($timezone);
239
-    }
240
-
241
-
242
-    /**
243
-     * a list of ALL valid registration statuses currently in use within the system
244
-     * generated by combining the filterable active and inactive reg status arrays
245
-     *
246
-     * @return array
247
-     */
248
-    public static function reg_statuses()
249
-    {
250
-        return array_unique(
251
-            array_merge(
252
-                EEM_Registration::active_reg_statuses(),
253
-                EEM_Registration::inactive_reg_statuses()
254
-            )
255
-        );
256
-    }
257
-
258
-
259
-    /**
260
-     * reg_statuses_that_allow_payment
261
-     * a filterable list of registration statuses that allow a registrant to make a payment
262
-     *
263
-     * @access public
264
-     * @return array
265
-     */
266
-    public static function reg_statuses_that_allow_payment()
267
-    {
268
-        return apply_filters(
269
-            'FHEE__EEM_Registration__reg_statuses_that_allow_payment',
270
-            array(
271
-                EEM_Registration::status_id_approved,
272
-                EEM_Registration::status_id_pending_payment,
273
-            )
274
-        );
275
-    }
276
-
277
-
278
-    /**
279
-     * active_reg_statuses
280
-     * a filterable list of registration statuses that are considered active
281
-     *
282
-     * @access public
283
-     * @return array
284
-     */
285
-    public static function active_reg_statuses()
286
-    {
287
-        return apply_filters(
288
-            'FHEE__EEM_Registration__active_reg_statuses',
289
-            array(
290
-                EEM_Registration::status_id_approved,
291
-                EEM_Registration::status_id_pending_payment,
292
-                EEM_Registration::status_id_wait_list,
293
-                EEM_Registration::status_id_not_approved,
294
-            )
295
-        );
296
-    }
297
-
298
-
299
-    /**
300
-     * inactive_reg_statuses
301
-     * a filterable list of registration statuses that are not considered active
302
-     *
303
-     * @access public
304
-     * @return array
305
-     */
306
-    public static function inactive_reg_statuses()
307
-    {
308
-        return apply_filters(
309
-            'FHEE__EEM_Registration__inactive_reg_statuses',
310
-            array(
311
-                EEM_Registration::status_id_incomplete,
312
-                EEM_Registration::status_id_cancelled,
313
-                EEM_Registration::status_id_declined,
314
-            )
315
-        );
316
-    }
317
-
318
-
319
-    /**
320
-     *    closed_reg_statuses
321
-     *    a filterable list of registration statuses that are considered "closed"
322
-     * meaning they should not be considered in any calculations involving monies owing
323
-     *
324
-     * @access public
325
-     * @return array
326
-     */
327
-    public static function closed_reg_statuses()
328
-    {
329
-        return apply_filters(
330
-            'FHEE__EEM_Registration__closed_reg_statuses',
331
-            array(
332
-                EEM_Registration::status_id_cancelled,
333
-                EEM_Registration::status_id_declined,
334
-                EEM_Registration::status_id_wait_list,
335
-            )
336
-        );
337
-    }
338
-
339
-
340
-    /**
341
-     *        get list of registration statuses
342
-     *
343
-     * @access public
344
-     * @param array $exclude The status ids to exclude from the returned results
345
-     * @param bool $translated If true will return the values as singular localized strings
346
-     * @return array
347
-     * @throws EE_Error
348
-     */
349
-    public static function reg_status_array($exclude = array(), $translated = false)
350
-    {
351
-        EEM_Registration::instance()->_get_registration_status_array($exclude);
352
-        return $translated
353
-            ? EEM_Status::instance()->localized_status(self::$_reg_status, false, 'sentence')
354
-            : self::$_reg_status;
355
-    }
356
-
357
-
358
-    /**
359
-     *    get list of registration statuses
360
-     *
361
-     * @access private
362
-     * @param array $exclude
363
-     * @return void
364
-     * @throws EE_Error
365
-     */
366
-    private function _get_registration_status_array($exclude = array())
367
-    {
368
-        // in the very rare circumstance that we are deleting a model's table's data
369
-        // and the table hasn't actually been created, this could have an error
370
-        /** @type WPDB $wpdb */
371
-        global $wpdb;
372
-        if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) {
373
-            $results = $wpdb->get_results(
374
-                "SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'"
375
-            );
376
-            self::$_reg_status = array();
377
-            foreach ($results as $status) {
378
-                if (!in_array($status->STS_ID, $exclude, true)) {
379
-                    self::$_reg_status[ $status->STS_ID ] = $status->STS_code;
380
-                }
381
-            }
382
-        }
383
-    }
384
-
385
-
386
-    /**
387
-     * Gets the injected table analyzer, or throws an exception
388
-     *
389
-     * @return TableAnalysis
390
-     * @throws EE_Error
391
-     */
392
-    protected function _get_table_analysis()
393
-    {
394
-        if ($this->_table_analysis instanceof TableAnalysis) {
395
-            return $this->_table_analysis;
396
-        }
397
-        throw new EE_Error(
398
-            sprintf(
399
-                esc_html__('Table analysis class on class %1$s is not set properly.', 'event_espresso'),
400
-                get_class($this)
401
-            )
402
-        );
403
-    }
404
-
405
-
406
-    /**
407
-     * This returns a wpdb->results array of all registration date month and years matching the incoming query params
408
-     * and grouped by month and year.
409
-     *
410
-     * @param  array $where_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
411
-     * @return array
412
-     * @throws EE_Error
413
-     */
414
-    public function get_reg_months_and_years($where_params)
415
-    {
416
-        $query_params[0] = $where_params;
417
-        $query_params['group_by'] = array('reg_year', 'reg_month');
418
-        $query_params['order_by'] = array('REG_date' => 'DESC');
419
-        $columns_to_select = array(
420
-            'reg_year' => array('YEAR(REG_date)', '%s'),
421
-            'reg_month' => array('MONTHNAME(REG_date)', '%s'),
422
-        );
423
-        return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
424
-    }
425
-
426
-
427
-    /**
428
-     * retrieve ALL registrations for a particular Attendee from db
429
-     *
430
-     * @param int $ATT_ID
431
-     * @return EE_Base_Class[]|EE_Registration[]|null
432
-     * @throws EE_Error
433
-     */
434
-    public function get_all_registrations_for_attendee($ATT_ID = 0)
435
-    {
436
-        if (!$ATT_ID) {
437
-            return null;
438
-        }
439
-        return $this->get_all(array(array('ATT_ID' => $ATT_ID)));
440
-    }
441
-
442
-
443
-    /**
444
-     * Gets a registration given their REG_url_link. Yes, this should usually
445
-     * be passed via a GET parameter.
446
-     *
447
-     * @param string $REG_url_link
448
-     * @return EE_Base_Class|EE_Registration|null
449
-     * @throws EE_Error
450
-     */
451
-    public function get_registration_for_reg_url_link($REG_url_link)
452
-    {
453
-        if (!$REG_url_link) {
454
-            return null;
455
-        }
456
-        return $this->get_one(array(array('REG_url_link' => $REG_url_link)));
457
-    }
458
-
459
-
460
-    /**
461
-     *        retrieve registration for a specific transaction attendee from db
462
-     *
463
-     * @access        public
464
-     * @param    int $TXN_ID
465
-     * @param    int $ATT_ID
466
-     * @param    int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the
467
-     *                         attendee number is required
468
-     * @return        mixed        array on success, FALSE on fail
469
-     * @throws EE_Error
470
-     */
471
-    public function get_registration_for_transaction_attendee($TXN_ID = 0, $ATT_ID = 0, $att_nmbr = 0)
472
-    {
473
-        return $this->get_one(array(
474
-            array(
475
-                'TXN_ID' => $TXN_ID,
476
-                'ATT_ID' => $ATT_ID,
477
-            ),
478
-            'limit' => array(min($att_nmbr - 1, 0), 1),
479
-        ));
480
-    }
481
-
482
-
483
-    /**
484
-     *        get the number of registrations per day  for the Registration Admin page Reports Tab.
485
-     *        (doesn't utilize models because it's a fairly specialized query)
486
-     *
487
-     * @access        public
488
-     * @param $period string which can be passed to php's strtotime function (eg "-1 month")
489
-     * @return stdClass[] with properties regDate and total
490
-     * @throws EE_Error
491
-     */
492
-    public function get_registrations_per_day_report($period = '-1 month')
493
-    {
494
-        $sql_date = $this->convert_datetime_for_query(
495
-            'REG_date',
496
-            date('Y-m-d H:i:s', strtotime($period)),
497
-            'Y-m-d H:i:s',
498
-            'UTC'
499
-        );
500
-        $where = array(
501
-            'REG_date' => array('>=', $sql_date),
502
-            'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
503
-        );
504
-        if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
505
-            $where['Event.EVT_wp_user'] = get_current_user_id();
506
-        }
507
-        $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date');
508
-        $results = $this->_get_all_wpdb_results(
509
-            array(
510
-                $where,
511
-                'group_by' => 'regDate',
512
-                'order_by' => array('REG_date' => 'ASC'),
513
-            ),
514
-            OBJECT,
515
-            array(
516
-                'regDate' => array('DATE(' . $query_interval . ')', '%s'),
517
-                'total' => array('count(REG_ID)', '%d'),
518
-            )
519
-        );
520
-        return $results;
521
-    }
522
-
523
-
524
-    /**
525
-     * Get the number of registrations per day including the count of registrations for each Registration Status.
526
-     * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
527
-     *
528
-     * @param string $period
529
-     * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID
530
-     * @throws EE_Error
531
-     *                    (i.e. RAP)
532
-     */
533
-    public function get_registrations_per_day_and_per_status_report($period = '-1 month')
534
-    {
535
-        global $wpdb;
536
-        $registration_table = $wpdb->prefix . 'esp_registration';
537
-        $event_table = $wpdb->posts;
538
-        $sql_date = date('Y-m-d H:i:s', strtotime($period));
539
-        // prepare the query interval for displaying offset
540
-        $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date');
541
-        // inner date query
542
-        $inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} ";
543
-        $inner_where = ' WHERE';
544
-        // exclude events not authored by user if permissions in effect
545
-        if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
546
-            $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
547
-            $inner_where .= ' post_author = ' . get_current_user_id() . ' AND';
548
-        }
549
-        $inner_where .= " REG_date >= '{$sql_date}'";
550
-        $inner_date_query .= $inner_where;
551
-        // start main query
552
-        $select = "SELECT DATE({$query_interval}) as Registration_REG_date, ";
553
-        $join = '';
554
-        $join_parts = array();
555
-        $select_parts = array();
556
-        // loop through registration stati to do parts for each status.
557
-        foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
558
-            if ($STS_ID === EEM_Registration::status_id_incomplete) {
559
-                continue;
560
-            }
561
-            $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
562
-            $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'";
563
-        }
564
-        // setup the selects
565
-        $select .= implode(', ', $select_parts);
566
-        $select .= " FROM ($inner_date_query) AS dates LEFT JOIN ";
567
-        // setup the joins
568
-        $join .= implode(' LEFT JOIN ', $join_parts);
569
-        // now let's put it all together
570
-        $query = $select . $join . ' GROUP BY Registration_REG_date';
571
-        // and execute it
572
-        return $wpdb->get_results($query, ARRAY_A);
573
-    }
574
-
575
-
576
-    /**
577
-     *        get the number of registrations per event  for the Registration Admin page Reports Tab
578
-     *
579
-     * @access        public
580
-     * @param $period string which can be passed to php's strtotime function (eg "-1 month")
581
-     * @return stdClass[] each with properties event_name, reg_limit, and total
582
-     * @throws EE_Error
583
-     */
584
-    public function get_registrations_per_event_report($period = '-1 month')
585
-    {
586
-        $date_sql = $this->convert_datetime_for_query(
587
-            'REG_date',
588
-            date('Y-m-d H:i:s', strtotime($period)),
589
-            'Y-m-d H:i:s',
590
-            'UTC'
591
-        );
592
-        $where = array(
593
-            'REG_date' => array('>=', $date_sql),
594
-            'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
595
-        );
596
-        if (!EE_Registry::instance()->CAP->current_user_can(
597
-            'ee_read_others_registrations',
598
-            'reg_per_event_report'
599
-        )
600
-        ) {
601
-            $where['Event.EVT_wp_user'] = get_current_user_id();
602
-        }
603
-        $results = $this->_get_all_wpdb_results(
604
-            array(
605
-            $where,
606
-            'group_by' => 'Event.EVT_name',
607
-            'order_by' => 'Event.EVT_name',
608
-            'limit' => array(0, 24),
609
-            ),
610
-            OBJECT,
611
-            array(
612
-                'event_name' => array('Event_CPT.post_title', '%s'),
613
-                'total' => array('COUNT(REG_ID)', '%s'),
614
-            )
615
-        );
616
-        return $results;
617
-    }
618
-
619
-
620
-    /**
621
-     * Get the number of registrations per event grouped by registration status.
622
-     * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
623
-     *
624
-     * @param string $period
625
-     * @return stdClass[] with properties `Registration_Event` and a column for each registration status as the STS_ID
626
-     * @throws EE_Error
627
-     *                    (i.e. RAP)
628
-     */
629
-    public function get_registrations_per_event_and_per_status_report($period = '-1 month')
630
-    {
631
-        global $wpdb;
632
-        $registration_table = $wpdb->prefix . 'esp_registration';
633
-        $event_table = $wpdb->posts;
634
-        $sql_date = date('Y-m-d H:i:s', strtotime($period));
635
-        // inner date query
636
-        $inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table ";
637
-        $inner_where = ' WHERE';
638
-        // exclude events not authored by user if permissions in effect
639
-        if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
640
-            $inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
641
-            $inner_where .= ' post_author = ' . get_current_user_id() . ' AND';
642
-        }
643
-        $inner_where .= " REG_date >= '{$sql_date}'";
644
-        $inner_date_query .= $inner_where;
645
-        // build main query
646
-        $select = 'SELECT Event.post_title as Registration_Event, ';
647
-        $join = '';
648
-        $join_parts = array();
649
-        $select_parts = array();
650
-        // loop through registration stati to do parts for each status.
651
-        foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
652
-            if ($STS_ID === EEM_Registration::status_id_incomplete) {
653
-                continue;
654
-            }
655
-            $select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
656
-            $join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.EVT_ID = dates.EVT_ID AND {$STS_code}.STS_ID = '{$STS_ID}' AND {$STS_code}.REG_date = dates.REG_date";
657
-        }
658
-        // setup the selects
659
-        $select .= implode(', ', $select_parts);
660
-        $select .= " FROM ($inner_date_query) AS dates LEFT JOIN $event_table as Event ON Event.ID = dates.EVT_ID LEFT JOIN ";
661
-        // setup remaining joins
662
-        $join .= implode(' LEFT JOIN ', $join_parts);
663
-        // now put it all together
664
-        $query = $select . $join . ' GROUP BY Registration_Event';
665
-        // and execute
666
-        return $wpdb->get_results($query, ARRAY_A);
667
-    }
668
-
669
-
670
-    /**
671
-     * Returns the EE_Registration of the primary attendee on the transaction id provided
672
-     *
673
-     * @param int $TXN_ID
674
-     * @return EE_Base_Class|EE_Registration|null
675
-     * @throws EE_Error
676
-     */
677
-    public function get_primary_registration_for_transaction_ID($TXN_ID = 0)
678
-    {
679
-        if (!$TXN_ID) {
680
-            return null;
681
-        }
682
-        return $this->get_one(array(
683
-            array(
684
-                'TXN_ID' => $TXN_ID,
685
-                'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT,
686
-            ),
687
-        ));
688
-    }
689
-
690
-
691
-    /**
692
-     *        get_event_registration_count
693
-     *
694
-     * @access public
695
-     * @param int $EVT_ID
696
-     * @param boolean $for_incomplete_payments
697
-     * @return int
698
-     * @throws EE_Error
699
-     */
700
-    public function get_event_registration_count($EVT_ID, $for_incomplete_payments = false)
701
-    {
702
-        // we only count approved registrations towards registration limits
703
-        $query_params = array(array('EVT_ID' => $EVT_ID, 'STS_ID' => self::status_id_approved));
704
-        if ($for_incomplete_payments) {
705
-            $query_params[0]['Transaction.STS_ID'] = array('!=', EEM_Transaction::complete_status_code);
706
-        }
707
-        return $this->count($query_params);
708
-    }
709
-
710
-
711
-    /**
712
-     * Deletes all registrations with no transactions. Note that this needs to be very efficient
713
-     * and so it uses wpdb directly
714
-     *
715
-     * @global WPDB $wpdb
716
-     * @return int number deleted
717
-     * @throws EE_Error
718
-     */
719
-    public function delete_registrations_with_no_transaction()
720
-    {
721
-        /** @type WPDB $wpdb */
722
-        global $wpdb;
723
-        return $wpdb->query(
724
-            'DELETE r FROM '
725
-            . $this->table()
726
-            . ' r LEFT JOIN '
727
-            . EEM_Transaction::instance()->table()
728
-            . ' t ON r.TXN_ID = t.TXN_ID WHERE t.TXN_ID IS NULL'
729
-        );
730
-    }
731
-
732
-
733
-    /**
734
-     *  Count registrations checked into (or out of) a datetime
735
-     *
736
-     * @param int $DTT_ID datetime ID
737
-     * @param boolean $checked_in whether to count registrations checked IN or OUT
738
-     * @return int
739
-     * @throws EE_Error
740
-     */
741
-    public function count_registrations_checked_into_datetime($DTT_ID, $checked_in = true)
742
-    {
743
-        global $wpdb;
744
-        // subquery to get latest checkin
745
-        $query = $wpdb->prepare(
746
-            'SELECT '
747
-            . 'COUNT( DISTINCT checkins.REG_ID ) '
748
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
749
-            . '( SELECT '
750
-            . 'max( CHK_timestamp ) AS latest_checkin, '
751
-            . 'REG_ID AS REG_ID '
752
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' '
753
-            . 'WHERE DTT_ID=%d '
754
-            . 'GROUP BY REG_ID'
755
-            . ') AS most_recent_checkin_per_reg '
756
-            . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID '
757
-            . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin '
758
-            . 'WHERE '
759
-            . 'checkins.CHK_in=%d',
760
-            $DTT_ID,
761
-            $checked_in
762
-        );
763
-        return (int) $wpdb->get_var($query);
764
-    }
765
-
766
-
767
-    /**
768
-     *  Count registrations checked into (or out of) an event.
769
-     *
770
-     * @param int $EVT_ID event ID
771
-     * @param boolean $checked_in whether to count registrations checked IN or OUT
772
-     * @return int
773
-     * @throws EE_Error
774
-     */
775
-    public function count_registrations_checked_into_event($EVT_ID, $checked_in = true)
776
-    {
777
-        global $wpdb;
778
-        // subquery to get latest checkin
779
-        $query = $wpdb->prepare(
780
-            'SELECT '
781
-            . 'COUNT( DISTINCT checkins.REG_ID ) '
782
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
783
-            . '( SELECT '
784
-            . 'max( CHK_timestamp ) AS latest_checkin, '
785
-            . 'REG_ID AS REG_ID '
786
-            . 'FROM ' . EEM_Checkin::instance()->table() . ' AS c '
787
-            . 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d '
788
-            . 'ON c.DTT_ID=d.DTT_ID '
789
-            . 'WHERE d.EVT_ID=%d '
790
-            . 'GROUP BY REG_ID'
791
-            . ') AS most_recent_checkin_per_reg '
792
-            . 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID '
793
-            . 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin '
794
-            . 'WHERE '
795
-            . 'checkins.CHK_in=%d',
796
-            $EVT_ID,
797
-            $checked_in
798
-        );
799
-        return (int) $wpdb->get_var($query);
800
-    }
801
-
802
-
803
-    /**
804
-     * The purpose of this method is to retrieve an array of
805
-     * EE_Registration objects that represent the latest registration
806
-     * for each ATT_ID given in the function argument.
807
-     *
808
-     * @param array $attendee_ids
809
-     * @return EE_Base_Class[]|EE_Registration[]
810
-     * @throws EE_Error
811
-     */
812
-    public function get_latest_registration_for_each_of_given_contacts($attendee_ids = array())
813
-    {
814
-        // first do a native wp_query to get the latest REG_ID's matching these attendees.
815
-        global $wpdb;
816
-        $registration_table = $wpdb->prefix . 'esp_registration';
817
-        $attendee_table = $wpdb->posts;
818
-        $attendee_ids = is_array($attendee_ids)
819
-            ? array_map('absint', $attendee_ids)
820
-            : array((int) $attendee_ids);
821
-        $ATT_IDs = implode(',', $attendee_ids);
822
-        // first we do a query to get the registration ids
823
-        // (because a group by before order by causes the order by to be ignored.)
824
-        $registration_id_query = "
16
+	/**
17
+	 * @var EEM_Registration $_instance
18
+	 */
19
+	protected static $_instance;
20
+
21
+	/**
22
+	 * Keys are the status IDs for registrations (eg, RAP, RCN, etc), and the values
23
+	 * are status codes (eg, approved, cancelled, etc)
24
+	 *
25
+	 * @var array
26
+	 */
27
+	private static $_reg_status;
28
+
29
+	/**
30
+	 * The value of REG_count for a primary registrant
31
+	 */
32
+	const PRIMARY_REGISTRANT_COUNT = 1;
33
+
34
+	/**
35
+	 * Status ID (STS_ID on esp_status table) to indicate an INCOMPLETE registration.
36
+	 * Initial status for registrations when they are first created
37
+	 * Payments are NOT allowed.
38
+	 * Automatically toggled to whatever the default Event registration status is upon completion of the attendee
39
+	 * information reg step NO space reserved. Registration is NOT active
40
+	 */
41
+	const status_id_incomplete = 'RIC';
42
+
43
+	/**
44
+	 * Status ID (STS_ID on esp_status table) to indicate an UNAPPROVED registration.
45
+	 * Payments are NOT allowed.
46
+	 * Event Admin must manually toggle STS_ID for it to change
47
+	 * No space reserved.
48
+	 * Registration is active
49
+	 */
50
+	const status_id_not_approved = 'RNA';
51
+
52
+	/**
53
+	 * Status ID (STS_ID on esp_status table) to indicate registration is PENDING_PAYMENT .
54
+	 * Payments are allowed.
55
+	 * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee
56
+	 * No space reserved.
57
+	 * Registration is active
58
+	 */
59
+	const status_id_pending_payment = 'RPP';
60
+
61
+	/**
62
+	 * Status ID (STS_ID on esp_status table) to indicate registration is on the WAIT_LIST .
63
+	 * Payments are allowed.
64
+	 * STS_ID will automatically be toggled to RAP if payment is made in full by the attendee
65
+	 * No space reserved.
66
+	 * Registration is active
67
+	 */
68
+	const status_id_wait_list = 'RWL';
69
+
70
+	/**
71
+	 * Status ID (STS_ID on esp_status table) to indicate an APPROVED registration.
72
+	 * the TXN may or may not be completed ( paid in full )
73
+	 * Payments are allowed.
74
+	 * A space IS reserved.
75
+	 * Registration is active
76
+	 */
77
+	const status_id_approved = 'RAP';
78
+
79
+	/**
80
+	 * Status ID (STS_ID on esp_status table) to indicate a registration was CANCELLED by the attendee.
81
+	 * Payments are NOT allowed.
82
+	 * NO space reserved.
83
+	 * Registration is NOT active
84
+	 */
85
+	const status_id_cancelled = 'RCN';
86
+
87
+	/**
88
+	 * Status ID (STS_ID on esp_status table) to indicate a registration was DECLINED by the Event Admin
89
+	 * Payments are NOT allowed.
90
+	 * No space reserved.
91
+	 * Registration is NOT active
92
+	 */
93
+	const status_id_declined = 'RDC';
94
+
95
+	/**
96
+	 * @var TableAnalysis $table_analysis
97
+	 */
98
+	protected $_table_analysis;
99
+
100
+
101
+	/**
102
+	 *    private constructor to prevent direct creation
103
+	 *
104
+	 * @Constructor
105
+	 * @access protected
106
+	 * @param string $timezone string representing the timezone we want to set for returned Date Time Strings (and any
107
+	 *                         incoming timezone data that gets saved). Note this just sends the timezone info to the
108
+	 *                         date time model field objects.  Default is NULL (and will be assumed using the set
109
+	 *                         timezone in the 'timezone_string' wp option)
110
+	 * @throws EE_Error
111
+	 */
112
+	protected function __construct($timezone = null)
113
+	{
114
+		$this->_table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
115
+		$this->singular_item = esc_html__('Registration', 'event_espresso');
116
+		$this->plural_item = esc_html__('Registrations', 'event_espresso');
117
+		$this->_tables = array(
118
+			'Registration' => new EE_Primary_Table('esp_registration', 'REG_ID'),
119
+		);
120
+		$this->_fields = array(
121
+			'Registration' => array(
122
+				'REG_ID' => new EE_Primary_Key_Int_Field(
123
+					'REG_ID',
124
+					esc_html__('Registration ID', 'event_espresso')
125
+				),
126
+				'EVT_ID' => new EE_Foreign_Key_Int_Field(
127
+					'EVT_ID',
128
+					esc_html__('Event ID', 'event_espresso'),
129
+					false,
130
+					0,
131
+					'Event'
132
+				),
133
+				'ATT_ID' => new EE_Foreign_Key_Int_Field(
134
+					'ATT_ID',
135
+					esc_html__('Attendee ID', 'event_espresso'),
136
+					false,
137
+					0,
138
+					'Attendee'
139
+				),
140
+				'TXN_ID' => new EE_Foreign_Key_Int_Field(
141
+					'TXN_ID',
142
+					esc_html__('Transaction ID', 'event_espresso'),
143
+					false,
144
+					0,
145
+					'Transaction'
146
+				),
147
+				'TKT_ID' => new EE_Foreign_Key_Int_Field(
148
+					'TKT_ID',
149
+					esc_html__('Ticket ID', 'event_espresso'),
150
+					false,
151
+					0,
152
+					'Ticket'
153
+				),
154
+				'STS_ID' => new EE_Foreign_Key_String_Field(
155
+					'STS_ID',
156
+					esc_html__('Status ID', 'event_espresso'),
157
+					false,
158
+					EEM_Registration::status_id_incomplete,
159
+					'Status'
160
+				),
161
+				'REG_date' => new EE_Datetime_Field(
162
+					'REG_date',
163
+					esc_html__('Time registration occurred', 'event_espresso'),
164
+					false,
165
+					EE_Datetime_Field::now,
166
+					$timezone
167
+				),
168
+				'REG_final_price' => new EE_Money_Field(
169
+					'REG_final_price',
170
+					esc_html__('Registration\'s share of the transaction total', 'event_espresso'),
171
+					false,
172
+					0
173
+				),
174
+				'REG_paid' => new EE_Money_Field(
175
+					'REG_paid',
176
+					esc_html__('Amount paid to date towards registration', 'event_espresso'),
177
+					false,
178
+					0
179
+				),
180
+				'REG_session' => new EE_Plain_Text_Field(
181
+					'REG_session',
182
+					esc_html__('Session ID of registration', 'event_espresso'),
183
+					false,
184
+					''
185
+				),
186
+				'REG_code' => new EE_Plain_Text_Field(
187
+					'REG_code',
188
+					esc_html__('Unique Code for this registration', 'event_espresso'),
189
+					false,
190
+					''
191
+				),
192
+				'REG_url_link' => new EE_Plain_Text_Field(
193
+					'REG_url_link',
194
+					esc_html__('String to be used in URL for identifying registration', 'event_espresso'),
195
+					false,
196
+					''
197
+				),
198
+				'REG_count' => new EE_Integer_Field(
199
+					'REG_count',
200
+					esc_html__('Count of this registration in the group registration ', 'event_espresso'),
201
+					true,
202
+					1
203
+				),
204
+				'REG_group_size' => new EE_Integer_Field(
205
+					'REG_group_size',
206
+					esc_html__('Number of registrations on this group', 'event_espresso'),
207
+					false,
208
+					1
209
+				),
210
+				'REG_att_is_going' => new EE_Boolean_Field(
211
+					'REG_att_is_going',
212
+					esc_html__('Flag indicating the registrant plans on attending', 'event_espresso'),
213
+					false,
214
+					false
215
+				),
216
+				'REG_deleted' => new EE_Trashed_Flag_Field(
217
+					'REG_deleted',
218
+					esc_html__('Flag indicating if registration has been archived or not.', 'event_espresso'),
219
+					false,
220
+					false
221
+				),
222
+			),
223
+		);
224
+		$this->_model_relations = array(
225
+			'Event' => new EE_Belongs_To_Relation(),
226
+			'Attendee' => new EE_Belongs_To_Relation(),
227
+			'Transaction' => new EE_Belongs_To_Relation(),
228
+			'Ticket' => new EE_Belongs_To_Relation(),
229
+			'Status' => new EE_Belongs_To_Relation(),
230
+			'Answer' => new EE_Has_Many_Relation(),
231
+			'Checkin' => new EE_Has_Many_Relation(),
232
+			'Registration_Payment' => new EE_Has_Many_Relation(),
233
+			'Payment' => new EE_HABTM_Relation('Registration_Payment'),
234
+			'Message' => new EE_Has_Many_Any_Relation(false)
235
+			// allow deletes even if there are messages in the queue related
236
+		);
237
+		$this->_model_chain_to_wp_user = 'Event';
238
+		parent::__construct($timezone);
239
+	}
240
+
241
+
242
+	/**
243
+	 * a list of ALL valid registration statuses currently in use within the system
244
+	 * generated by combining the filterable active and inactive reg status arrays
245
+	 *
246
+	 * @return array
247
+	 */
248
+	public static function reg_statuses()
249
+	{
250
+		return array_unique(
251
+			array_merge(
252
+				EEM_Registration::active_reg_statuses(),
253
+				EEM_Registration::inactive_reg_statuses()
254
+			)
255
+		);
256
+	}
257
+
258
+
259
+	/**
260
+	 * reg_statuses_that_allow_payment
261
+	 * a filterable list of registration statuses that allow a registrant to make a payment
262
+	 *
263
+	 * @access public
264
+	 * @return array
265
+	 */
266
+	public static function reg_statuses_that_allow_payment()
267
+	{
268
+		return apply_filters(
269
+			'FHEE__EEM_Registration__reg_statuses_that_allow_payment',
270
+			array(
271
+				EEM_Registration::status_id_approved,
272
+				EEM_Registration::status_id_pending_payment,
273
+			)
274
+		);
275
+	}
276
+
277
+
278
+	/**
279
+	 * active_reg_statuses
280
+	 * a filterable list of registration statuses that are considered active
281
+	 *
282
+	 * @access public
283
+	 * @return array
284
+	 */
285
+	public static function active_reg_statuses()
286
+	{
287
+		return apply_filters(
288
+			'FHEE__EEM_Registration__active_reg_statuses',
289
+			array(
290
+				EEM_Registration::status_id_approved,
291
+				EEM_Registration::status_id_pending_payment,
292
+				EEM_Registration::status_id_wait_list,
293
+				EEM_Registration::status_id_not_approved,
294
+			)
295
+		);
296
+	}
297
+
298
+
299
+	/**
300
+	 * inactive_reg_statuses
301
+	 * a filterable list of registration statuses that are not considered active
302
+	 *
303
+	 * @access public
304
+	 * @return array
305
+	 */
306
+	public static function inactive_reg_statuses()
307
+	{
308
+		return apply_filters(
309
+			'FHEE__EEM_Registration__inactive_reg_statuses',
310
+			array(
311
+				EEM_Registration::status_id_incomplete,
312
+				EEM_Registration::status_id_cancelled,
313
+				EEM_Registration::status_id_declined,
314
+			)
315
+		);
316
+	}
317
+
318
+
319
+	/**
320
+	 *    closed_reg_statuses
321
+	 *    a filterable list of registration statuses that are considered "closed"
322
+	 * meaning they should not be considered in any calculations involving monies owing
323
+	 *
324
+	 * @access public
325
+	 * @return array
326
+	 */
327
+	public static function closed_reg_statuses()
328
+	{
329
+		return apply_filters(
330
+			'FHEE__EEM_Registration__closed_reg_statuses',
331
+			array(
332
+				EEM_Registration::status_id_cancelled,
333
+				EEM_Registration::status_id_declined,
334
+				EEM_Registration::status_id_wait_list,
335
+			)
336
+		);
337
+	}
338
+
339
+
340
+	/**
341
+	 *        get list of registration statuses
342
+	 *
343
+	 * @access public
344
+	 * @param array $exclude The status ids to exclude from the returned results
345
+	 * @param bool $translated If true will return the values as singular localized strings
346
+	 * @return array
347
+	 * @throws EE_Error
348
+	 */
349
+	public static function reg_status_array($exclude = array(), $translated = false)
350
+	{
351
+		EEM_Registration::instance()->_get_registration_status_array($exclude);
352
+		return $translated
353
+			? EEM_Status::instance()->localized_status(self::$_reg_status, false, 'sentence')
354
+			: self::$_reg_status;
355
+	}
356
+
357
+
358
+	/**
359
+	 *    get list of registration statuses
360
+	 *
361
+	 * @access private
362
+	 * @param array $exclude
363
+	 * @return void
364
+	 * @throws EE_Error
365
+	 */
366
+	private function _get_registration_status_array($exclude = array())
367
+	{
368
+		// in the very rare circumstance that we are deleting a model's table's data
369
+		// and the table hasn't actually been created, this could have an error
370
+		/** @type WPDB $wpdb */
371
+		global $wpdb;
372
+		if ($this->_get_table_analysis()->tableExists($wpdb->prefix . 'esp_status')) {
373
+			$results = $wpdb->get_results(
374
+				"SELECT STS_ID, STS_code FROM {$wpdb->prefix}esp_status WHERE STS_type = 'registration'"
375
+			);
376
+			self::$_reg_status = array();
377
+			foreach ($results as $status) {
378
+				if (!in_array($status->STS_ID, $exclude, true)) {
379
+					self::$_reg_status[ $status->STS_ID ] = $status->STS_code;
380
+				}
381
+			}
382
+		}
383
+	}
384
+
385
+
386
+	/**
387
+	 * Gets the injected table analyzer, or throws an exception
388
+	 *
389
+	 * @return TableAnalysis
390
+	 * @throws EE_Error
391
+	 */
392
+	protected function _get_table_analysis()
393
+	{
394
+		if ($this->_table_analysis instanceof TableAnalysis) {
395
+			return $this->_table_analysis;
396
+		}
397
+		throw new EE_Error(
398
+			sprintf(
399
+				esc_html__('Table analysis class on class %1$s is not set properly.', 'event_espresso'),
400
+				get_class($this)
401
+			)
402
+		);
403
+	}
404
+
405
+
406
+	/**
407
+	 * This returns a wpdb->results array of all registration date month and years matching the incoming query params
408
+	 * and grouped by month and year.
409
+	 *
410
+	 * @param  array $where_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
411
+	 * @return array
412
+	 * @throws EE_Error
413
+	 */
414
+	public function get_reg_months_and_years($where_params)
415
+	{
416
+		$query_params[0] = $where_params;
417
+		$query_params['group_by'] = array('reg_year', 'reg_month');
418
+		$query_params['order_by'] = array('REG_date' => 'DESC');
419
+		$columns_to_select = array(
420
+			'reg_year' => array('YEAR(REG_date)', '%s'),
421
+			'reg_month' => array('MONTHNAME(REG_date)', '%s'),
422
+		);
423
+		return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
424
+	}
425
+
426
+
427
+	/**
428
+	 * retrieve ALL registrations for a particular Attendee from db
429
+	 *
430
+	 * @param int $ATT_ID
431
+	 * @return EE_Base_Class[]|EE_Registration[]|null
432
+	 * @throws EE_Error
433
+	 */
434
+	public function get_all_registrations_for_attendee($ATT_ID = 0)
435
+	{
436
+		if (!$ATT_ID) {
437
+			return null;
438
+		}
439
+		return $this->get_all(array(array('ATT_ID' => $ATT_ID)));
440
+	}
441
+
442
+
443
+	/**
444
+	 * Gets a registration given their REG_url_link. Yes, this should usually
445
+	 * be passed via a GET parameter.
446
+	 *
447
+	 * @param string $REG_url_link
448
+	 * @return EE_Base_Class|EE_Registration|null
449
+	 * @throws EE_Error
450
+	 */
451
+	public function get_registration_for_reg_url_link($REG_url_link)
452
+	{
453
+		if (!$REG_url_link) {
454
+			return null;
455
+		}
456
+		return $this->get_one(array(array('REG_url_link' => $REG_url_link)));
457
+	}
458
+
459
+
460
+	/**
461
+	 *        retrieve registration for a specific transaction attendee from db
462
+	 *
463
+	 * @access        public
464
+	 * @param    int $TXN_ID
465
+	 * @param    int $ATT_ID
466
+	 * @param    int $att_nmbr in case the ATT_ID is the same for multiple registrations (same details used) then the
467
+	 *                         attendee number is required
468
+	 * @return        mixed        array on success, FALSE on fail
469
+	 * @throws EE_Error
470
+	 */
471
+	public function get_registration_for_transaction_attendee($TXN_ID = 0, $ATT_ID = 0, $att_nmbr = 0)
472
+	{
473
+		return $this->get_one(array(
474
+			array(
475
+				'TXN_ID' => $TXN_ID,
476
+				'ATT_ID' => $ATT_ID,
477
+			),
478
+			'limit' => array(min($att_nmbr - 1, 0), 1),
479
+		));
480
+	}
481
+
482
+
483
+	/**
484
+	 *        get the number of registrations per day  for the Registration Admin page Reports Tab.
485
+	 *        (doesn't utilize models because it's a fairly specialized query)
486
+	 *
487
+	 * @access        public
488
+	 * @param $period string which can be passed to php's strtotime function (eg "-1 month")
489
+	 * @return stdClass[] with properties regDate and total
490
+	 * @throws EE_Error
491
+	 */
492
+	public function get_registrations_per_day_report($period = '-1 month')
493
+	{
494
+		$sql_date = $this->convert_datetime_for_query(
495
+			'REG_date',
496
+			date('Y-m-d H:i:s', strtotime($period)),
497
+			'Y-m-d H:i:s',
498
+			'UTC'
499
+		);
500
+		$where = array(
501
+			'REG_date' => array('>=', $sql_date),
502
+			'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
503
+		);
504
+		if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_day_report')) {
505
+			$where['Event.EVT_wp_user'] = get_current_user_id();
506
+		}
507
+		$query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'REG_date');
508
+		$results = $this->_get_all_wpdb_results(
509
+			array(
510
+				$where,
511
+				'group_by' => 'regDate',
512
+				'order_by' => array('REG_date' => 'ASC'),
513
+			),
514
+			OBJECT,
515
+			array(
516
+				'regDate' => array('DATE(' . $query_interval . ')', '%s'),
517
+				'total' => array('count(REG_ID)', '%d'),
518
+			)
519
+		);
520
+		return $results;
521
+	}
522
+
523
+
524
+	/**
525
+	 * Get the number of registrations per day including the count of registrations for each Registration Status.
526
+	 * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
527
+	 *
528
+	 * @param string $period
529
+	 * @return stdClass[] with properties Registration_REG_date and a column for each registration status as the STS_ID
530
+	 * @throws EE_Error
531
+	 *                    (i.e. RAP)
532
+	 */
533
+	public function get_registrations_per_day_and_per_status_report($period = '-1 month')
534
+	{
535
+		global $wpdb;
536
+		$registration_table = $wpdb->prefix . 'esp_registration';
537
+		$event_table = $wpdb->posts;
538
+		$sql_date = date('Y-m-d H:i:s', strtotime($period));
539
+		// prepare the query interval for displaying offset
540
+		$query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(), 'dates.REG_date');
541
+		// inner date query
542
+		$inner_date_query = "SELECT DISTINCT REG_date from {$registration_table} ";
543
+		$inner_where = ' WHERE';
544
+		// exclude events not authored by user if permissions in effect
545
+		if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
546
+			$inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
547
+			$inner_where .= ' post_author = ' . get_current_user_id() . ' AND';
548
+		}
549
+		$inner_where .= " REG_date >= '{$sql_date}'";
550
+		$inner_date_query .= $inner_where;
551
+		// start main query
552
+		$select = "SELECT DATE({$query_interval}) as Registration_REG_date, ";
553
+		$join = '';
554
+		$join_parts = array();
555
+		$select_parts = array();
556
+		// loop through registration stati to do parts for each status.
557
+		foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
558
+			if ($STS_ID === EEM_Registration::status_id_incomplete) {
559
+				continue;
560
+			}
561
+			$select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
562
+			$join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.REG_date = dates.REG_date AND {$STS_code}.STS_ID = '{$STS_ID}'";
563
+		}
564
+		// setup the selects
565
+		$select .= implode(', ', $select_parts);
566
+		$select .= " FROM ($inner_date_query) AS dates LEFT JOIN ";
567
+		// setup the joins
568
+		$join .= implode(' LEFT JOIN ', $join_parts);
569
+		// now let's put it all together
570
+		$query = $select . $join . ' GROUP BY Registration_REG_date';
571
+		// and execute it
572
+		return $wpdb->get_results($query, ARRAY_A);
573
+	}
574
+
575
+
576
+	/**
577
+	 *        get the number of registrations per event  for the Registration Admin page Reports Tab
578
+	 *
579
+	 * @access        public
580
+	 * @param $period string which can be passed to php's strtotime function (eg "-1 month")
581
+	 * @return stdClass[] each with properties event_name, reg_limit, and total
582
+	 * @throws EE_Error
583
+	 */
584
+	public function get_registrations_per_event_report($period = '-1 month')
585
+	{
586
+		$date_sql = $this->convert_datetime_for_query(
587
+			'REG_date',
588
+			date('Y-m-d H:i:s', strtotime($period)),
589
+			'Y-m-d H:i:s',
590
+			'UTC'
591
+		);
592
+		$where = array(
593
+			'REG_date' => array('>=', $date_sql),
594
+			'STS_ID' => array('!=', EEM_Registration::status_id_incomplete),
595
+		);
596
+		if (!EE_Registry::instance()->CAP->current_user_can(
597
+			'ee_read_others_registrations',
598
+			'reg_per_event_report'
599
+		)
600
+		) {
601
+			$where['Event.EVT_wp_user'] = get_current_user_id();
602
+		}
603
+		$results = $this->_get_all_wpdb_results(
604
+			array(
605
+			$where,
606
+			'group_by' => 'Event.EVT_name',
607
+			'order_by' => 'Event.EVT_name',
608
+			'limit' => array(0, 24),
609
+			),
610
+			OBJECT,
611
+			array(
612
+				'event_name' => array('Event_CPT.post_title', '%s'),
613
+				'total' => array('COUNT(REG_ID)', '%s'),
614
+			)
615
+		);
616
+		return $results;
617
+	}
618
+
619
+
620
+	/**
621
+	 * Get the number of registrations per event grouped by registration status.
622
+	 * Note: EEM_Registration::status_id_incomplete registrations are excluded from the results.
623
+	 *
624
+	 * @param string $period
625
+	 * @return stdClass[] with properties `Registration_Event` and a column for each registration status as the STS_ID
626
+	 * @throws EE_Error
627
+	 *                    (i.e. RAP)
628
+	 */
629
+	public function get_registrations_per_event_and_per_status_report($period = '-1 month')
630
+	{
631
+		global $wpdb;
632
+		$registration_table = $wpdb->prefix . 'esp_registration';
633
+		$event_table = $wpdb->posts;
634
+		$sql_date = date('Y-m-d H:i:s', strtotime($period));
635
+		// inner date query
636
+		$inner_date_query = "SELECT DISTINCT EVT_ID, REG_date from $registration_table ";
637
+		$inner_where = ' WHERE';
638
+		// exclude events not authored by user if permissions in effect
639
+		if (!EE_Registry::instance()->CAP->current_user_can('ee_read_others_registrations', 'reg_per_event_report')) {
640
+			$inner_date_query .= "LEFT JOIN {$event_table} ON ID = EVT_ID";
641
+			$inner_where .= ' post_author = ' . get_current_user_id() . ' AND';
642
+		}
643
+		$inner_where .= " REG_date >= '{$sql_date}'";
644
+		$inner_date_query .= $inner_where;
645
+		// build main query
646
+		$select = 'SELECT Event.post_title as Registration_Event, ';
647
+		$join = '';
648
+		$join_parts = array();
649
+		$select_parts = array();
650
+		// loop through registration stati to do parts for each status.
651
+		foreach (EEM_Registration::reg_status_array() as $STS_ID => $STS_code) {
652
+			if ($STS_ID === EEM_Registration::status_id_incomplete) {
653
+				continue;
654
+			}
655
+			$select_parts[] = "COUNT({$STS_code}.REG_ID) as {$STS_ID}";
656
+			$join_parts[] = "{$registration_table} AS {$STS_code} ON {$STS_code}.EVT_ID = dates.EVT_ID AND {$STS_code}.STS_ID = '{$STS_ID}' AND {$STS_code}.REG_date = dates.REG_date";
657
+		}
658
+		// setup the selects
659
+		$select .= implode(', ', $select_parts);
660
+		$select .= " FROM ($inner_date_query) AS dates LEFT JOIN $event_table as Event ON Event.ID = dates.EVT_ID LEFT JOIN ";
661
+		// setup remaining joins
662
+		$join .= implode(' LEFT JOIN ', $join_parts);
663
+		// now put it all together
664
+		$query = $select . $join . ' GROUP BY Registration_Event';
665
+		// and execute
666
+		return $wpdb->get_results($query, ARRAY_A);
667
+	}
668
+
669
+
670
+	/**
671
+	 * Returns the EE_Registration of the primary attendee on the transaction id provided
672
+	 *
673
+	 * @param int $TXN_ID
674
+	 * @return EE_Base_Class|EE_Registration|null
675
+	 * @throws EE_Error
676
+	 */
677
+	public function get_primary_registration_for_transaction_ID($TXN_ID = 0)
678
+	{
679
+		if (!$TXN_ID) {
680
+			return null;
681
+		}
682
+		return $this->get_one(array(
683
+			array(
684
+				'TXN_ID' => $TXN_ID,
685
+				'REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT,
686
+			),
687
+		));
688
+	}
689
+
690
+
691
+	/**
692
+	 *        get_event_registration_count
693
+	 *
694
+	 * @access public
695
+	 * @param int $EVT_ID
696
+	 * @param boolean $for_incomplete_payments
697
+	 * @return int
698
+	 * @throws EE_Error
699
+	 */
700
+	public function get_event_registration_count($EVT_ID, $for_incomplete_payments = false)
701
+	{
702
+		// we only count approved registrations towards registration limits
703
+		$query_params = array(array('EVT_ID' => $EVT_ID, 'STS_ID' => self::status_id_approved));
704
+		if ($for_incomplete_payments) {
705
+			$query_params[0]['Transaction.STS_ID'] = array('!=', EEM_Transaction::complete_status_code);
706
+		}
707
+		return $this->count($query_params);
708
+	}
709
+
710
+
711
+	/**
712
+	 * Deletes all registrations with no transactions. Note that this needs to be very efficient
713
+	 * and so it uses wpdb directly
714
+	 *
715
+	 * @global WPDB $wpdb
716
+	 * @return int number deleted
717
+	 * @throws EE_Error
718
+	 */
719
+	public function delete_registrations_with_no_transaction()
720
+	{
721
+		/** @type WPDB $wpdb */
722
+		global $wpdb;
723
+		return $wpdb->query(
724
+			'DELETE r FROM '
725
+			. $this->table()
726
+			. ' r LEFT JOIN '
727
+			. EEM_Transaction::instance()->table()
728
+			. ' t ON r.TXN_ID = t.TXN_ID WHERE t.TXN_ID IS NULL'
729
+		);
730
+	}
731
+
732
+
733
+	/**
734
+	 *  Count registrations checked into (or out of) a datetime
735
+	 *
736
+	 * @param int $DTT_ID datetime ID
737
+	 * @param boolean $checked_in whether to count registrations checked IN or OUT
738
+	 * @return int
739
+	 * @throws EE_Error
740
+	 */
741
+	public function count_registrations_checked_into_datetime($DTT_ID, $checked_in = true)
742
+	{
743
+		global $wpdb;
744
+		// subquery to get latest checkin
745
+		$query = $wpdb->prepare(
746
+			'SELECT '
747
+			. 'COUNT( DISTINCT checkins.REG_ID ) '
748
+			. 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
749
+			. '( SELECT '
750
+			. 'max( CHK_timestamp ) AS latest_checkin, '
751
+			. 'REG_ID AS REG_ID '
752
+			. 'FROM ' . EEM_Checkin::instance()->table() . ' '
753
+			. 'WHERE DTT_ID=%d '
754
+			. 'GROUP BY REG_ID'
755
+			. ') AS most_recent_checkin_per_reg '
756
+			. 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID '
757
+			. 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin '
758
+			. 'WHERE '
759
+			. 'checkins.CHK_in=%d',
760
+			$DTT_ID,
761
+			$checked_in
762
+		);
763
+		return (int) $wpdb->get_var($query);
764
+	}
765
+
766
+
767
+	/**
768
+	 *  Count registrations checked into (or out of) an event.
769
+	 *
770
+	 * @param int $EVT_ID event ID
771
+	 * @param boolean $checked_in whether to count registrations checked IN or OUT
772
+	 * @return int
773
+	 * @throws EE_Error
774
+	 */
775
+	public function count_registrations_checked_into_event($EVT_ID, $checked_in = true)
776
+	{
777
+		global $wpdb;
778
+		// subquery to get latest checkin
779
+		$query = $wpdb->prepare(
780
+			'SELECT '
781
+			. 'COUNT( DISTINCT checkins.REG_ID ) '
782
+			. 'FROM ' . EEM_Checkin::instance()->table() . ' AS checkins INNER JOIN'
783
+			. '( SELECT '
784
+			. 'max( CHK_timestamp ) AS latest_checkin, '
785
+			. 'REG_ID AS REG_ID '
786
+			. 'FROM ' . EEM_Checkin::instance()->table() . ' AS c '
787
+			. 'INNER JOIN ' . EEM_Datetime::instance()->table() . ' AS d '
788
+			. 'ON c.DTT_ID=d.DTT_ID '
789
+			. 'WHERE d.EVT_ID=%d '
790
+			. 'GROUP BY REG_ID'
791
+			. ') AS most_recent_checkin_per_reg '
792
+			. 'ON checkins.REG_ID=most_recent_checkin_per_reg.REG_ID '
793
+			. 'AND checkins.CHK_timestamp = most_recent_checkin_per_reg.latest_checkin '
794
+			. 'WHERE '
795
+			. 'checkins.CHK_in=%d',
796
+			$EVT_ID,
797
+			$checked_in
798
+		);
799
+		return (int) $wpdb->get_var($query);
800
+	}
801
+
802
+
803
+	/**
804
+	 * The purpose of this method is to retrieve an array of
805
+	 * EE_Registration objects that represent the latest registration
806
+	 * for each ATT_ID given in the function argument.
807
+	 *
808
+	 * @param array $attendee_ids
809
+	 * @return EE_Base_Class[]|EE_Registration[]
810
+	 * @throws EE_Error
811
+	 */
812
+	public function get_latest_registration_for_each_of_given_contacts($attendee_ids = array())
813
+	{
814
+		// first do a native wp_query to get the latest REG_ID's matching these attendees.
815
+		global $wpdb;
816
+		$registration_table = $wpdb->prefix . 'esp_registration';
817
+		$attendee_table = $wpdb->posts;
818
+		$attendee_ids = is_array($attendee_ids)
819
+			? array_map('absint', $attendee_ids)
820
+			: array((int) $attendee_ids);
821
+		$ATT_IDs = implode(',', $attendee_ids);
822
+		// first we do a query to get the registration ids
823
+		// (because a group by before order by causes the order by to be ignored.)
824
+		$registration_id_query = "
825 825
 			SELECT registrations.registration_ids as registration_id
826 826
 			FROM (
827 827
 				SELECT
@@ -835,61 +835,61 @@  discard block
 block discarded – undo
835 835
 			  ) AS registrations
836 836
 			  GROUP BY registrations.attendee_ids
837 837
 		";
838
-        $registration_ids = $wpdb->get_results($registration_id_query, ARRAY_A);
839
-        if (empty($registration_ids)) {
840
-            return array();
841
-        }
842
-        $ids_for_model_query = array();
843
-        // let's flatten the ids so they can be used in the model query.
844
-        foreach ($registration_ids as $registration_id) {
845
-            if (isset($registration_id['registration_id'])) {
846
-                $ids_for_model_query[] = $registration_id['registration_id'];
847
-            }
848
-        }
849
-        // construct query
850
-        $_where = array(
851
-            'REG_ID' => array('IN', $ids_for_model_query),
852
-        );
853
-        return $this->get_all(array($_where));
854
-    }
855
-
856
-
857
-
858
-    /**
859
-     * returns a count of registrations for the supplied event having the status as specified
860
-     *
861
-     * @param int $EVT_ID
862
-     * @param array $statuses
863
-     * @return int
864
-     * @throws InvalidArgumentException
865
-     * @throws InvalidStatusException
866
-     * @throws EE_Error
867
-     */
868
-    public function event_reg_count_for_statuses($EVT_ID, $statuses = array())
869
-    {
870
-        $EVT_ID = absint($EVT_ID);
871
-        if (! $EVT_ID) {
872
-            throw new InvalidArgumentException(
873
-                esc_html__('An invalid Event ID was supplied.', 'event_espresso')
874
-            );
875
-        }
876
-        $statuses = is_array($statuses) ? $statuses : array($statuses);
877
-        $statuses = ! empty($statuses) ? $statuses : array(EEM_Registration::status_id_approved);
878
-        $valid_reg_statuses = EEM_Registration::reg_statuses();
879
-        foreach ($statuses as $status) {
880
-            if (! in_array($status, $valid_reg_statuses, true)) {
881
-                throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso'));
882
-            }
883
-        }
884
-        return $this->count(
885
-            array(
886
-                array(
887
-                    'EVT_ID' => $EVT_ID,
888
-                    'STS_ID' => array('IN', $statuses),
889
-                ),
890
-            ),
891
-            'REG_ID',
892
-            true
893
-        );
894
-    }
838
+		$registration_ids = $wpdb->get_results($registration_id_query, ARRAY_A);
839
+		if (empty($registration_ids)) {
840
+			return array();
841
+		}
842
+		$ids_for_model_query = array();
843
+		// let's flatten the ids so they can be used in the model query.
844
+		foreach ($registration_ids as $registration_id) {
845
+			if (isset($registration_id['registration_id'])) {
846
+				$ids_for_model_query[] = $registration_id['registration_id'];
847
+			}
848
+		}
849
+		// construct query
850
+		$_where = array(
851
+			'REG_ID' => array('IN', $ids_for_model_query),
852
+		);
853
+		return $this->get_all(array($_where));
854
+	}
855
+
856
+
857
+
858
+	/**
859
+	 * returns a count of registrations for the supplied event having the status as specified
860
+	 *
861
+	 * @param int $EVT_ID
862
+	 * @param array $statuses
863
+	 * @return int
864
+	 * @throws InvalidArgumentException
865
+	 * @throws InvalidStatusException
866
+	 * @throws EE_Error
867
+	 */
868
+	public function event_reg_count_for_statuses($EVT_ID, $statuses = array())
869
+	{
870
+		$EVT_ID = absint($EVT_ID);
871
+		if (! $EVT_ID) {
872
+			throw new InvalidArgumentException(
873
+				esc_html__('An invalid Event ID was supplied.', 'event_espresso')
874
+			);
875
+		}
876
+		$statuses = is_array($statuses) ? $statuses : array($statuses);
877
+		$statuses = ! empty($statuses) ? $statuses : array(EEM_Registration::status_id_approved);
878
+		$valid_reg_statuses = EEM_Registration::reg_statuses();
879
+		foreach ($statuses as $status) {
880
+			if (! in_array($status, $valid_reg_statuses, true)) {
881
+				throw new InvalidStatusException($status, esc_html__('Registration', 'event_espresso'));
882
+			}
883
+		}
884
+		return $this->count(
885
+			array(
886
+				array(
887
+					'EVT_ID' => $EVT_ID,
888
+					'STS_ID' => array('IN', $statuses),
889
+				),
890
+			),
891
+			'REG_ID',
892
+			true
893
+		);
894
+	}
895 895
 }
Please login to merge, or discard this patch.
core/exceptions/InvalidStatusException.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -8,26 +8,26 @@
 block discarded – undo
8 8
 
9 9
 class InvalidStatusException extends InvalidArgumentException
10 10
 {
11
-    /**
12
-     * InvalidStatusException constructor.
13
-     * @param string $status the invalid status id that was supplied
14
-     * @param string $domain the name of the domain, model, or class that the status belongs to
15
-     * @param string $message custom message
16
-     * @param int $code
17
-     * @param Exception|null $previous
18
-     */
19
-    public function __construct($status, $domain, $message = '', $code = 0, Exception $previous = null)
20
-    {
21
-        if (empty($message)) {
22
-            $message = sprintf(
23
-                __(
24
-                    '"%1$s" is not a valid %2$s status',
25
-                    'event_espresso'
26
-                ),
27
-                $status,
28
-                $domain
29
-            );
30
-        }
31
-        parent::__construct($message, $code, $previous);
32
-    }
11
+	/**
12
+	 * InvalidStatusException constructor.
13
+	 * @param string $status the invalid status id that was supplied
14
+	 * @param string $domain the name of the domain, model, or class that the status belongs to
15
+	 * @param string $message custom message
16
+	 * @param int $code
17
+	 * @param Exception|null $previous
18
+	 */
19
+	public function __construct($status, $domain, $message = '', $code = 0, Exception $previous = null)
20
+	{
21
+		if (empty($message)) {
22
+			$message = sprintf(
23
+				__(
24
+					'"%1$s" is not a valid %2$s status',
25
+					'event_espresso'
26
+				),
27
+				$status,
28
+				$domain
29
+			);
30
+		}
31
+		parent::__construct($message, $code, $previous);
32
+	}
33 33
 }
Please login to merge, or discard this patch.
core/domain/services/admin/AdminToolBar.php 2 patches
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -120,7 +120,7 @@  discard block
 block discarded – undo
120 120
     {
121 121
         wp_register_style(
122 122
             'espresso-admin-toolbar',
123
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-admin-toolbar.css',
123
+            EE_GLOBAL_ASSETS_URL.'css/espresso-admin-toolbar.css',
124 124
             array('dashicons'),
125 125
             EVENT_ESPRESSO_VERSION
126 126
         );
@@ -143,7 +143,7 @@  discard block
 block discarded – undo
143 143
                 'href'  => $this->events_admin_url,
144 144
                 'meta'  => array(
145 145
                     'title' => esc_html__('Event Espresso', 'event_espresso'),
146
-                    'class' => $this->menu_class . 'first',
146
+                    'class' => $this->menu_class.'first',
147 147
                 ),
148 148
             )
149 149
         );
@@ -491,7 +491,7 @@  discard block
 block discarded – undo
491 491
                     'meta'   => array(
492 492
                         'title'  => esc_html__('Approved', 'event_espresso'),
493 493
                         'target' => '',
494
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-approved',
494
+                        'class'  => $this->menu_class.' ee-toolbar-icon-approved',
495 495
                     ),
496 496
                 )
497 497
             );
@@ -528,7 +528,7 @@  discard block
 block discarded – undo
528 528
                     'meta'   => array(
529 529
                         'title'  => esc_html__('Pending Payment', 'event_espresso'),
530 530
                         'target' => '',
531
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-pending',
531
+                        'class'  => $this->menu_class.' ee-toolbar-icon-pending',
532 532
                     ),
533 533
                 )
534 534
             );
@@ -565,7 +565,7 @@  discard block
 block discarded – undo
565 565
                     'meta'   => array(
566 566
                         'title'  => esc_html__('Not Approved', 'event_espresso'),
567 567
                         'target' => '',
568
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-not-approved',
568
+                        'class'  => $this->menu_class.' ee-toolbar-icon-not-approved',
569 569
                     ),
570 570
                 )
571 571
             );
@@ -602,7 +602,7 @@  discard block
 block discarded – undo
602 602
                     'meta'   => array(
603 603
                         'title'  => esc_html__('Cancelled', 'event_espresso'),
604 604
                         'target' => '',
605
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-cancelled',
605
+                        'class'  => $this->menu_class.' ee-toolbar-icon-cancelled',
606 606
                     ),
607 607
                 )
608 608
             );
@@ -674,7 +674,7 @@  discard block
 block discarded – undo
674 674
                     'meta'   => array(
675 675
                         'title'  => esc_html__('Approved', 'event_espresso'),
676 676
                         'target' => '',
677
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-approved',
677
+                        'class'  => $this->menu_class.' ee-toolbar-icon-approved',
678 678
                     ),
679 679
                 )
680 680
             );
@@ -711,7 +711,7 @@  discard block
 block discarded – undo
711 711
                     'meta'   => array(
712 712
                         'title'  => esc_html__('Pending', 'event_espresso'),
713 713
                         'target' => '',
714
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-pending',
714
+                        'class'  => $this->menu_class.' ee-toolbar-icon-pending',
715 715
                     ),
716 716
                 )
717 717
             );
@@ -748,7 +748,7 @@  discard block
 block discarded – undo
748 748
                     'meta'   => array(
749 749
                         'title'  => esc_html__('Not Approved', 'event_espresso'),
750 750
                         'target' => '',
751
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-not-approved',
751
+                        'class'  => $this->menu_class.' ee-toolbar-icon-not-approved',
752 752
                     ),
753 753
                 )
754 754
             );
@@ -785,7 +785,7 @@  discard block
 block discarded – undo
785 785
                     'meta'   => array(
786 786
                         'title'  => esc_html__('Cancelled', 'event_espresso'),
787 787
                         'target' => '',
788
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-cancelled',
788
+                        'class'  => $this->menu_class.' ee-toolbar-icon-cancelled',
789 789
                     ),
790 790
                 )
791 791
             );
Please login to merge, or discard this patch.
Indentation   +737 added lines, -737 removed lines patch added patch discarded remove patch
@@ -19,741 +19,741 @@
 block discarded – undo
19 19
 class AdminToolBar
20 20
 {
21 21
 
22
-    /**
23
-     * @var WP_Admin_Bar $admin_bar
24
-     */
25
-    private $admin_bar;
26
-
27
-    /**
28
-     * @var EE_Capabilities $capabilities
29
-     */
30
-    private $capabilities;
31
-
32
-    /**
33
-     * @var string $events_admin_url
34
-     */
35
-    private $events_admin_url;
36
-
37
-    /**
38
-     * @var string $menu_class
39
-     */
40
-    private $menu_class = 'espresso_menu_item_class';
41
-
42
-    /**
43
-     * @var string $reg_admin_url
44
-     */
45
-    private $reg_admin_url;
46
-
47
-
48
-    /**
49
-     * AdminToolBar constructor.
50
-     *
51
-     * @param EE_Capabilities $capabilities
52
-     */
53
-    public function __construct(EE_Capabilities $capabilities)
54
-    {
55
-        $this->capabilities = $capabilities;
56
-        add_action('admin_bar_menu', array($this, 'espressoToolbarItems'), 100);
57
-        $this->enqueueAssets();
58
-    }
59
-
60
-
61
-    /**
62
-     *    espresso_toolbar_items
63
-     *
64
-     * @access public
65
-     * @param  WP_Admin_Bar $admin_bar
66
-     * @return void
67
-     */
68
-    public function espressoToolbarItems(WP_Admin_Bar $admin_bar)
69
-    {
70
-        // if its an AJAX request, or user is NOT an admin, or in full M-Mode
71
-        if (defined('DOING_AJAX')
72
-            || ! $this->capabilities->current_user_can('ee_read_ee', 'ee_admin_bar_menu_top_level')
73
-            || EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
74
-        ) {
75
-            return;
76
-        }
77
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
78
-        $this->admin_bar = $admin_bar;
79
-        // we don't use the constants EVENTS_ADMIN_URL or REG_ADMIN_URL
80
-        // because they're only defined in each of their respective constructors
81
-        // and this might be a frontend request, in which case they aren't available
82
-        $this->events_admin_url = admin_url('admin.php?page=espresso_events');
83
-        $this->reg_admin_url = admin_url('admin.php?page=espresso_registrations');
84
-        // now let's add all of the menu items
85
-        $this->addTopLevelMenu();
86
-        $this->addEventsSubMenu();
87
-        $this->addEventsAddEditHeader();
88
-        $this->addEventsAddNew();
89
-        $this->addEventsEditCurrentEvent();
90
-        $this->addEventsViewHeader();
91
-        $this->addEventsViewAll();
92
-        $this->addEventsViewToday();
93
-        $this->addEventsViewThisMonth();
94
-        $this->addRegistrationSubMenu();
95
-        $this->addRegistrationOverviewToday();
96
-        $this->addRegistrationOverviewTodayApproved();
97
-        $this->addRegistrationOverviewTodayPendingPayment();
98
-        $this->addRegistrationOverviewTodayNotApproved();
99
-        $this->addRegistrationOverviewTodayCancelled();
100
-        $this->addRegistrationOverviewThisMonth();
101
-        $this->addRegistrationOverviewThisMonthApproved();
102
-        $this->addRegistrationOverviewThisMonthPending();
103
-        $this->addRegistrationOverviewThisMonthNotApproved();
104
-        $this->addRegistrationOverviewThisMonthCancelled();
105
-        $this->addExtensionsAndServices();
106
-    }
107
-
108
-
109
-    /**
110
-     * @return void
111
-     */
112
-    private function enqueueAssets()
113
-    {
114
-        wp_register_style(
115
-            'espresso-admin-toolbar',
116
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-admin-toolbar.css',
117
-            array('dashicons'),
118
-            EVENT_ESPRESSO_VERSION
119
-        );
120
-        wp_enqueue_style('espresso-admin-toolbar');
121
-    }
122
-
123
-
124
-    /**
125
-     * @return void
126
-     */
127
-    private function addTopLevelMenu()
128
-    {
129
-        $this->admin_bar->add_menu(
130
-            array(
131
-                'id'    => 'espresso-toolbar',
132
-                'title' => '<span class="ee-icon ee-icon-ee-cup-thick ee-icon-size-20"></span><span class="ab-label">'
133
-                           . esc_html_x('Event Espresso', 'admin bar menu group label', 'event_espresso')
134
-                           . '</span>',
135
-                'href'  => $this->events_admin_url,
136
-                'meta'  => array(
137
-                    'title' => esc_html__('Event Espresso', 'event_espresso'),
138
-                    'class' => $this->menu_class . 'first',
139
-                ),
140
-            )
141
-        );
142
-    }
143
-
144
-
145
-    /**
146
-     * @return void
147
-     */
148
-    private function addEventsSubMenu()
149
-    {
150
-        if ($this->capabilities->current_user_can(
151
-            'ee_read_events',
152
-            'ee_admin_bar_menu_espresso-toolbar-events'
153
-        )
154
-        ) {
155
-            $this->admin_bar->add_menu(
156
-                array(
157
-                    'id'     => 'espresso-toolbar-events',
158
-                    'parent' => 'espresso-toolbar',
159
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
160
-                                . esc_html__('Events', 'event_espresso'),
161
-                    'href'   => $this->events_admin_url,
162
-                    'meta'   => array(
163
-                        'title'  => esc_html__('Events', 'event_espresso'),
164
-                        'target' => '',
165
-                        'class'  => $this->menu_class,
166
-                    ),
167
-                )
168
-            );
169
-        }
170
-    }
171
-
172
-
173
-    /**
174
-     * @return void
175
-     */
176
-    private function addEventsAddEditHeader()
177
-    {
178
-        if ($this->capabilities->current_user_can(
179
-            'ee_read_events',
180
-            'ee_admin_bar_menu_espresso-toolbar-events-view'
181
-        )
182
-        ) {
183
-            $this->admin_bar->add_menu(
184
-                array(
185
-                    'id'     => 'espresso-toolbar-events-add-edit',
186
-                    'parent' => 'espresso-toolbar-events',
187
-                    'title'  => esc_html__('Add / Edit', 'event_espresso'),
188
-                    'href'   => '',
189
-                )
190
-            );
191
-        }
192
-    }
193
-
194
-
195
-    /**
196
-     * @return void
197
-     */
198
-    private function addEventsAddNew()
199
-    {
200
-        if ($this->capabilities->current_user_can(
201
-            'ee_edit_events',
202
-            'ee_admin_bar_menu_espresso-toolbar-events-new'
203
-        )) {
204
-            $this->admin_bar->add_menu(
205
-                array(
206
-                    'id'     => 'espresso-toolbar-events-new',
207
-                    'parent' => 'espresso-toolbar-events',
208
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
209
-                                . esc_html__('Add New', 'event_espresso'),
210
-                    'href'   => EEH_URL::add_query_args_and_nonce(
211
-                        array('action' => 'create_new'),
212
-                        $this->events_admin_url
213
-                    ),
214
-                    'meta'   => array(
215
-                        'title'  => esc_html__('Add New', 'event_espresso'),
216
-                        'target' => '',
217
-                        'class'  => $this->menu_class,
218
-                    ),
219
-                )
220
-            );
221
-        }
222
-    }
223
-
224
-
225
-    /**
226
-     * @return void
227
-     */
228
-    private function addEventsEditCurrentEvent()
229
-    {
230
-        if (is_single() && (get_post_type() === 'espresso_events')) {
231
-            // Current post
232
-            global $post;
233
-            if ($this->capabilities->current_user_can(
234
-                'ee_edit_event',
235
-                'ee_admin_bar_menu_espresso-toolbar-events-edit',
236
-                $post->ID
237
-            )) {
238
-                $this->admin_bar->add_menu(
239
-                    array(
240
-                        'id'     => 'espresso-toolbar-events-edit',
241
-                        'parent' => 'espresso-toolbar-events',
242
-                        'title'  => '<span class="ee-toolbar-icon"></span>'
243
-                                    . esc_html__('Edit Event', 'event_espresso'),
244
-                        'href'   => EEH_URL::add_query_args_and_nonce(
245
-                            array(
246
-                                'action' => 'edit',
247
-                                'post'   => $post->ID,
248
-                            ),
249
-                            $this->events_admin_url
250
-                        ),
251
-                        'meta'   => array(
252
-                            'title'  => esc_html__('Edit Event', 'event_espresso'),
253
-                            'target' => '',
254
-                            'class'  => $this->menu_class,
255
-                        ),
256
-                    )
257
-                );
258
-            }
259
-        }
260
-    }
261
-
262
-
263
-    /**
264
-     * @return void
265
-     */
266
-    private function addEventsViewHeader()
267
-    {
268
-        if ($this->capabilities->current_user_can(
269
-            'ee_read_events',
270
-            'ee_admin_bar_menu_espresso-toolbar-events-view'
271
-        )) {
272
-            $this->admin_bar->add_menu(
273
-                array(
274
-                    'id'     => 'espresso-toolbar-events-view',
275
-                    'parent' => 'espresso-toolbar-events',
276
-                    'title'  => esc_html__('View', 'event_espresso'),
277
-                    'href'   => '',
278
-                )
279
-            );
280
-        }
281
-    }
282
-
283
-
284
-    /**
285
-     * @return void
286
-     */
287
-    private function addEventsViewAll()
288
-    {
289
-        if ($this->capabilities->current_user_can(
290
-            'ee_read_events',
291
-            'ee_admin_bar_menu_espresso-toolbar-events-all'
292
-        )) {
293
-            $this->admin_bar->add_menu(
294
-                array(
295
-                    'id'     => 'espresso-toolbar-events-all',
296
-                    'parent' => 'espresso-toolbar-events',
297
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
298
-                                . esc_html__('All', 'event_espresso'),
299
-                    'href'   => $this->events_admin_url,
300
-                    'meta'   => array(
301
-                        'title'  => esc_html__('All', 'event_espresso'),
302
-                        'target' => '',
303
-                        'class'  => $this->menu_class,
304
-                    ),
305
-                )
306
-            );
307
-        }
308
-    }
309
-
310
-
311
-    /**
312
-     * @return void
313
-     */
314
-    private function addEventsViewToday()
315
-    {
316
-        if ($this->capabilities->current_user_can(
317
-            'ee_read_events',
318
-            'ee_admin_bar_menu_espresso-toolbar-events-today'
319
-        )) {
320
-            $this->admin_bar->add_menu(
321
-                array(
322
-                    'id'     => 'espresso-toolbar-events-today',
323
-                    'parent' => 'espresso-toolbar-events',
324
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
325
-                                . esc_html__('Today', 'event_espresso'),
326
-                    'href'   => EEH_URL::add_query_args_and_nonce(
327
-                        array(
328
-                            'action' => 'default',
329
-                            'status' => 'today',
330
-                        ),
331
-                        $this->events_admin_url
332
-                    ),
333
-                    'meta'   => array(
334
-                        'title'  => esc_html__('Today', 'event_espresso'),
335
-                        'target' => '',
336
-                        'class'  => $this->menu_class,
337
-                    ),
338
-                )
339
-            );
340
-        }
341
-    }
342
-
343
-
344
-    /**
345
-     * @return void
346
-     */
347
-    private function addEventsViewThisMonth()
348
-    {
349
-        if ($this->capabilities->current_user_can(
350
-            'ee_read_events',
351
-            'ee_admin_bar_menu_espresso-toolbar-events-month'
352
-        )) {
353
-            $this->admin_bar->add_menu(
354
-                array(
355
-                    'id'     => 'espresso-toolbar-events-month',
356
-                    'parent' => 'espresso-toolbar-events',
357
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
358
-                                . esc_html__('This Month', 'event_espresso'),
359
-                    'href'   => EEH_URL::add_query_args_and_nonce(
360
-                        array(
361
-                            'action' => 'default',
362
-                            'status' => 'month',
363
-                        ),
364
-                        $this->events_admin_url
365
-                    ),
366
-                    'meta'   => array(
367
-                        'title'  => esc_html__('This Month', 'event_espresso'),
368
-                        'target' => '',
369
-                        'class'  => $this->menu_class,
370
-                    ),
371
-                )
372
-            );
373
-        }
374
-    }
375
-
376
-
377
-    /**
378
-     * @return void
379
-     */
380
-    private function addRegistrationSubMenu()
381
-    {
382
-        if ($this->capabilities->current_user_can(
383
-            'ee_read_registrations',
384
-            'ee_admin_bar_menu_espresso-toolbar-registrations'
385
-        )) {
386
-            $this->admin_bar->add_menu(
387
-                array(
388
-                    'id'     => 'espresso-toolbar-registrations',
389
-                    'parent' => 'espresso-toolbar',
390
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
391
-                                . esc_html__('Registrations', 'event_espresso'),
392
-                    'href'   => $this->reg_admin_url,
393
-                    'meta'   => array(
394
-                        'title'  => esc_html__('Registrations', 'event_espresso'),
395
-                        'target' => '',
396
-                        'class'  => $this->menu_class,
397
-                    ),
398
-                )
399
-            );
400
-        }
401
-    }
402
-
403
-
404
-    /**
405
-     * @return void
406
-     */
407
-    private function addRegistrationOverviewToday()
408
-    {
409
-        if ($this->capabilities->current_user_can(
410
-            'ee_read_registrations',
411
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today'
412
-        )) {
413
-            $this->admin_bar->add_menu(
414
-                array(
415
-                    'id'     => 'espresso-toolbar-registrations-today',
416
-                    'parent' => 'espresso-toolbar-registrations',
417
-                    'title'  => esc_html__('Today', 'event_espresso'),
418
-                    'href'   => '',
419
-                    'meta'   => array(
420
-                        'title'  => esc_html__('Today', 'event_espresso'),
421
-                        'target' => '',
422
-                        'class'  => $this->menu_class,
423
-                    ),
424
-                )
425
-            );
426
-        }
427
-    }
428
-
429
-
430
-    /**
431
-     * @return void
432
-     */
433
-    private function addRegistrationOverviewTodayApproved()
434
-    {
435
-        if ($this->capabilities->current_user_can(
436
-            'ee_read_registrations',
437
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-approved'
438
-        )) {
439
-            $this->admin_bar->add_menu(
440
-                array(
441
-                    'id'     => 'espresso-toolbar-registrations-today-approved',
442
-                    'parent' => 'espresso-toolbar-registrations',
443
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
444
-                                . esc_html__('Approved', 'event_espresso'),
445
-                    'href'   => EEH_URL::add_query_args_and_nonce(
446
-                        array(
447
-                            'action'      => 'default',
448
-                            'status'      => 'today',
449
-                            '_reg_status' => EEM_Registration::status_id_approved,
450
-                        ),
451
-                        $this->reg_admin_url
452
-                    ),
453
-                    'meta'   => array(
454
-                        'title'  => esc_html__('Approved', 'event_espresso'),
455
-                        'target' => '',
456
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-approved',
457
-                    ),
458
-                )
459
-            );
460
-        }
461
-    }
462
-
463
-
464
-    /**
465
-     * @return void
466
-     */
467
-    private function addRegistrationOverviewTodayPendingPayment()
468
-    {
469
-        if ($this->capabilities->current_user_can(
470
-            'ee_read_registrations',
471
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-pending'
472
-        )) {
473
-            $this->admin_bar->add_menu(
474
-                array(
475
-                    'id'     => 'espresso-toolbar-registrations-today-pending',
476
-                    'parent' => 'espresso-toolbar-registrations',
477
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
478
-                                . esc_html__('Pending', 'event_espresso'),
479
-                    'href'   => EEH_URL::add_query_args_and_nonce(
480
-                        array(
481
-                            'action'      => 'default',
482
-                            'status'      => 'today',
483
-                            '_reg_status' => EEM_Registration::status_id_pending_payment,
484
-                        ),
485
-                        $this->reg_admin_url
486
-                    ),
487
-                    'meta'   => array(
488
-                        'title'  => esc_html__('Pending Payment', 'event_espresso'),
489
-                        'target' => '',
490
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-pending',
491
-                    ),
492
-                )
493
-            );
494
-        }
495
-    }
496
-
497
-
498
-    /**
499
-     * @return void
500
-     */
501
-    private function addRegistrationOverviewTodayNotApproved()
502
-    {
503
-        if ($this->capabilities->current_user_can(
504
-            'ee_read_registrations',
505
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-not-approved'
506
-        )) {
507
-            $this->admin_bar->add_menu(
508
-                array(
509
-                    'id'     => 'espresso-toolbar-registrations-today-not-approved',
510
-                    'parent' => 'espresso-toolbar-registrations',
511
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
512
-                                . esc_html__('Not Approved', 'event_espresso'),
513
-                    'href'   => EEH_URL::add_query_args_and_nonce(
514
-                        array(
515
-                            'action'      => 'default',
516
-                            'status'      => 'today',
517
-                            '_reg_status' => EEM_Registration::status_id_not_approved,
518
-                        ),
519
-                        $this->reg_admin_url
520
-                    ),
521
-                    'meta'   => array(
522
-                        'title'  => esc_html__('Not Approved', 'event_espresso'),
523
-                        'target' => '',
524
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-not-approved',
525
-                    ),
526
-                )
527
-            );
528
-        }
529
-    }
530
-
531
-
532
-    /**
533
-     * @return void
534
-     */
535
-    private function addRegistrationOverviewTodayCancelled()
536
-    {
537
-        if ($this->capabilities->current_user_can(
538
-            'ee_read_registrations',
539
-            'ee_admin_bar_menu_espresso-toolbar-registrations-today-cancelled'
540
-        )) {
541
-            $this->admin_bar->add_menu(
542
-                array(
543
-                    'id'     => 'espresso-toolbar-registrations-today-cancelled',
544
-                    'parent' => 'espresso-toolbar-registrations',
545
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
546
-                                . esc_html__('Cancelled', 'event_espresso'),
547
-                    'href'   => EEH_URL::add_query_args_and_nonce(
548
-                        array(
549
-                            'action'      => 'default',
550
-                            'status'      => 'today',
551
-                            '_reg_status' => EEM_Registration::status_id_cancelled,
552
-                        ),
553
-                        $this->reg_admin_url
554
-                    ),
555
-                    'meta'   => array(
556
-                        'title'  => esc_html__('Cancelled', 'event_espresso'),
557
-                        'target' => '',
558
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-cancelled',
559
-                    ),
560
-                )
561
-            );
562
-        }
563
-    }
564
-
565
-
566
-    /**
567
-     * @return void
568
-     */
569
-    private function addRegistrationOverviewThisMonth()
570
-    {
571
-        if ($this->capabilities->current_user_can(
572
-            'ee_read_registrations',
573
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month'
574
-        )) {
575
-            $this->admin_bar->add_menu(
576
-                array(
577
-                    'id'     => 'espresso-toolbar-registrations-month',
578
-                    'parent' => 'espresso-toolbar-registrations',
579
-                    'title'  => esc_html__('This Month', 'event_espresso'),
580
-                    'href'   => '', // EEH_URL::add_query_args_and_nonce(
581
-                    //     array(
582
-                    //         'action' => 'default',
583
-                    //         'status' => 'month'
584
-                    //     ),
585
-                    //     $this->reg_admin_url
586
-                    // ),
587
-                    'meta'   => array(
588
-                        'title'  => esc_html__('This Month', 'event_espresso'),
589
-                        'target' => '',
590
-                        'class'  => $this->menu_class,
591
-                    ),
592
-                )
593
-            );
594
-        }
595
-    }
596
-
597
-
598
-    /**
599
-     * @return void
600
-     */
601
-    private function addRegistrationOverviewThisMonthApproved()
602
-    {
603
-        if ($this->capabilities->current_user_can(
604
-            'ee_read_registrations',
605
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-approved'
606
-        )) {
607
-            $this->admin_bar->add_menu(
608
-                array(
609
-                    'id'     => 'espresso-toolbar-registrations-month-approved',
610
-                    'parent' => 'espresso-toolbar-registrations',
611
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
612
-                                . esc_html__('Approved', 'event_espresso'),
613
-                    'href'   => EEH_URL::add_query_args_and_nonce(
614
-                        array(
615
-                            'action'      => 'default',
616
-                            'status'      => 'month',
617
-                            '_reg_status' => EEM_Registration::status_id_approved,
618
-                        ),
619
-                        $this->reg_admin_url
620
-                    ),
621
-                    'meta'   => array(
622
-                        'title'  => esc_html__('Approved', 'event_espresso'),
623
-                        'target' => '',
624
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-approved',
625
-                    ),
626
-                )
627
-            );
628
-        }
629
-    }
630
-
631
-
632
-    /**
633
-     * @return void
634
-     */
635
-    private function addRegistrationOverviewThisMonthPending()
636
-    {
637
-        if ($this->capabilities->current_user_can(
638
-            'ee_read_registrations',
639
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-pending'
640
-        )) {
641
-            $this->admin_bar->add_menu(
642
-                array(
643
-                    'id'     => 'espresso-toolbar-registrations-month-pending',
644
-                    'parent' => 'espresso-toolbar-registrations',
645
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
646
-                                . esc_html__('Pending', 'event_espresso'),
647
-                    'href'   => EEH_URL::add_query_args_and_nonce(
648
-                        array(
649
-                            'action'      => 'default',
650
-                            'status'      => 'month',
651
-                            '_reg_status' => EEM_Registration::status_id_pending_payment,
652
-                        ),
653
-                        $this->reg_admin_url
654
-                    ),
655
-                    'meta'   => array(
656
-                        'title'  => esc_html__('Pending', 'event_espresso'),
657
-                        'target' => '',
658
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-pending',
659
-                    ),
660
-                )
661
-            );
662
-        }
663
-    }
664
-
665
-
666
-    /**
667
-     * @return void
668
-     */
669
-    private function addRegistrationOverviewThisMonthNotApproved()
670
-    {
671
-        if ($this->capabilities->current_user_can(
672
-            'ee_read_registrations',
673
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-not-approved'
674
-        )) {
675
-            $this->admin_bar->add_menu(
676
-                array(
677
-                    'id'     => 'espresso-toolbar-registrations-month-not-approved',
678
-                    'parent' => 'espresso-toolbar-registrations',
679
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
680
-                                . esc_html__('Not Approved', 'event_espresso'),
681
-                    'href'   => EEH_URL::add_query_args_and_nonce(
682
-                        array(
683
-                            'action'      => 'default',
684
-                            'status'      => 'month',
685
-                            '_reg_status' => EEM_Registration::status_id_not_approved,
686
-                        ),
687
-                        $this->reg_admin_url
688
-                    ),
689
-                    'meta'   => array(
690
-                        'title'  => esc_html__('Not Approved', 'event_espresso'),
691
-                        'target' => '',
692
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-not-approved',
693
-                    ),
694
-                )
695
-            );
696
-        }
697
-    }
698
-
699
-
700
-    /**
701
-     * @return void
702
-     */
703
-    private function addRegistrationOverviewThisMonthCancelled()
704
-    {
705
-        if ($this->capabilities->current_user_can(
706
-            'ee_read_registrations',
707
-            'ee_admin_bar_menu_espresso-toolbar-registrations-month-cancelled'
708
-        )) {
709
-            $this->admin_bar->add_menu(
710
-                array(
711
-                    'id'     => 'espresso-toolbar-registrations-month-cancelled',
712
-                    'parent' => 'espresso-toolbar-registrations',
713
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
714
-                                . esc_html__('Cancelled', 'event_espresso'),
715
-                    'href'   => EEH_URL::add_query_args_and_nonce(
716
-                        array(
717
-                            'action'      => 'default',
718
-                            'status'      => 'month',
719
-                            '_reg_status' => EEM_Registration::status_id_cancelled,
720
-                        ),
721
-                        $this->reg_admin_url
722
-                    ),
723
-                    'meta'   => array(
724
-                        'title'  => esc_html__('Cancelled', 'event_espresso'),
725
-                        'target' => '',
726
-                        'class'  => $this->menu_class . ' ee-toolbar-icon-cancelled',
727
-                    ),
728
-                )
729
-            );
730
-        }
731
-    }
732
-
733
-
734
-    /**
735
-     * @return void
736
-     */
737
-    private function addExtensionsAndServices()
738
-    {
739
-        if ($this->capabilities->current_user_can(
740
-            'ee_read_ee',
741
-            'ee_admin_bar_menu_espresso-toolbar-extensions-and-services'
742
-        )) {
743
-            $this->admin_bar->add_menu(
744
-                array(
745
-                    'id'     => 'espresso-toolbar-extensions-and-services',
746
-                    'parent' => 'espresso-toolbar',
747
-                    'title'  => '<span class="ee-toolbar-icon"></span>'
748
-                                . esc_html__('Extensions & Services', 'event_espresso'),
749
-                    'href'   => admin_url('admin.php?page=espresso_packages'),
750
-                    'meta'   => array(
751
-                        'title'  => esc_html__('Extensions & Services', 'event_espresso'),
752
-                        'target' => '',
753
-                        'class'  => $this->menu_class,
754
-                    ),
755
-                )
756
-            );
757
-        }
758
-    }
22
+	/**
23
+	 * @var WP_Admin_Bar $admin_bar
24
+	 */
25
+	private $admin_bar;
26
+
27
+	/**
28
+	 * @var EE_Capabilities $capabilities
29
+	 */
30
+	private $capabilities;
31
+
32
+	/**
33
+	 * @var string $events_admin_url
34
+	 */
35
+	private $events_admin_url;
36
+
37
+	/**
38
+	 * @var string $menu_class
39
+	 */
40
+	private $menu_class = 'espresso_menu_item_class';
41
+
42
+	/**
43
+	 * @var string $reg_admin_url
44
+	 */
45
+	private $reg_admin_url;
46
+
47
+
48
+	/**
49
+	 * AdminToolBar constructor.
50
+	 *
51
+	 * @param EE_Capabilities $capabilities
52
+	 */
53
+	public function __construct(EE_Capabilities $capabilities)
54
+	{
55
+		$this->capabilities = $capabilities;
56
+		add_action('admin_bar_menu', array($this, 'espressoToolbarItems'), 100);
57
+		$this->enqueueAssets();
58
+	}
59
+
60
+
61
+	/**
62
+	 *    espresso_toolbar_items
63
+	 *
64
+	 * @access public
65
+	 * @param  WP_Admin_Bar $admin_bar
66
+	 * @return void
67
+	 */
68
+	public function espressoToolbarItems(WP_Admin_Bar $admin_bar)
69
+	{
70
+		// if its an AJAX request, or user is NOT an admin, or in full M-Mode
71
+		if (defined('DOING_AJAX')
72
+			|| ! $this->capabilities->current_user_can('ee_read_ee', 'ee_admin_bar_menu_top_level')
73
+			|| EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
74
+		) {
75
+			return;
76
+		}
77
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
78
+		$this->admin_bar = $admin_bar;
79
+		// we don't use the constants EVENTS_ADMIN_URL or REG_ADMIN_URL
80
+		// because they're only defined in each of their respective constructors
81
+		// and this might be a frontend request, in which case they aren't available
82
+		$this->events_admin_url = admin_url('admin.php?page=espresso_events');
83
+		$this->reg_admin_url = admin_url('admin.php?page=espresso_registrations');
84
+		// now let's add all of the menu items
85
+		$this->addTopLevelMenu();
86
+		$this->addEventsSubMenu();
87
+		$this->addEventsAddEditHeader();
88
+		$this->addEventsAddNew();
89
+		$this->addEventsEditCurrentEvent();
90
+		$this->addEventsViewHeader();
91
+		$this->addEventsViewAll();
92
+		$this->addEventsViewToday();
93
+		$this->addEventsViewThisMonth();
94
+		$this->addRegistrationSubMenu();
95
+		$this->addRegistrationOverviewToday();
96
+		$this->addRegistrationOverviewTodayApproved();
97
+		$this->addRegistrationOverviewTodayPendingPayment();
98
+		$this->addRegistrationOverviewTodayNotApproved();
99
+		$this->addRegistrationOverviewTodayCancelled();
100
+		$this->addRegistrationOverviewThisMonth();
101
+		$this->addRegistrationOverviewThisMonthApproved();
102
+		$this->addRegistrationOverviewThisMonthPending();
103
+		$this->addRegistrationOverviewThisMonthNotApproved();
104
+		$this->addRegistrationOverviewThisMonthCancelled();
105
+		$this->addExtensionsAndServices();
106
+	}
107
+
108
+
109
+	/**
110
+	 * @return void
111
+	 */
112
+	private function enqueueAssets()
113
+	{
114
+		wp_register_style(
115
+			'espresso-admin-toolbar',
116
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-admin-toolbar.css',
117
+			array('dashicons'),
118
+			EVENT_ESPRESSO_VERSION
119
+		);
120
+		wp_enqueue_style('espresso-admin-toolbar');
121
+	}
122
+
123
+
124
+	/**
125
+	 * @return void
126
+	 */
127
+	private function addTopLevelMenu()
128
+	{
129
+		$this->admin_bar->add_menu(
130
+			array(
131
+				'id'    => 'espresso-toolbar',
132
+				'title' => '<span class="ee-icon ee-icon-ee-cup-thick ee-icon-size-20"></span><span class="ab-label">'
133
+						   . esc_html_x('Event Espresso', 'admin bar menu group label', 'event_espresso')
134
+						   . '</span>',
135
+				'href'  => $this->events_admin_url,
136
+				'meta'  => array(
137
+					'title' => esc_html__('Event Espresso', 'event_espresso'),
138
+					'class' => $this->menu_class . 'first',
139
+				),
140
+			)
141
+		);
142
+	}
143
+
144
+
145
+	/**
146
+	 * @return void
147
+	 */
148
+	private function addEventsSubMenu()
149
+	{
150
+		if ($this->capabilities->current_user_can(
151
+			'ee_read_events',
152
+			'ee_admin_bar_menu_espresso-toolbar-events'
153
+		)
154
+		) {
155
+			$this->admin_bar->add_menu(
156
+				array(
157
+					'id'     => 'espresso-toolbar-events',
158
+					'parent' => 'espresso-toolbar',
159
+					'title'  => '<span class="ee-toolbar-icon"></span>'
160
+								. esc_html__('Events', 'event_espresso'),
161
+					'href'   => $this->events_admin_url,
162
+					'meta'   => array(
163
+						'title'  => esc_html__('Events', 'event_espresso'),
164
+						'target' => '',
165
+						'class'  => $this->menu_class,
166
+					),
167
+				)
168
+			);
169
+		}
170
+	}
171
+
172
+
173
+	/**
174
+	 * @return void
175
+	 */
176
+	private function addEventsAddEditHeader()
177
+	{
178
+		if ($this->capabilities->current_user_can(
179
+			'ee_read_events',
180
+			'ee_admin_bar_menu_espresso-toolbar-events-view'
181
+		)
182
+		) {
183
+			$this->admin_bar->add_menu(
184
+				array(
185
+					'id'     => 'espresso-toolbar-events-add-edit',
186
+					'parent' => 'espresso-toolbar-events',
187
+					'title'  => esc_html__('Add / Edit', 'event_espresso'),
188
+					'href'   => '',
189
+				)
190
+			);
191
+		}
192
+	}
193
+
194
+
195
+	/**
196
+	 * @return void
197
+	 */
198
+	private function addEventsAddNew()
199
+	{
200
+		if ($this->capabilities->current_user_can(
201
+			'ee_edit_events',
202
+			'ee_admin_bar_menu_espresso-toolbar-events-new'
203
+		)) {
204
+			$this->admin_bar->add_menu(
205
+				array(
206
+					'id'     => 'espresso-toolbar-events-new',
207
+					'parent' => 'espresso-toolbar-events',
208
+					'title'  => '<span class="ee-toolbar-icon"></span>'
209
+								. esc_html__('Add New', 'event_espresso'),
210
+					'href'   => EEH_URL::add_query_args_and_nonce(
211
+						array('action' => 'create_new'),
212
+						$this->events_admin_url
213
+					),
214
+					'meta'   => array(
215
+						'title'  => esc_html__('Add New', 'event_espresso'),
216
+						'target' => '',
217
+						'class'  => $this->menu_class,
218
+					),
219
+				)
220
+			);
221
+		}
222
+	}
223
+
224
+
225
+	/**
226
+	 * @return void
227
+	 */
228
+	private function addEventsEditCurrentEvent()
229
+	{
230
+		if (is_single() && (get_post_type() === 'espresso_events')) {
231
+			// Current post
232
+			global $post;
233
+			if ($this->capabilities->current_user_can(
234
+				'ee_edit_event',
235
+				'ee_admin_bar_menu_espresso-toolbar-events-edit',
236
+				$post->ID
237
+			)) {
238
+				$this->admin_bar->add_menu(
239
+					array(
240
+						'id'     => 'espresso-toolbar-events-edit',
241
+						'parent' => 'espresso-toolbar-events',
242
+						'title'  => '<span class="ee-toolbar-icon"></span>'
243
+									. esc_html__('Edit Event', 'event_espresso'),
244
+						'href'   => EEH_URL::add_query_args_and_nonce(
245
+							array(
246
+								'action' => 'edit',
247
+								'post'   => $post->ID,
248
+							),
249
+							$this->events_admin_url
250
+						),
251
+						'meta'   => array(
252
+							'title'  => esc_html__('Edit Event', 'event_espresso'),
253
+							'target' => '',
254
+							'class'  => $this->menu_class,
255
+						),
256
+					)
257
+				);
258
+			}
259
+		}
260
+	}
261
+
262
+
263
+	/**
264
+	 * @return void
265
+	 */
266
+	private function addEventsViewHeader()
267
+	{
268
+		if ($this->capabilities->current_user_can(
269
+			'ee_read_events',
270
+			'ee_admin_bar_menu_espresso-toolbar-events-view'
271
+		)) {
272
+			$this->admin_bar->add_menu(
273
+				array(
274
+					'id'     => 'espresso-toolbar-events-view',
275
+					'parent' => 'espresso-toolbar-events',
276
+					'title'  => esc_html__('View', 'event_espresso'),
277
+					'href'   => '',
278
+				)
279
+			);
280
+		}
281
+	}
282
+
283
+
284
+	/**
285
+	 * @return void
286
+	 */
287
+	private function addEventsViewAll()
288
+	{
289
+		if ($this->capabilities->current_user_can(
290
+			'ee_read_events',
291
+			'ee_admin_bar_menu_espresso-toolbar-events-all'
292
+		)) {
293
+			$this->admin_bar->add_menu(
294
+				array(
295
+					'id'     => 'espresso-toolbar-events-all',
296
+					'parent' => 'espresso-toolbar-events',
297
+					'title'  => '<span class="ee-toolbar-icon"></span>'
298
+								. esc_html__('All', 'event_espresso'),
299
+					'href'   => $this->events_admin_url,
300
+					'meta'   => array(
301
+						'title'  => esc_html__('All', 'event_espresso'),
302
+						'target' => '',
303
+						'class'  => $this->menu_class,
304
+					),
305
+				)
306
+			);
307
+		}
308
+	}
309
+
310
+
311
+	/**
312
+	 * @return void
313
+	 */
314
+	private function addEventsViewToday()
315
+	{
316
+		if ($this->capabilities->current_user_can(
317
+			'ee_read_events',
318
+			'ee_admin_bar_menu_espresso-toolbar-events-today'
319
+		)) {
320
+			$this->admin_bar->add_menu(
321
+				array(
322
+					'id'     => 'espresso-toolbar-events-today',
323
+					'parent' => 'espresso-toolbar-events',
324
+					'title'  => '<span class="ee-toolbar-icon"></span>'
325
+								. esc_html__('Today', 'event_espresso'),
326
+					'href'   => EEH_URL::add_query_args_and_nonce(
327
+						array(
328
+							'action' => 'default',
329
+							'status' => 'today',
330
+						),
331
+						$this->events_admin_url
332
+					),
333
+					'meta'   => array(
334
+						'title'  => esc_html__('Today', 'event_espresso'),
335
+						'target' => '',
336
+						'class'  => $this->menu_class,
337
+					),
338
+				)
339
+			);
340
+		}
341
+	}
342
+
343
+
344
+	/**
345
+	 * @return void
346
+	 */
347
+	private function addEventsViewThisMonth()
348
+	{
349
+		if ($this->capabilities->current_user_can(
350
+			'ee_read_events',
351
+			'ee_admin_bar_menu_espresso-toolbar-events-month'
352
+		)) {
353
+			$this->admin_bar->add_menu(
354
+				array(
355
+					'id'     => 'espresso-toolbar-events-month',
356
+					'parent' => 'espresso-toolbar-events',
357
+					'title'  => '<span class="ee-toolbar-icon"></span>'
358
+								. esc_html__('This Month', 'event_espresso'),
359
+					'href'   => EEH_URL::add_query_args_and_nonce(
360
+						array(
361
+							'action' => 'default',
362
+							'status' => 'month',
363
+						),
364
+						$this->events_admin_url
365
+					),
366
+					'meta'   => array(
367
+						'title'  => esc_html__('This Month', 'event_espresso'),
368
+						'target' => '',
369
+						'class'  => $this->menu_class,
370
+					),
371
+				)
372
+			);
373
+		}
374
+	}
375
+
376
+
377
+	/**
378
+	 * @return void
379
+	 */
380
+	private function addRegistrationSubMenu()
381
+	{
382
+		if ($this->capabilities->current_user_can(
383
+			'ee_read_registrations',
384
+			'ee_admin_bar_menu_espresso-toolbar-registrations'
385
+		)) {
386
+			$this->admin_bar->add_menu(
387
+				array(
388
+					'id'     => 'espresso-toolbar-registrations',
389
+					'parent' => 'espresso-toolbar',
390
+					'title'  => '<span class="ee-toolbar-icon"></span>'
391
+								. esc_html__('Registrations', 'event_espresso'),
392
+					'href'   => $this->reg_admin_url,
393
+					'meta'   => array(
394
+						'title'  => esc_html__('Registrations', 'event_espresso'),
395
+						'target' => '',
396
+						'class'  => $this->menu_class,
397
+					),
398
+				)
399
+			);
400
+		}
401
+	}
402
+
403
+
404
+	/**
405
+	 * @return void
406
+	 */
407
+	private function addRegistrationOverviewToday()
408
+	{
409
+		if ($this->capabilities->current_user_can(
410
+			'ee_read_registrations',
411
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today'
412
+		)) {
413
+			$this->admin_bar->add_menu(
414
+				array(
415
+					'id'     => 'espresso-toolbar-registrations-today',
416
+					'parent' => 'espresso-toolbar-registrations',
417
+					'title'  => esc_html__('Today', 'event_espresso'),
418
+					'href'   => '',
419
+					'meta'   => array(
420
+						'title'  => esc_html__('Today', 'event_espresso'),
421
+						'target' => '',
422
+						'class'  => $this->menu_class,
423
+					),
424
+				)
425
+			);
426
+		}
427
+	}
428
+
429
+
430
+	/**
431
+	 * @return void
432
+	 */
433
+	private function addRegistrationOverviewTodayApproved()
434
+	{
435
+		if ($this->capabilities->current_user_can(
436
+			'ee_read_registrations',
437
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-approved'
438
+		)) {
439
+			$this->admin_bar->add_menu(
440
+				array(
441
+					'id'     => 'espresso-toolbar-registrations-today-approved',
442
+					'parent' => 'espresso-toolbar-registrations',
443
+					'title'  => '<span class="ee-toolbar-icon"></span>'
444
+								. esc_html__('Approved', 'event_espresso'),
445
+					'href'   => EEH_URL::add_query_args_and_nonce(
446
+						array(
447
+							'action'      => 'default',
448
+							'status'      => 'today',
449
+							'_reg_status' => EEM_Registration::status_id_approved,
450
+						),
451
+						$this->reg_admin_url
452
+					),
453
+					'meta'   => array(
454
+						'title'  => esc_html__('Approved', 'event_espresso'),
455
+						'target' => '',
456
+						'class'  => $this->menu_class . ' ee-toolbar-icon-approved',
457
+					),
458
+				)
459
+			);
460
+		}
461
+	}
462
+
463
+
464
+	/**
465
+	 * @return void
466
+	 */
467
+	private function addRegistrationOverviewTodayPendingPayment()
468
+	{
469
+		if ($this->capabilities->current_user_can(
470
+			'ee_read_registrations',
471
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-pending'
472
+		)) {
473
+			$this->admin_bar->add_menu(
474
+				array(
475
+					'id'     => 'espresso-toolbar-registrations-today-pending',
476
+					'parent' => 'espresso-toolbar-registrations',
477
+					'title'  => '<span class="ee-toolbar-icon"></span>'
478
+								. esc_html__('Pending', 'event_espresso'),
479
+					'href'   => EEH_URL::add_query_args_and_nonce(
480
+						array(
481
+							'action'      => 'default',
482
+							'status'      => 'today',
483
+							'_reg_status' => EEM_Registration::status_id_pending_payment,
484
+						),
485
+						$this->reg_admin_url
486
+					),
487
+					'meta'   => array(
488
+						'title'  => esc_html__('Pending Payment', 'event_espresso'),
489
+						'target' => '',
490
+						'class'  => $this->menu_class . ' ee-toolbar-icon-pending',
491
+					),
492
+				)
493
+			);
494
+		}
495
+	}
496
+
497
+
498
+	/**
499
+	 * @return void
500
+	 */
501
+	private function addRegistrationOverviewTodayNotApproved()
502
+	{
503
+		if ($this->capabilities->current_user_can(
504
+			'ee_read_registrations',
505
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-not-approved'
506
+		)) {
507
+			$this->admin_bar->add_menu(
508
+				array(
509
+					'id'     => 'espresso-toolbar-registrations-today-not-approved',
510
+					'parent' => 'espresso-toolbar-registrations',
511
+					'title'  => '<span class="ee-toolbar-icon"></span>'
512
+								. esc_html__('Not Approved', 'event_espresso'),
513
+					'href'   => EEH_URL::add_query_args_and_nonce(
514
+						array(
515
+							'action'      => 'default',
516
+							'status'      => 'today',
517
+							'_reg_status' => EEM_Registration::status_id_not_approved,
518
+						),
519
+						$this->reg_admin_url
520
+					),
521
+					'meta'   => array(
522
+						'title'  => esc_html__('Not Approved', 'event_espresso'),
523
+						'target' => '',
524
+						'class'  => $this->menu_class . ' ee-toolbar-icon-not-approved',
525
+					),
526
+				)
527
+			);
528
+		}
529
+	}
530
+
531
+
532
+	/**
533
+	 * @return void
534
+	 */
535
+	private function addRegistrationOverviewTodayCancelled()
536
+	{
537
+		if ($this->capabilities->current_user_can(
538
+			'ee_read_registrations',
539
+			'ee_admin_bar_menu_espresso-toolbar-registrations-today-cancelled'
540
+		)) {
541
+			$this->admin_bar->add_menu(
542
+				array(
543
+					'id'     => 'espresso-toolbar-registrations-today-cancelled',
544
+					'parent' => 'espresso-toolbar-registrations',
545
+					'title'  => '<span class="ee-toolbar-icon"></span>'
546
+								. esc_html__('Cancelled', 'event_espresso'),
547
+					'href'   => EEH_URL::add_query_args_and_nonce(
548
+						array(
549
+							'action'      => 'default',
550
+							'status'      => 'today',
551
+							'_reg_status' => EEM_Registration::status_id_cancelled,
552
+						),
553
+						$this->reg_admin_url
554
+					),
555
+					'meta'   => array(
556
+						'title'  => esc_html__('Cancelled', 'event_espresso'),
557
+						'target' => '',
558
+						'class'  => $this->menu_class . ' ee-toolbar-icon-cancelled',
559
+					),
560
+				)
561
+			);
562
+		}
563
+	}
564
+
565
+
566
+	/**
567
+	 * @return void
568
+	 */
569
+	private function addRegistrationOverviewThisMonth()
570
+	{
571
+		if ($this->capabilities->current_user_can(
572
+			'ee_read_registrations',
573
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month'
574
+		)) {
575
+			$this->admin_bar->add_menu(
576
+				array(
577
+					'id'     => 'espresso-toolbar-registrations-month',
578
+					'parent' => 'espresso-toolbar-registrations',
579
+					'title'  => esc_html__('This Month', 'event_espresso'),
580
+					'href'   => '', // EEH_URL::add_query_args_and_nonce(
581
+					//     array(
582
+					//         'action' => 'default',
583
+					//         'status' => 'month'
584
+					//     ),
585
+					//     $this->reg_admin_url
586
+					// ),
587
+					'meta'   => array(
588
+						'title'  => esc_html__('This Month', 'event_espresso'),
589
+						'target' => '',
590
+						'class'  => $this->menu_class,
591
+					),
592
+				)
593
+			);
594
+		}
595
+	}
596
+
597
+
598
+	/**
599
+	 * @return void
600
+	 */
601
+	private function addRegistrationOverviewThisMonthApproved()
602
+	{
603
+		if ($this->capabilities->current_user_can(
604
+			'ee_read_registrations',
605
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-approved'
606
+		)) {
607
+			$this->admin_bar->add_menu(
608
+				array(
609
+					'id'     => 'espresso-toolbar-registrations-month-approved',
610
+					'parent' => 'espresso-toolbar-registrations',
611
+					'title'  => '<span class="ee-toolbar-icon"></span>'
612
+								. esc_html__('Approved', 'event_espresso'),
613
+					'href'   => EEH_URL::add_query_args_and_nonce(
614
+						array(
615
+							'action'      => 'default',
616
+							'status'      => 'month',
617
+							'_reg_status' => EEM_Registration::status_id_approved,
618
+						),
619
+						$this->reg_admin_url
620
+					),
621
+					'meta'   => array(
622
+						'title'  => esc_html__('Approved', 'event_espresso'),
623
+						'target' => '',
624
+						'class'  => $this->menu_class . ' ee-toolbar-icon-approved',
625
+					),
626
+				)
627
+			);
628
+		}
629
+	}
630
+
631
+
632
+	/**
633
+	 * @return void
634
+	 */
635
+	private function addRegistrationOverviewThisMonthPending()
636
+	{
637
+		if ($this->capabilities->current_user_can(
638
+			'ee_read_registrations',
639
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-pending'
640
+		)) {
641
+			$this->admin_bar->add_menu(
642
+				array(
643
+					'id'     => 'espresso-toolbar-registrations-month-pending',
644
+					'parent' => 'espresso-toolbar-registrations',
645
+					'title'  => '<span class="ee-toolbar-icon"></span>'
646
+								. esc_html__('Pending', 'event_espresso'),
647
+					'href'   => EEH_URL::add_query_args_and_nonce(
648
+						array(
649
+							'action'      => 'default',
650
+							'status'      => 'month',
651
+							'_reg_status' => EEM_Registration::status_id_pending_payment,
652
+						),
653
+						$this->reg_admin_url
654
+					),
655
+					'meta'   => array(
656
+						'title'  => esc_html__('Pending', 'event_espresso'),
657
+						'target' => '',
658
+						'class'  => $this->menu_class . ' ee-toolbar-icon-pending',
659
+					),
660
+				)
661
+			);
662
+		}
663
+	}
664
+
665
+
666
+	/**
667
+	 * @return void
668
+	 */
669
+	private function addRegistrationOverviewThisMonthNotApproved()
670
+	{
671
+		if ($this->capabilities->current_user_can(
672
+			'ee_read_registrations',
673
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-not-approved'
674
+		)) {
675
+			$this->admin_bar->add_menu(
676
+				array(
677
+					'id'     => 'espresso-toolbar-registrations-month-not-approved',
678
+					'parent' => 'espresso-toolbar-registrations',
679
+					'title'  => '<span class="ee-toolbar-icon"></span>'
680
+								. esc_html__('Not Approved', 'event_espresso'),
681
+					'href'   => EEH_URL::add_query_args_and_nonce(
682
+						array(
683
+							'action'      => 'default',
684
+							'status'      => 'month',
685
+							'_reg_status' => EEM_Registration::status_id_not_approved,
686
+						),
687
+						$this->reg_admin_url
688
+					),
689
+					'meta'   => array(
690
+						'title'  => esc_html__('Not Approved', 'event_espresso'),
691
+						'target' => '',
692
+						'class'  => $this->menu_class . ' ee-toolbar-icon-not-approved',
693
+					),
694
+				)
695
+			);
696
+		}
697
+	}
698
+
699
+
700
+	/**
701
+	 * @return void
702
+	 */
703
+	private function addRegistrationOverviewThisMonthCancelled()
704
+	{
705
+		if ($this->capabilities->current_user_can(
706
+			'ee_read_registrations',
707
+			'ee_admin_bar_menu_espresso-toolbar-registrations-month-cancelled'
708
+		)) {
709
+			$this->admin_bar->add_menu(
710
+				array(
711
+					'id'     => 'espresso-toolbar-registrations-month-cancelled',
712
+					'parent' => 'espresso-toolbar-registrations',
713
+					'title'  => '<span class="ee-toolbar-icon"></span>'
714
+								. esc_html__('Cancelled', 'event_espresso'),
715
+					'href'   => EEH_URL::add_query_args_and_nonce(
716
+						array(
717
+							'action'      => 'default',
718
+							'status'      => 'month',
719
+							'_reg_status' => EEM_Registration::status_id_cancelled,
720
+						),
721
+						$this->reg_admin_url
722
+					),
723
+					'meta'   => array(
724
+						'title'  => esc_html__('Cancelled', 'event_espresso'),
725
+						'target' => '',
726
+						'class'  => $this->menu_class . ' ee-toolbar-icon-cancelled',
727
+					),
728
+				)
729
+			);
730
+		}
731
+	}
732
+
733
+
734
+	/**
735
+	 * @return void
736
+	 */
737
+	private function addExtensionsAndServices()
738
+	{
739
+		if ($this->capabilities->current_user_can(
740
+			'ee_read_ee',
741
+			'ee_admin_bar_menu_espresso-toolbar-extensions-and-services'
742
+		)) {
743
+			$this->admin_bar->add_menu(
744
+				array(
745
+					'id'     => 'espresso-toolbar-extensions-and-services',
746
+					'parent' => 'espresso-toolbar',
747
+					'title'  => '<span class="ee-toolbar-icon"></span>'
748
+								. esc_html__('Extensions & Services', 'event_espresso'),
749
+					'href'   => admin_url('admin.php?page=espresso_packages'),
750
+					'meta'   => array(
751
+						'title'  => esc_html__('Extensions & Services', 'event_espresso'),
752
+						'target' => '',
753
+						'class'  => $this->menu_class,
754
+					),
755
+				)
756
+			);
757
+		}
758
+	}
759 759
 }
Please login to merge, or discard this patch.