fix(setup): initialize newsletter opt-in on fresh installs - #1683
Conversation
📝 WalkthroughWalkthroughThe newsletter toggle configuration now uses ChangesNewsletter setting defaults
Estimated code review effort: 1 (Trivial) | ~5 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@inc/class-newsletter.php`:
- Around line 48-51: Update the wizard save flow used by
Settings::save_settings() so newsletter_optin retains its registered default
when the checkbox is omitted, rather than being converted to 0. Ensure the
general-section toggle handling distinguishes an omitted field from an
explicitly submitted unchecked value, while preserving explicit opt-out
behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: fede631c-8e53-4b36-820a-f3f13097a8d2
📒 Files selected for processing (3)
inc/class-newsletter.phpinc/class-settings.phptests/WP_Ultimo/Settings_Test.php
| 'title' => __('Signup for Ultimate Multisite Newsletter', 'ultimate-multisite'), | ||
| 'desc' => __('Be informed of new releases and all things related to running a WaaS Network.', 'ultimate-multisite'), | ||
| 'type' => 'toggle', | ||
| 'default' => '1', |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 12 "save_settings\(|newsletter_optin|wu_request\('tab'" --glob '*.php' .Repository: Ultimate-Multisite/ultimate-multisite
Length of output: 50394
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the relevant newsletter registration, setup-wizard submit logic, and settings save behavior.
sed -n '1,70p' inc/class-newsletter.php
printf '\n--- setup-wizard save_settings ---\n'
sed -n '815,833p' inc/admin-pages/class-setup-wizard-admin-page.php
printf '\n--- setup-wizard fields methods around general/general settings ---\n'
rg -n "class Setup_Wizard|get_general_settings|add_action|action='.*newsletter|checkbox|toggle|newsletter_optin|name='\$field|fields_to_get|fields_to_save" inc/admin-pages/class-setup-wizard-admin-page.php inc/functions/settings.php inc/class-settings.phpRepository: Ultimate-Multisite/ultimate-multisite
Length of output: 7648
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- setup-wizard general fields ---'
sed -n '580,609p' inc/admin-pages/class-setup-wizard-admin-page.php
printf '\n%s\n' '--- settings field form rendering around checkboxes/toggles ---'
sed -n '130,230p' inc/class-settings.php
sed -n '200,250p' inc/class-settings.php
printf '%s\n' '--- deterministic save_settings tab-zero logic check from source text ---'
python3 - <<'PY'
from pathlib import Path
import re
path = Path('inc/class-settings.php')
src = path.read_text()
m = re.search(
r'public\s+function\s+save_settings\s*\([^)]*\).*?\n\t{2}\{\n(.*?)^'.format(),
src,
re.S | re.M
)
if not m:
raise SystemExit('save_settings not found')
body = m.group(1)
print('contains omitted toggle general false:')
print("wu_request('tab' === \"general\")" in body)
print('! isset($settings_to_save[ $field_slug ]) && new_value = false' in body)
# Read-only source-based invariant: if the exact general-tab guard and omitted toggle guard exist, omitted general toggles are false.
guard = "if (wu_request('tab', 'general') === $section_slug && 'toggle' === $field->type && ! isset($settings_to_save[ $field_slug ]))"
print('exact general omit guard:')
print(guard in body)
if guard in body:
assignment = body[body.find(guard):].partition('\n')[0]
print('first line in guard block:')
print(assignment)
PYRepository: Ultimate-Multisite/ultimate-multisite
Length of output: 5931
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- field registration helper ---'
rg -n -C 10 "function wu_register_settings_field|if (.*tab|fields\]\s*\[" inc/functions/settings.php
printf '\n%s\n' '--- save_settings omitted toggle block ---'
sed -n '352,390p' inc/class-settings.php
printf '\n%s\n' '--- newsletter post handler fields/form references ---'
rg -n -C 5 "newsletter_optin|wu-settings-field|type.*checkbox|type.*toggle|input name|name.*news" --glob '*.php' --glob '*.js' .Repository: Ultimate-Multisite/ultimate-multisite
Length of output: 328
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- field registration helper ---'
rg -n -C 8 'function wu_register_settings_field|fields\]\s*\[' inc/functions/settings.php
printf '%s\n' '--- save_settings omitted toggle block ---'
sed -n '352,390p' inc/class-settings.php
printf '%s\n' '--- newsletter post handler fields/form references ---'
rg -n -C 5 'newsletter_optin|wu-settings-field|checkbox|toggle|submit|posts-to-edit|name.*news' --glob '*.php' --glob '*.js' .Repository: Ultimate-Multisite/ultimate-multisite
Length of output: 50394
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- wu_register_settings_field definition ---'
rg -n "function wu_register_settings_field|if \(\$tab" inc/functions/settings.php
printf '%s\n' '--- save_settings omitted toggle block ---'
sed -n '352,390p' inc/class-settings.php
printf '%s\n' '--- newsletter opt-in handling ---'
sed -n '70,140p' inc/class-newsletter.php
printf '%s\n' '--- deterministic data-flow evidence from source slices ---'
python3 - <<'PY'
from pathlib import Path
setup = Path('inc/admin-pages/class-setup-wizard-admin-page.php').read_text()
settings = Path('inc/class-settings.php').read_text()
news = Path('inc/class-newsletter.php').read_text()
print('setup uses general wizard step:', "'your-company' === $step" in setup)
print('setup includes all general fields:', "WP_Ultimo\\Settings::get_instance()->get_section('general')['fields']" in setup)
print('setup submits intersected POST keys:', "array_intersect_key($_POST, $fields_to_save)" in setup)
print('settings omits general toggles to false:', "wu_request('tab', 'general') === \$section_slug && 'toggle' === \$field->type && ! isset(\$settings_to_save[ \$field_slug ])" in settings)
print('newsletter subscribes by post presence pattern:', 'isset(\$settings_to_save[' in news and 'newsletter_optin' in news)
PYRepository: Ultimate-Multisite/ultimate-multisite
Length of output: 3553
Persist the newsletter optin default on the wizard save path.
The wizard renders all general section fields but submits only $_POST keys, so an unchecked newsletter_optin arrives as 0 for Settings::save_settings(). Since that save path also treats omitted general toggles as 0, a fresh wizard can overwrite the registered default unless the checkbox submits its value or the save path preserves defaults for omitted toggles.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@inc/class-newsletter.php` around lines 48 - 51, Update the wizard save flow
used by Settings::save_settings() so newsletter_optin retains its registered
default when the checkbox is omitted, rather than being converted to 0. Ensure
the general-section toggle handling distinguishes an omitted field from an
explicitly submitted unchecked value, while preserving explicit opt-out
behavior.
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
|
DISPATCH_CLAIM nonce=9f693acb3df7ebee378c0c9cfeff3e17 runner=superdav42 ts=2026-07-31T16:11:38Z max_age_s=120 version=3.32.199 opencode_version=1.18.5 lease_token=9f693acb3df7ebee378c0c9cfeff3e17 device=device-1783824528-2609248-26808 session=issue-1683 phase=prelaunch expires_at=1785514420 |
|
REVIEW_FOLLOWUP_CREATED source_pr=1683 issue=1687 fingerprint=source-pr-1683 runner=superdav42 ts=2026-07-31T16:12:00Z |
Summary
Verification
vendor/bin/phpcs inc/class-newsletter.php inc/class-settings.php tests/WP_Ultimo/Settings_Test.phpvendor/bin/phpunit --filter test_get_all_with_defaults_includes_newsletter_optin_when_db_is_emptyaidevops.sh v3.32.198 plugin for OpenCode v1.18.5 with gpt-5.6-terra
Summary by CodeRabbit
New Features
Bug Fixes