therealworld / adminer-module
Integration of the database tool Adminer (https://www.adminer.org/) into the OXID backend
Package info
bitbucket.org/therealworld/adminer-module
Type:oxideshop-module
pkg:composer/therealworld/adminer-module
Requires
- php: ^8.3
- oxid-esales/oxideshop-ce: >=v7.4
- therealworld/tools-plugin: >=v3.2
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- v2.x-dev
- v2.1.1
- v2.1.0
- v2.0.28
- v2.0.27
- v2.0.26
- v2.0.25
- v2.0.24
- v2.0.23
- v2.0.22
- v2.0.21
- v2.0.20
- v2.0.19
- v2.0.18
- v2.0.17
- v2.0.16
- v2.0.15
- v2.0.14
- v2.0.13
- v2.0.12
- v2.0.11
- v2.0.10
- v2.0.9
- v2.0.8
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.0.28
- v1.0.27
- v1.0.26
- v1.0.25
- v1.0.24
- v1.0.23
- v1.0.22
- v1.0.21
- v1.0.20
- v1.0.19
- v1.0.18
- v1.0.17
- v1.0.16
- v1.0.15
- v1.0.14
- v1.0.13
- v1.0.12
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- dev-master
This package is auto-updated.
Last update: 2026-10-27 19:31:39 UTC
README
Deutsche Fassung: README.de.md

description
Opens Adminer (version 6.1.2, MySQL build, German interface) from
the OXID backend. Server, database user and database name are taken from the shop's
config.inc.php and filled in; the database password still has to be typed into the Adminer
login. The module adds no settings.
- Composer package:
therealworld/adminer-module - OXID module id:
trwadminer
Requirements and installation
- OXID eShop CE
>=v7.4, PHP^8.3 therealworld/tools-plugin>=v3.2- Apache with
.htaccesssupport recommended (see Limits)
composer require therealworld/adminer-module
vendor/bin/oe-console oe:module:activate trwadminer
Usage
Backend menu Service → DB Adminer.
On the first call the module copies the bundled Adminer files into the shop's document root at
<sShopDir>/admin/Adminer/, renames the Adminer entry file to a random name (<uid>.php) and
writes an .htaccess next to it that only allows that one file (Apache 2.4 Require syntax,
with an Order/Allow fallback for Apache 2.2). The backend then redirects to
<sShopURL>/admin/Adminer/<uid>.php?server=...&username=...&db=.... Later calls reuse the
copy as long as the .htaccess exists and the copy still matches the shipped files: every
call compares a fingerprint of src/Adminer/ (file names and contents) with the one stored in
the copy (.trwadminer-fingerprint). After a module update that changed Adminer or the plugin,
the next call deletes the old copy and creates a new one with a new random file name.
The bundled Adminer plugin (adminer-plugins/OxidExtension.php):
- lists only the shop database in the database selection (cosmetic, not an access restriction — Adminer still accepts anything the database user may see)
- sends
X-Frame-Options: SameOrigin, so Adminer can be shown inside the backend frame - uses
<sShopDir>/import/adminer.sqlas the file for Adminer's "import from server" function
Binding to the backend login
The copy only runs for browsers that opened it through the backend. Every call of
Service → DB Adminer (reachable for logged-in admins only) creates a random token and sets it
as cookie trwadminer_access (HttpOnly, SameSite=Strict, Secure on https, path limited to
the copy directory /admin/Adminer/). The copy stores only the SHA-256 hash of the token with
its expiry (.trwadminer-tokens.php, one entry per token; expired entries are removed when the
next token is issued, at most 100 entries). Several admins and browsers therefore work
independently.
Before Adminer starts, adminer-guard.php checks the cookie against the stored hashes
(hash_equals) and their expiry, without loading OXID. If the cookie is missing, invalid or
expired, the copy answers 403 with a short hint to the menu entry. The check sits in the entry
file as well as in adminer-plugins.php, which Adminer loads before it connects, so it also
applies when adminer-de.php is called directly.
- Expiry: fixed 2 hours from opening the menu entry; using Adminer does not extend it. Afterwards call Service → DB Adminer again, which issues a new token and overwrites the cookie.
- Logout: logging out of the OXID backend does not revoke the token, it stays valid until it
expires (the cookie expires at the same time). Adminer's own logout only ends the database
login. To invalidate all tokens at once: deactivate/activate the module (deletes the copy) or
delete
admin/Adminer/.trwadminer-tokens.php.
Activating and deactivating the module deletes the copy in admin/Adminer/ completely; the
next call creates a new one with a new random file name.
Limits
- The copy and the
.htaccesssit in a public directory. Web servers that ignore.htaccess(e.g. nginx) do not restrict the directory; the files of the copy can then be called directly. Adminer itself still only starts with a valid token (see above), and the token store is a PHP file withexitin its first line that holds hashes only. nginx does serve the fingerprint (.trwadminer-fingerprint) then, unless it blocks dot files. - The cookie is set by the backend and only applies to its host. If the backend runs on a host
other than
sShopURL(e.g. its ownsAdminSSLURL), the cookie does not reach the copy and the copy answers403. - The binding is to the browser, not to the backend session: a stolen cookie stays valid until it expires (see Logout).
- The paths are built from
sShopDir/sShopURLplus a fixed/admin/. A shop whose admin directory is named differently has to overrideAdminerConfig::getAdminerPath().
Updating Adminer (maintainers)
- Download the MySQL/German build from adminer.org.
- Replace
src/Adminer/adminer-de.phpwith it (keep the file name, or adjust theincludein the wrappersrc/Adminer/36ba9de7be2f8a24dc54424f309d8bc0.php). The wrapper's file name is irrelevant for the shop: it is renamed to a random name when it is copied. - Nothing else to do in the shop: the next call of Service → DB Adminer notices the changed files and replaces the copy.
For developers
- Controller
AdminerController(TheRealWorld\AdminerModule\Application\Controller\Admin, controller keyadminercontroller, lowercase as inmenu.xml): checks the fingerprint, copies, randomises, issues the access token and redirects inrender(); on a copy or token error it shows the error template@trwadminer/admin/error. AdminerAccessToken: issues tokens (cookie, hash store, lifetimeLIFETIME). The checking sidesrc/Adminer/adminer-guard.phpruns without OXID and has to keep cookie name, file name and format in sync.AdminerConfig: source path (src/Adminer/), target path and target URL. OverloadgetAdminerPath()for a non-standard admin directory.AdminerEvents:onActivate/onDeactivateremove the copy.src/Adminer/adminer-plugins.phpis loaded by Adminer itself and registersOxidExtension.- No database tables, no migrations, no class extensions.