mirror of
https://github.com/humhub/humhub.git
synced 2025-02-24 19:23:21 +01:00
Moved directory member search into database instead of Lucence index
This commit is contained in:
parent
18df3db3cf
commit
578f0c4427
@ -31,9 +31,9 @@ class Module extends \humhub\components\Module
|
||||
public $isCoreModule = true;
|
||||
|
||||
/**
|
||||
* @var string sort field (e.g. lastname) of member list (leave empty to sort by auto sort search)
|
||||
* @var string sort field (e.g. lastname) of member list
|
||||
*/
|
||||
public $memberListSortField = '';
|
||||
public $memberListSortField = 'profile.lastname';
|
||||
|
||||
/**
|
||||
* @var int default page size for directory pages
|
||||
|
@ -10,6 +10,7 @@ namespace humhub\modules\directory\controllers;
|
||||
|
||||
use humhub\modules\directory\components\UserPostsStreamAction;
|
||||
use humhub\modules\directory\components\Controller;
|
||||
use humhub\modules\directory\Module;
|
||||
use humhub\modules\user\models\Group;
|
||||
use humhub\modules\user\models\User;
|
||||
use humhub\modules\space\models\Space;
|
||||
@ -22,13 +23,14 @@ use humhub\modules\directory\widgets\GroupStatistics;
|
||||
use yii\data\Pagination;
|
||||
use yii\base\Event;
|
||||
use Yii;
|
||||
use yii\web\HttpException;
|
||||
|
||||
/**
|
||||
* Community/Directory Controller
|
||||
*
|
||||
* Shows all available users, group, spaces
|
||||
*
|
||||
* @package humhub.modules_core.directory.controllers
|
||||
* @property Module $module
|
||||
* @since 0.5
|
||||
*/
|
||||
class DirectoryController extends Controller
|
||||
@ -74,52 +76,49 @@ class DirectoryController extends Controller
|
||||
|
||||
/**
|
||||
* Action for the members section of the directory
|
||||
*
|
||||
* @todo Dont pass lucene hits to view, build user array inside of action
|
||||
*/
|
||||
public function actionMembers()
|
||||
{
|
||||
$keyword = Yii::$app->request->get('keyword', '');
|
||||
$page = (int) Yii::$app->request->get('page', 1);
|
||||
$groupId = (int) Yii::$app->request->get('groupId', '');
|
||||
$keyword = (string)Yii::$app->request->get('keyword');
|
||||
|
||||
$query = User::find()->visible()->search($keyword);
|
||||
|
||||
// Restrict to group
|
||||
$group = null;
|
||||
$groupId = (int)Yii::$app->request->get('groupId');
|
||||
if ($groupId) {
|
||||
$group = Group::findOne(['id' => $groupId, 'show_at_directory' => 1]);
|
||||
if ($group === null) {
|
||||
throw new HttpException(404);
|
||||
}
|
||||
$query->isGroupMember($group);
|
||||
}
|
||||
|
||||
$searchOptions = [
|
||||
'model' => User::class,
|
||||
'page' => $page,
|
||||
'pageSize' => $this->module->pageSize,
|
||||
];
|
||||
|
||||
if ($this->module->memberListSortField != '') {
|
||||
$searchOptions['sortField'] = $this->module->memberListSortField;
|
||||
$countQuery = clone $query;
|
||||
$pagination = new Pagination(['totalCount' => $countQuery->count()]);
|
||||
|
||||
// Order
|
||||
$query->joinWith('profile');
|
||||
if (empty($this->module->memberListSortField) || $this->module->memberListSortField === 'lastname' || $this->module->memberListSortField === 'firstname') {
|
||||
// Fallback to default value
|
||||
$query->addOrderBy('profile.lastname');
|
||||
} else {
|
||||
$query->addOrderBy($this->module->memberListSortField);
|
||||
}
|
||||
|
||||
if ($group !== null) {
|
||||
$searchOptions['filters'] = ['groups' => $group->id];
|
||||
}
|
||||
|
||||
$searchResultSet = Yii::$app->search->find($keyword, $searchOptions);
|
||||
|
||||
$pagination = new Pagination([
|
||||
'totalCount' => $searchResultSet->total,
|
||||
'pageSize' => $searchResultSet->pageSize
|
||||
]);
|
||||
|
||||
Event::on(Sidebar::class, Sidebar::EVENT_INIT, function ($event) {
|
||||
$event->sender->addWidget(NewMembers::class, [], ['sortOrder' => 10]);
|
||||
$event->sender->addWidget(MemberStatistics::class, [], ['sortOrder' => 20]);
|
||||
});
|
||||
|
||||
return $this->render('members', [
|
||||
'keyword' => $keyword,
|
||||
'group' => $group,
|
||||
'users' => $searchResultSet->getResultInstances(),
|
||||
'pagination' => $pagination
|
||||
'keyword' => $keyword,
|
||||
'group' => $group,
|
||||
'users' => $query->offset($pagination->offset)->limit($pagination->limit)->all(),
|
||||
'pagination' => $pagination
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,7 +131,7 @@ class DirectoryController extends Controller
|
||||
public function actionSpaces()
|
||||
{
|
||||
$keyword = Yii::$app->request->get('keyword', '');
|
||||
$page = (int) Yii::$app->request->get('page', 1);
|
||||
$page = (int)Yii::$app->request->get('page', 1);
|
||||
|
||||
$searchResultSet = Yii::$app->search->find($keyword, [
|
||||
'model' => Space::class,
|
||||
@ -142,8 +141,8 @@ class DirectoryController extends Controller
|
||||
]);
|
||||
|
||||
$pagination = new Pagination([
|
||||
'totalCount' => $searchResultSet->total,
|
||||
'pageSize' => $searchResultSet->pageSize
|
||||
'totalCount' => $searchResultSet->total,
|
||||
'pageSize' => $searchResultSet->pageSize
|
||||
]);
|
||||
|
||||
Event::on(Sidebar::class, Sidebar::EVENT_INIT, function ($event) {
|
||||
@ -152,9 +151,9 @@ class DirectoryController extends Controller
|
||||
});
|
||||
|
||||
return $this->render('spaces', [
|
||||
'keyword' => $keyword,
|
||||
'spaces' => $searchResultSet->getResultInstances(),
|
||||
'pagination' => $pagination,
|
||||
'keyword' => $keyword,
|
||||
'spaces' => $searchResultSet->getResultInstances(),
|
||||
'pagination' => $pagination,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -176,7 +175,7 @@ class DirectoryController extends Controller
|
||||
});
|
||||
|
||||
return $this->render('groups', [
|
||||
'groups' => $groups,
|
||||
'groups' => $groups,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
namespace humhub\modules\user\components;
|
||||
|
||||
use humhub\modules\user\models\Group;
|
||||
use humhub\modules\user\models\ProfileField;
|
||||
use yii\db\ActiveQuery;
|
||||
use humhub\modules\user\models\User as UserModel;
|
||||
use humhub\events\ActiveQueryEvent;
|
||||
@ -19,6 +21,7 @@ use humhub\events\ActiveQueryEvent;
|
||||
*/
|
||||
class ActiveQueryUser extends ActiveQuery
|
||||
{
|
||||
const MAX_SEARCH_NEEDLES = 5;
|
||||
|
||||
/**
|
||||
* @event Event an event that is triggered when only visible users are requested via [[visible()]].
|
||||
@ -32,7 +35,7 @@ class ActiveQueryUser extends ActiveQuery
|
||||
|
||||
/**
|
||||
* Limit to active users
|
||||
*
|
||||
*
|
||||
* @return ActiveQueryUser the query
|
||||
*/
|
||||
public function active()
|
||||
@ -46,9 +49,9 @@ class ActiveQueryUser extends ActiveQuery
|
||||
/**
|
||||
* Returns only users that should appear in user lists or in the search results.
|
||||
* Also only active (enabled) users are returned.
|
||||
*
|
||||
* @since 1.2.3
|
||||
*
|
||||
* @return ActiveQueryUser the query
|
||||
* @since 1.2.3
|
||||
*/
|
||||
public function visible()
|
||||
{
|
||||
@ -56,9 +59,10 @@ class ActiveQueryUser extends ActiveQuery
|
||||
return $this->active();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds default user order (e.g. by lastname)
|
||||
*
|
||||
*
|
||||
* @return ActiveQueryUser the query
|
||||
*/
|
||||
public function defaultOrder()
|
||||
@ -69,4 +73,62 @@ class ActiveQueryUser extends ActiveQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a user full text search
|
||||
*
|
||||
* @param string|array $keywords
|
||||
* @param array|null $fields if empty all searchable profile fields will be used
|
||||
*/
|
||||
public function search($keywords, $fields = null)
|
||||
{
|
||||
if (empty($keywords)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($fields)) {
|
||||
$fields = $this->getSearchableUserFields();
|
||||
}
|
||||
|
||||
$this->joinWith('profile');
|
||||
|
||||
if (!is_array($keywords)) {
|
||||
$keywords = explode(' ', $keywords);
|
||||
}
|
||||
|
||||
foreach (array_slice($keywords, 0, static::MAX_SEARCH_NEEDLES) as $keyword) {
|
||||
$conditions = [];
|
||||
foreach ($fields as $field) {
|
||||
$conditions[] = ['LIKE', $field, $keyword];
|
||||
}
|
||||
$this->andWhere(array_merge(['OR'], $conditions));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of fields to be included in a user search.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getSearchableUserFields()
|
||||
{
|
||||
$fields = ['user.username', 'user.email', 'user.tags'];
|
||||
foreach (ProfileField::findAll(['searchable' => 1]) as $profileField) {
|
||||
$fields[] = $profileField->internal_name;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits the query to a specified user group
|
||||
*
|
||||
* @param Group $group
|
||||
*/
|
||||
public function isGroupMember(Group $group)
|
||||
{
|
||||
$this->leftJoin('group_user', 'user.id=group_user.user_id');
|
||||
$this->andWhere(['group_user.group_id' => $group->id]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ use yii\db\ActiveQuery;
|
||||
* @property string $ldap_attribute
|
||||
* @property string $translation_category
|
||||
* @property integer $is_system
|
||||
* @property integer $searchable
|
||||
*/
|
||||
class ProfileField extends ActiveRecord
|
||||
{
|
||||
|
@ -447,7 +447,6 @@ class User extends ContentContainerActiveRecord implements IdentityInterface, Se
|
||||
public function beforeSave($insert)
|
||||
{
|
||||
if ($insert) {
|
||||
|
||||
if ($this->auth_mode == '') {
|
||||
$passwordAuth = new PasswordAuth();
|
||||
$this->auth_mode = $passwordAuth->getId();
|
||||
|
Loading…
x
Reference in New Issue
Block a user