SQL query profiler & controller action debugger. Instruments every database query and controller call, measures execution time, detects N+1 query patterns, and renders a collapsible debug panel at the bottom of the page.
Based on Debug Panel by denis92
- SQL Query Profiling — intercepts every
mysqliquery with execution time, caller class/method, file path, and parent action route - Controller Action Timing — measures total, view, and logic time for every controller action with timeline visualization
- Query→Action Linking — each SQL query is linked to the controller action that spawned it; Actions tab shows query count per route
- N+1 Detection — normalizes queries and highlights repeated patterns (e.g. same SELECT in a loop)
- View Timing — separately measures
$template->render()time, splitting each action into logic (green) and view (blue) on the timeline - Request Inspector — displays raw GET, POST, SERVER, and COOKIE data
- Debug Helpers —
xdump($value, 'label')andxdd($value)functions available in all controllers, models, and views; output appears in the Dumps tab - Twig Debug — enables
{{ dump() }}in Twig templates viaDebugExtension - Sortable & Filterable Tables — click column headers to sort, type in filter box to search
- Summary Bar — page load time, total query time, action count, peak memory, N+1 warning count
- Zero Overhead When Off — all instrumentation is guarded by
file_exists()checks (cached by PHP stat cache) - Dark Theme UI — Catppuccin Mocha color scheme, fully isolated from host page CSS via
all: initial+#dbgscoping - Resizable Panel — drag the resize handle to adjust panel height
- OCMOD-only Installation — no manual file editing required; patches are applied via OpenCart's built-in modification system
- OpenCart 3.0.x — 3.0.3.x
- PHP 7.4+
- Node.js 14+ (for building from source)
- Download the latest
ocXRay.ocmod.zipfrom Releases (or build it yourself — see Development) - In OpenCart admin, go to Extensions → Installer and upload
ocXRay.ocmod.zip - Go to Extensions → Modifications and click the Refresh button (top right)
- Go to System → Settings → Edit Store → Server tab
- Set "ocXRay Debug Panel" to Yes and click Save
The debug panel will appear at the bottom of every storefront page.
- Set "ocXRay Debug Panel" to No in Settings → Server and Save
- Go to Extensions → Modifications, find ocXRay, and click Delete
- Click the Refresh button to rebuild the modification cache
ocXRay uses OCMOD (OpenCart's built-in file modification system) to patch core files at runtime — without touching the originals:
| File | What it does |
|---|---|
system/library/db/mysqli.php |
Wraps query() with timing, backtrace, and parent action route tracking |
system/engine/action.php |
Wraps call_user_func_array() with timing, route, and view time save/restore |
system/library/response.php |
Appends debug panel to response before gzip; loads xdump.php |
system/engine/loader.php |
Times $template->render() for view vs logic breakdown |
system/library/template/twig.php |
Enables {{ dump() }} via Twig DebugExtension |
Additionally, four patches add a Yes/No toggle to admin → Settings → Server:
- Write/delete the
ocxray_enabledflag file on settings save - Pass the flag state to the settings template
- Render the radio toggle UI in the Server tab
- Add localized label strings
All 12 OCMOD operations are conditional on file_exists('ocxray_enabled') — zero overhead when disabled.
Instead of storing the enabled/disabled state in the database, ocXRay uses a flag file (ocxray_enabled in the OpenCart root). This avoids infinite recursion — since mysqli.php is patched to intercept every SQL query, checking a DB setting would trigger another intercepted query, creating an endless loop.
file_exists() is used for the check, which is cached by PHP's stat cache and adds effectively zero overhead.
Never enable ocXRay in production. The debug panel exposes:
- All SQL queries (including those with sensitive data)
- Full request data (GET, POST, SERVER, COOKIE)
- File paths from
debug_backtrace()(reveals server directory structure) - Peak memory usage and timing information
The panel is a development-only tool. Ensure the ocxray_enabled flag file does not exist on production servers.
npm install && composer installnpm run build # Build current version (with quality checks)
npm run build:patch # Increment patch version and build
npm run build:minor # Increment minor version and build
npm run build:major # Increment major version and build
npm run build:skip-tests # Build without quality checksThe build script (build.js) runs quality checks, updates version numbers in version.txt and install.xml, and packages everything into build/ocXRay.ocmod.zip.
npm run check-style # PHPCS (PSR-12)
npm run fix-style # Auto-fix with PHPCBF
npm run analyse # PHPStan level 5
npm run phpmd # PHP Mess Detector
npm run test # PHPCS + PHPStan
npm run test:all # All checks (PHPCS + PHPStan + PHPMD + PHPCPD + Psalm)
npm run lint:all # PHPCS + PHPStan + PHPMDVerify that OCMOD patches apply cleanly against a real OpenCart installation:
python tools/ocmod_test.py install.xml /path/to/opencart
python tools/ocmod_test.py install.xml /path/to/opencart --with-existing # Test with other installed mods
python tools/ocmod_test.py install.xml /path/to/opencart --with-existing --exclude some_modThe tool faithfully replicates OpenCart's OCMOD engine (admin/controller/marketplace/modification.php), generates diffs, and runs PHP lint on patched files.
├── install.xml # OCMOD modification file (12 operations)
├── upload/
│ ├── debug_after_index.php # Debug panel: PHP data processing + HTML/CSS/JS output
│ └── xdump.php # xdump() and xdd() debug helper functions
├── build.js # Build script: versioning, quality checks, .ocmod.zip packaging
├── tools/
│ └── ocmod_test.py # OCMOD patch simulator and verifier
├── stubs/
│ └── opencart_stubs.php # OpenCart class stubs for PHPStan static analysis
├── version.txt # Current version (single source of truth)
├── INSTALL.txt # Quick installation guide
├── composer.json # PHP dev dependencies (PHPCS, PHPStan, PHPMD, etc.)
└── package.json # Node.js dependencies (archiver for zip creation)
The built .ocmod.zip archive has a specific structure required by OpenCart:
ocXRay.ocmod.zip
├── install.xml # Must be at the root (NOT install.ocmod.xml)
└── upload/
├── debug_after_index.php
└── xdump.php
MIT
Yevhenii Starychenko — Telegram