PluginProbe
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification / 5.6.3
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification v5.6.3
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
double-opt-in / src / Integration / OptInError.php

OptInError.php in Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification 5.6.3, at src/Integration/OptInError.php

200 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OptIn Error Value Object
4 *
5 * @package Forge12\DoubleOptIn\Integration
6 * @since 4.2.0
7 */
8
9 namespace Forge12\DoubleOptIn\Integration;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class OptInError
17 *
18 * Immutable value object representing an error that occurred during OptIn creation.
19 * Provides typed error codes and translatable default messages for each error scenario.
20 */
21 class OptInError {
22
23 /**
24 * Error code: Form submission was cancelled by a listener (FormSubmissionEvent).
25 */
26 public const SUBMISSION_CANCELLED = 'submission_cancelled';
27
28 /**
29 * Error code: No valid recipient email address found in the form data.
30 */
31 public const NO_RECIPIENT = 'no_recipient';
32
33 /**
34 * Error code: Rate limit exceeded for the submitting IP address.
35 */
36 public const RATE_LIMIT_IP = 'rate_limit_ip';
37
38 /**
39 * Error code: Rate limit exceeded for the recipient email address.
40 */
41 public const RATE_LIMIT_EMAIL = 'rate_limit_email';
42
43 /**
44 * Error code: Recipient email validation failed (e.g. MX check).
45 */
46 public const RECIPIENT_INVALID = 'recipient_invalid';
47
48 /**
49 * Error code: Duplicate email rejected by Unique Email validator.
50 */
51 public const UNIQUE_EMAIL_DUPLICATE = 'unique_email_duplicate';
52
53 /**
54 * Error code: Failed to save the OptIn record to the database.
55 */
56 public const SAVE_FAILED = 'save_failed';
57
58 /**
59 * Error code: Consent acceptance gate failed — the form has a
60 * configured consent_field, but the user did not check it. We
61 * reject the opt-in instead of fabricating GDPR Art. 7 evidence.
62 */
63 public const CONSENT_NOT_GIVEN = 'consent_not_given';
64
65 /**
66 * The error code.
67 *
68 * @var string
69 */
70 private string $code;
71
72 /**
73 * The human-readable error message.
74 *
75 * @var string
76 */
77 private string $message;
78
79 /**
80 * Additional context data.
81 *
82 * @var array
83 */
84 private array $context;
85
86 /**
87 * Constructor.
88 *
89 * @param string $code The error code.
90 * @param string $message The error message.
91 * @param array $context Additional context data.
92 */
93 public function __construct( string $code, string $message, array $context = array() ) {
94 $this->code = $code;
95 $this->message = $message;
96 $this->context = $context;
97 }
98
99 /**
100 * Create an OptInError from an error code with a default message.
101 *
102 * @param string $code The error code.
103 * @param array $context Additional context data.
104 *
105 * @return self
106 */
107 public static function fromCode( string $code, array $context = array() ): self {
108 $messages = self::getDefaultMessages();
109 $message = $messages[ $code ] ?? __( 'An unknown error occurred.', 'double-opt-in' );
110
111 return new self( $code, $message, $context );
112 }
113
114 /**
115 * Get the error code.
116 *
117 * @return string
118 */
119 public function getCode(): string {
120 return $this->code;
121 }
122
123 /**
124 * Get the human-readable error message.
125 *
126 * @return string
127 */
128 public function getMessage(): string {
129 return $this->message;
130 }
131
132 /**
133 * Get additional context data.
134 *
135 * @return array
136 */
137 public function getContext(): array {
138 return $this->context;
139 }
140
141 /**
142 * Must the visitor see this error, whatever the site configured?
143 *
144 * Only for errors the visitor caused and can fix on the spot. A refused
145 * consent is one: the form looked sent, no mail ever came, and the only
146 * hint was a toast over a green "Thank you" that vanished after ten
147 * seconds (CF7, Core 5.6.1). Rate limits, blocklists and the like stay
148 * behind `f12_cf7_doubleoptin_show_validation_error` — telling a bot why
149 * it was refused is not always wanted.
150 *
151 * @return bool
152 */
153 public function isAlwaysShown(): bool {
154 return self::CONSENT_NOT_GIVEN === $this->code;
155 }
156
157 /**
158 * Should the form show this error in place of its own success message?
159 *
160 * @param int $formId The form the submission came from.
161 *
162 * @return bool
163 */
164 public function shouldShowToVisitor( int $formId ): bool {
165 if ( $this->isAlwaysShown() ) {
166 return true;
167 }
168
169 /**
170 * Whether a refused submission's reason is shown in the form.
171 *
172 * Default false. A refused consent is always shown and never
173 * reaches this filter.
174 *
175 * @param bool $show Show the error.
176 * @param OptInError $error The error (since 5.6.2).
177 * @param int $formId The form (since 5.6.2).
178 */
179 return (bool) apply_filters( 'f12_cf7_doubleoptin_show_validation_error', false, $this, $formId );
180 }
181
182 /**
183 * Get the default translatable messages for all error codes.
184 *
185 * @return array<string, string>
186 */
187 private static function getDefaultMessages(): array {
188 return array(
189 self::SUBMISSION_CANCELLED => __( 'The form submission has been cancelled.', 'double-opt-in' ),
190 self::NO_RECIPIENT => __( 'No valid email address was found.', 'double-opt-in' ),
191 self::RATE_LIMIT_IP => __( 'Too many requests. Please try again later.', 'double-opt-in' ),
192 self::RATE_LIMIT_EMAIL => __( 'Too many requests for this email address. Please try again later.', 'double-opt-in' ),
193 self::RECIPIENT_INVALID => __( 'The email address could not be verified.', 'double-opt-in' ),
194 self::UNIQUE_EMAIL_DUPLICATE => __( 'This email address has already been used.', 'double-opt-in' ),
195 self::SAVE_FAILED => __( 'An error occurred. Please try again.', 'double-opt-in' ),
196 self::CONSENT_NOT_GIVEN => __( 'You must agree to the consent statement to continue.', 'double-opt-in' ),
197 );
198 }
199 }
200