mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 13:54:23 +00:00
Merge branch 'birthdate_constraint' into 'master'
Birthdate constraint ref #4 See merge request !3
This commit is contained in:
commit
0f022d4f95
@ -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);
|
||||
$this->get('logger')->info(sprintf('Person created with %d errors ', count($errors)));
|
||||
|
||||
if ( count($errors) > 0) {
|
||||
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;
|
||||
}
|
||||
|
@ -24,9 +24,14 @@ 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');
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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%
|
||||
|
@ -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
|
||||
|
112
Tests/Validator/BirthdateValidatorTest.php
Normal file
112
Tests/Validator/BirthdateValidatorTest.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
}
|
42
Validator/Constraints/Birthdate.php
Normal file
42
Validator/Constraints/Birthdate.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class Birthdate extends Constraint
|
||||
{
|
||||
public $message = "The birthdate must be before %date%";
|
||||
|
||||
public function validatedBy()
|
||||
{
|
||||
return 'birthdate_not_before';
|
||||
}
|
||||
}
|
75
Validator/Constraints/BirthdateValidator.php
Normal file
75
Validator/Constraints/BirthdateValidator.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
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'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user