diff --git a/.changes/unreleased/Feature-20241030-095713.yaml b/.changes/unreleased/Feature-20241030-095713.yaml
new file mode 100644
index 000000000..391fcd878
--- /dev/null
+++ b/.changes/unreleased/Feature-20241030-095713.yaml
@@ -0,0 +1,5 @@
+kind: Feature
+body: Introduce a gender entity
+time: 2024-10-30T09:57:13.110347067+01:00
+custom:
+ Issue: ""
diff --git a/package.json b/package.json
index 0c932b9f6..8f741d3e9 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,8 @@
"vue-i18n": "^9.1.6",
"vue-multiselect": "3.0.0-alpha.2",
"vue-toast-notification": "^3.1.2",
- "vuex": "^4.0.0"
+ "vuex": "^4.0.0",
+ "bootstrap-icons": "^1.11.3"
},
"browserslist": [
"Firefox ESR"
diff --git a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php
index 21aa746aa..723b47612 100644
--- a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php
+++ b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php
@@ -178,7 +178,7 @@ class CustomFieldsGroup
*
* @return CustomFieldsGroup
*/
- public function setName($name)
+ public function setName(array|string $name)
{
$this->name = $name;
diff --git a/src/Bundle/ChillMainBundle/Controller/GenderApiController.php b/src/Bundle/ChillMainBundle/Controller/GenderApiController.php
new file mode 100644
index 000000000..96fae4024
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Controller/GenderApiController.php
@@ -0,0 +1,32 @@
+andWhere(
+ $query->expr()->eq('e.active', "'TRUE'")
+ );
+ }
+
+ protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format)
+ {
+ return $query->addOrderBy('e.order', 'ASC');
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Controller/GenderController.php b/src/Bundle/ChillMainBundle/Controller/GenderController.php
new file mode 100644
index 000000000..a556145d4
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Controller/GenderController.php
@@ -0,0 +1,26 @@
+addOrderBy('e.order', 'ASC');
+
+ return parent::orderQuery($action, $query, $request, $paginator);
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php
new file mode 100644
index 000000000..2d74e6977
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php
@@ -0,0 +1,63 @@
+ ['en' => 'man', 'fr' => 'homme'],
+ 'genderTranslation' => GenderEnum::MALE,
+ 'icon' => GenderIconEnum::MALE,
+ ],
+ [
+ 'label' => ['en' => 'woman', 'fr' => 'femme'],
+ 'genderTranslation' => GenderEnum::FEMALE,
+ 'icon' => GenderIconEnum::FEMALE,
+ ],
+ [
+ 'label' => ['en' => 'neutral', 'fr' => 'neutre'],
+ 'genderTranslation' => GenderEnum::NEUTRAL,
+ 'icon' => GenderIconEnum::NEUTRAL,
+ ],
+ ];
+
+ public function getOrder()
+ {
+ return 100;
+ }
+
+ public function load(ObjectManager $manager)
+ {
+ echo "loading genders... \n";
+
+ foreach ($this->genders as $g) {
+ echo $g['label']['fr'].' ';
+ $new_g = new Gender();
+ $new_g->setGenderTranslation($g['genderTranslation']);
+ $new_g->setLabel($g['label']);
+ $new_g->setIcon($g['icon']);
+
+ $this->addReference('g_'.$g['genderTranslation']->value, $new_g);
+ $manager->persist($new_g);
+ }
+
+ $manager->flush();
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php
index 9d788c64e..ca293cdd3 100644
--- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php
+++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php
@@ -17,6 +17,8 @@ use Chill\MainBundle\Controller\CivilityApiController;
use Chill\MainBundle\Controller\CivilityController;
use Chill\MainBundle\Controller\CountryApiController;
use Chill\MainBundle\Controller\CountryController;
+use Chill\MainBundle\Controller\GenderApiController;
+use Chill\MainBundle\Controller\GenderController;
use Chill\MainBundle\Controller\GeographicalUnitApiController;
use Chill\MainBundle\Controller\LanguageController;
use Chill\MainBundle\Controller\LocationController;
@@ -52,6 +54,7 @@ use Chill\MainBundle\Doctrine\Type\PointType;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Civility;
use Chill\MainBundle\Entity\Country;
+use Chill\MainBundle\Entity\Gender;
use Chill\MainBundle\Entity\GeographicalUnitLayer;
use Chill\MainBundle\Entity\Language;
use Chill\MainBundle\Entity\Location;
@@ -63,6 +66,7 @@ use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Form\CenterType;
use Chill\MainBundle\Form\CivilityType;
use Chill\MainBundle\Form\CountryType;
+use Chill\MainBundle\Form\GenderType;
use Chill\MainBundle\Form\LanguageType;
use Chill\MainBundle\Form\LocationFormType;
use Chill\MainBundle\Form\LocationTypeType;
@@ -485,6 +489,28 @@ class ChillMainExtension extends Extension implements
],
],
],
+ [
+ 'class' => Gender::class,
+ 'name' => 'main_gender',
+ 'base_path' => '/admin/main/gender',
+ 'base_role' => 'ROLE_ADMIN',
+ 'form_class' => GenderType::class,
+ 'controller' => GenderController::class,
+ 'actions' => [
+ 'index' => [
+ 'role' => 'ROLE_ADMIN',
+ 'template' => '@ChillMain/Gender/index.html.twig',
+ ],
+ 'new' => [
+ 'role' => 'ROLE_ADMIN',
+ 'template' => '@ChillMain/Gender/new.html.twig',
+ ],
+ 'edit' => [
+ 'role' => 'ROLE_ADMIN',
+ 'template' => '@ChillMain/Gender/edit.html.twig',
+ ],
+ ],
+ ],
[
'class' => Language::class,
'name' => 'main_language',
@@ -788,6 +814,21 @@ class ChillMainExtension extends Extension implements
],
],
],
+ [
+ 'class' => Gender::class,
+ 'name' => 'gender',
+ 'base_path' => '/api/1.0/main/gender',
+ 'base_role' => 'ROLE_USER',
+ 'controller' => GenderApiController::class,
+ 'actions' => [
+ '_index' => [
+ 'methods' => [
+ Request::METHOD_GET => true,
+ Request::METHOD_HEAD => true,
+ ],
+ ],
+ ],
+ ],
[
'class' => GeographicalUnitLayer::class,
'controller' => GeographicalUnitApiController::class,
diff --git a/src/Bundle/ChillMainBundle/Entity/Gender.php b/src/Bundle/ChillMainBundle/Entity/Gender.php
new file mode 100644
index 000000000..59c0bd134
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Entity/Gender.php
@@ -0,0 +1,104 @@
+ Gender::class])]
+#[ORM\Entity(repositoryClass: GenderRepository::class)]
+#[ORM\Table(name: 'chill_main_gender')]
+class Gender
+{
+ #[Serializer\Groups(['read'])]
+ #[ORM\Id]
+ #[ORM\GeneratedValue]
+ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
+ private ?int $id = null;
+
+ #[Serializer\Groups(['read'])]
+ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
+ private array $label = [];
+
+ #[Serializer\Groups(['read'])]
+ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)]
+ private bool $active = true;
+
+ #[Assert\NotNull(message: 'You must choose a gender translation')]
+ #[Serializer\Groups(['read'])]
+ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, enumType: GenderEnum::class)]
+ private GenderEnum $genderTranslation;
+
+ #[Serializer\Groups(['read'])]
+ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, enumType: GenderIconEnum::class)]
+ private GenderIconEnum $icon;
+
+ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT, name: 'ordering', nullable: true, options: ['default' => '0.0'])]
+ private float $order = 0;
+
+ public function getId(): int
+ {
+ return $this->id;
+ }
+
+ public function getLabel(): array
+ {
+ return $this->label;
+ }
+
+ public function setLabel(array $label): void
+ {
+ $this->label = $label;
+ }
+
+ public function isActive(): bool
+ {
+ return $this->active;
+ }
+
+ public function setActive(bool $active): void
+ {
+ $this->active = $active;
+ }
+
+ public function getGenderTranslation(): GenderEnum
+ {
+ return $this->genderTranslation;
+ }
+
+ public function setGenderTranslation(GenderEnum $genderTranslation): void
+ {
+ $this->genderTranslation = $genderTranslation;
+ }
+
+ public function getIcon(): GenderIconEnum
+ {
+ return $this->icon;
+ }
+
+ public function setIcon(GenderIconEnum $icon): void
+ {
+ $this->icon = $icon;
+ }
+
+ public function getOrder(): float
+ {
+ return $this->order;
+ }
+
+ public function setOrder(float $order): void
+ {
+ $this->order = $order;
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Entity/GenderEnum.php b/src/Bundle/ChillMainBundle/Entity/GenderEnum.php
new file mode 100644
index 000000000..1fce6f2a6
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Entity/GenderEnum.php
@@ -0,0 +1,19 @@
+add('label', TranslatableStringFormType::class, [
+ 'required' => true,
+ ])
+ ->add('icon', EnumType::class, [
+ 'class' => GenderIconEnum::class,
+ 'choices' => GenderIconEnum::cases(),
+ 'expanded' => true,
+ 'multiple' => false,
+ 'mapped' => true,
+ 'choice_label' => fn (GenderIconEnum $enum) => '',
+ 'choice_value' => fn (?GenderIconEnum $enum) => null !== $enum ? $enum->value : null,
+ 'label' => 'gender.admin.Select Gender Icon',
+ 'label_html' => true,
+ ])
+ ->add('genderTranslation', EnumType::class, [
+ 'class' => GenderEnum::class,
+ 'choice_label' => fn (GenderEnum $enum) => $enum->value,
+ 'label' => 'gender.admin.Select Gender Translation',
+ ])
+ ->add('active', ChoiceType::class, [
+ 'choices' => [
+ 'Active' => true,
+ 'Inactive' => false,
+ ],
+ ])
+ ->add('order', NumberType::class);
+ }
+
+ public function configureOptions(OptionsResolver $resolver): void
+ {
+ $resolver->setDefaults([
+ 'data_class' => Gender::class,
+ ]);
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Repository/GenderRepository.php b/src/Bundle/ChillMainBundle/Repository/GenderRepository.php
new file mode 100644
index 000000000..56dcd1a4b
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Repository/GenderRepository.php
@@ -0,0 +1,47 @@
+
+ */
+class GenderRepository extends ServiceEntityRepository
+{
+ public function __construct(ManagerRegistry $registry)
+ {
+ parent::__construct($registry, Gender::class);
+ }
+
+ public function findByActiveOrdered(): array
+ {
+ return $this->createQueryBuilder('g')
+ ->select('g')
+ ->where('g.active = True')
+ ->orderBy('g.order', 'ASC')
+ ->getQuery()
+ ->getResult();
+ }
+
+ public function findByGenderTranslation($gender): array
+ {
+ return $this->createQueryBuilder('g')
+ ->select('g')
+ ->where('g.genderTranslation = :gender')
+ ->setParameter('gender', $gender)
+ ->getQuery()
+ ->getResult();
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/index.js b/src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/index.js
index a9d34e01d..91d66416a 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/index.js
+++ b/src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/index.js
@@ -10,6 +10,7 @@ import Modal from 'bootstrap/js/dist/modal';
import Collapse from 'bootstrap/js/src/collapse';
import Carousel from 'bootstrap/js/src/carousel';
import Popover from 'bootstrap/js/src/popover';
+import 'bootstrap-icons/font/bootstrap-icons.css';
//
// Carousel: ACHeaderSlider is a small slider used in banner of AccompanyingCourse Section
@@ -59,4 +60,4 @@ const popoverList = triggerList.map(function (el) {
return new Popover(el, {
html: true,
});
-});
\ No newline at end of file
+});
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/GenderIconRenderBox.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/GenderIconRenderBox.vue
new file mode 100644
index 000000000..2aeb123c7
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/GenderIconRenderBox.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.ts b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.ts
index f81699a7c..1e2844f3e 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.ts
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.ts
@@ -38,7 +38,8 @@ const messages = {
person: "Usager",
birthday: {
man: "Né le",
- woman: "Née le"
+ woman: "Née le",
+ neutral: "Né·e le"
},
deathdate: "Date de décès",
household_without_address: "Le ménage de l'usager est sans adresse",
diff --git a/src/Bundle/ChillMainBundle/Resources/views/Gender/edit.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Gender/edit.html.twig
new file mode 100644
index 000000000..39f01e519
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/views/Gender/edit.html.twig
@@ -0,0 +1,75 @@
+{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
+
+{% block title %}
+ {% include('@ChillMain/CRUD/_edit_title.html.twig') %}
+{% endblock %}
+
+{% form_theme form _self %}
+
+{% block _gender_icon_widget %}
+ {% for child in form %}
+
+
+
+
+
+ {% endfor %}
+{% endblock %}
+
+{% block admin_content %}
+ {% set formId = crudMainFormId|default('crud_main_form') %}
+
+ {% block crud_content_header %}
+ {{ ('crud.'~crud_name~'.title_edit')|trans }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_form %}
+ {{ form_start(form, { 'attr' : { 'id': formId } }) }}
+
+ {{ form_row(form.label) }}
+ {{ form_row(form.genderTranslation) }}
+ {{ form_row(form.icon) }}
+ {{ form_row(form.active) }}
+ {{ form_row(form.order) }}
+
+ {{ form_end(form) }}
+ {% block crud_content_after_form %}{% endblock %}
+
+ {% block crud_content_form_actions %}
+
+ {% endblock %}
+
+ {% endblock %}
+{% endblock admin_content %}
diff --git a/src/Bundle/ChillMainBundle/Resources/views/Gender/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Gender/index.html.twig
new file mode 100644
index 000000000..8155e18ec
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/views/Gender/index.html.twig
@@ -0,0 +1,46 @@
+{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
+
+{% block admin_content %}
+ {% embed '@ChillMain/CRUD/_index.html.twig' %}
+ {% block table_entities_thead_tr %}
+ id |
+ {{ 'label'|trans }} |
+ {{ 'icon'|trans }} |
+ {{ 'gender.genderTranslation'|trans }} |
+ {{ 'active'|trans }} |
+ {{ 'ordering'|trans }} |
+ |
+ {% endblock %}
+ {% block table_entities_tbody %}
+ {% for entity in entities %}
+
+ {{ entity.id }} |
+ {{ entity.label|localize_translatable_string }} |
+ {{ entity.icon|chill_entity_render_box }} |
+ {{ entity.genderTranslation.value }} |
+
+ {%- if entity.active -%}
+
+ {%- else -%}
+
+ {%- endif -%}
+ |
+ {{ entity.order }} |
+
+
+ |
+
+ {% endfor %}
+ {% endblock %}
+
+ {% block actions_before %}
+
+ {{'Back to the admin'|trans}}
+
+ {% endblock %}
+ {% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillMainBundle/Resources/views/Gender/new.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Gender/new.html.twig
new file mode 100644
index 000000000..a07ebfa9d
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/views/Gender/new.html.twig
@@ -0,0 +1,79 @@
+{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
+
+{% block title %}
+ {% include('@ChillMain/CRUD/_new_title.html.twig') %}
+{% endblock %}
+
+{% form_theme form _self %}
+
+{% block _gender_icon_widget %}
+ {% for child in form %}
+
+
+
+
+
+ {% endfor %}
+{% endblock %}
+
+{% block admin_content %}
+ {% set formId = crudMainFormId|default('crud_main_form') %}
+
+ {% block crud_content_header %}
+ {{ ('crud.' ~ crud_name ~ '.title_new')|trans({'%crud_name%' : crud_name }) }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_form %}
+ {{ form_start(form, { 'attr' : { 'id': formId } }) }}
+ {{ form_row(form.label) }}
+ {{ form_row(form.genderTranslation) }}
+ {{ form_row(form.icon) }}
+ {{ form_row(form.active) }}
+ {{ form_row(form.order) }}
+ {{ form_end(form) }}
+
+ {% block crud_content_after_form %}{% endblock %}
+
+ {% block crud_content_form_actions %}
+
+ {% endblock %}
+
+ {{ form_end(form) }}
+ {% endblock %}
+
+{% endblock admin_content %}
diff --git a/src/Bundle/ChillMainBundle/Search/AbstractSearch.php b/src/Bundle/ChillMainBundle/Search/AbstractSearch.php
index c4e0fecd9..a7c81d5bf 100644
--- a/src/Bundle/ChillMainBundle/Search/AbstractSearch.php
+++ b/src/Bundle/ChillMainBundle/Search/AbstractSearch.php
@@ -62,12 +62,12 @@ abstract class AbstractSearch implements SearchInterface
$recomposed .= ' '.$term.':';
$containsSpace = str_contains((string) $terms[$term], ' ');
- if ($containsSpace) {
+ if ($containsSpace || is_numeric($terms[$term])) {
$recomposed .= '"';
}
$recomposed .= (false === mb_stristr(' ', (string) $terms[$term])) ? $terms[$term] : '('.$terms[$term].')';
- if ($containsSpace) {
+ if ($containsSpace || is_numeric($terms[$term])) {
$recomposed .= '"';
}
}
diff --git a/src/Bundle/ChillMainBundle/Templating/Entity/ChillGenderIconRender.php b/src/Bundle/ChillMainBundle/Templating/Entity/ChillGenderIconRender.php
new file mode 100644
index 000000000..383234bd3
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Templating/Entity/ChillGenderIconRender.php
@@ -0,0 +1,35 @@
+
+ */
+final readonly class ChillGenderIconRender implements ChillEntityRenderInterface
+{
+ public function renderBox($icon, array $options): string
+ {
+ return '';
+ }
+
+ public function renderString($icon, array $options): string
+ {
+ return $icon->value;
+ }
+
+ public function supports($icon, array $options): bool
+ {
+ return $icon instanceof GenderIconEnum;
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/config/services/templating.yaml b/src/Bundle/ChillMainBundle/config/services/templating.yaml
index 0baa91b69..dc21b07f5 100644
--- a/src/Bundle/ChillMainBundle/config/services/templating.yaml
+++ b/src/Bundle/ChillMainBundle/config/services/templating.yaml
@@ -49,6 +49,8 @@ services:
Chill\MainBundle\Templating\Entity\NewsItemRender: ~
+ Chill\MainBundle\Templating\Entity\ChillGenderIconRender: ~
+
Chill\MainBundle\Templating\Entity\UserRender: ~
Chill\MainBundle\Templating\Listing\:
diff --git a/src/Bundle/ChillMainBundle/migrations/Version20240926093955.php b/src/Bundle/ChillMainBundle/migrations/Version20240926093955.php
new file mode 100644
index 000000000..50da93e33
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/migrations/Version20240926093955.php
@@ -0,0 +1,69 @@
+addSql('CREATE SEQUENCE chill_main_gender_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE TABLE chill_main_gender (id INT NOT NULL, label JSON NOT NULL, active BOOLEAN NOT NULL, genderTranslation VARCHAR(255) NOT NULL, icon VARCHAR(255) NOT NULL, ordering DOUBLE PRECISION DEFAULT \'0.0\', PRIMARY KEY(id))');
+
+ // Insert the four gender records into the chill_main_gender table
+ $this->addSql("
+ INSERT INTO chill_main_gender (id, label, active, genderTranslation, icon, ordering)
+ VALUES
+ (nextval('chill_main_gender_id_seq'),
+ '{\"fr\": \"homme\", \"nl\": \"man\"}',
+ true,
+ 'man',
+ '',
+ 1.0
+ ),
+ (nextval('chill_main_gender_id_seq'),
+ '{\"fr\": \"femme\", \"nl\": \"vrouw\"}',
+ true,
+ 'woman',
+ '',
+ 1.1
+ ),
+ (nextval('chill_main_gender_id_seq'),
+ '{\"fr\": \"neutre\", \"nl\": \"neutraal\"}',
+ true,
+ 'neutral',
+ '',
+ 1.1
+ ),
+ (nextval('chill_main_gender_id_seq'),
+ '{\"fr\": \"inconnu\", \"nl\": \"ongekend\"}',
+ true,
+ 'unknown',
+ '',
+ 1.2
+ )
+ ");
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('DROP SEQUENCE chill_main_gender_id_seq CASCADE');
+ $this->addSql('DROP TABLE chill_main_gender');
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml
index 421cac473..3e6ea2011 100644
--- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml
@@ -43,6 +43,7 @@ lifecycleUpdate: Evenements de création et mise à jour
address_fields: Données liées à l'adresse
Datas: Données
No title: Aucun titre
+icon: icône
user:
profile:
@@ -447,6 +448,12 @@ crud:
title_delete: Supprimer une actualité
button_delete: Supprimer
confirm_message_delete: Êtes-vous sûr de vouloir supprimer l'actualité, "%as_string%" ?
+ main_gender:
+ index:
+ title: Liste des genres
+ add_new: Ajouter un genre
+ title_new: Nouveau genre
+ title_edit: Modifier un genre
No entities: Aucun élément
@@ -704,4 +711,8 @@ news:
read_more: Lire la suite
show_details: Voir l'actualité
+gender:
+ genderTranslation: traduction grammaticale
+ not defined: Non défini
+
diff --git a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php
index d356cf9ad..f1be52959 100644
--- a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php
+++ b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php
@@ -15,11 +15,14 @@ use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Country;
+use Chill\MainBundle\Entity\Gender;
+use Chill\MainBundle\Entity\GenderEnum;
use Chill\MainBundle\Entity\PostalCode;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Repository\CenterRepository;
use Chill\MainBundle\Repository\CountryRepository;
+use Chill\MainBundle\Repository\GenderRepository;
use Chill\MainBundle\Repository\ScopeRepository;
use Chill\MainBundle\Repository\UserRepository;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
@@ -77,12 +80,15 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
*/
protected array $cacheUsers = [];
+ /**
+ * @var array|Gender[]
+ */
+ protected array $cacheGenders = [];
+
protected Generator $faker;
protected NativeLoader $loader;
- private array $genders = [Person::MALE_GENDER, Person::FEMALE_GENDER, Person::BOTH_GENDER];
-
private array $peoples = [
[
'lastName' => 'Depardieu',
@@ -90,7 +96,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
'birthdate' => '1948-12-27',
'placeOfBirth' => 'Châteauroux',
'nationality' => 'RU',
- 'gender' => Person::MALE_GENDER,
+ 'gender' => GenderEnum::MALE,
'center' => 'Center A',
'accompanyingPeriods' => [
[
@@ -119,7 +125,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
'maritalStatus' => 'ms_divorce',
],
[
- // to have a person with same birthdate of Gérard Depardieu
+ // to have a person with same birthdate as Gérard Depardieu
'lastName' => 'Van Snick',
'firstName' => 'Bart',
'birthdate' => '1948-12-27',
@@ -131,7 +137,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
'lastName' => 'Depardieu',
'firstName' => 'Charline',
'birthdate' => '1970-10-15',
- 'gender' => Person::FEMALE_GENDER,
+ 'gender' => GenderEnum::FEMALE,
'center' => 'Center A',
'maritalStatus' => 'ms_legalco',
],
@@ -228,6 +234,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
protected MaritalStatusRepository $maritalStatusRepository,
protected ScopeRepository $scopeRepository,
protected UserRepository $userRepository,
+ protected GenderRepository $genderRepository,
) {
$this->faker = Factory::create('fr_FR');
$this->faker->addProvider($this);
@@ -272,9 +279,17 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
/**
* @internal This method is public and called by faker as a custom generator
*/
- public function getRandomGender(): string
+ public function getRandomGender(int $nullPercentage = 50): ?Gender
{
- return $this->genders[array_rand($this->genders)];
+ if (0 === \count($this->cacheGenders)) {
+ $this->cacheGenders = $this->genderRepository->findByActiveOrdered();
+ }
+
+ if (\random_int(0, 100) > $nullPercentage) {
+ return null;
+ }
+
+ return $this->cacheGenders[array_rand($this->cacheGenders)];
}
/**
diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php
index 0b4b54681..f26aa095e 100644
--- a/src/Bundle/ChillPersonBundle/Entity/Person.php
+++ b/src/Bundle/ChillPersonBundle/Entity/Person.php
@@ -21,6 +21,7 @@ use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Civility;
use Chill\MainBundle\Entity\Country;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
+use Chill\MainBundle\Entity\Gender;
use Chill\MainBundle\Entity\HasCenterInterface;
use Chill\MainBundle\Entity\Language;
use Chill\MainBundle\Entity\User;
@@ -59,19 +60,11 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
#[HouseholdMembershipSequential(groups: ['household_memberships'])]
class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateInterface, \Stringable
{
- final public const BOTH_GENDER = 'both';
-
// have days in commun
final public const ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD = 2; // where there exist
final public const ERROR_PERIODS_ARE_COLLAPSING = 1; // when two different periods
- final public const FEMALE_GENDER = 'woman';
-
- final public const MALE_GENDER = 'man';
-
- final public const NO_INFORMATION = 'unknown';
-
/**
* Accept receiving email.
*/
@@ -242,11 +235,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
private ?string $fullnameCanonical = '';
/**
- * The person's gender.
+ * NEW column : The person's gender.
*/
#[Assert\NotNull(message: 'The gender must be set')]
- #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 9, nullable: true)]
- private ?string $gender = null;
+ #[ORM\ManyToOne(targetEntity: Gender::class)]
+ private ?Gender $gender = null;
/**
* Comment on gender.
@@ -1003,7 +996,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
return $this->fullnameCanonical;
}
- public function getGender(): ?string
+ public function getGender(): ?Gender
{
return $this->gender;
}
@@ -1013,24 +1006,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
return $this->genderComment;
}
- /**
- * return gender as a Numeric form.
- * This is used for translations.
- *
- * @return int
- *
- * @deprecated Keep for legacy. Used in Chill 1.5 for feminize before icu translations
- */
- public function getGenderNumeric()
- {
- return match ($this->getGender()) {
- self::FEMALE_GENDER => 1,
- self::MALE_GENDER => 0,
- self::BOTH_GENDER => 2,
- default => -1,
- };
- }
-
public function getHouseholdAddresses(): Collection
{
return $this->householdAddresses;
@@ -1532,7 +1507,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
return $this;
}
- public function setGender(?string $gender): self
+ public function setGender(?Gender $gender): self
{
$this->gender = $gender;
diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php
index 0181c6e7b..f7ae26dca 100644
--- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php
+++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php
@@ -12,7 +12,8 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators;
use Chill\MainBundle\Export\AggregatorInterface;
-use Chill\PersonBundle\Entity\Person;
+use Chill\MainBundle\Repository\GenderRepository;
+use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Export\Declarations;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;
@@ -20,7 +21,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
final readonly class GenderAggregator implements AggregatorInterface
{
- public function __construct(private TranslatorInterface $translator) {}
+ public function __construct(private TranslatorInterface $translator, private TranslatableStringHelperInterface $translatableStringHelper, private GenderRepository $repository) {}
public function addRole(): ?string
{
@@ -29,7 +30,8 @@ final readonly class GenderAggregator implements AggregatorInterface
public function alterQuery(QueryBuilder $qb, $data)
{
- $qb->addSelect('person.gender as gender');
+ $qb->leftJoin('person.gender', 'g');
+ $qb->addSelect('g.id as gender');
$qb->addGroupBy('gender');
}
@@ -48,30 +50,20 @@ final readonly class GenderAggregator implements AggregatorInterface
public function getLabels($key, array $values, $data)
{
- return function ($value) {
- switch ($value) {
- case Person::FEMALE_GENDER:
- return $this->translator->trans('woman');
-
- case Person::MALE_GENDER:
- return $this->translator->trans('man');
-
- case Person::BOTH_GENDER:
- return $this->translator->trans('both');
-
- case Person::NO_INFORMATION:
- return $this->translator->trans('unknown');
-
- case null:
- case '':
- return $this->translator->trans('Not given');
-
- case '_header':
- return $this->translator->trans('Gender');
-
- default:
- throw new \LogicException(sprintf('The value %s is not valid', $value));
+ return function (int|string|null $value) {
+ if (null === $value || '' === $value) {
+ return '';
}
+
+ if ('_header' === $value) {
+ return $this->translator->trans('Gender');
+ }
+
+ if (null === $gender = $this->repository->find((int) $value)) {
+ return '';
+ }
+
+ return (string) $this->translatableStringHelper->localize($gender->getLabel());
};
}
diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php
index 5009e37d0..fc09e385a 100644
--- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php
+++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php
@@ -11,11 +11,13 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Export\Filter\PersonFilters;
+use Chill\MainBundle\Entity\Gender;
+use Chill\MainBundle\Export\DataTransformerInterface;
use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\FilterInterface;
-use Chill\PersonBundle\Entity\Person;
+use Chill\MainBundle\Repository\GenderRepository;
+use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Export\Declarations;
-use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
@@ -24,17 +26,15 @@ use Symfony\Contracts\Translation\TranslatorInterface;
class GenderFilter implements
ExportElementValidatedInterface,
- FilterInterface
+ FilterInterface,
+ DataTransformerInterface
{
- /**
- * @var TranslatorInterface
- */
- protected $translator;
-
- public function __construct(TranslatorInterface $translator)
- {
- $this->translator = $translator;
- }
+ // inject gender repository and find the active genders so that you can pass them to the ChoiceType (ordered by ordering)
+ public function __construct(
+ private readonly TranslatorInterface $translator,
+ private readonly TranslatableStringHelperInterface $translatableStringHelper,
+ private readonly GenderRepository $genderRepository,
+ ) {}
public function addRole(): ?string
{
@@ -46,23 +46,17 @@ class GenderFilter implements
$where = $qb->getDQLPart('where');
$isIn = $qb->expr()->in('person.gender', ':person_gender');
- if (!\in_array('null', $data['accepted_genders'], true)) {
+ $acceptedGenders = $data['accepted_genders_entity'];
+ $nullIncluded = in_array(null, $acceptedGenders ?? [], true);
+
+ if (!$nullIncluded) {
$clause = $isIn;
} else {
$clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender'));
}
- if ($where instanceof Expr\Andx) {
- $where->add($clause);
- } else {
- $where = $qb->expr()->andX($clause);
- }
-
- $qb->add('where', $where);
- $qb->setParameter('person_gender', \array_filter(
- $data['accepted_genders'],
- static fn ($el) => 'null' !== $el
- ));
+ $qb->andWhere($clause);
+ $qb->setParameter('person_gender', array_filter($acceptedGenders ?? [], fn ($gender) => null !== $gender));
}
public function applyOn()
@@ -72,19 +66,42 @@ class GenderFilter implements
public function buildForm(FormBuilderInterface $builder)
{
- $builder->add('accepted_genders', ChoiceType::class, [
- 'choices' => [
- 'Woman' => Person::FEMALE_GENDER,
- 'Man' => Person::MALE_GENDER,
- 'Both' => Person::BOTH_GENDER,
- 'Unknown' => Person::NO_INFORMATION,
- 'Not given' => 'null',
- ],
+ $genderChoices = $this->genderRepository->findByActiveOrdered();
+ $choices = ['None' => null];
+
+ foreach ($genderChoices as $gender) {
+ $choices[$this->translatableStringHelper->localize($gender->getLabel())] = $gender->getId();
+ }
+
+ $builder->add('accepted_genders_entity', ChoiceType::class, [
+ 'choices' => $choices,
'multiple' => true,
'expanded' => true,
+ 'placeholder' => 'Select gender',
]);
}
+ public function transformData(?array $before): array
+ {
+ $transformedData = [];
+ $transformedData['accepted_genders_entity'] = $before['accepted_genders_entity'] ?? [];
+
+ if (array_key_exists('accepted_genders', $before)) {
+ foreach ($before['accepted_genders'] as $genderBefore) {
+ foreach ($this->genderRepository->findByGenderTranslation(
+ match ($genderBefore) {
+ 'both' => 'neutral',
+ default => $genderBefore,
+ }
+ ) as $gender) {
+ $transformedData['accepted_genders_entity'][] = $gender;
+ }
+ }
+ }
+
+ return $transformedData;
+ }
+
public function getFormDefaultData(): array
{
return [];
@@ -94,11 +111,11 @@ class GenderFilter implements
{
$genders = [];
- foreach ($data['accepted_genders'] as $g) {
- if ('null' === $g) {
- $genders[] = $this->translator->trans('Not given');
+ foreach ($data['accepted_genders_entity'] as $g) {
+ if (null === $g) {
+ $genders[] = $this->translator->trans('export.filter.person.gender.no_gender');
} else {
- $genders[] = $this->translator->trans($g);
+ $genders[] = $this->translatableStringHelper->localize($this->genderRepository->find($g)->getLabel());
}
}
@@ -120,7 +137,7 @@ class GenderFilter implements
public function validateForm($data, ExecutionContextInterface $context)
{
- if (!\is_array($data['accepted_genders']) || 0 === \count($data['accepted_genders'])) {
+ if (!\is_iterable($data['accepted_genders_entity']) || 0 === \count($data['accepted_genders_entity'])) {
$context->buildViolation('You should select an option')
->addViolation();
}
diff --git a/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php b/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php
index 393d246ea..0c270a7ca 100644
--- a/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php
+++ b/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php
@@ -16,6 +16,7 @@ use Chill\MainBundle\Export\Helper\ExportAddressHelper;
use Chill\MainBundle\Repository\CenterRepositoryInterface;
use Chill\MainBundle\Repository\CivilityRepositoryInterface;
use Chill\MainBundle\Repository\CountryRepository;
+use Chill\MainBundle\Repository\GenderRepository;
use Chill\MainBundle\Repository\LanguageRepositoryInterface;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
@@ -80,6 +81,7 @@ final readonly class ListPersonHelper
private TranslatableStringHelper $translatableStringHelper,
private TranslatorInterface $translator,
private UserRepositoryInterface $userRepository,
+ private GenderRepository $genderRepository,
/**
* @var iterable
*/
@@ -173,6 +175,11 @@ final readonly class ListPersonHelper
break;
+ case 'gender':
+ $qb->addSelect('IDENTITY(person.gender) AS gender');
+
+ break;
+
case 'maritalStatus':
$qb->addSelect('IDENTITY(person.maritalStatus) AS maritalStatus');
@@ -325,7 +332,13 @@ final readonly class ListPersonHelper
return $this->translator->trans($key);
}
- return $this->translator->trans($value);
+ if (null === $value) {
+ return '';
+ }
+
+ $gender = $this->genderRepository->find($value);
+
+ return $this->translatableStringHelper->localize($gender->getLabel());
};
case 'maritalStatus':
diff --git a/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php b/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php
index 9bfb75e31..bb40c6c35 100644
--- a/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php
+++ b/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php
@@ -20,8 +20,8 @@ use Chill\MainBundle\Form\Type\PickCenterType;
use Chill\MainBundle\Form\Type\PickCivilityType;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Person;
-use Chill\PersonBundle\Form\Type\GenderType;
use Chill\PersonBundle\Form\Type\PersonAltNameType;
+use Chill\PersonBundle\Form\Type\PickGenderType;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use libphonenumber\PhoneNumberType;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
@@ -60,7 +60,7 @@ final class CreationPersonType extends AbstractType
'label' => 'Civility',
'placeholder' => 'choose civility',
])
- ->add('gender', GenderType::class, [
+ ->add('gender', PickGenderType::class, [
'required' => true, 'placeholder' => null,
])
->add('birthdate', ChillDateType::class, [
diff --git a/src/Bundle/ChillPersonBundle/Form/PersonType.php b/src/Bundle/ChillPersonBundle/Form/PersonType.php
index 21717a25b..0f4fbd8e4 100644
--- a/src/Bundle/ChillPersonBundle/Form/PersonType.php
+++ b/src/Bundle/ChillPersonBundle/Form/PersonType.php
@@ -24,9 +24,9 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\PersonPhone;
-use Chill\PersonBundle\Form\Type\GenderType;
use Chill\PersonBundle\Form\Type\PersonAltNameType;
use Chill\PersonBundle\Form\Type\PersonPhoneType;
+use Chill\PersonBundle\Form\Type\PickGenderType;
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
@@ -80,7 +80,7 @@ class PersonType extends AbstractType
'input' => 'datetime_immutable',
'widget' => 'single_text',
])
- ->add('gender', GenderType::class, [
+ ->add('gender', PickGenderType::class, [
'required' => true,
])
->add('genderComment', CommentType::class, [
diff --git a/src/Bundle/ChillPersonBundle/Form/Type/GenderType.php b/src/Bundle/ChillPersonBundle/Form/Type/GenderType.php
deleted file mode 100644
index 2989b3ec4..000000000
--- a/src/Bundle/ChillPersonBundle/Form/Type/GenderType.php
+++ /dev/null
@@ -1,44 +0,0 @@
- Person::MALE_GENDER,
- Person::FEMALE_GENDER => Person::FEMALE_GENDER,
- Person::BOTH_GENDER => Person::BOTH_GENDER,
- ];
-
- $resolver->setDefaults([
- 'choices' => $a,
- 'expanded' => true,
- 'multiple' => false,
- 'placeholder' => null,
- ]);
- }
-
- public function getParent()
- {
- return ChoiceType::class;
- }
-}
diff --git a/src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php b/src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php
new file mode 100644
index 000000000..1e0c004d5
--- /dev/null
+++ b/src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php
@@ -0,0 +1,51 @@
+setDefault('label', 'Gender')
+ ->setDefault(
+ 'choice_label',
+ fn (Gender $gender): string => $this->translatableStringHelper->localize($gender->getLabel())
+ )
+ ->setDefault(
+ 'query_builder',
+ static fn (EntityRepository $er): QueryBuilder => $er->createQueryBuilder('g')
+ ->where('g.active = true')
+ ->orderBy('g.order'),
+ )
+ ->setDefault('placeholder', 'choose gender')
+ ->setDefault('class', Gender::class);
+ }
+
+ public function getParent()
+ {
+ return EntityType::class;
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/Menu/AdminPersonMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/AdminPersonMenuBuilder.php
index ee2dad9dc..c3d369f00 100644
--- a/src/Bundle/ChillPersonBundle/Menu/AdminPersonMenuBuilder.php
+++ b/src/Bundle/ChillPersonBundle/Menu/AdminPersonMenuBuilder.php
@@ -45,13 +45,17 @@ class AdminPersonMenuBuilder implements LocalMenuBuilderInterface
'route' => 'chill_crud_main_civility_index',
])->setExtras(['order' => 2010]);
+ $menu->addChild('Gender', [
+ 'route' => 'chill_crud_main_gender_index',
+ ])->setExtras(['order' => 2020]);
+
$menu->addChild('Marital status', [
'route' => 'chill_crud_person_marital-status_index',
- ])->setExtras(['order' => 2020]);
+ ])->setExtras(['order' => 2030]);
$menu->addChild('person_admin.person_resource_kind', [
'route' => 'chill_crud_person_resource-kind_index',
- ])->setExtras(['order' => 2030]);
+ ])->setExtras(['order' => 2040]);
}
public static function getMenuIds(): array
diff --git a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php
index 9e76dd374..686022ca3 100644
--- a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php
+++ b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php
@@ -34,7 +34,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
?\DateTimeInterface $birthdate = null,
?\DateTimeInterface $birthdateBefore = null,
?\DateTimeInterface $birthdateAfter = null,
- ?string $gender = null,
+ ?int $gender = null,
?string $countryCode = null,
?string $phonenumber = null,
?string $city = null,
@@ -62,7 +62,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
?\DateTimeInterface $birthdate = null,
?\DateTimeInterface $birthdateBefore = null,
?\DateTimeInterface $birthdateAfter = null,
- ?string $gender = null,
+ ?int $gender = null,
?string $countryCode = null,
?string $phonenumber = null,
?string $city = null,
@@ -96,7 +96,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
?\DateTimeInterface $birthdate = null,
?\DateTimeInterface $birthdateBefore = null,
?\DateTimeInterface $birthdateAfter = null,
- ?string $gender = null,
+ ?int $gender = null,
?string $countryCode = null,
?string $phonenumber = null,
?string $city = null,
@@ -202,7 +202,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
}
if (null !== $gender) {
- $query->andWhereClause('person.gender = ?', [$gender]);
+ $query->andWhereClause('person.gender_id = ?', [$gender]);
}
return $query;
@@ -253,7 +253,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
?\DateTimeInterface $birthdate = null,
?\DateTimeInterface $birthdateBefore = null,
?\DateTimeInterface $birthdateAfter = null,
- ?string $gender = null,
+ ?int $gender = null,
?string $countryCode = null,
?string $phonenumber = null,
?string $city = null,
diff --git a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepositoryInterface.php
index 7a45d6648..50fdcd4b3 100644
--- a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepositoryInterface.php
+++ b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepositoryInterface.php
@@ -23,7 +23,7 @@ interface PersonACLAwareRepositoryInterface
?\DateTimeInterface $birthdate = null,
?\DateTimeInterface $birthdateBefore = null,
?\DateTimeInterface $birthdateAfter = null,
- ?string $gender = null,
+ ?int $gender = null,
?string $countryCode = null,
?string $phonenumber = null,
?string $city = null,
@@ -36,7 +36,7 @@ interface PersonACLAwareRepositoryInterface
?\DateTimeInterface $birthdate = null,
?\DateTimeInterface $birthdateBefore = null,
?\DateTimeInterface $birthdateAfter = null,
- ?string $gender = null,
+ ?int $gender = null,
?string $countryCode = null,
?string $phonenumber = null,
?string $city = null,
@@ -55,7 +55,7 @@ interface PersonACLAwareRepositoryInterface
?\DateTimeInterface $birthdate = null,
?\DateTimeInterface $birthdateBefore = null,
?\DateTimeInterface $birthdateAfter = null,
- ?string $gender = null,
+ ?int $gender = null,
?string $countryCode = null,
?string $phonenumber = null,
?string $city = null,
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue
index 155fd6c46..a278d00c4 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue
@@ -128,7 +128,7 @@ export default {
body.mobilenumber = payload.data.mobilenumber;
body.email = payload.data.email;
body.altNames = payload.data.altNames;
- body.gender = payload.data.gender;
+ body.gender = {id: payload.data.gender.id, type: payload.data.gender.type };
if (payload.data.civility !== null) { body.civility = {id: payload.data.civility.id, type: payload.data.civility.type }; }
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/ResourceItem.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/ResourceItem.vue
index c2368d9ab..920287b86 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/ResourceItem.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/ResourceItem.vue
@@ -153,7 +153,7 @@ export default {
body.mobilenumber = payload.data.mobilenumber;
body.email = payload.data.email;
body.altNames = payload.data.altNames;
- body.gender = payload.data.gender;
+ body.gender = {id: payload.data.gender.id, type: payload.data.gender.type };
if (payload.data.civility !== null) { body.civility = {id: payload.data.civility.id, type: payload.data.civility.type}; }
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue
index 2258d8b77..fd2ef7bdb 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue
@@ -8,7 +8,7 @@
{{ $t('household_members_editor.holder') }}
- {{ $t('person.born', {'gender': conc.person.gender} ) }}
+ {{ $t('person.born', {'gender': conc.person.gender.genderTranslation} ) }}
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/i18n.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/i18n.js
index 474788f47..6c631a0ea 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/i18n.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/i18n.js
@@ -12,10 +12,6 @@ const visMessages = {
Holder: 'Titulaire',
Legend: 'Calques',
concerned: 'concerné',
- // both: 'neutre, non binaire',
- woman: 'féminin',
- man: 'masculin',
- undefined: "genre non précisé",
years: 'ans',
click_to_expand: 'cliquez pour étendre',
add_relationship_link: "Créer un lien de filiation",
@@ -64,7 +60,7 @@ const visMessages = {
placeholder: "Choisissez le genre de l'usager",
woman: "Féminin",
man: "Masculin",
- both: "Neutre, non binaire",
+ neutral: "Neutre, non binaire",
undefined: "Non renseigné",
unknown: "Non renseigné"
}
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/store.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/store.js
index 8382d460d..683dd840a 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/store.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/store.js
@@ -1,6 +1,6 @@
import { createStore } from 'vuex'
import { getHouseholdByPerson, getCoursesByPerson, getRelationshipsByPerson } from './api'
-import { getHouseholdLabel, getHouseholdWidth, getRelationshipLabel, getRelationshipTitle, getRelationshipDirection, splitId, getGender, getAge } from './vis-network'
+import { getHouseholdLabel, getHouseholdWidth, getRelationshipLabel, getRelationshipTitle, getRelationshipDirection, splitId, getAge } from './vis-network'
import {visMessages} from "./i18n";
import { darkBlue, darkBrown, darkGreen, lightBlue, lightBrown, lightGreen } from './colors';
@@ -148,7 +148,7 @@ const store = createStore({
person.group = person.type
person._id = person.id
person.id = `person_${person.id}`
- person.label = `*${person.text}${person.deathdate ? ' (‡)' : ''}*\n_${getGender(person.gender)}${age}_${debug}`
+ person.label = `*${person.text}${person.deathdate ? ' (‡)' : ''}*\n_${person.gender.label.fr}${age}_${debug}`
person.folded = false
// folded is used for missing persons
if (options.folded) {
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/vis-network.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/vis-network.js
index cb37c3661..4c279bcfa 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/vis-network.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/vis-network.js
@@ -141,25 +141,6 @@ window.options = {
}
}
-/**
- * @param gender
- * @returns {string}
- */
-const getGender = (gender) => {
- switch (gender) {
- case 'both':
- return visMessages.fr.visgraph.both
- case 'woman':
- return visMessages.fr.visgraph.woman
- case 'man':
- return visMessages.fr.visgraph.man
- case 'unknown':
- return visMessages.fr.visgraph.unknown
- default:
- return visMessages.fr.visgraph.undefined
- }
-}
-
/**
* TODO only one abstract function (-> getAge() is repeated in PersonRenderBox.vue)
* @param person
@@ -251,7 +232,6 @@ const splitId = (id, position) => {
}
export {
- getGender,
getAge,
getHouseholdLabel,
getHouseholdWidth,
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_api/OnTheFly.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_api/OnTheFly.js
index c9c77991f..bc8ce60e2 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_api/OnTheFly.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_api/OnTheFly.js
@@ -24,6 +24,13 @@ const getCivilities = () =>
throw Error('Error with request resource response');
});
+const getGenders = () => makeFetch("GET", '/api/1.0/main/gender.json')
+ // .then(response => {
+ // console.log(response)
+ // if (response.ok) { return response.json(); }
+ // throw Error('Error with request resource response');
+ // });
+
const getCentersForPersonCreation = () => makeFetch('GET', '/api/1.0/person/creation/authorized-centers', null);
/*
@@ -63,10 +70,11 @@ const patchPerson = (id, body) => {
};
export {
- getCentersForPersonCreation,
+ getCentersForPersonCreation,
getPerson,
getPersonAltNames,
getCivilities,
+ getGenders,
postPerson,
patchPerson
};
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue
index 100dc9caf..26f13d65f 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue
@@ -37,10 +37,9 @@
-
-
+