Completed
Branch FET/conditional-update-queries... (b217a8)
by
unknown
24:07 queued 16:07
created
messages/templates/ee_msg_editor_active_context_element.template.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -10,22 +10,22 @@  discard block
 block discarded – undo
10 10
  * @var int    $message_template_group_id The ID for the message template group this context belongs to.
11 11
  */
12 12
 $active_message = sprintf(
13
-    esc_html__(
14
-        'The template for %1$s is currently %2$sactive%3$s.',
15
-        'event_espresso'
16
-    ),
17
-    $context_label,
18
-    '<strong>',
19
-    '</strong>'
13
+	esc_html__(
14
+		'The template for %1$s is currently %2$sactive%3$s.',
15
+		'event_espresso'
16
+	),
17
+	$context_label,
18
+	'<strong>',
19
+	'</strong>'
20 20
 );
21 21
 $inactive_message = sprintf(
22
-    esc_html__(
23
-        'The template for %1$s is currently %2$sinactive%3$s.',
24
-        'event_espresso'
25
-    ),
26
-    $context_label,
27
-    '<strong>',
28
-    '</strong>'
22
+	esc_html__(
23
+		'The template for %1$s is currently %2$sinactive%3$s.',
24
+		'event_espresso'
25
+	),
26
+	$context_label,
27
+	'<strong>',
28
+	'</strong>'
29 29
 );
30 30
 ?>
31 31
 <div class="context-active-control-container">
@@ -34,8 +34,8 @@  discard block
 block discarded – undo
34 34
         <span id="on-off-nonce-<?php echo $context; ?>" class="hidden"><?php echo $nonce; ?></span>
35 35
         <span class="ee-on-off-toggle-label">
36 36
             <?php
37
-            echo $is_active ? $active_message : $inactive_message;
38
-            ?>
37
+			echo $is_active ? $active_message : $inactive_message;
38
+			?>
39 39
         </span>
40 40
         <div class="hidden js-data">
41 41
             <span class="ee-active-message"><?php echo $active_message; ?></span>
@@ -43,8 +43,8 @@  discard block
 block discarded – undo
43 43
         </div>
44 44
         <div class="switch">
45 45
             <?php
46
-            $checked = $is_active ? ' checked="checked"' : '';
47
-            ?>
46
+			$checked = $is_active ? ' checked="checked"' : '';
47
+			?>
48 48
             <input data-grpid="<?php echo $message_template_group_id; ?>" id="ee-on-off-toggle-<?php echo $context; ?>" type="checkbox" class="ee-on-off-toggle ee-toggle-round-flat"<?php echo $checked; ?> value="<?php echo $on_off_action; ?>">
49 49
             <label for="ee-on-off-toggle-<?php echo $context; ?>"></label>
50 50
         </div>
Please login to merge, or discard this patch.
acceptance_tests/tests/e-TestContextActivationToggleCept.php 1 patch
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -8,8 +8,8 @@  discard block
 block discarded – undo
8 8
 $event_label = 'Testing Context Deactivation';
9 9
 
10 10
 $I->wantTo(
11
-    'Test that the context activation toggle for turning on or off specific contexts for message sending works as'
12
-    . ' expected'
11
+	'Test that the context activation toggle for turning on or off specific contexts for message sending works as'
12
+	. ' expected'
13 13
 );
14 14
 
15 15
 $I->loginAsAdmin();
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
 $I->see('The template for Primary Registrant Recipient is currently inactive.');
35 35
 
36 36
 $I->amGoingTo(
37
-    'Trigger Registration Approved Messages and verify primary registrant context is excluded from sent messages.'
37
+	'Trigger Registration Approved Messages and verify primary registrant context is excluded from sent messages.'
38 38
 );
39 39
 $I->amOnDefaultEventsListTablePage();
40 40
 $I->click(EventsAdmin::ADD_NEW_EVENT_BUTTON_SELECTOR);
@@ -44,9 +44,9 @@  discard block
 block discarded – undo
44 44
 $event_link = $I->observeLinkUrlAt(EventsAdmin::EVENT_EDITOR_VIEW_LINK_AFTER_PUBLISH_SELECTOR);
45 45
 $event_id = $I->observeValueFromInputAt(EventsAdmin::EVENT_EDITOR_EVT_ID_SELECTOR);
46 46
 $test_registration_details = array(
47
-    'fname' => 'ContextTestGuy',
48
-    'lname' => 'ContextTestDude',
49
-    'email' => '[email protected]',
47
+	'fname' => 'ContextTestGuy',
48
+	'lname' => 'ContextTestDude',
49
+	'email' => '[email protected]',
50 50
 );
51 51
 $I->logOut();
52 52
 $I->amOnUrl($event_link);
@@ -63,48 +63,48 @@  discard block
 block discarded – undo
63 63
 $I->amOnMessagesActivityListTablePage();
64 64
 //verify registrant context
65 65
 $I->see(
66
-    $test_registration_details['email'],
67
-    MessagesAdmin::messagesActivityListTableCellSelectorFor(
68
-        'to',
69
-        'Registration Approved',
70
-        MessagesAdmin::MESSAGE_STATUS_SENT,
71
-        '',
72
-        'Registrant'
73
-    )
66
+	$test_registration_details['email'],
67
+	MessagesAdmin::messagesActivityListTableCellSelectorFor(
68
+		'to',
69
+		'Registration Approved',
70
+		MessagesAdmin::MESSAGE_STATUS_SENT,
71
+		'',
72
+		'Registrant'
73
+	)
74 74
 );
75 75
 $I->deleteMessageInMessagesListTableFor(
76
-    'Registration Approved',
77
-    MessagesAdmin::MESSAGE_STATUS_SENT,
78
-    'Email',
79
-    'Registrant'
76
+	'Registration Approved',
77
+	MessagesAdmin::MESSAGE_STATUS_SENT,
78
+	'Email',
79
+	'Registrant'
80 80
 );
81 81
 //verify admin context
82 82
 $I->see(
83
-    '[email protected]',
84
-    MessagesAdmin::messagesActivityListTableCellSelectorFor(
85
-        'to',
86
-        'Registration Approved',
87
-        MessagesAdmin::MESSAGE_STATUS_SENT
88
-    )
83
+	'[email protected]',
84
+	MessagesAdmin::messagesActivityListTableCellSelectorFor(
85
+		'to',
86
+		'Registration Approved',
87
+		MessagesAdmin::MESSAGE_STATUS_SENT
88
+	)
89 89
 );
90 90
 $I->deleteMessageInMessagesListTableFor(
91
-    'Registration Approved'
91
+	'Registration Approved'
92 92
 );
93 93
 //verify primary registrant context is NOT present.
94 94
 $I->dontSee(
95
-    $test_registration_details['email'],
96
-    MessagesAdmin::messagesActivityListTableCellSelectorFor(
97
-        'to',
98
-        'Registration Approved',
99
-        MessagesAdmin::MESSAGE_STATUS_SENT,
100
-        '',
101
-        'Primary Registrant'
102
-    )
95
+	$test_registration_details['email'],
96
+	MessagesAdmin::messagesActivityListTableCellSelectorFor(
97
+		'to',
98
+		'Registration Approved',
99
+		MessagesAdmin::MESSAGE_STATUS_SENT,
100
+		'',
101
+		'Primary Registrant'
102
+	)
103 103
 );
104 104
 
105 105
 $I->amGoingTo(
106
-    'Deactivate primary registrant context for Registration Approved Message Templates and restore the "To"'
107
-    . ' field to an empty string to verify the message does not send for that context.'
106
+	'Deactivate primary registrant context for Registration Approved Message Templates and restore the "To"'
107
+	. ' field to an empty string to verify the message does not send for that context.'
108 108
 );
109 109
 $I->amOnDefaultMessageTemplateListTablePage();
110 110
 $I->clickToEditMessageTemplateByMessageType('registration', 'primary_attendee');
@@ -128,41 +128,41 @@  discard block
 block discarded – undo
128 128
 $I->amOnMessagesActivityListTablePage();
129 129
 //verify registrant context
130 130
 $I->see(
131
-    $test_registration_details['email'],
132
-    MessagesAdmin::messagesActivityListTableCellSelectorFor(
133
-        'to',
134
-        'Registration Approved',
135
-        MessagesAdmin::MESSAGE_STATUS_SENT,
136
-        '',
137
-        'Registrant'
138
-    )
131
+	$test_registration_details['email'],
132
+	MessagesAdmin::messagesActivityListTableCellSelectorFor(
133
+		'to',
134
+		'Registration Approved',
135
+		MessagesAdmin::MESSAGE_STATUS_SENT,
136
+		'',
137
+		'Registrant'
138
+	)
139 139
 );
140 140
 $I->deleteMessageInMessagesListTableFor(
141
-    'Registration Approved',
142
-    MessagesAdmin::MESSAGE_STATUS_SENT,
143
-    'Email',
144
-    'Registrant'
141
+	'Registration Approved',
142
+	MessagesAdmin::MESSAGE_STATUS_SENT,
143
+	'Email',
144
+	'Registrant'
145 145
 );
146 146
 //verify admin context
147 147
 $I->see(
148
-    '[email protected]',
149
-    MessagesAdmin::messagesActivityListTableCellSelectorFor(
150
-        'to',
151
-        'Registration Approved',
152
-        MessagesAdmin::MESSAGE_STATUS_SENT
153
-    )
148
+	'[email protected]',
149
+	MessagesAdmin::messagesActivityListTableCellSelectorFor(
150
+		'to',
151
+		'Registration Approved',
152
+		MessagesAdmin::MESSAGE_STATUS_SENT
153
+	)
154 154
 );
155 155
 $I->deleteMessageInMessagesListTableFor(
156
-    'Registration Approved'
156
+	'Registration Approved'
157 157
 );
158 158
 //verify primary registrant context is NOT present.
159 159
 $I->dontSee(
160
-    $test_registration_details['email'],
161
-    MessagesAdmin::messagesActivityListTableCellSelectorFor(
162
-        'to',
163
-        'Registration Approved',
164
-        MessagesAdmin::MESSAGE_STATUS_SENT,
165
-        '',
166
-        'Primary Registrant'
167
-    )
160
+	$test_registration_details['email'],
161
+	MessagesAdmin::messagesActivityListTableCellSelectorFor(
162
+		'to',
163
+		'Registration Approved',
164
+		MessagesAdmin::MESSAGE_STATUS_SENT,
165
+		'',
166
+		'Primary Registrant'
167
+	)
168 168
 );
169 169
\ No newline at end of file
Please login to merge, or discard this patch.
public/Espresso_Arabica_2014/functions.php 1 patch
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -9,9 +9,9 @@  discard block
 block discarded – undo
9 9
  * @ link			http://www.eventespresso.com
10 10
  * @ version		4+
11 11
  */
12
-define( 'EE_THEME_FUNCTIONS_LOADED', TRUE );
12
+define('EE_THEME_FUNCTIONS_LOADED', TRUE);
13 13
 
14
-if ( ! function_exists( 'espresso_pagination' ) ) {
14
+if ( ! function_exists('espresso_pagination')) {
15 15
 	/**
16 16
 	 *    espresso_pagination
17 17
 	 *
@@ -23,21 +23,21 @@  discard block
 block discarded – undo
23 23
 		$big = 999999999; // need an unlikely integer
24 24
 		$pagination = paginate_links(
25 25
 			array(
26
-				'base'         => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
26
+				'base'         => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
27 27
 				'format'       => '?paged=%#%',
28
-				'current'      => max( 1, get_query_var( 'paged' ) ),
28
+				'current'      => max(1, get_query_var('paged')),
29 29
 				'total'        => $wp_query->max_num_pages,
30 30
 				'show_all'     => true,
31 31
 				'end_size'     => 10,
32 32
 				'mid_size'     => 6,
33 33
 				'prev_next'    => true,
34
-				'prev_text'    => __( '&lsaquo; PREV', 'event_espresso' ),
35
-				'next_text'    => __( 'NEXT &rsaquo;', 'event_espresso' ),
34
+				'prev_text'    => __('&lsaquo; PREV', 'event_espresso'),
35
+				'next_text'    => __('NEXT &rsaquo;', 'event_espresso'),
36 36
 				'type'         => 'plain',
37 37
 				'add_args'     => false,
38 38
 				'add_fragment' => ''
39 39
 			)
40 40
 		);
41
-		echo ! empty( $pagination ) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : '';
41
+		echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">'.$pagination.'</div>' : '';
42 42
 	}
43 43
 }
44 44
\ No newline at end of file
Please login to merge, or discard this patch.
admin_pages/messages/help_tabs/messages_settings_messengers.help_tab.php 2 patches
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -3,79 +3,79 @@
 block discarded – undo
3 3
 </p>
4 4
 <p>
5 5
     <?php esc_html_e(
6
-        'You can select Messengers via the tabs across the top of the settings page. The available messengers you see depends on what version of Event Espresso you have and what addons are installed. Every install include an "Email" messenger tab.  When you click one of those tabs it will display that messenger.',
7
-        'event_espresso'
8
-    ); ?>
6
+		'You can select Messengers via the tabs across the top of the settings page. The available messengers you see depends on what version of Event Espresso you have and what addons are installed. Every install include an "Email" messenger tab.  When you click one of those tabs it will display that messenger.',
7
+		'event_espresso'
8
+	); ?>
9 9
 </p>
10 10
 <p>
11 11
     <?php esc_html_e(
12
-        'There are two ways to determine whether a messenger is active or not.  The first way is via the messenger tab itself.',
13
-        'event_espresso'
14
-    ); ?>
12
+		'There are two ways to determine whether a messenger is active or not.  The first way is via the messenger tab itself.',
13
+		'event_espresso'
14
+	); ?>
15 15
 </p>
16 16
 <p>
17 17
     <?php printf(
18
-        esc_html__(
19
-            'The green colored gear %s indicates that this messenger is currently active.',
20
-            'event_espresso'
21
-        ),
22
-        '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png' . '"'
23
-        . ' alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />'
24
-    );
25
-    printf(
26
-        esc_html__(
27
-            ' The white colored gear %s indicates the messenger is inactive. This is very helpful for seeing at a glance all the messengers that are active when you first view the page.',
28
-            'event_espresso'
29
-        ),
30
-        '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
31
-        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />'
32
-    ); ?>
18
+		esc_html__(
19
+			'The green colored gear %s indicates that this messenger is currently active.',
20
+			'event_espresso'
21
+		),
22
+		'<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png' . '"'
23
+		. ' alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />'
24
+	);
25
+	printf(
26
+		esc_html__(
27
+			' The white colored gear %s indicates the messenger is inactive. This is very helpful for seeing at a glance all the messengers that are active when you first view the page.',
28
+			'event_espresso'
29
+		),
30
+		'<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
31
+		. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />'
32
+	); ?>
33 33
 </p>
34 34
 <p>
35 35
     <?php esc_html_e(
36
-        'The second way to determine whether a messenger is active or not is via the "on/off" button in the top right corner of the active messenger displayed content:',
37
-        'event_espresso'
38
-    ); ?>
36
+		'The second way to determine whether a messenger is active or not is via the "on/off" button in the top right corner of the active messenger displayed content:',
37
+		'event_espresso'
38
+	); ?>
39 39
 </p>
40 40
 <p>
41 41
     <?php printf(
42
-        esc_html__(
43
-            '%1$s means of course that the messenger is active and %2$s means the messenger is inactive.',
44
-            'event_espresso'
45
-        ),
46
-        '<div class="switch">'
47
-            . '<input class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" checked="checked" disabled>'
48
-            . '<label for="ee-on-off-toggle-on"></label>'
49
-        . '</div>',
50
-        '<div class="switch">'
51
-            . '<input class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" disabled>'
52
-            . '<label for="ee-on-off-toggle-on"></label>'
53
-        . '</div>'
54
-    ); ?>
42
+		esc_html__(
43
+			'%1$s means of course that the messenger is active and %2$s means the messenger is inactive.',
44
+			'event_espresso'
45
+		),
46
+		'<div class="switch">'
47
+			. '<input class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" checked="checked" disabled>'
48
+			. '<label for="ee-on-off-toggle-on"></label>'
49
+		. '</div>',
50
+		'<div class="switch">'
51
+			. '<input class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" disabled>'
52
+			. '<label for="ee-on-off-toggle-on"></label>'
53
+		. '</div>'
54
+	); ?>
55 55
 </p>
56 56
 <p>
57 57
     <?php
58
-        esc_html_e(
59
-            'The on/off toggle is also what you use to activate or deactivate a messenger.',
60
-            'event_espresso'
61
-        ); ?>
58
+		esc_html_e(
59
+			'The on/off toggle is also what you use to activate or deactivate a messenger.',
60
+			'event_espresso'
61
+		); ?>
62 62
 </p>
63 63
 <p>
64 64
     <?php esc_html_e(
65
-        'What happens when you click the toggle to activate is the messenger is activated and the system determines what default message types are activated with the messenger.  Then, if there are any default settings for either the messenger or message types those settings are saved.  Next, the system will generate any default templates (if none have been generated before, if there are previously generated templates then they are reactivated).  Finally, you will see the display change to reflect that the messenger is active. If the messenger has settings you can modify them then. Any message types that have settings will also automatically expand so you can see the default settings and make any changes as necessary to fit your needs. Usually the defaults are sufficient however.',
66
-        'event_espresso'
67
-    ); ?>
65
+		'What happens when you click the toggle to activate is the messenger is activated and the system determines what default message types are activated with the messenger.  Then, if there are any default settings for either the messenger or message types those settings are saved.  Next, the system will generate any default templates (if none have been generated before, if there are previously generated templates then they are reactivated).  Finally, you will see the display change to reflect that the messenger is active. If the messenger has settings you can modify them then. Any message types that have settings will also automatically expand so you can see the default settings and make any changes as necessary to fit your needs. Usually the defaults are sufficient however.',
66
+		'event_espresso'
67
+	); ?>
68 68
 </p>
69 69
 <p>
70 70
     <?php esc_html_e(
71
-        'When you deactivate a messenger, the system will first check if there are any custom event templates for that messenger. If there are you will be unable to deactivate the messenger. This is a fail safe to make sure you know that no messages will go out for those specific events so you don\'t accidentally deactivate.  If this check passes, then the system will deactivate any global templates for that messenger (note the templates are not erased, they just become inactive, so if you decide to reactivate the messenger later all your customizations are preserved). Then the display will change to reflect the deactivation.',
72
-        'event_espresso'
73
-    ); ?>
71
+		'When you deactivate a messenger, the system will first check if there are any custom event templates for that messenger. If there are you will be unable to deactivate the messenger. This is a fail safe to make sure you know that no messages will go out for those specific events so you don\'t accidentally deactivate.  If this check passes, then the system will deactivate any global templates for that messenger (note the templates are not erased, they just become inactive, so if you decide to reactivate the messenger later all your customizations are preserved). Then the display will change to reflect the deactivation.',
72
+		'event_espresso'
73
+	); ?>
74 74
 </p>
75 75
 <p>
76 76
     <strong><?php esc_html_e('Important', 'event_espresso'); ?></strong><br/>
77 77
     <?php esc_html_e(
78
-        'Although customizations made to global templates are preserved when a messenger is deactivated, any settings for that messenger (or the message types that were attached to it) are lost on deactivation.  Also, once you deactivate a messenger, no more messages will be delivered using that messenger for any of your events.',
79
-        'event_espresso'
80
-    ); ?>
78
+		'Although customizations made to global templates are preserved when a messenger is deactivated, any settings for that messenger (or the message types that were attached to it) are lost on deactivation.  Also, once you deactivate a messenger, no more messages will be delivered using that messenger for any of your events.',
79
+		'event_espresso'
80
+	); ?>
81 81
 </p>
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -19,16 +19,16 @@
 block discarded – undo
19 19
             'The green colored gear %s indicates that this messenger is currently active.',
20 20
             'event_espresso'
21 21
         ),
22
-        '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png' . '"'
23
-        . ' alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />'
22
+        '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-active.png'.'"'
23
+        . ' alt="'.esc_attr__('Active Email Tab', 'event_espresso').'" />'
24 24
     );
25 25
     printf(
26 26
         esc_html__(
27 27
             ' The white colored gear %s indicates the messenger is inactive. This is very helpful for seeing at a glance all the messengers that are active when you first view the page.',
28 28
             'event_espresso'
29 29
         ),
30
-        '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
31
-        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />'
30
+        '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-inactive.png'
31
+        . '" alt="'.esc_attr__('Inactive Email Tab', 'event_espresso').'" />'
32 32
     ); ?>
33 33
 </p>
34 34
 <p>
Please login to merge, or discard this patch.
core/libraries/shortcodes/EE_Venue_Shortcodes.lib.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -176,7 +176,7 @@
 block discarded – undo
176 176
     /**
177 177
      * This retrieves the EE_Venue from the available data object.
178 178
      *
179
-     * @return EE_Venue|null
179
+     * @return EE_Base_Class|null
180 180
      * @throws EE_Error
181 181
      * @throws EntityNotFoundException
182 182
      */
Please login to merge, or discard this patch.
Indentation   +311 added lines, -311 removed lines patch added patch discarded remove patch
@@ -17,315 +17,315 @@
 block discarded – undo
17 17
 {
18 18
 
19 19
 
20
-    /**
21
-     * Will hold the EE_Event if available
22
-     *
23
-     * @var EE_Event
24
-     */
25
-    protected $_event;
26
-
27
-    /**
28
-     * Will hold the EE_Venue if available
29
-     *
30
-     * @var EE_Venue
31
-     */
32
-    protected $_venue;
33
-
34
-
35
-    /**
36
-     * Initialize properties
37
-     */
38
-    protected function _init_props()
39
-    {
40
-        $this->label = esc_html__('Venue Shortcodes', 'event_espresso');
41
-        $this->description = esc_html__('All shortcodes specific to venue related data', 'event_espresso');
42
-        $this->_shortcodes = array(
43
-            '[VENUE_TITLE]'             => esc_html__('The title for the event venue', 'event_espresso'),
44
-            '[VENUE_DESCRIPTION]'       => esc_html__('The description for the event venue', 'event_espresso'),
45
-            '[VENUE_URL]'               => esc_html__('A url to a webpage for the venue', 'event_espresso'),
46
-            '[VENUE_DETAILS_URL]'       => sprintf(
47
-                esc_html__(
48
-                    'This shortcode outputs the url or website address to the venue details page on this website. This differs from %s which outputs what is entered in the "url" field in the venue details page.',
49
-                    'event_espresso'
50
-                ),
51
-                '[VENUE_URL]'
52
-            ),
53
-            '[VENUE_IMAGE]'             => esc_html__('An image representing the event venue', 'event_espresso'),
54
-            '[VENUE_PHONE]'             => esc_html__('The phone number for the venue', 'event_espresso'),
55
-            '[VENUE_ADDRESS]'           => esc_html__('The address for the venue', 'event_espresso'),
56
-            '[VENUE_ADDRESS2]'          => esc_html__('Address 2 for the venue', 'event_espresso'),
57
-            '[VENUE_CITY]'              => esc_html__('The city the venue is in', 'event_espresso'),
58
-            '[VENUE_STATE]'             => esc_html__('The state the venue is located in', 'event_espresso'),
59
-            '[VENUE_COUNTRY]'           => esc_html__('The country the venue is located in', 'event_espresso'),
60
-            '[VENUE_FORMATTED_ADDRESS]' => esc_html__(
61
-                'This just outputs the venue address in a semantic address format.',
62
-                'event_espresso'
63
-            ),
64
-            '[VENUE_ZIP]'               => esc_html__('The zip code for the venue address', 'event_espresso'),
65
-            '[VENUE_META_*]'            => esc_html__(
66
-                'This is a special dynamic shortcode. After the "*", add the exact name for your custom field, if there is a value set for that custom field within the venue then it will be output in place of this shortcode.',
67
-                'event_espresso'
68
-            ),
69
-            '[GOOGLE_MAP_URL]'          => esc_html__(
70
-                'URL for the google map associated with the venue.',
71
-                'event_espresso'
72
-            ),
73
-            '[GOOGLE_MAP_LINK]'         => esc_html__('Link to a google map for the venue', 'event_espresso'),
74
-            '[GOOGLE_MAP_IMAGE]'        => esc_html__('Google map for venue wrapped in image tags', 'event_espresso'),
75
-        );
76
-    }
77
-
78
-
79
-    /**
80
-     * Parse incoming shortcode
81
-     *
82
-     * @param string $shortcode
83
-     * @return string
84
-     * @throws EE_Error
85
-     * @throws EntityNotFoundException
86
-     */
87
-    protected function _parser($shortcode)
88
-    {
89
-        $this->_venue = $this->_get_venue();
90
-        // If there is no venue object by now then get out.
91
-        if (! $this->_venue instanceof EE_Venue) {
92
-            return '';
93
-        }
94
-
95
-        switch ($shortcode) {
96
-            case '[VENUE_TITLE]':
97
-                return $this->_venue('title');
98
-                break;
99
-
100
-            case '[VENUE_DESCRIPTION]':
101
-                return $this->_venue('description');
102
-                break;
103
-
104
-            case '[VENUE_URL]':
105
-                return $this->_venue('url');
106
-                break;
107
-
108
-            case '[VENUE_IMAGE]':
109
-                return $this->_venue('image');
110
-                break;
111
-
112
-            case '[VENUE_PHONE]':
113
-                return $this->_venue('phone');
114
-                break;
115
-
116
-            case '[VENUE_ADDRESS]':
117
-                return $this->_venue('address');
118
-                break;
119
-
120
-            case '[VENUE_ADDRESS2]':
121
-                return $this->_venue('address2');
122
-                break;
123
-
124
-            case '[VENUE_CITY]':
125
-                return $this->_venue('city');
126
-                break;
127
-
128
-            case '[VENUE_COUNTRY]':
129
-                return $this->_venue('country');
130
-                break;
131
-
132
-            case '[VENUE_STATE]':
133
-                return $this->_venue('state');
134
-                break;
135
-
136
-            case '[VENUE_ZIP]':
137
-                return $this->_venue('zip');
138
-                break;
139
-
140
-            case '[VENUE_FORMATTED_ADDRESS]':
141
-                return $this->_venue('formatted_address');
142
-                break;
143
-
144
-            case '[GOOGLE_MAP_URL]':
145
-                return $this->_venue('gmap_url');
146
-                break;
147
-
148
-            case '[GOOGLE_MAP_LINK]':
149
-                return $this->_venue('gmap_link');
150
-                break;
151
-
152
-            case '[GOOGLE_MAP_IMAGE]':
153
-                return $this->_venue('gmap_link_img');
154
-                break;
155
-
156
-            case '[VENUE_DETAILS_URL]':
157
-                return $this->_venue('permalink');
158
-                break;
159
-        }
160
-
161
-        if (strpos($shortcode, '[VENUE_META_*') !== false) {
162
-            $shortcode = str_replace('[VENUE_META_*', '', $shortcode);
163
-            $shortcode = trim(str_replace(']', '', $shortcode));
164
-
165
-            // pull the meta value from the venue post
166
-            $venue_meta = $this->_venue->get_post_meta($shortcode, true);
167
-
168
-            return ! empty($venue_meta) ? $venue_meta : '';
169
-        }
170
-    }
171
-
172
-    /**
173
-     * This retrieves the EE_Venue from the available data object.
174
-     *
175
-     * @return EE_Venue|null
176
-     * @throws EE_Error
177
-     * @throws EntityNotFoundException
178
-     */
179
-    private function _get_venue()
180
-    {
181
-
182
-        // we need the EE_Event object to get the venue.
183
-        $this->_event = $this->_data instanceof EE_Event ? $this->_data : null;
184
-
185
-        // if no event, then let's see if there is a reg_obj.  If there IS, then we'll try and grab the event from the
186
-        // reg_obj instead.
187
-        if (! $this->_event instanceof EE_Event) {
188
-            $aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null;
189
-            $aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee;
190
-
191
-            $this->_event = $aee instanceof EE_Messages_Addressee && $aee->reg_obj instanceof EE_Registration
192
-                ? $aee->reg_obj->event()
193
-                : null;
194
-
195
-            // if still empty do we have a ticket data item?
196
-            $this->_event = ! $this->_event instanceof EE_Event
197
-                            && $this->_data instanceof EE_Ticket
198
-                            && $this->_extra_data['data'] instanceof EE_Messages_Addressee
199
-                ? $this->_extra_data['data']->tickets[ $this->_data->ID() ]['EE_Event']
200
-                : $this->_event;
201
-
202
-            // if STILL empty event, let's try to get the first event in the list of events via EE_Messages_Addressee
203
-            // and use that.
204
-            $this->_event = ! $this->_event instanceof EE_Event && $aee instanceof EE_Messages_Addressee
205
-                ? reset($aee->events)
206
-                : $this->_event;
207
-        }
208
-
209
-        // If we have an event object use it to pull the venue.
210
-        if ($this->_event instanceof EE_Event) {
211
-            return $this->_event->get_first_related('Venue');
212
-        }
213
-
214
-        return null;
215
-    }
216
-
217
-    /**
218
-     * This retrieves the specified venue information
219
-     *
220
-     * @param string $field What Venue field to retrieve
221
-     * @return string What was retrieved!
222
-     * @throws EE_Error
223
-     * @throws EntityNotFoundException
224
-     */
225
-    private function _venue($field)
226
-    {
227
-
228
-        if (! $this->_venue instanceof EE_Venue) {
229
-            return '';
230
-        } //no venue so get out.
231
-
232
-        switch ($field) {
233
-            case 'title':
234
-                return $this->_venue->get('VNU_name');
235
-                break;
236
-
237
-            case 'description':
238
-                return $this->_venue->get('VNU_desc');
239
-                break;
240
-
241
-            case 'url':
242
-                $url = $this->_venue->get('VNU_url');
243
-                return empty($url) ? $this->_venue->get_permalink() : $url;
244
-                break;
245
-
246
-            case 'permalink':
247
-                return $this->_venue->get_permalink();
248
-                break;
249
-
250
-            case 'image':
251
-                return '<img src="' . $this->_venue->feature_image_url(array(200, 200,))
252
-                       . '" alt="' . sprintf(
253
-                           esc_attr__('%s Feature Image', 'event_espresso'),
254
-                           $this->_venue->get('VNU_name')
255
-                       ) . '" />';
256
-                break;
257
-
258
-            case 'phone':
259
-                return $this->_venue->get('VNU_phone');
260
-                break;
261
-
262
-            case 'address':
263
-                return $this->_venue->get('VNU_address');
264
-                break;
265
-
266
-            case 'address2':
267
-                return $this->_venue->get('VNU_address2');
268
-                break;
269
-
270
-            case 'city':
271
-                return $this->_venue->get('VNU_city');
272
-                break;
273
-
274
-            case 'state':
275
-                $state = $this->_venue->state_obj();
276
-                return is_object($state) ? $state->get('STA_name') : '';
277
-                break;
278
-
279
-            case 'country':
280
-                $country = $this->_venue->country_obj();
281
-                return is_object($country) ? $country->get('CNT_name') : '';
282
-                break;
283
-
284
-            case 'zip':
285
-                return $this->_venue->get('VNU_zip');
286
-                break;
287
-
288
-            case 'formatted_address':
289
-                return EEH_Address::format($this->_venue);
290
-                break;
291
-
292
-            case 'gmap_link':
293
-            case 'gmap_url':
294
-            case 'gmap_link_img':
295
-                $atts = $this->get_map_attributes($this->_venue, $field);
296
-                return EEH_Maps::google_map_link($atts);
297
-                break;
298
-        }
299
-        return '';
300
-    }
301
-
302
-
303
-    /**
304
-     * Generates the attributes for retrieving a google_map artifact.
305
-     *
306
-     * @param EE_Venue $venue
307
-     * @param string   $field
308
-     * @return array
309
-     * @throws EE_Error
310
-     */
311
-    protected function get_map_attributes(EE_Venue $venue, $field = 'gmap_link')
312
-    {
313
-        $state = $venue->state_obj();
314
-        $country = $venue->country_obj();
315
-        $atts = array(
316
-            'id'      => $venue->ID(),
317
-            'address' => $venue->get('VNU_address'),
318
-            'city'    => $venue->get('VNU_city'),
319
-            'state'   => is_object($state) ? $state->get('STA_name') : '',
320
-            'zip'     => $venue->get('VNU_zip'),
321
-            'country' => is_object($country) ? $country->get('CNT_name') : '',
322
-            'type'    => $field === 'gmap_link' ? 'url' : 'map',
323
-            'map_w'   => 200,
324
-            'map_h'   => 200,
325
-        );
326
-        if ($field === 'gmap_url') {
327
-            $atts['type'] = 'url_only';
328
-        }
329
-        return $atts;
330
-    }
20
+	/**
21
+	 * Will hold the EE_Event if available
22
+	 *
23
+	 * @var EE_Event
24
+	 */
25
+	protected $_event;
26
+
27
+	/**
28
+	 * Will hold the EE_Venue if available
29
+	 *
30
+	 * @var EE_Venue
31
+	 */
32
+	protected $_venue;
33
+
34
+
35
+	/**
36
+	 * Initialize properties
37
+	 */
38
+	protected function _init_props()
39
+	{
40
+		$this->label = esc_html__('Venue Shortcodes', 'event_espresso');
41
+		$this->description = esc_html__('All shortcodes specific to venue related data', 'event_espresso');
42
+		$this->_shortcodes = array(
43
+			'[VENUE_TITLE]'             => esc_html__('The title for the event venue', 'event_espresso'),
44
+			'[VENUE_DESCRIPTION]'       => esc_html__('The description for the event venue', 'event_espresso'),
45
+			'[VENUE_URL]'               => esc_html__('A url to a webpage for the venue', 'event_espresso'),
46
+			'[VENUE_DETAILS_URL]'       => sprintf(
47
+				esc_html__(
48
+					'This shortcode outputs the url or website address to the venue details page on this website. This differs from %s which outputs what is entered in the "url" field in the venue details page.',
49
+					'event_espresso'
50
+				),
51
+				'[VENUE_URL]'
52
+			),
53
+			'[VENUE_IMAGE]'             => esc_html__('An image representing the event venue', 'event_espresso'),
54
+			'[VENUE_PHONE]'             => esc_html__('The phone number for the venue', 'event_espresso'),
55
+			'[VENUE_ADDRESS]'           => esc_html__('The address for the venue', 'event_espresso'),
56
+			'[VENUE_ADDRESS2]'          => esc_html__('Address 2 for the venue', 'event_espresso'),
57
+			'[VENUE_CITY]'              => esc_html__('The city the venue is in', 'event_espresso'),
58
+			'[VENUE_STATE]'             => esc_html__('The state the venue is located in', 'event_espresso'),
59
+			'[VENUE_COUNTRY]'           => esc_html__('The country the venue is located in', 'event_espresso'),
60
+			'[VENUE_FORMATTED_ADDRESS]' => esc_html__(
61
+				'This just outputs the venue address in a semantic address format.',
62
+				'event_espresso'
63
+			),
64
+			'[VENUE_ZIP]'               => esc_html__('The zip code for the venue address', 'event_espresso'),
65
+			'[VENUE_META_*]'            => esc_html__(
66
+				'This is a special dynamic shortcode. After the "*", add the exact name for your custom field, if there is a value set for that custom field within the venue then it will be output in place of this shortcode.',
67
+				'event_espresso'
68
+			),
69
+			'[GOOGLE_MAP_URL]'          => esc_html__(
70
+				'URL for the google map associated with the venue.',
71
+				'event_espresso'
72
+			),
73
+			'[GOOGLE_MAP_LINK]'         => esc_html__('Link to a google map for the venue', 'event_espresso'),
74
+			'[GOOGLE_MAP_IMAGE]'        => esc_html__('Google map for venue wrapped in image tags', 'event_espresso'),
75
+		);
76
+	}
77
+
78
+
79
+	/**
80
+	 * Parse incoming shortcode
81
+	 *
82
+	 * @param string $shortcode
83
+	 * @return string
84
+	 * @throws EE_Error
85
+	 * @throws EntityNotFoundException
86
+	 */
87
+	protected function _parser($shortcode)
88
+	{
89
+		$this->_venue = $this->_get_venue();
90
+		// If there is no venue object by now then get out.
91
+		if (! $this->_venue instanceof EE_Venue) {
92
+			return '';
93
+		}
94
+
95
+		switch ($shortcode) {
96
+			case '[VENUE_TITLE]':
97
+				return $this->_venue('title');
98
+				break;
99
+
100
+			case '[VENUE_DESCRIPTION]':
101
+				return $this->_venue('description');
102
+				break;
103
+
104
+			case '[VENUE_URL]':
105
+				return $this->_venue('url');
106
+				break;
107
+
108
+			case '[VENUE_IMAGE]':
109
+				return $this->_venue('image');
110
+				break;
111
+
112
+			case '[VENUE_PHONE]':
113
+				return $this->_venue('phone');
114
+				break;
115
+
116
+			case '[VENUE_ADDRESS]':
117
+				return $this->_venue('address');
118
+				break;
119
+
120
+			case '[VENUE_ADDRESS2]':
121
+				return $this->_venue('address2');
122
+				break;
123
+
124
+			case '[VENUE_CITY]':
125
+				return $this->_venue('city');
126
+				break;
127
+
128
+			case '[VENUE_COUNTRY]':
129
+				return $this->_venue('country');
130
+				break;
131
+
132
+			case '[VENUE_STATE]':
133
+				return $this->_venue('state');
134
+				break;
135
+
136
+			case '[VENUE_ZIP]':
137
+				return $this->_venue('zip');
138
+				break;
139
+
140
+			case '[VENUE_FORMATTED_ADDRESS]':
141
+				return $this->_venue('formatted_address');
142
+				break;
143
+
144
+			case '[GOOGLE_MAP_URL]':
145
+				return $this->_venue('gmap_url');
146
+				break;
147
+
148
+			case '[GOOGLE_MAP_LINK]':
149
+				return $this->_venue('gmap_link');
150
+				break;
151
+
152
+			case '[GOOGLE_MAP_IMAGE]':
153
+				return $this->_venue('gmap_link_img');
154
+				break;
155
+
156
+			case '[VENUE_DETAILS_URL]':
157
+				return $this->_venue('permalink');
158
+				break;
159
+		}
160
+
161
+		if (strpos($shortcode, '[VENUE_META_*') !== false) {
162
+			$shortcode = str_replace('[VENUE_META_*', '', $shortcode);
163
+			$shortcode = trim(str_replace(']', '', $shortcode));
164
+
165
+			// pull the meta value from the venue post
166
+			$venue_meta = $this->_venue->get_post_meta($shortcode, true);
167
+
168
+			return ! empty($venue_meta) ? $venue_meta : '';
169
+		}
170
+	}
171
+
172
+	/**
173
+	 * This retrieves the EE_Venue from the available data object.
174
+	 *
175
+	 * @return EE_Venue|null
176
+	 * @throws EE_Error
177
+	 * @throws EntityNotFoundException
178
+	 */
179
+	private function _get_venue()
180
+	{
181
+
182
+		// we need the EE_Event object to get the venue.
183
+		$this->_event = $this->_data instanceof EE_Event ? $this->_data : null;
184
+
185
+		// if no event, then let's see if there is a reg_obj.  If there IS, then we'll try and grab the event from the
186
+		// reg_obj instead.
187
+		if (! $this->_event instanceof EE_Event) {
188
+			$aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null;
189
+			$aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee;
190
+
191
+			$this->_event = $aee instanceof EE_Messages_Addressee && $aee->reg_obj instanceof EE_Registration
192
+				? $aee->reg_obj->event()
193
+				: null;
194
+
195
+			// if still empty do we have a ticket data item?
196
+			$this->_event = ! $this->_event instanceof EE_Event
197
+							&& $this->_data instanceof EE_Ticket
198
+							&& $this->_extra_data['data'] instanceof EE_Messages_Addressee
199
+				? $this->_extra_data['data']->tickets[ $this->_data->ID() ]['EE_Event']
200
+				: $this->_event;
201
+
202
+			// if STILL empty event, let's try to get the first event in the list of events via EE_Messages_Addressee
203
+			// and use that.
204
+			$this->_event = ! $this->_event instanceof EE_Event && $aee instanceof EE_Messages_Addressee
205
+				? reset($aee->events)
206
+				: $this->_event;
207
+		}
208
+
209
+		// If we have an event object use it to pull the venue.
210
+		if ($this->_event instanceof EE_Event) {
211
+			return $this->_event->get_first_related('Venue');
212
+		}
213
+
214
+		return null;
215
+	}
216
+
217
+	/**
218
+	 * This retrieves the specified venue information
219
+	 *
220
+	 * @param string $field What Venue field to retrieve
221
+	 * @return string What was retrieved!
222
+	 * @throws EE_Error
223
+	 * @throws EntityNotFoundException
224
+	 */
225
+	private function _venue($field)
226
+	{
227
+
228
+		if (! $this->_venue instanceof EE_Venue) {
229
+			return '';
230
+		} //no venue so get out.
231
+
232
+		switch ($field) {
233
+			case 'title':
234
+				return $this->_venue->get('VNU_name');
235
+				break;
236
+
237
+			case 'description':
238
+				return $this->_venue->get('VNU_desc');
239
+				break;
240
+
241
+			case 'url':
242
+				$url = $this->_venue->get('VNU_url');
243
+				return empty($url) ? $this->_venue->get_permalink() : $url;
244
+				break;
245
+
246
+			case 'permalink':
247
+				return $this->_venue->get_permalink();
248
+				break;
249
+
250
+			case 'image':
251
+				return '<img src="' . $this->_venue->feature_image_url(array(200, 200,))
252
+					   . '" alt="' . sprintf(
253
+						   esc_attr__('%s Feature Image', 'event_espresso'),
254
+						   $this->_venue->get('VNU_name')
255
+					   ) . '" />';
256
+				break;
257
+
258
+			case 'phone':
259
+				return $this->_venue->get('VNU_phone');
260
+				break;
261
+
262
+			case 'address':
263
+				return $this->_venue->get('VNU_address');
264
+				break;
265
+
266
+			case 'address2':
267
+				return $this->_venue->get('VNU_address2');
268
+				break;
269
+
270
+			case 'city':
271
+				return $this->_venue->get('VNU_city');
272
+				break;
273
+
274
+			case 'state':
275
+				$state = $this->_venue->state_obj();
276
+				return is_object($state) ? $state->get('STA_name') : '';
277
+				break;
278
+
279
+			case 'country':
280
+				$country = $this->_venue->country_obj();
281
+				return is_object($country) ? $country->get('CNT_name') : '';
282
+				break;
283
+
284
+			case 'zip':
285
+				return $this->_venue->get('VNU_zip');
286
+				break;
287
+
288
+			case 'formatted_address':
289
+				return EEH_Address::format($this->_venue);
290
+				break;
291
+
292
+			case 'gmap_link':
293
+			case 'gmap_url':
294
+			case 'gmap_link_img':
295
+				$atts = $this->get_map_attributes($this->_venue, $field);
296
+				return EEH_Maps::google_map_link($atts);
297
+				break;
298
+		}
299
+		return '';
300
+	}
301
+
302
+
303
+	/**
304
+	 * Generates the attributes for retrieving a google_map artifact.
305
+	 *
306
+	 * @param EE_Venue $venue
307
+	 * @param string   $field
308
+	 * @return array
309
+	 * @throws EE_Error
310
+	 */
311
+	protected function get_map_attributes(EE_Venue $venue, $field = 'gmap_link')
312
+	{
313
+		$state = $venue->state_obj();
314
+		$country = $venue->country_obj();
315
+		$atts = array(
316
+			'id'      => $venue->ID(),
317
+			'address' => $venue->get('VNU_address'),
318
+			'city'    => $venue->get('VNU_city'),
319
+			'state'   => is_object($state) ? $state->get('STA_name') : '',
320
+			'zip'     => $venue->get('VNU_zip'),
321
+			'country' => is_object($country) ? $country->get('CNT_name') : '',
322
+			'type'    => $field === 'gmap_link' ? 'url' : 'map',
323
+			'map_w'   => 200,
324
+			'map_h'   => 200,
325
+		);
326
+		if ($field === 'gmap_url') {
327
+			$atts['type'] = 'url_only';
328
+		}
329
+		return $atts;
330
+	}
331 331
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -88,7 +88,7 @@  discard block
 block discarded – undo
88 88
     {
89 89
         $this->_venue = $this->_get_venue();
90 90
         // If there is no venue object by now then get out.
91
-        if (! $this->_venue instanceof EE_Venue) {
91
+        if ( ! $this->_venue instanceof EE_Venue) {
92 92
             return '';
93 93
         }
94 94
 
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
 
185 185
         // if no event, then let's see if there is a reg_obj.  If there IS, then we'll try and grab the event from the
186 186
         // reg_obj instead.
187
-        if (! $this->_event instanceof EE_Event) {
187
+        if ( ! $this->_event instanceof EE_Event) {
188 188
             $aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null;
189 189
             $aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee;
190 190
 
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
             $this->_event = ! $this->_event instanceof EE_Event
197 197
                             && $this->_data instanceof EE_Ticket
198 198
                             && $this->_extra_data['data'] instanceof EE_Messages_Addressee
199
-                ? $this->_extra_data['data']->tickets[ $this->_data->ID() ]['EE_Event']
199
+                ? $this->_extra_data['data']->tickets[$this->_data->ID()]['EE_Event']
200 200
                 : $this->_event;
201 201
 
202 202
             // if STILL empty event, let's try to get the first event in the list of events via EE_Messages_Addressee
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
     private function _venue($field)
226 226
     {
227 227
 
228
-        if (! $this->_venue instanceof EE_Venue) {
228
+        if ( ! $this->_venue instanceof EE_Venue) {
229 229
             return '';
230 230
         } //no venue so get out.
231 231
 
@@ -248,11 +248,11 @@  discard block
 block discarded – undo
248 248
                 break;
249 249
 
250 250
             case 'image':
251
-                return '<img src="' . $this->_venue->feature_image_url(array(200, 200,))
252
-                       . '" alt="' . sprintf(
251
+                return '<img src="'.$this->_venue->feature_image_url(array(200, 200,))
252
+                       . '" alt="'.sprintf(
253 253
                            esc_attr__('%s Feature Image', 'event_espresso'),
254 254
                            $this->_venue->get('VNU_name')
255
-                       ) . '" />';
255
+                       ).'" />';
256 256
                 break;
257 257
 
258 258
             case 'phone':
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_Radio_Button_Input.input.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -15,22 +15,22 @@
 block discarded – undo
15 15
 class EE_Radio_Button_Input extends EE_Form_Input_With_Options_Base
16 16
 {
17 17
 
18
-    /**
19
-     * @param array $answer_options
20
-     * @param array $input_settings
21
-     */
22
-    public function __construct($answer_options, $input_settings = array())
23
-    {
24
-        $this->_set_display_strategy(new EE_Radio_Button_Display_Strategy());
25
-        $this->_add_validation_strategy(
26
-            new EE_Enum_Validation_Strategy(
27
-                isset($input_settings['validation_error_message'])
28
-                    ? $input_settings['validation_error_message']
29
-                    : null
30
-            )
31
-        );
32
-        $this->_multiple_selections = false;
33
-        parent::__construct($answer_options, $input_settings);
34
-    }
18
+	/**
19
+	 * @param array $answer_options
20
+	 * @param array $input_settings
21
+	 */
22
+	public function __construct($answer_options, $input_settings = array())
23
+	{
24
+		$this->_set_display_strategy(new EE_Radio_Button_Display_Strategy());
25
+		$this->_add_validation_strategy(
26
+			new EE_Enum_Validation_Strategy(
27
+				isset($input_settings['validation_error_message'])
28
+					? $input_settings['validation_error_message']
29
+					: null
30
+			)
31
+		);
32
+		$this->_multiple_selections = false;
33
+		parent::__construct($answer_options, $input_settings);
34
+	}
35 35
 
36 36
 }
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_Datepicker_Input.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@  discard block
 block discarded – undo
29 29
             )
30 30
         );
31 31
         parent::__construct($input_settings);
32
-        $this->set_html_class($this->html_class() . ' datepicker');
32
+        $this->set_html_class($this->html_class().' datepicker');
33 33
         // add some style and make it dance
34 34
         add_action('wp_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
35 35
         add_action('admin_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
@@ -48,7 +48,7 @@  discard block
 block discarded – undo
48 48
         // load css
49 49
         wp_register_style(
50 50
             'espresso-ui-theme',
51
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
51
+            EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
52 52
             array(),
53 53
             EVENT_ESPRESSO_VERSION
54 54
         );
Please login to merge, or discard this patch.
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -10,45 +10,45 @@
 block discarded – undo
10 10
 class EE_Datepicker_Input extends EE_Form_Input_Base
11 11
 {
12 12
 
13
-    /**
14
-     * @param array $input_settings
15
-     */
16
-    public function __construct($input_settings = array())
17
-    {
18
-        $this->_set_display_strategy(new EE_Text_Input_Display_Strategy('datepicker'));
19
-        $this->_set_normalization_strategy(new EE_Text_Normalization());
20
-        // we could do better for validation, but at least verify its plaintext
21
-        $this->_add_validation_strategy(
22
-            new EE_Plaintext_Validation_Strategy(
23
-                isset($input_settings['validation_error_message'])
24
-                    ? $input_settings['validation_error_message']
25
-                    : null
26
-            )
27
-        );
28
-        parent::__construct($input_settings);
29
-        $this->set_html_class($this->html_class() . ' datepicker');
30
-        // add some style and make it dance
31
-        add_action('wp_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
32
-        add_action('admin_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
33
-    }
13
+	/**
14
+	 * @param array $input_settings
15
+	 */
16
+	public function __construct($input_settings = array())
17
+	{
18
+		$this->_set_display_strategy(new EE_Text_Input_Display_Strategy('datepicker'));
19
+		$this->_set_normalization_strategy(new EE_Text_Normalization());
20
+		// we could do better for validation, but at least verify its plaintext
21
+		$this->_add_validation_strategy(
22
+			new EE_Plaintext_Validation_Strategy(
23
+				isset($input_settings['validation_error_message'])
24
+					? $input_settings['validation_error_message']
25
+					: null
26
+			)
27
+		);
28
+		parent::__construct($input_settings);
29
+		$this->set_html_class($this->html_class() . ' datepicker');
30
+		// add some style and make it dance
31
+		add_action('wp_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
32
+		add_action('admin_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
33
+	}
34 34
 
35 35
 
36 36
 
37
-    /**
38
-     *    enqueue_styles_and_scripts
39
-     *
40
-     * @access        public
41
-     * @return        void
42
-     */
43
-    public static function enqueue_styles_and_scripts()
44
-    {
45
-        // load css
46
-        wp_register_style(
47
-            'espresso-ui-theme',
48
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
49
-            array(),
50
-            EVENT_ESPRESSO_VERSION
51
-        );
52
-        wp_enqueue_style('espresso-ui-theme');
53
-    }
37
+	/**
38
+	 *    enqueue_styles_and_scripts
39
+	 *
40
+	 * @access        public
41
+	 * @return        void
42
+	 */
43
+	public static function enqueue_styles_and_scripts()
44
+	{
45
+		// load css
46
+		wp_register_style(
47
+			'espresso-ui-theme',
48
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
49
+			array(),
50
+			EVENT_ESPRESSO_VERSION
51
+		);
52
+		wp_enqueue_style('espresso-ui-theme');
53
+	}
54 54
 }
Please login to merge, or discard this patch.
public/Espresso_Arabica_2014/loop-espresso_event_attendees.php 3 patches
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -22,15 +22,15 @@  discard block
 block discarded – undo
22 22
 
23 23
 <div class="event-attendees">
24 24
     <?php do_action_ref_array(
25
-        'AHEE__loop-espresso_event_attendees__before',
26
-        array(
27
-            $contacts,
28
-            $event,
29
-            $datetime,
30
-            $ticket,
31
-            $show_gravatar,
32
-        )
33
-    ); ?>
25
+		'AHEE__loop-espresso_event_attendees__before',
26
+		array(
27
+			$contacts,
28
+			$event,
29
+			$datetime,
30
+			$ticket,
31
+			$show_gravatar,
32
+		)
33
+	); ?>
34 34
 	<?php if ( $contacts ) : ?>
35 35
 		<ul class="event-attendees-list">
36 36
 			<?php foreach( $contacts as $contact ) :
@@ -47,13 +47,13 @@  discard block
 block discarded – undo
47 47
 		<p><?php echo $no_attendees_message; ?></p>
48 48
 	<?php endif; ?>
49 49
     <?php do_action_ref_array(
50
-        'AHEE__loop-espresso_event_attendees__after',
51
-        array(
52
-            $contacts,
53
-            $event,
54
-            $datetime,
55
-            $ticket,
56
-            $show_gravatar,
57
-        )
58
-    ); ?>
50
+		'AHEE__loop-espresso_event_attendees__after',
51
+		array(
52
+			$contacts,
53
+			$event,
54
+			$datetime,
55
+			$ticket,
56
+			$show_gravatar,
57
+		)
58
+	); ?>
59 59
 </div>
60 60
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -15,7 +15,7 @@  discard block
 block discarded – undo
15 15
  * @type bool       $show_gravatar  whether to show gravatar or not.
16 16
  */
17 17
 
18
-$no_attendees_message =  apply_filters( 'FHEE__loop-espresso_attendees-shortcode__template__no_attendees_message', __('No Attendees Yet', 'event_espresso' ) );
18
+$no_attendees_message = apply_filters('FHEE__loop-espresso_attendees-shortcode__template__no_attendees_message', __('No Attendees Yet', 'event_espresso'));
19 19
 
20 20
 
21 21
 ?>
@@ -31,16 +31,16 @@  discard block
 block discarded – undo
31 31
             $show_gravatar,
32 32
         )
33 33
     ); ?>
34
-	<?php if ( $contacts ) : ?>
34
+	<?php if ($contacts) : ?>
35 35
 		<ul class="event-attendees-list">
36
-			<?php foreach( $contacts as $contact ) :
37
-				EEH_Template::get_template_part( 'content', 'espresso_event_attendees', array( 
36
+			<?php foreach ($contacts as $contact) :
37
+				EEH_Template::get_template_part('content', 'espresso_event_attendees', array( 
38 38
 					'contact'       => $contact, 
39 39
 					'event'         => $event,
40 40
 					'datetime'      => $datetime,
41 41
 					'ticket'        => $ticket,
42 42
 					'show_gravatar' => $show_gravatar 
43
-				) );
43
+				));
44 44
 				endforeach; ?>
45 45
 		</ul>
46 46
 	<?php else : ?>
Please login to merge, or discard this patch.
Braces   +5 added lines, -2 removed lines patch added patch discarded remove patch
@@ -43,8 +43,11 @@
 block discarded – undo
43 43
 				) );
44 44
 				endforeach; ?>
45 45
 		</ul>
46
-	<?php else : ?>
47
-		<p><?php echo $no_attendees_message; ?></p>
46
+	<?php else {
47
+	: ?>
48
+		<p><?php echo $no_attendees_message;
49
+}
50
+?></p>
48 51
 	<?php endif; ?>
49 52
     <?php do_action_ref_array(
50 53
         'AHEE__loop-espresso_event_attendees__after',
Please login to merge, or discard this patch.
core/db_classes/EE_Transaction.class.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -438,7 +438,7 @@  discard block
 block discarded – undo
438 438
      * Gets all the attendees for this transaction (handy for use with EE_Attendee's get_registrations_for_event
439 439
      * function for getting attendees and how many registrations they each have for an event)
440 440
      *
441
-     * @return mixed EE_Attendee[] by default, int if $output is set to 'COUNT'
441
+     * @return EE_Base_Class[] EE_Attendee[] by default, int if $output is set to 'COUNT'
442 442
      * @throws EE_Error
443 443
      */
444 444
     public function attendees()
@@ -489,7 +489,7 @@  discard block
 block discarded – undo
489 489
     /**
490 490
      * Gets all payments which have not been approved
491 491
      *
492
-     * @return EE_Base_Class[]|EEI_Payment[]
492
+     * @return EE_Base_Class[]
493 493
      * @throws EE_Error if a model is misconfigured somehow
494 494
      */
495 495
     public function pending_payments()
Please login to merge, or discard this patch.
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -42,7 +42,7 @@  discard block
 block discarded – undo
42 42
         $txn = $has_object
43 43
             ? $has_object
44 44
             : new self($props_n_values, false, $timezone, $date_formats);
45
-        if (! $has_object) {
45
+        if ( ! $has_object) {
46 46
             $txn->set_old_txn_status($txn->status_ID());
47 47
         }
48 48
         return $txn;
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
     public function lock()
75 75
     {
76 76
         // attempt to set lock, but if that fails...
77
-        if (! $this->add_extra_meta('lock', time(), true)) {
77
+        if ( ! $this->add_extra_meta('lock', time(), true)) {
78 78
             // then attempt to remove the lock in case it is expired
79 79
             if ($this->_remove_expired_lock()) {
80 80
                 // if removal was successful, then try setting lock again
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
     public function is_locked()
123 123
     {
124 124
         // if TXN is not locked, then return false immediately
125
-        if (! $this->_get_lock()) {
125
+        if ( ! $this->_get_lock()) {
126 126
             return false;
127 127
         }
128 128
         // if not, then let's try and remove the lock in case it's expired...
@@ -527,7 +527,7 @@  discard block
 block discarded – undo
527 527
                 $icon = $show_icons ? '<span class="dashicons dashicons-plus ee-icon-size-16 orange-text"></span>' : '';
528 528
                 break;
529 529
         }
530
-        return $icon . $status[ $this->status_ID() ];
530
+        return $icon.$status[$this->status_ID()];
531 531
     }
532 532
 
533 533
 
@@ -631,7 +631,7 @@  discard block
 block discarded – undo
631 631
     public function invoice_url($type = 'html')
632 632
     {
633 633
         $REG = $this->primary_registration();
634
-        if (! $REG instanceof EE_Registration) {
634
+        if ( ! $REG instanceof EE_Registration) {
635 635
             return '';
636 636
         }
637 637
         return $REG->invoice_url($type);
@@ -673,7 +673,7 @@  discard block
 block discarded – undo
673 673
     public function receipt_url($type = 'html')
674 674
     {
675 675
         $REG = $this->primary_registration();
676
-        if (! $REG instanceof EE_Registration) {
676
+        if ( ! $REG instanceof EE_Registration) {
677 677
             return '';
678 678
         }
679 679
         return $REG->receipt_url($type);
@@ -818,7 +818,7 @@  discard block
 block discarded – undo
818 818
     public function total_line_item($create_if_not_found = true)
819 819
     {
820 820
         $item = $this->get_first_related('Line_Item', array(array('LIN_type' => EEM_Line_Item::type_total)));
821
-        if (! $item && $create_if_not_found) {
821
+        if ( ! $item && $create_if_not_found) {
822 822
             $item = EEH_Line_Item::create_total_line_item($this);
823 823
         }
824 824
         return $item;
@@ -863,7 +863,7 @@  discard block
 block discarded – undo
863 863
     public function billing_info()
864 864
     {
865 865
         $payment_method = $this->payment_method();
866
-        if (! $payment_method) {
866
+        if ( ! $payment_method) {
867 867
             EE_Error::add_error(
868 868
                 __(
869 869
                     'Could not find billing info for transaction because no gateway has been used for it yet',
@@ -876,7 +876,7 @@  discard block
 block discarded – undo
876 876
             return null;
877 877
         }
878 878
         $primary_reg = $this->primary_registration();
879
-        if (! $primary_reg) {
879
+        if ( ! $primary_reg) {
880 880
             EE_Error::add_error(
881 881
                 __(
882 882
                     'Cannot get billing info for gateway %s on transaction because no primary registration exists',
@@ -889,7 +889,7 @@  discard block
 block discarded – undo
889 889
             return null;
890 890
         }
891 891
         $attendee = $primary_reg->attendee();
892
-        if (! $attendee) {
892
+        if ( ! $attendee) {
893 893
             EE_Error::add_error(
894 894
                 __(
895 895
                     'Cannot get billing info for gateway %s on transaction because the primary registration has no attendee exists',
@@ -1025,7 +1025,7 @@  discard block
 block discarded – undo
1025 1025
     public function update_based_on_payments()
1026 1026
     {
1027 1027
         EE_Error::doing_it_wrong(
1028
-            __CLASS__ . '::' . __FUNCTION__,
1028
+            __CLASS__.'::'.__FUNCTION__,
1029 1029
             sprintf(
1030 1030
                 __('This method is deprecated. Please use "%s" instead', 'event_espresso'),
1031 1031
                 'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()'
@@ -1085,13 +1085,13 @@  discard block
 block discarded – undo
1085 1085
     private function _reg_steps_completed($reg_step_slug = '', $check_all = true)
1086 1086
     {
1087 1087
         $reg_steps = $this->reg_steps();
1088
-        if (! is_array($reg_steps) || empty($reg_steps)) {
1088
+        if ( ! is_array($reg_steps) || empty($reg_steps)) {
1089 1089
             return false;
1090 1090
         }
1091 1091
         // loop thru reg steps array)
1092 1092
         foreach ($reg_steps as $slug => $reg_step_completed) {
1093 1093
             // if NOT checking ALL steps (only checking one step)
1094
-            if (! $check_all) {
1094
+            if ( ! $check_all) {
1095 1095
                 // and this is the one
1096 1096
                 if ($slug === $reg_step_slug) {
1097 1097
                     return $reg_step_completed;
@@ -1258,30 +1258,30 @@  discard block
 block discarded – undo
1258 1258
         // get reg steps array
1259 1259
         $txn_reg_steps = $this->reg_steps();
1260 1260
         // if reg step does NOT exist
1261
-        if (! isset($txn_reg_steps[ $reg_step_slug ])) {
1261
+        if ( ! isset($txn_reg_steps[$reg_step_slug])) {
1262 1262
             return false;
1263 1263
         }
1264 1264
         // if  we're trying to complete a step that is already completed
1265
-        if ($txn_reg_steps[ $reg_step_slug ] === true) {
1265
+        if ($txn_reg_steps[$reg_step_slug] === true) {
1266 1266
             return true;
1267 1267
         }
1268 1268
         // if  we're trying to complete a step that hasn't even started
1269
-        if ($status === true && $txn_reg_steps[ $reg_step_slug ] === false) {
1269
+        if ($status === true && $txn_reg_steps[$reg_step_slug] === false) {
1270 1270
             return false;
1271 1271
         }
1272 1272
         // if current status value matches the incoming value (no change)
1273 1273
         // type casting as int means values should collapse to either 0, 1, or a timestamp like 1234567890
1274
-        if ((int) $txn_reg_steps[ $reg_step_slug ] === (int) $status) {
1274
+        if ((int) $txn_reg_steps[$reg_step_slug] === (int) $status) {
1275 1275
             // this will happen in cases where multiple AJAX requests occur during the same step
1276 1276
             return true;
1277 1277
         }
1278 1278
         // if we're trying to set a start time, but it has already been set...
1279
-        if (is_numeric($status) && is_numeric($txn_reg_steps[ $reg_step_slug ])) {
1279
+        if (is_numeric($status) && is_numeric($txn_reg_steps[$reg_step_slug])) {
1280 1280
             // skip the update below, but don't return FALSE so that errors won't be displayed
1281 1281
             return true;
1282 1282
         }
1283 1283
         // update completed status
1284
-        $txn_reg_steps[ $reg_step_slug ] = $status;
1284
+        $txn_reg_steps[$reg_step_slug] = $status;
1285 1285
         $this->set_reg_steps($txn_reg_steps);
1286 1286
         $this->save();
1287 1287
         return true;
@@ -1301,7 +1301,7 @@  discard block
 block discarded – undo
1301 1301
     {
1302 1302
         // get reg steps array
1303 1303
         $txn_reg_steps = $this->reg_steps();
1304
-        unset($txn_reg_steps[ $reg_step_slug ]);
1304
+        unset($txn_reg_steps[$reg_step_slug]);
1305 1305
         $this->set_reg_steps($txn_reg_steps);
1306 1306
     }
1307 1307
 
@@ -1374,12 +1374,12 @@  discard block
 block discarded – undo
1374 1374
             return;
1375 1375
         }
1376 1376
         $payments = $this->get_many_related('Payment');
1377
-        if (! empty($payments)) {
1377
+        if ( ! empty($payments)) {
1378 1378
             foreach ($payments as $payment) {
1379 1379
                 if ($payment instanceof EE_Payment) {
1380 1380
                     // kk this TXN should NOT be abandoned
1381 1381
                     $this->update_status_based_on_total_paid();
1382
-                    if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
1382
+                    if ( ! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
1383 1383
                         EE_Error::add_attention(
1384 1384
                             sprintf(
1385 1385
                                 esc_html__(
Please login to merge, or discard this patch.
Indentation   +1390 added lines, -1390 removed lines patch added patch discarded remove patch
@@ -13,1394 +13,1394 @@
 block discarded – undo
13 13
 class EE_Transaction extends EE_Base_Class implements EEI_Transaction
14 14
 {
15 15
 
16
-    /**
17
-     * The length of time in seconds that a lock is applied before being considered expired.
18
-     * It is not long because a transaction should only be locked for the duration of the request that locked it
19
-     */
20
-    const LOCK_EXPIRATION = 2;
21
-
22
-    /**
23
-     * txn status upon initial construction.
24
-     *
25
-     * @var string
26
-     */
27
-    protected $_old_txn_status;
28
-
29
-
30
-    /**
31
-     * @param array  $props_n_values          incoming values
32
-     * @param string $timezone                incoming timezone
33
-     *                                        (if not set the timezone set for the website will be used.)
34
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
35
-     *                                        date_format and the second value is the time format
36
-     * @return EE_Transaction
37
-     * @throws EE_Error
38
-     */
39
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
40
-    {
41
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
42
-        $txn = $has_object
43
-            ? $has_object
44
-            : new self($props_n_values, false, $timezone, $date_formats);
45
-        if (! $has_object) {
46
-            $txn->set_old_txn_status($txn->status_ID());
47
-        }
48
-        return $txn;
49
-    }
50
-
51
-
52
-    /**
53
-     * @param array  $props_n_values  incoming values from the database
54
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
55
-     *                                the website will be used.
56
-     * @return EE_Transaction
57
-     * @throws EE_Error
58
-     */
59
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
60
-    {
61
-        $txn = new self($props_n_values, true, $timezone);
62
-        $txn->set_old_txn_status($txn->status_ID());
63
-        return $txn;
64
-    }
65
-
66
-
67
-    /**
68
-     * Sets a meta field indicating that this TXN is locked and should not be updated in the db.
69
-     * If a lock has already been set, then we will attempt to remove it in case it has expired.
70
-     * If that also fails, then an exception is thrown.
71
-     *
72
-     * @throws EE_Error
73
-     */
74
-    public function lock()
75
-    {
76
-        // attempt to set lock, but if that fails...
77
-        if (! $this->add_extra_meta('lock', time(), true)) {
78
-            // then attempt to remove the lock in case it is expired
79
-            if ($this->_remove_expired_lock()) {
80
-                // if removal was successful, then try setting lock again
81
-                $this->lock();
82
-            } else {
83
-                // but if the lock can not be removed, then throw an exception
84
-                throw new EE_Error(
85
-                    sprintf(
86
-                        __(
87
-                            'Could not lock Transaction %1$d because it is already locked, meaning another part of the system is currently editing it. It should already be unlocked by the time you read this, so please refresh the page and try again.',
88
-                            'event_espresso'
89
-                        ),
90
-                        $this->ID()
91
-                    )
92
-                );
93
-            }
94
-        }
95
-    }
96
-
97
-
98
-    /**
99
-     * removes transaction lock applied in EE_Transaction::lock()
100
-     *
101
-     * @return int
102
-     * @throws EE_Error
103
-     */
104
-    public function unlock()
105
-    {
106
-        return $this->delete_extra_meta('lock');
107
-    }
108
-
109
-
110
-    /**
111
-     * Decides whether or not now is the right time to update the transaction.
112
-     * This is useful because we don't always know if it is safe to update the transaction
113
-     * and its related data. why?
114
-     * because it's possible that the transaction is being used in another
115
-     * request and could overwrite anything we save.
116
-     * So we want to only update the txn once we know that won't happen.
117
-     * We also check that the lock isn't expired, and remove it if it is
118
-     *
119
-     * @return boolean
120
-     * @throws EE_Error
121
-     */
122
-    public function is_locked()
123
-    {
124
-        // if TXN is not locked, then return false immediately
125
-        if (! $this->_get_lock()) {
126
-            return false;
127
-        }
128
-        // if not, then let's try and remove the lock in case it's expired...
129
-        // _remove_expired_lock() returns 0 when lock is valid (ie: removed = false)
130
-        // and a positive number if the lock was removed (ie: number of locks deleted),
131
-        // so we need to return the opposite
132
-        return ! $this->_remove_expired_lock() ? true : false;
133
-    }
134
-
135
-
136
-    /**
137
-     * Gets the meta field indicating that this TXN is locked
138
-     *
139
-     * @return int
140
-     * @throws EE_Error
141
-     */
142
-    protected function _get_lock()
143
-    {
144
-        return (int) $this->get_extra_meta('lock', true, 0);
145
-    }
146
-
147
-
148
-    /**
149
-     * If the lock on this transaction is expired, then we want to remove it so that the transaction can be updated
150
-     *
151
-     * @return int
152
-     * @throws EE_Error
153
-     */
154
-    protected function _remove_expired_lock()
155
-    {
156
-        $locked = $this->_get_lock();
157
-        if ($locked && time() - EE_Transaction::LOCK_EXPIRATION > $locked) {
158
-            return $this->unlock();
159
-        }
160
-        return 0;
161
-    }
162
-
163
-
164
-    /**
165
-     * Set transaction total
166
-     *
167
-     * @param float $total total value of transaction
168
-     * @throws EE_Error
169
-     */
170
-    public function set_total($total = 0.00)
171
-    {
172
-        $this->set('TXN_total', (float) $total);
173
-    }
174
-
175
-
176
-    /**
177
-     * Set Total Amount Paid to Date
178
-     *
179
-     * @param float $total_paid total amount paid to date (sum of all payments)
180
-     * @throws EE_Error
181
-     */
182
-    public function set_paid($total_paid = 0.00)
183
-    {
184
-        $this->set('TXN_paid', (float) $total_paid);
185
-    }
186
-
187
-
188
-    /**
189
-     * Set transaction status
190
-     *
191
-     * @param string $status        whether the transaction is open, declined, accepted,
192
-     *                              or any number of custom values that can be set
193
-     * @throws EE_Error
194
-     */
195
-    public function set_status($status = '')
196
-    {
197
-        $this->set('STS_ID', $status);
198
-    }
199
-
200
-
201
-    /**
202
-     * Set hash salt
203
-     *
204
-     * @param string $hash_salt required for some payment gateways
205
-     * @throws EE_Error
206
-     */
207
-    public function set_hash_salt($hash_salt = '')
208
-    {
209
-        $this->set('TXN_hash_salt', $hash_salt);
210
-    }
211
-
212
-
213
-    /**
214
-     * Sets TXN_reg_steps array
215
-     *
216
-     * @param array $txn_reg_steps
217
-     * @throws EE_Error
218
-     */
219
-    public function set_reg_steps(array $txn_reg_steps)
220
-    {
221
-        $this->set('TXN_reg_steps', $txn_reg_steps);
222
-    }
223
-
224
-
225
-    /**
226
-     * Gets TXN_reg_steps
227
-     *
228
-     * @return array
229
-     * @throws EE_Error
230
-     */
231
-    public function reg_steps()
232
-    {
233
-        $TXN_reg_steps = $this->get('TXN_reg_steps');
234
-        return is_array($TXN_reg_steps) ? (array) $TXN_reg_steps : array();
235
-    }
236
-
237
-
238
-    /**
239
-     * @return string of transaction's total cost, with currency symbol and decimal
240
-     * @throws EE_Error
241
-     */
242
-    public function pretty_total()
243
-    {
244
-        return $this->get_pretty('TXN_total');
245
-    }
246
-
247
-
248
-    /**
249
-     * Gets the amount paid in a pretty string (formatted and with currency symbol)
250
-     *
251
-     * @return string
252
-     * @throws EE_Error
253
-     */
254
-    public function pretty_paid()
255
-    {
256
-        return $this->get_pretty('TXN_paid');
257
-    }
258
-
259
-
260
-    /**
261
-     * calculate the amount remaining for this transaction and return;
262
-     *
263
-     * @return float amount remaining
264
-     * @throws EE_Error
265
-     */
266
-    public function remaining()
267
-    {
268
-        return $this->total() - $this->paid();
269
-    }
270
-
271
-
272
-    /**
273
-     * get Transaction Total
274
-     *
275
-     * @return float
276
-     * @throws EE_Error
277
-     */
278
-    public function total()
279
-    {
280
-        return (float) $this->get('TXN_total');
281
-    }
282
-
283
-
284
-    /**
285
-     * get Total Amount Paid to Date
286
-     *
287
-     * @return float
288
-     * @throws EE_Error
289
-     */
290
-    public function paid()
291
-    {
292
-        return (float) $this->get('TXN_paid');
293
-    }
294
-
295
-
296
-    /**
297
-     * @throws EE_Error
298
-     */
299
-    public function get_cart_session()
300
-    {
301
-        $session_data = (array) $this->get('TXN_session_data');
302
-        return isset($session_data['cart']) && $session_data['cart'] instanceof EE_Cart
303
-            ? $session_data['cart']
304
-            : null;
305
-    }
306
-
307
-
308
-    /**
309
-     * get Transaction session data
310
-     *
311
-     * @throws EE_Error
312
-     */
313
-    public function session_data()
314
-    {
315
-        $session_data = $this->get('TXN_session_data');
316
-        if (empty($session_data)) {
317
-            $session_data = array(
318
-                'id'            => null,
319
-                'user_id'       => null,
320
-                'ip_address'    => null,
321
-                'user_agent'    => null,
322
-                'init_access'   => null,
323
-                'last_access'   => null,
324
-                'pages_visited' => array(),
325
-            );
326
-        }
327
-        return $session_data;
328
-    }
329
-
330
-
331
-    /**
332
-     * Set session data within the TXN object
333
-     *
334
-     * @param EE_Session|array $session_data
335
-     * @throws EE_Error
336
-     */
337
-    public function set_txn_session_data($session_data)
338
-    {
339
-        if ($session_data instanceof EE_Session) {
340
-            $this->set('TXN_session_data', $session_data->get_session_data(null, true));
341
-        } else {
342
-            $this->set('TXN_session_data', $session_data);
343
-        }
344
-    }
345
-
346
-
347
-    /**
348
-     * get Transaction hash salt
349
-     *
350
-     * @throws EE_Error
351
-     */
352
-    public function hash_salt_()
353
-    {
354
-        return $this->get('TXN_hash_salt');
355
-    }
356
-
357
-
358
-    /**
359
-     * Returns the transaction datetime as either:
360
-     *            - unix timestamp format ($format = false, $gmt = true)
361
-     *            - formatted date string including the UTC (timezone) offset ($format = true ($gmt
362
-     *              has no affect with this option)), this also may include a timezone abbreviation if the
363
-     *              set timezone in this class differs from what the timezone is on the blog.
364
-     *            - formatted date string including the UTC (timezone) offset (default).
365
-     *
366
-     * @param boolean $format   - whether to return a unix timestamp (default) or formatted date string
367
-     * @param boolean $gmt      - whether to return a unix timestamp with UTC offset applied (default)
368
-     *                          or no UTC offset applied
369
-     * @return string | int
370
-     * @throws EE_Error
371
-     */
372
-    public function datetime($format = false, $gmt = false)
373
-    {
374
-        if ($format) {
375
-            return $this->get_pretty('TXN_timestamp');
376
-        }
377
-        if ($gmt) {
378
-            return $this->get_raw('TXN_timestamp');
379
-        }
380
-        return $this->get('TXN_timestamp');
381
-    }
382
-
383
-
384
-    /**
385
-     * Gets registrations on this transaction
386
-     *
387
-     * @param array   $query_params array of query parameters
388
-     * @param boolean $get_cached   TRUE to retrieve cached registrations or FALSE to pull from the db
389
-     * @return EE_Base_Class[]|EE_Registration[]
390
-     * @throws EE_Error
391
-     */
392
-    public function registrations($query_params = array(), $get_cached = false)
393
-    {
394
-        $query_params = (empty($query_params) || ! is_array($query_params))
395
-            ? array(
396
-                'order_by' => array(
397
-                    'Event.EVT_name'     => 'ASC',
398
-                    'Attendee.ATT_lname' => 'ASC',
399
-                    'Attendee.ATT_fname' => 'ASC',
400
-                ),
401
-            )
402
-            : $query_params;
403
-        $query_params = $get_cached ? array() : $query_params;
404
-        return $this->get_many_related('Registration', $query_params);
405
-    }
406
-
407
-
408
-    /**
409
-     * Gets all the attendees for this transaction (handy for use with EE_Attendee's get_registrations_for_event
410
-     * function for getting attendees and how many registrations they each have for an event)
411
-     *
412
-     * @return mixed EE_Attendee[] by default, int if $output is set to 'COUNT'
413
-     * @throws EE_Error
414
-     */
415
-    public function attendees()
416
-    {
417
-        return $this->get_many_related('Attendee', array(array('Registration.Transaction.TXN_ID' => $this->ID())));
418
-    }
419
-
420
-
421
-    /**
422
-     * Gets payments for this transaction. Unlike other such functions, order by 'DESC' by default
423
-     *
424
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
425
-     * @return EE_Base_Class[]|EE_Payment[]
426
-     * @throws EE_Error
427
-     */
428
-    public function payments($query_params = array())
429
-    {
430
-        return $this->get_many_related('Payment', $query_params);
431
-    }
432
-
433
-
434
-    /**
435
-     * gets only approved payments for this transaction
436
-     *
437
-     * @return EE_Base_Class[]|EE_Payment[]
438
-     * @throws EE_Error
439
-     * @throws InvalidArgumentException
440
-     * @throws ReflectionException
441
-     * @throws InvalidDataTypeException
442
-     * @throws InvalidInterfaceException
443
-     */
444
-    public function approved_payments()
445
-    {
446
-        EE_Registry::instance()->load_model('Payment');
447
-        return $this->get_many_related(
448
-            'Payment',
449
-            array(
450
-                array('STS_ID' => EEM_Payment::status_id_approved),
451
-                'order_by' => array('PAY_timestamp' => 'DESC'),
452
-            )
453
-        );
454
-    }
455
-
456
-
457
-    /**
458
-     * Gets all payments which have not been approved
459
-     *
460
-     * @return EE_Base_Class[]|EEI_Payment[]
461
-     * @throws EE_Error if a model is misconfigured somehow
462
-     */
463
-    public function pending_payments()
464
-    {
465
-        return $this->get_many_related(
466
-            'Payment',
467
-            array(
468
-                array(
469
-                    'STS_ID' => EEM_Payment::status_id_pending,
470
-                ),
471
-                'order_by' => array(
472
-                    'PAY_timestamp' => 'DESC',
473
-                ),
474
-            )
475
-        );
476
-    }
477
-
478
-
479
-    /**
480
-     * echoes $this->pretty_status()
481
-     *
482
-     * @param bool $show_icons
483
-     * @throws EE_Error
484
-     * @throws InvalidArgumentException
485
-     * @throws InvalidDataTypeException
486
-     * @throws InvalidInterfaceException
487
-     */
488
-    public function e_pretty_status($show_icons = false)
489
-    {
490
-        echo $this->pretty_status($show_icons);
491
-    }
492
-
493
-
494
-    /**
495
-     * returns a pretty version of the status, good for displaying to users
496
-     *
497
-     * @param bool $show_icons
498
-     * @return string
499
-     * @throws EE_Error
500
-     * @throws InvalidArgumentException
501
-     * @throws InvalidDataTypeException
502
-     * @throws InvalidInterfaceException
503
-     */
504
-    public function pretty_status($show_icons = false)
505
-    {
506
-        $status = EEM_Status::instance()->localized_status(
507
-            array($this->status_ID() => __('unknown', 'event_espresso')),
508
-            false,
509
-            'sentence'
510
-        );
511
-        $icon = '';
512
-        switch ($this->status_ID()) {
513
-            case EEM_Transaction::complete_status_code:
514
-                $icon = $show_icons ? '<span class="dashicons dashicons-yes ee-icon-size-24 green-text"></span>' : '';
515
-                break;
516
-            case EEM_Transaction::incomplete_status_code:
517
-                $icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 lt-blue-text"></span>'
518
-                    : '';
519
-                break;
520
-            case EEM_Transaction::abandoned_status_code:
521
-                $icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 red-text"></span>' : '';
522
-                break;
523
-            case EEM_Transaction::failed_status_code:
524
-                $icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' : '';
525
-                break;
526
-            case EEM_Transaction::overpaid_status_code:
527
-                $icon = $show_icons ? '<span class="dashicons dashicons-plus ee-icon-size-16 orange-text"></span>' : '';
528
-                break;
529
-        }
530
-        return $icon . $status[ $this->status_ID() ];
531
-    }
532
-
533
-
534
-    /**
535
-     * get Transaction Status
536
-     *
537
-     * @throws EE_Error
538
-     */
539
-    public function status_ID()
540
-    {
541
-        return $this->get('STS_ID');
542
-    }
543
-
544
-
545
-    /**
546
-     * Returns TRUE or FALSE for whether or not this transaction cost any money
547
-     *
548
-     * @return boolean
549
-     * @throws EE_Error
550
-     */
551
-    public function is_free()
552
-    {
553
-        return EEH_Money::compare_floats($this->get('TXN_total'), 0, '==');
554
-    }
555
-
556
-
557
-    /**
558
-     * Returns whether this transaction is complete
559
-     * Useful in templates and other logic for deciding if we should ask for another payment...
560
-     *
561
-     * @return boolean
562
-     * @throws EE_Error
563
-     */
564
-    public function is_completed()
565
-    {
566
-        return $this->status_ID() === EEM_Transaction::complete_status_code;
567
-    }
568
-
569
-
570
-    /**
571
-     * Returns whether this transaction is incomplete
572
-     * Useful in templates and other logic for deciding if we should ask for another payment...
573
-     *
574
-     * @return boolean
575
-     * @throws EE_Error
576
-     */
577
-    public function is_incomplete()
578
-    {
579
-        return $this->status_ID() === EEM_Transaction::incomplete_status_code;
580
-    }
581
-
582
-
583
-    /**
584
-     * Returns whether this transaction is overpaid
585
-     * Useful in templates and other logic for deciding if monies need to be refunded
586
-     *
587
-     * @return boolean
588
-     * @throws EE_Error
589
-     */
590
-    public function is_overpaid()
591
-    {
592
-        return $this->status_ID() === EEM_Transaction::overpaid_status_code;
593
-    }
594
-
595
-
596
-    /**
597
-     * Returns whether this transaction was abandoned
598
-     * meaning that the transaction/registration process was somehow interrupted and never completed
599
-     * but that contact information exists for at least one registrant
600
-     *
601
-     * @return boolean
602
-     * @throws EE_Error
603
-     */
604
-    public function is_abandoned()
605
-    {
606
-        return $this->status_ID() === EEM_Transaction::abandoned_status_code;
607
-    }
608
-
609
-
610
-    /**
611
-     * Returns whether this transaction failed
612
-     * meaning that the transaction/registration process was somehow interrupted and never completed
613
-     * and that NO contact information exists for any registrants
614
-     *
615
-     * @return boolean
616
-     * @throws EE_Error
617
-     */
618
-    public function failed()
619
-    {
620
-        return $this->status_ID() === EEM_Transaction::failed_status_code;
621
-    }
622
-
623
-
624
-    /**
625
-     * This returns the url for the invoice of this transaction
626
-     *
627
-     * @param string $type 'html' or 'pdf' (default is pdf)
628
-     * @return string
629
-     * @throws EE_Error
630
-     */
631
-    public function invoice_url($type = 'html')
632
-    {
633
-        $REG = $this->primary_registration();
634
-        if (! $REG instanceof EE_Registration) {
635
-            return '';
636
-        }
637
-        return $REG->invoice_url($type);
638
-    }
639
-
640
-
641
-    /**
642
-     * Gets the primary registration only
643
-     *
644
-     * @return EE_Base_Class|EE_Registration
645
-     * @throws EE_Error
646
-     */
647
-    public function primary_registration()
648
-    {
649
-        $registrations = (array) $this->get_many_related(
650
-            'Registration',
651
-            array(array('REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT))
652
-        );
653
-        foreach ($registrations as $registration) {
654
-            // valid registration that is NOT cancelled or declined ?
655
-            if ($registration instanceof EE_Registration
656
-                && ! in_array($registration->status_ID(), EEM_Registration::closed_reg_statuses(), true)
657
-            ) {
658
-                return $registration;
659
-            }
660
-        }
661
-        // nothing valid found, so just return first thing from array of results
662
-        return reset($registrations);
663
-    }
664
-
665
-
666
-    /**
667
-     * Gets the URL for viewing the receipt
668
-     *
669
-     * @param string $type 'pdf' or 'html' (default is 'html')
670
-     * @return string
671
-     * @throws EE_Error
672
-     */
673
-    public function receipt_url($type = 'html')
674
-    {
675
-        $REG = $this->primary_registration();
676
-        if (! $REG instanceof EE_Registration) {
677
-            return '';
678
-        }
679
-        return $REG->receipt_url($type);
680
-    }
681
-
682
-
683
-    /**
684
-     * Gets the URL of the thank you page with this registration REG_url_link added as
685
-     * a query parameter
686
-     *
687
-     * @return string
688
-     * @throws EE_Error
689
-     */
690
-    public function payment_overview_url()
691
-    {
692
-        $primary_registration = $this->primary_registration();
693
-        return $primary_registration instanceof EE_Registration ? $primary_registration->payment_overview_url() : false;
694
-    }
695
-
696
-
697
-    /**
698
-     * @return string
699
-     * @throws EE_Error
700
-     */
701
-    public function gateway_response_on_transaction()
702
-    {
703
-        $payment = $this->get_first_related('Payment');
704
-        return $payment instanceof EE_Payment ? $payment->gateway_response() : '';
705
-    }
706
-
707
-
708
-    /**
709
-     * Get the status object of this object
710
-     *
711
-     * @return EE_Base_Class|EE_Status
712
-     * @throws EE_Error
713
-     */
714
-    public function status_obj()
715
-    {
716
-        return $this->get_first_related('Status');
717
-    }
718
-
719
-
720
-    /**
721
-     * Gets all the extra meta info on this payment
722
-     *
723
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
724
-     * @return EE_Base_Class[]|EE_Extra_Meta
725
-     * @throws EE_Error
726
-     */
727
-    public function extra_meta($query_params = array())
728
-    {
729
-        return $this->get_many_related('Extra_Meta', $query_params);
730
-    }
731
-
732
-
733
-    /**
734
-     * Wrapper for _add_relation_to
735
-     *
736
-     * @param EE_Registration $registration
737
-     * @return EE_Base_Class the relation was added to
738
-     * @throws EE_Error
739
-     */
740
-    public function add_registration(EE_Registration $registration)
741
-    {
742
-        return $this->_add_relation_to($registration, 'Registration');
743
-    }
744
-
745
-
746
-    /**
747
-     * Removes the given registration from being related (even before saving this transaction).
748
-     * If an ID/index is provided and this transaction isn't saved yet, removes it from list of cached relations
749
-     *
750
-     * @param int $registration_or_id
751
-     * @return EE_Base_Class that was removed from being related
752
-     * @throws EE_Error
753
-     */
754
-    public function remove_registration_with_id($registration_or_id)
755
-    {
756
-        return $this->_remove_relation_to($registration_or_id, 'Registration');
757
-    }
758
-
759
-
760
-    /**
761
-     * Gets all the line items which are for ACTUAL items
762
-     *
763
-     * @return EE_Line_Item[]
764
-     * @throws EE_Error
765
-     */
766
-    public function items_purchased()
767
-    {
768
-        return $this->line_items(array(array('LIN_type' => EEM_Line_Item::type_line_item)));
769
-    }
770
-
771
-
772
-    /**
773
-     * Wrapper for _add_relation_to
774
-     *
775
-     * @param EE_Line_Item $line_item
776
-     * @return EE_Base_Class the relation was added to
777
-     * @throws EE_Error
778
-     */
779
-    public function add_line_item(EE_Line_Item $line_item)
780
-    {
781
-        return $this->_add_relation_to($line_item, 'Line_Item');
782
-    }
783
-
784
-
785
-    /**
786
-     * Gets ALL the line items related to this transaction (unstructured)
787
-     *
788
-     * @param array $query_params
789
-     * @return EE_Base_Class[]|EE_Line_Item[]
790
-     * @throws EE_Error
791
-     */
792
-    public function line_items($query_params = array())
793
-    {
794
-        return $this->get_many_related('Line_Item', $query_params);
795
-    }
796
-
797
-
798
-    /**
799
-     * Gets all the line items which are taxes on the total
800
-     *
801
-     * @return EE_Line_Item[]
802
-     * @throws EE_Error
803
-     */
804
-    public function tax_items()
805
-    {
806
-        return $this->line_items(array(array('LIN_type' => EEM_Line_Item::type_tax)));
807
-    }
808
-
809
-
810
-    /**
811
-     * Gets the total line item (which is a parent of all other related line items,
812
-     * meaning it takes them all into account on its total)
813
-     *
814
-     * @param bool $create_if_not_found
815
-     * @return \EE_Line_Item
816
-     * @throws EE_Error
817
-     */
818
-    public function total_line_item($create_if_not_found = true)
819
-    {
820
-        $item = $this->get_first_related('Line_Item', array(array('LIN_type' => EEM_Line_Item::type_total)));
821
-        if (! $item && $create_if_not_found) {
822
-            $item = EEH_Line_Item::create_total_line_item($this);
823
-        }
824
-        return $item;
825
-    }
826
-
827
-
828
-    /**
829
-     * Returns the total amount of tax on this transaction
830
-     * (assumes there's only one tax subtotal line item)
831
-     *
832
-     * @return float
833
-     * @throws EE_Error
834
-     */
835
-    public function tax_total()
836
-    {
837
-        $tax_line_item = $this->tax_total_line_item();
838
-        if ($tax_line_item) {
839
-            return (float) $tax_line_item->total();
840
-        }
841
-        return (float) 0;
842
-    }
843
-
844
-
845
-    /**
846
-     * Gets the tax subtotal line item (assumes there's only one)
847
-     *
848
-     * @return EE_Line_Item
849
-     * @throws EE_Error
850
-     */
851
-    public function tax_total_line_item()
852
-    {
853
-        return EEH_Line_Item::get_taxes_subtotal($this->total_line_item());
854
-    }
855
-
856
-
857
-    /**
858
-     * Gets the array of billing info for the gateway and for this transaction's primary registration's attendee.
859
-     *
860
-     * @return EE_Form_Section_Proper
861
-     * @throws EE_Error
862
-     */
863
-    public function billing_info()
864
-    {
865
-        $payment_method = $this->payment_method();
866
-        if (! $payment_method) {
867
-            EE_Error::add_error(
868
-                __(
869
-                    'Could not find billing info for transaction because no gateway has been used for it yet',
870
-                    'event_espresso'
871
-                ),
872
-                __FILE__,
873
-                __FUNCTION__,
874
-                __LINE__
875
-            );
876
-            return null;
877
-        }
878
-        $primary_reg = $this->primary_registration();
879
-        if (! $primary_reg) {
880
-            EE_Error::add_error(
881
-                __(
882
-                    'Cannot get billing info for gateway %s on transaction because no primary registration exists',
883
-                    'event_espresso'
884
-                ),
885
-                __FILE__,
886
-                __FUNCTION__,
887
-                __LINE__
888
-            );
889
-            return null;
890
-        }
891
-        $attendee = $primary_reg->attendee();
892
-        if (! $attendee) {
893
-            EE_Error::add_error(
894
-                __(
895
-                    'Cannot get billing info for gateway %s on transaction because the primary registration has no attendee exists',
896
-                    'event_espresso'
897
-                ),
898
-                __FILE__,
899
-                __FUNCTION__,
900
-                __LINE__
901
-            );
902
-            return null;
903
-        }
904
-        return $attendee->billing_info_for_payment_method($payment_method);
905
-    }
906
-
907
-
908
-    /**
909
-     * Gets PMD_ID
910
-     *
911
-     * @return int
912
-     * @throws EE_Error
913
-     */
914
-    public function payment_method_ID()
915
-    {
916
-        return $this->get('PMD_ID');
917
-    }
918
-
919
-
920
-    /**
921
-     * Sets PMD_ID
922
-     *
923
-     * @param int $PMD_ID
924
-     * @throws EE_Error
925
-     */
926
-    public function set_payment_method_ID($PMD_ID)
927
-    {
928
-        $this->set('PMD_ID', $PMD_ID);
929
-    }
930
-
931
-
932
-    /**
933
-     * Gets the last-used payment method on this transaction
934
-     * (we COULD just use the last-made payment, but some payment methods, namely
935
-     * offline ones, dont' create payments)
936
-     *
937
-     * @return EE_Payment_Method
938
-     * @throws EE_Error
939
-     */
940
-    public function payment_method()
941
-    {
942
-        $pm = $this->get_first_related('Payment_Method');
943
-        if ($pm instanceof EE_Payment_Method) {
944
-            return $pm;
945
-        }
946
-        $last_payment = $this->last_payment();
947
-        if ($last_payment instanceof EE_Payment && $last_payment->payment_method()) {
948
-            return $last_payment->payment_method();
949
-        }
950
-        return null;
951
-    }
952
-
953
-
954
-    /**
955
-     * Gets the last payment made
956
-     *
957
-     * @return EE_Base_Class|EE_Payment
958
-     * @throws EE_Error
959
-     */
960
-    public function last_payment()
961
-    {
962
-        return $this->get_first_related('Payment', array('order_by' => array('PAY_ID' => 'desc')));
963
-    }
964
-
965
-
966
-    /**
967
-     * Gets all the line items which are unrelated to tickets on this transaction
968
-     *
969
-     * @return EE_Line_Item[]
970
-     * @throws EE_Error
971
-     * @throws InvalidArgumentException
972
-     * @throws InvalidDataTypeException
973
-     * @throws InvalidInterfaceException
974
-     */
975
-    public function non_ticket_line_items()
976
-    {
977
-        return EEM_Line_Item::instance()->get_all_non_ticket_line_items_for_transaction($this->ID());
978
-    }
979
-
980
-
981
-    /**
982
-     * possibly toggles TXN status
983
-     *
984
-     * @param  boolean $update whether to save the TXN
985
-     * @return bool whether the TXN was saved
986
-     * @throws EE_Error
987
-     * @throws RuntimeException
988
-     */
989
-    public function update_status_based_on_total_paid($update = true)
990
-    {
991
-        // set transaction status based on comparison of TXN_paid vs TXN_total
992
-        if (EEH_Money::compare_floats($this->paid(), $this->total(), '>')) {
993
-            $new_txn_status = EEM_Transaction::overpaid_status_code;
994
-        } elseif (EEH_Money::compare_floats($this->paid(), $this->total())) {
995
-            $new_txn_status = EEM_Transaction::complete_status_code;
996
-        } elseif (EEH_Money::compare_floats($this->paid(), $this->total(), '<')) {
997
-            $new_txn_status = EEM_Transaction::incomplete_status_code;
998
-        } else {
999
-            throw new RuntimeException(
1000
-                __('The total paid calculation for this transaction is inaccurate.', 'event_espresso')
1001
-            );
1002
-        }
1003
-        if ($new_txn_status !== $this->status_ID()) {
1004
-            $this->set_status($new_txn_status);
1005
-            if ($update) {
1006
-                return $this->save() ? true : false;
1007
-            }
1008
-        }
1009
-        return false;
1010
-    }
1011
-
1012
-
1013
-    /**
1014
-     * Updates the transaction's status and total_paid based on all the payments
1015
-     * that apply to it
1016
-     *
1017
-     * @deprecated
1018
-     * @return array|bool
1019
-     * @throws EE_Error
1020
-     * @throws InvalidArgumentException
1021
-     * @throws ReflectionException
1022
-     * @throws InvalidDataTypeException
1023
-     * @throws InvalidInterfaceException
1024
-     */
1025
-    public function update_based_on_payments()
1026
-    {
1027
-        EE_Error::doing_it_wrong(
1028
-            __CLASS__ . '::' . __FUNCTION__,
1029
-            sprintf(
1030
-                __('This method is deprecated. Please use "%s" instead', 'event_espresso'),
1031
-                'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()'
1032
-            ),
1033
-            '4.6.0'
1034
-        );
1035
-        /** @type EE_Transaction_Processor $transaction_processor */
1036
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
1037
-        return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment($this);
1038
-    }
1039
-
1040
-
1041
-    /**
1042
-     * @return string
1043
-     */
1044
-    public function old_txn_status()
1045
-    {
1046
-        return $this->_old_txn_status;
1047
-    }
1048
-
1049
-
1050
-    /**
1051
-     * @param string $old_txn_status
1052
-     */
1053
-    public function set_old_txn_status($old_txn_status)
1054
-    {
1055
-        // only set the first time
1056
-        if ($this->_old_txn_status === null) {
1057
-            $this->_old_txn_status = $old_txn_status;
1058
-        }
1059
-    }
1060
-
1061
-
1062
-    /**
1063
-     * reg_status_updated
1064
-     *
1065
-     * @return bool
1066
-     * @throws EE_Error
1067
-     */
1068
-    public function txn_status_updated()
1069
-    {
1070
-        return $this->status_ID() !== $this->_old_txn_status && $this->_old_txn_status !== null;
1071
-    }
1072
-
1073
-
1074
-    /**
1075
-     * _reg_steps_completed
1076
-     * if $check_all is TRUE, then returns TRUE if ALL reg steps have been marked as completed,
1077
-     * if a $reg_step_slug is provided, then this step will be skipped when testing for completion
1078
-     * if $check_all is FALSE and a $reg_step_slug is provided, then ONLY that reg step will be tested for completion
1079
-     *
1080
-     * @param string $reg_step_slug
1081
-     * @param bool   $check_all
1082
-     * @return bool|int
1083
-     * @throws EE_Error
1084
-     */
1085
-    private function _reg_steps_completed($reg_step_slug = '', $check_all = true)
1086
-    {
1087
-        $reg_steps = $this->reg_steps();
1088
-        if (! is_array($reg_steps) || empty($reg_steps)) {
1089
-            return false;
1090
-        }
1091
-        // loop thru reg steps array)
1092
-        foreach ($reg_steps as $slug => $reg_step_completed) {
1093
-            // if NOT checking ALL steps (only checking one step)
1094
-            if (! $check_all) {
1095
-                // and this is the one
1096
-                if ($slug === $reg_step_slug) {
1097
-                    return $reg_step_completed;
1098
-                }
1099
-                // skip to next reg step in loop
1100
-                continue;
1101
-            }
1102
-            // $check_all must be true, else we would never have gotten to this point
1103
-            if ($slug === $reg_step_slug) {
1104
-                // if we reach this point, then we are testing either:
1105
-                // all_reg_steps_completed_except() or
1106
-                // all_reg_steps_completed_except_final_step(),
1107
-                // and since this is the reg step EXCEPTION being tested
1108
-                // we want to return true (yes true) if this reg step is NOT completed
1109
-                // ie: "is everything completed except the final step?"
1110
-                // "that is correct... the final step is not completed, but all others are."
1111
-                return $reg_step_completed !== true;
1112
-            }
1113
-            if ($reg_step_completed !== true) {
1114
-                // if any reg step is NOT completed, then ALL steps are not completed
1115
-                return false;
1116
-            }
1117
-        }
1118
-        return true;
1119
-    }
1120
-
1121
-
1122
-    /**
1123
-     * all_reg_steps_completed
1124
-     * returns:
1125
-     *    true if ALL reg steps have been marked as completed
1126
-     *        or false if any step is not completed
1127
-     *
1128
-     * @return bool
1129
-     * @throws EE_Error
1130
-     */
1131
-    public function all_reg_steps_completed()
1132
-    {
1133
-        return $this->_reg_steps_completed();
1134
-    }
1135
-
1136
-
1137
-    /**
1138
-     * all_reg_steps_completed_except
1139
-     * returns:
1140
-     *        true if ALL reg steps, except a particular step that you wish to skip over, have been marked as completed
1141
-     *        or false if any other step is not completed
1142
-     *        or false if ALL steps are completed including the exception you are testing !!!
1143
-     *
1144
-     * @param string $exception
1145
-     * @return bool
1146
-     * @throws EE_Error
1147
-     */
1148
-    public function all_reg_steps_completed_except($exception = '')
1149
-    {
1150
-        return $this->_reg_steps_completed($exception);
1151
-    }
1152
-
1153
-
1154
-    /**
1155
-     * all_reg_steps_completed_except
1156
-     * returns:
1157
-     *        true if ALL reg steps, except the final step, have been marked as completed
1158
-     *        or false if any step is not completed
1159
-     *    or false if ALL steps are completed including the final step !!!
1160
-     *
1161
-     * @return bool
1162
-     * @throws EE_Error
1163
-     */
1164
-    public function all_reg_steps_completed_except_final_step()
1165
-    {
1166
-        return $this->_reg_steps_completed('finalize_registration');
1167
-    }
1168
-
1169
-
1170
-    /**
1171
-     * reg_step_completed
1172
-     * returns:
1173
-     *    true if a specific reg step has been marked as completed
1174
-     *    a Unix timestamp if it has been initialized but not yet completed,
1175
-     *    or false if it has not yet been initialized
1176
-     *
1177
-     * @param string $reg_step_slug
1178
-     * @return bool|int
1179
-     * @throws EE_Error
1180
-     */
1181
-    public function reg_step_completed($reg_step_slug)
1182
-    {
1183
-        return $this->_reg_steps_completed($reg_step_slug, false);
1184
-    }
1185
-
1186
-
1187
-    /**
1188
-     * completed_final_reg_step
1189
-     * returns:
1190
-     *    true if the finalize_registration reg step has been marked as completed
1191
-     *    a Unix timestamp if it has been initialized but not yet completed,
1192
-     *    or false if it has not yet been initialized
1193
-     *
1194
-     * @return bool|int
1195
-     * @throws EE_Error
1196
-     */
1197
-    public function final_reg_step_completed()
1198
-    {
1199
-        return $this->_reg_steps_completed('finalize_registration', false);
1200
-    }
1201
-
1202
-
1203
-    /**
1204
-     * set_reg_step_initiated
1205
-     * given a valid TXN_reg_step, this sets it's value to a unix timestamp
1206
-     *
1207
-     * @param string $reg_step_slug
1208
-     * @return boolean
1209
-     * @throws EE_Error
1210
-     */
1211
-    public function set_reg_step_initiated($reg_step_slug)
1212
-    {
1213
-        return $this->_set_reg_step_completed_status($reg_step_slug, time());
1214
-    }
1215
-
1216
-
1217
-    /**
1218
-     * set_reg_step_completed
1219
-     * given a valid TXN_reg_step, this sets the step as completed
1220
-     *
1221
-     * @param string $reg_step_slug
1222
-     * @return boolean
1223
-     * @throws EE_Error
1224
-     */
1225
-    public function set_reg_step_completed($reg_step_slug)
1226
-    {
1227
-        return $this->_set_reg_step_completed_status($reg_step_slug, true);
1228
-    }
1229
-
1230
-
1231
-    /**
1232
-     * set_reg_step_completed
1233
-     * given a valid TXN_reg_step slug, this sets the step as NOT completed
1234
-     *
1235
-     * @param string $reg_step_slug
1236
-     * @return boolean
1237
-     * @throws EE_Error
1238
-     */
1239
-    public function set_reg_step_not_completed($reg_step_slug)
1240
-    {
1241
-        return $this->_set_reg_step_completed_status($reg_step_slug, false);
1242
-    }
1243
-
1244
-
1245
-    /**
1246
-     * set_reg_step_completed
1247
-     * given a valid reg step slug, this sets the TXN_reg_step completed status which is either:
1248
-     *
1249
-     * @param  string      $reg_step_slug
1250
-     * @param  boolean|int $status
1251
-     * @return boolean
1252
-     * @throws EE_Error
1253
-     */
1254
-    private function _set_reg_step_completed_status($reg_step_slug, $status)
1255
-    {
1256
-        // validate status
1257
-        $status = is_bool($status) || is_int($status) ? $status : false;
1258
-        // get reg steps array
1259
-        $txn_reg_steps = $this->reg_steps();
1260
-        // if reg step does NOT exist
1261
-        if (! isset($txn_reg_steps[ $reg_step_slug ])) {
1262
-            return false;
1263
-        }
1264
-        // if  we're trying to complete a step that is already completed
1265
-        if ($txn_reg_steps[ $reg_step_slug ] === true) {
1266
-            return true;
1267
-        }
1268
-        // if  we're trying to complete a step that hasn't even started
1269
-        if ($status === true && $txn_reg_steps[ $reg_step_slug ] === false) {
1270
-            return false;
1271
-        }
1272
-        // if current status value matches the incoming value (no change)
1273
-        // type casting as int means values should collapse to either 0, 1, or a timestamp like 1234567890
1274
-        if ((int) $txn_reg_steps[ $reg_step_slug ] === (int) $status) {
1275
-            // this will happen in cases where multiple AJAX requests occur during the same step
1276
-            return true;
1277
-        }
1278
-        // if we're trying to set a start time, but it has already been set...
1279
-        if (is_numeric($status) && is_numeric($txn_reg_steps[ $reg_step_slug ])) {
1280
-            // skip the update below, but don't return FALSE so that errors won't be displayed
1281
-            return true;
1282
-        }
1283
-        // update completed status
1284
-        $txn_reg_steps[ $reg_step_slug ] = $status;
1285
-        $this->set_reg_steps($txn_reg_steps);
1286
-        $this->save();
1287
-        return true;
1288
-    }
1289
-
1290
-
1291
-    /**
1292
-     * remove_reg_step
1293
-     * given a valid TXN_reg_step slug, this will remove (unset)
1294
-     * the reg step from the TXN reg step array
1295
-     *
1296
-     * @param string $reg_step_slug
1297
-     * @return void
1298
-     * @throws EE_Error
1299
-     */
1300
-    public function remove_reg_step($reg_step_slug)
1301
-    {
1302
-        // get reg steps array
1303
-        $txn_reg_steps = $this->reg_steps();
1304
-        unset($txn_reg_steps[ $reg_step_slug ]);
1305
-        $this->set_reg_steps($txn_reg_steps);
1306
-    }
1307
-
1308
-
1309
-    /**
1310
-     * toggle_failed_transaction_status
1311
-     * upgrades a TXNs status from failed to abandoned,
1312
-     * meaning that contact information has been captured for at least one registrant
1313
-     *
1314
-     * @param bool $save
1315
-     * @return bool
1316
-     * @throws EE_Error
1317
-     */
1318
-    public function toggle_failed_transaction_status($save = true)
1319
-    {
1320
-        // if TXN status is still set as "failed"...
1321
-        if ($this->status_ID() === EEM_Transaction::failed_status_code) {
1322
-            $this->set_status(EEM_Transaction::abandoned_status_code);
1323
-            if ($save) {
1324
-                $this->save();
1325
-            }
1326
-            return true;
1327
-        }
1328
-        return false;
1329
-    }
1330
-
1331
-
1332
-    /**
1333
-     * toggle_abandoned_transaction_status
1334
-     * upgrades a TXNs status from failed or abandoned to incomplete
1335
-     *
1336
-     * @return bool
1337
-     * @throws EE_Error
1338
-     */
1339
-    public function toggle_abandoned_transaction_status()
1340
-    {
1341
-        // if TXN status has not been updated already due to a payment, and is still set as "failed" or "abandoned"...
1342
-        $txn_status = $this->status_ID();
1343
-        if ($txn_status === EEM_Transaction::failed_status_code
1344
-            || $txn_status === EEM_Transaction::abandoned_status_code
1345
-        ) {
1346
-            // if a contact record for the primary registrant has been created
1347
-            if ($this->primary_registration() instanceof EE_Registration
1348
-                && $this->primary_registration()->attendee() instanceof EE_Attendee
1349
-            ) {
1350
-                $this->set_status(EEM_Transaction::incomplete_status_code);
1351
-            } else {
1352
-                // no contact record? yer abandoned!
1353
-                $this->set_status(EEM_Transaction::abandoned_status_code);
1354
-            }
1355
-            return true;
1356
-        }
1357
-        return false;
1358
-    }
1359
-
1360
-
1361
-    /**
1362
-     * checks if an Abandoned TXN has any related payments, and if so,
1363
-     * updates the TXN status based on the amount paid
1364
-     *
1365
-     * @throws EE_Error
1366
-     * @throws InvalidDataTypeException
1367
-     * @throws InvalidInterfaceException
1368
-     * @throws InvalidArgumentException
1369
-     * @throws RuntimeException
1370
-     */
1371
-    public function verify_abandoned_transaction_status()
1372
-    {
1373
-        if ($this->status_ID() !== EEM_Transaction::abandoned_status_code) {
1374
-            return;
1375
-        }
1376
-        $payments = $this->get_many_related('Payment');
1377
-        if (! empty($payments)) {
1378
-            foreach ($payments as $payment) {
1379
-                if ($payment instanceof EE_Payment) {
1380
-                    // kk this TXN should NOT be abandoned
1381
-                    $this->update_status_based_on_total_paid();
1382
-                    if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
1383
-                        EE_Error::add_attention(
1384
-                            sprintf(
1385
-                                esc_html__(
1386
-                                    'The status for Transaction #%1$d has been updated from "Abandoned" to "%2$s", because at least one payment has been made towards it. If the payment appears in the "Payment Details" table below, you may need to edit its status and/or other details as well.',
1387
-                                    'event_espresso'
1388
-                                ),
1389
-                                $this->ID(),
1390
-                                $this->pretty_status()
1391
-                            )
1392
-                        );
1393
-                    }
1394
-                    // get final reg step status
1395
-                    $finalized = $this->final_reg_step_completed();
1396
-                    // if the 'finalize_registration' step has been initiated (has a timestamp)
1397
-                    // but has not yet been fully completed (TRUE)
1398
-                    if (is_int($finalized) && $finalized !== false && $finalized !== true) {
1399
-                        $this->set_reg_step_completed('finalize_registration');
1400
-                        $this->save();
1401
-                    }
1402
-                }
1403
-            }
1404
-        }
1405
-    }
16
+	/**
17
+	 * The length of time in seconds that a lock is applied before being considered expired.
18
+	 * It is not long because a transaction should only be locked for the duration of the request that locked it
19
+	 */
20
+	const LOCK_EXPIRATION = 2;
21
+
22
+	/**
23
+	 * txn status upon initial construction.
24
+	 *
25
+	 * @var string
26
+	 */
27
+	protected $_old_txn_status;
28
+
29
+
30
+	/**
31
+	 * @param array  $props_n_values          incoming values
32
+	 * @param string $timezone                incoming timezone
33
+	 *                                        (if not set the timezone set for the website will be used.)
34
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
35
+	 *                                        date_format and the second value is the time format
36
+	 * @return EE_Transaction
37
+	 * @throws EE_Error
38
+	 */
39
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
40
+	{
41
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
42
+		$txn = $has_object
43
+			? $has_object
44
+			: new self($props_n_values, false, $timezone, $date_formats);
45
+		if (! $has_object) {
46
+			$txn->set_old_txn_status($txn->status_ID());
47
+		}
48
+		return $txn;
49
+	}
50
+
51
+
52
+	/**
53
+	 * @param array  $props_n_values  incoming values from the database
54
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
55
+	 *                                the website will be used.
56
+	 * @return EE_Transaction
57
+	 * @throws EE_Error
58
+	 */
59
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
60
+	{
61
+		$txn = new self($props_n_values, true, $timezone);
62
+		$txn->set_old_txn_status($txn->status_ID());
63
+		return $txn;
64
+	}
65
+
66
+
67
+	/**
68
+	 * Sets a meta field indicating that this TXN is locked and should not be updated in the db.
69
+	 * If a lock has already been set, then we will attempt to remove it in case it has expired.
70
+	 * If that also fails, then an exception is thrown.
71
+	 *
72
+	 * @throws EE_Error
73
+	 */
74
+	public function lock()
75
+	{
76
+		// attempt to set lock, but if that fails...
77
+		if (! $this->add_extra_meta('lock', time(), true)) {
78
+			// then attempt to remove the lock in case it is expired
79
+			if ($this->_remove_expired_lock()) {
80
+				// if removal was successful, then try setting lock again
81
+				$this->lock();
82
+			} else {
83
+				// but if the lock can not be removed, then throw an exception
84
+				throw new EE_Error(
85
+					sprintf(
86
+						__(
87
+							'Could not lock Transaction %1$d because it is already locked, meaning another part of the system is currently editing it. It should already be unlocked by the time you read this, so please refresh the page and try again.',
88
+							'event_espresso'
89
+						),
90
+						$this->ID()
91
+					)
92
+				);
93
+			}
94
+		}
95
+	}
96
+
97
+
98
+	/**
99
+	 * removes transaction lock applied in EE_Transaction::lock()
100
+	 *
101
+	 * @return int
102
+	 * @throws EE_Error
103
+	 */
104
+	public function unlock()
105
+	{
106
+		return $this->delete_extra_meta('lock');
107
+	}
108
+
109
+
110
+	/**
111
+	 * Decides whether or not now is the right time to update the transaction.
112
+	 * This is useful because we don't always know if it is safe to update the transaction
113
+	 * and its related data. why?
114
+	 * because it's possible that the transaction is being used in another
115
+	 * request and could overwrite anything we save.
116
+	 * So we want to only update the txn once we know that won't happen.
117
+	 * We also check that the lock isn't expired, and remove it if it is
118
+	 *
119
+	 * @return boolean
120
+	 * @throws EE_Error
121
+	 */
122
+	public function is_locked()
123
+	{
124
+		// if TXN is not locked, then return false immediately
125
+		if (! $this->_get_lock()) {
126
+			return false;
127
+		}
128
+		// if not, then let's try and remove the lock in case it's expired...
129
+		// _remove_expired_lock() returns 0 when lock is valid (ie: removed = false)
130
+		// and a positive number if the lock was removed (ie: number of locks deleted),
131
+		// so we need to return the opposite
132
+		return ! $this->_remove_expired_lock() ? true : false;
133
+	}
134
+
135
+
136
+	/**
137
+	 * Gets the meta field indicating that this TXN is locked
138
+	 *
139
+	 * @return int
140
+	 * @throws EE_Error
141
+	 */
142
+	protected function _get_lock()
143
+	{
144
+		return (int) $this->get_extra_meta('lock', true, 0);
145
+	}
146
+
147
+
148
+	/**
149
+	 * If the lock on this transaction is expired, then we want to remove it so that the transaction can be updated
150
+	 *
151
+	 * @return int
152
+	 * @throws EE_Error
153
+	 */
154
+	protected function _remove_expired_lock()
155
+	{
156
+		$locked = $this->_get_lock();
157
+		if ($locked && time() - EE_Transaction::LOCK_EXPIRATION > $locked) {
158
+			return $this->unlock();
159
+		}
160
+		return 0;
161
+	}
162
+
163
+
164
+	/**
165
+	 * Set transaction total
166
+	 *
167
+	 * @param float $total total value of transaction
168
+	 * @throws EE_Error
169
+	 */
170
+	public function set_total($total = 0.00)
171
+	{
172
+		$this->set('TXN_total', (float) $total);
173
+	}
174
+
175
+
176
+	/**
177
+	 * Set Total Amount Paid to Date
178
+	 *
179
+	 * @param float $total_paid total amount paid to date (sum of all payments)
180
+	 * @throws EE_Error
181
+	 */
182
+	public function set_paid($total_paid = 0.00)
183
+	{
184
+		$this->set('TXN_paid', (float) $total_paid);
185
+	}
186
+
187
+
188
+	/**
189
+	 * Set transaction status
190
+	 *
191
+	 * @param string $status        whether the transaction is open, declined, accepted,
192
+	 *                              or any number of custom values that can be set
193
+	 * @throws EE_Error
194
+	 */
195
+	public function set_status($status = '')
196
+	{
197
+		$this->set('STS_ID', $status);
198
+	}
199
+
200
+
201
+	/**
202
+	 * Set hash salt
203
+	 *
204
+	 * @param string $hash_salt required for some payment gateways
205
+	 * @throws EE_Error
206
+	 */
207
+	public function set_hash_salt($hash_salt = '')
208
+	{
209
+		$this->set('TXN_hash_salt', $hash_salt);
210
+	}
211
+
212
+
213
+	/**
214
+	 * Sets TXN_reg_steps array
215
+	 *
216
+	 * @param array $txn_reg_steps
217
+	 * @throws EE_Error
218
+	 */
219
+	public function set_reg_steps(array $txn_reg_steps)
220
+	{
221
+		$this->set('TXN_reg_steps', $txn_reg_steps);
222
+	}
223
+
224
+
225
+	/**
226
+	 * Gets TXN_reg_steps
227
+	 *
228
+	 * @return array
229
+	 * @throws EE_Error
230
+	 */
231
+	public function reg_steps()
232
+	{
233
+		$TXN_reg_steps = $this->get('TXN_reg_steps');
234
+		return is_array($TXN_reg_steps) ? (array) $TXN_reg_steps : array();
235
+	}
236
+
237
+
238
+	/**
239
+	 * @return string of transaction's total cost, with currency symbol and decimal
240
+	 * @throws EE_Error
241
+	 */
242
+	public function pretty_total()
243
+	{
244
+		return $this->get_pretty('TXN_total');
245
+	}
246
+
247
+
248
+	/**
249
+	 * Gets the amount paid in a pretty string (formatted and with currency symbol)
250
+	 *
251
+	 * @return string
252
+	 * @throws EE_Error
253
+	 */
254
+	public function pretty_paid()
255
+	{
256
+		return $this->get_pretty('TXN_paid');
257
+	}
258
+
259
+
260
+	/**
261
+	 * calculate the amount remaining for this transaction and return;
262
+	 *
263
+	 * @return float amount remaining
264
+	 * @throws EE_Error
265
+	 */
266
+	public function remaining()
267
+	{
268
+		return $this->total() - $this->paid();
269
+	}
270
+
271
+
272
+	/**
273
+	 * get Transaction Total
274
+	 *
275
+	 * @return float
276
+	 * @throws EE_Error
277
+	 */
278
+	public function total()
279
+	{
280
+		return (float) $this->get('TXN_total');
281
+	}
282
+
283
+
284
+	/**
285
+	 * get Total Amount Paid to Date
286
+	 *
287
+	 * @return float
288
+	 * @throws EE_Error
289
+	 */
290
+	public function paid()
291
+	{
292
+		return (float) $this->get('TXN_paid');
293
+	}
294
+
295
+
296
+	/**
297
+	 * @throws EE_Error
298
+	 */
299
+	public function get_cart_session()
300
+	{
301
+		$session_data = (array) $this->get('TXN_session_data');
302
+		return isset($session_data['cart']) && $session_data['cart'] instanceof EE_Cart
303
+			? $session_data['cart']
304
+			: null;
305
+	}
306
+
307
+
308
+	/**
309
+	 * get Transaction session data
310
+	 *
311
+	 * @throws EE_Error
312
+	 */
313
+	public function session_data()
314
+	{
315
+		$session_data = $this->get('TXN_session_data');
316
+		if (empty($session_data)) {
317
+			$session_data = array(
318
+				'id'            => null,
319
+				'user_id'       => null,
320
+				'ip_address'    => null,
321
+				'user_agent'    => null,
322
+				'init_access'   => null,
323
+				'last_access'   => null,
324
+				'pages_visited' => array(),
325
+			);
326
+		}
327
+		return $session_data;
328
+	}
329
+
330
+
331
+	/**
332
+	 * Set session data within the TXN object
333
+	 *
334
+	 * @param EE_Session|array $session_data
335
+	 * @throws EE_Error
336
+	 */
337
+	public function set_txn_session_data($session_data)
338
+	{
339
+		if ($session_data instanceof EE_Session) {
340
+			$this->set('TXN_session_data', $session_data->get_session_data(null, true));
341
+		} else {
342
+			$this->set('TXN_session_data', $session_data);
343
+		}
344
+	}
345
+
346
+
347
+	/**
348
+	 * get Transaction hash salt
349
+	 *
350
+	 * @throws EE_Error
351
+	 */
352
+	public function hash_salt_()
353
+	{
354
+		return $this->get('TXN_hash_salt');
355
+	}
356
+
357
+
358
+	/**
359
+	 * Returns the transaction datetime as either:
360
+	 *            - unix timestamp format ($format = false, $gmt = true)
361
+	 *            - formatted date string including the UTC (timezone) offset ($format = true ($gmt
362
+	 *              has no affect with this option)), this also may include a timezone abbreviation if the
363
+	 *              set timezone in this class differs from what the timezone is on the blog.
364
+	 *            - formatted date string including the UTC (timezone) offset (default).
365
+	 *
366
+	 * @param boolean $format   - whether to return a unix timestamp (default) or formatted date string
367
+	 * @param boolean $gmt      - whether to return a unix timestamp with UTC offset applied (default)
368
+	 *                          or no UTC offset applied
369
+	 * @return string | int
370
+	 * @throws EE_Error
371
+	 */
372
+	public function datetime($format = false, $gmt = false)
373
+	{
374
+		if ($format) {
375
+			return $this->get_pretty('TXN_timestamp');
376
+		}
377
+		if ($gmt) {
378
+			return $this->get_raw('TXN_timestamp');
379
+		}
380
+		return $this->get('TXN_timestamp');
381
+	}
382
+
383
+
384
+	/**
385
+	 * Gets registrations on this transaction
386
+	 *
387
+	 * @param array   $query_params array of query parameters
388
+	 * @param boolean $get_cached   TRUE to retrieve cached registrations or FALSE to pull from the db
389
+	 * @return EE_Base_Class[]|EE_Registration[]
390
+	 * @throws EE_Error
391
+	 */
392
+	public function registrations($query_params = array(), $get_cached = false)
393
+	{
394
+		$query_params = (empty($query_params) || ! is_array($query_params))
395
+			? array(
396
+				'order_by' => array(
397
+					'Event.EVT_name'     => 'ASC',
398
+					'Attendee.ATT_lname' => 'ASC',
399
+					'Attendee.ATT_fname' => 'ASC',
400
+				),
401
+			)
402
+			: $query_params;
403
+		$query_params = $get_cached ? array() : $query_params;
404
+		return $this->get_many_related('Registration', $query_params);
405
+	}
406
+
407
+
408
+	/**
409
+	 * Gets all the attendees for this transaction (handy for use with EE_Attendee's get_registrations_for_event
410
+	 * function for getting attendees and how many registrations they each have for an event)
411
+	 *
412
+	 * @return mixed EE_Attendee[] by default, int if $output is set to 'COUNT'
413
+	 * @throws EE_Error
414
+	 */
415
+	public function attendees()
416
+	{
417
+		return $this->get_many_related('Attendee', array(array('Registration.Transaction.TXN_ID' => $this->ID())));
418
+	}
419
+
420
+
421
+	/**
422
+	 * Gets payments for this transaction. Unlike other such functions, order by 'DESC' by default
423
+	 *
424
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
425
+	 * @return EE_Base_Class[]|EE_Payment[]
426
+	 * @throws EE_Error
427
+	 */
428
+	public function payments($query_params = array())
429
+	{
430
+		return $this->get_many_related('Payment', $query_params);
431
+	}
432
+
433
+
434
+	/**
435
+	 * gets only approved payments for this transaction
436
+	 *
437
+	 * @return EE_Base_Class[]|EE_Payment[]
438
+	 * @throws EE_Error
439
+	 * @throws InvalidArgumentException
440
+	 * @throws ReflectionException
441
+	 * @throws InvalidDataTypeException
442
+	 * @throws InvalidInterfaceException
443
+	 */
444
+	public function approved_payments()
445
+	{
446
+		EE_Registry::instance()->load_model('Payment');
447
+		return $this->get_many_related(
448
+			'Payment',
449
+			array(
450
+				array('STS_ID' => EEM_Payment::status_id_approved),
451
+				'order_by' => array('PAY_timestamp' => 'DESC'),
452
+			)
453
+		);
454
+	}
455
+
456
+
457
+	/**
458
+	 * Gets all payments which have not been approved
459
+	 *
460
+	 * @return EE_Base_Class[]|EEI_Payment[]
461
+	 * @throws EE_Error if a model is misconfigured somehow
462
+	 */
463
+	public function pending_payments()
464
+	{
465
+		return $this->get_many_related(
466
+			'Payment',
467
+			array(
468
+				array(
469
+					'STS_ID' => EEM_Payment::status_id_pending,
470
+				),
471
+				'order_by' => array(
472
+					'PAY_timestamp' => 'DESC',
473
+				),
474
+			)
475
+		);
476
+	}
477
+
478
+
479
+	/**
480
+	 * echoes $this->pretty_status()
481
+	 *
482
+	 * @param bool $show_icons
483
+	 * @throws EE_Error
484
+	 * @throws InvalidArgumentException
485
+	 * @throws InvalidDataTypeException
486
+	 * @throws InvalidInterfaceException
487
+	 */
488
+	public function e_pretty_status($show_icons = false)
489
+	{
490
+		echo $this->pretty_status($show_icons);
491
+	}
492
+
493
+
494
+	/**
495
+	 * returns a pretty version of the status, good for displaying to users
496
+	 *
497
+	 * @param bool $show_icons
498
+	 * @return string
499
+	 * @throws EE_Error
500
+	 * @throws InvalidArgumentException
501
+	 * @throws InvalidDataTypeException
502
+	 * @throws InvalidInterfaceException
503
+	 */
504
+	public function pretty_status($show_icons = false)
505
+	{
506
+		$status = EEM_Status::instance()->localized_status(
507
+			array($this->status_ID() => __('unknown', 'event_espresso')),
508
+			false,
509
+			'sentence'
510
+		);
511
+		$icon = '';
512
+		switch ($this->status_ID()) {
513
+			case EEM_Transaction::complete_status_code:
514
+				$icon = $show_icons ? '<span class="dashicons dashicons-yes ee-icon-size-24 green-text"></span>' : '';
515
+				break;
516
+			case EEM_Transaction::incomplete_status_code:
517
+				$icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 lt-blue-text"></span>'
518
+					: '';
519
+				break;
520
+			case EEM_Transaction::abandoned_status_code:
521
+				$icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 red-text"></span>' : '';
522
+				break;
523
+			case EEM_Transaction::failed_status_code:
524
+				$icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' : '';
525
+				break;
526
+			case EEM_Transaction::overpaid_status_code:
527
+				$icon = $show_icons ? '<span class="dashicons dashicons-plus ee-icon-size-16 orange-text"></span>' : '';
528
+				break;
529
+		}
530
+		return $icon . $status[ $this->status_ID() ];
531
+	}
532
+
533
+
534
+	/**
535
+	 * get Transaction Status
536
+	 *
537
+	 * @throws EE_Error
538
+	 */
539
+	public function status_ID()
540
+	{
541
+		return $this->get('STS_ID');
542
+	}
543
+
544
+
545
+	/**
546
+	 * Returns TRUE or FALSE for whether or not this transaction cost any money
547
+	 *
548
+	 * @return boolean
549
+	 * @throws EE_Error
550
+	 */
551
+	public function is_free()
552
+	{
553
+		return EEH_Money::compare_floats($this->get('TXN_total'), 0, '==');
554
+	}
555
+
556
+
557
+	/**
558
+	 * Returns whether this transaction is complete
559
+	 * Useful in templates and other logic for deciding if we should ask for another payment...
560
+	 *
561
+	 * @return boolean
562
+	 * @throws EE_Error
563
+	 */
564
+	public function is_completed()
565
+	{
566
+		return $this->status_ID() === EEM_Transaction::complete_status_code;
567
+	}
568
+
569
+
570
+	/**
571
+	 * Returns whether this transaction is incomplete
572
+	 * Useful in templates and other logic for deciding if we should ask for another payment...
573
+	 *
574
+	 * @return boolean
575
+	 * @throws EE_Error
576
+	 */
577
+	public function is_incomplete()
578
+	{
579
+		return $this->status_ID() === EEM_Transaction::incomplete_status_code;
580
+	}
581
+
582
+
583
+	/**
584
+	 * Returns whether this transaction is overpaid
585
+	 * Useful in templates and other logic for deciding if monies need to be refunded
586
+	 *
587
+	 * @return boolean
588
+	 * @throws EE_Error
589
+	 */
590
+	public function is_overpaid()
591
+	{
592
+		return $this->status_ID() === EEM_Transaction::overpaid_status_code;
593
+	}
594
+
595
+
596
+	/**
597
+	 * Returns whether this transaction was abandoned
598
+	 * meaning that the transaction/registration process was somehow interrupted and never completed
599
+	 * but that contact information exists for at least one registrant
600
+	 *
601
+	 * @return boolean
602
+	 * @throws EE_Error
603
+	 */
604
+	public function is_abandoned()
605
+	{
606
+		return $this->status_ID() === EEM_Transaction::abandoned_status_code;
607
+	}
608
+
609
+
610
+	/**
611
+	 * Returns whether this transaction failed
612
+	 * meaning that the transaction/registration process was somehow interrupted and never completed
613
+	 * and that NO contact information exists for any registrants
614
+	 *
615
+	 * @return boolean
616
+	 * @throws EE_Error
617
+	 */
618
+	public function failed()
619
+	{
620
+		return $this->status_ID() === EEM_Transaction::failed_status_code;
621
+	}
622
+
623
+
624
+	/**
625
+	 * This returns the url for the invoice of this transaction
626
+	 *
627
+	 * @param string $type 'html' or 'pdf' (default is pdf)
628
+	 * @return string
629
+	 * @throws EE_Error
630
+	 */
631
+	public function invoice_url($type = 'html')
632
+	{
633
+		$REG = $this->primary_registration();
634
+		if (! $REG instanceof EE_Registration) {
635
+			return '';
636
+		}
637
+		return $REG->invoice_url($type);
638
+	}
639
+
640
+
641
+	/**
642
+	 * Gets the primary registration only
643
+	 *
644
+	 * @return EE_Base_Class|EE_Registration
645
+	 * @throws EE_Error
646
+	 */
647
+	public function primary_registration()
648
+	{
649
+		$registrations = (array) $this->get_many_related(
650
+			'Registration',
651
+			array(array('REG_count' => EEM_Registration::PRIMARY_REGISTRANT_COUNT))
652
+		);
653
+		foreach ($registrations as $registration) {
654
+			// valid registration that is NOT cancelled or declined ?
655
+			if ($registration instanceof EE_Registration
656
+				&& ! in_array($registration->status_ID(), EEM_Registration::closed_reg_statuses(), true)
657
+			) {
658
+				return $registration;
659
+			}
660
+		}
661
+		// nothing valid found, so just return first thing from array of results
662
+		return reset($registrations);
663
+	}
664
+
665
+
666
+	/**
667
+	 * Gets the URL for viewing the receipt
668
+	 *
669
+	 * @param string $type 'pdf' or 'html' (default is 'html')
670
+	 * @return string
671
+	 * @throws EE_Error
672
+	 */
673
+	public function receipt_url($type = 'html')
674
+	{
675
+		$REG = $this->primary_registration();
676
+		if (! $REG instanceof EE_Registration) {
677
+			return '';
678
+		}
679
+		return $REG->receipt_url($type);
680
+	}
681
+
682
+
683
+	/**
684
+	 * Gets the URL of the thank you page with this registration REG_url_link added as
685
+	 * a query parameter
686
+	 *
687
+	 * @return string
688
+	 * @throws EE_Error
689
+	 */
690
+	public function payment_overview_url()
691
+	{
692
+		$primary_registration = $this->primary_registration();
693
+		return $primary_registration instanceof EE_Registration ? $primary_registration->payment_overview_url() : false;
694
+	}
695
+
696
+
697
+	/**
698
+	 * @return string
699
+	 * @throws EE_Error
700
+	 */
701
+	public function gateway_response_on_transaction()
702
+	{
703
+		$payment = $this->get_first_related('Payment');
704
+		return $payment instanceof EE_Payment ? $payment->gateway_response() : '';
705
+	}
706
+
707
+
708
+	/**
709
+	 * Get the status object of this object
710
+	 *
711
+	 * @return EE_Base_Class|EE_Status
712
+	 * @throws EE_Error
713
+	 */
714
+	public function status_obj()
715
+	{
716
+		return $this->get_first_related('Status');
717
+	}
718
+
719
+
720
+	/**
721
+	 * Gets all the extra meta info on this payment
722
+	 *
723
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
724
+	 * @return EE_Base_Class[]|EE_Extra_Meta
725
+	 * @throws EE_Error
726
+	 */
727
+	public function extra_meta($query_params = array())
728
+	{
729
+		return $this->get_many_related('Extra_Meta', $query_params);
730
+	}
731
+
732
+
733
+	/**
734
+	 * Wrapper for _add_relation_to
735
+	 *
736
+	 * @param EE_Registration $registration
737
+	 * @return EE_Base_Class the relation was added to
738
+	 * @throws EE_Error
739
+	 */
740
+	public function add_registration(EE_Registration $registration)
741
+	{
742
+		return $this->_add_relation_to($registration, 'Registration');
743
+	}
744
+
745
+
746
+	/**
747
+	 * Removes the given registration from being related (even before saving this transaction).
748
+	 * If an ID/index is provided and this transaction isn't saved yet, removes it from list of cached relations
749
+	 *
750
+	 * @param int $registration_or_id
751
+	 * @return EE_Base_Class that was removed from being related
752
+	 * @throws EE_Error
753
+	 */
754
+	public function remove_registration_with_id($registration_or_id)
755
+	{
756
+		return $this->_remove_relation_to($registration_or_id, 'Registration');
757
+	}
758
+
759
+
760
+	/**
761
+	 * Gets all the line items which are for ACTUAL items
762
+	 *
763
+	 * @return EE_Line_Item[]
764
+	 * @throws EE_Error
765
+	 */
766
+	public function items_purchased()
767
+	{
768
+		return $this->line_items(array(array('LIN_type' => EEM_Line_Item::type_line_item)));
769
+	}
770
+
771
+
772
+	/**
773
+	 * Wrapper for _add_relation_to
774
+	 *
775
+	 * @param EE_Line_Item $line_item
776
+	 * @return EE_Base_Class the relation was added to
777
+	 * @throws EE_Error
778
+	 */
779
+	public function add_line_item(EE_Line_Item $line_item)
780
+	{
781
+		return $this->_add_relation_to($line_item, 'Line_Item');
782
+	}
783
+
784
+
785
+	/**
786
+	 * Gets ALL the line items related to this transaction (unstructured)
787
+	 *
788
+	 * @param array $query_params
789
+	 * @return EE_Base_Class[]|EE_Line_Item[]
790
+	 * @throws EE_Error
791
+	 */
792
+	public function line_items($query_params = array())
793
+	{
794
+		return $this->get_many_related('Line_Item', $query_params);
795
+	}
796
+
797
+
798
+	/**
799
+	 * Gets all the line items which are taxes on the total
800
+	 *
801
+	 * @return EE_Line_Item[]
802
+	 * @throws EE_Error
803
+	 */
804
+	public function tax_items()
805
+	{
806
+		return $this->line_items(array(array('LIN_type' => EEM_Line_Item::type_tax)));
807
+	}
808
+
809
+
810
+	/**
811
+	 * Gets the total line item (which is a parent of all other related line items,
812
+	 * meaning it takes them all into account on its total)
813
+	 *
814
+	 * @param bool $create_if_not_found
815
+	 * @return \EE_Line_Item
816
+	 * @throws EE_Error
817
+	 */
818
+	public function total_line_item($create_if_not_found = true)
819
+	{
820
+		$item = $this->get_first_related('Line_Item', array(array('LIN_type' => EEM_Line_Item::type_total)));
821
+		if (! $item && $create_if_not_found) {
822
+			$item = EEH_Line_Item::create_total_line_item($this);
823
+		}
824
+		return $item;
825
+	}
826
+
827
+
828
+	/**
829
+	 * Returns the total amount of tax on this transaction
830
+	 * (assumes there's only one tax subtotal line item)
831
+	 *
832
+	 * @return float
833
+	 * @throws EE_Error
834
+	 */
835
+	public function tax_total()
836
+	{
837
+		$tax_line_item = $this->tax_total_line_item();
838
+		if ($tax_line_item) {
839
+			return (float) $tax_line_item->total();
840
+		}
841
+		return (float) 0;
842
+	}
843
+
844
+
845
+	/**
846
+	 * Gets the tax subtotal line item (assumes there's only one)
847
+	 *
848
+	 * @return EE_Line_Item
849
+	 * @throws EE_Error
850
+	 */
851
+	public function tax_total_line_item()
852
+	{
853
+		return EEH_Line_Item::get_taxes_subtotal($this->total_line_item());
854
+	}
855
+
856
+
857
+	/**
858
+	 * Gets the array of billing info for the gateway and for this transaction's primary registration's attendee.
859
+	 *
860
+	 * @return EE_Form_Section_Proper
861
+	 * @throws EE_Error
862
+	 */
863
+	public function billing_info()
864
+	{
865
+		$payment_method = $this->payment_method();
866
+		if (! $payment_method) {
867
+			EE_Error::add_error(
868
+				__(
869
+					'Could not find billing info for transaction because no gateway has been used for it yet',
870
+					'event_espresso'
871
+				),
872
+				__FILE__,
873
+				__FUNCTION__,
874
+				__LINE__
875
+			);
876
+			return null;
877
+		}
878
+		$primary_reg = $this->primary_registration();
879
+		if (! $primary_reg) {
880
+			EE_Error::add_error(
881
+				__(
882
+					'Cannot get billing info for gateway %s on transaction because no primary registration exists',
883
+					'event_espresso'
884
+				),
885
+				__FILE__,
886
+				__FUNCTION__,
887
+				__LINE__
888
+			);
889
+			return null;
890
+		}
891
+		$attendee = $primary_reg->attendee();
892
+		if (! $attendee) {
893
+			EE_Error::add_error(
894
+				__(
895
+					'Cannot get billing info for gateway %s on transaction because the primary registration has no attendee exists',
896
+					'event_espresso'
897
+				),
898
+				__FILE__,
899
+				__FUNCTION__,
900
+				__LINE__
901
+			);
902
+			return null;
903
+		}
904
+		return $attendee->billing_info_for_payment_method($payment_method);
905
+	}
906
+
907
+
908
+	/**
909
+	 * Gets PMD_ID
910
+	 *
911
+	 * @return int
912
+	 * @throws EE_Error
913
+	 */
914
+	public function payment_method_ID()
915
+	{
916
+		return $this->get('PMD_ID');
917
+	}
918
+
919
+
920
+	/**
921
+	 * Sets PMD_ID
922
+	 *
923
+	 * @param int $PMD_ID
924
+	 * @throws EE_Error
925
+	 */
926
+	public function set_payment_method_ID($PMD_ID)
927
+	{
928
+		$this->set('PMD_ID', $PMD_ID);
929
+	}
930
+
931
+
932
+	/**
933
+	 * Gets the last-used payment method on this transaction
934
+	 * (we COULD just use the last-made payment, but some payment methods, namely
935
+	 * offline ones, dont' create payments)
936
+	 *
937
+	 * @return EE_Payment_Method
938
+	 * @throws EE_Error
939
+	 */
940
+	public function payment_method()
941
+	{
942
+		$pm = $this->get_first_related('Payment_Method');
943
+		if ($pm instanceof EE_Payment_Method) {
944
+			return $pm;
945
+		}
946
+		$last_payment = $this->last_payment();
947
+		if ($last_payment instanceof EE_Payment && $last_payment->payment_method()) {
948
+			return $last_payment->payment_method();
949
+		}
950
+		return null;
951
+	}
952
+
953
+
954
+	/**
955
+	 * Gets the last payment made
956
+	 *
957
+	 * @return EE_Base_Class|EE_Payment
958
+	 * @throws EE_Error
959
+	 */
960
+	public function last_payment()
961
+	{
962
+		return $this->get_first_related('Payment', array('order_by' => array('PAY_ID' => 'desc')));
963
+	}
964
+
965
+
966
+	/**
967
+	 * Gets all the line items which are unrelated to tickets on this transaction
968
+	 *
969
+	 * @return EE_Line_Item[]
970
+	 * @throws EE_Error
971
+	 * @throws InvalidArgumentException
972
+	 * @throws InvalidDataTypeException
973
+	 * @throws InvalidInterfaceException
974
+	 */
975
+	public function non_ticket_line_items()
976
+	{
977
+		return EEM_Line_Item::instance()->get_all_non_ticket_line_items_for_transaction($this->ID());
978
+	}
979
+
980
+
981
+	/**
982
+	 * possibly toggles TXN status
983
+	 *
984
+	 * @param  boolean $update whether to save the TXN
985
+	 * @return bool whether the TXN was saved
986
+	 * @throws EE_Error
987
+	 * @throws RuntimeException
988
+	 */
989
+	public function update_status_based_on_total_paid($update = true)
990
+	{
991
+		// set transaction status based on comparison of TXN_paid vs TXN_total
992
+		if (EEH_Money::compare_floats($this->paid(), $this->total(), '>')) {
993
+			$new_txn_status = EEM_Transaction::overpaid_status_code;
994
+		} elseif (EEH_Money::compare_floats($this->paid(), $this->total())) {
995
+			$new_txn_status = EEM_Transaction::complete_status_code;
996
+		} elseif (EEH_Money::compare_floats($this->paid(), $this->total(), '<')) {
997
+			$new_txn_status = EEM_Transaction::incomplete_status_code;
998
+		} else {
999
+			throw new RuntimeException(
1000
+				__('The total paid calculation for this transaction is inaccurate.', 'event_espresso')
1001
+			);
1002
+		}
1003
+		if ($new_txn_status !== $this->status_ID()) {
1004
+			$this->set_status($new_txn_status);
1005
+			if ($update) {
1006
+				return $this->save() ? true : false;
1007
+			}
1008
+		}
1009
+		return false;
1010
+	}
1011
+
1012
+
1013
+	/**
1014
+	 * Updates the transaction's status and total_paid based on all the payments
1015
+	 * that apply to it
1016
+	 *
1017
+	 * @deprecated
1018
+	 * @return array|bool
1019
+	 * @throws EE_Error
1020
+	 * @throws InvalidArgumentException
1021
+	 * @throws ReflectionException
1022
+	 * @throws InvalidDataTypeException
1023
+	 * @throws InvalidInterfaceException
1024
+	 */
1025
+	public function update_based_on_payments()
1026
+	{
1027
+		EE_Error::doing_it_wrong(
1028
+			__CLASS__ . '::' . __FUNCTION__,
1029
+			sprintf(
1030
+				__('This method is deprecated. Please use "%s" instead', 'event_espresso'),
1031
+				'EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()'
1032
+			),
1033
+			'4.6.0'
1034
+		);
1035
+		/** @type EE_Transaction_Processor $transaction_processor */
1036
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
1037
+		return $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment($this);
1038
+	}
1039
+
1040
+
1041
+	/**
1042
+	 * @return string
1043
+	 */
1044
+	public function old_txn_status()
1045
+	{
1046
+		return $this->_old_txn_status;
1047
+	}
1048
+
1049
+
1050
+	/**
1051
+	 * @param string $old_txn_status
1052
+	 */
1053
+	public function set_old_txn_status($old_txn_status)
1054
+	{
1055
+		// only set the first time
1056
+		if ($this->_old_txn_status === null) {
1057
+			$this->_old_txn_status = $old_txn_status;
1058
+		}
1059
+	}
1060
+
1061
+
1062
+	/**
1063
+	 * reg_status_updated
1064
+	 *
1065
+	 * @return bool
1066
+	 * @throws EE_Error
1067
+	 */
1068
+	public function txn_status_updated()
1069
+	{
1070
+		return $this->status_ID() !== $this->_old_txn_status && $this->_old_txn_status !== null;
1071
+	}
1072
+
1073
+
1074
+	/**
1075
+	 * _reg_steps_completed
1076
+	 * if $check_all is TRUE, then returns TRUE if ALL reg steps have been marked as completed,
1077
+	 * if a $reg_step_slug is provided, then this step will be skipped when testing for completion
1078
+	 * if $check_all is FALSE and a $reg_step_slug is provided, then ONLY that reg step will be tested for completion
1079
+	 *
1080
+	 * @param string $reg_step_slug
1081
+	 * @param bool   $check_all
1082
+	 * @return bool|int
1083
+	 * @throws EE_Error
1084
+	 */
1085
+	private function _reg_steps_completed($reg_step_slug = '', $check_all = true)
1086
+	{
1087
+		$reg_steps = $this->reg_steps();
1088
+		if (! is_array($reg_steps) || empty($reg_steps)) {
1089
+			return false;
1090
+		}
1091
+		// loop thru reg steps array)
1092
+		foreach ($reg_steps as $slug => $reg_step_completed) {
1093
+			// if NOT checking ALL steps (only checking one step)
1094
+			if (! $check_all) {
1095
+				// and this is the one
1096
+				if ($slug === $reg_step_slug) {
1097
+					return $reg_step_completed;
1098
+				}
1099
+				// skip to next reg step in loop
1100
+				continue;
1101
+			}
1102
+			// $check_all must be true, else we would never have gotten to this point
1103
+			if ($slug === $reg_step_slug) {
1104
+				// if we reach this point, then we are testing either:
1105
+				// all_reg_steps_completed_except() or
1106
+				// all_reg_steps_completed_except_final_step(),
1107
+				// and since this is the reg step EXCEPTION being tested
1108
+				// we want to return true (yes true) if this reg step is NOT completed
1109
+				// ie: "is everything completed except the final step?"
1110
+				// "that is correct... the final step is not completed, but all others are."
1111
+				return $reg_step_completed !== true;
1112
+			}
1113
+			if ($reg_step_completed !== true) {
1114
+				// if any reg step is NOT completed, then ALL steps are not completed
1115
+				return false;
1116
+			}
1117
+		}
1118
+		return true;
1119
+	}
1120
+
1121
+
1122
+	/**
1123
+	 * all_reg_steps_completed
1124
+	 * returns:
1125
+	 *    true if ALL reg steps have been marked as completed
1126
+	 *        or false if any step is not completed
1127
+	 *
1128
+	 * @return bool
1129
+	 * @throws EE_Error
1130
+	 */
1131
+	public function all_reg_steps_completed()
1132
+	{
1133
+		return $this->_reg_steps_completed();
1134
+	}
1135
+
1136
+
1137
+	/**
1138
+	 * all_reg_steps_completed_except
1139
+	 * returns:
1140
+	 *        true if ALL reg steps, except a particular step that you wish to skip over, have been marked as completed
1141
+	 *        or false if any other step is not completed
1142
+	 *        or false if ALL steps are completed including the exception you are testing !!!
1143
+	 *
1144
+	 * @param string $exception
1145
+	 * @return bool
1146
+	 * @throws EE_Error
1147
+	 */
1148
+	public function all_reg_steps_completed_except($exception = '')
1149
+	{
1150
+		return $this->_reg_steps_completed($exception);
1151
+	}
1152
+
1153
+
1154
+	/**
1155
+	 * all_reg_steps_completed_except
1156
+	 * returns:
1157
+	 *        true if ALL reg steps, except the final step, have been marked as completed
1158
+	 *        or false if any step is not completed
1159
+	 *    or false if ALL steps are completed including the final step !!!
1160
+	 *
1161
+	 * @return bool
1162
+	 * @throws EE_Error
1163
+	 */
1164
+	public function all_reg_steps_completed_except_final_step()
1165
+	{
1166
+		return $this->_reg_steps_completed('finalize_registration');
1167
+	}
1168
+
1169
+
1170
+	/**
1171
+	 * reg_step_completed
1172
+	 * returns:
1173
+	 *    true if a specific reg step has been marked as completed
1174
+	 *    a Unix timestamp if it has been initialized but not yet completed,
1175
+	 *    or false if it has not yet been initialized
1176
+	 *
1177
+	 * @param string $reg_step_slug
1178
+	 * @return bool|int
1179
+	 * @throws EE_Error
1180
+	 */
1181
+	public function reg_step_completed($reg_step_slug)
1182
+	{
1183
+		return $this->_reg_steps_completed($reg_step_slug, false);
1184
+	}
1185
+
1186
+
1187
+	/**
1188
+	 * completed_final_reg_step
1189
+	 * returns:
1190
+	 *    true if the finalize_registration reg step has been marked as completed
1191
+	 *    a Unix timestamp if it has been initialized but not yet completed,
1192
+	 *    or false if it has not yet been initialized
1193
+	 *
1194
+	 * @return bool|int
1195
+	 * @throws EE_Error
1196
+	 */
1197
+	public function final_reg_step_completed()
1198
+	{
1199
+		return $this->_reg_steps_completed('finalize_registration', false);
1200
+	}
1201
+
1202
+
1203
+	/**
1204
+	 * set_reg_step_initiated
1205
+	 * given a valid TXN_reg_step, this sets it's value to a unix timestamp
1206
+	 *
1207
+	 * @param string $reg_step_slug
1208
+	 * @return boolean
1209
+	 * @throws EE_Error
1210
+	 */
1211
+	public function set_reg_step_initiated($reg_step_slug)
1212
+	{
1213
+		return $this->_set_reg_step_completed_status($reg_step_slug, time());
1214
+	}
1215
+
1216
+
1217
+	/**
1218
+	 * set_reg_step_completed
1219
+	 * given a valid TXN_reg_step, this sets the step as completed
1220
+	 *
1221
+	 * @param string $reg_step_slug
1222
+	 * @return boolean
1223
+	 * @throws EE_Error
1224
+	 */
1225
+	public function set_reg_step_completed($reg_step_slug)
1226
+	{
1227
+		return $this->_set_reg_step_completed_status($reg_step_slug, true);
1228
+	}
1229
+
1230
+
1231
+	/**
1232
+	 * set_reg_step_completed
1233
+	 * given a valid TXN_reg_step slug, this sets the step as NOT completed
1234
+	 *
1235
+	 * @param string $reg_step_slug
1236
+	 * @return boolean
1237
+	 * @throws EE_Error
1238
+	 */
1239
+	public function set_reg_step_not_completed($reg_step_slug)
1240
+	{
1241
+		return $this->_set_reg_step_completed_status($reg_step_slug, false);
1242
+	}
1243
+
1244
+
1245
+	/**
1246
+	 * set_reg_step_completed
1247
+	 * given a valid reg step slug, this sets the TXN_reg_step completed status which is either:
1248
+	 *
1249
+	 * @param  string      $reg_step_slug
1250
+	 * @param  boolean|int $status
1251
+	 * @return boolean
1252
+	 * @throws EE_Error
1253
+	 */
1254
+	private function _set_reg_step_completed_status($reg_step_slug, $status)
1255
+	{
1256
+		// validate status
1257
+		$status = is_bool($status) || is_int($status) ? $status : false;
1258
+		// get reg steps array
1259
+		$txn_reg_steps = $this->reg_steps();
1260
+		// if reg step does NOT exist
1261
+		if (! isset($txn_reg_steps[ $reg_step_slug ])) {
1262
+			return false;
1263
+		}
1264
+		// if  we're trying to complete a step that is already completed
1265
+		if ($txn_reg_steps[ $reg_step_slug ] === true) {
1266
+			return true;
1267
+		}
1268
+		// if  we're trying to complete a step that hasn't even started
1269
+		if ($status === true && $txn_reg_steps[ $reg_step_slug ] === false) {
1270
+			return false;
1271
+		}
1272
+		// if current status value matches the incoming value (no change)
1273
+		// type casting as int means values should collapse to either 0, 1, or a timestamp like 1234567890
1274
+		if ((int) $txn_reg_steps[ $reg_step_slug ] === (int) $status) {
1275
+			// this will happen in cases where multiple AJAX requests occur during the same step
1276
+			return true;
1277
+		}
1278
+		// if we're trying to set a start time, but it has already been set...
1279
+		if (is_numeric($status) && is_numeric($txn_reg_steps[ $reg_step_slug ])) {
1280
+			// skip the update below, but don't return FALSE so that errors won't be displayed
1281
+			return true;
1282
+		}
1283
+		// update completed status
1284
+		$txn_reg_steps[ $reg_step_slug ] = $status;
1285
+		$this->set_reg_steps($txn_reg_steps);
1286
+		$this->save();
1287
+		return true;
1288
+	}
1289
+
1290
+
1291
+	/**
1292
+	 * remove_reg_step
1293
+	 * given a valid TXN_reg_step slug, this will remove (unset)
1294
+	 * the reg step from the TXN reg step array
1295
+	 *
1296
+	 * @param string $reg_step_slug
1297
+	 * @return void
1298
+	 * @throws EE_Error
1299
+	 */
1300
+	public function remove_reg_step($reg_step_slug)
1301
+	{
1302
+		// get reg steps array
1303
+		$txn_reg_steps = $this->reg_steps();
1304
+		unset($txn_reg_steps[ $reg_step_slug ]);
1305
+		$this->set_reg_steps($txn_reg_steps);
1306
+	}
1307
+
1308
+
1309
+	/**
1310
+	 * toggle_failed_transaction_status
1311
+	 * upgrades a TXNs status from failed to abandoned,
1312
+	 * meaning that contact information has been captured for at least one registrant
1313
+	 *
1314
+	 * @param bool $save
1315
+	 * @return bool
1316
+	 * @throws EE_Error
1317
+	 */
1318
+	public function toggle_failed_transaction_status($save = true)
1319
+	{
1320
+		// if TXN status is still set as "failed"...
1321
+		if ($this->status_ID() === EEM_Transaction::failed_status_code) {
1322
+			$this->set_status(EEM_Transaction::abandoned_status_code);
1323
+			if ($save) {
1324
+				$this->save();
1325
+			}
1326
+			return true;
1327
+		}
1328
+		return false;
1329
+	}
1330
+
1331
+
1332
+	/**
1333
+	 * toggle_abandoned_transaction_status
1334
+	 * upgrades a TXNs status from failed or abandoned to incomplete
1335
+	 *
1336
+	 * @return bool
1337
+	 * @throws EE_Error
1338
+	 */
1339
+	public function toggle_abandoned_transaction_status()
1340
+	{
1341
+		// if TXN status has not been updated already due to a payment, and is still set as "failed" or "abandoned"...
1342
+		$txn_status = $this->status_ID();
1343
+		if ($txn_status === EEM_Transaction::failed_status_code
1344
+			|| $txn_status === EEM_Transaction::abandoned_status_code
1345
+		) {
1346
+			// if a contact record for the primary registrant has been created
1347
+			if ($this->primary_registration() instanceof EE_Registration
1348
+				&& $this->primary_registration()->attendee() instanceof EE_Attendee
1349
+			) {
1350
+				$this->set_status(EEM_Transaction::incomplete_status_code);
1351
+			} else {
1352
+				// no contact record? yer abandoned!
1353
+				$this->set_status(EEM_Transaction::abandoned_status_code);
1354
+			}
1355
+			return true;
1356
+		}
1357
+		return false;
1358
+	}
1359
+
1360
+
1361
+	/**
1362
+	 * checks if an Abandoned TXN has any related payments, and if so,
1363
+	 * updates the TXN status based on the amount paid
1364
+	 *
1365
+	 * @throws EE_Error
1366
+	 * @throws InvalidDataTypeException
1367
+	 * @throws InvalidInterfaceException
1368
+	 * @throws InvalidArgumentException
1369
+	 * @throws RuntimeException
1370
+	 */
1371
+	public function verify_abandoned_transaction_status()
1372
+	{
1373
+		if ($this->status_ID() !== EEM_Transaction::abandoned_status_code) {
1374
+			return;
1375
+		}
1376
+		$payments = $this->get_many_related('Payment');
1377
+		if (! empty($payments)) {
1378
+			foreach ($payments as $payment) {
1379
+				if ($payment instanceof EE_Payment) {
1380
+					// kk this TXN should NOT be abandoned
1381
+					$this->update_status_based_on_total_paid();
1382
+					if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
1383
+						EE_Error::add_attention(
1384
+							sprintf(
1385
+								esc_html__(
1386
+									'The status for Transaction #%1$d has been updated from "Abandoned" to "%2$s", because at least one payment has been made towards it. If the payment appears in the "Payment Details" table below, you may need to edit its status and/or other details as well.',
1387
+									'event_espresso'
1388
+								),
1389
+								$this->ID(),
1390
+								$this->pretty_status()
1391
+							)
1392
+						);
1393
+					}
1394
+					// get final reg step status
1395
+					$finalized = $this->final_reg_step_completed();
1396
+					// if the 'finalize_registration' step has been initiated (has a timestamp)
1397
+					// but has not yet been fully completed (TRUE)
1398
+					if (is_int($finalized) && $finalized !== false && $finalized !== true) {
1399
+						$this->set_reg_step_completed('finalize_registration');
1400
+						$this->save();
1401
+					}
1402
+				}
1403
+			}
1404
+		}
1405
+	}
1406 1406
 }
Please login to merge, or discard this patch.