| @@ -67,34 +67,8 @@ | ||
| 67 | 67 | */ |
| 68 | 68 | protected ?OptInError $lastCreationError = null; |
| 69 | 69 | |
| 70 | 70 | /** |
| 71 | - * Why the last maybeCreateOptIn() returned null, or null if it did not. | |
| 72 | - * | |
| 73 | - * Callers use it to answer in the form plugin's own words — Elementor | |
| 74 | - * adds the message to its AJAX response when the error must reach the | |
| 75 | - * visitor (OptInError::shouldShowToVisitor()). | |
| 76 | - * | |
| 77 | - * @return OptInError|null | |
| 78 | - */ | |
| 79 | - public function getLastCreationError(): ?OptInError { | |
| 80 | - return $this->lastCreationError; | |
| 81 | - } | |
| 82 | - | |
| 83 | - /** | |
| 84 | - * Remember the refusal and hand it to the frontend toast. | |
| 85 | - * | |
| 86 | - * @param OptInError $error The reason. | |
| 87 | - * @param int $formId The form. | |
| 88 | - * | |
| 89 | - * @return void | |
| 90 | - */ | |
| 91 | - protected function storeCreationError( OptInError $error, int $formId ): void { | |
| 92 | - $this->lastCreationError = $error; | |
| 93 | - ErrorNotification::store( $error, $formId ); | |
| 94 | - } | |
| 95 | - | |
| 96 | - /** | |
| 97 | 71 | * Get the validation status from the last validateOptIn() call. |
| 98 | 72 | * |
| 99 | 73 | * @return string One of: '', 'confirmed', 'already_confirmed', 'expired', 'not_found'. |
| 100 | 74 | */ |
| @@ -648,26 +622,8 @@ | ||
| 648 | 622 | return false; |
| 649 | 623 | } |
| 650 | 624 | |
| 651 | 625 | /** |
| 652 | - * Enable / Disable default mail. | |
| 653 | - * | |
| 654 | - * @param bool $status Enable (true) or disable (false) the default mail. | |
| 655 | - * @param int $postId The ID of the Post / Form. | |
| 656 | - * | |
| 657 | - * @since 2.3.3 | |
| 658 | - */ | |
| 659 | - $sendDefaultMail = (bool) apply_filters( 'f12_cf7_doubleoptin_send_default_mail', true, $OptIn->get_cf_form_id() ); | |
| 660 | - | |
| 661 | - /** | |
| 662 | - * Bind the follow-up plan before the confirmation is saved (see | |
| 663 | - * AbstractFormIntegration::validateOptIn). False when no adapter | |
| 664 | - * handles this integration → previous behaviour below. | |
| 665 | - */ | |
| 666 | - $coordinator = \Forge12\DoubleOptIn\FollowUp\FollowUpCoordinator::instance(); | |
| 667 | - $managed = $coordinator !== null && $coordinator->plan( $OptIn, $sendDefaultMail ); | |
| 668 | - | |
| 669 | - /** | |
| 670 | 626 | * Confirm the OptIn. |
| 671 | 627 | */ |
| 672 | 628 | if ( $this->updateOptInByHash( $hash, 1, $OptIn ) <= 0 ) { |
| 673 | 629 | $this->get_logger()->info( 'OptIn update failed', [ |
| @@ -679,23 +635,17 @@ | ||
| 679 | 635 | } |
| 680 | 636 | |
| 681 | 637 | $this->setValidationStatus( 'confirmed' ); |
| 682 | 638 | |
| 683 | - if ( $managed ) { | |
| 684 | - // Planned actions (skipped ones included) are recorded by the | |
| 685 | - // coordinator; trigger_default_mail is not fired for managed | |
| 686 | - // opt-ins, so no listener can replay them a second time. | |
| 687 | - if ( $sendDefaultMail ) { | |
| 688 | - do_action( 'f12_cf7_doubleoptin_before_send_default_mail', $OptIn ); | |
| 689 | - } | |
| 690 | - $coordinator->run( $OptIn, \Forge12\DoubleOptIn\FollowUp\FollowUpAttempt::TRIGGER_CONFIRM ); | |
| 691 | - if ( $sendDefaultMail ) { | |
| 692 | - do_action( 'f12_cf7_doubleoptin_after_send_default_mail', $OptIn ); | |
| 693 | - } | |
| 694 | - return true; | |
| 695 | - } | |
| 696 | - | |
| 697 | - if ( ! $sendDefaultMail ) { | |
| 639 | + /** | |
| 640 | + * Enable / Disable default mail. | |
| 641 | + * | |
| 642 | + * @param bool $status Enable (true) or disable (false) the default mail. | |
| 643 | + * @param int $postId The ID of the Post / Form. | |
| 644 | + * | |
| 645 | + * @since 2.3.3 | |
| 646 | + */ | |
| 647 | + if ( ! apply_filters( 'f12_cf7_doubleoptin_send_default_mail', true, $OptIn->get_cf_form_id() ) ) { | |
| 698 | 648 | $this->get_logger()->info( 'Default mail disabled for OptIn', [ |
| 699 | 649 | 'plugin' => 'double-opt-in', |
| 700 | 650 | 'form_id' => $OptIn->get_cf_form_id(), |
| 701 | 651 | 'optin_id' => $OptIn->get_id(), |
| @@ -838,10 +788,8 @@ | ||
| 838 | 788 | * |
| 839 | 789 | * @return OptIn|null |
| 840 | 790 | */ |
| 841 | 791 | protected function maybeCreateOptIn( int $formId, string $formHtml, array $parameter, array $files = array(), array $knownFields = array() ): ?OptIn { |
| 842 | - $this->lastCreationError = null; | |
| 843 | - | |
| 844 | 792 | $this->get_logger()->debug( 'maybeCreateOptIn called', [ |
| 845 | 793 | 'plugin' => 'double-opt-in', |
| 846 | 794 | 'class' => __CLASS__, |
| 847 | 795 | 'method' => __METHOD__, |
| @@ -884,9 +832,9 @@ | ||
| 884 | 832 | if ( empty( $recipient ) ) { |
| 885 | 833 | $this->get_logger()->warning( 'No recipient found, skipping OptIn creation', [ |
| 886 | 834 | 'plugin' => 'double-opt-in', |
| 887 | 835 | ] ); |
| 888 | - $this->storeCreationError( | |
| 836 | + ErrorNotification::store( | |
| 889 | 837 | OptInError::fromCode( OptInError::NO_RECIPIENT, [ 'form_id' => $formId ] ), |
| 890 | 838 | $formId |
| 891 | 839 | ); |
| 892 | 840 | return null; |
| @@ -933,9 +881,9 @@ | ||
| 933 | 881 | 'integration' => $this->type, |
| 934 | 882 | 'consent_field' => $consentField, |
| 935 | 883 | ] ); |
| 936 | 884 | do_action( 'f12_cf7_doubleoptin_consent_not_given', $formId, $consentField ); |
| 937 | - $this->storeCreationError( | |
| 885 | + ErrorNotification::store( | |
| 938 | 886 | OptInError::fromCode( |
| 939 | 887 | OptInError::CONSENT_NOT_GIVEN, |
| 940 | 888 | [ 'form_id' => $formId, 'consent_field' => $consentField ] |
| 941 | 889 | ), |
| @@ -970,9 +918,9 @@ | ||
| 970 | 918 | 'ip' => $ip, |
| 971 | 919 | 'formId' => $formId, |
| 972 | 920 | ] ); |
| 973 | 921 | do_action( 'f12_cf7_doubleoptin_rate_limited', 'ip', $ip, $formId ); |
| 974 | - $this->storeCreationError( | |
| 922 | + ErrorNotification::store( | |
| 975 | 923 | OptInError::fromCode( OptInError::RATE_LIMIT_IP, [ 'ip' => $ip, 'form_id' => $formId ] ), |
| 976 | 924 | $formId |
| 977 | 925 | ); |
| 978 | 926 | return null; |
| @@ -984,9 +932,9 @@ | ||
| 984 | 932 | 'email' => $recipient, |
| 985 | 933 | 'formId' => $formId, |
| 986 | 934 | ] ); |
| 987 | 935 | do_action( 'f12_cf7_doubleoptin_rate_limited', 'email', $recipient, $formId ); |
| 988 | - $this->storeCreationError( | |
| 936 | + ErrorNotification::store( | |
| 989 | 937 | OptInError::fromCode( OptInError::RATE_LIMIT_EMAIL, [ 'email' => $recipient, 'form_id' => $formId ] ), |
| 990 | 938 | $formId |
| 991 | 939 | ); |
| 992 | 940 | return null; |
| @@ -1045,9 +993,9 @@ | ||
| 1045 | 993 | ! empty( $errorMsg ) ? $errorMsg : OptInError::fromCode( OptInError::RECIPIENT_INVALID )->getMessage(), |
| 1046 | 994 | [ 'email' => $recipient, 'form_id' => $formId ] |
| 1047 | 995 | ); |
| 1048 | 996 | |
| 1049 | - $this->storeCreationError( $this->lastCreationError, $formId ); | |
| 997 | + ErrorNotification::store( $this->lastCreationError, $formId ); | |
| 1050 | 998 | return null; |
| 1051 | 999 | } |
| 1052 | 1000 | |
| 1053 | 1001 | /** |
| @@ -1112,9 +1060,9 @@ | ||
| 1112 | 1060 | ] ); |
| 1113 | 1061 | |
| 1114 | 1062 | do_action( 'f12_cf7_doubleoptin_creation_failed', $formId, $recipient ); |
| 1115 | 1063 | |
| 1116 | - $this->storeCreationError( | |
| 1064 | + ErrorNotification::store( | |
| 1117 | 1065 | OptInError::fromCode( OptInError::SAVE_FAILED, [ 'form_id' => $formId ] ), |
| 1118 | 1066 | $formId |
| 1119 | 1067 | ); |
| 1120 | 1068 | |
| @@ -1125,13 +1073,11 @@ | ||
| 1125 | 1073 | /** |
| 1126 | 1074 | * Validate if the optin is enabled. |
| 1127 | 1075 | */ |
| 1128 | 1076 | protected function isOptinEnabled( int $formId ): bool { |
| 1129 | - // Disable optin sending while our own post-confirmation replay runs. | |
| 1130 | - // Not `isset( $_GET['optin'] )`: that is client input and let a | |
| 1131 | - // submitter switch the double opt-in off. | |
| 1132 | - if ( \Forge12\DoubleOptIn\Integration\AbstractFormIntegration::isReplaying() ) { | |
| 1133 | - $this->get_logger()->debug( 'Optin disabled during post-confirmation replay', [ | |
| 1077 | + // Disable optin sending if the optin flag is set. | |
| 1078 | + if ( isset( $_GET['optin'] ) ) { | |
| 1079 | + $this->get_logger()->debug( 'Optin disabled due to optin flag in GET request', [ | |
| 1134 | 1080 | 'plugin' => 'double-opt-in', |
| 1135 | 1081 | 'class' => __CLASS__, |
| 1136 | 1082 | 'method' => __METHOD__, |
| 1137 | 1083 | ] ); |
| @@ -1240,23 +1186,8 @@ | ||
| 1240 | 1186 | 'class' => __CLASS__, |
| 1241 | 1187 | 'method' => __METHOD__, |
| 1242 | 1188 | 'hash' => $hash, |
| 1243 | 1189 | ] ); |
| 1244 | - return; | |
| 1245 | - } | |
| 1246 | - | |
| 1247 | - /** | |
| 1248 | - * Only for this integration's own opt-in, only right after it was | |
| 1249 | - * confirmed in this request, and only when no follow-up adapter | |
| 1250 | - * owns the files. Previously any `?optin=` request — an expired | |
| 1251 | - * link, a second click, another integration's hash — deleted the | |
| 1252 | - * stored files, including ones a pending action still needed. | |
| 1253 | - */ | |
| 1254 | - if ( ! $OptIn->isType( $this->type ) || self::$validationStatus !== 'confirmed' ) { | |
| 1255 | - return; | |
| 1256 | - } | |
| 1257 | - $coordinator = \Forge12\DoubleOptIn\FollowUp\FollowUpCoordinator::instance(); | |
| 1258 | - if ( $coordinator !== null && $coordinator->adapterFor( $OptIn ) !== null ) { | |
| 1259 | 1190 | return; |
| 1260 | 1191 | } |
| 1261 | 1192 | |
| 1262 | 1193 | /** |