6540a9314a
Reported apart from unreadable files, with example paths and the advice to rename them, instead of advice about permissions. Start of the 1.1.0 plan in PLAN.md.
92 lines
5.4 KiB
PHP
92 lines
5.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
// SPDX-FileCopyrightText: 2026 Dillard Blom
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
namespace OCA\NgBackup\Notification;
|
|
|
|
use OCA\NgBackup\AppInfo\Application;
|
|
use OCP\IURLGenerator;
|
|
use OCP\L10N\IFactory;
|
|
use OCP\Notification\INotification;
|
|
use OCP\Notification\INotifier;
|
|
use OCP\Notification\UnknownNotificationException;
|
|
|
|
final class Notifier implements INotifier {
|
|
public function __construct(
|
|
private IFactory $l10n,
|
|
private IURLGenerator $url,
|
|
) {
|
|
}
|
|
|
|
public function getID(): string {
|
|
return Application::APP_ID;
|
|
}
|
|
|
|
public function getName(): string {
|
|
return $this->l10n->get(Application::APP_ID)->t('NG Backup');
|
|
}
|
|
|
|
public function prepare(INotification $notification, string $languageCode): INotification {
|
|
if ($notification->getApp() !== Application::APP_ID) {
|
|
throw new UnknownNotificationException();
|
|
}
|
|
$l = $this->l10n->get(Application::APP_ID, $languageCode);
|
|
$p = $notification->getSubjectParameters();
|
|
switch ($notification->getSubject()) {
|
|
case 'run_failed':
|
|
$notification->setParsedSubject($p['kind'] === 'restore'
|
|
? $l->t('Restore from %s failed', [$p['target']])
|
|
: $l->t('Backup to %s failed', [$p['target']]));
|
|
$notification->setParsedMessage((string)($p['error'] ?? ''));
|
|
break;
|
|
case 'run_warnings':
|
|
$notification->setParsedSubject($l->t('Backup to %1$s finished with warnings: %2$s unreadable, %3$s changed while being read', [$p['target'], $p['unreadable'], $p['changing']]));
|
|
$notification->setParsedMessage($l->t('Unreadable files and folders are missing from this backup (check their permissions). Files that kept changing were saved as they were while being read. Examples: %s', [$p['examples'] ?? '']));
|
|
break;
|
|
case 'run_bad_names':
|
|
$notification->setParsedSubject($l->n('Backup to %s finished, but %n item is missing because of its name', 'Backup to %s finished, but %n items are missing because of their names', (int)$p['count'], [$p['target']]));
|
|
$notification->setParsedMessage($l->t('Names with a backslash or a control character, or that are not valid UTF-8, are not supported, so these files and folders are not in this backup. Rename them; the next backup includes them. Examples: %s', [$p['examples'] ?? '']));
|
|
break;
|
|
case 'quota_warning':
|
|
$notification->setParsedSubject($l->t('Backup location %1$s is at %2$s%% of its limit (%3$s of %4$s)', [$p['target'], $p['percent'], $p['used'], $p['limit']]));
|
|
$notification->setParsedMessage($l->t('Backups stop when the limit is reached. Raise the limit, or let the retention policy remove older backups.'));
|
|
break;
|
|
case 'backup_stale':
|
|
// 'never' was stored by 0.9.4 and earlier
|
|
$notification->setParsedSubject(in_array($p['since'] ?? '', ['', 'never'], true)
|
|
? $l->t('No successful backup to %s yet', [$p['target']])
|
|
: $l->t('No successful backup to %1$s since %2$s', [$p['target'], $p['since']]));
|
|
$notification->setParsedMessage($l->t('Check the backup settings and the server log.'));
|
|
break;
|
|
case 'security_event':
|
|
$who = (string)($p['actor'] ?? '');
|
|
$notification->setParsedSubject(match ($p['event'] ?? '') {
|
|
'kit_downloaded' => $l->t('%s downloaded the backup recovery kit', [$who]),
|
|
'target_removed' => $l->t('%1$s removed backup location %2$s', [$who, $p['target'] ?? '']),
|
|
'target_changed' => $l->t('%1$s changed the connection settings of backup location %2$s', [$who, $p['target'] ?? '']),
|
|
'append_only_off' => $l->t('%1$s turned off append-only for backup location %2$s', [$who, $p['target'] ?? '']),
|
|
'retention_changed' => $l->t('%1$s changed the backup retention to %2$s', [$who, $p['policy'] ?? '']),
|
|
'snapshots_forgotten' => $l->t('%1$s moved %2$s snapshots of %3$s to the trash; they are deleted permanently after %4$s unless restored', [$who, $p['count'] ?? '', $p['target'] ?? '', $p['until'] ?? '']),
|
|
'snapshot_untrashed' => $l->t('%1$s restored snapshot %2$s of %3$s from the trash', [$who, $p['snapshot'] ?? '', $p['target'] ?? '']),
|
|
'catalog_trusted' => $l->t('%1$s accepted an older state of backup location %2$s (catalog generation %3$s)', [$who, $p['target'] ?? '', $p['generation'] ?? '']),
|
|
'slot_added' => $l->t('%1$s added backup passphrase slot %2$s (%3$s); download and confirm the new recovery kit', [$who, $p['slot'] ?? '', $p['label'] ?? '']),
|
|
'slot_replaced' => $l->t('%1$s set a new passphrase for backup key slot %2$s (%3$s); download and confirm the new recovery kit', [$who, $p['slot'] ?? '', $p['label'] ?? '']),
|
|
'user_export_retention_changed' => $l->t('%1$s changed how many exports per user are kept to %2$s', [$who, $p['keep'] ?? '']),
|
|
'user_exports_forgotten' => $l->t('%1$s removed %2$s per-user exports from %3$s', [$who, $p['count'] ?? '', $p['target'] ?? '']),
|
|
'slot_removed' => $l->t('%1$s removed backup passphrase slot %2$s; download and confirm the new recovery kit', [$who, $p['slot'] ?? '']),
|
|
default => $l->t('NG Backup security event'),
|
|
});
|
|
$notification->setParsedMessage($l->t('If this was not you or another administrator, check who has admin access.'));
|
|
break;
|
|
default:
|
|
throw new UnknownNotificationException();
|
|
}
|
|
$notification->setLink($this->url->linkToRouteAbsolute('settings.AdminSettings.index', ['section' => 'ng_backup']));
|
|
$notification->setIcon($this->url->getAbsoluteURL($this->url->imagePath(Application::APP_ID, 'app-dark.svg')));
|
|
return $notification;
|
|
}
|
|
}
|