Skip to content

Commit 95fa133

Browse files
committed
fix(cardav): return correct card version on report
Signed-off-by: Hamza <hamzamahjoubi221@gmail.com>
1 parent b243fd3 commit 95fa133

3 files changed

Lines changed: 93 additions & 0 deletions

File tree

apps/contactsinteraction/lib/Card.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ public function getContentType(): ?string {
6666
return 'text/vcard; charset=utf-8';
6767
}
6868

69+
public function getVersion(): ?string {
70+
return '3.0';
71+
}
72+
6973
/**
7074
* @inheritDoc
7175
*/

apps/dav/lib/CardDAV/Card.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ public function getAddressbookId(): int {
2929
return (int)$this->cardData['addressbookid'];
3030
}
3131

32+
public function getVersion(): ?string {
33+
preg_match('/^VERSION:([34])\.0/mi', $this->cardData['carddata'], $matches);
34+
return isset($matches[1]) ? $matches[1] . '.0' : null;
35+
}
36+
3237
public function getPrincipalUri(): string {
3338
return $this->addressBookInfo['principaluri'];
3439
}

apps/dav/lib/CardDAV/Plugin.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace OCA\DAV\CardDAV;
99

1010
use OCA\DAV\CardDAV\Xml\Groups;
11+
use Sabre\CardDAV\ICard;
1112
use Sabre\DAV\INode;
1213
use Sabre\DAV\PropFind;
1314
use Sabre\DAV\Server;
@@ -55,4 +56,87 @@ public function propFind(PropFind $propFind, INode $node) {
5556
});
5657
}
5758
}
59+
60+
/**
61+
* This function handles the addressbook-query REPORT.
62+
*
63+
* This report is used by the client to filter an addressbook based on a
64+
* complex query.
65+
*
66+
* @param \Sabre\CardDAV\Xml\Request\AddressBookQueryReport $report
67+
*/
68+
protected function addressbookQueryReport($report) {
69+
$depth = $this->server->getHTTPDepth(0);
70+
71+
if ($depth == 0) {
72+
$candidateNodes = [
73+
$this->server->tree->getNodeForPath($this->server->getRequestUri()),
74+
];
75+
if (!$candidateNodes[0] instanceof ICard) {
76+
throw new ReportNotSupported('The addressbook-query report is not supported on this url with Depth: 0');
77+
}
78+
} else {
79+
$candidateNodes = $this->server->tree->getChildren($this->server->getRequestUri());
80+
}
81+
82+
$validNodes = [];
83+
foreach ($candidateNodes as $node) {
84+
if (!$node instanceof ICard) {
85+
continue;
86+
}
87+
88+
$blob = $node->get();
89+
if (is_resource($blob)) {
90+
$blob = stream_get_contents($blob);
91+
}
92+
93+
if (!$this->validateFilters($blob, $report->filters, $report->test)) {
94+
continue;
95+
}
96+
97+
$validNodes[] = $node;
98+
99+
if ($report->limit && $report->limit <= count($validNodes)) {
100+
// We hit the maximum number of items, we can stop now.
101+
break;
102+
}
103+
}
104+
105+
$result = [];
106+
foreach ($validNodes as $validNode) {
107+
$contentType = $report->contentType;
108+
// we theoretically support versions 3.0 and 4.0 so $vcardType should be dyncamic depending on the node
109+
if ($validNode->getVersion()) {
110+
$contentType .= '; version=' . $validNode?->getVersion();
111+
} elseif ($report->version) {
112+
$contentType .= '; version=' . $report->version;
113+
}
114+
$vcardType = $this->negotiateVCard(
115+
$contentType
116+
);
117+
if ($depth == 0) {
118+
$href = $this->server->getRequestUri();
119+
} else {
120+
$href = $this->server->getRequestUri() . '/' . $validNode->getName();
121+
}
122+
123+
[$props] = $this->server->getPropertiesForPath($href, $report->properties, 0);
124+
125+
if (isset($props[200]['{' . self::NS_CARDDAV . '}address-data'])) {
126+
$props[200]['{' . self::NS_CARDDAV . '}address-data'] = $this->convertVCard(
127+
$props[200]['{' . self::NS_CARDDAV . '}address-data'],
128+
$vcardType,
129+
$report->addressDataProperties
130+
);
131+
}
132+
$result[] = $props;
133+
}
134+
135+
$prefer = $this->server->getHTTPPrefer();
136+
137+
$this->server->httpResponse->setStatus(207);
138+
$this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
139+
$this->server->httpResponse->setHeader('Vary', 'Brief,Prefer');
140+
$this->server->httpResponse->setBody($this->server->generateMultiStatus($result, $prefer['return'] === 'minimal'));
141+
}
58142
}

0 commit comments

Comments
 (0)