Skip to content

[2.x] fix: allow boolean settings with truthy defaults to be disabled - #4782

Merged
imorland merged 2 commits into
flarum:2.xfrom
huoxin233:huoxin/2.x-fix-boolean-setting-fallback
Aug 5, 2026
Merged

[2.x] fix: allow boolean settings with truthy defaults to be disabled#4782
imorland merged 2 commits into
flarum:2.xfrom
huoxin233:huoxin/2.x-fix-boolean-setting-fallback

Conversation

@huoxin233

Copy link
Copy Markdown
Contributor

Fixes #4781

Changes proposed in this pull request:

Resolves a bug in AdminPage.tsx where boolean settings (toggles) that have a truthy default value could not be turned off by the administrator.

By switching from the logical OR operator (||) to the nullish coalescing operator (??), the setting stream correctly recognizes "" as a valid saved state. The fallback is now only applied when the setting is strictly undefined or null (e.g., during a fresh installation where the setting hasn't been saved to the database yet).

Reviewers should focus on:

Screenshot

PixPin_2026-06-26_18-10-57.mp4

Necessity

  • Has the problem that is being solved here been clearly explained?
  • If applicable, have various options for solving this problem been considered?
  • For core PRs, does this need to be in core, or could it be in an extension?
  • Are we willing to maintain this for years / potentially forever?

Confirmed

  • Frontend changes: tested on a local Flarum installation.
  • Backend changes: tests are green (run composer test).
  • Core developer confirmed locally this works as intended.
  • Tests have been added, or are not appropriate here.

Required changes:

  • Related documentation PR: (Remove if irrelevant)

@imorland

Copy link
Copy Markdown
Member

Thanks for the PR. Please see my comment on the issue you created: #4781 (comment)

Pins what `setting(key, fallback)` seeds its stream with: a saved value is
used, an absent one falls back to the default, and a saved empty string is
kept rather than mistaken for absent. That last case is the bug — settings
live in a string column, so a `false` comes back as `''`, and choosing the
fallback on falsiness meant a setting whose default is truthy reverted to on
with every reload.

Also pins `'0'`, which was never affected: the string is truthy in JavaScript,
unlike the number. Worth stating so the distinction survives.
@imorland imorland added this to the 2.0.0-rc.6 milestone Aug 5, 2026
@imorland

imorland commented Aug 5, 2026

Copy link
Copy Markdown
Member

Thanks for tracking this down properly — the diagnosis is right, and the point about setting(key, fallback) publicly exposing a fallback is fair: while it uses ||, anyone using that parameter hits this.

I've pushed tests onto your branch to go with the fix. They pin all four cases — saved value, absent value, saved empty string (the bug), and '0'.

One note on that last one: '0' was never actually affected, since the string is truthy in JavaScript, unlike the number. So the empty string is the only value a setting can hold that JS reads as absent. I've pinned it anyway so that distinction doesn't get lost.

@imorland
imorland merged commit 3170c2c into flarum:2.x Aug 5, 2026
18 checks passed
imorland added a commit that referenced this pull request Aug 5, 2026
#4782 fixed this in `AdminPage` but the identical line in `SettingsModal`
survived, so the bug still reached every settings *modal*: settings live in a
string column, a saved `false` arrives as an empty string, and choosing the
fallback on falsiness discarded it and reseeded the default. A boolean setting
whose default is truthy could not be switched off — it came back on with every
reload.

`SettingsModal` is public API, imported by extensions as
`flarum/admin/components/SettingsModal`, and core's custom header, footer and
CSS modals extend it, as does flarum/audit.

The existing test file now covers both classes side by side rather than only
the one the original issue named, which is what would have caught this the
first time. Its docblock is corrected too: it claimed a saved `'0'` was also
discarded, but the string is truthy in JavaScript, unlike the number — the
empty string is the only value a setting can hold that JavaScript reads as
absent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[1.x & 2.x] Admin boolean settings with truthy default values cannot be disabled (Switch component)

2 participants