├── .gitignore ├── docs └── images │ ├── google-recaptcha-v2-default.png │ ├── google-recaptcha-v3-default.png │ └── google-recaptcha-v3-inline.png ├── composer.json ├── README.md └── src └── AlexStack └── GoogleRecaptchaToAnyForm └── GoogleRecaptcha.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor/ 3 | composer.lock -------------------------------------------------------------------------------- /docs/images/google-recaptcha-v2-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexStack/Google-Recaptcha-to-any-form/master/docs/images/google-recaptcha-v2-default.png -------------------------------------------------------------------------------- /docs/images/google-recaptcha-v3-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexStack/Google-Recaptcha-to-any-form/master/docs/images/google-recaptcha-v3-default.png -------------------------------------------------------------------------------- /docs/images/google-recaptcha-v3-inline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexStack/Google-Recaptcha-to-any-form/master/docs/images/google-recaptcha-v3-inline.png -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alexstack/google-recaptcha-to-any-form", 3 | "description": "Display a Google Recaptcha v2 or v3 or invisible in any custom form with flexible settings and no affection to your existing code. Also works well for SilverStripe 4.x/3.x/2.x & Laravel & Wordpress & other CMS. ", 4 | "homepage": "https://github.com/AlexStack/Google-Recaptcha-to-any-form", 5 | "type": "library", 6 | "keywords": [ 7 | "silverstripe", 8 | "silverstripe3", 9 | "silverstripe4", 10 | "google recaptcha", 11 | "recaptcha", 12 | "google recaptcha v2" 13 | ], 14 | "license": "MIT", 15 | "authors": [ 16 | { 17 | "name": "Alex", 18 | "homepage": "https://developers.google.com/recaptcha/" 19 | } 20 | ], 21 | "support": { 22 | "issues": "https://github.com/AlexStack/Google-Recaptcha-to-any-form/issues" 23 | }, 24 | "minimum-stability": "dev", 25 | "require": { 26 | "php": ">=5.0" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "GoogleRecaptchaToAnyForm\\": "src/AlexStack/GoogleRecaptchaToAnyForm" 31 | } 32 | }, 33 | "extra": { 34 | "screenshots": [ 35 | "https://developers.google.com/recaptcha/images/newCaptchaAnchor.gif", 36 | "https://raw.githubusercontent.com/AlexStack/Google-Recaptcha-to-any-form/master/docs/images/google-recaptcha-v2-default.png", 37 | "https://raw.githubusercontent.com/AlexStack/Google-Recaptcha-to-any-form/master/docs/images/google-recaptcha-v3-default.png", 38 | "https://raw.githubusercontent.com/AlexStack/Google-Recaptcha-to-any-form/master/docs/images/google-recaptcha-v3-inline.png" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Google Recaptcha v2 or v3 to any form 2 | [![Latest Stable Version](https://poser.pugx.org/alexstack/google-recaptcha-to-any-form/v/stable)](https://packagist.org/packages/alexstack/google-recaptcha-to-any-form) 3 | [![License](https://poser.pugx.org/alexstack/google-recaptcha-to-any-form/license)](https://packagist.org/packages/alexstack/google-recaptcha-to-any-form) 4 | [![Total Downloads](https://poser.pugx.org/alexstack/google-recaptcha-to-any-form/downloads)](https://packagist.org/packages/alexstack/google-recaptcha-to-any-form) 5 | 6 | - It can display a Google Recaptcha v2 or v3 or invisible in any custom form with flexible settings and no affection to your existing code. Also works well for SilverStripe 4.x/3.x/2.x & Larave & Wordpress & other CMS. 7 | 8 | # Basic example codes 9 | 10 | - Display Google Recaptcha v2 or v3 after a Form_Field_ID: 11 | 12 | ```php 13 | // For Google recaptcha v2 14 | GoogleRecaptcha::show('SiteKey', 'Form_Field_ID'); 15 | 16 | // For Google recaptcha v3 17 | GoogleRecaptcha::showV3('SiteKey', 'Form_Field_ID'); 18 | ``` 19 | 20 | - Verify it in the backend php: 21 | 22 | ```php 23 | GoogleRecaptcha::verify('SecretKey'); 24 | ``` 25 | 26 | # How to install 27 | 28 | ```php 29 | composer require alexstack/google-recaptcha-to-any-form 30 | ``` 31 | 32 | # Contents 33 | 34 | - [x] [How to display it on frontend page](#frontend) - Support [Google recaptcha v3](#v3) / [v2](#frontend) / [Invisible](#invisible) 35 | - [x] [How to verify it in the backend script](#backend) 36 | - [x] [Usage example for SilverStripe 4.x/3.x](#silverstripe) 37 | - [x] [Usage example for Laravel](#laravel) 38 | - [x] [Usage example for Wordpress](#wordpress) 39 | 40 | # How to display it on frontend page? 41 | 42 | ![How to display it on frontend page](https://developers.google.com/recaptcha/images/newCaptchaAnchor.gif "Google Recaptcha") 43 | 44 | - Set up your Google Recaptcha v2 or v3 account for you website and get the site key and secret key 45 | - Import the GoogleRecaptcha class: 46 | 47 | ```php 48 | use GoogleRecaptchaToAnyForm\GoogleRecaptcha; 49 | ``` 50 | 51 | - Put below php code in your frontend template/page for **Google Recaptcha v2**. 52 | 53 | ```php 54 | GoogleRecaptcha::show($SiteKey, 'Form_ContactForm_Message', 'no_debug', 'mt-4 mb-1', 'Please tick the reCAPTCHA checkbox first!'); 55 | ``` 56 | ![google-recaptcha-v2-default](docs/images/google-recaptcha-v2-default.png "google-recaptcha-v2-default") 57 | 58 | ### Explain for above code: 59 | - '\$SiteKey': The Google Recaptcha Site Key of your website. You can directly put site key here or a variable or from database. 60 | - 'Form_ContactForm_Message': Form_Field_ID, via html code. eg. ... `` ... Your Google Recaptcha will display after this form field. 61 | - 'no_debug': Change to debug and not tick the I'm not a robot checkbox will continue submit the form, then you will see the failed message. 62 | - 'mt-4 mb-1': Extra css class name for the Google Recaptcha area. For recaptcha v2: Add theme-dark if you want the dark theme instead of the light. Add no-api-js if you already import the recaptcha/api.js. 63 | - 'Please tick the reCAPTCHA checkbox first': Frontend alert message if the end user does not tick the checkbox. **Tips:** You can change this value to "v3", it will automatically switch to use Google Recaptcha v3 64 | - Default value of the parameters of the show() method 65 | 66 | ```php 67 | show($site_key,$after_field_id='Form_ContactForm_Comment', $debug='no_debug', $extra_class="mt-4 mb-4", $please_tick_msg="Please tick the I'm not robot checkbox"); 68 | ``` 69 | 70 | ### How to use **Google Recaptcha Invisible** 71 | - You need get Google Recaptcha Invisible site key and secret key first. It's different from v2 72 | - Based on above explain, add a sting **invisible** to the Extra css class will do the job. eg. mt-4 invisible mb-1 73 | ```php 74 | GoogleRecaptcha::show($SiteKey, 'Form_Field_ID', 'no_debug','mb-2 invisible'); 75 | ``` 76 | 77 | ### Frontend example for **Google Recaptcha v3** 78 | ```php 79 | GoogleRecaptcha::show($SiteKey, 'Form_Field_ID', 'no_debug','show-inline-badge mt-4 mb-3','v3'); 80 | // or 81 | GoogleRecaptcha::showV3($SiteKey, 'Form_Field_ID', 'no_debug'); 82 | ``` 83 | ![google-recaptcha-v3-default](docs/images/google-recaptcha-v3-default.png "google-recaptcha-v3-default") 84 | 85 | - Our Google Recaptcha v3 will automatically get g-recaptcha-response value after the page load 10 seconds or the Form_Field_ID(eg. Form_ContactForm_Message) was clicked. 86 | - 'no_debug': Change to "debug" will always submit an empty g-recaptcha-response to the backend. 87 | - 'show-inline-badge mt-4 mb-3': Extra css class name for the Google Recaptcha inline-badge. Remove show-inline-badge will show a right bottom float Recaptcha badge instead inline-badge. 88 | 89 | ![google-recaptcha-v3-inline](docs/images/google-recaptcha-v3-inline.png "google-recaptcha-v3-inline") 90 | - You need set up Google Recaptcha v3 site key and secret key first. It's different from v2 91 | 92 | - If you do not want to use the show() method, You can also use your own code to display the recaptcha for a custom style. Just make sure the form action method is POST, then you can still use below verify() method in your backend script. 93 | 94 | 95 | # How to verify it in the backend script 96 | 97 | - Import the GoogleRecaptcha class: 98 | 99 | ```php 100 | use GoogleRecaptchaToAnyForm\GoogleRecaptcha; 101 | ``` 102 | 103 | - Put below php code into the form-submitted-method() of your backend php file. 104 | 105 | ```php 106 | GoogleRecaptcha::verify($GoogleRecaptchaSecretKey, 'Google Recaptcha Validation Failed!!'); 107 | ``` 108 | 109 | - Description for above code: 110 | - '\$GoogleRecaptchaSecretKey': The Google Recaptcha Secret Key of your website. You can directly put secret key here or a variable or from database. 111 | - 'Google Recaptcha Validation Failed': Javascript alert message if the verification failed. Set it null or false if you don't want a javascript alert. It will return true or false by the Google recaptcha verification result. Then you can show your own error message. 112 | - Default value of the parameters of the verify() method 113 | 114 | ```php 115 | verify($secret_key, $break_msg = null, $recaptcha_score=0.5) 116 | ``` 117 | 118 | - If you are using Google Recaptcha v3, it verify score < 0.5 as a failed result by default. You can set the score if you want a different value. eg. 119 | 120 | ```php 121 | GoogleRecaptcha::verify($SecretKey, 'Google Recaptcha Validation Failed!!', 0.36); 122 | ``` 123 | 124 | # Usage example for SilverStripe 4.x/3.x 125 | 126 | - Import the GoogleRecaptcha class: 127 | 128 | ```php 129 | use GoogleRecaptchaToAnyForm\GoogleRecaptcha; 130 | ``` 131 | 132 | - Create a function to display the recaptcha in your controller. eg.: 133 | 134 | ```php 135 | public function showGoogleRecaptcha() { 136 | return GoogleRecaptcha::show($SiteKey, 'Form_ContactForm_Message', 'no_debug', 'mt-4 mb-1', 'Please tick the reCAPTCHA checkbox first!'); 137 | } 138 | ``` 139 | 140 | - Display the recaptcha in the frontend.ss form, add below code to the end of a frontend.ss template. eg. : 141 | 142 | ```php 143 | $showGoogleRecaptcha.RAW 144 | ``` 145 | 146 | - Verify the recaptcha in the controller php file, add below code to the formAction function of your controller. eg.: 147 | 148 | ```php 149 | GoogleRecaptcha::verify($GoogleRecaptchaSecretKey, 'Google Recaptcha Validation Failed!!'); 150 | ``` 151 | 152 | # Usage example for Laravel 5.x custom login form 153 | 154 | - Include it in your LoginController.php file first: 155 | 156 | ```php 157 | use GoogleRecaptchaToAnyForm\GoogleRecaptcha; 158 | ``` 159 | 160 | - Create a function to display the recaptcha in your LoginController.php eg.: 161 | 162 | ```php 163 | public function showLoginForm() 164 | { 165 | $showRecaptcha = GoogleRecaptcha::show('site_key', 'password', 'no_debug', 'mt-4 mb-3 col-md-6 offset-md-4', 'Please tick the reCAPTCHA checkbox first!'); 166 | return view('auth.login', compact('showRecaptcha')); 167 | } 168 | ``` 169 | 170 | - Display the recaptcha in the auth/login.blade.php, add below code to the end of the auth/login.blade.php template. eg. : 171 | 172 | ```php 173 | {!! $showRecaptcha !!} 174 | ``` 175 | 176 | - Verify the recaptcha in the LoginController.php file, add below code for validateLogin. eg.: 177 | 178 | ```php 179 | protected function validateLogin(Request $request) 180 | { 181 | 182 | GoogleRecaptcha::verify('secret_key', 'Google Recaptcha Validation Failed!!'); 183 | 184 | $request->validate([ 185 | $this->username() => 'required|string', 186 | 'password' => 'required|string', 187 | ]); 188 | } 189 | ``` 190 | 191 | # Usage example for Wordpress custom form 192 | 193 | - Include it in your custom form template php file first. Note: Change the correct vendor path for require_once: 194 | 195 | ```php 196 | require_once(__DIR__ . '/../../../../vendor/autoload.php'); 197 | use GoogleRecaptchaToAnyForm\GoogleRecaptcha; 198 | ``` 199 | 200 | - Display the recaptcha in the form template. eg. : 201 | 202 | ```php 203 | echo GoogleRecaptcha::show('site_key', 'input_2_3', 'no_debug', 'mt-4 mb-3 col-md-6 offset-md-4', 'Please tick the reCAPTCHA checkbox first!'); 204 | ``` 205 | 206 | - Verify the recaptcha in the handle form submission method . eg.: 207 | 208 | ```php 209 | require_once(__DIR__ . '/../../vendor/autoload.php'); 210 | use GoogleRecaptchaToAnyForm\GoogleRecaptcha; 211 | 212 | GoogleRecaptcha::verify('secret_key', 'Google Recaptcha Validation Failed!!'); 213 | ``` 214 | 215 | # License 216 | 217 | - MIT 218 | -------------------------------------------------------------------------------- /src/AlexStack/GoogleRecaptchaToAnyForm/GoogleRecaptcha.php: -------------------------------------------------------------------------------- 1 | 20) { 24 | $valid = Self::result($secret_key, $_POST['g-recaptcha-response'], $recaptcha_score); 25 | } 26 | 27 | if (!$valid && $break_msg) { 28 | if (strlen($break_msg) < 10) { 29 | $break_msg = "Google Recaptcha Validation Failed!!"; 30 | } 31 | echo ''; 32 | exit(); 33 | } 34 | return $valid; 35 | } 36 | 37 | /** 38 | * result function 39 | * 40 | * @param [type] $secret_key 41 | * @param [type] $g_recaptcha_response 42 | * @return void 43 | */ 44 | public static function result($secret_key, $g_recaptcha_response, $recaptcha_score = 0.5) 45 | { 46 | $google_recaptcha_uri = 'https://www.google.com/recaptcha/api/siteverify'; 47 | 48 | if (!$g_recaptcha_response || strlen($g_recaptcha_response) < 10) { 49 | return false; 50 | } 51 | 52 | if (function_exists('curl_init')) { 53 | $curl = curl_init(); 54 | curl_setopt_array($curl, [ 55 | CURLOPT_RETURNTRANSFER => true, 56 | CURLOPT_POST => true, 57 | CURLOPT_SSL_VERIFYPEER => false, 58 | CURLOPT_URL => $google_recaptcha_uri, 59 | CURLOPT_POSTFIELDS => [ 60 | 'secret' => $secret_key, 61 | 'response' => $g_recaptcha_response, 62 | 'remoteip' => $_SERVER['REMOTE_ADDR'] 63 | ] 64 | ]); 65 | $rs = curl_exec($curl); 66 | curl_close($curl); 67 | } else { 68 | $rs = file_get_contents($google_recaptcha_uri . '?secret=' . $secret_key . '&response=' . $g_recaptcha_response . '&remoteip=' . $_SERVER['REMOTE_ADDR'] . '', true); 69 | } 70 | 71 | 72 | $response = json_decode($rs); 73 | 74 | //var_dump($response); exit();// un-comment for debug 75 | 76 | if (!$response || $response->success == false) { 77 | return false; 78 | } else if (isset($response->score) && $response->score < $recaptcha_score) { 79 | return false; 80 | } else { 81 | return true; 82 | } 83 | } 84 | 85 | /** 86 | * show recaptcha function without jQuery 87 | * 88 | * @param string $site_key 89 | * @param string $after_field_id 90 | * @param string $debug 91 | * @param string $extra_class 92 | * @param string $please_tick_msg 93 | * @return void 94 | */ 95 | public static function show($site_key, $after_field_id = 'Form_ContactForm_Comment', $debug = 'no_debug', $extra_class = "mt-4 mb-4", $please_tick_msg = "Please tick the I'm not robot checkbox") 96 | { 97 | if ($please_tick_msg == 'v3') { 98 | return Self::showV3($site_key, $after_field_id, $debug, $extra_class); 99 | } 100 | 101 | if (strpos($extra_class, 'invisible') !== false) { 102 | return Self::showInvisible($site_key, $after_field_id, $debug, $extra_class); 103 | } 104 | 105 | $api_js_str = ""; 106 | if (strpos($extra_class, 'no-api-js') !== false) { 107 | $api_js_str = ""; 108 | } 109 | $data_theme = 'light'; 110 | if (strpos($extra_class, 'theme-dark') !== false) { 111 | $data_theme = "dark"; 112 | } 113 | 114 | $debug_alert = ($debug == 'no_debug') ? 'false' : 'true'; 115 | $str = << 117 | 118 | $api_js_str 119 | 155 | 156 | EOF; 157 | return $str; 158 | } 159 | 160 | 161 | /** 162 | * show recaptcha v3 function without jQuery 163 | * 164 | * @param string $site_key 165 | * @param string $after_field_id 166 | * @param string $debug 167 | * @param string $extra_class 168 | * @param string $please_tick_msg 169 | * @return void 170 | */ 171 | public static function showV3($site_key, $after_field_id = 'Form_ContactForm_Comment', $debug = 'no_debug', $extra_class = "mt-4 mb-4") 172 | { 173 | $debug_mode = ($debug == 'no_debug') ? '' : 'return false; // debug mode is on '; 174 | 175 | if (strpos($extra_class, 'show-inline-badge') !== false) { 176 | $api_js = "https://www.google.com/recaptcha/api.js?render=explicit&onload=alexGetRecaptchaValue"; 177 | $recaptcha_client = "var recaptchaClient = grecaptcha.render('CustomContactUsForm-inline-badge', { 178 | 'sitekey': '$site_key', 179 | 'badge': 'inline', 180 | 'size': 'invisible' 181 | });"; 182 | } else { 183 | $api_js = "https://www.google.com/recaptcha/api.js?render=$site_key&onload=alexRecaptchaReadyCallback"; 184 | $recaptcha_client = "var recaptchaClient = '$site_key';"; 185 | } 186 | $str = << 188 | 189 | 190 | 191 | 192 | 231 | 232 | 233 | EOF; 234 | return $str; 235 | } 236 | 237 | 238 | 239 | /** 240 | * show recaptcha Invisible function without jQuery 241 | * 242 | * @param string $site_key 243 | * @param string $after_field_id 244 | * @param string $debug 245 | * @param string $extra_class 246 | * @param string $please_tick_msg 247 | * @return void 248 | */ 249 | public static function showInvisible($site_key, $after_field_id = 'Form_ContactForm_Comment', $debug = 'no_debug', $extra_class = "mt-4 mb-4") 250 | { 251 | $debug_mode = ($debug == 'no_debug') ? '' : 'return false; // debug mode is on '; 252 | 253 | $str = << 255 | 256 | 257 | 258 | 259 | 283 | 284 | 285 | EOF; 286 | return $str; 287 | } 288 | 289 | /** 290 | * jqueryShow function 291 | * 292 | * @param string $site_key 293 | * @param string $after_field_id 294 | * @param string $debug 295 | * @param string $extra_class 296 | * @param string $please_tick_msg 297 | * @return void 298 | */ 299 | public static function jqueryShow($site_key, $after_field_id = 'Form_ContactForm_Comment', $debug = 'no_debug', $extra_class = "mt-4 mb-4", $please_tick_msg = "Please tick the I'm not robot checkbox") 300 | { 301 | $debug_alert = ($debug == 'no_debug') ? 'false' : 'true'; 302 | $str = << 304 | 305 | 306 | 307 | 324 | 325 | EOF; 326 | return $str; 327 | } 328 | } 329 | --------------------------------------------------------------------------------