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 / OnUpdate.php

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

268 lines 8.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace forge12\contactform7\CF7DoubleOptIn;
4
5 use Forge12\Shared\Logger;
6
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit;
9 }
10
11 function onUpdate() {
12 $logger = Logger::getInstance();
13
14 $logger->info( 'Running onUpdate routine', [
15 'plugin' => 'double-opt-in',
16 'class' => __CLASS__ ?? null,
17 'method' => __FUNCTION__,
18 ] );
19
20 // Read and write the stored version with the SAME scope. Historically
21 // the read used get_site_option() (network scope on multisite) while
22 // every write below uses update_option() (blog scope) — so on a
23 // network-activated multisite the version never read back, and every
24 // idempotent block re-ran on each admin load. Blog scope matches the
25 // per-site tables created in OnActivation.php.
26 $currentVersion = get_option( FORGE12_OPTIN_SLUG . '_version' );
27
28 if ( version_compare( $currentVersion, '1.7' ) < 0 ) {
29 $logger->info( 'Updating to version 1.7', [
30 'plugin' => 'double-opt-in',
31 'current' => $currentVersion,
32 'target' => '1.7',
33 ] );
34
35 createTableOptinCategories();
36 $logger->debug( 'createTableOptinCategories executed', [
37 'plugin' => 'double-opt-in',
38 ] );
39
40 createTableOptin();
41 $logger->debug( 'createTableOptin executed', [
42 'plugin' => 'double-opt-in',
43 ] );
44
45 update_option( FORGE12_OPTIN_SLUG . '_version', '1.7' );
46 $logger->info( 'Version updated to 1.7', [
47 'plugin' => 'double-opt-in',
48 ] );
49 }
50
51 if ( version_compare( $currentVersion, '2.0' ) < 0 ) {
52 $logger->info( 'Updating to version 2.0', [
53 'plugin' => 'double-opt-in',
54 'current' => $currentVersion,
55 'target' => '2.0',
56 ] );
57
58 createTableOptin();
59 $logger->debug( 'createTableOptin executed', [
60 'plugin' => 'double-opt-in',
61 ] );
62
63 update_option( FORGE12_OPTIN_SLUG . '_version', '2.0' );
64 $logger->info( 'Version updated to 2.0', [
65 'plugin' => 'double-opt-in',
66 ] );
67 }
68
69 if ( version_compare( $currentVersion, '3.0.1' ) < 0 ) {
70 $logger->info( 'Updating to version 3.0.1', [
71 'plugin' => 'double-opt-in',
72 'current' => $currentVersion,
73 'target' => '3.0.1',
74 ] );
75
76 createTableOptin();
77 $logger->debug( 'createTableOptin executed', [
78 'plugin' => 'double-opt-in',
79 ] );
80
81 update_option( FORGE12_OPTIN_SLUG . '_version', '3.0.1' );
82 $logger->info( 'Version updated to 3.0.1', [
83 'plugin' => 'double-opt-in',
84 ] );
85 }
86
87 if ( version_compare( $currentVersion, '3.2.0' ) < 0 ) {
88 $logger->info( 'Updating to version 3.2.0', [
89 'plugin' => 'double-opt-in',
90 'current' => $currentVersion,
91 'target' => '3.2.0',
92 ] );
93
94 createTableOptin();
95 $logger->debug( 'createTableOptin executed', [
96 'plugin' => 'double-opt-in',
97 ] );
98
99 update_option( FORGE12_OPTIN_SLUG . '_version', '3.2.0' );
100 $logger->info( 'Version updated to 3.2.0', [
101 'plugin' => 'double-opt-in',
102 ] );
103 }
104
105 if ( version_compare( $currentVersion, '3.3.0' ) < 0 ) {
106 $logger->info( 'Updating to version 3.3.0', [
107 'plugin' => 'double-opt-in',
108 'current' => $currentVersion,
109 'target' => '3.3.0',
110 ] );
111
112 // Migrate Unix timestamps to ISO 8601 format
113 global $wpdb;
114 $table = $wpdb->prefix . 'f12_cf7_doubleoptin';
115 foreach ( [ 'createtime', 'updatetime', 'optouttime' ] as $col ) {
116 $wpdb->query(
117 "UPDATE {$table} SET {$col} = FROM_UNIXTIME({$col})
118 WHERE {$col} REGEXP '^[0-9]+$' AND {$col} != '' AND {$col} != '0'"
119 );
120 $logger->debug( "Migrated column {$col} from Unix to ISO 8601", [
121 'plugin' => 'double-opt-in',
122 ] );
123 }
124
125 update_option( FORGE12_OPTIN_SLUG . '_version', '3.3.0' );
126 $logger->info( 'Version updated to 3.3.0', [
127 'plugin' => 'double-opt-in',
128 ] );
129 }
130
131 if ( version_compare( $currentVersion, '3.4.0' ) < 0 ) {
132 $logger->info( 'Updating to version 3.4.0', [
133 'plugin' => 'double-opt-in',
134 'current' => $currentVersion,
135 'target' => '3.4.0',
136 ] );
137
138 createTableOptin();
139 $logger->debug( 'createTableOptin executed (adds reminder columns)', [
140 'plugin' => 'double-opt-in',
141 ] );
142
143 update_option( FORGE12_OPTIN_SLUG . '_version', '3.4.0' );
144 $logger->info( 'Version updated to 3.4.0', [
145 'plugin' => 'double-opt-in',
146 ] );
147 }
148
149 if ( version_compare( $currentVersion, '4.2.0' ) < 0 ) {
150 $logger->info( 'Updating to version 4.2.0', [
151 'plugin' => 'double-opt-in',
152 'current' => $currentVersion,
153 'target' => '4.2.0',
154 ] );
155
156 createTableAuditLog();
157 $logger->debug( 'createTableAuditLog executed', [
158 'plugin' => 'double-opt-in',
159 ] );
160
161 update_option( FORGE12_OPTIN_SLUG . '_version', '4.2.0' );
162 $logger->info( 'Version updated to 4.2.0', [
163 'plugin' => 'double-opt-in',
164 ] );
165 }
166
167 if ( version_compare( $currentVersion, '5.0.1' ) < 0 ) {
168 $logger->info( 'Updating to version 5.0.1 (adds consent_field column)', [
169 'plugin' => 'double-opt-in',
170 'current' => $currentVersion,
171 'target' => '5.0.1',
172 ] );
173
174 // dbDelta detects the new `consent_field` column in
175 // createTableOptin()'s schema and ALTERs the existing table
176 // to add it. Existing rows get the column's DEFAULT '' so
177 // no data migration is needed.
178 createTableOptin();
179 $logger->debug( 'createTableOptin executed (adds consent_field column)', [
180 'plugin' => 'double-opt-in',
181 ] );
182
183 update_option( FORGE12_OPTIN_SLUG . '_version', '5.0.1' );
184 $logger->info( 'Version updated to 5.0.1', [
185 'plugin' => 'double-opt-in',
186 ] );
187 }
188
189 if ( version_compare( $currentVersion, '5.6.0' ) < 0 ) {
190 $logger->info( 'Updating to version 5.6.0 (adds follow-up status table)', [
191 'plugin' => 'double-opt-in',
192 'current' => $currentVersion,
193 'target' => '5.6.0',
194 ] );
195
196 // New table only. Opt-ins confirmed before this version get no
197 // rows and are shown as "no status recorded" — deliberately not
198 // replayed, which would re-send historic mails.
199 \Forge12\DoubleOptIn\Repository\FollowUpSchema::install();
200
201 update_option( FORGE12_OPTIN_SLUG . '_version', '5.6.0' );
202 }
203
204 if ( version_compare( $currentVersion, '5.8.0' ) < 0 ) {
205 $logger->info( 'Updating to version 5.8.0 (adds confirmation mail status columns)', [
206 'plugin' => 'double-opt-in',
207 'current' => $currentVersion,
208 'target' => '5.8.0',
209 ] );
210
211 // mail_status / mail_error / mail_status_at. Existing rows keep an
212 // empty status ("recorded before 5.8"), nothing is back-filled.
213 createTableOptin();
214
215 update_option( FORGE12_OPTIN_SLUG . '_version', '5.8.0' );
216 }
217
218 // Safety net: Ensure both tables always exist regardless of stored version.
219 // Handles edge cases such as database migrations, manual file uploads, or
220 // restored backups that are missing the custom tables.
221 global $wpdb;
222 $optinTable = $wpdb->prefix . 'f12_cf7_doubleoptin';
223 $categoryTable = $wpdb->prefix . 'f12_cf7_doubleoptin_categories';
224
225 if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $optinTable ) ) !== $optinTable ) {
226 $logger->warning( 'OptIn table missing – recreating.', [ 'plugin' => 'double-opt-in', 'table' => $optinTable ] );
227 createTableOptin();
228 }
229
230 if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $categoryTable ) ) !== $categoryTable ) {
231 $logger->warning( 'Categories table missing – recreating.', [ 'plugin' => 'double-opt-in', 'table' => $categoryTable ] );
232 createTableOptinCategories();
233 }
234
235 $auditTable = $wpdb->prefix . 'f12_cf7_doubleoptin_audit_log';
236 if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $auditTable ) ) !== $auditTable ) {
237 $logger->warning( 'Audit log table missing – recreating.', [ 'plugin' => 'double-opt-in', 'table' => $auditTable ] );
238 createTableAuditLog();
239 }
240
241 if ( ! \Forge12\DoubleOptIn\Repository\FollowUpSchema::isCurrent() ) {
242 $logger->warning( 'Follow-up table missing or outdated – running dbDelta.', [ 'plugin' => 'double-opt-in' ] );
243 \Forge12\DoubleOptIn\Repository\FollowUpSchema::install();
244 }
245
246 // Always pin the stored version to the live plugin version. The
247 // version_compare ladder above only writes the target of the last
248 // block that ran (e.g. '5.0.1'), so without this line the stored
249 // version permanently lags FORGE12_OPTIN_VERSION even after the
250 // upgrade completed — including for releases that ship no schema
251 // change (e.g. 5.1.0). Unconditional so it self-heals any drift.
252 if ( defined( 'FORGE12_OPTIN_VERSION' )
253 && version_compare( (string) $currentVersion, FORGE12_OPTIN_VERSION, '<' ) ) {
254 update_option( FORGE12_OPTIN_SLUG . '_version', FORGE12_OPTIN_VERSION );
255 $logger->info( 'Stored version pinned to current plugin version', [
256 'plugin' => 'double-opt-in',
257 'from' => $currentVersion,
258 'to' => FORGE12_OPTIN_VERSION,
259 ] );
260 }
261
262 $logger->info( 'onUpdate routine finished', [
263 'plugin' => 'double-opt-in',
264 ] );
265 }
266
267 onUpdate();
268