PluginProbe
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification / 5.5.0
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification v5.5.0
5.6.2 5.6.3 5.6.1 5.6.0 5.5.0 5.4.0 5.3.2 5.3.1 5.1.6 5.1.5 trunk 2.1.5 2.11 2.12 2.13 2.15 3.0.0 3.0.1 3.0.2 3.0.3 3.0.5 3.0.51 3.0.60 3.0.61 3.0.62 All 38 releases
← All changes | compatibility/OptInFrontend.class.php +18 -87 5.6.2 → 5.5.0 View file →
@@ -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 /**