diff options
Diffstat (limited to 'apps/dav/lib/CardDAV/CardDavBackend.php')
-rw-r--r-- | apps/dav/lib/CardDAV/CardDavBackend.php | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index e5ddeb9b4e1..613ec16921f 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -53,6 +53,7 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IDBConnection; use OCP\IGroupManager; use OCP\IUserManager; +use OC\Search\Filter\DateTimeFilter; use PDO; use Sabre\CardDAV\Backend\BackendInterface; use Sabre\CardDAV\Backend\SyncSupport; @@ -1109,7 +1110,15 @@ class CardDavBackend implements BackendInterface, SyncSupport { * @param string $pattern * @param array $searchProperties * @param array $options - * @psalm-param array{types?: bool, escape_like_param?: bool, limit?: int, offset?: int, wildcard?: bool} $options + * @psalm-param array{ + * types?: bool, + * escape_like_param?: bool, + * limit?: int, + * offset?: int, + * wildcard?: bool, + * since?: DateTimeFilter|null, + * until?: DateTimeFilter|null, + * } $options * @return array */ private function searchByAddressBookIds(array $addressBookIds, @@ -1130,32 +1139,31 @@ class CardDavBackend implements BackendInterface, SyncSupport { return []; } - $propertyOr = $query2->expr()->orX(); - foreach ($searchProperties as $property) { - if ($escapePattern) { + if ($escapePattern) { + $searchProperties = array_filter($searchProperties, function ($property) use ($pattern) { if ($property === 'EMAIL' && str_contains($pattern, ' ')) { // There can be no spaces in emails - continue; + return false; } if ($property === 'CLOUD' && preg_match('/[^a-zA-Z0-9 :_.@\/\-\']/', $pattern) === 1) { // There can be no chars in cloud ids which are not valid for user ids plus :/ // worst case: CA61590A-BBBC-423E-84AF-E6DF01455A53@https://my.nxt/srv/ - continue; + return false; } - } - $propertyOr->add($query2->expr()->eq('cp.name', $query2->createNamedParameter($property))); + return true; + }); } - if ($propertyOr->count() === 0) { + if (empty($searchProperties)) { return []; } $query2->selectDistinct('cp.cardid') ->from($this->dbCardsPropertiesTable, 'cp') ->andWhere($addressBookOr) - ->andWhere($propertyOr); + ->andWhere($query2->expr()->in('cp.name', $query2->createNamedParameter($searchProperties, IQueryBuilder::PARAM_STR_ARRAY))); // No need for like when the pattern is empty if ('' !== $pattern) { @@ -1167,7 +1175,6 @@ class CardDavBackend implements BackendInterface, SyncSupport { $query2->andWhere($query2->expr()->ilike('cp.value', $query2->createNamedParameter('%' . $this->db->escapeLikeParameter($pattern) . '%'))); } } - if (isset($options['limit'])) { $query2->setMaxResults($options['limit']); } @@ -1175,6 +1182,29 @@ class CardDavBackend implements BackendInterface, SyncSupport { $query2->setFirstResult($options['offset']); } + if (isset($options['since']) || isset($options['until'])) { + $query2->join('cp', $this->dbCardsPropertiesTable, 'cp_bday', 'cp.cardid = cp_bday.cardid'); + $query2->andWhere($query2->expr()->eq('cp_bday.name', $query2->createNamedParameter('BDAY'))); + /** + * FIXME Find a way to match only 4 last digits + * BDAY can be --1018 without year or 20001019 with it + * $bDayOr = $query2->expr()->orX(); + * if ($options['since'] instanceof DateTimeFilter) { + * $bDayOr->add( + * $query2->expr()->gte('SUBSTR(cp_bday.value, -4)', + * $query2->createNamedParameter($options['since']->get()->format('md'))) + * ); + * } + * if ($options['until'] instanceof DateTimeFilter) { + * $bDayOr->add( + * $query2->expr()->lte('SUBSTR(cp_bday.value, -4)', + * $query2->createNamedParameter($options['until']->get()->format('md'))) + * ); + * } + * $query2->andWhere($bDayOr); + */ + } + $result = $query2->execute(); $matches = $result->fetchAll(); $result->closeCursor(); @@ -1410,7 +1440,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { $maxId = (int) $result->fetchOne(); $result->closeCursor(); if (!$maxId || $maxId < $keep) { - return 0; + return 0; } $query = $this->db->getQueryBuilder(); |