diff --git a/Controller/PersonController.php b/Controller/PersonController.php
index 60e9f7eb7..655bbad1b 100644
--- a/Controller/PersonController.php
+++ b/Controller/PersonController.php
@@ -75,7 +75,7 @@ class PersonController extends Controller
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
'You are not allowed to edit this person');
- $form = $this->createForm(new PersonType(), $person,
+ $form = $this->createForm(PersonType::class, $person,
array(
"action" => $this->generateUrl('chill_person_general_update',
array("person_id" => $person_id)),
@@ -98,7 +98,7 @@ class PersonController extends Controller
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
'You are not allowed to edit this person');
- $form = $this->createForm(new PersonType(), $person,
+ $form = $this->createForm(PersonType::class, $person,
array("cFGroup" => $this->getCFGroup()));
if ($request->getMethod() === 'POST') {
diff --git a/DependencyInjection/ChillPersonExtension.php b/DependencyInjection/ChillPersonExtension.php
index 589e2c14e..536f414f2 100644
--- a/DependencyInjection/ChillPersonExtension.php
+++ b/DependencyInjection/ChillPersonExtension.php
@@ -31,10 +31,25 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
// set configuration for validation
$container->setParameter('chill_person.validation.birtdate_not_before',
$config['validation']['birthdate_not_after']);
+
+ $this->handlePersonFieldsParameters($container, $config['person_fields']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
+
+ private function handlePersonFieldsParameters(ContainerBuilder $container, $config)
+ {
+ if (array_key_exists('enabled', $config)) {
+ unset($config['enabled']);
+ }
+
+ $container->setParameter('chill_person.person_fields', $config);
+
+ foreach ($config as $key => $value) {
+ $container->setParameter('chill_person.person_fields.'.$key, $value);
+ }
+ }
private function declarePersonAsCustomizable (ContainerBuilder $container)
{
@@ -66,6 +81,18 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$asseticConfig['bundles'][] = 'ChillPersonBundle';
$container->prependExtensionConfig('assetic',
array('bundles' => array('ChillPersonBundle')));
+
+ //add person_fields parameter as global
+ $chillPersonConfig = $container->getExtensionConfig($this->getAlias());
+ $config = $this->processConfiguration(new Configuration(), $chillPersonConfig);
+ $twigConfig = array(
+ 'globals' => array(
+ 'chill_person' => array(
+ 'fields' => $config['person_fields']
+ )
+ )
+ );
+ $container->prependExtensionConfig('twig', $twigConfig);
$this-> declarePersonAsCustomizable($container);
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 833b5498d..5299a22fd 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -27,40 +27,70 @@ class Configuration implements ConfigurationInterface
$rootNode
->canBeDisabled()
->children()
- ->arrayNode('search')
- ->canBeDisabled()
+ ->arrayNode('search')
+ ->canBeDisabled()
->children()
- ->booleanNode('use_double_metaphone')
- ->defaultFalse()
- ->end()
- ->booleanNode('use_trigrams')
- ->defaultFalse()
- ->end()
- ->end()
- ->end()
- ->arrayNode('validation')
- ->canBeDisabled()
- ->children()
- ->scalarNode('birthdate_not_after')
- ->info($this->validationBirthdateNotAfterInfos)
- ->defaultValue('P1D')
- ->validate()
- ->ifTrue(function($period) {
- try {
- $interval = new \DateInterval($period);
- } catch (\Exception $ex) {
- return true;
- }
- return false;
- })
- ->thenInvalid('Invalid period for birthdate validation : "%s" '
- . 'The parameter should match duration as defined by ISO8601 : '
- . 'https://en.wikipedia.org/wiki/ISO_8601#Durations')
- ->end()
- ->end()
- ->end();
+ ->booleanNode('use_double_metaphone')
+ ->defaultFalse()
+ ->end() // use_double_metaphone, parent = children for 'search'
+ ->booleanNode('use_trigrams')
+ ->defaultFalse()
+ ->end() // use_trigrams, parent = children of 'search'
+ ->end() //children for 'search', parent = array node 'search'
+ ->end() // array 'search', parent = children of root
+ ->arrayNode('validation')
+ ->canBeDisabled()
+ ->children()
+ ->scalarNode('birthdate_not_after')
+ ->info($this->validationBirthdateNotAfterInfos)
+ ->defaultValue('P1D')
+ ->validate()
+ ->ifTrue(function($period) {
+ try {
+ $interval = new \DateInterval($period);
+ } catch (\Exception $ex) {
+ return true;
+ }
+ return false;
+ })
+ ->thenInvalid('Invalid period for birthdate validation : "%s" '
+ . 'The parameter should match duration as defined by ISO8601 : '
+ . 'https://en.wikipedia.org/wiki/ISO_8601#Durations')
+ ->end() // birthdate_not_after, parent = children of validation
+
+ ->end() // children for 'validation', parent = validation
+ ->end() //validation, parent = children of root
+ ->end() // children of root, parent = root
+ ->arrayNode('person_fields')
+ ->canBeDisabled()
+ ->children()
+ ->append($this->addFieldNode('place_of_birth'))
+ ->append($this->addFieldNode('email'))
+ ->append($this->addFieldNode('phonenumber'))
+ ->append($this->addFieldNode('nationality'))
+ ->append($this->addFieldNode('country_of_birth'))
+ ->append($this->addFieldNode('marital_status'))
+ ->append($this->addFieldNode('spoken_languages'))
+ ->end() //children for 'person_fields', parent = array 'person_fields'
+ ->end() // person_fields, parent = children of root
+ ->end() // children of 'root', parent = root
+ ;
return $treeBuilder;
}
+
+ private function addFieldNode($key)
+ {
+ $tree = new TreeBuilder();
+ $node = $tree->root($key, 'enum');
+
+ $node
+ ->values(array('hidden', 'visible'))
+ ->defaultValue('visible')
+ ->info("If the field $key must be shown")
+ ->end();
+ //var_dump($node);
+ return $node;
+ }
}
diff --git a/Form/PersonType.php b/Form/PersonType.php
index 16f50cf6f..aa76a3ba7 100644
--- a/Form/PersonType.php
+++ b/Form/PersonType.php
@@ -28,6 +28,25 @@ use Chill\PersonBundle\Form\Type\GenderType;
class PersonType extends AbstractType
{
+ /**
+ * array of configuration for person_fields.
+ *
+ * Contains whether we should add fields some optional fields (optional per
+ * instance)
+ *
+ * @var string[]
+ */
+ protected $config = array();
+
+ /**
+ *
+ * @param string[] $personFieldsConfiguration configuration of visibility of some fields
+ */
+ public function __construct(array $personFieldsConfiguration)
+ {
+ $this->config = $personFieldsConfiguration;
+ }
+
/**
* @param FormBuilderInterface $builder
* @param array $options
@@ -38,27 +57,48 @@ class PersonType extends AbstractType
->add('firstName')
->add('lastName')
->add('birthdate', 'date', array('required' => false, 'widget' => 'single_text', 'format' => 'dd-MM-yyyy'))
- ->add('placeOfBirth', 'text', array('required' => false))
->add('gender', new GenderType(), array(
'required' => true
))
->add('memo', 'textarea', array('required' => false))
- ->add('phonenumber', 'textarea', array('required' => false))
- ->add('email', 'textarea', array('required' => false))
- ->add('countryOfBirth', 'select2_chill_country', array(
+ ;
+
+ if ($this->config['place_of_birth'] === 'visible') {
+ $builder->add('placeOfBirth', 'text', array('required' => false));
+ }
+
+ if ($this->config['phonenumber'] === 'visible') {
+ $builder->add('phonenumber', 'textarea', array('required' => false));
+ }
+
+ if ($this->config['email'] === 'visible') {
+ $builder->add('email', 'textarea', array('required' => false));
+ }
+
+ if ($this->config['country_of_birth'] === 'visible') {
+ $builder->add('countryOfBirth', 'select2_chill_country', array(
'required' => false
- ))
- ->add('nationality', 'select2_chill_country', array(
+ ));
+ }
+
+ if ($this->config['nationality'] === 'visible') {
+ $builder->add('nationality', 'select2_chill_country', array(
'required' => false
- ))
- ->add('spokenLanguages', 'select2_chill_language', array(
+ ));
+ }
+
+ if ($this->config['spoken_languages'] === 'visible') {
+ $builder->add('spokenLanguages', 'select2_chill_language', array(
'required' => false,
'multiple' => true
- ))
- ->add('maritalStatus', 'select2_chill_marital_status', array(
+ ));
+ }
+
+ if ($this->config['marital_status'] === 'visible'){
+ $builder->add('maritalStatus', 'select2_chill_marital_status', array(
'required' => false
- ))
- ;
+ ));
+ }
if($options['cFGroup']) {
$builder
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index e934a7c71..b0cf94e1d 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -1,7 +1,14 @@
parameters:
# cl_chill_person.example.class: Chill\PersonBundle\Example
-services:
+services:
+ chill.person.form.person_creation:
+ class: Chill\PersonBundle\Form\PersonType
+ arguments:
+ - %chill_person.person_fields%
+ tags:
+ - { name: form.type }
+
chill.person.accompanying_period_closing_motive:
class: Chill\PersonBundle\Form\Type\ClosingMotiveType
scope: request
diff --git a/Resources/views/Person/edit.html.twig b/Resources/views/Person/edit.html.twig
index 10472a12f..fd3a59854 100644
--- a/Resources/views/Person/edit.html.twig
+++ b/Resources/views/Person/edit.html.twig
@@ -43,23 +43,40 @@
+{%- if form.nationality is defined or form.spokenLanguages is defined or form.maritalStatus is defined -%}
+{%- endif -%}
+{%- if form.email is defined or form.phonenumber is defined -%}
+{%- endif -%}
{{ form_rest(form) }}
diff --git a/Resources/views/Person/view.html.twig b/Resources/views/Person/view.html.twig
index 5ae10a9a5..e86a55857 100644
--- a/Resources/views/Person/view.html.twig
+++ b/Resources/views/Person/view.html.twig
@@ -86,8 +86,11 @@ This view should receive those arguments:
{%- endif -%}
+ {%- if chill_person.fields.place_of_birth == 'visible' -%}
{% spaceless %}
{% if person.countryOfBirth is not null %}
@@ -96,6 +99,7 @@ This view should receive those arguments:
{{ 'Unknown country of birth'|trans }}
{% endif %}
{% endspaceless %}
+ {%- endif -%}
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
@@ -106,10 +110,12 @@ This view should receive those arguments:
+ {%- if chill_person.fields.nationality == 'visible' or chill_person.fields.spoken_languages == 'visible'-%}
{{ 'Administrative information'|trans|upper }}
+ {%- if chill_person.fields.nationality == 'visible' -%}
{{ 'Nationality'|trans }} :
@@ -120,6 +126,8 @@ This view should receive those arguments:
{% endif %}
{{ 'Spoken languages'|trans|upper}} :
{% if person.spokenLanguages|length == 0 %}
@@ -87,7 +90,8 @@
{{ lang.name|localize_translatable_string }}{% if not loop.last %},{% endif %}
{% endfor %}
{% endif %}
-
+
+ {%- endif -%}
{% endblock %}
diff --git a/Tests/Controller/PersonControllerUpdateTest.php b/Tests/Controller/PersonControllerUpdateTest.php
index 9429e4e3e..b7087024d 100644
--- a/Tests/Controller/PersonControllerUpdateTest.php
+++ b/Tests/Controller/PersonControllerUpdateTest.php
@@ -96,6 +96,24 @@ class PersonControllerUpdateTest extends WebTestCase
"The person edit form is accessible");
}
+ /**
+ * Test the configurable fields are present
+ *
+ * @group configurable_fields
+ */
+ public function testHiddenFielsArePresent()
+ {
+ $crawler = $this->client->request('GET', $this->editUrl);
+
+ $configurables = array('placeOfBirth', 'phonenumber', 'email',
+ 'countryOfBirth', 'nationality', 'spokenLanguages', 'maritalStatus');
+ $form = $crawler->selectButton('Submit')->form(); //;
+
+ foreach($configurables as $key) {
+ $this->assertTrue($form->has('chill_personbundle_person['.$key.']'));
+ }
+ }
+
/**
* Test if the edit page of a given person is not accessible for a user
* of another center of the person
diff --git a/Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php b/Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php
new file mode 100644
index 000000000..7d374a3a7
--- /dev/null
+++ b/Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php
@@ -0,0 +1,211 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Chill\PersonBundle\Tests\Controller;
+
+//ini_set('memory_limit', '-1');
+
+use Chill\PersonBundle\Entity\Person;
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+
+/**
+ * Test the edition of persons
+ *
+ * As I am logged in as "center a_social"
+ *
+ * @author Julien Fastré
+ */
+class PersonControllerUpdateWithHiddenFieldsTest extends WebTestCase
+{
+ /** @var \Doctrine\ORM\EntityManagerInterface The entity manager */
+ private $em;
+
+ /** @var Person The person on which the test is executed */
+ private $person;
+
+ /** @var string The url using for editing the person's information */
+ private $editUrl;
+
+ /** @var string The url using for seeing the person's information */
+ private $viewUrl;
+
+ /**
+ * Prepare client and create a random person
+ */
+ public function setUp()
+ {
+ static::bootKernel(array('environment' => 'test_with_hidden_fields'));
+
+ $this->em = static::$kernel->getContainer()
+ ->get('doctrine.orm.entity_manager');
+
+ $center = $this->em->getRepository('ChillMainBundle:Center')
+ ->findOneBy(array('name' => 'Center A'));
+
+ $this->person = (new Person())
+ ->setLastName("My Beloved")
+ ->setFirstName("Jesus")
+ ->setCenter($center)
+ ->setGender(Person::MALE_GENDER);
+
+ $this->em->persist($this->person);
+ $this->em->flush();
+
+ $this->editUrl = '/en/person/'.$this->person->getId().'/general/edit';
+ $this->viewUrl = '/en/person/'.$this->person->getId().'/general';
+
+ $this->client = static::createClient(
+ array(
+ 'environment' => 'test_with_hidden_fields'
+ ),
+ array(
+ 'PHP_AUTH_USER' => 'center a_social',
+ 'PHP_AUTH_PW' => 'password',
+ )
+ );
+ }
+
+ /**
+ * Reload the person from the db
+ */
+ protected function refreshPerson()
+ {
+ $this->person = $this->em->getRepository('ChillPersonBundle:Person')
+ ->find($this->person->getId());
+ }
+
+ /**
+ * Test the edit page are accessible
+ */
+ public function testEditPageIsSuccessful()
+ {
+ $this->client->request('GET', $this->editUrl);
+ $this->assertTrue($this->client->getResponse()->isSuccessful(),
+ "The person edit form is accessible");
+ }
+
+ /**
+ * Test the configurable fields are absent
+ *
+ * @group configurable_fields
+ */
+ public function testHiddenFielsAreAbsent()
+ {
+ $crawler = $this->client->request('GET', $this->editUrl);
+
+ $configurables = array('placeOfBirth', 'phonenumber', 'email',
+ 'countryOfBirth', 'nationality', 'spokenLanguages', 'maritalStatus');
+ $form = $crawler->selectButton('Submit')->form(); //;
+
+ foreach($configurables as $key) {
+ $this->assertFalse($form->has('chill_personbundle_person['.$key.']'));
+ }
+ }
+
+ /**
+ * Test the edition of a field
+ *
+ * Given I fill the field with $value
+ * And I submit the form
+ * Then I am redirected to the 'general' page
+ * And the person is updated in the db
+ *
+ * @dataProvider validTextFieldsProvider
+ * @param string $field
+ * @param string $value
+ * @param \Closure $callback
+ */
+ public function testEditTextField($field, $value, \Closure $callback)
+ {
+ $crawler = $this->client->request('GET', $this->editUrl);
+
+ $form = $crawler->selectButton('Submit')
+ ->form();
+ //transform countries into value if needed
+ switch ($field) {
+ case 'nationality':
+ case 'countryOfBirth':
+ if ($value !== NULL) {
+ $country = $this->em->getRepository('ChillMainBundle:Country')
+ ->findOneByCountryCode($value);
+ $transformedValue = $country->getId();
+ } else {
+ $transformedValue = NULL;
+ }
+ break;
+ default:
+ $transformedValue = $value;
+ }
+
+ $form->get('chill_personbundle_person['.$field. ']')
+ ->setValue($transformedValue);
+
+ $this->client->submit($form);
+ $this->refreshPerson();
+
+ $this->assertTrue($this->client->getResponse()->isRedirect($this->viewUrl),
+ 'the page is redirected to general view');
+ $this->assertEquals($value, $callback($this->person),
+ 'the value '.$field.' is updated in db');
+
+ $crawler = $this->client->followRedirect();
+ $this->assertGreaterThan(0, $crawler->filter('.success')->count(),
+ 'a element .success is shown');
+
+ if($field == 'birthdate' or $field == 'memo' or $field == 'countryOfBirth' or $field == 'nationality'
+ or $field == 'gender') {
+ // we do not perform test on the web page contents.
+ } else {
+ $this->assertGreaterThan(0, $crawler->filter('html:contains("'.$value.'")')->count());
+ }
+ }
+
+ /**
+ * provide valid values to test, with field name and
+ * a function to find the value back from person entity
+ *
+ * @return mixed[]
+ */
+ public function validTextFieldsProvider()
+ {
+ return array(
+ ['firstName', 'random Value', function(Person $person) { return $person->getFirstName(); } ],
+ ['lastName' , 'random Value', function(Person $person) { return $person->getLastName(); } ],
+ ['birthdate', '15-12-1980', function(Person $person) { return $person->getBirthdate()->format('d-m-Y'); }],
+ ['memo', 'jfkdlmq jkfldmsq jkmfdsq', function(Person $person) { return $person->getMemo(); }],
+ ['birthdate', '', function(Person $person) { return $person->getBirthdate(); }],
+ ['gender', Person::FEMALE_GENDER, function(Person $person) { return $person->getGender(); }],
+ );
+ }
+
+ public function tearDown()
+ {
+ $this->refreshPerson();
+ $this->em->remove($this->person);
+ $this->em->flush();
+ }
+
+ private function getVeryLongText()
+ {
+ return <<assertGreaterThan(0, $crawler->filter('html:contains("Tested Person")')->count());
$this->assertGreaterThan(0, $crawler->filter('html:contains("Réginald")')->count());
+ $this->assertContains('Email addresses', $crawler->text());
+ $this->assertContains('Phonenumber', $crawler->text());
+ $this->assertContains('Langues parlées', $crawler->text());
+ $this->assertContains(/* Etat */ 'civil', $crawler->text());
}
/**
diff --git a/Tests/Controller/PersonControllerViewWithHiddenFieldsTest.php b/Tests/Controller/PersonControllerViewWithHiddenFieldsTest.php
new file mode 100644
index 000000000..2ace5c1da
--- /dev/null
+++ b/Tests/Controller/PersonControllerViewWithHiddenFieldsTest.php
@@ -0,0 +1,107 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Chill\PersonBundle\Tests\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+use Chill\PersonBundle\Entity\Person;
+
+/**
+ * @author Julien Fastré
+ * @author Marc Ducobu
+ */
+class PersonControllerViewTestWithHiddenFields extends WebTestCase
+{
+ /** @var \Doctrine\ORM\EntityManagerInterface The entity manager */
+ private $em;
+
+ /** @var Person A person used on which to run the test */
+ private $person;
+
+ /** @var String The url to view the person details */
+ private $viewUrl;
+
+ public function setUp()
+ {
+ static::bootKernel(array('environment' => 'test_with_hidden_fields'));
+
+ $this->em = static::$kernel->getContainer()
+ ->get('doctrine.orm.entity_manager');
+
+ $center = $this->em->getRepository('ChillMainBundle:Center')
+ ->findOneBy(array('name' => 'Center A'));
+
+ $this->person = (new Person())
+ ->setLastName("Tested Person")
+ ->setFirstName("Réginald")
+ ->setCenter($center)
+ ->setGender(Person::MALE_GENDER);
+
+ $this->em->persist($this->person);
+ $this->em->flush();
+
+ $this->viewUrl = '/en/person/'.$this->person->getId().'/general';
+ }
+
+ /**
+ * Test if the view page is accessible
+ *
+ * @group configurable_fields
+ */
+ public function testViewPerson()
+ {
+ $client = static::createClient(
+ array('environment' => 'test_with_hidden_fields'),
+ array(
+ 'PHP_AUTH_USER' => 'center a_social',
+ 'PHP_AUTH_PW' => 'password',
+ 'HTTP_ACCEPT_LANGUAGE' => 'fr'
+ )
+ );
+
+ $crawler = $client->request('GET', $this->viewUrl);
+ $response = $client->getResponse();
+
+ $this->assertTrue($response->isSuccessful());
+
+ $this->assertGreaterThan(0, $crawler->filter('html:contains("Tested Person")')->count());
+ $this->assertGreaterThan(0, $crawler->filter('html:contains("Réginald")')->count());
+ $this->assertNotContains('Email addresses', $crawler->text());
+ $this->assertNotContains('Phonenumber', $crawler->text());
+ $this->assertNotContains('Langues parlées', $crawler->text());
+ $this->assertNotContains(/* Etat */ 'civil', $crawler->text());
+ }
+
+ /**
+ * Reload the person from the db
+ */
+ protected function refreshPerson()
+ {
+ $this->person = $this->em->getRepository('ChillPersonBundle:Person')
+ ->find($this->person->getId());
+ }
+
+ public function tearDown()
+ {
+ $this->refreshPerson();
+ $this->em->remove($this->person);
+ $this->em->flush();
+ }
+
+}
diff --git a/Tests/Fixtures/App/app/config/config_test_with_hidden_fields.yml b/Tests/Fixtures/App/app/config/config_test_with_hidden_fields.yml
new file mode 100644
index 000000000..e11599661
--- /dev/null
+++ b/Tests/Fixtures/App/app/config/config_test_with_hidden_fields.yml
@@ -0,0 +1,18 @@
+# config/config_test.yml
+imports:
+ - { resource: config.yml } #here we import a config.yml file, this is not required
+
+framework:
+ test: ~
+ session:
+ storage_id: session.storage.filesystem
+
+chill_person:
+ person_fields:
+ nationality: hidden
+ email: hidden
+ place_of_birth: hidden
+ phonenumber: hidden
+ country_of_birth: hidden
+ marital_status: hidden
+ spoken_languages: hidden
\ No newline at end of file