1414
1515use FluentForm \App \Models \Form as FluentForm ;
1616use FluentForm \App \Modules \Form \FormFieldsParser ;
17+ use FluentForm \Framework \Helpers \ArrayHelper ;
18+ use HCaptcha \Abstracts \LoginBase ;
1719use HCaptcha \Helpers \HCaptcha ;
1820use HCaptcha \Main ;
1921use stdClass ;
2022
2123/**
2224 * Class Form
25+ *
26+ * Can be used as a login form also.
2327 */
24- class Form {
28+ class Form extends LoginBase {
2529
2630 /**
2731 * Nonce action.
2832 */
29- private const ACTION = 'hcaptcha_fluentform ' ;
33+ protected const ACTION = 'hcaptcha_fluentform ' ;
3034
3135 /**
3236 * Nonce name.
3337 */
34- private const NONCE = 'hcaptcha_fluentform_nonce ' ;
38+ protected const NONCE = 'hcaptcha_fluentform_nonce ' ;
3539
3640 /**
3741 * Script handle.
@@ -55,19 +59,12 @@ class Form {
5559 */
5660 protected $ form_id = 0 ;
5761
58- /**
59- * Constructor.
60- */
61- public function __construct () {
62- $ this ->init_hooks ();
63- }
64-
6562 /**
6663 * Init hooks.
6764 *
6865 * @return void
6966 */
70- private function init_hooks (): void {
67+ protected function init_hooks (): void {
7168 add_filter ( 'fluentform/rendering_field_html_hcaptcha ' , [ $ this , 'render_field_hcaptcha ' ], 10 , 3 );
7269 add_action ( 'fluentform/render_item_submit_button ' , [ $ this , 'add_hcaptcha ' ], 9 , 2 );
7370 add_action ( 'fluentform/validation_errors ' , [ $ this , 'verify ' ], 10 , 4 );
@@ -130,6 +127,30 @@ public function add_hcaptcha( array $submit_button, stdClass $form ): void {
130127 * @noinspection PhpUnusedParameterInspection
131128 */
132129 public function verify ( array $ errors , array $ data , FluentForm $ form , array $ fields ): array {
130+ if ( $ this ->is_login_form ( $ form ) ) {
131+ $ email = (string ) ArrayHelper::get ( $ data , 'email ' );
132+ $ password = (string ) ArrayHelper::get ( $ data , 'password ' );
133+ $ user = get_user_by ( 'email ' , $ email );
134+
135+ if ( $ user && wp_check_password ( $ password , $ user ->user_pass , $ user ->ID ) ) {
136+ $ this ->login ( $ email , $ user );
137+ } else {
138+ $ this ->login_failed ( $ email );
139+ }
140+
141+ if ( ! $ this ->is_login_limit_exceeded () ) {
142+ return $ errors ;
143+ }
144+
145+ wp_send_json (
146+ __ ( 'Login failed. Please reload the page. ' , 'hcaptcha-for-forms-and-more ' ),
147+ 423
148+ );
149+
150+ // For testing purposes.
151+ return $ errors ;
152+ }
153+
133154 remove_filter ( 'pre_http_request ' , [ $ this , 'pre_http_request ' ] );
134155
135156 $ hcaptcha_response = $ data ['h-captcha-response ' ] ?? '' ;
@@ -201,7 +222,7 @@ public function enqueue_scripts(): void {
201222 wp_dequeue_script ( $ fluent_forms_conversational_script );
202223 wp_deregister_script ( $ fluent_forms_conversational_script );
203224
204- $ form = $ this ->get_captcha ();
225+ $ form = $ this ->get_hcaptcha ();
205226 $ form = str_replace (
206227 [
207228 'class="h-captcha" ' ,
@@ -306,6 +327,7 @@ public function fluentform_rendering_form_filter( $form ) {
306327 */
307328 public function fluentform_has_hcaptcha (): bool {
308329 add_filter ( 'pre_http_request ' , [ $ this , 'pre_http_request ' ], 10 , 3 );
330+
309331 return false ;
310332 }
311333
@@ -381,8 +403,15 @@ protected function has_own_hcaptcha( $form ): bool {
381403 * Get hCaptcha.
382404 *
383405 * @return string
406+ * @noinspection PhpUndefinedMethodInspection
384407 */
385- private function get_captcha (): string {
408+ protected function get_hcaptcha (): string {
409+ $ form = FluentForm::find ( $ this ->form_id );
410+
411+ if ( $ this ->is_login_form ( $ form ) && ! $ this ->is_login_limit_exceeded () ) {
412+ return '' ;
413+ }
414+
386415 $ args = [
387416 'action ' => self ::ACTION ,
388417 'name ' => self ::NONCE ,
@@ -395,6 +424,37 @@ private function get_captcha(): string {
395424 return HCaptcha::form ( $ args );
396425 }
397426
427+ /**
428+ * Whether the form is a login form.
429+ *
430+ * @param FluentForm $form Form.
431+ *
432+ * @return bool
433+ */
434+ private function is_login_form ( FluentForm $ form ): bool {
435+
436+ return (
437+ has_action ( 'fluentform/before_insert_submission ' ) &&
438+ $ this ->has_element ( $ form , 'input_email ' ) &&
439+ $ this ->has_element ( $ form , 'input_password ' )
440+ );
441+ }
442+
443+ /**
444+ * Whether the form has an element.
445+ *
446+ * @param FluentForm $form Form.
447+ * @param string $element_name Element name.
448+ *
449+ * @return bool
450+ * @noinspection PhpUndefinedFieldInspection
451+ */
452+ private function has_element ( FluentForm $ form , string $ element_name ): bool {
453+ $ fields_json = $ form ->form_fields ;
454+
455+ return false !== strpos ( $ fields_json , '"element":" ' . $ element_name . '" ' );
456+ }
457+
398458 /**
399459 * Get hCaptcha wrapped as Fluent Forms field.
400460 *
@@ -403,13 +463,14 @@ private function get_captcha(): string {
403463 private function get_hcaptcha_wrapped (): string {
404464 ob_start ();
405465
466+ /* language=HTML */
406467 ?>
407468 <div class="ff-el-group">
408469 <div class="ff-el-input--content">
409470 <div data-fluent_id="1" name="h-captcha-response">
410471 <?php
411472 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
412- echo $ this ->get_captcha ();
473+ echo $ this ->get_hcaptcha ();
413474 ?>
414475 </div>
415476 </div>
0 commit comments