This commit is contained in:
Fathi Ben Nasr 2026-08-12 23:38:58 +00:00 committed by GitHub
commit b3a25b323b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -160,6 +160,31 @@ class PdoAddressBook
$bReadWrite = $this->isDAVReadWrite();
/**
* An empty list on either side is far more often a fault than a real
* "delete everything": a fresh or rebuilt local store, a DAV listing
* that failed to parse, a stale server-side index. Acting on it
* destroys data the other side still holds, so skip the deletions in
* that direction and let the following import/export reconcile.
*/
$iLocalLive = 0;
foreach ($aLocalSyncData as $aGuardData) {
if (empty($aGuardData['deleted'])) {
++$iLocalLive;
}
}
$iRemoteCount = \count($aRemoteSyncData);
$bProtectRemote = (0 === $iLocalLive && 0 < $iRemoteCount);
$bProtectLocal = (0 === $iRemoteCount && 0 < $iLocalLive);
if ($bProtectRemote) {
\SnappyMail\Log::warning('PdoAddressBook', "Sync() local store is empty while remote holds"
. " {$iRemoteCount} contacts: importing only, no remote deletions");
}
if ($bProtectLocal) {
\SnappyMail\Log::warning('PdoAddressBook', "Sync() remote listing is empty while local holds"
. " {$iLocalLive} contacts: keeping local, no local deletions");
}
// Delete remote when Mode = read + write
if ($bReadWrite) {
\SnappyMail\Log::info('PdoAddressBook', 'Sync() is import and export');
@ -168,7 +193,7 @@ class PdoAddressBook
if ($aData['deleted']) {
++$iCount;
unset($aLocalSyncData[$sKey]);
if (isset($aRemoteSyncData[$sKey], $aRemoteSyncData[$sKey]['vcf'])) {
if (!$bProtectRemote && isset($aRemoteSyncData[$sKey], $aRemoteSyncData[$sKey]['vcf'])) {
\SnappyMail\HTTP\Stream::JSON(['messsage'=>"Delete remote {$sKey}"]);
$this->davClientRequest($oClient, 'DELETE', $sPath.$aRemoteSyncData[$sKey]['vcf']);
}
@ -183,9 +208,11 @@ class PdoAddressBook
// Delete local
$aIdsForDeletion = array();
foreach ($aLocalSyncData as $sKey => $aData) {
if (!empty($aData['etag']) && !isset($aRemoteSyncData[$sKey])) {
$aIdsForDeletion[] = $aData['id_contact'];
if (!$bProtectLocal) {
foreach ($aLocalSyncData as $sKey => $aData) {
if (!empty($aData['etag']) && !isset($aRemoteSyncData[$sKey])) {
$aIdsForDeletion[] = $aData['id_contact'];
}
}
}
if (\count($aIdsForDeletion)) {