From 466fa78e9063608165f252fb3edb5f6262daf5b9 Mon Sep 17 00:00:00 2001
From: Gwildor Sok
Date: Tue, 5 Mar 2024 22:23:16 +0100
Subject: [PATCH] [143] Add middle names
---
.env | 1 +
README.md | 8 ++++
config/services.yaml | 1 +
migrations/Version20240305203045.php | 37 +++++++++++++++++++
src/Controller/Admin/MemberCrud.php | 9 ++++-
.../Admin/MembershipApplicationCrud.php | 17 +++++++--
src/Controller/MemberController.php | 11 ++++--
src/DataFixtures/MemberFixtures.php | 3 +-
src/Entity/Member.php | 13 ++++++-
src/Entity/MembershipApplication.php | 16 ++++++++
src/Form/MembershipApplicationType.php | 23 ++++++++++--
.../email/html/contact_new_member.html.twig | 2 +-
.../email/html/request_new_password.html.twig | 2 +-
.../email/text/contact_new_member.txt.twig | 2 +-
.../email/text/request_new_password.txt.twig | 2 +-
templates/user/member/apply.html.twig | 5 +++
16 files changed, 135 insertions(+), 17 deletions(-)
create mode 100644 migrations/Version20240305203045.php
diff --git a/.env b/.env
index c0a22bb..93c7877 100644
--- a/.env
+++ b/.env
@@ -56,6 +56,7 @@ ORGANIZATION_NAME_SHORT='ROOD'
ORG_LOGO='assets/image/logo.png'
PRIVACY_POLICY_URL='https://roodjongeren.nl/privacybeleid/'
LISTMONK_URL='https://listmonk.roodjongeren.nl/admin'
+USE_MIDDLE_NAME=true
# Set to https in production environment
SECURE_SCHEME='http'
diff --git a/README.md b/README.md
index b3793a5..42c7894 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,14 @@ Go to `http://localhost:8080/` and you should be greeted by the MijnRood login p
You can log in with `admindebaas@example.com` as email, and `admin` as password.
Look at `src/DataFixtures/` to see an overview of all test data, including other accounts.
+## Contributing
+
+You can generate new migrations with:
+
+`docker compose run --rm php82-service symfony console doctrine:migrations:diff`
+
+Make sure the output is as you expected, and change it if necessary!
+
## License
This project is licensed under the EUPL, the license text in English can be found in the `LICENSE` file.
diff --git a/config/services.yaml b/config/services.yaml
index bc47830..ec17c51 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -12,6 +12,7 @@ parameters:
app.orgLogo: '%env(ORG_LOGO)%'
app.privacyPolicyUrl: '%env(PRIVACY_POLICY_URL)%'
app.listmonkUrl: '%env(string:LISTMONK_URL)%'
+ app.useMiddleName: '%env(bool:USE_MIDDLE_NAME)%'
router.request_context.scheme: '%env(SECURE_SCHEME)%'
asset.request_context.secure: true
diff --git a/migrations/Version20240305203045.php b/migrations/Version20240305203045.php
new file mode 100644
index 0000000..fc16a70
--- /dev/null
+++ b/migrations/Version20240305203045.php
@@ -0,0 +1,37 @@
+addSql('ALTER TABLE admin_member ADD COLUMN IF NOT EXISTS middle_name VARCHAR(50) DEFAULT \'\' NOT NULL');
+ $this->addSql('ALTER TABLE admin_membership_application ADD COLUMN IF NOT EXISTS middle_name VARCHAR(50) DEFAULT \'\' NOT NULL');
+ $this->addSql('UPDATE admin_member SET middle_name = \'\' WHERE middle_name IS NULL');
+ $this->addSql('UPDATE admin_membership_application SET middle_name = \'\' WHERE middle_name IS NULL');
+ $this->addSql('ALTER TABLE admin_member CHANGE middle_name middle_name VARCHAR(50) DEFAULT \'\' NOT NULL');
+ $this->addSql('ALTER TABLE admin_membership_application CHANGE middle_name middle_name VARCHAR(50) DEFAULT \'\' NOT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->addSql('ALTER TABLE admin_member DROP middle_name');
+ $this->addSql('ALTER TABLE admin_membership_application DROP middle_name');
+ }
+}
diff --git a/src/Controller/Admin/MemberCrud.php b/src/Controller/Admin/MemberCrud.php
index e9e1bd4..199b1f2 100644
--- a/src/Controller/Admin/MemberCrud.php
+++ b/src/Controller/Admin/MemberCrud.php
@@ -170,13 +170,20 @@ public function configureFields(string $pageName): iterable
->setFormTypeOptions(['attr' => ['placeholder' => 'Wordt automatisch bepaald']]),
TextField::new('firstName', 'Voornaam')->setDisabled(!$isAdmin),
+ ];
+
+ if ($this->getParameter('app.useMiddleName')) {
+ $fields[] = TextField::new('middleName', 'Tussenvoegsel')->setDisabled(!$isAdmin)->setRequired(false);
+ }
+
+ array_push($fields,
TextField::new('lastName', 'Achternaam')->setDisabled(!$isAdmin),
DateField::new('dateOfBirth', 'Geboortedatum')->setDisabled(!$isAdmin)->hideOnIndex(),
DateField::new('registrationTime', 'Inschrijfdatum')
->setFormat(DateTimeField::FORMAT_SHORT)
->hideOnIndex(),
TextField::new('comments', 'Extra informatie'),
- ];
+ );
if ($isAdmin) {
$fields[] = AssociationField::new('currentMembershipStatus', 'Lidmaatschapstype');
diff --git a/src/Controller/Admin/MembershipApplicationCrud.php b/src/Controller/Admin/MembershipApplicationCrud.php
index 3f96b07..474aaef 100644
--- a/src/Controller/Admin/MembershipApplicationCrud.php
+++ b/src/Controller/Admin/MembershipApplicationCrud.php
@@ -130,7 +130,7 @@ public function acceptApplication(AdminContext $context)
$message = (new Email())
->subject("Welkom bij $organizationName!")
- ->to(new Address($member->getEmail(), $member->getFirstName() .' '. $member->getLastName()))
+ ->to(new Address($member->getEmail(), $member->getFullName()))
->from(new Address($noreply,$organizationName))
->html(
$this->renderView('email/html/welcome.html.twig', ['member' => $member])
@@ -147,7 +147,7 @@ public function acceptApplication(AdminContext $context)
{
$message2 = (new Email())
->subject('Nieuw lid aangesloten bij je groep')
- ->to(new Address($contact->getEmail(), $contact->getFirstName() .' '. $contact->getLastName()))
+ ->to(new Address($contact->getEmail(), $contact->getFullName()))
->from(new Address($noreply, $organizationName))
->html(
$this->renderView('email/html/contact_new_member.html.twig', [
@@ -174,8 +174,15 @@ public function acceptApplication(AdminContext $context)
public function configureFields(string $pageName): iterable
{
- return [
+ $fields = [
TextField::new('firstName', 'Voornaam'),
+ ];
+
+ if ($this->getParameter('app.useMiddleName')) {
+ $fields[] = TextField::new('middleName', 'Tussenvoegsel')->setRequired(false);
+ }
+
+ array_push($fields,
TextField::new('lastName', 'Achternaam'),
DateField::new('dateOfBirth', 'Geboortedatum')
->hideOnIndex(),
@@ -209,7 +216,9 @@ public function configureFields(string $pageName): iterable
->hideOnIndex(),
BooleanField::new('paid', 'Eerste contributie betaald')
- ];
+ );
+
+ return $fields;
}
public function configureFilters(Filters $filters): Filters
diff --git a/src/Controller/MemberController.php b/src/Controller/MemberController.php
index 9429c72..340ec6f 100644
--- a/src/Controller/MemberController.php
+++ b/src/Controller/MemberController.php
@@ -89,7 +89,11 @@ public function apply(Request $request): Response {
$membershipApplication = new MembershipApplication();
$membershipApplication->setRegistrationTime(new \DateTime());
$membershipApplication->setContributionPeriod(Member::PERIOD_QUARTERLY);
- $form = $this->createForm(MembershipApplicationType::class, $membershipApplication);
+ $form = $this->createForm(MembershipApplicationType::class, $membershipApplication, [
+ 'use_middle_name' => $this->getParameter('app.useMiddleName'),
+ 'privacy_policy_url' => $this->getParameter('app.privacyPolicyUrl'),
+ 'organization_name' => $this->getParameter('app.organizationName')
+ ]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -107,7 +111,7 @@ public function apply(Request $request): Response {
else
{
$customer = $this->mollieApiClient->customers->create([
- 'name' => $membershipApplication->getFirstName() . ' ' . $membershipApplication->getLastName(),
+ 'name' => $membershipApplication->getFullName(),
'email' => $membershipApplication->getEmail()
]);
@@ -125,7 +129,8 @@ public function apply(Request $request): Response {
return $this->render('user/member/apply.html.twig', [
'success' => false,
- 'form' => $form->createView()
+ 'form' => $form->createView(),
+ 'useMiddleName' => $this->getParameter('app.useMiddleName')
]);
}
diff --git a/src/DataFixtures/MemberFixtures.php b/src/DataFixtures/MemberFixtures.php
index 36d6968..c513fc9 100644
--- a/src/DataFixtures/MemberFixtures.php
+++ b/src/DataFixtures/MemberFixtures.php
@@ -61,7 +61,8 @@ public function load(ObjectManager $manager)
$newMember = new Member();
$newMember->setId(1339);
$newMember->setFirstName("Henk");
- $newMember->setLastName("de Vries");
+ $newMember->setMiddleName("de");
+ $newMember->setLastName("Vries");
$newMember->setEmail("henkdevries@example.com");
$newMember->setContributionPerPeriodInEuros(5);
$newMember->setPasswordHash(password_hash("new_member", PASSWORD_DEFAULT));
diff --git a/src/Entity/Member.php b/src/Entity/Member.php
index f410261..a7107c2 100644
--- a/src/Entity/Member.php
+++ b/src/Entity/Member.php
@@ -32,6 +32,11 @@ class Member implements UserInterface {
*/
private string $firstName = '';
+ /**
+ * @ORM\Column(type="string", length=50, options={"default": ""})
+ */
+ private string $middleName = '';
+
/**
* @ORM\Column(type="string", length=100)
*/
@@ -184,11 +189,17 @@ public function setId(int $id): void { $this->id = $id; }
public function getFirstName(): string { return $this->firstName; }
public function setFirstName(string $firstName): void { $this->firstName = $firstName; }
+ public function getMiddleName(): string { return $this->middleName; }
+ public function setMiddleName(?string $middleName): void { $this->middleName = $middleName ? $middleName : ''; }
+
public function getLastName(): string { return $this->lastName; }
public function setLastName(string $lastName): void { $this->lastName = $lastName; }
public function getFullName(): string {
- return $this->firstName. ' ' . $this->lastName;
+ if ($this->middleName === '') {
+ return $this->firstName. ' ' . $this->lastName;
+ }
+ return $this->firstName . ' ' . $this->middleName . ' ' . $this->lastName;
}
public function getAddress(): string { return $this->address; }
diff --git a/src/Entity/MembershipApplication.php b/src/Entity/MembershipApplication.php
index 0bd7e0f..35e9b13 100644
--- a/src/Entity/MembershipApplication.php
+++ b/src/Entity/MembershipApplication.php
@@ -27,6 +27,11 @@ class MembershipApplication {
*/
private string $firstName = '';
+ /**
+ * @ORM\Column(type="string", length=50, options={"default": ""})
+ */
+ private string $middleName = '';
+
/**
* @ORM\Column(type="string", length=100)
*/
@@ -118,6 +123,7 @@ public function __toString() {
public function createMember(?string $mollieSubscriptionId): Member {
$member = new Member();
$member->setFirstName($this->getFirstName());
+ $member->setMiddleName($this->getMiddleName());
$member->setLastName($this->getLastName());
$member->setAddress($this->getAddress());
$member->setCity($this->getCity());
@@ -142,9 +148,19 @@ public function setId(int $id): void { $this->id = $id; }
public function getFirstName(): string { return $this->firstName; }
public function setFirstName(string $firstName): void { $this->firstName = $firstName; }
+ public function getMiddleName(): string { return $this->middleName; }
+ public function setMiddleName(?string $middleName): void { $this->middleName = $middleName ? $middleName : ''; }
+
public function getLastName(): string { return $this->lastName; }
public function setLastName(string $lastName): void { $this->lastName = $lastName; }
+ public function getFullName(): string {
+ if ($this->middleName === '') {
+ return $this->firstName. ' ' . $this->lastName;
+ }
+ return $this->firstName . ' ' . $this->middleName . ' ' . $this->lastName;
+ }
+
public function getAddress(): string { return $this->address; }
public function setAddress(string $address): void { $this->address = $address; }
diff --git a/src/Form/MembershipApplicationType.php b/src/Form/MembershipApplicationType.php
index a893fe3..cbc3aee 100644
--- a/src/Form/MembershipApplicationType.php
+++ b/src/Form/MembershipApplicationType.php
@@ -16,8 +16,13 @@ class MembershipApplicationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
+ $builder->add('firstName', null, ['label' => 'Voornaam', 'error_bubbling' => true, 'constraints' => [new NotBlank()]]);
+
+ if ($options['use_middle_name']) {
+ $builder->add('middleName', null, ['label' => 'Tussenvoegsel', 'error_bubbling' => true]);
+ }
+
$builder
- ->add('firstName', null, ['label' => 'Voornaam', 'error_bubbling' => true, 'constraints' => [new NotBlank()]])
->add('lastName', null, ['label' => 'Achternaam', 'error_bubbling' => true, 'constraints' => [new NotBlank()]])
->add('email', null, ['label' => 'E-mailadres', 'error_bubbling' => true, 'constraints' => [new NotBlank()]])
->add('phone', null, ['label' => 'Telefoonnummer', 'error_bubbling' => true, 'constraints' => [new NotBlank()]])
@@ -46,12 +51,12 @@ public function buildForm(FormBuilderInterface $builder, array $options)
'error_bubbling' => true
])
->add('accept', CheckboxType::class, [
- 'label' => 'Ik heb het privacybeleid gelezen en ik ga daarmee akkoord.',
+ 'label' => 'Ik heb het privacybeleid gelezen en ik ga daarmee akkoord.',
'label_html' => true,
'mapped' => false,
'required' => true,
'error_bubbling' => true,
- 'constraints' => [new IsTrue(['message' => 'Je moet akkoord gaan met het privacybeleid van ROOD, tenzij je jonger bent dan 16.'])]
+ 'constraints' => [new IsTrue(['message' => 'Je moet akkoord gaan met het privacybeleid van ' . $options['organization_name'] . ', tenzij je jonger bent dan 16.'])]
])
;
}
@@ -61,5 +66,17 @@ public function configureOptions(OptionsResolver $resolver)
$resolver->setDefaults([
'data_class' => MembershipApplication::class,
]);
+
+ $resolver->setRequired([
+ 'use_middle_name'
+ ]);
+
+ $resolver->setRequired([
+ 'privacy_policy_url'
+ ]);
+
+ $resolver->setRequired([
+ 'organization_name'
+ ]);
}
}
diff --git a/templates/email/html/contact_new_member.html.twig b/templates/email/html/contact_new_member.html.twig
index 695dc01..0e9f468 100644
--- a/templates/email/html/contact_new_member.html.twig
+++ b/templates/email/html/contact_new_member.html.twig
@@ -5,7 +5,7 @@
Beste {{ member.division.contact.firstName }} {{ member.division.contact.lastName }},
- Onlangs heeft een nieuw lid zich aangemeld bij {{ organisatienaam }}: {{ member.firstName }} {{ member.lastName }}.
+ Onlangs heeft een nieuw lid zich aangemeld bij {{ organisatienaam }}: {{ member.getFullName }}.
Hun lidmaatschap is zojuist goedgekeurd door het bestuur van {{ organisatienaam }}. Bij het aanmelden heeft dit lid aangegeven
zich graag aan te sluiten bij de groep {{ member.division.name }}.
diff --git a/templates/email/html/request_new_password.html.twig b/templates/email/html/request_new_password.html.twig
index 61513ff..55b1e9f 100644
--- a/templates/email/html/request_new_password.html.twig
+++ b/templates/email/html/request_new_password.html.twig
@@ -2,7 +2,7 @@
{% set url = url('set_new_password', { token: member.newPasswordToken }) %}
{% block content %}
- Beste {{ member.firstName }} {{ member.lastName }},
+ Beste {{ member.getFullName }},
Je hebt in het ledenadministratiesysteem een verzoek gedaan om een nieuw wachtwoord in te stellen.
diff --git a/templates/email/text/contact_new_member.txt.twig b/templates/email/text/contact_new_member.txt.twig
index 4ac6c91..9101239 100644
--- a/templates/email/text/contact_new_member.txt.twig
+++ b/templates/email/text/contact_new_member.txt.twig
@@ -3,7 +3,7 @@ r% extends 'email/text/layout.txt.twig' %}
{% block content %}
Beste {{ member.division.contact.firstName }} {{ member.division.contact.lastName }},
-Onlangs heeft een nieuw lid zich aangemeld bij {{ organisatienaam }}: {{ member.firstName }} {{ member.lastName }}.
+Onlangs heeft een nieuw lid zich aangemeld bij {{ organisatienaam }}: {{ member.getFullName }}.
Hun lidmaatschap is zojuist goedgekeurd door het bestuur van {{ organisatienaam }}. Bij het aanmelden heeft dit lid aangegeven zich graag aan te sluiten bij de groep {{ member.division.name }}.
Hun gegevens zijn toegevoegd aan het ledenoverzicht in het ledenadministratiesysteem. Klik op de onderstaande link om het te openen.
diff --git a/templates/email/text/request_new_password.txt.twig b/templates/email/text/request_new_password.txt.twig
index 0c8c109..0bc4369 100644
--- a/templates/email/text/request_new_password.txt.twig
+++ b/templates/email/text/request_new_password.txt.twig
@@ -1,7 +1,7 @@
{% extends 'email/text/layout.txt.twig' %}
{% set url = url('set_new_password', { token: member.newPasswordToken }) %}
{% block content %}
-Beste {{ member.firstName }} {{ member.lastName }},
+Beste {{ member.getFullName }},
Je hebt in het ledenadministratiesysteem een verzoek gedaan om een nieuw wachtwoord in te stellen.
Als je je niet kunt herinneren dat je dit gedaan hebt, kun je deze e-mail negeren.
diff --git a/templates/user/member/apply.html.twig b/templates/user/member/apply.html.twig
index 1041743..21b5a26 100644
--- a/templates/user/member/apply.html.twig
+++ b/templates/user/member/apply.html.twig
@@ -49,6 +49,11 @@
{{ form_label(form.firstName, 'Naam') }}
{{ form_widget(form.firstName, { attr: { class: 'text-input', placeholder: 'Voornaam' } }) }}
+
+ {% if useMiddleName %}
+ {{ form_widget(form.middleName, { attr: { class: 'text-input', placeholder: 'Tussenvoegsel' } }) }}
+ {% endif %}
+
{{ form_widget(form.lastName, { attr: { class: 'text-input', placeholder: 'Achternaam' } }) }}