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' } }) }}