Skip to content

Commit 117233f

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 aa57c67 commit 117233f

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
@@ -13,6 +13,7 @@
1313
use Symfony\Component\Console\Command\Command;
1414
use Symfony\Component\Console\Helper\ProgressBar;
1515
use Symfony\Component\Console\Input\InputInterface;
16+
use Symfony\Component\Console\Input\InputOption;
1617
use Symfony\Component\Console\Output\OutputInterface;
1718

1819
class SyncFederationAddressBooks extends Command {
@@ -25,19 +26,21 @@ public function __construct(
2526
protected function configure() {
2627
$this
2728
->setName('federation:sync-addressbooks')
28-
->setDescription('Synchronizes addressbooks of all federated clouds');
29+
->setDescription('Synchronizes addressbooks of all federated clouds')
30+
->addOption('full', null, InputOption::VALUE_NONE, 'Perform a full sync instead of a delta sync');
2931
}
3032

3133
protected function execute(InputInterface $input, OutputInterface $output): int {
3234
$progress = new ProgressBar($output);
3335
$progress->start();
36+
$full = (bool)$input->getOption('full');
3437
$this->syncService->syncThemAll(function ($url, $ex) use ($progress, $output): void {
3538
if ($ex instanceof \Exception) {
3639
$output->writeln("Error while syncing $url : " . $ex->getMessage());
3740
} else {
3841
$progress->advance();
3942
}
40-
});
43+
}, $full);
4144

4245
$progress->finish();
4346
$output->writeln('');

apps/federation/lib/SyncFederationAddressBooks.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function __construct(
2424
/**
2525
* @param \Closure $callback
2626
*/
27-
public function syncThemAll(\Closure $callback) {
27+
public function syncThemAll(\Closure $callback, bool $full = false) {
2828
$trustedServers = $this->dbHandler->getAllServer();
2929
foreach ($trustedServers as $trustedServer) {
3030
$url = $trustedServer['url'];
@@ -55,7 +55,7 @@ public function syncThemAll(\Closure $callback) {
5555
$cardDavUser,
5656
$addressBookUrl,
5757
$sharedSecret,
58-
$syncToken,
58+
$full ? null : $syncToken,
5959
$targetBookId,
6060
$targetPrincipal,
6161
$targetBookProperties

0 commit comments

Comments
 (0)