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

.
refactor(session): complete stage 4a facade rollout
Replace remaining direct \ usage in modules with Johncms\Http\Session so data access stays unified before the 4b backend swap.

This avoids split storage risk during SessionInterface migration and updates the HTTP kernel migration plan to reflect 4a completion.
.
refactor(profile): replace raw $_SESSION with Session facade
3 files: SettingsController ($_SESSION['lng'] → set(), set_ok/reset_ok → flash()), EditProfileController (success_message → flash()), RestorePasswordController ($_SESSION['code'] → set/remove).
.
refactor(downloads): replace raw $_SESSION with Session facade
IndexController.php and DownloadCategoryController.php: $_SESSION['sort_down'] / $_SESSION['sort_down2'] → $this->session->get(..., 0) / $this->session->set(), lazy init via default argument dropped.
.
refactor(collections,system): replace raw $_SESSION with Session facade
Collections (4 admin controllers): $_SESSION['success_message'] → $this->session->flash()/getFlash(), removed pullFlash() helper.

System (4 files):
- Comments.php: $_SESSION['code'] → $this->session->set/get, fixed $owner type (bool→int) for isBlockedBy()
- TranslatorServiceFactory.php: $_SESSION['lng'] → $session->set/get/has, injected via $container
- Validator/Rules/Captcha.php: $_SESSION[$this->sessionField] → $session->has/get via di()
- Security/Csrf.php: $_SESSION['_csrf'][$token_id] → $this->session->set/get, constructor injection
.
refactor(admin): replace raw $_SESSION with Session facade
- 14 admin controllers now inject Johncms\Http\Session\n- Use session->flash()/getFlash() for success messages\n- All files are final readonly classes with constructor injection
.
refactor(news): replace raw $_SESSION with Session facade
- Inject Johncms\Http\Session into AdminController, AdminSectionController, AdminArticleController, Article

- Use flash()/getFlash() for success messages, set()/get() for delete_token and view tracking

- Remove redundant $services->set(Article::class) that lacked autowire

- Make Article final readonly with promoted constructor properties
.
refactor(system): remove PHP version check from bootstrap
Composer's autoloader already enforces the PHP version requirement via platform config, making this check redundant.
.
docs(plan): record stages 2c, 2d and 3b as done
Per-module notes for the 2c sweep, the 2d decision to keep compression in the
web server, and the 3b session/send() reasoning. Also records what was left
deliberately (BanIP, both UserFactory::userUnset(), the path-less cookie in
ChangePasswordController) and which stage picks it up.
.
feat(http): complete the kernel with a Response pipeline and terminate()
Stage 3b of the HTTP kernel migration.

MiddlewareInterface::handle() now returns a Response instead of mixed, across
all 15 implementations. To make that true at runtime and not just in the
signature, normalization moved inside the pipeline: the handler closure passed
to MiddlewareDispatcher::dispatch() calls ResponseNormalizer::normalize()
itself, and the dispatcher is typed on Response throughout. The transitional
controller contract (Response|string|null) is unchanged, it is just normalized
one step earlier.

The legacy status seam is gone with it. handleRaw() no longer reads
http_response_code() to build the status, and handle() no longer resets it to
200: after stage 2c no controller sets the status that way, the only remaining
callers being GlobalErrorHandler and the pre-kernel BanIP.

Kernel implements TerminableInterface. UserStat and the mail queue moved into
terminate(): both are post-response side effects the response does not depend
on. The mail queue condition is kept 1:1, including the isSuccessful() check.
public/index.php is down to handle() -> send() -> terminate().

send() is now the full one, with fastcgi_finish_request(). That is only safe
because handle() closes the session once the response is built (guarded by
PHP_SESSION_ACTIVE and non-console mode): PHP otherwise holds the session file
locked until shutdown, so the next request from the same visitor would queue
behind the mail batch running in terminate().

Refs: .claude/http-kernel-migration-plan.md stage 3b
.
refactor(http): drop the global output buffer
Stage 2d of the HTTP kernel migration.

news/Admin/AdminController::index() was the last controller writing to the
output directly; it now returns a Response. With that gone, the
ob_start('ob_gzhandler') block at the end of system/bootstrap.php can go too:
compression is the web server's job (nginx already has gzip on, and text/html
is compressed unconditionally). The buffer also masked premature output, which
would have silently sent headers and lost the status or the Location of the
Response being built.

The four ob_start()/ob_get_clean() pairs wrapping the legacy Comments class are
self-contained and do not depend on the removed global buffer.

Refs: .claude/http-kernel-migration-plan.md stage 2d