We are experiencing this with the MediaViewer enabled flag. MediaViewer is set up as follows:
the preference is defined as
$prefs['multimediaviewer-enable'] = array( 'type' => 'toggle', 'label-message' => 'multimediaviewer-optin-pref', 'section' => 'rendering/files', );
additionally, when the viewer is enabled by default (this depends on the site and whether the user is logged in)
$wgDefaultUserOptions['multimediaviewer-enable'] = true;
Using the Special:Preferences page, when MediaViewer is enabled by default, enabled/disabled state is stored in user_properties.up_value as no row / '' respectively. When it is disabled by default, enabled/disabled is stored as '1' / no row respectively.
When $wgDefaultUserOptions['multimediaviewer-enable'] is true, this behavior can be replicated via the options the API by using a value of '1' (or anything other truthy) for enabling, and '' for disabling. When the default is not set to true, the behavior can be replicated by using '1' (needs to be exactly that) for enabled and no value (missing optionvalue parameter) for disabled.
However, there is no way to tell from the client side what the default is, and there doesn't seem to be any way of using the API which will work in both cases; instead of the database row just disappearing when set to the default state, it will be set to some value which could never be achieved via Special:Preferences.
So, there seems to be multiple levels of fail here:
- the DB representation of binary preferences is messy in the first place ('1' and '' instead of '1' and '0' or some other clean setup - I presume this is because '0' can be truthy in some circumstances, but that sort of low-level consideration should be hidden from someone using the API)
- the preference can be set to pretty much any value via the options API, not just the ones which are valid (can result from Special:Preferences)
- setting the preference to '' does not delete the DB row when the preference defaults to false.