Skip to content

Commit 6eadf3e

Browse files
committed
Added language select to the user create form
- Updated user invite to take language from user. - Added tests to cover. - Added page/tab title to user create view. For #2576 and #2408
1 parent f83cc83 commit 6eadf3e

File tree

7 files changed

+79
-32
lines changed

7 files changed

+79
-32
lines changed

app/Http/Controllers/UserController.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public function create()
6262
$this->checkPermission('users-manage');
6363
$authMethod = config('auth.method');
6464
$roles = $this->userRepo->getAllRoles();
65+
$this->setPageTitle(trans('settings.users_add_new'));
6566

6667
return view('users.create', ['authMethod' => $authMethod, 'roles' => $roles]);
6768
}
@@ -78,6 +79,7 @@ public function store(Request $request)
7879
$validationRules = [
7980
'name' => ['required'],
8081
'email' => ['required', 'email', 'unique:users,email'],
82+
'setting' => ['array'],
8183
];
8284

8385
$authMethod = config('auth.method');
@@ -104,6 +106,13 @@ public function store(Request $request)
104106
DB::transaction(function () use ($user, $sendInvite, $request) {
105107
$user->save();
106108

109+
// Save user-specific settings
110+
if ($request->filled('setting')) {
111+
foreach ($request->get('setting') as $key => $value) {
112+
setting()->putUser($user, $key, $value);
113+
}
114+
}
115+
107116
if ($sendInvite) {
108117
$this->inviteService->sendInvitation($user);
109118
}
@@ -198,7 +207,7 @@ public function update(Request $request, int $id)
198207
$user->external_auth_id = $request->get('external_auth_id');
199208
}
200209

201-
// Save an user-specific settings
210+
// Save user-specific settings
202211
if ($request->filled('setting')) {
203212
foreach ($request->get('setting') as $key => $value) {
204213
setting()->putUser($user, $key, $value);

app/Notifications/UserInvite.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,33 @@
22

33
namespace BookStack\Notifications;
44

5+
use BookStack\Auth\User;
6+
use Illuminate\Notifications\Messages\MailMessage;
7+
58
class UserInvite extends MailNotification
69
{
710
public $token;
811

912
/**
1013
* Create a new notification instance.
11-
*
12-
* @param string $token
1314
*/
14-
public function __construct($token)
15+
public function __construct(string $token)
1516
{
1617
$this->token = $token;
1718
}
1819

1920
/**
2021
* Get the mail representation of the notification.
21-
*
22-
* @param mixed $notifiable
23-
*
24-
* @return \Illuminate\Notifications\Messages\MailMessage
2522
*/
26-
public function toMail($notifiable)
23+
public function toMail(User $notifiable): MailMessage
2724
{
2825
$appName = ['appName' => setting('app-name')];
26+
$language = setting()->getUser($notifiable, 'language');
2927

3028
return $this->newMailMessage()
31-
->subject(trans('auth.user_invite_email_subject', $appName))
32-
->greeting(trans('auth.user_invite_email_greeting', $appName))
33-
->line(trans('auth.user_invite_email_text'))
34-
->action(trans('auth.user_invite_email_action'), url('/register/invite/' . $this->token));
29+
->subject(trans('auth.user_invite_email_subject', $appName, $language))
30+
->greeting(trans('auth.user_invite_email_greeting', $appName, $language))
31+
->line(trans('auth.user_invite_email_text', [], $language))
32+
->action(trans('auth.user_invite_email_action', [], $language), url('/register/invite/' . $this->token));
3533
}
3634
}

resources/views/users/create.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
<div class="setting-list">
1818
@include('users.parts.form')
19+
@include('users.parts.language-option-row', ['value' => old('setting.language') ?? config('app.default_locale')])
1920
</div>
2021

2122
<div class="form-group text-right">

resources/views/users/edit.blade.php

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,7 @@
3535
</div>
3636
</div>
3737

38-
<div class="grid half gap-xl v-center">
39-
<div>
40-
<label for="user-language" class="setting-list-label">{{ trans('settings.users_preferred_language') }}</label>
41-
<p class="small">
42-
{{ trans('settings.users_preferred_language_desc') }}
43-
</p>
44-
</div>
45-
<div>
46-
<select name="setting[language]" id="user-language">
47-
@foreach(trans('settings.language_select') as $lang => $label)
48-
<option @if(setting()->getUser($user, 'language', config('app.default_locale')) === $lang) selected @endif value="{{ $lang }}">{{ $label }}</option>
49-
@endforeach
50-
</select>
51-
</div>
52-
</div>
53-
38+
@include('users.parts.language-option-row', ['value' => setting()->getUser($user, 'language', config('app.default_locale'))])
5439
</div>
5540

5641
<div class="text-right">
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{{--
2+
$value - Currently selected lanuage value
3+
--}}
4+
<div class="grid half gap-xl v-center">
5+
<div>
6+
<label for="user-language" class="setting-list-label">{{ trans('settings.users_preferred_language') }}</label>
7+
<p class="small">
8+
{{ trans('settings.users_preferred_language_desc') }}
9+
</p>
10+
</div>
11+
<div>
12+
<select name="setting[language]" id="user-language">
13+
@foreach(trans('settings.language_select') as $lang => $label)
14+
<option @if($value === $lang) selected @endif value="{{ $lang }}">{{ $label }}</option>
15+
@endforeach
16+
</select>
17+
</div>
18+
</div>

tests/Auth/UserInviteTest.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use BookStack\Auth\User;
77
use BookStack\Notifications\UserInvite;
88
use Carbon\Carbon;
9+
use Illuminate\Notifications\Messages\MailMessage;
910
use Illuminate\Support\Facades\DB;
1011
use Illuminate\Support\Facades\Notification;
1112
use Illuminate\Support\Str;
@@ -20,8 +21,8 @@ public function test_user_creation_creates_invite()
2021

2122
$email = Str::random(16) . '@example.com';
2223
$resp = $this->actingAs($admin)->post('/settings/users/create', [
23-
'name' => 'Barry',
24-
'email' => $email,
24+
'name' => 'Barry',
25+
'email' => $email,
2526
'send_invite' => 'true',
2627
]);
2728
$resp->assertRedirect('/settings/users');
@@ -34,6 +35,31 @@ public function test_user_creation_creates_invite()
3435
]);
3536
}
3637

38+
public function test_user_invite_sent_in_selected_language()
39+
{
40+
Notification::fake();
41+
$admin = $this->getAdmin();
42+
43+
$email = Str::random(16) . '@example.com';
44+
$resp = $this->actingAs($admin)->post('/settings/users/create', [
45+
'name' => 'Barry',
46+
'email' => $email,
47+
'send_invite' => 'true',
48+
'setting' => [
49+
'language' => 'de',
50+
]
51+
]);
52+
$resp->assertRedirect('/settings/users');
53+
54+
$newUser = User::query()->where('email', '=', $email)->orderBy('id', 'desc')->first();
55+
Notification::assertSentTo($newUser, UserInvite::class, function ($notification, $channels, $notifiable) {
56+
/** @var MailMessage $mail */
57+
$mail = $notification->toMail($notifiable);
58+
return 'Du wurdest eingeladen BookStack beizutreten!' === $mail->subject &&
59+
'Ein Konto wurde für Sie auf BookStack erstellt.' === $mail->greeting;
60+
});
61+
}
62+
3763
public function test_invite_set_password()
3864
{
3965
Notification::fake();
@@ -54,7 +80,7 @@ public function test_invite_set_password()
5480
]);
5581
$setPasswordResp->assertSee('Password set, you should now be able to login using your set password to access BookStack!');
5682
$newPasswordValid = auth()->validate([
57-
'email' => $user->email,
83+
'email' => $user->email,
5884
'password' => 'my test password',
5985
]);
6086
$this->assertTrue($newPasswordValid);

tests/User/UserManagementTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,16 @@ public function test_guest_profile_cannot_be_deleted()
183183
$resp->assertSee('cannot delete the guest user');
184184
}
185185

186+
public function test_user_create_language_reflects_default_system_locale()
187+
{
188+
$langs = ['en', 'fr', 'hr'];
189+
foreach ($langs as $lang) {
190+
config()->set('app.locale', $lang);
191+
$resp = $this->asAdmin()->get('/settings/users/create');
192+
$resp->assertElementExists('select[name="setting[language]"] option[value="' . $lang . '"][selected]');
193+
}
194+
}
195+
186196
public function test_user_creation_is_not_performed_if_the_invitation_sending_fails()
187197
{
188198
/** @var User $user */

0 commit comments

Comments
 (0)