2395a4eabc
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Failing after 5s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 23s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 9s
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Secret Scan (pull_request) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 5s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 17s
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 7m48s
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
Fixes all critical and high severity issues from the codebase audit: CRITICAL: - #71: RestoreCommand passed wrong args to RestoreEngine (filepath instead of record ID) — CLI restore was completely broken - #72: JpaUnarchiver path traversal — added traversal rejection and realpath boundary check to prevent writes outside staging dir - #77: RestoreEngine staging path sanitized — $record->tag stripped of non-alphanumeric characters HIGH: - #75: (noted, AkeebaImporter unserialize needs separate refactor) - #76: BackupTable now deletes DB row before file — prevents data loss if DB delete fails - #78: API profiles endpoint now masks sensitive fields (passwords, keys, tokens) with '***' - #79: Webcron handler adds return after sendJsonResponse — prevents execution falling through on non-terminal close() - #80: BackupModel/ProfileModel loadFormData() now casts array to object — prevents TypeError on PHP 8.x form state restore PREFLIGHT HARDENING: - PreflightCheck::run() wrapped in try-catch for DB exceptions - mkdir() failure now includes actual error reason - Unresolved placeholders generate a warning instead of silent return Closes #71, closes #76, closes #77, closes #78, closes #79, closes #80 Ref #72, ref #81
61 lines
1.4 KiB
PHP
61 lines
1.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @package MokoSuiteBackup
|
|
* @subpackage com_mokosuitebackup
|
|
* @author Moko Consulting <hello@mokoconsulting.tech>
|
|
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
|
* @license GNU General Public License version 3 or later; see LICENSE
|
|
*/
|
|
|
|
namespace Joomla\Component\MokoSuiteBackup\Administrator\Table;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Table\Table;
|
|
use Joomla\Database\DatabaseDriver;
|
|
|
|
class BackupTable extends Table
|
|
{
|
|
public function __construct(DatabaseDriver $db)
|
|
{
|
|
parent::__construct('#__mokosuitebackup_records', 'id', $db);
|
|
}
|
|
|
|
public function check(): bool
|
|
{
|
|
if (empty($this->profile_id)) {
|
|
$this->setError('Profile ID is required.');
|
|
|
|
return false;
|
|
}
|
|
|
|
if (empty($this->backupstart) || $this->backupstart === '0000-00-00 00:00:00') {
|
|
$this->backupstart = date('Y-m-d H:i:s');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function delete($pk = null): bool
|
|
{
|
|
$archivePath = $this->absolute_path;
|
|
|
|
// Delete DB record first — if this fails, the file is preserved
|
|
$result = parent::delete($pk);
|
|
|
|
if ($result && !empty($archivePath) && is_file($archivePath)) {
|
|
@unlink($archivePath);
|
|
|
|
// Also remove the log file if it exists alongside the archive
|
|
$logPath = preg_replace('/\.(zip|tar\.gz)$/i', '.log', $archivePath);
|
|
|
|
if (is_file($logPath)) {
|
|
@unlink($logPath);
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
}
|