Skip to content

[3.0] Limits a print page to one page of posts - #9672

Open
albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/printpage-page-limit
Open

albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/printpage-page-limit

Conversation

@albertlast

@albertlast albertlast commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Description

?action=printpage renders a whole topic in one request: one query for every message in it, each one parsed and held in memory at once, available to anyone who can read the board. Every other view that shows a lot of a topic at once is capped — the "All" view refuses a topic longer than enableAllMessages, a feed takes at most 255 items — and the print view was the exception.

This gives it the same treatment. A print page now shows as many posts as the admin is willing to show in the "All" view and pages through the rest, so a long topic is still printable in full but no single request builds all of it. Forums that never show "All" get a limit of 250 rather than none, since 0 in that setting means the link is off, not that a request may render anything it likes.

The rest follows from paging:

  • the page index and the text/images links carry the current start;
  • the poll prints once, with the first page, instead of on top of every page;
  • an out of range start redirects the way a topic page does;
  • the page links are plain text, because the print page loads neither the theme's icon CSS nor its JavaScript, so the usual arrows and the expanding page list would both be dead there. @media print already hides .print_options, so paper output is unchanged.

This came out of a request on the community forum, reporting that the print view is a favourite target for scrapers, residential proxy botnets and aggressive crawlers, which use it to pull entire threads past pagination and exhaust FastCGI slots on shared hosting.

Other ways this could be done

The limit is not the only answer, and it is not exclusive with any of these. It was picked first because it bounds what one request costs no matter who sends it, while the rest gate who may ask — and a scraper that registers an account, or rides a residential proxy, walks past a gate.

  1. A print_topic board permission. What the report asked for first, and the one that fits SMF's existing machinery best: per board, per membergroup, and the only way spider_group could be made to restrict the print view, since today there is no permission there to deny. It is a much wider change — an entry in Permission.php, rows in Sources/Db/Schema/v3_0/BoardPermissions.php, language strings, Topic::$permissions['can_print'], and a migration granting it to existing groups or every upgraded forum silently loses its print button. Note also that keeping upgrades non-breaking means granting it to guests, so "off for guests by default" would only ever be true of new installs.
  2. A "guests may not use the print view" setting, next to disable_print_topic. Cheapest of the lot, but it is a second ad-hoc setting covering a slice of what the permission system already models, and it leaves the request itself unbounded for everyone else.
  3. disable_print_topic, which exists today and turns the feature off for everybody. It is the only lever an admin has right now, which is rather the point of this PR.
  4. Nothing in core. SMF already sets robot_no_index on the page and disallows ?action=printpage in the robots.txt it generates, so a well behaved crawler is handled; the rest is an .htaccess or WAF matter. That is what the report was doing already, and what it asked not to have to do.
Testing
  • tests/Integration/Http/TopicPrintTest.php is the regression test. Before the change it fails with "the print page rendered the whole topic instead of one page of it — Failed asserting that 5 is identical to 2", and again on the missing page links.
  • tests/Unit/TopicPrintTest.php covers where the limit comes from, including the 0 fallback.
  • Whole suite green on MySQL and PostgreSQL via .docker/test.sh.
  • By hand on a running forum with the ceiling at 3 and a 7 post topic: 3 / 3 / 1 posts across .0, .3 and .6; ;images survives the page links; .2 redirects to .0, .999 to .6, .msg1 to .0; nothing logged in smf_log_errors.

Issues References (Fixes|Related|Closes)

  1. Related: the feature request this came from, https://www.simplemachines.org/community/index.php?topic=594998.0 — no issue has been filed for it here.

🤖 Generated with Claude Code

Every other view that shows a lot of a topic at once is capped. The "All" view
refuses a topic longer than enableAllMessages, and a feed takes at most 255
items. The print view took the lot: one query for every message in the topic,
each one parsed and held in memory, for anyone who could read the board.

It now shows the same number of posts the admin is willing to show in the "All"
view, and pages through the rest with a page index of its own. Forums that never
show "All" get a limit of 250 rather than none, since 0 there means the link is
off and not that a request may render anything it likes.

The rest follows from paging: the page index and the text/images links carry the
current start, the poll prints once with the first page rather than on top of
every page, and an out of range start redirects the way a topic page does. The
page links are plain text because the print page loads neither the theme's icon
CSS nor its JavaScript, so the usual arrows and the expanding page list would
both be dead there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
@github-actions github-actions Bot added Theme Topics Localization Language & internationalization Unit Testing labels Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Localization Language & internationalization Theme Topics Unit Testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant