Skip to content

Commit

Permalink
Make profile urls work with usernames only and not user IDs. Fixes #1356
Browse files Browse the repository at this point in the history
  • Loading branch information
clarkwinkelmann committed Apr 24, 2020
1 parent 7794546 commit e7d2729
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 8 deletions.
28 changes: 26 additions & 2 deletions js/src/forum/components/UserPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import SelectDropdown from '../../common/components/SelectDropdown';
import LinkButton from '../../common/components/LinkButton';
import Separator from '../../common/components/Separator';
import listItems from '../../common/helpers/listItems';
import Alert from '../../common/components/Alert';

/**
* The `UserPage` component shows a user's profile. It can be extended to show
Expand Down Expand Up @@ -91,14 +92,37 @@ export default class UserPage extends Page {
app.preloadedApiDocument();

app.store.all('users').some((user) => {
if ((user.username().toLowerCase() === lowercaseUsername || user.id() === username) && user.joinTime()) {
if (user.username().toLowerCase() === lowercaseUsername && user.joinTime()) {
this.show(user);
return true;
}
});

if (!this.user) {
app.store.find('users', username).then(this.show.bind(this));
app
.request({
method: 'GET',
url: app.forum.attribute('apiUrl') + '/users',
data: {
filter: {
q: 'username:' + username,
},
},
})
.then((payload) => {
const users = app.store.pushPayload(payload);

if (users.length) {
this.show(users[0]);
} else {
app.alerts.show(
new Alert({
type: 'error',
children: app.translator.trans('core.lib.error.not_found_message'),
})
);
}
});
}
}

Expand Down
20 changes: 14 additions & 6 deletions src/Forum/Content/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace Flarum\Forum\Content;

use Flarum\Api\Client;
use Flarum\Api\Controller\ShowUserController;
use Flarum\Api\Controller\ListUsersController;
use Flarum\Frontend\Document;
use Flarum\Http\UrlGenerator;
use Flarum\User\User as FlarumUser;
Expand Down Expand Up @@ -44,14 +44,16 @@ public function __invoke(Document $document, Request $request)
{
$queryParams = $request->getQueryParams();
$actor = $request->getAttribute('actor');
$userId = Arr::get($queryParams, 'username');
$username = Arr::get($queryParams, 'username');

$params = [
'id' => $userId,
'filter' => [
'q' => "username:$username",
],
];

$apiDocument = $this->getApiDocument($actor, $params);
$user = $apiDocument->data->attributes;
$user = $apiDocument->data[0]->attributes;

$document->title = $user->displayName;
$document->canonicalUrl = $this->url->to('forum')->route('user', ['username' => $user->username]);
Expand All @@ -70,13 +72,19 @@ public function __invoke(Document $document, Request $request)
*/
protected function getApiDocument(FlarumUser $actor, array $params)
{
$response = $this->api->send(ShowUserController::class, $actor, $params);
$response = $this->api->send(ListUsersController::class, $actor, $params);
$statusCode = $response->getStatusCode();

if ($statusCode === 404) {
throw new ModelNotFoundException;
}

return json_decode($response->getBody());
$body = json_decode($response->getBody());

if (count($body->data) === 0) {
throw new ModelNotFoundException;
}

return $body;
}
}
2 changes: 2 additions & 0 deletions src/Search/SearchServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Flarum\User\Search\Gambit\EmailGambit;
use Flarum\User\Search\Gambit\FulltextGambit as UserFulltextGambit;
use Flarum\User\Search\Gambit\GroupGambit;
use Flarum\User\Search\Gambit\UsernameGambit;
use Flarum\User\Search\UserSearcher;
use Illuminate\Contracts\Container\Container;

Expand Down Expand Up @@ -48,6 +49,7 @@ public function registerUserGambits()
$gambits->setFulltextGambit(UserFulltextGambit::class);
$gambits->add(EmailGambit::class);
$gambits->add(GroupGambit::class);
$gambits->add(UsernameGambit::class);

$app->make('events')->dispatch(
new ConfigureUserGambits($gambits)
Expand Down
51 changes: 51 additions & 0 deletions src/User/Search/Gambit/UsernameGambit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/

namespace Flarum\User\Search\Gambit;

use Flarum\Search\AbstractRegexGambit;
use Flarum\Search\AbstractSearch;
use Flarum\User\Search\UserSearch;
use Flarum\User\UserRepository;
use LogicException;

class UsernameGambit extends AbstractRegexGambit
{
/**
* {@inheritdoc}
*/
protected $pattern = 'username:(.+)';

/**
* @var \Flarum\User\UserRepository
*/
protected $users;

/**
* @param \Flarum\User\UserRepository $users
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}

/**
* {@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');
}

$username = trim($matches[1], '"');

$search->getQuery()->where('username', $negate ? '!=' : '=', $username);
}
}

0 comments on commit e7d2729

Please sign in to comment.