api->getSettings()); * echo json_encode(BackupModule::create($pdo, Context::system(), $config, $redis)->api->export($domain, $page)); // backup.php * * $config: timezone (TZ of mailcow, for the schedule), alias_disable_external_domains ($ALIAS_DISABLE_EXTERNAL_DOMAINS). * $redis: for DKIM keys, rate limits and the domain map (export and restore). */ class BackupModule { public function __construct( public readonly SettingsService $settings, public readonly JobService $jobs, public readonly ExportService $export, public readonly RestoreService $restore, public readonly DomainRestoreService $domainRestore, public readonly BackupApiController $api ) { } public static function create(PDO $pdo, Context $context, array $config = [], ?Redis $redis = null): self { $jobRepo = new JobRepository($pdo); $restoreRepo = new RestoreRepository($pdo); $legacy = new LegacyDomain($redis); $settings = new SettingsService(new SettingsRepository($pdo), $context); $jobs = new JobService($jobRepo, new SnapshotRepository($pdo), $settings, $context, (string)($config['timezone'] ?? 'UTC')); $export = new ExportService(new ExportRepository($pdo), $legacy); $sogo = SogoModule::create()->sogo; $dovecot = DovecotModule::create()->dovecot; // the group module without group templates: a restored mailbox keeps the settings of the backup $groupRepo = new GroupRepository($pdo); $lookup = new LookupRepository($pdo); $templates = new TemplateService($lookup, new NoTemplates()); $effects = new ChangeEffects($templates, $sogo, $groupRepo, $dovecot); $groups = new GroupMembers($groupRepo, $lookup, $templates, $effects, new SharingService($groupRepo, $dovecot, $sogo, $effects)); $restore = new RestoreService($restoreRepo, $jobRepo, $groups, $sogo, $dovecot, $legacy, (bool)($config['alias_disable_external_domains'] ?? false)); $domainRestore = new DomainRestoreService($restoreRepo, $jobRepo, $groups, $legacy); return new self($settings, $jobs, $export, $restore, $domainRestore, new BackupApiController($settings, $jobs, $export, $restore, $domainRestore, new ApiResponse(Settings::SECRETS))); } /** Legacy entry point for procedural callers: reads $pdo, $redis, $_SESSION, TZ and $ALIAS_DISABLE_EXTERNAL_DOMAINS */ public static function fromGlobals(?Context $context = null): self { return self::create($GLOBALS['pdo'], $context ?? Context::fromSession($_SESSION ?? []), [ 'timezone' => getenv('TZ') ?: 'UTC', 'alias_disable_external_domains' => ($GLOBALS['ALIAS_DISABLE_EXTERNAL_DOMAINS'] ?? false) === true, ], ($GLOBALS['redis'] ?? null) instanceof Redis ? $GLOBALS['redis'] : null); } }