mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
move validation on person into annotations
This commit is contained in:
parent
7faddbe3fe
commit
41d76542b4
@ -43,26 +43,26 @@ class Configuration implements ConfigurationInterface
|
||||
->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
|
||||
->booleanNode('center_required')
|
||||
->info('Enable a center for each person entity. If disabled, you must provide your own center provider')
|
||||
->defaultValue(true)
|
||||
->end()
|
||||
->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
|
||||
|
@ -43,6 +43,11 @@ use Doctrine\Common\Collections\Criteria;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
||||
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Chill\PersonBundle\Validator\Constraints\Person\Birthdate;
|
||||
use Chill\MainBundle\Validation\Constraint\PhonenumberConstraint;
|
||||
use Chill\PersonBundle\Validator\Constraints\Person\PersonHasCenter;
|
||||
use Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequential;
|
||||
|
||||
/**
|
||||
* Person Class
|
||||
@ -57,6 +62,12 @@ use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
||||
* @DiscriminatorMap(typeProperty="type", mapping={
|
||||
* "person"=Person::class
|
||||
* })
|
||||
* @PersonHasCenter(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
* @HouseholdMembershipSequential(
|
||||
* groups={"household_memberships"}
|
||||
* )
|
||||
*/
|
||||
class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
@ -75,6 +86,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=255)
|
||||
* @Assert\NotBlank(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
* @Assert\Length(
|
||||
* max=255,
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $firstName;
|
||||
|
||||
@ -83,6 +101,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=255)
|
||||
* @Assert\NotBlank(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
* @Assert\Length(
|
||||
* max=255,
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $lastName;
|
||||
|
||||
@ -102,6 +127,12 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(type="date", nullable=true)
|
||||
* @Assert\Date(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
* @Birthdate(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $birthdate;
|
||||
|
||||
@ -110,6 +141,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var \DateTimeImmutable
|
||||
*
|
||||
* @ORM\Column(type="date_immutable", nullable=true)
|
||||
* @Assert\Date(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private ?\DateTimeImmutable $deathdate;
|
||||
|
||||
@ -150,6 +184,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="string", length=9, nullable=true)
|
||||
* @Assert\NotNull(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $gender;
|
||||
|
||||
@ -179,8 +216,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(type="date", nullable=true)
|
||||
* @Assert\Date(
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $maritalStatusDate;
|
||||
private ?\DateTime $maritalStatusDate;
|
||||
|
||||
/**
|
||||
* Comment on marital status
|
||||
@ -202,6 +242,10 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
* @Assert\Email(
|
||||
* checkMX=true,
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $email = '';
|
||||
|
||||
@ -210,6 +254,14 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="text", length=40, nullable=true)
|
||||
* @Assert\Regex(
|
||||
* pattern="/^([\+{1}])([0-9\s*]{4,20})$/",
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
* @PhonenumberConstraint(
|
||||
* type="landline",
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $phonenumber = '';
|
||||
|
||||
@ -218,6 +270,14 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="text", length=40, nullable=true)
|
||||
* @Assert\Regex(
|
||||
* pattern="/^([\+{1}])([0-9\s*]{4,20})$/",
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
* @PhonenumberConstraint(
|
||||
* type="mobile",
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $mobilenumber = '';
|
||||
|
||||
@ -230,12 +290,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* cascade={"persist", "remove", "merge", "detach"},
|
||||
* orphanRemoval=true
|
||||
* )
|
||||
* @Assert\Valid(
|
||||
* traverse=true,
|
||||
* groups={"general", "creation"}
|
||||
* )
|
||||
*/
|
||||
private $otherPhoneNumbers;
|
||||
|
||||
//TO-ADD caseOpeningDate
|
||||
//TO-ADD nativeLanguag
|
||||
|
||||
/**
|
||||
* The person's spoken languages
|
||||
* @var ArrayCollection
|
||||
@ -352,6 +413,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
private $addresses;
|
||||
|
||||
/**
|
||||
* fullname canonical. Read-only field, which is calculated by
|
||||
* the database.
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
@ -372,6 +435,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
private array $currentHouseholdAt = [];
|
||||
|
||||
/**
|
||||
* Read-only field, computed by the database
|
||||
*
|
||||
* @ORM\OneToMany(
|
||||
* targetEntity=PersonHouseholdAddress::class,
|
||||
* mappedBy="person"
|
||||
@ -389,8 +454,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
|
||||
/**
|
||||
* Person constructor.
|
||||
*
|
||||
* @param \DateTime|null $opening
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -403,6 +466,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
$this->householdAddresses = new ArrayCollection();
|
||||
$this->genderComment = new CommentEmbeddable();
|
||||
$this->maritalStatusComment = new CommentEmbeddable();
|
||||
$this->periodLocatedOn = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1200,6 +1264,10 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* Validation callback that checks if the accompanying periods are valid
|
||||
*
|
||||
* This method add violation errors.
|
||||
*
|
||||
* @Assert\Callback(
|
||||
* groups={"accompanying_period_consistent"}
|
||||
* )
|
||||
*/
|
||||
public function isAccompanyingPeriodValid(ExecutionContextInterface $context)
|
||||
{
|
||||
@ -1245,6 +1313,10 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
* two addresses with the same validFrom date)
|
||||
*
|
||||
* This method add violation errors.
|
||||
*
|
||||
* @Assert\Callback(
|
||||
* groups={"addresses_consistent"}
|
||||
* )
|
||||
*/
|
||||
public function isAddressesValid(ExecutionContextInterface $context)
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ class BirthdateValidatorTest extends ConstraintValidatorTestCase
|
||||
$this->validator->validate($bornToday, $this->createConstraint());
|
||||
$this->buildViolation('msg')
|
||||
->setParameter('%date%', (new \DateTime('yesterday'))->format('d-m-Y'))
|
||||
->setCode('3f42fd96-0b2d-11ec-8cf3-0f3b1b1ca1c4')
|
||||
->assertRaised();
|
||||
}
|
||||
|
||||
@ -54,6 +55,7 @@ class BirthdateValidatorTest extends ConstraintValidatorTestCase
|
||||
$this->validator->validate($bornAfter, $this->createConstraint());
|
||||
$this->buildViolation('msg')
|
||||
->setParameter('%date%', (new \DateTime('yesterday'))->format('d-m-Y'))
|
||||
->setCode('3f42fd96-0b2d-11ec-8cf3-0f3b1b1ca1c4')
|
||||
->assertRaised();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Validator\Person;
|
||||
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Validator\Constraints\Person\Birthdate;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
class PersonValidationTest extends KernelTestCase
|
||||
{
|
||||
private ValidatorInterface $validator;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
self::bootKernel();
|
||||
$this->validator = self::$container->get(ValidatorInterface::class);
|
||||
}
|
||||
|
||||
public function testFirstnameValidation()
|
||||
{
|
||||
$person = (new Person())
|
||||
->setFirstname(\str_repeat('a', 500));
|
||||
$errors = $this->validator->validate($person, null, ["creation"]);
|
||||
foreach ($errors->getIterator() as $error) {
|
||||
if (Length::TOO_LONG_ERROR === $error->getCode()) {
|
||||
$this->assertTrue(true,
|
||||
"error code for firstname too long is present");
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->assertTrue(false,
|
||||
"error code for fistname too long is present");
|
||||
|
||||
}
|
||||
|
||||
public function testBirthdateInFuture()
|
||||
{
|
||||
$person = (new Person())
|
||||
->setBirthdate(new \Datetime('+2 months'));
|
||||
$errors = $this->validator->validate($person, null, ["creation"]);
|
||||
foreach ($errors->getIterator() as $error) {
|
||||
if (Birthdate::BIRTHDATE_INVALID_CODE === $error->getCode()) {
|
||||
$this->assertTrue(true,
|
||||
"error code for birthdate invalid is present");
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->assertTrue(false,
|
||||
"error code for birthdate invalid is present");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -29,9 +29,11 @@ use Symfony\Component\Validator\Constraint;
|
||||
* (this interval_spec itself is based on ISO8601 :
|
||||
* https://en.wikipedia.org/wiki/ISO_8601#Durations)
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @Annotation
|
||||
*/
|
||||
class Birthdate extends Constraint
|
||||
{
|
||||
public const BIRTHDATE_INVALID_CODE = '3f42fd96-0b2d-11ec-8cf3-0f3b1b1ca1c4';
|
||||
|
||||
public $message = "The birthdate must be before %date%";
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ class BirthdateValidator extends ConstraintValidator
|
||||
if ($limitDate < $value) {
|
||||
$this->context->buildViolation($constraint->message)
|
||||
->setParameter('%date%', $limitDate->format('d-m-Y'))
|
||||
->setCode(Birthdate::BIRTHDATE_INVALID_CODE)
|
||||
->addViolation();
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
namespace Chill\PersonBundle\Validator\Constraints\Person;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class PersonHasCenter extends \Symfony\Component\Validator\Constraint
|
||||
{
|
||||
public string $message = "A center is required";
|
||||
|
@ -62,18 +62,18 @@ services:
|
||||
- { name: security.voter }
|
||||
- { name: chill.role }
|
||||
|
||||
chill.person.birthdate_validation:
|
||||
class: Chill\PersonBundle\Validator\Constraints\BirthdateValidator
|
||||
Chill\PersonBundle\Validator\Constraints\:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
resource: '../Validator/Constraints/'
|
||||
|
||||
# override default config, must be loaded after resource
|
||||
Chill\PersonBundle\Validator\Constraints\BirthdateValidator:
|
||||
arguments:
|
||||
- "%chill_person.validation.birtdate_not_before%"
|
||||
tags:
|
||||
- { name: validator.constraint_validator, alias: birthdate_not_before }
|
||||
|
||||
Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequentialValidator:
|
||||
autowire: true
|
||||
tags:
|
||||
- { name: validator.constraint_validator }
|
||||
|
||||
Chill\PersonBundle\Repository\:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
@ -1,70 +1,3 @@
|
||||
Chill\PersonBundle\Entity\Person:
|
||||
properties:
|
||||
firstName:
|
||||
- NotBlank:
|
||||
groups: [general, creation]
|
||||
- Length:
|
||||
min: 2
|
||||
max: 255
|
||||
minMessage: 'This name is too short. It must containt {{ limit }} chars'
|
||||
maxMessage: 'This name is too long. It must containt {{ limit }} chars'
|
||||
groups: [general, creation]
|
||||
lastName:
|
||||
- NotBlank:
|
||||
groups: [general, creation]
|
||||
- Length:
|
||||
min: 2
|
||||
max: 255
|
||||
minMessage: 'This name is too short. It must containt {{ limit }} chars'
|
||||
maxMessage: 'This name is too long. It must containt {{ limit }} chars'
|
||||
groups: [general, creation]
|
||||
birthdate:
|
||||
- Date:
|
||||
message: 'Birthdate not valid'
|
||||
groups: [general, creation]
|
||||
- Chill\PersonBundle\Validator\Constraints\Birthdate:
|
||||
groups: [general, creation]
|
||||
gender:
|
||||
- NotNull:
|
||||
groups: [general, creation]
|
||||
#accompanyingPeriods:
|
||||
# - Valid:
|
||||
# traverse: true
|
||||
email:
|
||||
- Email:
|
||||
groups: [general, creation]
|
||||
message: 'The email is not valid'
|
||||
checkMX: true
|
||||
phonenumber:
|
||||
- Regex:
|
||||
pattern: '/^([\+{1}])([0-9\s*]{4,20})$/'
|
||||
groups: [general, creation]
|
||||
message: 'Invalid phone number: it should begin with the international prefix starting with "+", hold only digits and be smaller than 20 characters. Ex: +33123456789'
|
||||
- Chill\MainBundle\Validation\Constraint\PhonenumberConstraint:
|
||||
type: landline
|
||||
groups: [ general, creation ]
|
||||
mobilenumber:
|
||||
- Regex:
|
||||
pattern: '/^([\+{1}])([0-9\s*]{4,20})$/'
|
||||
groups: [general, creation]
|
||||
message: 'Invalid phone number: it should begin with the international prefix starting with "+", hold only digits and be smaller than 20 characters. Ex: +33623456789'
|
||||
- Chill\MainBundle\Validation\Constraint\PhonenumberConstraint:
|
||||
type: mobile
|
||||
groups: [ general, creation ]
|
||||
otherPhoneNumbers:
|
||||
- Valid:
|
||||
traverse: true
|
||||
constraints:
|
||||
- Callback:
|
||||
callback: isAccompanyingPeriodValid
|
||||
groups: [accompanying_period_consistent]
|
||||
- Callback:
|
||||
callback: isAddressesValid
|
||||
groups: [addresses_consistent]
|
||||
- Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequential:
|
||||
groups: [ 'household_memberships' ]
|
||||
|
||||
|
||||
Chill\PersonBundle\Entity\AccompanyingPeriod:
|
||||
properties:
|
||||
openingDate:
|
||||
|
Loading…
x
Reference in New Issue
Block a user