Skip to content

Commit

Permalink
Action in the preferences to clear the local cache of an addressbook
Browse files Browse the repository at this point in the history
  • Loading branch information
mstilkerich committed Oct 16, 2021
1 parent 4f1293e commit e69d49a
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,9 @@
- Fix: Display error message when a card cannot be updated because it changed on the server since the last sync.
- Fix #356: Don't create group vcards with duplicate members, don't fail to process them if we receive one from the
server
- New: Action in the preferences to clear the local cache of an addressbook, to allow a full sync from scratch. This is
meant to fix errors in the local state that cannot be repaired from incremental syncs, as might be the result of issue
#356.

## Version 4.2.0 (to 4.1.2)

Expand Down
40 changes: 32 additions & 8 deletions carddav.php
Expand Up @@ -557,6 +557,12 @@ public function savePreferences(array $args): array
$newset = $this->getAddressbookSettingsFromPOST($abookId, $abookrow["presetname"]);
$this->updateAddressbook($abookId, $newset);

// first clear the local cache if requested
if (isset($_POST["${abookId}_cd_clearcache"])) {
$this->deleteAddressbook($abookId, true);
}

// then perform a resync if requested
if (isset($_POST["${abookId}_cd_resync"])) {
[ 'instance' => $backend ] = $this->getAddressbook(['id' => "carddav_$abookId"]);
if ($backend instanceof Addressbook) {
Expand Down Expand Up @@ -1015,13 +1021,20 @@ private function buildSettingsBlock(string $blockheader, array $abook, string $a
'name' => $blockheader
];

if (empty($presetName) && preg_match('/^\d+$/', $abookId)) {
$checkbox = new html_checkbox(['name' => $abookId . '_cd_delete', 'value' => 1]);
$content_delete = $checkbox->show("0");
$retval['options'][] = ['title' => rcube::Q($this->gettext('cd_delete')), 'content' => $content_delete];
}

if ($abookId != "new") {
if (empty($presetName)) {
$checkbox = new html_checkbox(['name' => $abookId . '_cd_delete', 'value' => 1]);
$content_delete = $checkbox->show("0");
$retval['options'][] = ['title' => rcube::Q($this->gettext('cd_delete')), 'content' => $content_delete];
}

$checkbox = new html_checkbox(['name' => $abookId . '_cd_clearcache', 'value' => 1]);
$content_clearcache = $checkbox->show("0");
$retval['options'][] = [
'title' => rcube::Q($this->gettext('cd_clearcache')),
'content' => $content_clearcache
];

$checkbox = new html_checkbox(['name' => $abookId . '_cd_resync', 'value' => 1]);
$content_resync = $checkbox->show("0");
$retval['options'][] = ['title' => rcube::Q($this->gettext('cd_resync')), 'content' => $content_resync];
Expand Down Expand Up @@ -1105,7 +1118,14 @@ private function getAddressbookSettingsFromPOST(string $abookId, ?string $preset
return $result;
}

private function deleteAddressbook(string $abookId): void
/**
* Deletes an addressbook from the local database, fully or only its address data.
*
* @param string $abookId ID of the target addressbook
* @param bool $dataOnly If true, only the cached address data is deleted and the sync reset to initial state.
* If false, the addressbook is fully removed from the database.
*/
private function deleteAddressbook(string $abookId, bool $dataOnly = false): void
{
$infra = Config::inst();
$logger = $infra->logger();
Expand All @@ -1131,7 +1151,11 @@ private function deleteAddressbook(string $abookId): void
// ...contacts
$db->delete(['abook_id' => $abookId], 'contacts');

$db->delete($abookId, 'addressbooks');
if ($dataOnly) {
$db->update($abookId, ["last_updated", "sync_token"], ["0", ""], "addressbooks");
} else {
$db->delete($abookId, 'addressbooks');
}

$db->endTransaction();
} catch (\Exception $e) {
Expand Down
5 changes: 4 additions & 1 deletion localization/de_DE.inc
Expand Up @@ -16,7 +16,10 @@ $labels = Array(
'cd_disabled' => 'Inaktiv',
'cd_lastupdate_time'=>'Zuletzt aktualisiert',
'cd_resync' => "Sofortige Synchronisation mit dem Server erzwingen",
'cd_frompreset' => ' (aus Vorgabe _PRESETNAME_)',
'cd_clearcache' => "Lokale Kopie des Adressbuchs löschen (der nächste Sync lädt die Daten komplett neu)",
'cd_msg_synchronized' => 'CardDAV-Adressbuch $name synchronisiert (Dauer $duration Sekunden)',
'cd_msg_syncfailed' => 'Sync des CardDAV-Adressbuchs $name fehlgeschlagen: $errormsg',
'cd_frompreset' => ' (aus Voreinstellung _PRESETNAME_)',
'cd_etagmismatch' => 'Update fehlgeschlagen, da Adressobjekt serverseitig modifiziert wurde',
);
?>
1 change: 1 addition & 0 deletions localization/en_US.inc
Expand Up @@ -16,6 +16,7 @@ $labels = Array(
'cd_disabled' => 'Disabled',
'cd_lastupdate_time'=>'Time of last update',
'cd_resync' => "Force immediate synchronization with server",
'cd_clearcache' => "Delete locally cached data for this addressbook (next resync starts from scratch)",
'cd_msg_synchronized' => 'CardDAV addressbook $name synchronized (Took $duration seconds)',
'cd_msg_syncfailed' => 'Sync of CardDAV addressbook $name failed: $errormsg',
'cd_frompreset' => ' (from preset _PRESETNAME_)',
Expand Down

0 comments on commit e69d49a

Please sign in to comment.