style.php: unset laptop/tablet "Section side padding" emits padding 0 and overrides desktop value

TITLE: style.php: unset laptop/tablet "Section side padding" emits padding 0 and overrides the desktop value (introduced 28.5.3, still present in 28.5.7)

SUMMARY

Version 28.5.3 fixed the laptop and tablet section-side-padding blocks in style.php — the media queries had been invalid, written as max-width 1440 and max-width 959 with the px unit missing — and at the same time changed the emission gate from a truthiness test to a "greater than or equal to zero" comparison, presumably so that an explicit 0 would be honored.

The side effect is that the gate now fires when the field was never filled in. mfn_opts_get returns its default, null, for an unset key, and in PHP a null compared as greater than or equal to zero evaluates to true. So the blocks emit ".section_wrapper { padding-left: 0px; padding-right: 0px }" between 960 and 1440 pixels and between 768 and 959 pixels on every site where the laptop and tablet values were left empty. The gate can no longer tell "the user chose 0" from "the user never touched this field".

In the current 28.5.7 package these are style.php lines 61 and 69, unchanged since 28.5.3.

A note on presentation: this site's firewall rejects both posts and uploads that contain PHP code, which is why the template code is described in prose here rather than quoted. The exact excerpts with line numbers are ready, and I am happy to send them by whatever channel suits you.

IMPACT

On a site with a non-zero desktop "Section side padding" and the laptop and tablet fields left empty, the desktop rule (emitted from 768 pixels upward) used to apply at all widths of 768 and above — in 28.5.2 the laptop and tablet blocks were dead CSS because of the missing px unit, so they never interfered. After updating, the now-valid laptop and tablet blocks override the desktop padding with 0 across 768 to 1440 pixels. Section side padding silently disappears on tablet and laptop viewports, with no settings change by the site owner.

STEPS TO REPRODUCE

1. In Theme Options, set the desktop "Section side padding" to a non-zero value, for example 30px. Leave the laptop and tablet responsive values empty, never filled.

2. On 28.5.2, view a page at a viewport width between 768 and 1440 pixels. The section wrapper has 30px of side padding, because the desktop rule applies and the laptop and tablet blocks are inert.

3. Update to 28.5.3 or later and reload at the same viewport.

EXPECTED: unset laptop and tablet values inherit the desktop padding, which was the previous effective behavior, while an explicit 0 in those fields overrides it — the apparent intent of the 28.5.3 change.

ACTUAL: the section wrapper side padding becomes 0 between 768 and 1440 pixels. The unset state is treated as an explicit 0.

ONE THING WORTH CHECKING ON YOUR SIDE

MFN_Options::get (options.php, line 620) normalizes an empty saved value back to the same default, returning it whenever the stored value is empty and is not the string "0". So "never saved the options page" and "saved with the field blank" both reach the gate as null, and both emit. There is no blank-versus-unset divergence to work around; the gate simply cannot distinguish any of those states from an explicit 0.

SUGGESTED FIX

Gate on presence rather than on a numeric comparison, so an explicit 0 still emits but an unset or blank value does not: read the option into a variable, then test that its string cast is not empty. Casting null or false to string yields an empty string, so unset and blank behave identically, while the string "0" passes and is emitted. The same change applies to the tablet key. The exact two lines are in the attached file.

RELATED INCONSISTENCY

The desktop block eight lines above, at style.php line 53, still uses the older truthiness gate, so an explicit desktop 0 still cannot emit. If the intent of the 28.5.3 change was to honor an explicit 0, the same presence gate would apply there too.

ENVIRONMENT

Introduced in BeTheme 28.5.3, verified by comparing the 28.5.2 and 28.5.3 packages, and still present unchanged in 28.5.7 — re-verified against the 28.5.7 package, where the two gates are byte-identical at style.php lines 61 and 69. The null comparison behavior is identical on PHP 7 and PHP 8.

Comments

  • Hi,

    thanks for suggestion. We will take your suggestion into account with future updates.

  • Thanks Albert. One correction on the classification, then the technical part.

    This was filed as a regression, not a suggestion. Rendering changed between 28.5.2 and 28.5.3 on sites where the owner changed no setting, and it still differs in 28.5.9.1. I raise it only because I suspect the "suggestion" label is why it is still open.

    Where to look: style.php in the theme root, the file sitting next to style.css.

    The 28.5.3 change had the right intent. Moving the laptop and tablet gates from a truthiness test to a "greater than or equal to zero" comparison only makes sense as a way to let an explicit 0 through, since a truthiness test drops it. The trouble is that the comparison cannot tell an explicit 0 from a field that was never filled in. mfn_opts_get returns null for an unset key, and in PHP null compared as greater than or equal to zero is true. So on any install where the laptop and tablet fields were left empty, those two blocks emit a zero side padding between 960 and 1440 pixels and between 768 and 959 pixels, overriding the desktop value the owner did set.

    A presence test does separate the two cases, and the idiom is already in this same file: line 25 gates the header height on an empty-string comparison rather than a numeric one. Read each option into a variable and test that its string cast is not empty. Null and false both cast to an empty string, so unset and blank behave identically, while the string "0" passes and is emitted. That gives you exactly what the 28.5.3 change was reaching for.

    Worth applying to all three branches rather than the two. The desktop gate at line 41 is still the older truthiness test, so an explicit desktop 0 cannot emit either. The same change fixes that at the same time.

    Two details in case they save someone a few minutes:

    The get method on MFN_Options, around line 620 of muffin-options/options.php, normalises an empty saved value back to the default. "Never saved the options page" and "saved with the field blank" therefore arrive at the gate identically, so there is no blank-versus-unset case needing separate handling.

    In the 28.5.7 package these three gates were at lines 53, 61 and 69; in 28.5.9.1 they are at 41, 49 and 57. The three lines are byte-identical between the two packages, so they moved only because the file was edited around them.

    On how long this has been live: 28.5.3 through 28.5.9.1 is eight releases. I have the packages for 28.5.3 to 28.5.7 and for 28.5.9.1 and checked the gate in each of those six. I could not obtain 28.5.8 or 28.5.9 through the update endpoint, but the three lines are byte-identical either side of them.

    Happy to write the change out line by line in this thread if that is useful to whoever picks it up.

    One note on presentation: this site's firewall rejects posts and uploads that contain code, which is why everything above is described rather than quoted.

  • Hi,

    The fix we prepared caused other issues. We need to find an appropriate way to introduce this correction.

    Please follow our changelog regarding this matter.

    https://support.muffingroup.com/changelog/


    Thanks

Sign In or Register to comment.
This website uses cookies

We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you’ve provided to them or that they’ve collected from your use of their services.

Cookies are small text files that can be used by websites to make a user's experience more efficient.

The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This means that cookies which are categorized as necessary, are processed based on GDPR Art. 6 (1) (f). All other cookies, meaning those from the categories preferences and marketing, are processed based on GDPR Art. 6 (1) (a) GDPR.

This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.

You can at any time change or withdraw your consent from the Cookie Declaration on our website.

Learn more about who we are, how you can contact us and how we process personal data in our Privacy Policy.

Please state your consent ID and date when you contact us regarding your consent.