[Bug] "Select Editor" choice (design_template) not persisted for existing campaigns
# "Select Editor" choice (design_template) not persisted for existing campaigns β stale `settings.template_config.design_template` overrides the user's selection on save
## Environment
- FluentCRM: 3.1.6
- FluentCRM Pro / FluentCampaign: 3.1.6
- WordPress: 7.0
- WooCommerce: 10.8.1
- PHP: 8.3
- Database: MariaDB 11.4
## Summary
In the campaign editor, switching the editor via "Select Editor" (Default/Gutenberg β Classic Editor / Raw HTML) and saving does not persist for an existing campaign: after save + reload the campaign opens again in the previous editor (typically Default/Gutenberg).
Asymmetry observed:
- Switching to a Gutenberg-based template (simple/plain/classic) β persists.
- Switching to `raw_classic` / `raw_html` (`use_gutenberg=false`) β does not persist.
## Root cause (diagnosed via network capture + source)
On save, the request to `POST /wp-json/fluent-crm/v2/campaigns/update-single-campaign` does carry the correct user choice as a top-level field:
design_template: "raw_classic" Β Β Β Β Β Β // correct β the user's Select Editor choicesettings.template_config.design_template: "simple" Β // STALE
But the server (`CampaignController::updateSingleCampaignSimulate`, ~L352β360) lets the nested value override the top-level one:
$updateData = Arr::only($data, [..., 'design_template']); Β // = 'raw_classic' (correct)
if (!empty($data['settings']['template_config']['design_template'])) {
Β Β $updateData['design_template'] = $data['settings']['template_config']['design_template']; // = 'simple' β reverts
}
Because `raw_classic` / `raw_html` use an empty `config` (see `Helper::getEmailDesignTemplates()`), the `template_config.design_template` is never refreshed when switching to them, so the stale `simple` survives and overrides the user's choice β the column is saved as `simple` β reload opens Gutenberg.
(The campaign editor loads the editor based on the `design_template` column, which is why the stale-override reverts the UI.)
## Reproduction
- Open an existing campaign that is in Default (Gutenberg) mode.
- Select Editor β Classic Editor. Save (toast: success).
- Reload / reopen the campaign.
- Observe: it opens in Default (Gutenberg) again. DB shows `design_template = 'simple'` and `settings.template_config.design_template = 'simple'`, even though the save request's top-level `design_template` was `'raw_classic'`.
## Impact
Users cannot reliably switch an existing campaign to the Classic / Raw HTML editor; the choice silently reverts. (Choosing the editor at campaign creation does persist β only post-creation switching is affected.)
## Expected
On save, the user's explicit top-level `design_template` (the Select Editor choice) should win, and `settings.template_config.design_template` should be synced to it β so the chosen editor mode persists in either direction (mode-agnostic), regardless of whether the target mode has an empty config.
## Our mitigation (site-side, until fixed)
A small mu-plugin hooks `fluent_crm/campaign_data_updated` and, when the saved `design_template` differs from the request's top-level `design_template`, restores the user's choice and syncs `template_config`. It is mode-agnostic and self-deactivating (no-op once the core override is fixed).
## Attachments
- Captured save payload (top-level `design_template=raw_classic`, `template_config.design_template=simple`).
- Before/after DB values.