diff --git a/Controller/PersonController.php b/Controller/PersonController.php
index 0f0a59117..b5a52bb56 100644
--- a/Controller/PersonController.php
+++ b/Controller/PersonController.php
@@ -170,12 +170,12 @@ class PersonController extends Controller
->getGroupCenters()[0]
->getCenter();
- $person = (new Person())
+ $person = (new Person(new \DateTime('now')))
->setCenter($defaultCenter);
$form = $this->createForm(
new CreationPersonType(CreationPersonType::FORM_NOT_REVIEWED),
- array('creation_date' => new \DateTime(), 'center' => $defaultCenter),
+ $person,
array('action' => $this->generateUrl('chill_person_review'))
);
@@ -197,18 +197,22 @@ class PersonController extends Controller
*/
private function _bindCreationForm($form)
{
- $date = new \DateTime();
- $person = new Person($form['creation_date']->getData());
+ /**
+ * @var Person
+ */
+ $person = $form->getData();
-
- $date_of_birth = new \DateTime();
-
- $person->setFirstName($form['firstName']->getData())
- ->setLastName($form['lastName']->getData())
- ->setGender($form['gender']->getData())
- ->setBirthdate($form['birthdate']->getData())
- ->setCenter($form['center']->getData())
- ;
+ $periods = $person->getAccompanyingPeriodsOrdered();
+ $period = $periods[0];
+ $period->setOpeningDate($form['creation_date']->getData());
+// $person = new Person($form['creation_date']->getData());
+//
+// $person->setFirstName($form['firstName']->getData())
+// ->setLastName($form['lastName']->getData())
+// ->setGender($form['gender']->getData())
+// ->setBirthdate($form['birthdate']->getData())
+// ->setCenter($form['center']->getData())
+// ;
return $person;
}
@@ -251,15 +255,18 @@ class PersonController extends Controller
$form = $this->createForm(
new CreationPersonType(CreationPersonType::FORM_BEING_REVIEWED),
- null, array('action' => $this->generateUrl('chill_person_create')));
+ new Person(),
+ array('action' => $this->generateUrl('chill_person_create')));
$form->handleRequest($request);
$person = $this->_bindCreationForm($form);
$errors = $this->_validatePersonAndAccompanyingPeriod($person);
-
- if ( count($errors) > 0) {
+ $this->get('logger')->info(sprintf('Person created with %d errors ', count($errors)));
+
+ if ($errors->count() > 0) {
+ $this->get('logger')->info('The created person has errors');
$flashBag = $this->get('session')->getFlashBag();
$translator = $this->get('translator');
@@ -271,11 +278,14 @@ class PersonController extends Controller
$form = $this->createForm(
new CreationPersonType(CreationPersonType::FORM_NOT_REVIEWED),
- array('action' => $this->generateUrl('chill_person_create')));
+ new Person(),
+ array('action' => $this->generateUrl('chill_person_review')));
$form->handleRequest($request);
return $this->_renderNewForm($form);
+ } else {
+ $this->get('logger')->info('Person created without errors');
}
$em = $this->getDoctrine()->getManager();
@@ -331,7 +341,7 @@ class PersonController extends Controller
$form = $this->createForm(new CreationPersonType());
$form->handleRequest($request);
-
+ var_dump($form->getData());
$person = $this->_bindCreationForm($form);
$errors = $this->_validatePersonAndAccompanyingPeriod($person);
@@ -349,7 +359,11 @@ class PersonController extends Controller
return $this->redirect($this->generateUrl('chill_person_general_edit',
array('person_id' => $person->getId())));
} else {
- $r = new Response('this should not happen if you reviewed your submission');
+ $text = "this should not happen if you reviewed your submission\n";
+ foreach ($errors as $error) {
+ $text .= $error->getMessage()."\n";
+ }
+ $r = new Response($text);
$r->setStatusCode(400);
return $r;
}
diff --git a/DependencyInjection/ChillPersonExtension.php b/DependencyInjection/ChillPersonExtension.php
index 548f3536f..589e2c14e 100644
--- a/DependencyInjection/ChillPersonExtension.php
+++ b/DependencyInjection/ChillPersonExtension.php
@@ -24,8 +24,13 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
+ // set configuration for double metaphone
$container->setParameter('cl_chill_person.search.use_double_metaphone',
$config['search']['use_double_metaphone']);
+
+ // set configuration for validation
+ $container->setParameter('chill_person.validation.birtdate_not_before',
+ $config['validation']['birthdate_not_after']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index d92d0cfbe..833b5498d 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -12,6 +12,10 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
*/
class Configuration implements ConfigurationInterface
{
+
+ private $validationBirthdateNotAfterInfos = "The period before today during which"
+ . " any birthdate is not allowed. The birthdate is expressed as ISO8601 : "
+ . "https://en.wikipedia.org/wiki/ISO_8601#Durations";
/**
* {@inheritDoc}
*/
@@ -29,13 +33,34 @@ class Configuration implements ConfigurationInterface
->booleanNode('use_double_metaphone')
->defaultFalse()
->end()
- ->booleanNode('use_trigrams')->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();
- // Here you should define the parameters that are allowed to
- // configure your bundle. See the documentation linked above for
- // more information on that topic.
-
return $treeBuilder;
}
}
diff --git a/Form/CreationPersonType.php b/Form/CreationPersonType.php
index dc22aa952..6966d8346 100644
--- a/Form/CreationPersonType.php
+++ b/Form/CreationPersonType.php
@@ -24,9 +24,7 @@ namespace Chill\PersonBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
-use Chill\PersonBundle\Form\Type\CivilType;
use Chill\PersonBundle\Form\Type\GenderType;
-use CL\BelgianNationalNumberBundle\Form\BelgianNationalNumberType;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
class CreationPersonType extends AbstractType
@@ -53,20 +51,26 @@ class CreationPersonType extends AbstractType
if ($this->form_status === self::FORM_BEING_REVIEWED) {
$dateToStringTransformer = new DateTimeToStringTransformer(
- null, null, 'dd-MM-yyyy', true);
+ null, null, 'd-m-Y', false);
$builder->add('firstName', 'hidden')
->add('lastName', 'hidden')
- ->add( $builder->create('birthdate', 'hidden')
- ->addModelTransformer($dateToStringTransformer)
- )
+ ->add('birthdate', 'hidden', array(
+ 'property_path' => 'birthdate'
+ ))
->add('gender', 'hidden')
- ->add( $builder->create('creation_date', 'hidden')
- ->addModelTransformer($dateToStringTransformer)
- )
- ->add('form_status', 'hidden')
+ ->add('creation_date', 'hidden', array(
+ 'mapped' => false
+ ))
+ ->add('form_status', 'hidden', array(
+ 'mapped' => false
+ ))
->add('center', 'center')
;
+ $builder->get('birthdate')
+ ->addModelTransformer($dateToStringTransformer);
+ $builder->get('creation_date', 'hidden')
+ ->addModelTransformer($dateToStringTransformer);
} else {
$builder
->add('firstName')
@@ -76,10 +80,16 @@ class CreationPersonType extends AbstractType
->add('gender', new GenderType(), array(
'required' => true, 'empty_value' => null
))
- ->add('creation_date', 'date', array('required' => true,
- 'widget' => 'single_text', 'format' => 'dd-MM-yyyy',
+ ->add('creation_date', 'date', array(
+ 'required' => true,
+ 'widget' => 'single_text',
+ 'format' => 'dd-MM-yyyy',
+ 'mapped' => false,
'data' => new \DateTime()))
- ->add('form_status', 'hidden', array('data' => $this->form_status))
+ ->add('form_status', 'hidden', array(
+ 'data' => $this->form_status,
+ 'mapped' => false
+ ))
->add('center', 'center')
;
}
@@ -94,9 +104,9 @@ class CreationPersonType extends AbstractType
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
-// $resolver->setDefaults(array(
-// 'data_class' => 'Chill\PersonBundle\Entity\Person'
-// ));
+ $resolver->setDefaults(array(
+ 'data_class' => 'Chill\PersonBundle\Entity\Person'
+ ));
}
/**
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index 26d220c2f..0e81ec15a 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -48,3 +48,11 @@ services:
tags:
- { name: security.voter }
- { name: chill.role }
+
+ chill.person.birthdate_validation:
+ class: Chill\PersonBundle\Validator\Constraints\BirthdateValidator
+ arguments:
+ - "%chill_person.validation.birtdate_not_before%"
+ tags:
+ - { name: validator.constraint_validator, alias: birthdate_not_before }
+
diff --git a/Resources/config/validation.yml b/Resources/config/validation.yml
index ccda164ee..f6e683d3e 100644
--- a/Resources/config/validation.yml
+++ b/Resources/config/validation.yml
@@ -22,6 +22,8 @@ Chill\PersonBundle\Entity\Person:
- Date:
message: 'Birthdate not valid'
groups: [general, creation]
+ - Chill\PersonBundle\Validator\Constraints\Birthdate:
+ groups: [general, creation]
gender:
- NotNull:
groups: [general, creation]
diff --git a/Resources/translations/validators.fr.yml b/Resources/translations/validators.fr.yml
index b29c5306d..38fabbbbf 100644
--- a/Resources/translations/validators.fr.yml
+++ b/Resources/translations/validators.fr.yml
@@ -11,3 +11,4 @@
'Closing date is not valid': 'La date de fermeture n''est pas valide'
'Closing date can not be null': 'La date de fermeture ne peut être nulle'
The date of closing is before the date of opening: La période de fermeture est après la période d'ouverture
+The birthdate must be before %date%: La date de naissance doit être avant le %date%
diff --git a/Tests/Controller/PersonControllerCreateTest.php b/Tests/Controller/PersonControllerCreateTest.php
index bcada006a..83acbbf7b 100644
--- a/Tests/Controller/PersonControllerCreateTest.php
+++ b/Tests/Controller/PersonControllerCreateTest.php
@@ -38,7 +38,7 @@ class PersonControllerCreateTest extends WebTestCase
const CREATEDATE_INPUT = "chill_personbundle_person_creation[creation_date]";
const CENTER_INPUT = "chill_personbundle_person_creation[center]";
- const LONG_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq.";
+ const LONG_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta.Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq.";
/**
* return an authenticated client, useful for submitting form
diff --git a/Tests/Validator/BirthdateValidatorTest.php b/Tests/Validator/BirthdateValidatorTest.php
new file mode 100644
index 000000000..94f1347a5
--- /dev/null
+++ b/Tests/Validator/BirthdateValidatorTest.php
@@ -0,0 +1,112 @@
+
+ *
+ * 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\Validator;
+
+use Chill\PersonBundle\Validator\Constraints\BirthdateValidator;
+use Chill\PersonBundle\Validator\Constraints\Birthdate;
+use Prophecy\Argument;
+use Prophecy\Prophet;
+
+/**
+ * Test the behaviour of BirthdayValidator
+ *
+ * @author Julien Fastré
+ */
+class BirthdateValidatorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * A prophecy for \Symfony\Component\Validator\Context\ExecutionContextInterface
+ *
+ * Will reveal \Symfony\Component\Validator\Context\ExecutionContextInterface
+ */
+ private $context;
+
+ private $prophet;
+
+ /**
+ *
+ * @var Birthdate
+ */
+ private $constraint;
+
+ public function setUp()
+ {
+ $this->prophet = new Prophet;
+
+ $constraintViolationBuilder = $this->prophet->prophesize();
+ $constraintViolationBuilder->willImplement('Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface');
+
+ $constraintViolationBuilder->setParameter(Argument::any(), Argument::any())
+ ->willReturn($constraintViolationBuilder->reveal());
+ $constraintViolationBuilder->addViolation()
+ ->willReturn($constraintViolationBuilder->reveal());
+
+ $this->context = $this->prophet->prophesize();
+ $this->context->willImplement('Symfony\Component\Validator\Context\ExecutionContextInterface');
+ $this->context->buildViolation(Argument::type('string'))
+ ->willReturn($constraintViolationBuilder->reveal());
+
+ $this->constraint = new Birthdate();
+ }
+
+ public function testValidBirthDate()
+ {
+
+ $date = new \DateTime('2015-01-01');
+
+ $birthdateValidator = new BirthdateValidator();
+ $birthdateValidator->initialize($this->context->reveal());
+
+ $birthdateValidator->validate($date, $this->constraint);
+
+ $this->context->buildViolation(Argument::any())->shouldNotHaveBeenCalled();
+ }
+
+ public function testInvalidBirthDate()
+ {
+ $date = new \DateTime('tomorrow');
+
+ $birthdateValidator = new BirthdateValidator();
+ $birthdateValidator->initialize($this->context->reveal());
+
+ $birthdateValidator->validate($date, $this->constraint);
+
+ $this->context->buildViolation(Argument::type('string'))->shouldHaveBeenCalled();
+ }
+
+ public function testInvalidBirthDateWithParameter()
+ {
+ $date = (new \DateTime('today'))->sub(new \DateInterval('P1M'));
+
+ $birthdateValidator = new BirthdateValidator('P1Y');
+ $birthdateValidator->initialize($this->context->reveal());
+
+ $birthdateValidator->validate($date, $this->constraint);
+
+ $this->context->buildViolation(Argument::type('string'))->shouldHaveBeenCalled();
+ }
+
+ public function tearDown()
+ {
+ $this->prophet->checkPredictions();
+ }
+
+
+}
diff --git a/Validator/Constraints/Birthdate.php b/Validator/Constraints/Birthdate.php
new file mode 100644
index 000000000..d09d549fd
--- /dev/null
+++ b/Validator/Constraints/Birthdate.php
@@ -0,0 +1,42 @@
+
+ *
+ * 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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Create a constraint on birth date: the birthdate after today are not allowed.
+ *
+ * It is possible to add a delay before today, expressed as described in
+ * interval_spec : http://php.net/manual/en/dateinterval.construct.php
+ * (this interval_spec itself is based on ISO8601 :
+ * https://en.wikipedia.org/wiki/ISO_8601#Durations)
+ *
+ * @author Julien Fastré
+ */
+class Birthdate extends Constraint
+{
+ public $message = "The birthdate must be before %date%";
+
+ public function validatedBy()
+ {
+ return 'birthdate_not_before';
+ }
+}
diff --git a/Validator/Constraints/BirthdateValidator.php b/Validator/Constraints/BirthdateValidator.php
new file mode 100644
index 000000000..cba955ef6
--- /dev/null
+++ b/Validator/Constraints/BirthdateValidator.php
@@ -0,0 +1,75 @@
+
+ *
+ * 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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ *
+ *
+ * @author Julien Fastré
+ */
+class BirthdateValidator extends ConstraintValidator
+{
+ private $interval_spec = null;
+
+ public function __construct($interval_spec = null)
+ {
+ $this->interval_spec = $interval_spec;
+ }
+
+ public function validate($value, Constraint $constraint)
+ {
+ if ($value === NULL) {
+
+ return;
+ }
+
+ if (!$value instanceof \DateTime) {
+ throw new \LogicException('The input should a be a \DateTime interface,'
+ . (is_object($value) ? get_class($value) : gettype($value)));
+ }
+
+ $limitDate = $this->getLimitDate();
+
+ if ($limitDate < $value) {
+ $this->context->buildViolation($constraint->message)
+ ->setParameter('%date%', $limitDate->format('d-m-Y'))
+ ->addViolation();
+ }
+
+ }
+
+ /**
+ *
+ * @return \DateTime
+ */
+ private function getLimitDate()
+ {
+ if ($this->interval_spec !== NULL) {
+ $interval = new \DateInterval($this->interval_spec);
+ return (new \DateTime('now'))->sub($interval);
+ } else {
+ return (new \DateTime('now'));
+ }
+ }
+
+}