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