Skip to content

refactor(globals): shrink the context to what actually carries state - #300

Merged
HugoFara merged 1 commit into
refactor/remove-dead-server-renderfrom
refactor/shrink-globals
Aug 30, 2026
Merged

refactor(globals): shrink the context to what actually carries state#300
HugoFara merged 1 commit into
refactor/remove-dead-server-renderfrom
refactor/shrink-globals

Conversation

@HugoFara

Copy link
Copy Markdown
Owner

Stack 3 of 6. Base: #299. Globals goes from 505 lines to 353.

Most of the file's bulk did nothing. Four things come out:

  • table() was the identity function — literally return $tableName;, left
    over from a configurable table prefix that no longer exists. It read as though
    it transformed the name, and HomeFacade carried a comment claiming it
    returned "properly prefixed" names. Its 185 call sites are now plain
    strings, and the literal concatenations that produced
    ('DELETE FROM ' . 'words') are folded into single literals.
  • query() forwarded one line to QueryBuilder::table(). Callers now say so.
  • The error-display flag was set to false by initialize() and never set
    true by anything; its single reader passed it straight to
    setErrorReporting(). That reader now passes false outright, which is what
    it always got. initialize() then had nothing left to do.
  • The mysqli handle lived in two placesConnection::$instance and
    Globals::$dbConnection — with getInstance() resyncing from the second on
    every call and setInstance() writing both. Connection now owns it alone
    and the Globals accessors delegate.

Two judgement calls worth a second opinion

The Globals::get/setDbConnection() accessors stay. 291 call sites use them
as an "is the database up?" probe, mostly test skip guards. Rewriting all of
them would be churn for its own sake — the duplicated storage was the problem,
not the name.

Connection::reset() now genuinely clears the handle instead of leaving a
copy for the next getInstance() to recover. This is the one behaviour change
in the PR. testResetClearsInstance was asserting the opposite of its own name;
it now asserts the clear and restores the shared connection for the rest of the
run.

What is deliberately left alone

The user context (currentUserId, multiUserEnabled, isCurrentUserAdmin) is
load-bearing: QueryBuilder reads it at lines 248/287/292/323/328 to scope
every query, so a repository that looks unscoped is in fact filtered. That is
now stated on the class as a security boundary rather than a setting. Threading
a UserId through every repository call is a much larger change where a partial
job is a data-leak bug, so it is not attempted here.

Also drops 29 Globals imports left unused by the above.

Stack: #298#2993#4#5#6

Globals had grown into a grab-bag where only some of the contents did
anything. Four things came out:

- table() was the identity function — `return $tableName;` — left over from
  a configurable table prefix that no longer exists. It read as though it
  transformed the name, and HomeFacade even carried a comment claiming it
  returned "properly prefixed" names. Its 185 call sites are now plain
  strings, and the literal concatenations that produced ('DELETE FROM ' .
  'words') are folded into single literals.
- query() forwarded one line to QueryBuilder::table(). Callers now say so.
- The error-display flag was set to false by initialize() and never set
  true by anything; its single reader passed it straight to
  setErrorReporting(). That reader now passes false outright, which is what
  it always got. initialize() had nothing left to do and is gone.
- The mysqli handle lived in both Connection::$instance and
  Globals::$dbConnection, with getInstance() resyncing from the second on
  every call and setInstance() writing both. Connection now owns it alone
  and Globals::get/setDbConnection() delegate. The accessors stay because
  291 call sites use them as a "is the database up?" probe; the duplicated
  storage was the problem, not the name.

One behaviour change falls out: Connection::reset() now genuinely clears the
handle instead of leaving a copy for the next getInstance() to recover.
testResetClearsInstance was asserting the opposite of its own name, so it now
asserts the clear and restores the shared connection for the rest of the run.

Also drops 29 Globals imports left unused by the above, and documents on the
class that the user context is a security boundary QueryBuilder depends on
rather than an ordinary setting.
@HugoFara
HugoFara force-pushed the refactor/shrink-globals branch from fc2449e to 0f24088 Compare August 30, 2026 22:14
@HugoFara
HugoFara merged commit 27ac193 into develop Aug 30, 2026
14 checks passed
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.

1 participant