[2.x] fix: distinguish a missing announcement excerpt from an empty one - #4902
Merged
Conversation
The announcements fetcher read each excerpt from the `firstPost` include and ran it through `makeExcerpt()` regardless of whether that post arrived. With no post, `Arr::get(null, ...)` yields `''` and the excerpt became an empty string — the same value a post with no text would produce. That is how the admin announcements widget came to render every card blank without anyone noticing: the response looked well-formed and said, in effect, "these announcements have no content". The actual fault was upstream, where fof/gamification had narrowed the `firstPost` eager load and stopped the include being serialized at all. The excerpt is now null where the post never arrived, and an empty string only where the post is genuinely empty. The widget already guards on a falsy excerpt, so nothing renders differently — but a future recurrence is legible instead of silent. Tests: that the request asks for the relationships the excerpt and author are read from — nothing asserted that before, so a lost include would not have been noticed; that a missing include yields null; and that an empty post still yields an empty string, so the distinction holds in both directions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The announcements fetcher read each excerpt from the
firstPostinclude and ran it throughmakeExcerpt()whether or not that post arrived:With no post,
Arr::get(null, …)yields'', so the excerpt became an empty string — indistinguishable from a post that genuinely has no text.That is how the admin announcements widget came to render every card blank without anyone noticing. The response looked well-formed and said, in effect, "these announcements have no content". The real fault was upstream:
fof/gamificationhad narrowed thefirstPosteager load on the discussion index, so discuss.flarum.org stopped serializing the include at all (fixed in FriendsOfFlarum/gamification#169).Since every Flarum forum pulls this endpoint, that single upstream change blanked the widget everywhere.
The change
excerptis nownullwhere the post never arrived, and''only where the post is genuinely empty.Nothing renders differently —
AnnouncementItemalready guards with{a.excerpt && …}— but a recurrence becomes legible rather than silent. TheAnnouncementDatatype is updated to match, since it can now be null.Tests
Three added. The existing ten all hand-build their own
includedarray, so none of them could notice the request losing itsinclude, nor the include coming back empty — which is exactly the gap this fell through.includecontainsfirstPostanduser, via a Guzzle history middleware. Passes today; would have caught a lost include.Failed asserting that '' is null). I checked by reverting it.Core unit suite green: 405 tests. Also drops a deprecated
ReflectionProperty::setAccessible()call flagged on PHP 8.5, taking the suite's deprecation count from 2 to 1.