File size: 2,960 Bytes
d2897cd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?php

declare(strict_types=1);

namespace Mautic\EmailBundle\Validator;

use Mautic\EmailBundle\Entity\Email;
use Mautic\LeadBundle\Entity\LeadList;
use Mautic\LeadBundle\Form\Validator\Constraints\LeadListAccess;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

final class EmailListsValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint): void
    {
        if (!$value instanceof Email) {
            throw new UnexpectedTypeException($value, Email::class);
        }

        if ('list' !== $value->getEmailType() || $value->getTranslationParent()) {
            return;
        }

        $this->validateLists($value);
        $this->validateExcludedLists($value);
        $this->validateConflictingLists($value);
    }

    private function validateLists(Email $email): void
    {
        $violations = $this->context->getValidator()->validate(
            $email->getLists(),
            [
                new LeadListAccess(),
                new NotBlank(
                    [
                        'message' => 'mautic.lead.lists.required',
                    ]
                ),
            ]
        );
        $this->addViolationsAtPath($violations, 'lists');
    }

    private function validateExcludedLists(Email $email): void
    {
        $violations = $this->context->getValidator()->validate(
            $email->getExcludedLists(),
            [
                new LeadListAccess(['allowEmpty' => true]),
            ]
        );
        $this->addViolationsAtPath($violations, 'excludedLists');
    }

    private function validateConflictingLists(Email $email): void
    {
        $listsIds         = $this->getListsIds($email->getLists());
        $excludedListsIds = $this->getListsIds($email->getExcludedLists());
        $isConflicting    = (bool) array_intersect($listsIds, $excludedListsIds);

        if ($isConflicting) {
            $this->context->buildViolation('mautic.lead.excluded_lists.conflicting')
                ->atPath('excludedLists')
                ->addViolation();
        }
    }

    /**
     * @param LeadList[] $lists
     *
     * @return string[]
     */
    private function getListsIds(iterable $lists): array
    {
        $ids = [];

        foreach ($lists as $list) {
            $ids[] = (string) $list->getId();
        }

        return $ids;
    }

    /**
     * @param ConstraintViolationInterface[] $violations
     */
    private function addViolationsAtPath(iterable $violations, string $path): void
    {
        foreach ($violations as $violation) {
            $this->context->buildViolation($violation->getMessage())
                ->atPath($path)
                ->addViolation();
        }
    }
}