Skip to content

Commit

Permalink
Handle save_data keys without label (Fixes #332)
Browse files Browse the repository at this point in the history
Roundcube under certain circumstances passed multi-value fields without
a label (e.g. instead of email:home, it uses the key email). One such
situation is when using the "add to addressbook" functionality from the
mail view. Additionally, in this case roundcube does not pass the
addresses as an array, but as a plain string value. This situation was
already handled though.
  • Loading branch information
mstilkerich committed Feb 1, 2021
1 parent 8c9815a commit b7d1d0b
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
- Fix #325: Roundcube setting for contact sorting field was not used
- Fix #279: More specific error message when syntactically wrong URL is entered for new addressbook
- Fix #328: Contact search with MySQL might not have returned all results
- Fix #332: When adding a new contact via "add to addressbook" from mail view, the email address was missing in the new
card
- New: Download externally referenced photos on demand, drastically speeding up sync with when photos are stored
separately from the VCard (e.g. iCloud). For details see #247.
- New: Support for instant messaging data fields and maiden name (resolves #46). Interoperability with other
Expand Down Expand Up @@ -89,3 +91,5 @@ detailed changelog within the next weeks.
- The CardDAV interaction is moved to a [library](https://github.com/mstilkerich/carddavclient). It is essentially a
complete rewrite of the code communicating with the CardDAV servers and includes interoperability tests with many
common servers, see [here](https://github.com/mstilkerich/carddavclient).

<!-- vim: set ts=4 sw=4 expandtab fenc=utf8 ff=unix tw=120: -->
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ There is no supported upgrade path from the 2.0.x version. You need to manually

There is no upgrade path from the 1.0 version. You need to manually remove RCMCardDAV 1.0, drop its tables from your database and start with a fresh installation.

<!-- vim: set ts=4 sw=4 expandtab fenc=utf8 ff=unix tw=120: -->
19 changes: 16 additions & 3 deletions src/DataConversion.php
Original file line number Diff line number Diff line change
Expand Up @@ -594,12 +594,18 @@ private function setMultiValueProperties(array $save_data, VCard $vcard): void
$subtypes = isset($save_data["$rckey:$rclabel"]) ? [ $rclabel ] : [];
} else {
$rclabel = null;
$subtypes = preg_filter("/^$rckey:/", '', array_keys($save_data), 1);
$subtypes = preg_filter("/^$rckey:?/", '', array_keys($save_data), 1);
}

foreach ($subtypes as $subtype) {
// In some cases, roundcube passes a multi-value attribute without subtype (e.g. "email"), e.g. "add
// contact to addressbook" from mail view
$sdkey = strlen($subtype) > 0 ? "$rckey:$subtype" : $rckey;

// Cast to array - roundcube passes simple string in some cases, e.g. "add contact to addressbook" from
// mail view
/** @var SaveDataMultiField $values */
$values = (array) $save_data["$rckey:$subtype"];
$values = (array) $save_data[$sdkey];
foreach ($values as $value) {
$prop = null;

Expand Down Expand Up @@ -783,14 +789,16 @@ private function clearOrphanAttrLabels(VCard $vcard): void
}

/**
* This function assigned a label (subtype) to a VCard multi-value property.
* This function assigns a label (subtype) to a VCard multi-value property.
*
* Typical multi-value properties are EMAIL, TEL and ADR.
*
* Note that roundcube/rcmcarddav only supports a single subtype per property, whereas VCard allows to have more
* than one. As an effect, when a card is updated only the subtype selected in roundcube will be preserved, possible
* extra subtypes will be lost.
*
* If the given label is empty, not TYPE parameter is assigned.
*
* If the given label is one of the known standard labels, it will be assigned as a TYPE parameter of the property,
* otherwise it will be assigned using the X-ABLabel extension.
*
Expand All @@ -804,6 +812,11 @@ private function clearOrphanAttrLabels(VCard $vcard): void
*/
private function setAttrLabel(VCard $vcard, VObject\Property $vprop, string $attrname, string $newlabel): void
{
// Don't set a type parameter if there is no label
if (strlen($newlabel) == 0) {
return;
}

// X-ABLabel?
if (in_array($newlabel, $this->xlabels[$attrname])) {
$usedGroups = $this->getAllPropertyGroups($vcard);
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/data/vcardCreate/EmptyLabel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "Chairman Wesker",
"firstname": "Albert",
"surname": "Wesker",
"email": "[email protected]",
"phone": "12345",
"website": "https://wesker.example.com",
"address": [
{
"street": "239 Umbrella Ave",
"locality": "Tokyo",
"region": "Kanto",
"zipcode": "99887",
"country": "Japan"
}
]
}
12 changes: 12 additions & 0 deletions tests/unit/data/vcardCreate/EmptyLabel.vcf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
BEGIN:VCARD
VERSION:3.0
PRODID:-//Sabre//Sabre VObject 4.3.1//EN
UID:sabre-vobject-005e805f-0bc1-4333-8be2-97889fb45b7a
REV:2020-08-27T20:38:49Z
N:Wesker;Albert;;;
FN:Chairman Wesker
EMAIL:[email protected]
TEL:12345
URL;VALUE=URI:https://wesker.example.com
ADR:;;239 Umbrella Ave;Tokyo;Kanto;99887;Japan
END:VCARD
4 changes: 4 additions & 0 deletions tests/unit/data/vcardCreate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ There are a few specifics to be tested during the creation:
to show as company and use organization as displayname.
- EmptyDisplaynameResetShowAs: Like EmptyDisplayname, but set to show as company when no organization attribute is
available. Must reset showas to individual and compose displayname from name attributes.
- EmptyLabel: Roundcube data uses keys for multi-value properties without a label, plus it passes in a single value as
a string, not the usual array. This happens when using "add to addressbook" from the mail view.
- Group: A KIND=group VCard
- InstantMessaging: Contains data for all supported instant messaging services and custom ones.
- ZeroStrings: Contains "0" values from some data fields, which are considered empty() by PHPs empty() function. These
properties must be properly set to 0 in the created VCard, not omitted.

<!-- vim: set ts=4 sw=4 expandtab fenc=utf8 ff=unix tw=120: -->

0 comments on commit b7d1d0b

Please sign in to comment.