rulesById($username); foreach ($this->sync->allRuleEntries($username) as $ruleId => $entries) { if (!isset($rules[$ruleId]) || empty($rules[$ruleId]['enabled'])) { $this->deleteEntries($username, $ruleId, $entries); } } foreach ($rules as $ruleId => $rule) { if (empty($rule['enabled'])) { continue; } $this->syncRule($username, $ruleId, $rule); } } /** @return array> */ private function rulesById(string $username): array { $out = []; foreach ($this->rules->all($username) as $rule) { $id = (string)($rule['id'] ?? ''); if ($id !== '') { $out[$id] = $rule; } } return $out; } /** @param array $rule */ private function syncRule(string $username, string $ruleId, array $rule): void { $existing = $this->indexedEntries($this->sync->entriesForRule($username, $ruleId)); $targets = $this->targetMailboxes($username, $rule); $next = []; foreach ($targets as $mailbox) { $email = strtolower((string)$mailbox['email']); $isTracked = isset($existing[$email]); if (!$isTracked && $this->api->vacationExists($username, $email)) { throw new RuntimeException('Untracked DirectAdmin vacation already exists for ' . $email); } $this->api->saveVacation($username, $email, $rule, $isTracked); $next[] = [ 'rule_id' => $ruleId, 'domain' => (string)$mailbox['domain'], 'mailbox' => (string)$mailbox['mailbox'], 'email' => $email, 'api_key' => $email, 'last_sync_at' => time(), ]; unset($existing[$email]); } foreach ($existing as $entry) { $this->api->deleteVacation($username, (string)$entry['email']); } $this->sync->replaceRuleEntries($username, $ruleId, $next); } /** @param array> $entries */ private function deleteEntries(string $username, string $ruleId, array $entries): void { foreach ($entries as $entry) { $email = (string)($entry['email'] ?? $entry['api_key'] ?? ''); if ($email !== '') { $this->api->deleteVacation($username, $email); } } $this->sync->deleteRuleEntries($username, $ruleId); } /** @param array> $entries @return array> */ private function indexedEntries(array $entries): array { $out = []; foreach ($entries as $entry) { $email = strtolower((string)($entry['email'] ?? $entry['api_key'] ?? '')); if ($email !== '') { $out[$email] = $entry + ['email' => $email]; } } return $out; } /** @param array $rule @return array */ private function targetMailboxes(string $username, array $rule): array { if (empty($rule['dynamic_scope']) && isset($rule['mailbox_snapshot']) && is_array($rule['mailbox_snapshot'])) { return array_values(array_filter($rule['mailbox_snapshot'], static function (mixed $mailbox): bool { return is_array($mailbox) && isset($mailbox['domain'], $mailbox['mailbox'], $mailbox['email']) && filter_var((string)$mailbox['email'], FILTER_VALIDATE_EMAIL); })); } return $this->mailboxes->mailboxesForUser($username); } }