Skip to content

Admin panel: on-demand database backups #57

@lewisgoddard

Description

@lewisgoddard

Part of the admin-panel expansion epic. Depends on Foundation.

Make the cron-only backup runnable + browsable from the panel.

Tasks

  • Extract the backup engine: move the dump logic out of bin/backup-database.php into src/functions/db.backup.phpdb_backup(array $settings, int $time): array returning ['ok' => bool, 'file' => ?string, 'error' => ?string] (instead of echo/exit). Preserve every current behaviour: the p:-prefix strip on db_host, the 0600 temp --defaults-extra-file, the two proc_open mysqldump passes (full minus peers rows, then peers schema only), and rotation by backup_rotate days. bin/backup-database.php becomes a thin wrapper that calls db_backup() and echoes/exits — cron behaviour unchanged.
  • List backups: src/functions/db.backup.list.phpdb_backup_list(), reusing the existing glob($backup_dir.$db_name.'.*.sql') pattern, returning name/size/mtime per file.
  • Controller/action/view:
    • src/controller/admin.backups.phpadmin_backups_controller() renders the page (list + "Run backup now" button).
    • src/controller/admin.backup.phpadmin_backup_action()process=backup; calls db_backup(), then task_log(..., 'backup', $time).
    • src/views/html.admin.backups.phpview_admin_backups_html().

Environment caveat (surface in the view)

db_backup() needs the mysqldump binary + proc_open available to the web user, and a writable backup_dir; show a clear error from the result array when unmet.

Optional — download a backup

Validate the requested basename strictly against db_backup_list() (no path traversal) before streaming.

Tests

DbBackupListTest; DbBackup is integration-ish (needs mysqldump) — test the result-shape contract and skip when the binary is absent.

Files

  • New: src/functions/db.backup.php, src/functions/db.backup.list.php, src/controller/admin.backups.php, src/controller/admin.backup.php, src/views/html.admin.backups.php.
  • Modified: bin/backup-database.php (thin wrapper).

Metadata

Metadata

Assignees

No one assigned

    Priority

    ⚠️ Medium

    Effort

    😏 Medium

    Stage

    👍 Confirmed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions