Skip to content

Commit

Permalink
Fix unreleased regression: Move/copy cards between carddav addressboo…
Browse files Browse the repository at this point in the history
…ks (#470)

When a card is moved or copied from one CardDAV addressbook to another via the roundcube web interface,
the Addressbook::insert() function will receive a save_data object produced by rcmcarddav's DataConversion
class, which includes a dummy vcard, but also the original vcard object. With the recent change to use a
vcard provided by roundcube upon the import action, this dummy vcard would wrongly be added to the target
addressbook. To avoid this, use the original vcard object that is also included in the save_data when it
has been produced by rcmcarddav.
  • Loading branch information
mstilkerich committed Jun 5, 2024
1 parent e2c0b77 commit 0c1f597
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
19 changes: 14 additions & 5 deletions src/Addressbook.php
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,18 @@ public function insert($save_data, $check = false)
$logger->info("insert(" . ($save_data["name"] ?? "no name") . ", $check)");
/** @psalm-var SaveData $save_data XXX temporary vimeo/psalm#8980 workaround */

if (isset($save_data['vcard'])) {

// If this save_data was produced by rcmcarddav, we can directly use the original vcard
// (e.g. move from one addressbook to another)
if (isset($save_data['_carddav_vcard'])) {
$vcard = $save_data['_carddav_vcard'];

// If roundcube has set a vcard property (e.g., import), directly import it to the CardDAV server, skipping
// Roundcube's save_data conversion (and our conversion back to save data).
} elseif (isset($save_data['vcard'])) {
$vcard = $this->parseVCard($save_data['vcard']);

// Otherwise (e.g., new contact created in Roundcube), convert the save_data to a vcard
} else {
$vcard = $this->dataConverter->fromRoundcube($save_data);
}
Expand Down Expand Up @@ -1774,16 +1784,15 @@ private function checkPostSearchFilter(
if ($col == '*') { // any contact attribute must match $val
foreach ($save_data as $k => $v) {
// Skip photo/vcard to avoid download - matching against photo is no meaningful use case
if ($k !== "photo" && $k !== "vcard" && strpos($k, "_carddav_") !== 0) {
$v = is_array($v) ? $v : (string) $v;
if (!is_object($v)) {
if ($this->compare_search_value($k, $v, $val, $mode)) {
$psFilterMatched = true;
break;
}
}
}
} elseif (isset($save_data[$col])) {
$sdVal = is_array($save_data[$col]) ? $save_data[$col] : (string) $save_data[$col];
} elseif (isset($save_data[$col]) && !is_object($save_data[$col])) {
$sdVal = $save_data[$col];
$psFilterMatched = $this->compare_search_value($col, $sdVal, $val, $mode);
}

Expand Down
1 change: 1 addition & 0 deletions src/DataConversion.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
* organization?: string,
* department?: string,
* vcard?: string,
* _carddav_vcard?: VCard,
* } & array<string, SaveDataMultiField|list<SaveDataAddressField>>
*
* @psalm-type SaveDataFromDC = array{
Expand Down

0 comments on commit 0c1f597

Please sign in to comment.