|
|
|
|
@ -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(); |
|
|
|
|
|