Skip to content

Commit

Permalink
chore: allow using usernames in filters
Browse files Browse the repository at this point in the history
  • Loading branch information
SychO9 committed Sep 17, 2024
1 parent 2ecedfb commit 7d7f5ce
Show file tree
Hide file tree
Showing 14 changed files with 62 additions and 11 deletions.
2 changes: 1 addition & 1 deletion extensions/likes/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ app.initializers.add('flarum-likes', () => {
});
extend('flarum/forum/components/SearchModal', 'defaultFilters', function (filters) {
if (app.current.data.routeName && app.current.data.routeName.includes('user.likes') && app.current.data.user) {
filters.posts.likedBy = app.current.data.user.id();
filters.posts.likedBy = app.current.data.user.username();
}
});
});
2 changes: 1 addition & 1 deletion extensions/likes/locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ flarum-likes:
posts:
likedBy:
key: likedBy
hint: The ID of the user
hint: The ID or username of the user
14 changes: 13 additions & 1 deletion extensions/likes/src/Query/LikedByFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Flarum\Search\Filter\FilterInterface;
use Flarum\Search\SearchState;
use Flarum\Search\ValidateFilterTrait;
use Flarum\User\UserRepository;

/**
* @implements FilterInterface<DatabaseSearchState>
Expand All @@ -21,14 +22,25 @@ class LikedByFilter implements FilterInterface
{
use ValidateFilterTrait;

public function __construct(
protected UserRepository $users
) {
}

public function getFilterKey(): string
{
return 'likedBy';
}

public function filter(SearchState $state, string|array $value, bool $negate): void
{
$likedId = $this->asInt($value);
$likedUsername = $this->asString($value);

$likedId = $this->users->getIdForUsername($likedUsername);

if (! $likedId) {
$likedId = intval($likedUsername);
}

$state
->getQuery()
Expand Down
6 changes: 6 additions & 0 deletions extensions/likes/src/Query/LikedFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Flarum\Search\Filter\FilterInterface;
use Flarum\Search\SearchState;
use Flarum\Search\ValidateFilterTrait;
use Flarum\User\UserRepository;

/**
* @implements FilterInterface<DatabaseSearchState>
Expand All @@ -21,6 +22,11 @@ class LikedFilter implements FilterInterface
{
use ValidateFilterTrait;

public function __construct(
protected UserRepository $users
) {
}

public function getFilterKey(): string
{
return 'liked';
Expand Down
2 changes: 1 addition & 1 deletion extensions/mentions/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ app.initializers.add('flarum-mentions', () => {
});
extend('flarum/forum/components/SearchModal', 'defaultFilters', function (filters) {
if (app.current.data.routeName && app.current.data.routeName.includes('user.mentions') && app.current.data.user) {
filters.posts.mentioned = app.current.data.user.id();
filters.posts.mentioned = app.current.data.user.username();
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion extensions/mentions/locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,4 @@ flarum-mentions:
posts:
mentioned:
key: mentioned
hint: The ID of the mentioned user
hint: The ID or username of the mentioned user
14 changes: 13 additions & 1 deletion extensions/mentions/src/Filter/MentionedFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Flarum\Search\Filter\FilterInterface;
use Flarum\Search\SearchState;
use Flarum\Search\ValidateFilterTrait;
use Flarum\User\UserRepository;

/**
* @implements FilterInterface<DatabaseSearchState>
Expand All @@ -21,14 +22,25 @@ class MentionedFilter implements FilterInterface
{
use ValidateFilterTrait;

public function __construct(
protected UserRepository $users
) {
}

public function getFilterKey(): string
{
return 'mentioned';
}

public function filter(SearchState $state, string|array $value, bool $negate): void
{
$mentionedId = $this->asInt($value);
$mentionedUsername = $this->asString($value);

$mentionedId = $this->users->getIdForUsername($mentionedUsername);

if (! $mentionedId) {
$mentionedId = intval($mentionedUsername);
}

$state
->getQuery()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ import type { DiscussionListParams } from '../states/DiscussionListState';
import Icon from '../../common/components/Icon';
import Avatar from '../../common/components/Avatar';
import Post from '../../common/models/Post';
import type User from '../../common/models/User';

export interface IDiscussionListItemAttrs extends ComponentAttrs {
discussion: Discussion;
post?: Post;
params: DiscussionListParams;
jumpTo?: number;
author?: User;
}

/**
Expand Down Expand Up @@ -142,7 +145,7 @@ export default class DiscussionListItem<CustomAttrs extends IDiscussionListItemA
const items = new ItemList<Mithril.Children>();

const discussion = this.attrs.discussion;
const user = discussion.user();
const user = this.attrs.author || discussion.user();

items.add(
'avatar',
Expand Down Expand Up @@ -181,6 +184,10 @@ export default class DiscussionListItem<CustomAttrs extends IDiscussionListItemA
}

getJumpTo() {
if (this.attrs.jumpTo) {
return this.attrs.jumpTo;
}

const discussion = this.attrs.discussion;
let jumpTo = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default class PostsSearchSource implements SearchSource {
return (this.results.get(query) || []).map((post) => {
return (
<li className="PostSearchResult" data-index={'posts' + post.id()} data-id={post.id()}>
<MinimalDiscussionListItem discussion={post.discussion()} post={post} params={{ q: query }} />
<MinimalDiscussionListItem discussion={post.discussion()} post={post} params={{ q: query }} jumpTo={post.number()} author={post.user()} />
</li>
);
}) as Array<Mithril.Vnode>;
Expand Down
2 changes: 1 addition & 1 deletion framework/core/locale/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ core:

# Translations in this namespace are used in messages output by the API.
api:
invalid_username_message: "The username may only contain letters, numbers, and dashes."
invalid_username_message: "The username may only contain letters, numbers, and dashes. With at least one letter."
invalid_filter_type:
must_be_numeric_message: "The {filter} filter must be numeric."
must_not_be_array_message: "The {filter} filter must not be an array."
Expand Down
2 changes: 1 addition & 1 deletion framework/core/src/Api/Resource/UserResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public function fields(): array
Schema\Str::make('username')
->requiredOnCreateWithout(['token'])
->unique('users', 'username', true)
->regex('/^[a-z0-9_-]+$/i')
->regex('/^(?![0-9]*$)[a-z0-9_-]+$/i')
->validationMessages([
'username.regex' => $translator->trans('core.api.invalid_username_message'),
'username.required_without' => $translator->trans('validation.required', ['attribute' => $translator->trans('validation.attributes.username')])
Expand Down
7 changes: 7 additions & 0 deletions framework/core/src/Discussion/Search/Filter/AuthorFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ protected function constrain(Builder $query, string|array $rawUsernames, bool $n

$ids = $this->users->getIdsForUsernames($usernames);

// To be able to also use IDs.
$actualIds = array_diff($usernames, array_keys($ids));

if (! empty($actualIds)) {
$ids = array_merge($ids, $actualIds);
}

$query->whereIn('discussions.user_id', $ids, 'and', $negate);
}
}
7 changes: 7 additions & 0 deletions framework/core/src/Post/Filter/AuthorFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ public function filter(SearchState $state, string|array $value, bool $negate): v

$ids = $this->users->getIdsForUsernames($usernames);

// To be able to also use IDs.
$actualIds = array_diff($usernames, array_keys($ids));

if (! empty($actualIds)) {
$ids = array_merge($ids, $actualIds);
}

$state->getQuery()->whereIn('posts.user_id', $ids, 'and', $negate);
}
}
2 changes: 1 addition & 1 deletion framework/core/src/User/UserRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function getIdsForUsernames(array $usernames, User $actor = null): array
{
$query = $this->query()->whereIn('username', $usernames);

return $this->scopeVisibleTo($query, $actor)->pluck('id')->all();
return $this->scopeVisibleTo($query, $actor)->pluck('id', 'username')->all();
}

/**
Expand Down

0 comments on commit 7d7f5ce

Please sign in to comment.