mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-07-01 14:36:13 +00:00
add model + form to handle alt names
This commit is contained in:
parent
7b7ce4a604
commit
426458811c
70
Config/ConfigPersonAltNamesHelper.php
Normal file
70
Config/ConfigPersonAltNamesHelper.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Config;
|
||||
|
||||
|
||||
/**
|
||||
* Give help to interact with the config for alt names
|
||||
*
|
||||
*
|
||||
*/
|
||||
class ConfigPersonAltNamesHelper
|
||||
{
|
||||
/**
|
||||
* the raw config, directly from the container parameter
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $config = [];
|
||||
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if at least one alt name is configured
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAltNames(): bool
|
||||
{
|
||||
return count($this->config) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the choices as key => values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChoices(): array
|
||||
{
|
||||
$choices = [];
|
||||
foreach ($this->config as $entry) {
|
||||
|
||||
$labels = $entry['labels'];
|
||||
$lang = false;
|
||||
$label = false;
|
||||
$cur = reset($labels);
|
||||
while ($cur) {
|
||||
if (key($labels) === 'lang') {
|
||||
$lang = current($labels);
|
||||
}
|
||||
|
||||
if (key($labels) === 'label') {
|
||||
$label = current($labels);
|
||||
}
|
||||
|
||||
if ($lang !== FALSE && $label !== FALSE) {
|
||||
$choices[$entry['key']][$lang] = $label;
|
||||
$lang = false;
|
||||
$label = false;
|
||||
}
|
||||
$cur = next($labels);
|
||||
}
|
||||
}
|
||||
|
||||
return $choices;
|
||||
}
|
||||
|
||||
}
|
@ -65,6 +65,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
$loader->load('services/form.yml');
|
||||
$loader->load('services/repository.yml');
|
||||
$loader->load('services/templating.yml');
|
||||
$loader->load('services/alt_names.yml');
|
||||
|
||||
// load service advanced search only if configure
|
||||
if ($config['search']['search_by_phone'] != 'never') {
|
||||
|
@ -78,6 +78,26 @@ class Configuration implements ConfigurationInterface
|
||||
->append($this->addFieldNode('address'))
|
||||
->append($this->addFieldNode('accompanying_period'))
|
||||
->append($this->addFieldNode('memo'))
|
||||
->arrayNode('alt_names')
|
||||
->defaultValue([])
|
||||
->arrayPrototype()
|
||||
->children()
|
||||
->scalarNode('key')
|
||||
->isRequired()->cannotBeEmpty()
|
||||
->end()
|
||||
->arrayNode('labels')->isRequired()->cannotBeEmpty()
|
||||
->children()
|
||||
->scalarNode('lang')->isRequired()->cannotBeEmpty()
|
||||
->example('fr')
|
||||
->end()
|
||||
->scalarNode('label')->isRequired()->cannotBeEmpty()
|
||||
->example('Nom de jeune fille')
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end() //children for 'person_fields', parent = array 'person_fields'
|
||||
->end() // person_fields, parent = children of root
|
||||
->arrayNode('accompanying_periods_fields')
|
||||
|
@ -43,6 +43,12 @@ class Person implements HasCenterInterface {
|
||||
/** @var string The person's last name */
|
||||
private $lastName;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \Doctrine\Common\Collections\Collection
|
||||
*/
|
||||
private $altNames;
|
||||
|
||||
/** @var \DateTime The person's birthdate */
|
||||
private $birthdate; //to change in birthdate
|
||||
|
||||
@ -123,6 +129,7 @@ class Person implements HasCenterInterface {
|
||||
$this->accompanyingPeriods = new ArrayCollection();
|
||||
$this->spokenLanguages = new ArrayCollection();
|
||||
$this->addresses = new ArrayCollection();
|
||||
$this->altNames = new ArrayCollection();
|
||||
|
||||
if ($opening === null) {
|
||||
$opening = new \DateTime();
|
||||
@ -325,6 +332,38 @@ class Person implements HasCenterInterface {
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
public function getAltNames(): \Doctrine\Common\Collections\Collection
|
||||
{
|
||||
return $this->altNames;
|
||||
}
|
||||
|
||||
public function setAltNames(\Doctrine\Common\Collections\Collection $altNames)
|
||||
{
|
||||
$this->altNames = $altNames;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addAltName(PersonAltName $altName)
|
||||
{
|
||||
if (FALSE === $this->altNames->contains($altName)) {
|
||||
$this->altNames->add($altName);
|
||||
$altName->setPerson($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeAltName(PersonAltName $altName)
|
||||
{
|
||||
if ($this->altNames->contains($altName)) {
|
||||
$altName->setPerson(null);
|
||||
$this->altNames->removeElement($altName);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set birthdate
|
||||
*
|
||||
|
118
Entity/PersonAltName.php
Normal file
118
Entity/PersonAltName.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* PersonAltName
|
||||
*
|
||||
* @ORM\Table(name="person_alt_name")
|
||||
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonAltNameRepository")
|
||||
*/
|
||||
class PersonAltName
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="key", type="string", length=255)
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="label", type="text")
|
||||
*/
|
||||
private $label;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Person
|
||||
* @ORM\OneToMany(
|
||||
* targetEntity="Chill\PersonBundle\Entity\Person",
|
||||
* mappedBy="altNames"
|
||||
* )
|
||||
*/
|
||||
private $person;
|
||||
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set key.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return PersonAltName
|
||||
*/
|
||||
public function setKey($key)
|
||||
{
|
||||
$this->key = $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set label.
|
||||
*
|
||||
* @param string $label
|
||||
*
|
||||
* @return PersonAltName
|
||||
*/
|
||||
public function setLabel($label)
|
||||
{
|
||||
$this->label = $label;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get label.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel()
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function getPerson(): Person
|
||||
{
|
||||
return $this->person;
|
||||
}
|
||||
|
||||
public function setPerson(?Person $person = null)
|
||||
{
|
||||
$this->person = $person;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
73
Form/DataMapper/PersonAltNameDataMapper.php
Normal file
73
Form/DataMapper/PersonAltNameDataMapper.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Form\DataMapper;
|
||||
|
||||
use Symfony\Component\Form\DataMapperInterface;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||
use Chill\PersonBundle\Entity\PersonAltName;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
class PersonAltNameDataMapper implements DataMapperInterface
|
||||
{
|
||||
public function mapDataToForms($viewData, $forms)
|
||||
{
|
||||
if (null === $viewData) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$viewData instanceof Collection) {
|
||||
throw new UnexpectedTypeException($viewData, Collection::class);
|
||||
}
|
||||
|
||||
$mapIndexToKey = [];
|
||||
foreach ($viewData->getIterator() as $key => $altName) {
|
||||
/** @var PersonAltName $altName */
|
||||
$mapIndexToKey[$altName->getKey()] = $key;
|
||||
}
|
||||
|
||||
foreach ($forms as $key => $form) {
|
||||
if (\array_key_exists($key, $mapIndexToKey)) {
|
||||
$form->setData($viewData->get($mapIndexToKey[$key])->getLabel());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param FormInterface[] $forms
|
||||
* @param Collection $viewData
|
||||
*/
|
||||
public function mapFormsToData($forms, &$viewData)
|
||||
{
|
||||
$mapIndexToKey = [];
|
||||
foreach ($viewData->getIterator() as $key => $altName) {
|
||||
/** @var PersonAltName $altName */
|
||||
$mapIndexToKey[$altName->getKey()] = $key;
|
||||
}
|
||||
|
||||
foreach ($forms as $key => $form) {
|
||||
$isEmpty = empty($form->getData());
|
||||
|
||||
if (\array_key_exists($key, $mapIndexToKey)) {
|
||||
if ($isEmpty) {
|
||||
$viewData->remove($mapIndexToKey[$key]);
|
||||
} else {
|
||||
$viewData->get($mapIndexToKey[$key])->setLabel($form->getData());
|
||||
}
|
||||
} else {
|
||||
if (!$isEmpty) {
|
||||
$altName = (new PersonAltName())
|
||||
->setKey($key)
|
||||
->setLabel($form->getData())
|
||||
;
|
||||
$viewData->add($altName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -34,6 +34,8 @@ use Chill\MainBundle\Form\Type\Select2CountryType;
|
||||
use Chill\MainBundle\Form\Type\Select2LanguageType;
|
||||
use Chill\CustomFieldsBundle\Form\Type\CustomFieldType;
|
||||
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
|
||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
||||
|
||||
class PersonType extends AbstractType
|
||||
{
|
||||
@ -47,13 +49,22 @@ class PersonType extends AbstractType
|
||||
*/
|
||||
protected $config = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var ConfigPersonAltNamesHelper
|
||||
*/
|
||||
protected $configAltNamesHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string[] $personFieldsConfiguration configuration of visibility of some fields
|
||||
*/
|
||||
public function __construct(array $personFieldsConfiguration)
|
||||
{
|
||||
public function __construct(
|
||||
array $personFieldsConfiguration,
|
||||
ConfigPersonAltNamesHelper $configAltNamesHelper
|
||||
) {
|
||||
$this->config = $personFieldsConfiguration;
|
||||
$this->configAltNamesHelper = $configAltNamesHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,6 +81,12 @@ class PersonType extends AbstractType
|
||||
'required' => true
|
||||
));
|
||||
|
||||
if ($this->configAltNamesHelper->hasAltNames()) {
|
||||
$builder->add('altNames', PersonAltNameType::class, [
|
||||
'by_reference' => false
|
||||
]);
|
||||
}
|
||||
|
||||
if ($this->config['memo'] === 'visible') {
|
||||
$builder
|
||||
->add('memo', TextareaType::class, array('required' => false))
|
||||
|
70
Form/Type/PersonAltNameType.php
Normal file
70
Form/Type/PersonAltNameType.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
class PersonAltNameType extends AbstractType
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var ConfigPersonAltNamesHelper
|
||||
*/
|
||||
private $configHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var TranslatableStringHelper
|
||||
*/
|
||||
private $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
ConfigPersonAltNamesHelper $configHelper,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->configHelper = $configHelper;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
foreach ($this->getKeyChoices() as $label => $key) {
|
||||
$builder->add($key, TextType::class, [
|
||||
'label' => $label,
|
||||
'required' => false
|
||||
]);
|
||||
}
|
||||
|
||||
$builder->setDataMapper(new \Chill\PersonBundle\Form\DataMapper\PersonAltNameDataMapper());
|
||||
}
|
||||
|
||||
protected function getKeyChoices()
|
||||
{
|
||||
$choices = $this->configHelper->getChoices();
|
||||
$translatedChoices = [];
|
||||
|
||||
foreach ($choices as $key => $labels) {
|
||||
$label = $this->translatableStringHelper->localize($labels);
|
||||
$translatedChoices[$label] = $key;
|
||||
}
|
||||
|
||||
return $translatedChoices;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver
|
||||
->setDefault('class', \Chill\PersonBundle\Entity\PersonAltName::class)
|
||||
;
|
||||
}
|
||||
|
||||
}
|
@ -74,6 +74,11 @@ Chill\PersonBundle\Entity\Person:
|
||||
targetEntity: AccompanyingPeriod
|
||||
mappedBy: person
|
||||
cascade: [persist, remove, merge, detach]
|
||||
altNames:
|
||||
targetEntity: PersonAltName
|
||||
mappedBy: person
|
||||
cascade: [persist, remove, merge, detach]
|
||||
orphanRemoval: true
|
||||
manyToMany:
|
||||
spokenLanguages:
|
||||
targetEntity: Chill\MainBundle\Entity\Language
|
||||
|
21
Resources/config/doctrine/PersonAltName.orm.yml
Normal file
21
Resources/config/doctrine/PersonAltName.orm.yml
Normal file
@ -0,0 +1,21 @@
|
||||
Chill\PersonBundle\Entity\PersonAltName:
|
||||
type: entity
|
||||
table: chill_person_alt_name
|
||||
repositoryClass: Chill\PersonBundle\Repository\PersonAltNameRepository
|
||||
id:
|
||||
id:
|
||||
type: integer
|
||||
id: true
|
||||
generator:
|
||||
strategy: AUTO
|
||||
fields:
|
||||
key:
|
||||
type: string
|
||||
length: 255
|
||||
label:
|
||||
type: text
|
||||
|
||||
manyToOne:
|
||||
person:
|
||||
targetEntity: Person
|
||||
inversedBy: altNames
|
4
Resources/config/services/alt_names.yml
Normal file
4
Resources/config/services/alt_names.yml
Normal file
@ -0,0 +1,4 @@
|
||||
services:
|
||||
Chill\PersonBundle\Config\ConfigPersonAltNamesHelper:
|
||||
arguments:
|
||||
$config: '%chill_person.person_fields.alt_names%'
|
@ -3,6 +3,7 @@ services:
|
||||
class: Chill\PersonBundle\Form\PersonType
|
||||
arguments:
|
||||
- "%chill_person.person_fields%"
|
||||
- '@Chill\PersonBundle\Config\ConfigPersonAltNamesHelper'
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
||||
@ -29,3 +30,10 @@ services:
|
||||
- '@Symfony\Component\Translation\TranslatorInterface'
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
||||
Chill\PersonBundle\Form\Type\PersonAltNameType:
|
||||
arguments:
|
||||
$configHelper: '@Chill\PersonBundle\Config\ConfigPersonAltNamesHelper'
|
||||
$translatableStringHelper: '@chill.main.helper.translatable_string'
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
31
Resources/migrations/Version20200128084445.php
Normal file
31
Resources/migrations/Version20200128084445.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Application\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Add person alt name table
|
||||
*/
|
||||
final class Version20200128084445 extends AbstractMigration
|
||||
{
|
||||
public function up(Schema $schema) : void
|
||||
{
|
||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
||||
|
||||
$this->addSql("CREATE SEQUENCE chill_person_alt_name_id_seq INCREMENT BY 1 MINVALUE 1 START 1");
|
||||
$this->addSql("CREATE TABLE chill_person_alt_name (id INT NOT NULL, person_id INT DEFAULT NULL, key VARCHAR(255) NOT NULL, label TEXT NOT NULL, PRIMARY KEY(id))");
|
||||
$this->addSql("CREATE INDEX IDX_2628668E217BBB47 ON chill_person_alt_name (person_id)");
|
||||
$this->addSql("ALTER TABLE chill_person_alt_name ADD CONSTRAINT FK_2628668E217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE");
|
||||
}
|
||||
|
||||
public function down(Schema $schema) : void
|
||||
{
|
||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
||||
|
||||
$this->addSql("DROP INDEX IDX_2628668E217BBB47");
|
||||
$this->addSql("DROP TABLE chill_person_alt_name");
|
||||
$this->addSql("DROP SEQUENCE chill_person_alt_name_id_seq");
|
||||
}
|
||||
}
|
@ -39,6 +39,9 @@
|
||||
<legend><h2>{{ 'General information'|trans }}</h2></legend>
|
||||
{{ form_row(form.firstName, {'label' : 'First name'}) }}
|
||||
{{ form_row(form.lastName, {'label' : 'Last name'}) }}
|
||||
{% if form.altNames is defined %}
|
||||
{{ form_widget(form.altNames, { 'label': 'Alternative names'}) }}
|
||||
{% endif %}
|
||||
{{ form_row(form.gender, {'label' : 'Gender'}) }}
|
||||
</fieldset>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user