Skip to content

Fix factual errors, stale source links and broken anchors in the 2.x docs - #592

Open
karl-bullock wants to merge 3 commits into
flarum:mainfrom
karl-bullock:fix-2x-docs-accuracy
Open

karl-bullock wants to merge 3 commits into
flarum:mainfrom
karl-bullock:fix-2x-docs-accuracy

Conversation

@karl-bullock

Copy link
Copy Markdown
Member

I audited the 2.x documentation (the docs/ tree) against flarum/[email protected] at ed8a525 and fixed what I could verify as wrong. Every claim below was checked against the source rather than assumed.

Wrong API references

  • extend/model-visibility.md attributed a code sample to Flarum\Post\PostPolicy, which does not exist. The sample is verbatim from Flarum\Post\Access\ScopePostVisibility, and since the section is about scopers rather than policies, I repointed it there. PostPolicy does no query scoping at all.
  • extend/api.md said fields are removed "through the removeField method", but the extender method (and the code block directly beneath that sentence) is removeFields.
  • extend/forms.md said Flarum patches Mithril with the external m.attrs.bidi library. In 2.x bidi is part of core at framework/core/js/src/common/utils/bidi.js, applied by patchMithril.js, and is not a package dependency. The link was also truncated mid-URL with no closing parenthesis, and the repo it pointed at is gone.
  • contributing.md said "We use PHP 7 type hinting". Core requires ^8.3.
  • extend/testing.md linked a "PHPUnit annotations guide" in the same sentence that explains annotations no longer register tests, and that page is a 404 under PHPUnit 12. It now points at the attributes guide.
  • extend/models.md had two relationship examples written as new Extend\Model(User::class)->hasOne(...). Parenthesis-free new requires PHP 8.4, so those examples were a parse error on 8.3, which is the supported floor. I wrapped them to match every other example on the page.

Stale source links

22 links pointed into flarum/framework on main. That branch's HEAD is "Apply fixes from StyleCI" from 2024-06-21, so it serves 1.x-era code. Most of those paths still exist on 2.x, which means readers were being shown 1.x source for 2.x documentation instead of getting an obvious 404. A further 15 links pointed at the bundled extension repos on master, which is the 1.x subtree split (those repos default to 2.x now).

All of them now point at 2.x. Three files had been renamed or moved and needed a real target rather than a branch swap:

  • SimpleFlarumSearchTest.php was removed in the 2.0 search refactor. The workaround it was cited for (FULLTEXT indexing not happening inside a transaction) now lives in framework/core/tests/integration/api/discussions/ListWithFulltextSearchTest.php.
  • flarum/likes js/src/forum/index.js is now index.ts.
  • flarum/tags TagDiscussionModal.js is now TagDiscussionModal.tsx.

I left flarum/installation-packages/tree/main alone (that repo's default branch really is main), along with the two deliberate 1.x links in the upgrade guide.

Broken internal anchors

19 internal links pointed at anchors that do not exist. Six were in i18n.md alone, including #appendix-a:-standard-key-format, which keeps a colon the slugger strips, and #html-tags where the heading is "Adding HTML Tags" (line 7 of that same file already used the correct #adding-html-tags). admin.md#telling-the-api-about-your-extension was referenced from two pages although no such heading exists anywhere in the docs, so those now point at i18n.md#namespacing-translations, which is where the extension ID format is actually documented.

Laravel documentation links

Core requires illuminate/* ^13.0, but the docs linked laravel.com/docs/12.x 41 times, plus stray 9.x, 10.x and 11.x links and four api/11.x links. All now point at 13.x.

Dead external links

Fixed where the correct target was unambiguous: flarum.org/chat and flarum.org/discord/ (both 404) to discord.gg/flarum, Symfony's 5.2 translation pages to their current equivalents, the Intervention Image v3 upgrade guide, the ItemList API docs link (it used the old ESDoc URL shape rather than the TypeDoc one the rest of the docs use), the symfony/console ArrayInput link, and the docs URL in the composer.md example.

install.md accuracy

  • MySQL 5.7+ / 8.0.30+ became MySQL 5.7.8+, which is what DatabaseRequirements::MYSQL_MINIMUM enforces. I could not find anything in 2.0 that gates on 8.0.30.
  • The requirements list named only pdo_mysql on a page that documents SQLite and PostgreSQL support, so I noted that those engines also need pdo_pgsql or pdo_sqlite.
  • The Caddy example used a php7.4-fpm.sock socket on a page that requires PHP 8.3+.

Things I found but did not change

  • Flarum\Install\Installation::prerequisites() hard-requires the pdo_mysql extension even for a SQLite or PostgreSQL install. That looks like a core issue rather than a docs one, so I documented the additional driver requirement and left this for you to judge.
  • The requirements list also names curl and session. The installer checks neither, and I found no curl_* or session_* calls in core or the bundled extensions. Guzzle does prefer curl in practice, so I did not want to remove them on my own reading.
  • Five links are dead with no clear replacement: fluxbb.org (the domain no longer resolves, in README.md), the SMF2 migration script repo and the thegeekdiary.com permissions tutorial (install.md), and flarum.org/composer/ plus flarum.org/dashboard/subscriptions in extensions.md (those premium extension instructions look like they predate a flarum.org restructure).
  • console.md documents 10 commands. avatars:backfill-variants, avatars:convert-to-webp, schema:dump, extension:enable, bisect, queue:pause, queue:resume, announcements:refresh and extensions:sync-abandoned are all registered but undocumented.
  • The PHP API docs links use /php/master/. I checked and that alias does serve 2.x (2.0-only classes resolve, 1.x-only classes 404), so I left them as they are.

Verification

  • Every Flarum\* class reference in the docs was checked against the 2.x source: 107 distinct references, and the four that do not resolve are all deliberate (a Flarum\Discussions counter-example in contributing.md, the removed Flarum\Query and Flarum\Filter namespaces in the upgrade guide, and a Flarum\TYPE\Event placeholder).
  • All 105 documented flarum/{common,forum,admin}/... frontend import paths resolve to real files.
  • All 86 URLs this PR touches return 200.
  • Internal links and anchors were re-checked after the edits. The only remaining report is models.md#adding-new-models-1, which is correct: it is Docusaurus's suffix for the second "Adding New Models" heading.

I only touched docs/, nothing under i18n/ or versioned_docs/.

…docs

Audited the docs/ tree against flarum/[email protected] and corrected what could be verified against the source.

Wrong API references: model-visibility.md attributed a scoper sample to the non-existent Flarum\Post\PostPolicy (it is Flarum\Post\Access\ScopePostVisibility); api.md said removeField where the method is removeFields; forms.md credited the external m.attrs.bidi library for what is now core's own common/utils/bidi; contributing.md still said PHP 7 type hinting; testing.md linked a removed PHPUnit annotations page; models.md had two examples using parenthesis-free new, which only parses on PHP 8.4 and not on the 8.3 floor.

Stale source links: 22 links pointed into flarum/framework on main, whose HEAD predates 2.0, and 15 at the bundled extension repos on master, the 1.x subtree split. All repointed to 2.x, with real replacements for three files renamed or removed since 1.x.

Broken anchors: 19 internal links pointed at anchors that do not exist, including six in i18n.md and two references to a heading that exists nowhere in the docs.

Laravel links: core requires illuminate/* ^13.0, so the 12.x (and stray 9.x/10.x/11.x) documentation links now point at 13.x.

install.md: MySQL minimum corrected to 5.7.8 to match DatabaseRequirements, the PostgreSQL and SQLite PDO drivers noted alongside pdo_mysql, and the Caddy example moved off a PHP 7.4 socket.

Also fixed dead external links where the correct target was unambiguous.
@karl-bullock

Copy link
Copy Markdown
Member Author

Some existing issues I only found after opening this, in case they help with triage:

  • [2.x] docs mention php extension pdo_mysql #488 is exactly the pdo_mysql problem the install.md change here addresses: "This is only true when using mariadb or mysql." This PR notes that PostgreSQL and SQLite installs also need pdo_pgsql or pdo_sqlite. It does not cover that issue's second half, the PHP 8.4 package renames (php8.4-xml providing dom, php8.4-common providing fileinfo and tokenizer), since that is a packaging detail rather than a wrong requirement and I did not want to guess at how you would rather word it.
  • PHP session extension required. #470 asks for session to be added to the extension list, and it is already there on main, so that one looks resolved. Worth recording why it belongs: nothing in core calls session_*, but illuminate/session's FileSessionHandler needs SessionHandlerInterface from the extension, which is the fatal error in that report. I had wondered whether session and curl were over-listed and left both alone for exactly this reason.
  • 2.x javascript extender docs sometimes use return #497 reports admin.md alternating between export default [] and return []. Every one of those blocks on current main uses export default [, so that also appears to be already fixed.

Unrelated to the diff, but found while checking the same pages: Flarum\Install\Installation::prerequisites() requires the pdo_mysql extension unconditionally, including for a SQLite or PostgreSQL install. That looks like a core issue rather than a docs one, so this PR just documents the extra driver a non-MySQL install needs and leaves the behaviour alone.

The HTML tags section said "not all tags are passed as an argument, only those who have attributes". Attributes are not what decides it. Translator::autoProvidedTags() is a closed list (strong, code, i, s, em, sup, sub) that Flarum fills in for you; any other tag, including the <a> in the very example on that page, renders nothing unless a matching parameter is passed. Attributes are instead the reason to pass a parameter for a tag that is already on the list.

Relatedly, attributes in a locale string are not supported at all: preprocessTranslation() strips them and fires a debug warning, and no bundled locale file carries any. That constraint was undocumented, so it is now stated where someone writing a translation will meet it.

Also documented two things the page did not mention. trans() returns Mithril content rather than a string, so its third argument and flarum/common/utils/extractText are the way to get a plain string for an attribute, a title or a select option. And 'user' is a reserved parameter name: the translator extracts it as a User model and derives username from it, so {user} resolves to nothing, which is a confusing half hour for anyone who picked it as a variable name.
@karl-bullock

Copy link
Copy Markdown
Member Author

Pushed one more commit here, from a closer read of i18n.md against Translator.tsx. It belongs in this PR rather than a separate one, because this branch already edits the same regions of that file and two PRs touching them would conflict.

  • The HTML tags section said "not all tags are passed as an argument, only those who have attributes". Attributes are not the deciding factor. Translator::autoProvidedTags() is a closed list (strong, code, i, s, em, sup, sub) that Flarum fills in for you, and any other tag renders nothing without a matching parameter, including the <a> in the example directly above that sentence. Attributes are instead the reason you would pass a parameter for a tag that is already on the list.
  • Attributes in a locale string are not supported at all: preprocessTranslation() strips them and fires a debug warning. No bundled locale file carries any, so the rule is already being followed, it just was not written down.
  • trans() returns Mithril content, not a string. Its third argument and flarum/common/utils/extractText are how you get a plain string for an attribute, a title or a <select> option. Neither was mentioned.
  • user is effectively a reserved parameter name: the translator extracts it as a User model and derives username from it, so a {user} placeholder resolves to nothing. That is a confusing half hour for anyone who picks user as a variable name.

One thing I checked and deliberately left alone: the example passes the tag parameter as a vnode (a: <a href={...} />) rather than the function form the formatter now prefers. Core still uses the vnode form itself in EditGroupModal, relying on the compatibility layer, so the docs match reality and I did not want to document a form core does not use.

The PostLikedBlueprint sample declares none of the five methods' return types, while BlueprintInterface declares one on every method: ?AbstractModel, ?User, mixed, string and string. PHP permits a return type to be narrowed, never widened, and an omitted type counts as wider than a declared one, so copying the example gives "Declaration of PostLikedBlueprint::getSubject() must be compatible with BlueprintInterface::getSubject(): ?AbstractModel" rather than a working blueprint. Verified by compiling both the old and the corrected form.

The sample now matches the real class in flarum/likes, which also means constructor property promotion in place of two hand-declared properties, getData() returning null rather than falling off the end, and the AbstractModel import that getSubject()'s return type needs. A note explains why the types cannot be dropped, since omitting a return type reads like a tidiness choice rather than a hard requirement.

Everything else checked on this page: the driver example's send() and registerType() signatures already match NotificationDriverInterface exactly, and all four documented mail templates (mail::html.notification, mail::plain.notification, mail::html.information, mail::plain.information) exist as real view files.
@karl-bullock

Copy link
Copy Markdown
Member Author

One more commit here, found by a check worth describing because it is mechanical and repeatable.

After #603 turned up a documented class whose method signature was incompatible with the interface it implements, I extracted every documented implements/extends example across the docs and compared each method signature against the real parent. Two pages fail, and they fail fatally:

The blueprint declares none of its five return types, while BlueprintInterface declares one on every method (?AbstractModel, ?User, mixed, string, string). PHP allows a return type to be narrowed but never widened, and an omitted type counts as wider than a declared one, so this is a fatal error rather than an untidiness:

Declaration of PostLikedBlueprint::getSubject() must be compatible with
BlueprintInterface::getSubject(): ?AbstractModel

I confirmed that by compiling both the old and the corrected form against a stand-in of the real interface. Worth stressing that mixed behaves the same way: omitting a : mixed return type is equally fatal, which is unintuitive.

The sample now matches the real class in flarum/likes, which brings constructor property promotion in place of two hand-declared properties, getData() returning null rather than falling off the end, and the Flarum\Database\AbstractModel import that getSubject()'s return type requires. A note explains why the types cannot be dropped.

It is folded into this PR rather than opened separately because this branch already edits the lines just above that code block (the blob/master link on it), and a separate branch conflicted.

Two things on that page needed nothing, which is the useful half: the driver example's send() and registerType() signatures already match NotificationDriverInterface exactly, and all four documented mail templates (mail::html.notification, mail::plain.notification, mail::html.information, mail::plain.information) exist as real view files.

No other page in the docs has a signature mismatch.

This branch has not been deployed

No deployments
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