feat(backup): use real MokoSuiteBackup schema and prefer BackupStatusHelper (#208)
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Project CI / Lint & Validate (pull_request) Successful in 9s
Universal: PR Check / Validate PR (pull_request) Failing after 24s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 28s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: moko-platform CI / CI Summary (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
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Project CI / Lint & Validate (pull_request) Successful in 9s
Universal: PR Check / Validate PR (pull_request) Failing after 24s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 28s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: moko-platform CI / CI Summary (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
Update bridge to use correct column names (backupstart/backupend, status values: complete/fail/running/pending). Prefer the BackupStatusHelper API when available, with direct table query fallback for older MokoSuiteBackup versions.
This commit is contained in:
@@ -22,6 +22,10 @@ use Joomla\Event\SubscriberInterface;
|
||||
* Detects whether MokoSuiteBackup is installed and collects backup
|
||||
* status data for inclusion in heartbeat payloads to MokoSuiteHQ.
|
||||
*
|
||||
* Prefers MokoSuiteBackup's own BackupStatusHelper when available,
|
||||
* falling back to a direct table query if the helper class is missing
|
||||
* (e.g. older versions of MokoSuiteBackup).
|
||||
*
|
||||
* @since 02.34.84
|
||||
*/
|
||||
class Backup extends CMSPlugin implements SubscriberInterface
|
||||
@@ -90,6 +94,9 @@ class Backup extends CMSPlugin implements SubscriberInterface
|
||||
/**
|
||||
* Get backup status summary from MokoSuiteBackup.
|
||||
*
|
||||
* Prefers the BackupStatusHelper API when available. Falls back
|
||||
* to a direct database query for compatibility with older versions.
|
||||
*
|
||||
* @return array Backup status data for heartbeat inclusion.
|
||||
*/
|
||||
public function getBackupStatus(): array
|
||||
@@ -101,12 +108,22 @@ class Backup extends CMSPlugin implements SubscriberInterface
|
||||
];
|
||||
}
|
||||
|
||||
$db = Factory::getContainer()->get(DatabaseInterface::class);
|
||||
$tables = $db->getTableList();
|
||||
$prefix = $db->getPrefix();
|
||||
$statsTable = $prefix . 'mokosuitebackup_records';
|
||||
// Prefer MokoSuiteBackup's own helper (clean public API)
|
||||
$helperClass = 'Joomla\\Component\\MokoSuiteBackup\\Administrator\\Utility\\BackupStatusHelper';
|
||||
|
||||
if (!in_array($statsTable, $tables, true))
|
||||
if (class_exists($helperClass))
|
||||
{
|
||||
$staleDays = (int) $this->params->get('stale_days', 7);
|
||||
|
||||
return $helperClass::getStatus($staleDays);
|
||||
}
|
||||
|
||||
// Fallback: direct table query for older MokoSuiteBackup versions
|
||||
$db = Factory::getContainer()->get(DatabaseInterface::class);
|
||||
$tables = $db->getTableList();
|
||||
$prefix = $db->getPrefix();
|
||||
|
||||
if (!in_array($prefix . 'mokosuitebackup_records', $tables, true))
|
||||
{
|
||||
return [
|
||||
'installed' => true,
|
||||
@@ -115,32 +132,17 @@ class Backup extends CMSPlugin implements SubscriberInterface
|
||||
];
|
||||
}
|
||||
|
||||
// TODO: Query MokoSuiteBackup records table for latest backup status.
|
||||
//
|
||||
// This is a placeholder — the actual column names and table structure
|
||||
// depend on MokoSuiteBackup's schema. Once that component is available
|
||||
// locally, update this query to match its database layout.
|
||||
//
|
||||
// Expected return shape:
|
||||
// [
|
||||
// 'installed' => true,
|
||||
// 'status' => 'ok' | 'degraded',
|
||||
// 'last_backup' => '2026-06-18 10:30:45',
|
||||
// 'last_status' => 'complete' | 'failed' | 'partial',
|
||||
// 'last_size_mb' => 512,
|
||||
// 'days_since' => 2,
|
||||
// 'total_backups'=> 42,
|
||||
// 'recent_7d' => 5,
|
||||
// 'destination' => 'local' | 's3' | 'remote',
|
||||
// 'description' => 'Full site backup',
|
||||
// ]
|
||||
|
||||
return $this->queryBackupRecords($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query MokoSuiteBackup records for the latest backup summary.
|
||||
*
|
||||
* Column names match the MokoSuiteBackup schema:
|
||||
* - backupstart/backupend (not created/modified)
|
||||
* - status: pending, running, complete, fail
|
||||
* - total_size in bytes
|
||||
*
|
||||
* @param DatabaseInterface $db Database driver.
|
||||
*
|
||||
* @return array Backup status array.
|
||||
@@ -149,9 +151,19 @@ class Backup extends CMSPlugin implements SubscriberInterface
|
||||
{
|
||||
$staleDays = (int) $this->params->get('stale_days', 7);
|
||||
|
||||
// Get the most recent backup record
|
||||
// Most recent backup record
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->select([
|
||||
$db->quoteName('id'),
|
||||
$db->quoteName('description'),
|
||||
$db->quoteName('status'),
|
||||
$db->quoteName('backup_type'),
|
||||
$db->quoteName('total_size'),
|
||||
$db->quoteName('backupstart'),
|
||||
$db->quoteName('backupend'),
|
||||
$db->quoteName('origin'),
|
||||
$db->quoteName('filesexist'),
|
||||
])
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->order($db->quoteName('id') . ' DESC');
|
||||
|
||||
@@ -167,53 +179,77 @@ class Backup extends CMSPlugin implements SubscriberInterface
|
||||
];
|
||||
}
|
||||
|
||||
// Count total and recent backups
|
||||
// Count completed backups
|
||||
$db->setQuery(
|
||||
$db->getQuery(true)
|
||||
->select('COUNT(*)')
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->where($db->quoteName('status') . ' = ' . $db->quote('complete'))
|
||||
);
|
||||
$totalBackups = (int) $db->loadResult();
|
||||
|
||||
// Recent completed backups (last 7 days)
|
||||
$cutoff = date('Y-m-d H:i:s', strtotime('-7 days'));
|
||||
$db->setQuery(
|
||||
$db->getQuery(true)
|
||||
->select('COUNT(*)')
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->where($db->quoteName('created') . ' >= DATE_SUB(NOW(), INTERVAL 7 DAY)')
|
||||
->where($db->quoteName('status') . ' = ' . $db->quote('complete'))
|
||||
->where($db->quoteName('backupstart') . ' >= ' . $db->quote($cutoff))
|
||||
);
|
||||
$recentBackups = (int) $db->loadResult();
|
||||
|
||||
// Failures in last 7 days
|
||||
$db->setQuery(
|
||||
$db->getQuery(true)
|
||||
->select('COUNT(*)')
|
||||
->from($db->quoteName('#__mokosuitebackup_records'))
|
||||
->where($db->quoteName('status') . ' = ' . $db->quote('fail'))
|
||||
->where($db->quoteName('backupstart') . ' >= ' . $db->quote($cutoff))
|
||||
);
|
||||
$failCount7d = (int) $db->loadResult();
|
||||
|
||||
// Determine status
|
||||
$lastDate = $latest->created ?? '';
|
||||
$daysSince = $lastDate ? (int) ((time() - strtotime($lastDate)) / 86400) : 999;
|
||||
$lastStatus = $latest->status ?? 'unknown';
|
||||
$daysSince = 999;
|
||||
|
||||
if (!empty($latest->backupstart) && $latest->backupstart !== '0000-00-00 00:00:00')
|
||||
{
|
||||
$daysSince = (int) ((time() - strtotime($latest->backupstart)) / 86400);
|
||||
}
|
||||
|
||||
$status = 'ok';
|
||||
|
||||
if ($lastStatus !== 'complete')
|
||||
if ($latest->status === 'fail')
|
||||
{
|
||||
$status = 'degraded';
|
||||
}
|
||||
elseif ($latest->status !== 'complete')
|
||||
{
|
||||
$status = ($latest->status === 'running') ? 'ok' : 'degraded';
|
||||
}
|
||||
elseif ($daysSince > $staleDays)
|
||||
{
|
||||
$status = 'degraded';
|
||||
}
|
||||
|
||||
$sizeMb = !empty($latest->total_size)
|
||||
$sizeMb = $latest->total_size
|
||||
? round($latest->total_size / 1048576)
|
||||
: null;
|
||||
|
||||
return [
|
||||
'installed' => true,
|
||||
'status' => $status,
|
||||
'last_backup' => $lastDate,
|
||||
'last_status' => $lastStatus,
|
||||
'last_size_mb' => $sizeMb,
|
||||
'days_since' => $daysSince,
|
||||
'total_backups' => $totalBackups,
|
||||
'recent_7d' => $recentBackups,
|
||||
'destination' => $latest->destination ?? null,
|
||||
'description' => $latest->description ?? null,
|
||||
'installed' => true,
|
||||
'status' => $status,
|
||||
'last_backup' => $latest->backupstart,
|
||||
'last_status' => $latest->status,
|
||||
'last_size_mb' => $sizeMb,
|
||||
'days_since' => $daysSince,
|
||||
'backup_type' => $latest->backup_type,
|
||||
'origin' => $latest->origin,
|
||||
'total_backups' => $totalBackups,
|
||||
'recent_7d' => $recentBackups,
|
||||
'fail_count_7d' => $failCount7d,
|
||||
'files_exist' => (bool) $latest->filesexist,
|
||||
'description' => $latest->description,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user