Skip to content

Commit b600014

Browse files
committed
feat: add option to perform a full addressbook sync instead of a delta sync
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent cc1026f commit b600014

3 files changed

Lines changed: 18 additions & 4 deletions

File tree

apps/dav/lib/CardDAV/SyncService.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,13 @@ public function syncRemoteAddressBook(string $url, string $userName, string $add
6666
throw $ex;
6767
}
6868

69+
$received = [];
6970
// 3. apply changes
7071
// TODO: use multi-get for download
7172
foreach ($response['response'] as $resource => $status) {
7273
$cardUri = basename($resource);
7374
if (isset($status[200])) {
75+
$received[] = $cardUri;
7476
$absoluteUrl = $this->prepareUri($url, $resource);
7577
$vCard = $this->download($absoluteUrl, $userName, $sharedSecret);
7678
$this->atomic(function () use ($addressBookId, $cardUri, $vCard): void {
@@ -86,6 +88,15 @@ public function syncRemoteAddressBook(string $url, string $userName, string $add
8688
}
8789
}
8890

91+
// when doing a full sync, remove any items in the local address book that aren't in the remote one
92+
if (!$syncToken) {
93+
$existingCards = $this->backend->getCards($addressBookId);
94+
$removedCards = array_filter($existingCards, fn (array $card) => !in_array($card['uri'], $received));
95+
foreach ($removedCards as $removedCard) {
96+
$this->backend->deleteCard($addressBookId, $removedCard['uri']);
97+
}
98+
}
99+
89100
return [
90101
$response['token'],
91102
$response['truncated'],

apps/federation/lib/Command/SyncFederationAddressBooks.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Symfony\Component\Console\Command\Command;
1212
use Symfony\Component\Console\Helper\ProgressBar;
1313
use Symfony\Component\Console\Input\InputInterface;
14+
use Symfony\Component\Console\Input\InputOption;
1415
use Symfony\Component\Console\Output\OutputInterface;
1516

1617
class SyncFederationAddressBooks extends Command {
@@ -23,19 +24,21 @@ public function __construct(
2324
protected function configure() {
2425
$this
2526
->setName('federation:sync-addressbooks')
26-
->setDescription('Synchronizes addressbooks of all federated clouds');
27+
->setDescription('Synchronizes addressbooks of all federated clouds')
28+
->addOption('full', null, InputOption::VALUE_NONE, 'Perform a full sync instead of a delta sync');
2729
}
2830

2931
protected function execute(InputInterface $input, OutputInterface $output): int {
3032
$progress = new ProgressBar($output);
3133
$progress->start();
34+
$full = (bool)$input->getOption('full');
3235
$this->syncService->syncThemAll(function ($url, $ex) use ($progress, $output): void {
3336
if ($ex instanceof \Exception) {
3437
$output->writeln("Error while syncing $url : " . $ex->getMessage());
3538
} else {
3639
$progress->advance();
3740
}
38-
});
41+
}, $full);
3942

4043
$progress->finish();
4144
$output->writeln('');

apps/federation/lib/SyncFederationAddressBooks.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function __construct(
2828
/**
2929
* @param \Closure $callback
3030
*/
31-
public function syncThemAll(\Closure $callback) {
31+
public function syncThemAll(\Closure $callback, bool $full = false) {
3232
$trustedServers = $this->dbHandler->getAllServer();
3333
foreach ($trustedServers as $trustedServer) {
3434
$url = $trustedServer['url'];
@@ -59,7 +59,7 @@ public function syncThemAll(\Closure $callback) {
5959
$cardDavUser,
6060
$addressBookUrl,
6161
$sharedSecret,
62-
$syncToken,
62+
$full ? null : $syncToken,
6363
$targetBookId,
6464
$targetPrincipal,
6565
$targetBookProperties

0 commit comments

Comments
 (0)