Completed
Branch BUG/11475/decode-site-title-fo... (bbd86e)
by
unknown
13:39 queued 25s
created

EED_Recaptcha::set_hooks()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 33
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 23
nc 2
nop 0
dl 0
loc 33
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
use EventEspresso\core\exceptions\InvalidDataTypeException;
4
use EventEspresso\core\exceptions\InvalidInterfaceException;
5
use ReCaptcha\ReCaptcha;
6
use ReCaptcha\RequestMethod\SocketPost;
7
use ReCaptcha\Response;
8
9
defined('EVENT_ESPRESSO_VERSION') || exit('NO direct script access allowed');
10
11
12
13
/**
14
 * EED_Recaptcha
15
 * PLZ NOTE: ALL ADMIN SETTINGS FUNCTIONALITY HAS BEEN MOVED TO
16
 * \EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings
17
 *
18
 * @package        Event Espresso
19
 * @subpackage     /modules/recaptcha/
20
 * @author         Brent Christensen
21
 */
22
class EED_Recaptcha extends EED_Module
23
{
24
25
    /**
26
     * @var EE_Registration_Config $config
27
     */
28
    private static $config;
29
30
    /**
31
     * @type bool $_not_a_robot
32
     */
33
    private static $_not_a_robot;
34
35
    /**
36
     * @type string $_recaptcha_response
37
     */
38
    private static $_recaptcha_response;
39
40
41
    /**
42
     * @return EED_Module|EED_Recaptcha
43
     */
44
    public static function instance()
45
    {
46
        return parent::get_instance(__CLASS__);
47
    }
48
49
50
    /**
51
     * set_hooks - for hooking into EE Core, other modules, etc
52
     *
53
     * @return void
54
     * @throws InvalidArgumentException
55
     * @throws InvalidInterfaceException
56
     * @throws InvalidDataTypeException
57
     */
58
    public static function set_hooks()
59
    {
60
        EED_Recaptcha::$config = EE_Registry::instance()->CFG->registration;
61
        // use_captcha ?
62
        if (
63
            EED_Recaptcha::useRecaptcha()
64
            && EED_Recaptcha::notPaymentOptionsRevisit()
65
        ) {
66
            EED_Recaptcha::set_definitions();
67
            EED_Recaptcha::enqueue_styles_and_scripts();
68
            add_action('wp', array('EED_Recaptcha', 'set_late_hooks'), 1, 0);
69
            add_action(
70
                'AHEE__before_spco_whats_next_buttons',
71
                array('EED_Recaptcha', 'display_recaptcha'), 10, 0
72
            );
73
            add_filter(
74
                'FHEE__EED_Single_Page_Checkout__init___continue_reg',
75
                array('EED_Recaptcha', 'not_a_robot')
76
            );
77
            add_filter(
78
                'FHEE__EE_SPCO_Reg_Step__set_completed___completed',
79
                array('EED_Recaptcha', 'not_a_robot')
80
            );
81
            add_filter(
82
                'FHEE__EE_SPCO_JSON_Response___toString__JSON_response',
83
                array('EED_Recaptcha', 'recaptcha_response')
84
            );
85
            add_filter(
86
                'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array',
87
                array('EED_Recaptcha', 'bypass_recaptcha_for_spco_load_payment_method')
88
            );
89
        }
90
    }
91
92
93
    /**
94
     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
95
     *
96
     * @return void
97
     * @throws InvalidArgumentException
98
     * @throws InvalidInterfaceException
99
     * @throws InvalidDataTypeException
100
     */
101
    public static function set_hooks_admin()
102
    {
103
        EED_Recaptcha::$config = EE_Registry::instance()->CFG->registration;
104
        EED_Recaptcha::set_definitions();
105
        // use_captcha ?
106
        if (
107
            EED_Recaptcha::useRecaptcha()
108
            && EED_Recaptcha::notPaymentOptionsRevisit()
109
            && EE_Registry::instance()->REQ->get('step', '') !== ''
110
        ) {
111
            EED_Recaptcha::enqueue_styles_and_scripts();
112
            add_filter(
113
                'FHEE__EED_Single_Page_Checkout__init___continue_reg',
114
                array('EED_Recaptcha', 'not_a_robot')
115
            );
116
            add_filter(
117
                'FHEE__EE_SPCO_Reg_Step__set_completed___completed',
118
                array('EED_Recaptcha', 'not_a_robot')
119
            );
120
            add_filter(
121
                'FHEE__EE_SPCO_JSON_Response___toString__JSON_response',
122
                array('EED_Recaptcha', 'recaptcha_response')
123
            );
124
        }
125
    }
126
127
128
    /**
129
     * @return void
130
     */
131
    public static function set_definitions()
132
    {
133
        if (is_user_logged_in()) {
134
            EED_Recaptcha::$_not_a_robot = true;
135
        }
136
        define(
137
            'RECAPTCHA_BASE_PATH',
138
            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
139
        );
140
        define('RECAPTCHA_BASE_URL', plugin_dir_url(__FILE__));
141
    }
142
143
144
    /**
145
     * @return void
146
     */
147
    public static function set_late_hooks()
148
    {
149
        add_filter(
150
            'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
151
            array('EED_Recaptcha', 'not_a_robot')
152
        );
153
    }
154
155
156
    /**
157
     * @return boolean
158
     */
159
    public static function useRecaptcha()
160
    {
161
        return EED_Recaptcha::$config->use_captcha
162
               && EED_Recaptcha::$config->recaptcha_theme !== 'invisible';
163
    }
164
165
166
    /**
167
     * @return boolean
168
     * @throws InvalidArgumentException
169
     * @throws InvalidInterfaceException
170
     * @throws InvalidDataTypeException
171
     */
172
    public static function notPaymentOptionsRevisit()
173
    {
174
        return ! (
175
            EE_Registry::instance()->REQ->get('step', '') === 'payment_options'
176
            && (boolean) EE_Registry::instance()->REQ->get('revisit', false) === true
177
        );
178
    }
179
180
181
    /**
182
     * @return void
183
     * @throws InvalidArgumentException
184
     * @throws InvalidInterfaceException
185
     * @throws InvalidDataTypeException
186
     */
187
    public static function enqueue_styles_and_scripts()
188
    {
189
        wp_register_script(
190
            'espresso_recaptcha',
191
            RECAPTCHA_BASE_URL . 'scripts' . DS . 'espresso_recaptcha.js',
192
            array('single_page_checkout'),
193
            EVENT_ESPRESSO_VERSION,
194
            true
195
        );
196
        wp_register_script(
197
            'google_recaptcha',
198
            'https://www.google.com/recaptcha/api.js?hl=' . EED_Recaptcha::$config->recaptcha_language,
199
            array('espresso_recaptcha'),
200
            EVENT_ESPRESSO_VERSION,
201
            true
202
        );
203
        EE_Registry::$i18n_js_strings['no_SPCO_error']      = __(
204
            'It appears the Single Page Checkout javascript was not loaded properly! Please refresh the page and try again or contact support.',
205
            'event_espresso'
206
        );
207
        EE_Registry::$i18n_js_strings['no_recaptcha_error'] = __(
208
            'There appears to be a problem with the reCAPTCHA configuration! Please check the admin settings or contact support.',
209
            'event_espresso'
210
        );
211
        EE_Registry::$i18n_js_strings['recaptcha_fail']     = __(
212
            'Please complete the anti-spam test before proceeding.',
213
            'event_espresso'
214
        );
215
    }
216
217
218
    /**
219
     * @param \WP $WP
220
     */
221
    public function run($WP)
222
    {
223
    }
224
225
226
    /**
227
     * @return boolean
228
     * @throws InvalidArgumentException
229
     * @throws InvalidInterfaceException
230
     * @throws InvalidDataTypeException
231
     */
232
    public static function not_a_robot()
233
    {
234
        $not_a_robot = is_bool(EED_Recaptcha::$_not_a_robot)
235
            ? EED_Recaptcha::$_not_a_robot
236
            : EED_Recaptcha::recaptcha_passed();
237
        return $not_a_robot;
238
    }
239
240
241
    /**
242
     * @return void
243
     * @throws DomainException
244
     * @throws InvalidArgumentException
245
     * @throws InvalidInterfaceException
246
     * @throws InvalidDataTypeException
247
     */
248
    public static function display_recaptcha()
249
    {
250
        // logged in means you have already passed a turing test of sorts
251
        if (is_user_logged_in()) {
252
            return;
253
        }
254
        // don't display if not using recaptcha or user is logged in
255
        if (EED_Recaptcha::useRecaptcha() && ! EED_Recaptcha::$_not_a_robot) {
256
            // only display if they have NOT passed the test yet
257
            EEH_Template::display_template(
258
                RECAPTCHA_BASE_PATH . DS . 'templates' . DS . 'recaptcha.template.php',
259
                array(
260
                    'recaptcha_publickey' => EED_Recaptcha::$config->recaptcha_publickey,
261
                    'recaptcha_theme'     => EED_Recaptcha::$config->recaptcha_theme,
262
                    'recaptcha_type'      => EED_Recaptcha::$config->recaptcha_type,
263
                )
264
            );
265
            wp_enqueue_script('google_recaptcha');
266
        }
267
    }
268
269
270
    /**
271
     * @return array
272
     * @throws InvalidArgumentException
273
     * @throws InvalidInterfaceException
274
     * @throws InvalidDataTypeException
275
     */
276
    public static function bypass_recaptcha_for_spco_load_payment_method()
277
    {
278
        return array(
279
            'EESID'  => EE_Registry::instance()->SSN->id(),
280
            'step'   => 'payment_options',
281
            'action' => 'switch_spco_billing_form',
282
        );
283
    }
284
285
286
    /**
287
     * @return boolean
288
     * @throws InvalidArgumentException
289
     * @throws InvalidInterfaceException
290
     * @throws InvalidDataTypeException
291
     */
292
    public static function recaptcha_passed()
293
    {
294
        // logged in means you have already passed a turing test of sorts
295
        if (is_user_logged_in() || EED_Recaptcha::_bypass_recaptcha()) {
296
            return true;
297
        }
298
        // was test already passed?
299
        $recaptcha_passed = EE_Registry::instance()->SSN->get_session_data('recaptcha_passed');
300
        $recaptcha_passed = filter_var($recaptcha_passed, FILTER_VALIDATE_BOOLEAN);
301
        // verify recaptcha
302
        EED_Recaptcha::_get_recaptcha_response();
303
        if (! $recaptcha_passed && EED_Recaptcha::$_recaptcha_response) {
304
            $recaptcha_passed = EED_Recaptcha::_process_recaptcha_response();
305
            EE_Registry::instance()->SSN->set_session_data(array('recaptcha_passed' => $recaptcha_passed));
306
        }
307
        EED_Recaptcha::$_not_a_robot = $recaptcha_passed;
308
        return $recaptcha_passed;
309
    }
310
311
312
    /**
313
     * @param array $recaptcha_response
314
     * @return array
315
     */
316
    public static function recaptcha_response($recaptcha_response = array())
317
    {
318
        if (EED_Recaptcha::_bypass_recaptcha()) {
319
            $recaptcha_response['bypass_recaptcha'] = true;
320
            $recaptcha_response['recaptcha_passed'] = true;
321
        } else {
322
            $recaptcha_response['recaptcha_passed'] = EED_Recaptcha::$_not_a_robot;
323
        }
324
        return $recaptcha_response;
325
    }
326
327
328
    /**
329
     * @return boolean
330
     */
331
    private static function _bypass_recaptcha()
332
    {
333
        // an array of key value pairs that must match exactly with the incoming request,
334
        // in order to bypass recaptcha for the current request ONLY
335
        $bypass_request_params_array = (array) apply_filters(
336
            'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array',
337
            array()
338
        );
339
        // does $bypass_request_params_array have any values ?
340
        if (empty($bypass_request_params_array)) {
341
            return false;
342
        }
343
        // initially set bypass to TRUE
344
        $bypass_recaptcha = true;
345
        foreach ($bypass_request_params_array as $key => $value) {
346
            // if $key is not found or value doesn't match exactly, then toggle bypass to FALSE,
347
            // otherwise carry over it's value. This way, one missed setting results in no bypass
348
            $bypass_recaptcha = isset($_REQUEST[ $key ]) && $_REQUEST[ $key ] === $value
349
                ? $bypass_recaptcha
350
                : false;
351
        }
352
        return $bypass_recaptcha;
353
    }
354
355
356
    /**
357
     * @return void
358
     * @throws InvalidArgumentException
359
     * @throws InvalidInterfaceException
360
     * @throws InvalidDataTypeException
361
     */
362
    private static function _get_recaptcha_response()
363
    {
364
        EED_Recaptcha::$_recaptcha_response = EE_Registry::instance()->REQ->get(
365
            'g-recaptcha-response',
366
            false
367
        );
368
    }
369
370
371
    /**
372
     * @return boolean
373
     * @throws InvalidArgumentException
374
     * @throws InvalidInterfaceException
375
     * @throws InvalidDataTypeException
376
     */
377
    private static function _process_recaptcha_response()
378
    {
379
        // verify library is loaded
380
        if (! class_exists('\ReCaptcha\ReCaptcha')) {
381
            require_once RECAPTCHA_BASE_PATH . DS . 'autoload.php';
382
        }
383
        // The response from reCAPTCHA
384
        EED_Recaptcha::_get_recaptcha_response();
385
        $recaptcha_response = EED_Recaptcha::$_recaptcha_response;
386
        // Was there a reCAPTCHA response?
387
        if ($recaptcha_response) {
388
            // if allow_url_fopen is Off, then set a different request method
389
            $request_method     = ! ini_get('allow_url_fopen') ? new SocketPost() : null;
390
            $recaptcha          = new ReCaptcha(
391
                EED_Recaptcha::$config->recaptcha_privatekey,
392
                $request_method
393
            );
394
            $recaptcha_response = $recaptcha->verify(
395
                EED_Recaptcha::$_recaptcha_response,
396
                $_SERVER['REMOTE_ADDR']
397
            );
398
        }
399
        return $recaptcha_response instanceof Response && $recaptcha_response->isSuccess();
400
    }
401
}
402
// End of file EED_Recaptcha.module.php
403
// Location: /modules/recaptcha/EED_Recaptcha.module.php
404