aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Group/Database.php52
-rw-r--r--lib/private/Group/Group.php17
-rw-r--r--lib/private/User/LazyUser.php20
-rw-r--r--lib/private/User/Manager.php29
-rw-r--r--lib/public/Group/Backend/ABackend.php15
-rw-r--r--lib/public/GroupInterface.php24
-rw-r--r--lib/public/IGroup.php2
7 files changed, 126 insertions, 33 deletions
diff --git a/lib/private/Group/Database.php b/lib/private/Group/Database.php
index 5f17477db77..bfc95c574e2 100644
--- a/lib/private/Group/Database.php
+++ b/lib/private/Group/Database.php
@@ -43,6 +43,9 @@ use OCP\Group\Backend\IRemoveFromGroupBackend;
use OCP\Group\Backend\ISetDisplayNameBackend;
use OCP\Group\Backend\INamedBackend;
use OCP\IDBConnection;
+use OCP\IUserManager;
+use OC\User\LazyUser;
+use OC\User\DisplayNameCache;
/**
* Class for group management in a SQL Database (e.g. MySQL, SQLite)
@@ -376,6 +379,55 @@ class Database extends ABackend implements
return $users;
}
+ public function searchInGroup(string $gid, string $search = '', int $limit = -1, int $offset = 0): array {
+ $this->fixDI();
+
+ $query = $this->dbConn->getQueryBuilder();
+ $query->select('g.uid', 'u.displayname');
+
+ $query->from('group_user', 'g')
+ ->where($query->expr()->eq('gid', $query->createNamedParameter($gid)))
+ ->orderBy('g.uid', 'ASC');
+
+ $query->leftJoin('g', 'users', 'u', $query->expr()->eq('g.uid', 'u.uid'))
+
+ if ($search !== '') {
+ $query->leftJoin('u', 'preferences', 'p', $query->expr()->andX(
+ $query->expr()->eq('p.userid', 'u.uid'),
+ $query->expr()->eq('p.appid', $query->expr()->literal('settings')),
+ $query->expr()->eq('p.configkey', $query->expr()->literal('email'))
+ ))
+ // sqlite doesn't like re-using a single named parameter here
+ ->andWhere(
+ $query->expr()->orX(
+ $query->expr()->ilike('g.uid', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')),
+ $query->expr()->ilike('u.displayname', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')),
+ $query->expr()->ilike('p.configvalue', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))
+ )
+ )
+ ->orderBy('u.uid_lower', 'ASC');
+ }
+
+ if ($limit !== -1) {
+ $query->setMaxResults($limit);
+ }
+ if ($offset !== 0) {
+ $query->setFirstResult($offset);
+ }
+
+ $result = $query->executeQuery();
+
+ $users = [];
+ $userManager = \OCP\Server::get(IUserManager::class);
+ $displayNameCache = \OCP\Server::get(DisplayNameCache::class);
+ while ($row = $result->fetch()) {
+ $users[$row['uid']] = new LazyUser($row['uid'], $displayNameCache, $userManager, $row['displayname'] ?? null);
+ }
+ $result->closeCursor();
+
+ return $users;
+ }
+
/**
* get the number of all users matching the search string in a group
* @param string $gid
diff --git a/lib/private/Group/Group.php b/lib/private/Group/Group.php
index cca179bfe19..b2903bcdb26 100644
--- a/lib/private/Group/Group.php
+++ b/lib/private/Group/Group.php
@@ -242,18 +242,13 @@ class Group implements IGroup {
}
/**
- * search for users in the group by userid
- *
- * @param string $search
- * @param int $limit
- * @param int $offset
- * @return \OC\User\User[]
+ * Search for users in the group by userid or display name
+ * @return IUser[]
*/
- public function searchUsers($search, $limit = null, $offset = null) {
+ public function searchUsers(string $search, ?int $limit = null, ?int $offset = null): array {
$users = [];
foreach ($this->backends as $backend) {
- $userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset);
- $users += $this->getVerifiedUsers($userIds);
+ $users = array_merge($users, $backend->searchInGroup($this->gid, $search, $limit ?? -1, $offset ?? 0));
if (!is_null($limit) and $limit <= 0) {
return $users;
}
@@ -309,12 +304,12 @@ class Group implements IGroup {
* @param int $limit
* @param int $offset
* @return \OC\User\User[]
+ * @deprecated 25.0.0 Use searchUsers instead (same implementation)
*/
public function searchDisplayName($search, $limit = null, $offset = null) {
$users = [];
foreach ($this->backends as $backend) {
- $userIds = $backend->usersInGroup($this->gid, $search, $limit, $offset);
- $users = $this->getVerifiedUsers($userIds);
+ $users = array_merge($users, $backend->searchInGroup($this->gid, $search, $limit ?? -1, $offset ?? 0));
if (!is_null($limit) and $limit <= 0) {
return array_values($users);
}
diff --git a/lib/private/User/LazyUser.php b/lib/private/User/LazyUser.php
index 096578b8f37..c36ff86eff4 100644
--- a/lib/private/User/LazyUser.php
+++ b/lib/private/User/LazyUser.php
@@ -30,16 +30,26 @@ use OCP\UserInterface;
class LazyUser implements IUser {
private ?IUser $user = null;
private string $uid;
+ private ?string $displayName;
private IUserManager $userManager;
+ private ?UserInterface $backend;
- public function __construct(string $uid, IUserManager $userManager) {
+ public function __construct(string $uid, IUserManager $userManager, ?string $displayName = null, ?UserInterface $backend = null) {
$this->uid = $uid;
$this->userManager = $userManager;
+ $this->displayName = $displayName;
+ $this->backend = $backend;
}
private function getUser(): IUser {
if ($this->user === null) {
- $this->user = $this->userManager->get($this->uid);
+ if ($this->backend) {
+ /** @var \OC\User\Manager $manager */
+ $manager = $this->userManager;
+ $this->user = $manager->getUserObject($this->uid, $this->backend);
+ } else {
+ $this->user = $this->userManager->get($this->uid);
+ }
}
/** @var IUser */
$user = $this->user;
@@ -51,7 +61,11 @@ class LazyUser implements IUser {
}
public function getDisplayName() {
- return $this->userManager->getDisplayName($this->uid) ?? $this->uid;
+ if ($this->displayName) {
+ return $this->displayName;
+ }
+
+ return $this->userManager->getDisplayName($this->uid);
}
public function setDisplayName($displayName) {
diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php
index 859ebd2a604..c3275934a5a 100644
--- a/lib/private/User/Manager.php
+++ b/lib/private/User/Manager.php
@@ -202,7 +202,7 @@ class Manager extends PublicEmitter implements IUserManager {
* @param bool $cacheUser If false the newly created user object will not be cached
* @return \OC\User\User
*/
- protected function getUserObject($uid, $backend, $cacheUser = true) {
+ public function getUserObject($uid, $backend, $cacheUser = true) {
if ($backend instanceof IGetRealUIDBackend) {
$uid = $backend->getRealUID($uid);
}
@@ -293,58 +293,53 @@ class Manager extends PublicEmitter implements IUserManager {
}
/**
- * search by user id
+ * Search by user id
*
* @param string $pattern
* @param int $limit
* @param int $offset
- * @return \OC\User\User[]
+ * @return IUser[]
+ * @deprecated since 25.0.0, use searchDisplayName instead
*/
public function search($pattern, $limit = null, $offset = null) {
$users = [];
+ $displayNameCache = \OCP\Server::get(DisplayNameCache::class);
foreach ($this->backends as $backend) {
$backendUsers = $backend->getUsers($pattern, $limit, $offset);
if (is_array($backendUsers)) {
foreach ($backendUsers as $uid) {
- $users[$uid] = $this->getUserObject($uid, $backend);
+ $users[$uid] = new LazyUser($uid, $displayNameCache, $this, null, $backend);
}
}
}
- uasort($users, function ($a, $b) {
- /**
- * @var \OC\User\User $a
- * @var \OC\User\User $b
- */
+ uasort($users, function (IUser $a, IUser $b) {
return strcasecmp($a->getUID(), $b->getUID());
});
return $users;
}
/**
- * search by displayName
+ * Search by displayName
*
* @param string $pattern
* @param int $limit
* @param int $offset
- * @return \OC\User\User[]
+ * @return IUser[]
*/
public function searchDisplayName($pattern, $limit = null, $offset = null) {
$users = [];
+ $displayNameCache = \OCP\Server::get(DisplayNameCache::class);
foreach ($this->backends as $backend) {
$backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
if (is_array($backendUsers)) {
foreach ($backendUsers as $uid => $displayName) {
- $users[] = $this->getUserObject($uid, $backend);
+ $users[] = new LazyUser($uid, $displayNameCache, $this, $displayName, $backend);
}
}
}
- usort($users, function ($a, $b) {
- /**
- * @var \OC\User\User $a
- * @var \OC\User\User $b
- */
+ usort($users, function (IUser $a, IUser $b) {
return strcasecmp($a->getDisplayName(), $b->getDisplayName());
});
return $users;
diff --git a/lib/public/Group/Backend/ABackend.php b/lib/public/Group/Backend/ABackend.php
index 7f5cf732335..e76285dfda9 100644
--- a/lib/public/Group/Backend/ABackend.php
+++ b/lib/public/Group/Backend/ABackend.php
@@ -26,6 +26,10 @@ declare(strict_types=1);
namespace OCP\Group\Backend;
use OCP\GroupInterface;
+use OCP\IUserManager;
+use OCP\Server;
+use OC\User\LazyUser;
+use OC\User\DisplayNameCache;
/**
* @since 14.0.0
@@ -65,4 +69,15 @@ abstract class ABackend implements GroupInterface {
return (bool)($actions & $implements);
}
+
+ public function searchInGroup(string $gid, string $search = '', int $limit = -1, int $offset = 0): array {
+ // Default implementation for compatibility reasons
+ $displayNameCache = Server::get(DisplayNameCache::class);
+ $userManager = Server::get(IUserManager::class);
+ $users = [];
+ foreach ($this->usersInGroup($gid, $search, $limit, $offset) as $userId) {
+ $users[$userId] = new LazyUser($userId, $displayNameCache, $userManager);
+ }
+ return $users;
+ }
}
diff --git a/lib/public/GroupInterface.php b/lib/public/GroupInterface.php
index b7c07136126..07fd5cb50c4 100644
--- a/lib/public/GroupInterface.php
+++ b/lib/public/GroupInterface.php
@@ -106,13 +106,35 @@ interface GroupInterface {
public function groupExists($gid);
/**
- * get a list of all users in a group
+ * @brief Get a list of user ids in a group matching the given search parameters.
+ *
* @param string $gid
* @param string $search
* @param int $limit
* @param int $offset
* @return array an array of user ids
* @since 4.5.0
+ * @deprecated 25.0.0 Use searchInGroup instead, for performance reasons
*/
public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0);
+
+ /**
+ * @brief Get a list of users matching the given search parameters.
+ *
+ * Implementations of this method should return lazy evaluated user objects and
+ * preload if possible the display name.
+ *
+ * <code>
+ * $users = $groupBackend->searchInGroup('admin', 'John', 10, 0);
+ * </code>
+ *
+ * @param string $gid The group id of the user we want to search
+ * @param string $search The part of the display name or user id of the users we
+ * want to search. This can be empty to get all the users.
+ * @param int $limit The limit of results
+ * @param int $offset The offset of the results
+ * @return IUser[]
+ * @since 25.0.0
+ */
+ public function searchInGroup(string $gid, string $search = '', int $limit = -1, int $offset = 0): array;
}
diff --git a/lib/public/IGroup.php b/lib/public/IGroup.php
index ba13359c472..ec26cc55b69 100644
--- a/lib/public/IGroup.php
+++ b/lib/public/IGroup.php
@@ -99,7 +99,7 @@ interface IGroup {
* @return \OCP\IUser[]
* @since 8.0.0
*/
- public function searchUsers($search, $limit = null, $offset = null);
+ public function searchUsers(string $search, ?int $limit = null, ?int $offset = null): array;
/**
* returns the number of users matching the search string