XOOPS 2.7.3 Beta 1 is ready for testing. It pairs a set of stability and security fixes with new diagnostic tooling — a persistent, opt-in log that records what the in-page debug panel cannot.
Download: https://github.com/XOOPS/XoopsCore27/releases/tag/v2.7.3-Beta1
The headline addition is a persistent file log. XOOPS has always been able to show notices, warnings, errors and SQL to an administrator in the debug panel — but only on a page that actually renders. When a request dies before output, fails only for a guest, or misbehaves only under real traffic, there was nothing to read afterwards.
The new logger records all of it to xoops_data/logs/debug.log, with a backtrace on every entry:
===========[2026-07-28 03:06:31] ================ WARNING ================
errstr = Attempt to read property "value" on null
errfile= /caches/smarty_compile/12f84838_..._themes_item.tpl.php
errline= 110
-------
uri: /modules/themes/item.php?itemid=18
messages.WARNING req=fc006e1d uid=19563
errno=2
/caches/smarty_compile/..._themes_item.tpl.php:110 XoopsErrorHandler_HandleError()
/class/theme.php:601 fetch()
/footer.php:51 render()
/modules/themes/item.php:256 require_once() Each entry opens with a labelled rule — QUERY ERROR, EXCEPTION, ERROR, WARNING, NOTICE, DEPRECATED — so you can see what you are looking at before reading a word, and what failed and where sits directly under the timestamp.
If you maintain a module, this closes most of the gaps where a bug used to be invisible:
queries_with_errors_only defaults to true; turn it off and you get every statement with its execution time — enough to find an N+1 without installing anything.req=...) on each line, so interleaved requests under real traffic can be told apart.DEPRECATED entries rather than drowning in general noise.XOOPS_DB_LEGACY_LOG reports deprecated Criteria forms and queryF() used for writes — a checklist for bringing an older module up to date.Some of the fixes listed below were found by installing DebugBar and simply looking at what a page was doing. Its query panel is blunt about things no error log will ever report, because none of them are errors:
SELECT * FROM groups queries on a single page. Nothing failed. Nothing warned. The query panel just showed the same statement 48 times, which is the whole diagnosis.If you maintain a module, this is the most direct way to find that class of problem in your own code — an N+1 in a loop, a query built in a template, a listing with no index behind it. They are invisible until something plots them per request, and then they are obvious.
DebugBar is a separate, optional module: it moved to its own distribution in 2.7.1 and installs from XoopsModules27x/debugbar. The php-debugbar and Monolog libraries stay bundled in xoops_lib, so there is no Composer step on your side.
It also stacks with the new file log rather than competing with it — both register with the same XoopsLogger seat and receive identical events. DebugBar shows you the page you are looking at; the log keeps what you cannot look at, such as the request that died before output. Using both is the intended setup.
Debug settings now live in one place instead of being edited into mainfile.php:
xoops_data/data/debug.dist.php -> copy to xoops_data/data/debug.php Nothing changes until you create that file. Only the .dist template ships. An absent or malformed debug.php leaves XOOPS in its normal production behaviour, so upgrading cannot switch debugging on by accident.
The log holds real data. SQL, user ids, backtraces and file paths. XOOPS ships .htaccess files denying web access, but those work on Apache only — on nginx, IIS, or Apache with AllowOverride None they do nothing. The logger therefore refuses to run while xoops_data sits inside the document root unless you explicitly accept the risk. The right answer is to move xoops_data outside the web root.
display_errors is not covered by debugLevel. The debugLevel setting in xoops_data/configs/xoopsconfig.php restricts debug output to administrators, but it does so *after* authentication, while display_errors is applied much earlier. Errors raised during bootstrap — the database connection, config loading, preloads — are still shown to any visitor. On a public site set display_errors to false and read the log instead; it captures that same window.
XoopsTextSanitizer::htmlSpecialChars() declared a string parameter while its body cast to string anyway, so any module declaring strict_types and passing an id, count or timestamp got an uncaught TypeError instead of coercion.xoops_getrank() fataled when no rank row matched — a deleted rank, a post count falling in a gap between ranks, or no ranks defined.TypeError. They now return the failure value they already document, and report the misuse so the calling module's bug stays visible.redirect_header() used the entity & as a query separator — which names the next parameter amp;xoops_redirect to anything parsing the URL. Chains such as ?start=0&%3Bamp%3Bamp%3Bforum=0 grew by a layer per hop.$redirect_page was only assigned when the request carried a redirect target, and the shipped xbootstrap5 profile form reads it without a guard, so simply opening the login page produced Undefined array key "redirect_page" and Attempt to read property "value" on null. It is now assigned unconditionally, which holds for custom themes too. A malformed redirect target also no longer discards itself entirely on the way through escaping.anon_canpost was only assigned on one branch. On a busy site this was the single largest source of log noise.SELECT * FROM groups queries per page removed by memoising the group list per request.Full details: docs/changelog.270.txt
This is a Beta. Please install it on a test site, not a production one.
The upgrade path carries the 2.7.3 schema changes, including the new comments index. If you are coming from 2.7.1 or 2.7.2, run the upgrade wizard as usual.
mainfile.php is not replaced by an upgrade. You do not need to touch it for the file logger — include/common.php reads debug.php itself. Updating mainfile.php from the new dist adds the XOOPS_DEBUG and XOOPS_DB_LEGACY_LOG constants and raises error reporting earlier than common.php runs, which only matters for failures during bootstrap.
That is what a Beta is for. Issues, with the relevant debug.log entry attached if you have one, to:
https://github.com/XOOPS/XoopsCore27/issues
Thanks to everyone testing.
|
|