История коммитов

.
fix(profile): lift and delete a ban only of somebody standing below
A ban was given downwards only but lifted by anybody holding the permission, so an administrator could end the ban the supervisor gave another administrator. Lifting a ban, deleting its record and clearing the history now ask the same as giving one (BanHierarchy), which also covers the ban of one's own, and the history offers those buttons only to whoever may press them.
.
fix(auth): let a ban close only what it is for
BanVoter refused every permission to an account under a ban of any kind, reading among them: a member banned from the guestbook for an hour could not open the forum, the library or the downloads, which a guest can, and a moderator banned from the library lost the panel. It now acts on the full ban alone and leaves such an account what a guest may do; the supervisor is not locked out. A ban of a section is asked for by that section.

Several places relied on that refusal and asked for no ban themselves. The forum refuses everything that writes in it to an account banned from it or from the site (ForumBanMiddleware on the routes of the signed-in visitor) and offers it no reply, edit or poll form. The library does the same for its articles, their changes and the votes (LibraryAccess), and the downloads take no upload from an account banned from the site (DownloadsAccess).
.
test(profile): record how the bans of an account are given and what they close
Pins the current behaviour before the bans are reworked, the odd parts included and marked as such: a ban of any kind refuses every permission, reading among them; a ban is lifted by anybody holding the permission; deleting a ban takes karma whether it cost some or not; clearing the history deletes the bans in force.
.
test(core): cover the generation of the sitemap and robots.txt
The generator and RobotsTxtUpdater take the public and cache directories as constructor arguments, PUBLIC_PATH and CACHE_PATH by default, so the tests write into a directory of their own instead of the robots.txt of the checkout.
.
ci: align the columns of the coverage table
Every cell is padded to the widest one of its column, so the table reads in a terminal as well. Markdown renders it the same as before.
.
test: measure the coverage locally with composer test:coverage
The script turns on the coverage mode of Xdebug itself, runs both suites and prints the same table by area that CI shows.
.
chore(i18n): drop the strings of the system only Counters used
"Unread" and "Last activity" belonged to the link Counters built for the unread topics of the forum, which is gone. The template of the forum follows the lines of the controllers that now count the unread topics through the forum itself.
.
refactor(homepage): let the modules supply the blocks of the home page
The home page picked the latest news itself and drew them itself, so homepage
depended on the news without declaring it — the last module that did.

A module now puts a block on the home page through
HomepageBlockProviderInterface, an extension point of the core: a template of
its own and the data for it. HomepageBlocks collects the blocks of the
switched-on modules, the lighter higher, and the home page includes them. The
latest news become a block of the news module, with its own template and the
settings it always had.

The characterization tests of the block pass unchanged. The baseline has no
dependency of the core on a module or of a module on another it does not
require left, and loses a call to a scope PHPStan could not see.
.
test(homepage): record the latest news the home page shows
Newest first, as many as the settings of the news ask for, only those of the last days when the settings say so, and none when the block is switched off. Pinned before the news start supplying the block themselves.
.
refactor(core): take what Counters knew of the modules out of it
With the sections of the menu and the notifications declared by their modules,
most of Counters had nobody to call it: the counters of the forum, the
guestbook, the downloads, the library and the albums, the news that were always
zero, and the forum(), downloads(), library(), album() and mail() of an older
time. They are gone, and with them the permissions of five modules the core
used to name.

The pages of the forum asked Counters for the unread topics through the
container. UnreadTopicsCounter of the forum counts them now, for those pages,
for the line of the menu and for the notification, which counted them twice
over.

What remains of Counters is the visitors online, the members and the scripts
of the analytics. The core depends on no module any more, and the five entries
of the baseline that said otherwise are gone.