Settings themes handled in SettingsController

This commit is contained in:
frischler 2022-06-07 21:33:08 +02:00 committed by Igor Scheller
parent bb49b308fb
commit 3043a9512a
10 changed files with 203 additions and 97 deletions

View File

@ -22,6 +22,8 @@ $route->post('/oauth/{provider}/disconnect', 'OAuthController@disconnect');
// User settings
$route->get('/settings/password', 'SettingsController@password');
$route->post('/settings/password', 'SettingsController@savePassword');
$route->get('/settings/theme', 'SettingsController@theme');
$route->post('/settings/theme', 'SettingsController@saveTheme');
$route->get('/settings/oauth', 'SettingsController@oauth');
// Password recovery

View File

@ -105,34 +105,6 @@ function user_settings_main($user_source, $enable_tshirt_size, $tshirt_sizes)
return $user_source;
}
/**
* Change user theme
*
* @param User $user_source The user
* @param array $themes List of available themes
* @return User
*/
function user_settings_theme($user_source, $themes)
{
$valid = true;
$request = request();
if ($request->has('theme') && isset($themes[$request->input('theme')])) {
$user_source->settings->theme = $request->input('theme');
} else {
$valid = false;
}
if ($valid) {
$user_source->settings->save();
success(__('Theme changed.'));
throw_redirect(page_link_to('user_settings'));
}
return $user_source;
}
/**
* Change use locale
*
@ -172,13 +144,6 @@ function user_settings()
{
$request = request();
$config = config();
$themesConfig = config('themes');
$themes = [];
foreach ($themesConfig as $themeIndex => $themeConfig) {
$themes[$themeIndex] = $themeConfig['name'];
}
$enable_tshirt_size = config('enable_tshirt_size');
$tshirt_sizes = config('tshirt_sizes');
@ -200,8 +165,6 @@ function user_settings()
$user_source = auth()->user();
if ($request->hasPostData('submit')) {
$user_source = user_settings_main($user_source, $enable_tshirt_size, $tshirt_sizes);
} elseif ($request->hasPostData('submit_theme')) {
$user_source = user_settings_theme($user_source, $themes);
} elseif ($request->hasPostData('submit_language')) {
$user_source = user_settings_locale($user_source, $locales);
}
@ -209,7 +172,6 @@ function user_settings()
return User_settings_view(
$user_source,
$locales,
$themes,
$buildup_start_date,
$teardown_end_date,
$enable_tshirt_size,

View File

@ -14,7 +14,6 @@ use Engelsystem\Controllers\SettingsController;
*
* @param User $user_source The user
* @param array $locales Available languages
* @param array $themes Available themes
* @param int $buildup_start_date Unix timestamp
* @param int $teardown_end_date Unix timestamp
* @param bool $enable_tshirt_size
@ -25,7 +24,6 @@ use Engelsystem\Controllers\SettingsController;
function User_settings_view(
$user_source,
$locales,
$themes,
$buildup_start_date,
$teardown_end_date,
$enable_tshirt_size,
@ -118,11 +116,6 @@ function User_settings_view(
form_info('', __('Please visit the angeltypes page to manage your angeltypes.')),
form_submit('submit', __('Save'))
]),
form([
form_info(__('Here you can choose your color settings:')),
form_select('theme', __('Color settings:'), $themes, $user_source->settings->theme),
form_submit('submit_theme', __('Save'))
]),
form([
form_info(__('Here you can choose your language:')),
form_select('language', __('Language:'), $locales, $user_source->settings->language),

View File

@ -1830,10 +1830,6 @@ msgstr "-> Nicht OK. Bitte erneut versuchen."
msgid "Your password is to short (please use at least 6 characters)."
msgstr "Dein Passwort ist zu kurz (Bitte mindestens 6 Zeichen nutzen)."
#: includes/pages/user_settings.php:146
msgid "Theme changed."
msgstr "Aussehen geändert."
#: includes/pages/user_shifts.php:101
msgid "The administration has not configured any rooms yet."
msgstr "Die Administratoren habe noch keine Räume eingerichtet."
@ -2525,14 +2521,6 @@ msgstr "Geplanter Abreisetag"
msgid "Please visit the angeltypes page to manage your angeltypes."
msgstr "Bitte benutze die Engeltypen-Seite um deine Engeltypen zu verwalten."
#: includes/view/User_view.php:96
msgid "Here you can choose your color settings:"
msgstr "Hier kannst Du das Aussehen auswählen:"
#: includes/view/User_view.php:97
msgid "Color settings:"
msgstr "Aussehen:"
#: includes/view/User_view.php:101
msgid "Here you can choose your language:"
msgstr "Hier kannst Du Deine Sprache auswählen:"
@ -2968,6 +2956,15 @@ msgstr "Passwort wiederholen"
msgid "settings.password.success"
msgstr "Passwort wurde erfolgreich geändert."
msgid "settings.theme"
msgstr "Theme"
msgid "settings.theme.info"
msgstr "Hier kannst Du Dein Theme ändern."
msgid "settings.theme.success"
msgstr "Theme wurde erfolgreich geändert."
msgid "settings.oauth"
msgstr "Single Sign-On"

View File

@ -226,6 +226,15 @@ msgstr "Password confirmation"
msgid "settings.password.success"
msgstr "Password was changed successfully."
msgid "settings.theme"
msgstr "Theme"
msgid "settings.theme.info"
msgstr "Here you can change your theme."
msgid "settings.theme.success"
msgstr "Theme was changed successfully."
msgid "settings.oauth"
msgstr "Single Sign-On"

View File

@ -1614,10 +1614,6 @@ msgstr "-> não OK. Por favor tente novamente."
msgid "Failed setting password."
msgstr "A alteração da senha falhaou."
#: includes/pages/user_settings.php:126
msgid "Theme changed."
msgstr "Tema alterado."
#: includes/pages/user_shifts.php:82
msgid "The administration has not configured any rooms yet."
msgstr "O administrador não configurou nenhuma sala ainda."
@ -2211,14 +2207,6 @@ msgstr "Nova senha:"
msgid "Password confirmation:"
msgstr "Confirmação de senha:"
#: includes/view/User_view.php:68
msgid "Here you can choose your color settings:"
msgstr "Aqui você pode selecionar sua configuração de cor:"
#: includes/view/User_view.php:69
msgid "Color settings:"
msgstr "Configuração de cor:"
#: includes/view/User_view.php:73
msgid "Here you can choose your language:"
msgstr "Aqui você pode selecionar seu idioma:"

View File

@ -5,35 +5,35 @@
{% block title %}{{ __('settings.password') }}{% endblock %}
{% block row_content %}
<form action="" enctype="multipart/form-data" method="post">
{{ csrf() }}
<form action="" enctype="multipart/form-data" method="post">
{{ csrf() }}
<div class="row">
<div class="col-md-12">
{{ m.info(__('settings.password.info')) }}
<div class="row">
<div class="col-md-12">
{{ m.info(__('settings.password.info')) }}
{% if user.password %}
{{ f.input(
'password',
__('settings.password.password'),
'password',
{'required': true}
) }}
{% endif %}
{% if user.password %}
{{ f.input(
'new_password',
__('settings.password.new_password'),
'password',
{'min': min_length, 'required': true}
) }}
{{ f.input(
'new_password2',
__('settings.password.new_password2'),
__('settings.password.password'),
'password',
{'min': min_length, 'required': true}
{'required': true}
) }}
{{ f.submit() }}
</div>
{% endif %}
{{ f.input(
'new_password',
__('settings.password.new_password'),
'password',
{'min': min_length, 'required': true}
) }}
{{ f.input(
'new_password2',
__('settings.password.new_password2'),
'password',
{'min': min_length, 'required': true}
) }}
{{ f.submit() }}
</div>
</form>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends 'pages/settings/settings.twig' %}
{% import 'macros/form.twig' as f %}
{% import 'macros/base.twig' as m %}
{% block title %}{{ __('settings.theme') }}{% endblock %}
{% block row_content %}
<form action="" enctype="multipart/form-data" method="post">
{{ csrf() }}
<div class="row">
<div class="col-md-12">
{{ m.info(__('settings.theme.info')) }}
{{ f.select('select_theme', themes, __('settings.theme'), current_theme) }}
{{ f.submit() }}
</div>
</div>
</form>
{% endblock %}

View File

@ -96,6 +96,49 @@ class SettingsController extends BaseController
return $this->redirect->to('/settings/password');
}
/**
* @return Response
*/
public function theme(): Response
{
$themes = array_map(function ($theme) {
return $theme['name'];
}, config('themes'));
$currentTheme = $this->auth->user()->settings->theme;
return $this->response->withView(
'pages/settings/theme',
[
'settings_menu' => $this->settingsMenu(),
'themes' => $themes,
'current_theme' => $currentTheme
] + $this->getNotifications()
);
}
/**
* @param Request $request
* @return Response
*/
public function saveTheme(Request $request): Response
{
$user = $this->auth->user();
$data = $this->validate($request, ['select_theme' => 'int']);
$selectTheme = $data['select_theme'];
if (!isset(config('themes')[$selectTheme])) {
throw new HttpNotFound('Theme with id ' . $selectTheme . ' does not exist.');
}
$user->settings->theme = $selectTheme;
$user->settings->save();
$this->addNotification('settings.theme.success');
return $this->redirect->to('/settings/theme');
}
/**
* @return Response
*/
@ -122,7 +165,8 @@ class SettingsController extends BaseController
{
$menu = [
url('/user-settings') => 'settings.profile',
url('/settings/password') => 'settings.password'
url('/settings/password') => 'settings.password',
url('/settings/theme') => 'settings.theme'
];
if (!empty(config('oauth'))) {

View File

@ -6,6 +6,7 @@ use Engelsystem\Config\Config;
use Engelsystem\Controllers\SettingsController;
use Engelsystem\Http\Exceptions\HttpNotFound;
use Engelsystem\Http\Response;
use Engelsystem\Models\User\Settings;
use Engelsystem\Test\Unit\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\HttpFoundation\Session\Session;
@ -240,6 +241,88 @@ class SettingsControllerTest extends TestCase
$controller->savePassword($this->request);
}
/**
* @testdox theme: underNormalConditions -> returnsCorrectViewAndData
* @covers \Engelsystem\Controllers\SettingsController::theme
*/
public function testThemeUnderNormalConditionReturnsCorrectViewAndData()
{
$this->setExpects($this->auth, 'user', null, $this->user, $this->once());
/** @var Response|MockObject $response */
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function ($view, $data) {
$this->assertEquals('pages/settings/theme', $view);
$this->assertArrayHasKey('settings_menu', $data);
$this->assertArrayHasKey('themes', $data);
$this->assertArrayHasKey('current_theme', $data);
$this->assertEquals([0 => 'Engelsystem light', 1 => 'Engelsystem dark'], $data['themes']);
$this->assertEquals(1, $data['current_theme']);
return $this->response;
});
/** @var SettingsController $controller */
$controller = $this->app->make(SettingsController::class);
$controller->theme();
}
/**
* @testdox saveTheme: withNoSelectedThemeGiven -> throwsException
* @covers \Engelsystem\Controllers\SettingsController::saveTheme
*/
public function testSaveThemeWithNoSelectedThemeGivenThrowsException()
{
$this->setExpects($this->auth, 'user', null, $this->user, $this->once());
$this->expectException(ValidationException::class);
/** @var SettingsController $controller */
$controller = $this->app->make(SettingsController::class);
$controller->setValidator(new Validator());
$controller->saveTheme($this->request);
}
/**
* @testdox saveTheme: withUnknownSelectedThemeGiven -> throwsException
* @covers \Engelsystem\Controllers\SettingsController::saveTheme
*/
public function testSaveThemeWithUnknownSelectedThemeGivenThrowsException()
{
$this->request = $this->request->withParsedBody(['select_theme' => 2]);
$this->setExpects($this->auth, 'user', null, $this->user, $this->once());
$this->expectException(HttpNotFound::class);
/** @var SettingsController $controller */
$controller = $this->app->make(SettingsController::class);
$controller->setValidator(new Validator());
$controller->saveTheme($this->request);
}
/**
* @testdox saveTheme: withKnownSelectedThemeGiven -> savesThemeAndRedirect
* @covers \Engelsystem\Controllers\SettingsController::saveTheme
*/
public function testSaveThemeWithKnownSelectedThemeGivenSavesThemeAndRedirect()
{
$this->assertEquals(1, $this->user->settings->theme);
$this->setExpects($this->auth, 'user', null, $this->user, $this->once());
$this->response->expects($this->once())
->method('redirectTo')
->with('http://localhost/settings/theme')
->willReturn($this->response);
$this->request = $this->request->withParsedBody(['select_theme' => 0]);
/** @var SettingsController $controller */
$controller = $this->app->make(SettingsController::class);
$controller->setValidator(new Validator());
$controller->saveTheme($this->request);
$this->assertEquals(0, $this->user->settings->theme);
}
/**
* @covers \Engelsystem\Controllers\SettingsController::__construct
* @covers \Engelsystem\Controllers\SettingsController::oauth
@ -294,6 +377,7 @@ class SettingsControllerTest extends TestCase
$this->assertEquals([
'http://localhost/user-settings' => 'settings.profile',
'http://localhost/settings/password' => 'settings.password',
'http://localhost/settings/theme' => 'settings.theme',
'http://localhost/settings/oauth' => ['title' => 'settings.oauth', 'hidden' => false]
], $controller->settingsMenu());
@ -301,6 +385,7 @@ class SettingsControllerTest extends TestCase
$this->assertEquals([
'http://localhost/user-settings' => 'settings.profile',
'http://localhost/settings/password' => 'settings.password',
'http://localhost/settings/theme' => 'settings.theme',
'http://localhost/settings/oauth' => ['title' => 'settings.oauth', 'hidden' => true]
], $controller->settingsMenu());
}
@ -317,7 +402,8 @@ class SettingsControllerTest extends TestCase
$this->assertEquals([
'http://localhost/user-settings' => 'settings.profile',
'http://localhost/settings/password' => 'settings.password'
'http://localhost/settings/password' => 'settings.password',
'http://localhost/settings/theme' => 'settings.theme'
], $controller->settingsMenu());
}
@ -329,7 +415,11 @@ class SettingsControllerTest extends TestCase
parent::setUp();
$this->initDatabase();
$this->config = new Config(['min_password_length' => 6]);
$themes = [
0 => ['name' => 'Engelsystem light'],
1 => ['name' => 'Engelsystem dark']
];
$this->config = new Config(['min_password_length' => 6, 'themes' => $themes]);
$this->app->instance('config', $this->config);
$this->app->instance(Config::class, $this->config);
@ -352,6 +442,8 @@ class SettingsControllerTest extends TestCase
$this->auth = $this->createMock(Authenticator::class);
$this->app->instance(Authenticator::class, $this->auth);
$this->user = User::factory()->create();
$this->user = User::factory()
->has(Settings::factory(['theme' => 1]))
->create();
}
}