Completed
Pull Request — master (#1140)
by
unknown
96:21 queued 70:36
created
events/help_tabs/events_default_settings_max_tickets.help_tab.php 1 patch
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <p>
2 2
     <?php esc_html_e(
3
-        'Use this to control what the default will be for maximum tickets on an order when creating a new event.',
4
-        'event_espresso'
5
-    ); ?>
3
+		'Use this to control what the default will be for maximum tickets on an order when creating a new event.',
4
+		'event_espresso'
5
+	); ?>
6 6
 </p>
7 7
\ No newline at end of file
Please login to merge, or discard this patch.
core/services/notices/ConvertNoticesToEeErrors.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -43,7 +43,7 @@
 block discarded – undo
43 43
             $error_string = esc_html__('The following errors occurred:', 'event_espresso');
44 44
             foreach ($notices->getError() as $notice) {
45 45
                 if ($this->getThrowExceptions()) {
46
-                    $error_string .= '<br />' . $notice->message();
46
+                    $error_string .= '<br />'.$notice->message();
47 47
                 } else {
48 48
                     EE_Error::add_error(
49 49
                         $notice->message(),
Please login to merge, or discard this patch.
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -19,56 +19,56 @@
 block discarded – undo
19 19
 class ConvertNoticesToEeErrors extends NoticeConverter
20 20
 {
21 21
 
22
-    /**
23
-     * Converts Notice objects into EE_Error notifications
24
-     *
25
-     * @param NoticesContainerInterface $notices
26
-     * @throws EE_Error
27
-     */
28
-    public function process(NoticesContainerInterface $notices)
29
-    {
30
-        $this->setNotices($notices);
31
-        $notices = $this->getNotices();
32
-        if ($notices->hasAttention()) {
33
-            foreach ($notices->getAttention() as $notice) {
34
-                EE_Error::add_attention(
35
-                    $notice->message(),
36
-                    $notice->file(),
37
-                    $notice->func(),
38
-                    $notice->line()
39
-                );
40
-            }
41
-        }
42
-        if ($notices->hasError()) {
43
-            $error_string = esc_html__('The following errors occurred:', 'event_espresso');
44
-            foreach ($notices->getError() as $notice) {
45
-                if ($this->getThrowExceptions()) {
46
-                    $error_string .= '<br />' . $notice->message();
47
-                } else {
48
-                    EE_Error::add_error(
49
-                        $notice->message(),
50
-                        $notice->file(),
51
-                        $notice->func(),
52
-                        $notice->line()
53
-                    );
54
-                }
55
-            }
56
-            if ($this->getThrowExceptions()) {
57
-                throw new EE_Error($error_string);
58
-            }
59
-        }
60
-        if ($notices->hasSuccess()) {
61
-            foreach ($notices->getSuccess() as $notice) {
62
-                EE_Error::add_success(
63
-                    $notice->message(),
64
-                    $notice->file(),
65
-                    $notice->func(),
66
-                    $notice->line()
67
-                );
68
-            }
69
-        }
70
-        $this->clearNotices();
71
-    }
22
+	/**
23
+	 * Converts Notice objects into EE_Error notifications
24
+	 *
25
+	 * @param NoticesContainerInterface $notices
26
+	 * @throws EE_Error
27
+	 */
28
+	public function process(NoticesContainerInterface $notices)
29
+	{
30
+		$this->setNotices($notices);
31
+		$notices = $this->getNotices();
32
+		if ($notices->hasAttention()) {
33
+			foreach ($notices->getAttention() as $notice) {
34
+				EE_Error::add_attention(
35
+					$notice->message(),
36
+					$notice->file(),
37
+					$notice->func(),
38
+					$notice->line()
39
+				);
40
+			}
41
+		}
42
+		if ($notices->hasError()) {
43
+			$error_string = esc_html__('The following errors occurred:', 'event_espresso');
44
+			foreach ($notices->getError() as $notice) {
45
+				if ($this->getThrowExceptions()) {
46
+					$error_string .= '<br />' . $notice->message();
47
+				} else {
48
+					EE_Error::add_error(
49
+						$notice->message(),
50
+						$notice->file(),
51
+						$notice->func(),
52
+						$notice->line()
53
+					);
54
+				}
55
+			}
56
+			if ($this->getThrowExceptions()) {
57
+				throw new EE_Error($error_string);
58
+			}
59
+		}
60
+		if ($notices->hasSuccess()) {
61
+			foreach ($notices->getSuccess() as $notice) {
62
+				EE_Error::add_success(
63
+					$notice->message(),
64
+					$notice->file(),
65
+					$notice->func(),
66
+					$notice->line()
67
+				);
68
+			}
69
+		}
70
+		$this->clearNotices();
71
+	}
72 72
 
73 73
 
74 74
 }
Please login to merge, or discard this patch.
public/Espresso_Arabica_2014/loop-espresso_events.php 2 patches
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -11,48 +11,48 @@
 block discarded – undo
11 11
  * @version     4+
12 12
  */
13 13
 if (have_posts()) :
14
-    if (apply_filters('FHEE__archive_espresso_events_template__show_header', true)) : ?>
14
+	if (apply_filters('FHEE__archive_espresso_events_template__show_header', true)) : ?>
15 15
         <header class="page-header">
16 16
             <h1 class="page-title">
17 17
                 <?php
18
-                if (is_day()) :
19
-                    printf(__('Today\'s Events: %s', 'event_espresso'), get_the_date());
20
-                elseif (is_month()) :
21
-                    printf(
22
-                        __('Events This Month: %s', 'event_espresso'),
23
-                        get_the_date(_x('F Y', 'monthly archives date format', 'event_espresso'))
24
-                    );
25
-                elseif (is_year()) :
26
-                    printf(
27
-                        __('Events This Year: %s', 'event_espresso'),
28
-                        get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29
-                    );
30
-                else :
31
-                    echo apply_filters(
32
-                        'FHEE__archive_espresso_events_template__upcoming_events_h1',
33
-                        __('Upcoming Events', 'event_espresso')
34
-                    );
35
-                endif;
36
-                ?>
18
+				if (is_day()) :
19
+					printf(__('Today\'s Events: %s', 'event_espresso'), get_the_date());
20
+				elseif (is_month()) :
21
+					printf(
22
+						__('Events This Month: %s', 'event_espresso'),
23
+						get_the_date(_x('F Y', 'monthly archives date format', 'event_espresso'))
24
+					);
25
+				elseif (is_year()) :
26
+					printf(
27
+						__('Events This Year: %s', 'event_espresso'),
28
+						get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29
+					);
30
+				else :
31
+					echo apply_filters(
32
+						'FHEE__archive_espresso_events_template__upcoming_events_h1',
33
+						__('Upcoming Events', 'event_espresso')
34
+					);
35
+				endif;
36
+				?>
37 37
             </h1>
38 38
 
39 39
         </header><!-- .page-header -->
40 40
 
41 41
         <?php
42
-    endif;
43
-    // allow other stuff
44
-    do_action('AHEE__archive_espresso_events_template__before_loop');
45
-    // Start the Loop.
46
-    while (have_posts()) : the_post();
47
-        // Include the post TYPE-specific template for the content.
48
-        espresso_get_template_part('content', 'espresso_events-shortcode');
49
-    endwhile;
50
-    // Previous/next page navigation.
51
-    espresso_pagination();
52
-    // allow moar other stuff
53
-    do_action('AHEE__archive_espresso_events_template__after_loop');
42
+	endif;
43
+	// allow other stuff
44
+	do_action('AHEE__archive_espresso_events_template__before_loop');
45
+	// Start the Loop.
46
+	while (have_posts()) : the_post();
47
+		// Include the post TYPE-specific template for the content.
48
+		espresso_get_template_part('content', 'espresso_events-shortcode');
49
+	endwhile;
50
+	// Previous/next page navigation.
51
+	espresso_pagination();
52
+	// allow moar other stuff
53
+	do_action('AHEE__archive_espresso_events_template__after_loop');
54 54
 else :
55
-    // If no content, include the "No posts found" template.
56
-    espresso_get_template_part('content', 'none');
55
+	// If no content, include the "No posts found" template.
56
+	espresso_get_template_part('content', 'none');
57 57
 endif;
58 58
 
Please login to merge, or discard this patch.
Braces   +6 added lines, -2 removed lines patch added patch discarded remove patch
@@ -27,11 +27,13 @@  discard block
 block discarded – undo
27 27
                         __('Events This Year: %s', 'event_espresso'),
28 28
                         get_the_date(_x('Y', 'yearly archives date format', 'event_espresso'))
29 29
                     );
30
-                else :
30
+                else {
31
+                	:
31 32
                     echo apply_filters(
32 33
                         'FHEE__archive_espresso_events_template__upcoming_events_h1',
33 34
                         __('Upcoming Events', 'event_espresso')
34 35
                     );
36
+                }
35 37
                 endif;
36 38
                 ?>
37 39
             </h1>
@@ -51,8 +53,10 @@  discard block
 block discarded – undo
51 53
     espresso_pagination();
52 54
     // allow moar other stuff
53 55
     do_action('AHEE__archive_espresso_events_template__after_loop');
54
-else :
56
+else {
57
+	:
55 58
     // If no content, include the "No posts found" template.
56 59
     espresso_get_template_part('content', 'none');
60
+}
57 61
 endif;
58 62
 
Please login to merge, or discard this patch.
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.
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.