PluginProbe
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification / 5.8.1
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification v5.8.1
5.8.0 5.8.1 5.7.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 All 41 releases
double-opt-in / src / Admin / ResendController.php

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

199 lines 5.9 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\Service\ConfirmationMailResender;
13 use Forge12\DoubleOptIn\Service\ResendResult;
14 use Forge12\Shared\LoggerInterface;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit;
18 }
19
20 /**
21 * Class ResendController
22 *
23 * Handles resending confirmation emails for unconfirmed opt-ins.
24 */
25 class ResendController {
26
27 private LoggerInterface $logger;
28
29 public function __construct( LoggerInterface $logger ) {
30 $this->logger = $logger;
31
32 add_action( 'wp_ajax_doi_resend_optin_mail', array( $this, 'handleResend' ) );
33 add_action( 'f12_cf7_doubleoptin_ui_view_optin_options', array( $this, 'renderResendButton' ) );
34 }
35
36 /**
37 * Render the resend button on the view-optin page.
38 *
39 * @param \forge12\contactform7\CF7DoubleOptIn\OptIn $optin The OptIn facade instance.
40 *
41 * @return void
42 */
43 public function renderResendButton( $optin ): void {
44 // Free since 5.8, like the resend in the SPA: no licence check.
45 $is_confirmed = $optin->is_confirmed();
46 $has_mail = ! empty( $optin->get_mail_optin() );
47 $disabled = $is_confirmed || ! $has_mail;
48
49 $nonce = wp_create_nonce( 'doi_resend_mail' );
50 $id = $optin->get_id();
51
52 // Build tooltip explaining why the button is disabled
53 $title = '';
54 if ( $is_confirmed ) {
55 $title = __( 'This Opt-In has already been confirmed.', 'double-opt-in' );
56 } elseif ( ! $has_mail ) {
57 $title = __( 'No mail body stored for this Opt-In.', 'double-opt-in' );
58 }
59 ?>
60 <button type="button"
61 class="button"
62 id="doi-resend-btn"
63 data-id="<?php echo esc_attr( $id ); ?>"
64 data-nonce="<?php echo esc_attr( $nonce ); ?>"
65 <?php echo $disabled ? 'disabled' : ''; ?>
66 <?php echo ! empty( $title ) ? 'title="' . esc_attr( $title ) . '"' : ''; ?>
67 style="<?php echo $disabled ? 'opacity:.6;cursor:not-allowed;' : ''; ?>">
68 <?php
69 _e( 'Resend Confirmation Mail', 'double-opt-in' );
70 ?>
71 </button>
72 <span class="doi-tooltip">
73 <span class="dashicons dashicons-info-outline"></span>
74 <span class="doi-tooltip-text">
75 <?php
76 esc_html_e( 'Re-sends the original confirmation email with the opt-in link to the recipient.', 'double-opt-in' );
77 ?>
78 </span>
79 </span>
80 <span id="doi-resend-feedback" style="font-size:13px;"></span>
81 <?php if ( ! $disabled ) : ?>
82 <script>
83 (function() {
84 var btn = document.getElementById('doi-resend-btn');
85 var feedback = document.getElementById('doi-resend-feedback');
86 if (!btn || btn.disabled) return;
87
88 btn.addEventListener('click', function() {
89 btn.disabled = true;
90 btn.style.opacity = '.6';
91 feedback.textContent = '';
92
93 var formData = new FormData();
94 formData.append('action', 'doi_resend_optin_mail');
95 formData.append('_wpnonce', btn.dataset.nonce);
96 formData.append('optin_id', btn.dataset.id);
97
98 fetch(ajaxurl, {
99 method: 'POST',
100 body: formData,
101 credentials: 'same-origin'
102 })
103 .then(function(response) { return response.json(); })
104 .then(function(data) {
105 if (data.success) {
106 feedback.style.color = '#00a32a';
107 feedback.textContent = data.data.message || 'Mail sent';
108 } else {
109 feedback.style.color = '#d63638';
110 feedback.textContent = data.data.message || 'Error';
111 btn.disabled = false;
112 btn.style.opacity = '';
113 }
114 })
115 .catch(function() {
116 feedback.style.color = '#d63638';
117 feedback.textContent = 'Request failed';
118 btn.disabled = false;
119 btn.style.opacity = '';
120 });
121 });
122 })();
123 </script>
124 <?php endif; ?>
125 <?php
126 }
127
128 /**
129 * Handle the AJAX request to resend a confirmation mail.
130 *
131 * @return void
132 */
133 public function handleResend(): void {
134 if ( ! current_user_can( 'manage_options' ) ) {
135 wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'double-opt-in' ) ), 403 );
136 }
137
138 if ( ! check_ajax_referer( 'doi_resend_mail', '_wpnonce', false ) ) {
139 wp_send_json_error( array( 'message' => __( 'Security check failed.', 'double-opt-in' ) ), 403 );
140 }
141
142 $optinId = isset( $_POST['optin_id'] ) ? (int) $_POST['optin_id'] : 0;
143
144 if ( $optinId <= 0 ) {
145 wp_send_json_error( array( 'message' => __( 'Invalid Opt-In ID.', 'double-opt-in' ) ) );
146 }
147
148 try {
149 $outcome = Container::getInstance()->get( ConfirmationMailResender::class )->resend( $optinId );
150 } catch ( \Exception $e ) {
151 $this->logger->error(
152 'Failed to load OptIn for resend',
153 array(
154 'plugin' => 'double-opt-in',
155 'id' => $optinId,
156 'error' => $e->getMessage(),
157 )
158 );
159 wp_send_json_error( array( 'message' => __( 'Failed to load Opt-In.', 'double-opt-in' ) ) );
160 }
161
162 if ( $outcome->isSent() ) {
163 $this->logger->info(
164 'Confirmation mail resent',
165 array(
166 'plugin' => 'double-opt-in',
167 'optin_id' => $optinId,
168 )
169 );
170 wp_send_json_success( array( 'message' => __( 'Confirmation mail has been resent.', 'double-opt-in' ) ) );
171 }
172
173 $messages = array(
174 ResendResult::NOT_FOUND => __( 'Opt-In not found.', 'double-opt-in' ),
175 ResendResult::CONFIRMED => __( 'This Opt-In is already confirmed.', 'double-opt-in' ),
176 ResendResult::OPTED_OUT => __( 'This contact has opted out. The confirmation email is not sent again.', 'double-opt-in' ),
177 ResendResult::NO_BODY => __( 'No mail body stored for this Opt-In.', 'double-opt-in' ),
178 ResendResult::NO_RECIPIENT => __( 'No recipient email found.', 'double-opt-in' ),
179 );
180
181 if ( $outcome->getReason() === ResendResult::SEND_FAILED ) {
182 $this->logger->error(
183 'Failed to resend confirmation mail',
184 array(
185 'plugin' => 'double-opt-in',
186 'optin_id' => $optinId,
187 )
188 );
189 }
190
191 wp_send_json_error(
192 array(
193 'message' => $messages[ $outcome->getReason() ]
194 ?? __( 'Failed to send mail. Please check your mail configuration.', 'double-opt-in' ),
195 )
196 );
197 }
198 }
199