Files
chill-bundles/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/ParticipationOverlapValidator.php
2022-02-16 10:38:58 +01:00

98 lines
3.3 KiB
PHP

<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod;
use Chill\MainBundle\Util\DateRangeCovering;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use function count;
class ParticipationOverlapValidator extends ConstraintValidator
{
private const MAX_PARTICIPATION = 1;
private PersonRenderInterface $personRender;
private ThirdPartyRender $thirdpartyRender;
public function __construct(PersonRenderInterface $personRender, ThirdPartyRender $thirdPartyRender)
{
$this->personRender = $personRender;
$this->thirdpartyRender = $thirdPartyRender;
}
public function validate($participations, Constraint $constraint)
{
if (!$constraint instanceof ParticipationOverlap) {
throw new UnexpectedTypeException($constraint, ParticipationOverlap::class);
}
if (!$participations instanceof Collection) {
throw new UnexpectedTypeException($participations, 'This should be a collection');
}
if (count($participations) <= self::MAX_PARTICIPATION) {
return;
}
if (0 === count($participations)) {
return;
}
$participationList = [];
foreach ($participations as $participation) {
if (!$participation instanceof AccompanyingPeriodParticipation) {
throw new UnexpectedTypeException($participation, AccompanyingPeriodParticipation::class);
}
$personId = $participation->getPerson()->getId();
$participationList[$personId][] = $participation;
}
foreach ($participationList as $group) {
if (count($group) > 1) {
$overlaps = new DateRangeCovering(self::MAX_PARTICIPATION, $participations[0]->getStartDate()->getTimezone());
foreach ($group as $p) {
$overlaps->add($p->getStartDate(), $p->getEndDate(), $p->getId());
}
$overlaps->compute();
if ($overlaps->hasIntersections()) {
foreach ($overlaps->getIntersections() as [$start, $end, $ids]) {
$msg = null === $end ? $constraint->message :
$constraint->message;
$this->context->buildViolation($msg)
->setParameters([
'{{ start }}' => $start->format('d-m-Y'),
'{{ end }}' => null === $end ? null : $end->format('d-m-Y'),
'{{ ids }}' => $ids,
'{{ name }}' => $this->personRender->renderString($participation->getPerson(), []),
])
->addViolation();
}
}
}
}
}
}