1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace EventEspresso\modules\invalid_checkout_access; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Class InvalidCheckoutAccessForm |
7
|
|
|
* Controls and tracks invalid access to the registration checkout page |
8
|
|
|
* |
9
|
|
|
* @package Event Espresso |
10
|
|
|
* @author Brent Christensen |
11
|
|
|
* @since 4.9.17 |
12
|
|
|
*/ |
13
|
|
|
class InvalidCheckoutAccess |
14
|
|
|
{ |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* key used for saving invalid checkout access data to the wp_options table |
18
|
|
|
*/ |
19
|
|
|
const OPTION_KEY = 'ee_invalid_checkout_access'; |
20
|
|
|
|
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* _block_bots |
24
|
|
|
* checks that the incoming request has either of the following set: |
25
|
|
|
* a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector |
26
|
|
|
* a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN |
27
|
|
|
* so if you're not coming from the Ticket Selector nor returning for a valid IP... |
28
|
|
|
* then where you coming from man? |
29
|
|
|
* |
30
|
|
|
* @param \EE_Checkout $checkout |
31
|
|
|
* @return bool true if access to registration checkout appears to be invalid |
32
|
|
|
*/ |
33
|
|
|
public function checkoutAccessIsInvalid(\EE_Checkout $checkout) |
34
|
|
|
{ |
35
|
|
|
if (! ($checkout->uts || $checkout->reg_url_link) |
36
|
|
|
&& ! (defined('DOING_AJAX') && DOING_AJAX) |
37
|
|
|
&& \EE_Config::instance()->registration->track_invalid_checkout_access() |
38
|
|
|
) { |
39
|
|
|
/** @var \EE_Request $request */ |
40
|
|
|
$request = \EE_Registry::instance()->load_core('EE_Request'); |
41
|
|
|
$ip_address = $request->ip_address(); |
|
|
|
|
42
|
|
|
$ee_bot_checkout = get_option(InvalidCheckoutAccess::OPTION_KEY); |
43
|
|
|
if ($ee_bot_checkout === false) { |
44
|
|
|
$ee_bot_checkout = array(); |
45
|
|
|
add_option(InvalidCheckoutAccess::OPTION_KEY, $ee_bot_checkout, '', false); |
46
|
|
|
} |
47
|
|
|
if (! isset($ee_bot_checkout[ $ip_address ])) { |
48
|
|
|
$ee_bot_checkout[ $ip_address ] = array(); |
49
|
|
|
} |
50
|
|
|
$http_referer = isset($_SERVER['HTTP_REFERER']) |
51
|
|
|
? esc_attr($_SERVER['HTTP_REFERER']) |
52
|
|
|
: 0; |
53
|
|
|
if (! isset($ee_bot_checkout[ $ip_address ][ $http_referer ])) { |
54
|
|
|
$ee_bot_checkout[ $ip_address ][ $http_referer ] = 0; |
55
|
|
|
} |
56
|
|
|
$ee_bot_checkout[ $ip_address ][ $http_referer ]++; |
57
|
|
|
update_option(InvalidCheckoutAccess::OPTION_KEY, $ee_bot_checkout); |
58
|
|
|
if (WP_DEBUG) { |
59
|
|
|
\EE_Error::add_error( |
60
|
|
|
esc_html__('Direct access to the registration checkout page is not allowed.', 'event_espresso'), |
61
|
|
|
__FILE__, |
62
|
|
|
__FUNCTION__, |
63
|
|
|
__LINE__ |
64
|
|
|
); |
65
|
|
|
} |
66
|
|
|
return true; |
67
|
|
|
} |
68
|
|
|
return false; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* _invalid_checkout_access_form |
74
|
|
|
* |
75
|
|
|
* @return \EE_Form_Section_Proper |
76
|
|
|
* @throws \EE_Error |
77
|
|
|
*/ |
78
|
|
|
public function getForm() |
79
|
|
|
{ |
80
|
|
|
return new \EE_Form_Section_Proper( |
81
|
|
|
array( |
82
|
|
|
'name' => 'invalid_checkout_access', |
83
|
|
|
'html_id' => 'invalid_checkout_access', |
84
|
|
|
'layout_strategy' => new \EE_Admin_Two_Column_Layout(), |
85
|
|
|
'subsections' => array( |
86
|
|
|
'invalid_checkout_access_hdr' => new \EE_Form_Section_HTML( |
87
|
|
|
\EEH_HTML::h2(esc_html__('Invalid Checkout Access', 'event_espresso')) |
88
|
|
|
), |
89
|
|
|
'ee_bot_checkout_data' => new \EE_Text_Area_Input( |
90
|
|
|
array( |
91
|
|
|
'html_label_text' => esc_html__('Invalid Checkout Data', 'event_espresso'), |
92
|
|
|
'default' => var_export( |
93
|
|
|
get_option(InvalidCheckoutAccess::OPTION_KEY, array()), |
94
|
|
|
true |
95
|
|
|
), |
96
|
|
|
'required' => false, |
97
|
|
|
'html_help_text' => esc_html__( |
98
|
|
|
'Event Espresso blocks any attempt to directly access the registration checkout page, that is NOT from a Ticket Selector or for a return visit for a valid transaction. These are not valid requests accessing your checkout page, so we track the IP addresses, what web page they just came from, and the number of times that they have attempted to access your registration page. This information may help you with protecting your site by other means, such as firewalls, etc, but please note that IP addresses are almost guaranteed to be spoofed by malicious agents.', |
99
|
|
|
'event_espresso' |
100
|
|
|
), |
101
|
|
|
) |
102
|
|
|
), |
103
|
|
|
'track_invalid_checkout_access' => new \EE_Yes_No_Input( |
104
|
|
|
array( |
105
|
|
|
'html_label_text' => __('Track Invalid Checkout Access?', 'event_espresso'), |
106
|
|
|
'html_help_text' => esc_html__( |
107
|
|
|
'Controls whether or not invalid attempts to directly access the registration checkout page should be tracked. Setting this to "No" means that the above data will no longer be collected.', |
108
|
|
|
'event_espresso' |
109
|
|
|
), |
110
|
|
|
'default' => \EE_Config::instance() |
111
|
|
|
->registration |
112
|
|
|
->track_invalid_checkout_access(), |
113
|
|
|
'display_html_label_text' => false, |
114
|
|
|
) |
115
|
|
|
), |
116
|
|
|
'delete_invalid_checkout_data' => new \EE_Yes_No_Input( |
117
|
|
|
array( |
118
|
|
|
'html_label_text' => __('Reset Invalid Checkout Data', 'event_espresso'), |
119
|
|
|
'html_help_text' => esc_html__( |
120
|
|
|
'Setting this to "Yes" will delete all existing invalid checkout access data.', |
121
|
|
|
'event_espresso' |
122
|
|
|
), |
123
|
|
|
'default' => false, |
124
|
|
|
'display_html_label_text' => false, |
125
|
|
|
) |
126
|
|
|
), |
127
|
|
|
), |
128
|
|
|
) |
129
|
|
|
); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* update_invalid_checkout_access_form |
135
|
|
|
* |
136
|
|
|
* @param \EE_Registration_Config $EE_Registration_Config |
137
|
|
|
* @return \EE_Registration_Config |
138
|
|
|
*/ |
139
|
|
|
public function processForm(\EE_Registration_Config $EE_Registration_Config) |
140
|
|
|
{ |
141
|
|
|
try { |
142
|
|
|
$invalid_checkout_access_form = $this->getForm(); |
143
|
|
|
// if not displaying a form, then check for form submission |
144
|
|
|
if ($invalid_checkout_access_form->was_submitted()) { |
145
|
|
|
// capture form data |
146
|
|
|
$invalid_checkout_access_form->receive_form_submission(); |
147
|
|
|
// validate form data |
148
|
|
|
if ($invalid_checkout_access_form->is_valid()) { |
149
|
|
|
// grab validated data from form |
150
|
|
|
$valid_data = $invalid_checkout_access_form->valid_data(); |
151
|
|
|
// ensure form inputs we want are set |
152
|
|
|
if (isset( |
153
|
|
|
$valid_data['track_invalid_checkout_access'], |
154
|
|
|
$valid_data['delete_invalid_checkout_data'] |
155
|
|
|
)) { |
156
|
|
|
$EE_Registration_Config->set_track_invalid_checkout_access( |
157
|
|
|
$valid_data['track_invalid_checkout_access'] |
158
|
|
|
); |
159
|
|
|
// if deleting, then update option with empty array |
160
|
|
|
if (filter_var($valid_data['delete_invalid_checkout_data'], FILTER_VALIDATE_BOOLEAN)) { |
161
|
|
|
update_option(InvalidCheckoutAccess::OPTION_KEY, array()); |
162
|
|
|
} |
163
|
|
|
} else { |
164
|
|
|
\EE_Error::add_error( |
165
|
|
|
esc_html__( |
166
|
|
|
'Invalid or missing Invalid Checkout Access form data. Please refresh the form and try again.', |
167
|
|
|
'event_espresso' |
168
|
|
|
), |
169
|
|
|
__FILE__, |
170
|
|
|
__FUNCTION__, |
171
|
|
|
__LINE__ |
172
|
|
|
); |
173
|
|
|
} |
174
|
|
|
} else { |
175
|
|
|
if ($invalid_checkout_access_form->submission_error_message() !== '') { |
176
|
|
|
\EE_Error::add_error( |
177
|
|
|
$invalid_checkout_access_form->submission_error_message(), |
178
|
|
|
__FILE__, |
179
|
|
|
__FUNCTION__, |
180
|
|
|
__LINE__ |
181
|
|
|
); |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
} catch (\EE_Error $e) { |
186
|
|
|
$e->get_error(); |
187
|
|
|
} |
188
|
|
|
return $EE_Registration_Config; |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.