From 204f63fa298f7d7dfa96139eb947a374f333e39b Mon Sep 17 00:00:00 2001 From: Li Ji Date: Wed, 4 Jan 2017 04:13:58 +0800 Subject: [PATCH] Add group gambit to support search user by group name (#1073) Add group gambit to support search user by group name /api/users?filter[q]=group:admin /api/users?filter[q]=group:admin,mod refer to #256 --- .../src/Core/Repository/GroupRepository.php | 13 ++++ .../src/Core/Search/SearchServiceProvider.php | 2 +- .../Core/Search/User/Gambit/GroupGambit.php | 62 +++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 framework/core/src/Core/Search/User/Gambit/GroupGambit.php diff --git a/framework/core/src/Core/Repository/GroupRepository.php b/framework/core/src/Core/Repository/GroupRepository.php index 88519c71e..658c3739b 100644 --- a/framework/core/src/Core/Repository/GroupRepository.php +++ b/framework/core/src/Core/Repository/GroupRepository.php @@ -44,6 +44,19 @@ class GroupRepository return $this->scopeVisibleTo($query, $actor)->firstOrFail(); } + /** + * Find a group by name. + * + * @param string $name + * @return User|null + */ + public function findByName($name, User $actor = null) + { + $query = Group::where('name_singular', $name)->orWhere('name_plural', $name); + + return $this->scopeVisibleTo($query, $actor)->first(); + } + /** * Scope a query to only include records that are visible to a user. * diff --git a/framework/core/src/Core/Search/SearchServiceProvider.php b/framework/core/src/Core/Search/SearchServiceProvider.php index 66cd44312..aaf53a481 100644 --- a/framework/core/src/Core/Search/SearchServiceProvider.php +++ b/framework/core/src/Core/Search/SearchServiceProvider.php @@ -44,7 +44,7 @@ class SearchServiceProvider extends AbstractServiceProvider $gambits->setFulltextGambit('Flarum\Core\Search\User\Gambit\FulltextGambit'); $gambits->add('Flarum\Core\Search\User\Gambit\EmailGambit'); - + $gambits->add('Flarum\Core\Search\User\Gambit\GroupGambit'); $app->make('events')->fire( new ConfigureUserGambits($gambits) ); diff --git a/framework/core/src/Core/Search/User/Gambit/GroupGambit.php b/framework/core/src/Core/Search/User/Gambit/GroupGambit.php new file mode 100644 index 000000000..4d5481f0e --- /dev/null +++ b/framework/core/src/Core/Search/User/Gambit/GroupGambit.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Core\Search\User\Gambit; + +use Flarum\Core\Repository\GroupRepository; +use Flarum\Core\Search\AbstractRegexGambit; +use Flarum\Core\Search\AbstractSearch; +use Flarum\Core\Search\User\UserSearch; +use LogicException; + +class GroupGambit extends AbstractRegexGambit +{ + /** + * {@inheritdoc} + */ + protected $pattern = 'group:(.+)'; + + /** + * @var GroupRepository + */ + protected $groups; + + /** + * @param \Flarum\Core\Repository\GroupRepository $groups + */ + public function __construct(GroupRepository $groups) + { + $this->groups = $groups; + } + + /** + * {@inheritdoc} + */ + protected function conditions(AbstractSearch $search, array $matches, $negate) + { + if (! $search instanceof UserSearch) { + throw new LogicException('This gambit can only be applied on a UserSearch'); + } + + $groupName = trim($matches[1], '"'); + $groupName = explode(',', $groupName); + + $ids = []; + foreach ($groupName as $name) { + $group = $this->groups->findByName($name); + if ($group && count($group->users)) { + $ids = array_merge($ids, $group->users->pluck('id')->all()); + } + } + + $search->getQuery()->whereIn('id', $ids, 'and', $negate); + } +}