diff options
author | Bjoern Schiessle <bjoern@schiessle.org> | 2017-06-22 18:14:50 +0300 |
---|---|---|
committer | Bjoern Schiessle <bjoern@schiessle.org> | 2017-06-22 18:27:54 +0300 |
commit | f79f34ef1327a88bcce35df25b0d6ca1c2f11903 (patch) | |
tree | feafb8807c73026ed32f5c73eaa3f423c8e67d8d | |
parent | 7ec825e8021a00d5f4c5b2b8fb07e8d6239c12a4 (diff) |
cleanup search logic
Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
-rw-r--r-- | server/lib/UserManager.php | 119 |
1 files changed, 44 insertions, 75 deletions
diff --git a/server/lib/UserManager.php b/server/lib/UserManager.php index cf04e40..52a895e 100644 --- a/server/lib/UserManager.php +++ b/server/lib/UserManager.php @@ -64,34 +64,62 @@ class UserManager { } $search = $params['search']; - $searchCloudId = isset($params['exactCloudId']) ? $params['exactCloudId'] : '0'; - $gssSearch = isset($params['gss']) ? $params['gss'] : '0'; + // search for a specific federated cloud ID + $searchCloudId = isset($params['exactCloudId']) ? $params['exactCloudId'] === '1' : '0'; + // return unique exact match, e.g. the user with a specific email address + $exactMatch = isset($params['exact']) ? $params['exact'] === '1' : false; + + // parameters allow you to specify which keys should be checked for a search query + // by default we check all keys, this way you can for example search for email addresses only + $parameters = []; + if ($exactMatch === true) { + $keys = isset($params['keys']) ? $params['keys'] : '{}'; + $keysDecoded = json_decode($keys, false, 2); + if (is_array($keysDecoded)) { + $parameters = $keysDecoded; + } + } - if ($searchCloudId === '1') { + if ($searchCloudId === true) { $users = $this->getExactCloudId($search); - } else if ($gssSearch === '1') { - // lookup request from a global site selector to login the user - $users = $this->gssLookup($search); } else if ($this->globalScaleMode === true) { // in a global scale setup we ignore the karma - // this is used to find people you want to share with - $users = $this->searchNoKarma(); + // the lookup server is populated by the admin and we know + // that it contain only valid user information + $users = $this->performSearch($search, $exactMatch, $parameters, 0); } else { - $users = $this->searchKarma(); + // in a general setup we only return users who validated at least one personal date + $users = $this->performSearch($search, $exactMatch, $parameters, 1); + } + + // if we look for a exact match we return only this one result, not a list of one element + if($exactMatch && !empty($users)) { + $users = $users[0]; } $response->getBody()->write(json_encode($users)); return $response; } + + /** * search user, for example to share with them * return all results with karma >= 1 * - * @param $search + * @param string $search + * @param bool $exactMatch + * @param array $parameters + * @param int $minKarma * @return array */ - private function searchKarma($search) { + private function performSearch($search, $exactMatch, $parameters, $minKarma) { + + $operator = $exactMatch ? ' = ' : ' LIKE '; + $limit = $exactMatch ? ' 1 ' : ' 50 '; + $constraint = empty($parameters) ? '' : ' AND k IN (\'' . implode( '\', \'', $parameters ) . '\') '; + + $stmt = $this->db->prepare('SELECT * FROM ( SELECT userId AS userId, SUM(valid) AS karma @@ -99,52 +127,17 @@ FROM ( WHERE userId IN ( SELECT DISTINCT userId FROM `store` - WHERE v LIKE :search + WHERE v ' . $operator . ' :search ' . $constraint .' ) GROUP BY userId ) AS tmp -WHERE karma > 0 +WHERE karma >= ' . $minKarma . ' ORDER BY karma -LIMIT 50'); - $search = '%' . $search . '%'; - $stmt->bindParam(':search', $search, \PDO::PARAM_STR); - $stmt->execute(); - - /* - * TODO: Better fuzzy search? - */ +LIMIT ' . $limit); - $users = []; - while($data = $stmt->fetch()) { - $users[] = $this->getForUserId((int)$data['userId']); - } - $stmt->closeCursor(); - - return $users; - } - - - /** - * search user, for example to share with them - * return all results, ignoring the karma - * in a global scale setup we assume that all - * entries are trustworthy - * - * @param $search - * @return array - */ - private function searchNoKarma($search) { - $stmt = $this->db->prepare('SELECT * -FROM `store` - WHERE userId IN ( - SELECT DISTINCT userId - FROM `store` - WHERE v LIKE :search - ) - GROUP BY userId - LIMIT 50'); - $search = '%' . $search . '%'; + $search = $exactMatch ? $search : '%' . $search . '%'; $stmt->bindParam(':search', $search, \PDO::PARAM_STR); + $stmt->execute(); /* @@ -160,30 +153,6 @@ FROM `store` return $users; } - /** - * find the user who want to login in a global scale setup - * we return the first exact match - * - * @param $search - * @return array - */ - private function gssLookup($search) { - $stmt = $this->db->prepare('SELECT * FROM `store` WHERE v = :search LIMIT 1'); - $stmt->bindParam(':search', $search, \PDO::PARAM_STR); - $stmt->execute(); - - $data = $stmt->fetch(); - $stmt->closeCursor(); - - $user = []; - - if (isset($data['userId'])) { - $user = $this->getForUserId((int)$data['userId']); - } - - return $user; - } - private function getExactCloudId($cloudId) { $stmt = $this->db->prepare('SELECT id FROM users WHERE federationId = :id'); |