Skip to content

fix: restore the separators the language file conversion dropped - #6457

Open
e107help[bot] wants to merge 8 commits into
masterfrom
e107help/6331
Open

fix: restore the separators the language file conversion dropped#6457
e107help[bot] wants to merge 8 commits into
masterfrom
e107help/6331

Conversation

@e107help

@e107help e107help Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Why

Fixes #6331.

31e7d1d3b06e012a2c299cb0f6b3d98d860d7dad ("Issue #5465 Core language files converted", 4 April 2025) rewrote the core language files from define() calls to returned arrays. 168 of the constants it moved carried a leading or trailing space, and not one of them came out with it. Where a call site leaned on that invisible space, the words now run together.

A visitor meets four of them. Who's Online reads Guests:3, Members:2; the search flood message reads Sorry, search is restricted to one search every30seconds.; a reply page titles itself Replying to:Hello everyone; and two subject lines leave the site altogether as Emailed item fromMy Site and Password reset fromMy Site. The rest are admin-side, mostly a label glued to the value it introduces.

The count in the issue needs correcting. #6331 says 62 call sites. It is 67, and the difference is in both directions:

What Changed

67 call sites across 23 files get a literal space in the concatenation. Eight commits, grouped by what a reader meets rather than by file.

The language files are deliberately untouched. A trailing space inside a translatable string is invisible to whoever translates it, gets trimmed by tooling, and every shipped pack would then need the same invisible space to stay correct. The separator belongs to the layout, so it goes in the layout.

A constant padded at the front gets its space in front of it: LAN_SEARCH_18, LAN_MAILOUT_70, LAN_MAILOUT_241, RL_LAN_057, EMOLAN_35, LAN_NOTWRITABLE and LANINS_038. EPL_ADLAN_72 was padded at both ends and gets one on each side.

Two things stay out on purpose:

How It Was Tested

Three tests, each proven to fail on the unfixed source by reverting it and re-running, never by reading:

  • e107_tests/tests/unit/onlinePageTest.php renders online.php in a booted subprocess and asserts each count is separated from its label, including the most-ever-online line. It persists and restores the tracking preferences it needs rather than setting them after boot, where nothing would read them.
  • e107pluginTest::testDependencyFailuresAreSpacedFromTheirValues calls XmlDependencies() with a missing plugin, a missing extension, an extension below its required version, an impossible PHP version and an impossible MySQL version. The extension-version case is there for EPL_ADLAN_72, the one constant in this change padded at both ends and so the only one that can be wrong in two directions.
  • notifyTest::testUserVerificationLinesAreSpacedFromTheirValues captures the user verification notice and asserts all three lines are separated from their values.

The remaining sites have no practical test and were verified by reading, one at a time: the concatenation at the call site, against the constant's original padded value taken from the parent of 31e7d1d3b0. That covers the update log, the admin page messages and the search flood message. No claim is made that any of them was rendered in a browser.

The search flood message was given a page-rendering test and the test was then withdrawn. Driving that branch needs the flood interval, the visitor's own address and a row in tmp to line up, and the result passed alone but not inside the shuffled suite. An order-dependent test misleads everyone who meets it later, so the line is read-verified with the rest rather than covered by a test that cannot be trusted.

The whole unit suite (2732 tests), the parse check and the downgrade fixed point all pass on the branch.

Backwards Compatibility

Rendered HTML gains exactly one space per site, which is the defect being fixed. Nothing else about the markup changes: no tag, attribute or class list is touched, so a skin that has not been updated in a decade renders as it did before 31e7d1d3b0.

Shipped translation packs stay valid, because no language file changes. A pack translated after April 2025 carries unpadded strings and is now rendered correctly.

A pack that was never converted is worth stating plainly rather than leaving to be discovered. The loader still accepts an old-style define() pack and lets its values win, so on such a site the pack's own padding remains and the new literal space makes two. HTML collapses that everywhere except four plain-text sites: the three email subjects at fpw.php#L379, email.php#L182 and mail_manager_class.php#L971, and the notification body at notify_class.php#L342-L344. A recipient on an unconverted pack sees Password reset from My Site with a double space. That is the deliberate trade: a doubled space on a pack that has not caught up, against words run together on every pack that has. Putting the padding back in the language files would invert it, and that is the option being refused.

release/v2.3.x is not affected and must not be twinned. That branch never took 31e7d1d3b0, still ships "Guests: ", "Password reset from " and the rest, and renders correctly today. Applying this change there would double every space. Anyone tempted to finish the job should measure against that branch's own language pack first.

Sixteen of the changed lines are update log bodies, plus the ADMIN_01 and USET_15 entries. Core renders those bodies rather than parsing them, and no bundled plugin matches on them, so nothing in this tree reads the shape that changed. A third-party log shipper pattern-matching on a LAN_UPDATE_* prefix would see one extra space.

Third-party themes and plugins that concatenate these constants themselves still show the run-together text. Core cannot reach those, and the fix in each case is the same single space.

AI Model

Claude Opus 5 (claude-opus-5), as e107help.

Checklist

  • The change is on master and does not belong on release/v2.3.x
  • Rendered HTML changes only by the space each site lost
  • No language file is modified
  • Regression tests fail without the fix
  • British spelling in prose and commit messages
  • Every citation pinned to a commit

ONLINE_EL1 ("Guests: "), ONLINE_EL2 ("Members: "), ONLINE_EL8 ("most ever
online: ") and OTHER ("Other page: ") each ended in a space until 31e7d1d
converted the core language files from define() calls to returned arrays and
dropped the padding from 168 constants. The page and its menu concatenate
those labels straight onto their values, so the block read "Guests:3,
Members:2" and a location read "Other page:/mypage.php".

The separator belongs in the concatenation, never back in the language file.
A trailing space inside a translatable string is invisible to whoever
translates it, tooling trims it, and every shipped pack would then need the
same invisible space to stay correct.

release/v2.3.x never took that commit. It still ships the padded strings and
still renders correctly, so this must not be ported there.
LAN_SEARCH_17 ended in a space and LAN_SEARCH_18 began with one until
31e7d1d dropped the padding from 168 core language constants. The two sit
either side of the interval, so a visitor who searched again too soon was
told "Sorry, search is restricted to one search every30seconds."

The separator goes in the concatenation, never back into a translatable
string. release/v2.3.x still has the padded strings and is not affected.
COMLAN_102 was "Replying to: " until 31e7d1d dropped the padding from 168
core language constants, so the reply page titled itself "Replying to:Hello
everyone".

The separator goes in the concatenation, never back into a translatable
string. release/v2.3.x still has the padded strings and is not affected.
LAN_EMAIL_3 was "Emailed item from " and LAN_09 was "Password reset from "
until 31e7d1d dropped the padding from 168 core language constants. Both
are concatenated onto SITENAME to build a subject line, so recipients got
"Emailed item fromMy Site" and "Password reset fromMy Site". These two are
the only affected sites that leave the site altogether.

The password reset subject also loses a pair of empty string concatenations
that were doing nothing.

The separator goes in the concatenation, never back into a translatable
string. release/v2.3.x still has the padded strings and is not affected.
EPL_ADLAN_70 to 75, 86, and 249 to 251 all carried their own padding until
31e7d1d dropped it from 168 core language constants. Each is concatenated
straight onto the name or version it reports, so an unmet dependency read
"Required plugin not installed:forum" and an extended field reported
"Adding Extended Field:location ...".

EPL_ADLAN_72 (" Version: ") was padded at both ends and gets a space on
each side.

The separator goes in the concatenation, never back into a translatable
string. release/v2.3.x still has the padded strings and is not affected.
LAN_UPDATE_14 and 20 to 26 each ended in a space until 31e7d1d dropped
the padding from 168 core language constants. Every one of them is
concatenated straight onto the version, table, field or preference it
names, so the update log filled with lines like "Start version:2.3.5" and
"Updating Table Structure:comments".

The separator goes in the concatenation, never back into a translatable
string. release/v2.3.x still has the padded strings and is not affected.
NT_LAN_UV_2 to 4, LAN_MAILOUT_23, 69, 70, 241, 244, 248 and 255 carried
their own padding until 31e7d1d dropped it from 168 core language
constants. Each labels a value that follows it, so the user verification
notice read "User ID:42", a completion subject read "Email sent:Newsletter"
and a recipient count read "5 matches, after3 duplicates stripped."

LAN_MAILOUT_70 and LAN_MAILOUT_241 are the mirror image, suffixes that used
to carry a leading space, so their separator goes in front of them.

The separator goes in the concatenation, never back into a translatable
string. release/v2.3.x still has the padded strings and is not affected.
The last of the call sites that leaned on padding 31e7d1d removed from
168 core language constants. Each label ran into the value after it:
the admin log's delete confirmation and its result, a page delete debug
message, an emoticon pack removal, the avatar list and its delete notice,
a language file overwrite, the news item information block, an admin
permissions log entry, a signup flood log entry, the language check's
unwritable file notice, and the installer's database stage title.

RL_LAN_057, EMOLAN_35, LAN_NOTWRITABLE and LANINS_038 are the mirror image,
suffixes that used to carry a leading space, so their separator goes in
front of them.

The separator goes in the concatenation, never back into a translatable
string. release/v2.3.x still has the padded strings and is not affected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The language-file conversion dropped the padding from 168 core strings

1 participant