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.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 3.0.70 3.0.71 3.0.72 3.1.0 All 34 releases
double-opt-in / src / Admin / ResendController.php

ResendController.php in Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification 5.5.0, at src/Admin/ResendController.php

235 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Resend Confirmation Mail Controller
4 *
5 * @package Forge12\DoubleOptIn\Admin
6 * @since 3.2.0
7 */
8
9 namespace Forge12\DoubleOptIn\Admin;
10
11 use Forge12\DoubleOptIn\Container\Container;
12 use Forge12\DoubleOptIn\Repository\OptInRepositoryInterface;
13 use Forge12\Shared\LoggerInterface;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Class ResendController
21 *
22 * Handles resending confirmation emails for unconfirmed opt-ins.
23 */
24 class ResendController {
25
26 private LoggerInterface $logger;
27
28 public function __construct( LoggerInterface $logger ) {
29 $this->logger = $logger;
30
31 add_action( 'wp_ajax_doi_resend_optin_mail', array( $this, 'handleResend' ) );
32 add_action( 'f12_cf7_doubleoptin_ui_view_optin_options', array( $this, 'renderResendButton' ) );
33 }
34
35 /**
36 * Render the resend button on the view-optin page.
37 *
38 * @param \forge12\contactform7\CF7DoubleOptIn\OptIn $optin The OptIn facade instance.
39 *
40 * @return void
41 */
42 public function renderResendButton( $optin ): void {
43 $is_pro = apply_filters( 'f12_doi_is_pro_active', false );
44 $is_confirmed = $optin->is_confirmed();
45 $has_mail = ! empty( $optin->get_mail_optin() );
46 $disabled = ! $is_pro || $is_confirmed || ! $has_mail;
47
48 $nonce = wp_create_nonce( 'doi_resend_mail' );
49 $id = $optin->get_id();
50
51 // Build tooltip explaining why the button is disabled
52 $title = '';
53 if ( ! $is_pro ) {
54 $title = __( 'This feature is available in the Pro version.', 'double-opt-in' );
55 } elseif ( $is_confirmed ) {
56 $title = __( 'This Opt-In has already been confirmed.', 'double-opt-in' );
57 } elseif ( ! $has_mail ) {
58 $title = __( 'No mail body stored for this Opt-In.', 'double-opt-in' );
59 }
60 ?>
61 <button type="button"
62 class="button"
63 id="doi-resend-btn"
64 data-id="<?php echo esc_attr( $id ); ?>"
65 data-nonce="<?php echo esc_attr( $nonce ); ?>"
66 <?php echo $disabled ? 'disabled' : ''; ?>
67 <?php echo ! empty( $title ) ? 'title="' . esc_attr( $title ) . '"' : ''; ?>
68 style="<?php echo $disabled ? 'opacity:.6;cursor:not-allowed;' : ''; ?>">
69 <?php
70 _e( 'Resend Confirmation Mail', 'double-opt-in' );
71 ?>
72 </button>
73 <?php
74 if ( ! $is_pro ) :
75 ?>
76 <span style="display:inline-block;background:linear-gradient(135deg,#e6a817,#d4941a);color:#fff;font-size:10px;font-weight:700;line-height:1;padding:3px 6px;border-radius:3px;letter-spacing:.5px;text-transform:uppercase;"
77 title="<?php esc_attr_e( 'This feature is available in the Pro version.', 'double-opt-in' ); ?>">PRO</span>
78 <?php endif; ?>
79 <span class="doi-tooltip">
80 <span class="dashicons dashicons-info-outline"></span>
81 <span class="doi-tooltip-text">
82 <?php
83 esc_html_e( 'Re-sends the original confirmation email with the opt-in link to the recipient.', 'double-opt-in' );
84 ?>
85 </span>
86 </span>
87 <span id="doi-resend-feedback" style="font-size:13px;"></span>
88 <?php if ( $is_pro && ! $disabled ) : ?>
89 <script>
90 (function() {
91 var btn = document.getElementById('doi-resend-btn');
92 var feedback = document.getElementById('doi-resend-feedback');
93 if (!btn || btn.disabled) return;
94
95 btn.addEventListener('click', function() {
96 btn.disabled = true;
97 btn.style.opacity = '.6';
98 feedback.textContent = '';
99
100 var formData = new FormData();
101 formData.append('action', 'doi_resend_optin_mail');
102 formData.append('_wpnonce', btn.dataset.nonce);
103 formData.append('optin_id', btn.dataset.id);
104
105 fetch(ajaxurl, {
106 method: 'POST',
107 body: formData,
108 credentials: 'same-origin'
109 })
110 .then(function(response) { return response.json(); })
111 .then(function(data) {
112 if (data.success) {
113 feedback.style.color = '#00a32a';
114 feedback.textContent = data.data.message || 'Mail sent';
115 } else {
116 feedback.style.color = '#d63638';
117 feedback.textContent = data.data.message || 'Error';
118 btn.disabled = false;
119 btn.style.opacity = '';
120 }
121 })
122 .catch(function() {
123 feedback.style.color = '#d63638';
124 feedback.textContent = 'Request failed';
125 btn.disabled = false;
126 btn.style.opacity = '';
127 });
128 });
129 })();
130 </script>
131 <?php endif; ?>
132 <?php
133 }
134
135 /**
136 * Handle the AJAX request to resend a confirmation mail.
137 *
138 * @return void
139 */
140 public function handleResend(): void {
141 if ( ! apply_filters( 'f12_doi_is_pro_active', false ) ) {
142 wp_send_json_error( array( 'message' => __( 'This feature requires the Pro version.', 'double-opt-in' ) ), 403 );
143 }
144
145 if ( ! current_user_can( 'manage_options' ) ) {
146 wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'double-opt-in' ) ), 403 );
147 }
148
149 if ( ! check_ajax_referer( 'doi_resend_mail', '_wpnonce', false ) ) {
150 wp_send_json_error( array( 'message' => __( 'Security check failed.', 'double-opt-in' ) ), 403 );
151 }
152
153 $optinId = isset( $_POST['optin_id'] ) ? (int) $_POST['optin_id'] : 0;
154
155 if ( $optinId <= 0 ) {
156 wp_send_json_error( array( 'message' => __( 'Invalid Opt-In ID.', 'double-opt-in' ) ) );
157 }
158
159 try {
160 $container = Container::getInstance();
161 $repository = $container->get( OptInRepositoryInterface::class );
162 $entity = $repository->findById( $optinId );
163 } catch ( \Exception $e ) {
164 $this->logger->error(
165 'Failed to load OptIn for resend',
166 array(
167 'plugin' => 'double-opt-in',
168 'id' => $optinId,
169 'error' => $e->getMessage(),
170 )
171 );
172 wp_send_json_error( array( 'message' => __( 'Failed to load Opt-In.', 'double-opt-in' ) ) );
173 }
174
175 if ( ! $entity ) {
176 wp_send_json_error( array( 'message' => __( 'Opt-In not found.', 'double-opt-in' ) ) );
177 }
178
179 if ( $entity->isConfirmed() ) {
180 wp_send_json_error( array( 'message' => __( 'This Opt-In is already confirmed.', 'double-opt-in' ) ) );
181 }
182
183 $body = $entity->getMailOptIn();
184 if ( empty( $body ) ) {
185 wp_send_json_error( array( 'message' => __( 'No mail body stored for this Opt-In.', 'double-opt-in' ) ) );
186 }
187
188 $email = $entity->getEmail();
189 if ( empty( $email ) ) {
190 wp_send_json_error( array( 'message' => __( 'No recipient email found.', 'double-opt-in' ) ) );
191 }
192
193 // Load subject from form settings with fallback
194 $formId = $entity->getFormId();
195 $formParameter = \forge12\contactform7\CF7DoubleOptIn\CF7DoubleOptIn::getInstance()->getParameter( $formId );
196 $subject = ! empty( $formParameter['subject'] )
197 ? $formParameter['subject']
198 : __( 'Please confirm your opt-in', 'double-opt-in' );
199
200 $headers = array( 'Content-Type: text/html; charset=UTF-8' );
201
202 if ( ! empty( $formParameter['sender'] ) ) {
203 if ( ! empty( $formParameter['sender_name'] ) ) {
204 $headers[] = 'From: ' . $formParameter['sender_name'] . ' <' . $formParameter['sender'] . '>';
205 } else {
206 $headers[] = 'From: ' . $formParameter['sender'];
207 }
208 }
209
210 $sent = wp_mail( $email, $subject, $body, $headers );
211
212 if ( $sent ) {
213 $this->logger->info(
214 'Confirmation mail resent',
215 array(
216 'plugin' => 'double-opt-in',
217 'optin_id' => $optinId,
218 'email' => $email,
219 )
220 );
221 wp_send_json_success( array( 'message' => __( 'Confirmation mail has been resent.', 'double-opt-in' ) ) );
222 } else {
223 $this->logger->error(
224 'Failed to resend confirmation mail',
225 array(
226 'plugin' => 'double-opt-in',
227 'optin_id' => $optinId,
228 'email' => $email,
229 )
230 );
231 wp_send_json_error( array( 'message' => __( 'Failed to send mail. Please check your mail configuration.', 'double-opt-in' ) ) );
232 }
233 }
234 }
235