User display names (#1246)

* Introduce user display names

It is not uncommon for forums to be intergrated with sites where users
don't have a unique "handle" - they might just have their first name,
or a full name, which is not guaranteed to be unique.

This commit introduces the concept of "display names" for users. By
default display names are the same as usernames, but extensions may
override this and set them to something different. The important thing
is that all code should use `display_name` whenever intending to output
a human-readable name - `username` is reserved for cases where you want
to output a unique identifier (which may or may not be human-friendly).

The new "GetDisplayName" API is probably sub-optimal, but I didn't worry
too much because we can come up with something better in `next-back`.

ref #557

* Apply fixes from StyleCI

[ci skip] [skip ci]
This commit is contained in:
Toby Zerner 2017-09-20 16:42:18 +09:30 committed by GitHub
parent 65ffee8696
commit 6f75d95e9f
10 changed files with 54 additions and 9 deletions

View File

@ -28942,7 +28942,9 @@ System.register('flarum/components/UsersSearchSource', ['flarum/helpers/highligh
query = query.toLowerCase();
var results = app.store.all('users').filter(function (user) {
return user.username().toLowerCase().substr(0, query.length) === query;
return [user.username(), user.displayName()].some(function (value) {
return value.toLowerCase().substr(0, query.length) === query;
});
});
if (!results.length) return '';
@ -29534,7 +29536,7 @@ System.register("flarum/helpers/username", [], function (_export, _context) {
"use strict";
function username(user) {
var name = user && user.username() || app.translator.trans('core.lib.username.deleted_text');
var name = user && user.displayName() || app.translator.trans('core.lib.username.deleted_text');
return m(
"span",
@ -30533,6 +30535,7 @@ System.register('flarum/models/User', ['flarum/Model', 'flarum/utils/stringToCol
babelHelpers.extends(User.prototype, {
username: Model.attribute('username'),
displayName: Model.attribute('displayName'),
email: Model.attribute('email'),
isActivated: Model.attribute('isActivated'),
password: Model.attribute('password'),

View File

@ -20,7 +20,7 @@ export default class UsersSearchResults {
query = query.toLowerCase();
const results = app.store.all('users')
.filter(user => user.username().toLowerCase().substr(0, query.length) === query);
.filter(user => [user.username(), user.displayName()].some(value => value.toLowerCase().substr(0, query.length) === query));
if (!results.length) return '';

View File

@ -6,7 +6,7 @@
* @return {Object}
*/
export default function username(user) {
const name = (user && user.username()) || app.translator.trans('core.lib.username.deleted_text');
const name = (user && user.displayName()) || app.translator.trans('core.lib.username.deleted_text');
return <span className="username">{name}</span>;
}

View File

@ -10,6 +10,7 @@ export default class User extends Model {}
Object.assign(User.prototype, {
username: Model.attribute('username'),
displayName: Model.attribute('displayName'),
email: Model.attribute('email'),
isActivated: Model.attribute('isActivated'),
password: Model.attribute('password'),

View File

@ -12,7 +12,6 @@
namespace Flarum\Api\Serializer;
use Flarum\Core\Post;
use Flarum\Core\Post\CommentPost;
use InvalidArgumentException;
class PostBasicSerializer extends AbstractSerializer

View File

@ -36,8 +36,9 @@ class UserBasicSerializer extends AbstractSerializer
}
return [
'username' => $user->username,
'avatarUrl' => $user->avatar_url
'username' => $user->username,
'displayName' => $user->display_name,
'avatarUrl' => $user->avatar_url
];
}

View File

@ -107,7 +107,7 @@ class RequestPasswordResetHandler
$token->save();
$data = [
'{username}' => $user->username,
'{username}' => $user->display_name,
'{url}' => $this->url->toRoute('resetPassword', ['token' => $token->id]),
'{forum}' => $this->settings->get('forum_title'),
];

View File

@ -130,7 +130,7 @@ class EmailConfirmationMailer
$token = $this->generateToken($user, $email);
return [
'{username}' => $user->username,
'{username}' => $user->display_name,
'{url}' => $this->url->toRoute('confirmEmail', ['token' => $token->id]),
'{forum}' => $this->settings->get('forum_title')
];

View File

@ -18,6 +18,7 @@ use Flarum\Core\Support\ScopeVisibilityTrait;
use Flarum\Database\AbstractModel;
use Flarum\Event\CheckUserPassword;
use Flarum\Event\ConfigureUserPreferences;
use Flarum\Event\GetDisplayName;
use Flarum\Event\PostWasDeleted;
use Flarum\Event\PrepareUserGroups;
use Flarum\Event\UserAvatarWasChanged;
@ -333,6 +334,16 @@ class User extends AbstractModel
}
}
/**
* Get the user's display name.
*
* @return string
*/
public function getDisplayNameAttribute()
{
return static::$dispatcher->until(new GetDisplayName($this)) ?: $this->username;
}
/**
* Get the user's locale, falling back to the forum's default if they
* haven't set one.

View File

@ -0,0 +1,30 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Event;
use Flarum\Core\User;
class GetDisplayName
{
/**
* @var User
*/
public $user;
/**
* @param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
}