| @@ -8,9 +8,11 @@ | ||
| 8 | 8 | |
| 9 | 9 | namespace Forge12\DoubleOptIn\FormSettings; |
| 10 | 10 | |
| 11 | 11 | use Forge12\DoubleOptIn\EmailTemplates\EmailTemplateRepository; |
| 12 | +use Forge12\DoubleOptIn\Health\StaleConsentFieldCheck; | |
| 12 | 13 | use Forge12\DoubleOptIn\Integration\FormIntegrationRegistry; |
| 14 | +use Forge12\DoubleOptIn\Integration\SubmittedContent; | |
| 13 | 15 | use Forge12\Shared\LoggerInterface; |
| 14 | 16 | |
| 15 | 17 | if ( ! defined( 'ABSPATH' ) ) { |
| 16 | 18 | exit; |
| @@ -143,8 +145,14 @@ | ||
| 143 | 145 | 'enabled' => $settings->enabled, |
| 144 | 146 | ) |
| 145 | 147 | ); |
| 146 | 148 | |
| 149 | + // The acceptance-field health check caches its scan for hours. | |
| 150 | + // Someone who just saved these settings very likely did so to fix | |
| 151 | + // what that check reported, and a stale "still broken" would be a | |
| 152 | + // bad answer. | |
| 153 | + StaleConsentFieldCheck::flush(); | |
| 154 | + | |
| 147 | 155 | return true; |
| 148 | 156 | } |
| 149 | 157 | |
| 150 | 158 | /** |
| @@ -330,8 +338,42 @@ | ||
| 330 | 338 | $fieldsList[] = array( |
| 331 | 339 | 'name' => (string) $name, |
| 332 | 340 | 'label' => $label, |
| 333 | 341 | ); |
| 342 | + } | |
| 343 | + | |
| 344 | + // Reconcile the stored consent field with the form's real field | |
| 345 | + // names. Settings written before 5.3.2 went through | |
| 346 | + // sanitize_key(), which lowercased them — so an Elementor | |
| 347 | + // checkbox with the id `Datenschutz` sits in post_meta as | |
| 348 | + // `datenschutz`, matches nothing, and the settings page warns | |
| 349 | + // that the field does not exist. Forever: re-picking it from | |
| 350 | + // the dropdown lowercased it again (customer report 2026-08-27). | |
| 351 | + // | |
| 352 | + // The validator no longer mangles new saves; this repairs the | |
| 353 | + // installations that already have a mangled one. Doing it on | |
| 354 | + // read means an untouched site recovers the moment the page is | |
| 355 | + // opened, and the corrected spelling is what the next save | |
| 356 | + // persists. | |
| 357 | + // | |
| 358 | + // A name that matches NOTHING is left exactly as it is — the | |
| 359 | + // field really was removed from the form, and the red banner | |
| 360 | + // saying so is the correct answer. | |
| 361 | + $storedConsentField = (string) ( $settingsArray['consentField'] ?? '' ); | |
| 362 | + if ( $storedConsentField !== '' ) { | |
| 363 | + $canonical = SubmittedContent::matchFieldName( $storedConsentField, array_keys( $fields ) ); | |
| 364 | + if ( $canonical !== '' && $canonical !== $storedConsentField ) { | |
| 365 | + $this->logger->info( | |
| 366 | + 'Repaired a consent field name that only differed in case', | |
| 367 | + array( | |
| 368 | + 'plugin' => 'double-opt-in', | |
| 369 | + 'form_id' => $formId, | |
| 370 | + 'stored' => $storedConsentField, | |
| 371 | + 'form' => $canonical, | |
| 372 | + ) | |
| 373 | + ); | |
| 374 | + $settingsArray['consentField'] = $canonical; | |
| 375 | + } | |
| 334 | 376 | } |
| 335 | 377 | |
| 336 | 378 | return array( |
| 337 | 379 | 'id' => $formId, |