From 27323bfba5fe5cc5e536d3dc53381c1246a30995 Mon Sep 17 00:00:00 2001
From: xuwhite <73076134+xuwhite@users.noreply.github.com>
Date: Fri, 3 Nov 2023 15:15:44 +0100
Subject: [PATCH] make required fields configurable
---
config/config.default.php | 10 +++++++
includes/view/User_view.php | 6 ++++-
resources/lang/de_DE/additional.po | 20 +++++++-------
resources/lang/en_US/additional.po | 20 +++++++-------
resources/views/pages/settings/profile.twig | 14 ++++++++--
resources/views/pages/sign-up.twig | 14 ++++++++--
src/Controllers/SettingsController.php | 26 ++++++++++++++-----
src/Controllers/SignUpController.php | 7 +++++
src/Factories/User.php | 18 ++++++++-----
.../Controllers/SettingsControllerTest.php | 10 +++++++
tests/Utils/SignUpConfig.php | 24 +++++++++++++++++
11 files changed, 132 insertions(+), 37 deletions(-)
diff --git a/config/config.default.php b/config/config.default.php
index 990515cb..b60d0b07 100644
--- a/config/config.default.php
+++ b/config/config.default.php
@@ -233,6 +233,16 @@ return [
// Users are able to sign up
'registration_enabled' => (bool) env('REGISTRATION_ENABLED', true),
+ // Required fields on sign-up page
+ 'signup_required_fields' => [
+ 'pronoun' => (bool) env('PRONOUN_REQUIRED', false),
+ 'firstname' => (bool) env('FIRSTNAME_REQUIRED', false),
+ 'lastname' => (bool) env('LASTNAME_REQUIRED', false),
+ 'tshirt_size' => (bool) env('TSHIRT_SIZE_REQUIRED', true),
+ 'mobile' => (bool) env('MOBILE_REQUIRED', false),
+ 'dect' => (bool) env('DECT_REQUIRED', false),
+ ],
+
// Only arrived angels can sign up for shifts
'signup_requires_arrival' => (bool) env('SIGNUP_REQUIRES_ARRIVAL', false),
diff --git a/includes/view/User_view.php b/includes/view/User_view.php
index 318bb22b..aa0eb016 100644
--- a/includes/view/User_view.php
+++ b/includes/view/User_view.php
@@ -952,7 +952,11 @@ function render_user_tshirt_hint()
{
$goodie = GoodieType::from(config('goodie_type'));
$goodie_tshirt = $goodie === GoodieType::Tshirt;
- if ($goodie_tshirt && !auth()->user()->personalData->shirt_size) {
+ if (
+ $goodie_tshirt
+ && config('signup_required_fields')['tshirt_size']
+ && !auth()->user()->personalData->shirt_size
+ ) {
$text = __('You need to specify a tshirt size in your settings!');
return render_profile_link($text);
}
diff --git a/resources/lang/de_DE/additional.po b/resources/lang/de_DE/additional.po
index 123725fb..94998c04 100644
--- a/resources/lang/de_DE/additional.po
+++ b/resources/lang/de_DE/additional.po
@@ -23,20 +23,20 @@ msgstr "Das angegebene Passwort ist zu kurz."
msgid "validation.login.required"
msgstr "Bitte gib einen Loginnamen an."
-msgid "validation.pronoun.optional"
-msgstr "Das Pronomen, das Du eingegeben hast, ist zu lang. Verwende maximal 15 Zeichen."
+msgid "validation.pronoun.required"
+msgstr "Bitte gebe dein Pronomen an."
-msgid "validation.firstname.optional"
-msgstr "Der von dir eingegebene Vorname ist zu lang. Verwende maximal 64 Zeichen."
+msgid "validation.firstname.required"
+msgstr "Bitte gebe deinen Vornamen an."
-msgid "validation.lastname.optional"
-msgstr "Der von dir eingegebene Vorname ist zu lang. Verwende maximal 64 Zeichen."
+msgid "validation.lastname.required"
+msgstr "Bitte gebe deinen Nachnamen an."
-msgid "validation.mobile.optional"
-msgstr "Der von dir eingegebene Handynummer ist zu lang. Verwende maximal 40 Zeichen."
+msgid "validation.mobile.required"
+msgstr "Bitte gebe deine Handynummer an."
-msgid "validation.dect.optional"
-msgstr "Der von dir eingegebene DECT-Nummer ist zu lang. Verwende maximal 40 Zeichen."
+msgid "validation.dect.required"
+msgstr "Bitte gebe deine DECT-Nummer an."
msgid "validation.username.required"
msgstr "Bitte gebe deinen Nick an."
diff --git a/resources/lang/en_US/additional.po b/resources/lang/en_US/additional.po
index dae46a16..7e52d6e2 100644
--- a/resources/lang/en_US/additional.po
+++ b/resources/lang/en_US/additional.po
@@ -21,20 +21,20 @@ msgstr "The password entered is too short."
msgid "validation.login.required"
msgstr "The login name is required."
-msgid "validation.pronoun.length"
-msgstr "The pronoun you have entered is too long. Use a maximum of 15 characters."
+msgid "validation.pronoun.required"
+msgstr "Please enter your pronoun."
-msgid "validation.firstname.length"
-msgstr "The first name you have entered is too long. Use a maximum of 64 characters."
+msgid "validation.firstname.required"
+msgstr "Please enter your first name."
-msgid "validation.lastname.length"
-msgstr "The last name you have entered is too long. Use a maximum of 64 characters."
+msgid "validation.lastname.required"
+msgstr "Please enter your last name."
-msgid "validation.mobile.optional"
-msgstr "The mobile number you have entered is too long. Use a maximum of 40 characters."
+msgid "validation.mobile.required"
+msgstr "Please enter your mobile number."
-msgid "validation.dect.optional"
-msgstr "The DECT number you have entered is too long. Use a maximum of 40 characters."
+msgid "validation.dect.required"
+msgstr "Please enter your DECT number."
msgid "validation.username.required"
msgstr "Please enter your nick."
diff --git a/resources/views/pages/settings/profile.twig b/resources/views/pages/settings/profile.twig
index c82bcd6e..043f89dc 100644
--- a/resources/views/pages/settings/profile.twig
+++ b/resources/views/pages/settings/profile.twig
@@ -28,6 +28,8 @@
{{ f.input('pronoun', __('settings.profile.pronoun'), {
'value': user.personalData.pronoun,
'max_length': 15,
+ 'required': isPronounRequired,
+ 'required_icon': isPronounRequired,
}) }}
{{ m.info(__('settings.profile.pronoun.info')) }}
@@ -40,12 +42,16 @@
{{ f.input('first_name', __('settings.profile.firstname'), {
'value': user.personalData.first_name,
'max_length': 64,
+ 'required': isFirstnameRequired,
+ 'required_icon': isFirstnameRequired,
}) }}
{{ f.input('last_name', __('settings.profile.lastname'), {
'value': user.personalData.last_name,
'max_length': 64,
+ 'required': isLastnameRequired,
+ 'required_icon': isLastnameRequired,
}) }}
@@ -82,6 +88,8 @@
{{ f.input('dect', __('general.dect'), {
'value': user.contact.dect,
'max_length': 40,
+ 'required': isDectRequired,
+ 'required_icon': isDectRequired,
}) }}
{% endif %}
@@ -89,6 +97,8 @@
{{ f.input('mobile', __('settings.profile.mobile'), {
'value': user.contact.mobile,
'max_length': 40,
+ 'required': isMobileRequired,
+ 'required_icon': isMobileRequired,
}) }}
{% if config('enable_mobile_show') %}
{{ f.checkbox('mobile_show', __('settings.profile.mobile_show'), {
@@ -141,8 +151,8 @@
{{ f.select('shirt_size', __('settings.profile.shirt_size'), config('tshirt_sizes'), {
'selected': user.personalData.shirt_size,
- 'required': true,
- 'required_icon': true,
+ 'required': isTShirtSizeRequired,
+ 'required_icon': isTShirtSizeRequired,
'default_option': __('form.select_placeholder'),
}) }}
diff --git a/resources/views/pages/sign-up.twig b/resources/views/pages/sign-up.twig
index eb4d2196..c9e177f6 100644
--- a/resources/views/pages/sign-up.twig
+++ b/resources/views/pages/sign-up.twig
@@ -31,6 +31,8 @@
__('settings.profile.pronoun'),
{
'max_length': 15,
+ 'required': isPronounRequired,
+ 'required_icon': isPronounRequired,
'value': f.formData('pronoun', ''),
}
) }}
@@ -162,6 +164,8 @@
{
'autocomplete': 'given-name',
'max_length': 64,
+ 'required': isFirstnameRequired,
+ 'required_icon': isFirstnameRequired,
'value': f.formData('firstname', ''),
}
) }}
@@ -173,6 +177,8 @@
{
'autocomplete': 'family-name',
'max_length': 64,
+ 'required': isLastnameRequired,
+ 'required_icon': isLastnameRequired,
'value': f.formData('lastname', ''),
}
) }}
@@ -227,8 +233,8 @@
tShirtSizes,
{
'default_option': __('form.select_placeholder'),
- 'required': true,
- 'required_icon': true,
+ 'required': isTShirtSizeRequired,
+ 'required_icon': isTShirtSizeRequired,
'selected': f.formData('tshirt_size', ''),
}
) }}
@@ -242,6 +248,8 @@
{
'type': 'tel-national',
'max_length': 40,
+ 'required': isMobileRequired,
+ 'required_icon': isMobileRequired,
'value': f.formData('mobile', ''),
}
) }}
@@ -265,6 +273,8 @@
{
'type': 'tel-local',
'max_length': 40,
+ 'required': isDectRequired,
+ 'required_icon': isDectRequired,
'value': f.formData('dect', ''),
}
) }}
diff --git a/src/Controllers/SettingsController.php b/src/Controllers/SettingsController.php
index 916d0aec..d64a3aee 100644
--- a/src/Controllers/SettingsController.php
+++ b/src/Controllers/SettingsController.php
@@ -35,6 +35,7 @@ class SettingsController extends BaseController
public function profile(): Response
{
$user = $this->auth->user();
+ $requiredFields = $this->config->get('signup_required_fields');
return $this->response->withView(
'pages/settings/profile',
@@ -43,6 +44,12 @@ class SettingsController extends BaseController
'user' => $user,
'goodie_tshirt' => $this->config->get('goodie_type') === GoodieType::Tshirt->value,
'goodie_enabled' => $this->config->get('goodie_type') !== GoodieType::None->value,
+ 'isPronounRequired' => $requiredFields['pronoun'],
+ 'isFirstnameRequired' => $requiredFields['firstname'],
+ 'isLastnameRequired' => $requiredFields['lastname'],
+ 'isTShirtSizeRequired' => $requiredFields['tshirt_size'],
+ 'isMobileRequired' => $requiredFields['mobile'],
+ 'isDectRequired' => $requiredFields['dect'],
]
);
}
@@ -359,6 +366,12 @@ class SettingsController extends BaseController
return true;
}
+ private function isRequired(string $key): string
+ {
+ $requiredFields = $this->config->get('signup_required_fields');
+ return $requiredFields[$key] ? 'required' : 'optional';
+ }
+
/**
* @return string[]
*/
@@ -366,11 +379,12 @@ class SettingsController extends BaseController
{
$goodie_tshirt = $this->config->get('goodie_type') === GoodieType::Tshirt->value;
$rules = [
- 'pronoun' => 'optional|max:15',
- 'first_name' => 'optional|max:64',
- 'last_name' => 'optional|max:64',
- 'dect' => 'optional|length:0:40', // dect/mobile can be purely numbers. "max" would have
- 'mobile' => 'optional|length:0:40', // checked their values, not their character length.
+ 'pronoun' => $this->isRequired('pronoun') . '|max:15',
+ 'first_name' => $this->isRequired('firstname') . '|max:64',
+ 'last_name' => $this->isRequired('lastname') . '|max:64',
+ 'dect' => $this->isRequired('dect') . '|length:0:40',
+ // dect/mobile can be purely numbers. "max" would have checked their values, not their character length.
+ 'mobile' => $this->isRequired('mobile') . '|length:0:40',
'mobile_show' => 'optional|checked',
'email' => 'required|email|max:254',
'email_shiftinfo' => 'optional|checked',
@@ -384,7 +398,7 @@ class SettingsController extends BaseController
$rules['planned_departure_date'] = 'optional|date:Y-m-d';
}
if ($goodie_tshirt) {
- $rules['shirt_size'] = 'required|shirt_size';
+ $rules['shirt_size'] = $this->isRequired('tshirt_size') . '|shirt_size';
}
return $rules;
}
diff --git a/src/Controllers/SignUpController.php b/src/Controllers/SignUpController.php
index 51e34b2b..ed634fc7 100644
--- a/src/Controllers/SignUpController.php
+++ b/src/Controllers/SignUpController.php
@@ -79,6 +79,7 @@ class SignUpController extends BaseController
{
$goodieType = GoodieType::from($this->config->get('goodie_type'));
$preselectedAngelTypes = $this->determinePreselectedAngelTypes();
+ $requiredFields = $this->config->get('signup_required_fields');
// form-data-register-submit is a marker, that the form was submitted.
// It will be used for instance to use the default angel types or the user selected ones.
@@ -101,6 +102,12 @@ class SignUpController extends BaseController
'isPronounEnabled' => $this->config->get('enable_pronoun'),
'isFullNameEnabled' => $this->config->get('enable_user_name'),
'isPlannedArrivalDateEnabled' => $this->config->get('enable_planned_arrival'),
+ 'isPronounRequired' => $requiredFields['pronoun'],
+ 'isFirstnameRequired' => $requiredFields['firstname'],
+ 'isLastnameRequired' => $requiredFields['lastname'],
+ 'isTShirtSizeRequired' => $requiredFields['tshirt_size'],
+ 'isMobileRequired' => $requiredFields['mobile'],
+ 'isDectRequired' => $requiredFields['dect'],
],
);
}
diff --git a/src/Factories/User.php b/src/Factories/User.php
index 44f971a5..4fbd4e66 100644
--- a/src/Factories/User.php
+++ b/src/Factories/User.php
@@ -67,6 +67,12 @@ class User
return $this->config->get('buildup_start') ?? CarbonImmutable::now();
}
+ private function isRequired(string $key): string
+ {
+ $requiredFields = $this->config->get('signup_required_fields');
+ return $requiredFields[$key] ? 'required' : 'optional';
+ }
+
/**
* @param Array $rawData
* @throws ValidationException
@@ -82,7 +88,7 @@ class User
'email_news' => 'optional|checked',
'email_goody' => 'optional|checked',
// Using length here, because min/max would validate dect/mobile as numbers.
- 'mobile' => 'optional|length:0:40',
+ 'mobile' => $this->isRequired('mobile') . '|length:0:40',
];
$isPasswordEnabled = $this->determineIsPasswordEnabled();
@@ -96,14 +102,14 @@ class User
$isFullNameEnabled = $this->config->get('enable_user_name');
if ($isFullNameEnabled) {
- $validationRules['firstname'] = 'optional|length:0:64';
- $validationRules['lastname'] = 'optional|length:0:64';
+ $validationRules['firstname'] = $this->isRequired('firstname') . '|length:0:64';
+ $validationRules['lastname'] = $this->isRequired('lastname') . '|length:0:64';
}
$isPronounEnabled = $this->config->get('enable_pronoun');
if ($isPronounEnabled) {
- $validationRules['pronoun'] = 'optional|max:15';
+ $validationRules['pronoun'] = $this->isRequired('pronoun') . '|max:15';
}
$isShowMobileEnabled = $this->config->get('enable_mobile_show');
@@ -137,14 +143,14 @@ class User
if ($isDECTEnabled) {
// Using length here, because min/max would validate dect/mobile as numbers.
- $validationRules['dect'] = 'optional|length:0:40';
+ $validationRules['dect'] = $this->isRequired('dect') . '|length:0:40';
}
$goodieType = GoodieType::from($this->config->get('goodie_type'));
$isGoodieTShirt = $goodieType === GoodieType::Tshirt;
if ($isGoodieTShirt) {
- $validationRules['tshirt_size'] = 'required|shirt-size';
+ $validationRules['tshirt_size'] = $this->isRequired('tshirt_size') . '|shirt-size';
}
$data = $this->validate($rawData, $validationRules);
diff --git a/tests/Unit/Controllers/SettingsControllerTest.php b/tests/Unit/Controllers/SettingsControllerTest.php
index f09f018e..89354e38 100644
--- a/tests/Unit/Controllers/SettingsControllerTest.php
+++ b/tests/Unit/Controllers/SettingsControllerTest.php
@@ -106,6 +106,7 @@ class SettingsControllerTest extends ControllerTest
/**
* @covers \Engelsystem\Controllers\SettingsController::saveProfile
* @covers \Engelsystem\Controllers\SettingsController::getSaveProfileRules
+ * @covers \Engelsystem\Controllers\SettingsController::isRequired
*/
public function testSaveProfile(): void
{
@@ -934,12 +935,21 @@ class SettingsControllerTest extends ControllerTest
'de_DE' => 'Deutsch',
];
$tshirt_sizes = ['S' => 'Small'];
+ $requiredFields = [
+ 'pronoun' => false,
+ 'firstname' => false,
+ 'lastname' => false,
+ 'tshirt_size' => true,
+ 'mobile' => false,
+ 'dect' => false,
+ ];
$this->config = new Config([
'min_password_length' => 6,
'themes' => $themes,
'locales' => $languages,
'tshirt_sizes' => $tshirt_sizes,
'goodie_type' => GoodieType::Goodie->value,
+ 'signup_required_fields' => $requiredFields,
]);
$this->app->instance('config', $this->config);
$this->app->instance(Config::class, $this->config);
diff --git a/tests/Utils/SignUpConfig.php b/tests/Utils/SignUpConfig.php
index 5a9aeb6b..5f97c7cf 100644
--- a/tests/Utils/SignUpConfig.php
+++ b/tests/Utils/SignUpConfig.php
@@ -11,6 +11,14 @@ final class SignUpConfig
{
public static function setMaximumConfig(Config $config): void
{
+ $requiredFields = [
+ 'pronoun' => false,
+ 'firstname' => false,
+ 'lastname' => false,
+ 'tshirt_size' => true,
+ 'mobile' => false,
+ 'dect' => false,
+ ];
$config->set('registration_enabled', true);
$config->set('enable_password', true);
$config->set('enable_pronoun', true);
@@ -27,10 +35,25 @@ final class SignUpConfig
$config->set('enable_user_name', true);
$config->set('enable_mobile_show', true);
$config->set('enable_dect', true);
+ $config->set('signup_required_fields', $requiredFields);
}
public static function setMinimumConfig(Config $config): void
{
+ $requiredFields = [
+ 'pronoun' => false,
+ 'firstname' => false,
+ 'lastname' => false,
+ 'tshirt_size' => true,
+ 'mobile' => false,
+ 'dect' => false,
+ ];
+ $requiredFields['pronoun'] = false;
+ $requiredFields['firstname'] = false;
+ $requiredFields['lastname'] = false;
+ $requiredFields['tshirt_size'] = true;
+ $requiredFields['mobile'] = false;
+ $requiredFields['dect'] = false;
$config->set('registration_enabled', true);
$config->set('enable_password', true);
$config->set('enable_pronoun', false);
@@ -43,5 +66,6 @@ final class SignUpConfig
$config->set('enable_user_name', false);
$config->set('enable_mobile_show', false);
$config->set('enable_dect', false);
+ $config->set('signup_required_fields', $requiredFields);
}
}