Add option to show user first and last name instead of nickname

This commit is contained in:
Johannes Rudolph 2022-07-10 21:12:10 +02:00 committed by Michael Weimann
parent 031e1a08fe
commit c67fbbad73
29 changed files with 140 additions and 41 deletions

View File

@ -266,9 +266,13 @@ return [
// Whether the mobile number can be shown to other users
'enable_mobile_show' => (bool) env('ENABLE_MOBILE_SHOW', false),
// Enables prename and lastname
// Enables first name and last name
'enable_user_name' => (bool) env('ENABLE_USER_NAME', false),
// Show a users first name and last name instead of username
'display_full_name' => env('display_full_name', false)
&& env('ENABLE_USER_NAME', false),
// Enable displaying the pronoun fields
'enable_pronoun' => (bool) env('ENABLE_PRONOUN', true),

View File

@ -108,7 +108,7 @@ function shift_entry_create_controller_admin(Shift $shift, ?AngelType $angeltype
$shiftEntry->save();
ShiftEntry_onCreate($shiftEntry);
success(sprintf(__('%s has been subscribed to the shift.'), $signup_user->name));
success(sprintf(__('%s has been subscribed to the shift.'), $signup_user->displayName));
throw_redirect(shift_link($shift));
}
@ -116,7 +116,7 @@ function shift_entry_create_controller_admin(Shift $shift, ?AngelType $angeltype
$users = User::query()->orderBy('name')->get();
$users_select = [];
foreach ($users as $user) {
$users_select[$user->id] = $user->name;
$users_select[$user->id] = $user->displayName;
}
$angeltypes_select = $angeltypes->pluck('name', 'id')->toArray();
@ -157,14 +157,14 @@ function shift_entry_create_controller_supporter(Shift $shift, AngelType $angelt
$shiftEntry->save();
ShiftEntry_onCreate($shiftEntry);
success(sprintf(__('%s has been subscribed to the shift.'), $signup_user->name));
success(sprintf(__('%s has been subscribed to the shift.'), $signup_user->displayName));
throw_redirect(shift_link($shift));
}
$users = $angeltype->userAngelTypes->sortBy('name');
$users_select = [];
foreach ($users as $u) {
$users_select[$u->id] = $u->name;
$users_select[$u->id] = $u->displayName;
}
$room = $shift->room;

View File

@ -169,7 +169,7 @@ function user_angeltype_confirm_controller(): array
User_Nick_render($user_source, true),
AngelType_name_render($angeltype, true)
));
success(sprintf(__('%s confirmed for angeltype %s.'), $user_source->name, $angeltype->name));
success(sprintf(__('%s confirmed for angeltype %s.'), $user_source->displayName, $angeltype->name));
user_angeltype_confirm_email($user_source, $angeltype);
@ -195,7 +195,7 @@ function user_angeltype_confirm_email(User $user, AngelType $angeltype): void
$user,
'notification.angeltype.confirmed',
'emails/angeltype-confirmed',
['name' => $angeltype->name, 'angeltype' => $angeltype, 'username' => $user->name]
['name' => $angeltype->name, 'angeltype' => $angeltype, 'username' => $user->displayName]
);
} catch (TransportException $e) {
/** @var LoggerInterface $logger */
@ -220,7 +220,7 @@ function user_angeltype_add_email(User $user, AngelType $angeltype): void
$user,
'notification.angeltype.added',
'emails/angeltype-added',
['name' => $angeltype->name, 'angeltype' => $angeltype, 'username' => $user->name]
['name' => $angeltype->name, 'angeltype' => $angeltype, 'username' => $user->displayName]
);
} catch (TransportException $e) {
/** @var LoggerInterface $logger */
@ -264,7 +264,7 @@ function user_angeltype_delete_controller(): array
$user_angeltype->delete();
engelsystem_log(sprintf('User %s removed from %s.', User_Nick_render($user_source, true), $angeltype->name));
success(sprintf(__('User %s removed from %s.'), $user_source->name, $angeltype->name));
success(sprintf(__('User %s removed from %s.'), $user_source->displayName, $angeltype->name));
throw_redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id]));
}
@ -319,7 +319,7 @@ function user_angeltype_update_controller(): array
AngelType_name_render($angeltype, true),
User_Nick_render($user_source, true)
));
success(sprintf($msg, $angeltype->name, $user_source->name));
success(sprintf($msg, $angeltype->name, $user_source->displayName));
throw_redirect(page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype->id]));
}
@ -367,7 +367,7 @@ function user_angeltype_add_controller(): array
User_Nick_render($user_source, true),
AngelType_name_render($angeltype, true)
));
success(sprintf(__('User %s added to %s.'), $user_source->name, $angeltype->name));
success(sprintf(__('User %s added to %s.'), $user_source->displayName, $angeltype->name));
if ($request->hasPostData('auto_confirm_user')) {
$userAngelType->confirmUser()->associate($user_source);

View File

@ -137,7 +137,7 @@ function user_driver_license_edit_controller()
}
return [
sprintf(__('Edit %s driving license information'), $user_source->name),
sprintf(__('Edit %s driving license information'), $user_source->displayName),
UserDriverLicense_edit_view($user_source, $driverLicense),
];
}

View File

@ -91,7 +91,7 @@ function user_delete_controller()
}
return [
sprintf(__('Delete %s'), $user_source->name),
sprintf(__('Delete %s'), $user_source->displayName),
User_delete_view($user_source),
];
}
@ -182,7 +182,7 @@ function user_edit_vouchers_controller()
}
return [
sprintf(__('%s\'s vouchers'), $user_source->name),
sprintf(__('%s\'s vouchers'), $user_source->displayName),
User_edit_vouchers_view($user_source),
];
}
@ -244,7 +244,7 @@ function user_controller()
}
return [
$user_source->name,
$user_source->displayName,
User_view(
$user_source,
auth()->can('admin_user'),

View File

@ -32,7 +32,7 @@ function engelsystem_email_to_user($recipientUser, $title, $message, $notIfItsMe
$recipientUser->contact->email ?: $recipientUser->email,
$title,
'emails/mail',
['username' => $recipientUser->name, 'message' => $message]
['username' => $recipientUser->displayName, 'message' => $message]
);
} catch (Exception $e) {
$status = false;
@ -48,7 +48,7 @@ function engelsystem_email_to_user($recipientUser, $title, $message, $notIfItsMe
$translator->setLocale($locale);
if (!$status) {
error(sprintf(__('User %s could not be notified by email due to an error.'), $recipientUser->name));
error(sprintf(__('User %s could not be notified by email due to an error.'), $recipientUser->displayName));
engelsystem_log(sprintf('User %s could not be notified by email due to an error.', $recipientUser->name));
}

View File

@ -84,7 +84,7 @@ class Shift
'end' => $end,
'room' => $room,
'freeloaded' => $freeloaded,
'username' => $user->name,
'username' => $user->displayName,
]
);
} catch (TransportException $e) {

View File

@ -339,7 +339,7 @@ function admin_active()
array_merge(
[
'no' => __('No.'),
'nick' => __('Nickname'),
'nick' => __('Name'),
],
($goodie_tshirt ? ['shirt_size' => __('Size')] : []),
[

View File

@ -185,7 +185,7 @@ function admin_arrive()
form_submit('submit', __('Search')),
], page_link_to('admin_arrive')),
table([
'name' => __('Nickname'),
'name' => __('Name'),
'rendered_planned_arrival_date' => __('Planned arrival'),
'arrived' => __('Arrived?'),
'rendered_arrival_date' => __('Arrival date'),

View File

@ -3,6 +3,7 @@
use Engelsystem\Helpers\Carbon;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Query\JoinClause;
/**
@ -25,6 +26,7 @@ function admin_free()
$search = strip_request_item('search');
}
/** @var AngelType[]|Collection $angel_types_source */
$angel_types_source = AngelType::all(['id', 'name']);
$angel_types = [
'' => __('All'),
@ -121,7 +123,7 @@ function admin_free()
]),
]),
table([
'name' => __('Nick'),
'name' => __('Name'),
'shift_state' => __('Next shift'),
'last_shift' => __('Last shift'),
'dect' => __('DECT'),

View File

View File

@ -10,6 +10,7 @@ use Engelsystem\Models\Shifts\Schedule;
use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftType;
use Engelsystem\Models\User\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Str;
/**
@ -55,6 +56,7 @@ function admin_shifts()
}
// Load shift types
/** @var ShiftType[]|Collection $shifttypes_source */
$shifttypes_source = ShiftType::all();
$shifttypes = [];
foreach ($shifttypes_source as $shifttype) {

View File

@ -13,6 +13,7 @@ use Engelsystem\Models\User\Settings;
use Engelsystem\Models\User\State;
use Engelsystem\Models\User\User;
use Illuminate\Database\Connection;
use Illuminate\Database\Eloquent\Collection;
/**
* @return string
@ -67,6 +68,7 @@ function guest_register()
$selected_angel_types = [];
$planned_arrival_date = null;
/** @var AngelType[]|Collection $angel_types_source */
$angel_types_source = AngelType::all();
$angel_types = [];
if (!empty($session->get('oauth2_groups'))) {

View File

@ -20,7 +20,7 @@ function UserAngelType_update_view(UserAngelType $user_angeltype, User $user, An
? __('Do you really want to add supporter rights for %s to %s?')
: __('Do you really want to remove supporter rights for %s from %s?'),
$angeltype->name,
$user->name
$user->displayName
), true),
form([
buttons([
@ -92,7 +92,7 @@ function UserAngelType_confirm_view(UserAngelType $user_angeltype, User $user, A
msg(),
info(sprintf(
__('Do you really want to confirm %s for %s?'),
$user->name,
$user->displayName,
$angeltype->name
), true),
form([
@ -116,7 +116,7 @@ function UserAngelType_delete_view(UserAngelType $user_angeltype, User $user, An
msg(),
info(sprintf(
__('Do you really want to delete %s from %s?'),
$user->name,
$user->displayName,
$angeltype->name
), true),
form([
@ -170,7 +170,7 @@ function UserAngelType_join_view($user, AngelType $angeltype)
msg(),
info(sprintf(
__('Do you really want to add %s to %s?'),
$user->name,
$user->displayName,
$angeltype->name
), true),
form([

View File

@ -129,9 +129,11 @@ function Users_view(
'actions' => '<strong>' . count($usersList) . '</strong>',
];
$user_table_headers = [
'name' => Users_table_header_link('name', __('Nick'), $order_by),
];
$user_table_headers = [];
if (!config('display_full_name')) {
$user_table_headers['name'] = Users_table_header_link('name', __('Nick'), $order_by);
}
if (config('enable_user_name')) {
$user_table_headers['first_name'] = Users_table_header_link('first_name', __('Prename'), $order_by);
$user_table_headers['last_name'] = Users_table_header_link('last_name', __('Name'), $order_by);
@ -844,11 +846,11 @@ function User_Nick_render($user, $plain = false)
}
if ($plain) {
return sprintf('%s (%u)', $user->name, $user->id);
return sprintf('%s (%u)', $user->displayName, $user->id);
}
return render_profile_link(
'<span class="icon-icon_angel"></span> ' . htmlspecialchars($user->name) . '</a>',
'<span class="icon-icon_angel"></span> ' . htmlspecialchars($user->displayName) . '</a>',
$user->id,
($user->state->arrived ? '' : 'text-muted')
);

View File

@ -16,7 +16,7 @@
<updated>{{ news.updated_at.format(dateFormat) }}</updated>
<published>{{ news.created_at.format(dateFormat) }}</published>
<author>
<name>{{ news.user.name }}</name>
<name>{{ news.user.displayName }}</name>
</author>
<content type="html">
{{ news.text }}

View File

@ -16,7 +16,7 @@
<link>{{ url('/news/' ~ news.id) }}</link>
<guid isPermaLink="false">{{ uuidBy(news.id, '113115') }}</guid>
<pubDate>{{ news.created_at.format(dateFormat) }}</pubDate>
<author>{{ news.user.name }}</author>
<author>{{ news.user.displayName }}</author>
<description>
{{ news.text }}
</description>

View File

@ -74,7 +74,7 @@
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ m.angel() }} {{ user.name }}
{{ m.angel() }} {{ user.displayName }}
</a>
<ul class="dropdown-menu dropdown-menu-end">
{% if has_permission_to('user_myshifts') %}

View File

@ -26,7 +26,7 @@
<a href="{{ opt.url|default(url('users', {'action': 'view', 'user_id': user.id})) }}"
{%- if not user.state.arrived %} class="text-muted"{% endif -%}
>
{{ _self.angel() }} {{ user.name }}
{{ _self.angel() }} {{ user.displayName }}
{%- if opt.pronoun|default(false) and config('enable_pronoun')
and user.personalData.pronoun %}
({{ user.personalData.pronoun }})

View File

@ -2,7 +2,7 @@
{% import 'macros/base.twig' as m %}
{% import 'macros/form.twig' as f %}
{% block title %}{{ __('message.title') }}: {{ other_user.name }}{% endblock %}
{% block title %}{{ __('message.title') }}: {{ other_user.displayName }}{% endblock %}
{% block content %}
<div class="container">

View File

@ -65,12 +65,14 @@ class MessagesController extends BaseController
];
}
/** @var Collection $users */
$users = $this->user->orderBy('name')->get()
->except($currentUser->id)
->mapWithKeys(function ($u) {
return [$u->id => $u->name];
->mapWithKeys(function (User $u) {
return [$u->id => $u->displayName];
});
$users->prepend($currentUser->name, $currentUser->id);
$users->prepend($currentUser->displayName, $currentUser->id);
return $this->response->withView(
'pages/messages/overview.twig',

View File

@ -61,7 +61,7 @@ class PasswordResetController extends BaseController
$user,
'Password recovery',
'emails/password-reset',
['username' => $user->name, 'reset' => $reset]
['username' => $user->displayName, 'reset' => $reset]
);
}

View File

@ -34,7 +34,11 @@ class Messages
$user,
$subject,
$template,
['sender' => $message->sender->name, 'send_message' => $message, 'username' => $user->name]
[
'sender' => $message->sender->displayName,
'send_message' => $message,
'username' => $user->displayName,
]
);
} catch (TransportException $e) {
$this->log->error(

View File

@ -41,7 +41,7 @@ class News
$user,
$subject,
$template,
['title' => $news->title, 'news' => $news, 'username' => $user->name]
['title' => $news->title, 'news' => $news, 'username' => $user->displayName]
);
} catch (TransportException $e) {
$this->log->error(

View File

@ -42,6 +42,7 @@ use Illuminate\Support\Collection as SupportCollection;
* @property-read QueryBuilder|PersonalData $personalData
* @property-read QueryBuilder|Settings $settings
* @property-read QueryBuilder|State $state
* @property-read string $displayName
*
* @property-read Collection|Group[] $groups
* @property-read Collection|News[] $news
@ -263,4 +264,20 @@ class User extends BaseModel
{
return $this->hasMany(Shift::class, 'updated_by');
}
public function getDisplayNameAttribute(): string
{
if (
config('display_full_name')
&& !empty(trim($this->personalData->first_name . $this->personalData->last_name))
) {
return trim(
trim((string) $this->personalData->first_name)
. ' ' .
trim((string) $this->personalData->last_name)
);
}
return $this->name;
}
}

View File

@ -62,6 +62,28 @@ class MessagesControllerTest extends ControllerTest
$this->controller->index();
}
/**
* @testdox index: User is shown as first name and last name instead of nickname
* @covers \Engelsystem\Controllers\MessagesController::listConversations
*/
public function testIndexUnderNormalConditionsReturnsFormattedUserName(): void
{
$this->config->set('display_full_name', true);
$this->userA->personalData->first_name = 'Frank';
$this->userA->personalData->last_name = 'Nord';
$this->userA->personalData->save();
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) {
$this->assertEquals('Frank Nord', $data['users'][1]);
return $this->response;
});
$this->controller->index();
}
/**
* @testdox index: usersExist -> returnsUsersWithMeAtFirstPosition
* @covers \Engelsystem\Controllers\MessagesController::index

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Events\Listener;
use Engelsystem\Config\Config;
use Engelsystem\Events\Listener\Messages;
use Engelsystem\Mail\EngelsystemMailer;
use Engelsystem\Models\Message;
@ -110,5 +111,6 @@ class MessagesTest extends TestCase
parent::setUp();
$this->initDatabase();
$this->app->instance('config', new Config());
}
}

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Events\Listener;
use Engelsystem\Config\Config;
use Engelsystem\Events\Listener\News;
use Engelsystem\Mail\EngelsystemMailer;
use Engelsystem\Models\News as NewsModel;
@ -33,6 +34,7 @@ class NewsTest extends TestCase
*/
public function testCreated(): void
{
$this->app->instance('config', new Config());
/** @var NewsModel $news */
$news = NewsModel::factory(['title' => 'Foo'])->create();

View File

@ -482,4 +482,42 @@ class UserTest extends ModelTest
$this->assertCount(2, $user2->shiftsCreated);
$this->assertCount(2, $user2->shiftsUpdated);
}
public function getDisplayNameAttributeProvider(): array
{
return [
['lorem'],
['lorem', ' '],
['lorem', null, ' '],
['lorem', ' ', ' '],
['Test', 'Test', ' '],
['Tester', ' ', 'Tester'],
['Foo', 'Foo'],
['Bar', null, 'Bar'],
['Foo Bar', 'Foo', 'Bar'],
['Some name', ' Some', ' name'],
['Another Surname', ' Another ', ' Surname '],
];
}
/**
* @covers \Engelsystem\Models\User\User::getDisplayNameAttribute
* @dataProvider getDisplayNameAttributeProvider
*/
public function testGetDisplayNameAttribute(
string $expected,
?string $firstName = null,
?string $lastName = null
): void {
$this->app->instance('config', new Config());
($user1 = new User($this->data))->save();
$user1->personalData->first_name = $firstName;
$user1->personalData->last_name = $lastName;
$this->assertEquals('lorem', $user1->displayName);
config(['display_full_name' => true]);
$this->assertEquals($expected, $user1->displayName);
}
}