5353use OCP \IDBConnection ;
5454use OCP \IGroupManager ;
5555use OCP \IUserManager ;
56+ use OCP \Search \Filter \DateTimeFilter ;
5657use PDO ;
5758use Sabre \CardDAV \Backend \BackendInterface ;
5859use Sabre \CardDAV \Backend \SyncSupport ;
@@ -1130,32 +1131,31 @@ private function searchByAddressBookIds(array $addressBookIds,
11301131 return [];
11311132 }
11321133
1133- $ propertyOr = $ query2 ->expr ()->orX ();
1134- foreach ($ searchProperties as $ property ) {
1135- if ($ escapePattern ) {
1134+ if ($ escapePattern ) {
1135+ $ searchProperties = array_filter ($ searchProperties , function ($ property ) use ($ pattern ) {
11361136 if ($ property === 'EMAIL ' && str_contains ($ pattern , ' ' )) {
11371137 // There can be no spaces in emails
1138- continue ;
1138+ return false ;
11391139 }
11401140
11411141 if ($ property === 'CLOUD ' && preg_match ('/[^a-zA-Z0-9 :_.@\/\- \']/ ' , $ pattern ) === 1 ) {
11421142 // There can be no chars in cloud ids which are not valid for user ids plus :/
11431143 // worst case: CA61590A-BBBC-423E-84AF-E6DF01455A53@https://my.nxt/srv/
1144- continue ;
1144+ return false ;
11451145 }
1146- }
11471146
1148- $ propertyOr ->add ($ query2 ->expr ()->eq ('cp.name ' , $ query2 ->createNamedParameter ($ property )));
1147+ return true ;
1148+ });
11491149 }
11501150
1151- if ($ propertyOr -> count () === 0 ) {
1151+ if (empty ( $ searchProperties ) ) {
11521152 return [];
11531153 }
11541154
11551155 $ query2 ->selectDistinct ('cp.cardid ' )
11561156 ->from ($ this ->dbCardsPropertiesTable , 'cp ' )
11571157 ->andWhere ($ addressBookOr )
1158- ->andWhere ($ propertyOr );
1158+ ->andWhere ($ query2 -> expr ()-> in ( ' cp.name ' , $ query2 -> createNamedParameter ( $ searchProperties , IQueryBuilder:: PARAM_STR_ARRAY )) );
11591159
11601160 // No need for like when the pattern is empty
11611161 if ('' !== $ pattern ) {
@@ -1167,14 +1167,39 @@ private function searchByAddressBookIds(array $addressBookIds,
11671167 $ query2 ->andWhere ($ query2 ->expr ()->ilike ('cp.value ' , $ query2 ->createNamedParameter ('% ' . $ this ->db ->escapeLikeParameter ($ pattern ) . '% ' )));
11681168 }
11691169 }
1170-
11711170 if (isset ($ options ['limit ' ])) {
11721171 $ query2 ->setMaxResults ($ options ['limit ' ]);
11731172 }
11741173 if (isset ($ options ['offset ' ])) {
11751174 $ query2 ->setFirstResult ($ options ['offset ' ]);
11761175 }
11771176
1177+ if (
1178+ $ options ['since ' ] instanceof DateTimeFilter
1179+ || $ options ['until ' ] instanceof DateTimeFilter
1180+ ) {
1181+ $ query2 ->join ('cp ' , $ this ->dbCardsPropertiesTable , 'cp_bday ' , 'cp.cardid = cp_bday.cardid ' );
1182+ $ query2 ->andWhere ($ query2 ->expr ()->eq ('cp_bday.name ' , $ query2 ->createNamedParameter ('BDAY ' )));
1183+ /**
1184+ * FIXME Find a way to match only 4 last digits
1185+ * BDAY can be --1018 without year or 20001019 with it
1186+ * $bDayOr = $query2->expr()->orX();
1187+ * if ($options['since'] instanceof DateTimeFilter) {
1188+ * $bDayOr->add(
1189+ * $query2->expr()->gte('SUBSTR(cp_bday.value, -4)',
1190+ * $query2->createNamedParameter($options['since']->get()->format('md')))
1191+ * );
1192+ * }
1193+ * if ($options['until'] instanceof DateTimeFilter) {
1194+ * $bDayOr->add(
1195+ * $query2->expr()->lte('SUBSTR(cp_bday.value, -4)',
1196+ * $query2->createNamedParameter($options['until']->get()->format('md')))
1197+ * );
1198+ * }
1199+ * $query2->andWhere($bDayOr);
1200+ */
1201+ }
1202+
11781203 $ result = $ query2 ->execute ();
11791204 $ matches = $ result ->fetchAll ();
11801205 $ result ->closeCursor ();
@@ -1410,7 +1435,7 @@ public function pruneOutdatedSyncTokens(int $keep = 10_000): int {
14101435 $ maxId = (int ) $ result ->fetchOne ();
14111436 $ result ->closeCursor ();
14121437 if (!$ maxId || $ maxId < $ keep ) {
1413- return 0 ;
1438+ return 0 ;
14141439 }
14151440
14161441 $ query = $ this ->db ->getQueryBuilder ();
0 commit comments