# CPalius CMF 2.2.11

**Released:** 2026-09-25 · **Channel:** stable · **Critical:** yes

Turkish: [2.2.11-tr.md](2.2.11-tr.md)

Deleting a module's files by hand (instead of deactivating it first) could take down unrelated pages, and a query-budget guard was tripping on pages that had nothing to do with the feature it was protecting. Both traced back to the same root pattern: several places read the same piece of state independently instead of through the one path built to be safe, so a fix applied to one of them left the others exposed. This release closes both.

## What's fixed

**Deleting a module's files without deactivating it first could crash unrelated pages instead of being safely ignored.** The module health check trusted PHP's `class_exists()` to tell it whether a module's code was still there. Under `composer install --optimize-autoloader` (what every packaged release runs), `class_exists()` reads a static classmap generated once, not the actual filesystem — so it kept reporting a deleted module's class as present long after the files were gone, only failing later and uncaught, the moment something actually tried to use it (a template rendering that module's views, a class another module still referenced directly). The check now verifies the file is actually on disk first. A module whose files are removed by hand is now quarantined immediately and cleanly, the same as any other broken module, instead of crashing whatever page happens to touch it next.

**The Forum module rendered every post through a class that lived in the Importer module.** Forum's post-rendering path called Importer's BBCode-cleanup converter unconditionally, on every post, regardless of whether that post was ever imported — a permanent, undeclared runtime dependency on a module Forum's own manifest never listed as required (Importer already declares Forum as a dependency; the reverse was never supposed to exist). Forum posts stopped rendering entirely if Importer was ever removed. The converter now lives in Forum itself; Importer references Forum's copy, matching the dependency direction already declared in Importer's own manifest.

**A shared per-request query budget was being spent by code that didn't check whether anyone had already asked.** Seven separate places — four AACP dashboard widgets, the two listeners that read and write the origin cache on every request, and the Varnish response header listener — each queried the same performance-backend-status table independently instead of sharing the one request-scoped lookup already built for exactly this. On a single request touching more than a couple of these, the combined query count could exceed the safety budget meant to catch runaway lazy-loading elsewhere, and the failure surfaced on whatever ran last — most often the origin cache write, silently, with no visible error to the visitor. All seven now share one lookup per request.

## Upgrade notes

No schema changes. No manual steps.

## Known limitations

This does not, on its own, repair a production install where a module was already deleted with an old build's classmap still in place — regenerating that classmap requires either restoring the deleted files temporarily or applying this update through a path that replaces `cp-includes/vendor` (a full-release update, not a hand-copied file). See the upgrade guidance that accompanied this release for your specific situation.
