Skip to content

Document why getClass existed, and which of it and new is right where - #187

Merged
mastacontrola merged 1 commit into
masterfrom
docs/getclass-vs-new
Sep 7, 2026
Merged

Document why getClass existed, and which of it and new is right where#187
mastacontrola merged 1 commit into
masterfrom
docs/getclass-vs-new

Conversation

@mastacontrola

Copy link
Copy Markdown
Member

The plugin docs already tell a plugin author what to write (PR #182). What was missing is the overarching version you asked for: what changed, why the factory existed in the first place, and the rule for choosing between the two.

New page: development/naming-a-classNaming a Class — new and getClass.

Why the "why it existed" half matters

Without it the change reads as a style preference someone imposed. It was not. FOG's move into namespaces renamed 226 files and the tree had to keep working after every commit; one function turning a bare name into whatever the namespace happened to be that week is exactly the right tool for that job. 459 literal call sites across 120 files went through the entire migration unedited — the project's own refactor brief called it the reason the migration was tractable.

It stopped earning its keep when the migration finished.

Why the literal form went

  • The type was erased. @return object|mixed means nothing can check what you do with the result. Converting the tree surfaced 90 PHPStan errors on a baseline that reported zero — every one pre-existing and previously unreachable.
  • It was never a substitution seam, which is the usual argument for keeping a factory. qualify() consults core's map before the plugins', so a bare name could only ever resolve to one class.

The rule, as a table

Naming the class... Write
Literal, inside packages/web/src use import + new Host()
Literal, no-namespace file or anywhere in fog-plugins new \FOG\Items\Host()
Variable — a name from a URL, the API, or a config row self::getClass($name)
Default properties rather than an instance self::getClass($name, '', true)

Plus the two literal forms that survive because they have no new equivalent at all, how the gate enforces it, and bin/getclass-to-new.php for re-running the sweep on a plugin tree or a long-lived branch.

Numbers

Verified against the current tree rather than taken from ADR 0043: 43 variable-named sites remain in packages/web/src, and tests/getclass-literals.test.php reports 3 literals in 2 distinct names, which are the surviving forms.

Also adds install-script-architecture and fos-release-workflows to the Development index, which had been listing six of its eight pages.

Verification

docs:build clean · check-anchors 0 broken (including the path-qualified anchor into plugin-development) · check-version-split consistent · node --test 63/63 · show-nav places the page · no unparsed wikilink.

🤖 Generated with Claude Code

https://claude.ai/code/session_014PabMCuXYVRKbye7RAHaBC

The plugin docs already tell a plugin author what to write. What was
missing is the overarching version: what changed, why the factory existed
in the first place, and the rule for choosing between the two.

The "why it existed" half matters most, because without it the change reads
as a style preference someone imposed. It was not. FOG's move into
namespaces renamed 226 files, the tree had to keep working after every
commit, and one function turning a bare name into whatever the namespace
happened to be that week is exactly the right tool for that -- 459 literal
call sites across 120 files went through the whole migration unedited.
The project's own refactor brief called it the reason the migration was
tractable. It stopped earning that keep when the migration finished.

The "why it went" half is the evidence: a factory declared
@return object|mixed erases the type, so converting the tree surfaced 90
PHPStan errors on a baseline that reported zero, every one pre-existing and
previously unreachable. And it was never a substitution seam, which is the
usual argument for keeping a factory -- qualify() consults core's map before
the plugins', so a bare name could only ever resolve to one class.

The rule, as a table: a literal gets new (imported inside packages/web/src,
fully qualified in a file with no namespace and throughout fog-plugins); a
variable gets getClass(), which is the one shape new cannot express and is
what the function is now for. Plus the two literal forms that survive
because they have no new equivalent at all.

Numbers verified against the current tree rather than taken from the ADR:
43 variable-named sites remain in packages/web/src, and the gate reports 3
literals in 2 distinct names, which are the surviving forms.

Also adds install-script-architecture and fos-release-workflows to the
Development index, which had been listing six of its eight pages.

Verified: docs:build clean, check-anchors 0 broken (including the
path-qualified anchor into plugin-development), check-version-split
consistent, node --test 63/63, show-nav places the page, no unparsed
wikilink.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014PabMCuXYVRKbye7RAHaBC
@mastacontrola
mastacontrola merged commit af96630 into master Sep 7, 2026
@mastacontrola
mastacontrola deleted the docs/getclass-vs-new branch September 7, 2026 00:46
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