@@ -48,40 +48,98 @@ class ReCaptchaBuilder {
4848
4949 public function __construct ($ api_site_key , $ api_secret_key , $ version = 'v2 ' ) {
5050
51+ $ this ->setApiSiteKey ($ api_site_key );
52+ $ this ->setApiSecretKey ($ api_secret_key );
53+ $ this ->setVersion ($ version );
54+ $ this ->setSkipByIp ($ this ->skipByIp ());
55+ }
56+
57+ /**
58+ * @param string $api_site_key
59+ *
60+ * @return ReCaptchaBuilder
61+ */
62+ public function setApiSiteKey (string $ api_site_key ): ReCaptchaBuilder {
5163 $ this ->api_site_key = $ api_site_key ;
64+
65+ return $ this ;
66+ }
67+
68+ /**
69+ * @param string $api_secret_key
70+ *
71+ * @return ReCaptchaBuilder
72+ */
73+ public function setApiSecretKey (string $ api_secret_key ): ReCaptchaBuilder {
5274 $ this ->api_secret_key = $ api_secret_key ;
75+
76+ return $ this ;
77+ }
78+
79+ /**
80+ * @param string $version
81+ *
82+ * @return ReCaptchaBuilder
83+ */
84+ public function setVersion (string $ version ): ReCaptchaBuilder {
5385 $ this ->version = $ version ;
54- $ this ->skip_by_ip = self ::skipByIp ();
86+
87+ return $ this ;
88+ }
89+
90+ /**
91+ * @return string
92+ */
93+ public function getVersion (): string {
94+ return $ this ->version ;
95+ }
96+
97+ /**
98+ * @param bool $skip_by_ip
99+ *
100+ * @return ReCaptchaBuilder
101+ */
102+ public function setSkipByIp (bool $ skip_by_ip ): ReCaptchaBuilder {
103+ $ this ->skip_by_ip = $ skip_by_ip ;
104+
105+ return $ this ;
55106 }
56107
57108 /**
58109 * Checks whether the user IP address is among IPs "to be skipped"
59110 *
60111 * @return boolean
61112 */
62- public static function skipByIp () {
63-
64- $ skip_ip = (config ('recaptcha.skip_ip ' )) ? config ('recaptcha.skip_ip ' ) : [];
113+ public function skipByIp (): bool {
65114
66- return (in_array (request ()->ip (), $ skip_ip ));
115+ return (in_array (request ()->ip (), config ( ' recaptcha. skip_ip' , []) ));
67116 }
68117
69118 /**
70119 * Write script HTML tag in you HTML code
71120 * Insert before </head> tag
72121 *
73- * @param string $formId
122+ * @param string|null $formId
123+ * @param array|null $configuration
74124 *
75125 * @return string
76126 * @throws Exception
77127 */
78- public function htmlScriptTagJsApi ($ formId = '' ) {
128+ public function htmlScriptTagJsApi (? string $ formId = '' , ? array $ configuration = []): string {
79129
80130 if ($ this ->skip_by_ip ) {
81131 return '' ;
82132 }
83- $ html = "<script src='https://www.google.com/recaptcha/api.js' async defer></script> " ;
84- if ($ this ->version != 'v2 ' ) {
133+
134+ switch ($ this ->version ) {
135+ case 'v3 ' :
136+ $ html = "<script src= \"https://www.google.com/recaptcha/api.js?render= {$ this ->api_site_key }\"></script> " ;
137+ break ;
138+ default :
139+ $ html = "<script src= \"https://www.google.com/recaptcha/api.js \" async defer></script> " ;
140+ }
141+
142+ if ($ this ->version == 'invisible ' ) {
85143 if (!$ formId ) {
86144 throw new Exception ("formId required " , 1 );
87145 }
@@ -91,10 +149,62 @@ function biscolabLaravelReCaptcha(token) {
91149 }
92150 </script> ' ;
93151 }
152+ elseif ($ this ->version == 'v3 ' ) {
153+
154+ $ action = array_get ($ configuration , 'action ' , 'homepage ' );
155+
156+ $ js_custom_validation = array_get ($ configuration , 'custom_validation ' , '' );
157+
158+ // Check if set custom_validation. That function will override default fetch validation function
159+ if ($ js_custom_validation ) {
160+
161+ $ validate_function = ($ js_custom_validation ) ? "{$ js_custom_validation }(token); " : '' ;
162+ }
163+ else {
164+
165+ $ js_then_callback = array_get ($ configuration , 'callback_then ' , '' );
166+ $ js_callback_catch = array_get ($ configuration , 'callback_catch ' , '' );
167+
168+ $ js_then_callback = ($ js_then_callback ) ? "{$ js_then_callback }(response) " : '' ;
169+ $ js_callback_catch = ($ js_callback_catch ) ? "{$ js_callback_catch }(err) " : '' ;
170+
171+ $ validate_function = "
172+ fetch('/ " . config ('recaptcha.default_validation_route ' , 'biscolab-recaptcha/validate ' ) . "? " . config ('recaptcha.default_token_parameter_name ' , 'token ' ) . "=' + token, {
173+ headers: {
174+ \"X-Requested-With \": \"XMLHttpRequest \",
175+ \"X-CSRF-TOKEN \": csrfToken.content
176+ }
177+ })
178+ .then(function(response) {
179+ {$ js_then_callback }
180+ })
181+ .catch(function(err) {
182+ {$ js_callback_catch }
183+ }); " ;
184+ }
185+
186+ $ html .= "<script>
187+ var csrfToken = document.head.querySelector('meta[name= \"csrf-token \"]');
188+ grecaptcha.ready(function() {
189+ grecaptcha.execute(' {$ this ->api_site_key }', {action: ' {$ action }'}).then(function(token) {
190+ {$ validate_function }
191+ });
192+ });
193+ </script> " ;
194+ }
94195
95196 return $ html ;
96197 }
97198
199+ /**
200+ * @param array|null $configuration
201+ *
202+ * @return string
203+ */
204+ public function htmlScriptTagJsApiV3 (?array $ configuration = []): string {
205+ return $ this ->htmlScriptTagJsApi ('' , $ configuration );
206+ }
207+
98208 /**
99209 * Call out to reCAPTCHA and process the response
100210 *
@@ -131,6 +241,10 @@ public function validate($response) {
131241 }
132242 $ response = json_decode (trim ($ curl_response ), true );
133243
244+ if ($ this ->version == 'v3 ' ) {
245+ return $ response ;
246+ }
247+
134248 return $ response ['success ' ];
135249
136250 }
0 commit comments