Repository navigation
4.3.0
Improvements
Standalone admin backend
A self-contained Bootstrap 5 + Font Awesome 6 admin UI that runs alongside any host app. Default-on for fresh installs, opt-out via FileStorage.adminLayout.
- New dashboard at
/admin/file-storagewith stats cards (total files, bytes, orphan rows, adapter count) plus tables for top collections, models, adapters, mime types, largest files, and recent uploads. - New cleanup workflow at
/admin/file-storage/cleanup: scope by model/collection, run dry-run preview (orphan rows, orphan files on disk, rows with missing backing files), then execute. SameService\CleanupServicepowers the existingfile_storage cleanupCLI. - Bulk delete on the file listing — checkbox column, master toggle, summary flash. CSP-safe (no inline handlers).
- Queued variant regeneration: per-row button on the listing and on the detail page. Enabled when
dereuromark/cakephp-queueis loaded, gracefully disabled with a tooltip otherwise. - Filter bar on the file listing covering model, collection, mime prefix, filename substring, foreign key, min size (MB), and
createddate range. Native CakePHP only — nofriendsofcake/searchdependency. - Download action (
/admin/file-storage/download/:id) that streams files via the configured Flysystem adapter, so it works for Local, S3, and any other adapter. Supports?variant=nameand?inline=1. - File detail view (
/admin/file-storage/view/:id) gains a Variants table with image thumbnails, per-variant on-disk size (probed via the adapter), present/missing state badges, and download / open-inline buttons.
Fail-closed admin access gate
- New
FileStorage.adminAccessconfig gate on the admin controllers. Every admin action (index/view/edit/delete/cleanup/deleteBulk/regenerateVariants/download) returns 403 until the host explicitly opts in. Two supported opt-ins:'adminAccess' => true— trust an upstream gate (Authentication+Authorization plugin, TinyAuth, custom middleware) on theAdminprefix.'adminAccess' => fn (\Cake\Http\ServerRequest $request) => $request->getAttribute('identity')?->is_admin === true— evaluate authorization inline, no auth plugin required.
- Closure exceptions are logged and converted to a generic 403 — the gate must not leak internal error detail to unauthenticated callers.
New config keys
FileStorage.adminAccess— see above.FileStorage.adminLayout—null(default) uses the bundledFileStorage.file_storagelayout;falsefalls back to the host's default;stringsets a custom one.FileStorage.standalone—trueskips the host'sApp\Controller\AppController::initialize()chain for projects without their own admin shell.
config/app.example.php and docs/Documentation/Installation.md document each key with the available choices.
BC notes
- Admin access is now fail-closed. Consumers who previously relied on the host gating the
Adminprefix must add'adminAccess' => true(or a closure) under theFileStorageconfig block on upgrade — without it, every admin request returns 403. This is the intended posture: misconfiguration that previously silently exposed the file_storage table now fails loudly. - Admin UI now ships its own layout by default. Setting
'FileStorage.adminLayout' => falsekeeps the pre-4.3 behaviour (host's default layout). New routes (/admin/file-storagedashboard,/admin/file-storage/cleanup,/admin/file-storage/download/:id) are additive — no existing route URLs change.
Full Changelog: 4.2.0...4.3.0