Failed Conditions
Pull Request — 4.0 (#3667)
by k-yamamura
05:55
created

EmailValidator::checkHost()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Form\Validator;
15
16
use Eccube\Validator\EmailValidator\NoRFCEmailValidator;
17
use Egulias\EmailValidator\Validation\EmailValidation;
18
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation;
19
use Symfony\Component\Validator\Constraint;
20
use Symfony\Component\Validator\Exception\RuntimeException;
21
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
22
23
class EmailValidator extends \Symfony\Component\Validator\Constraints\EmailValidator
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28
    public function validate($value, Constraint $constraint)
29
    {
30
        if (!$constraint instanceof Email) {
31
            throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Email');
32
        }
33
34
        if (null === $value || '' === $value) {
35
            return;
36
        }
37
38
        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
39
            throw new UnexpectedTypeException($value, 'string');
40
        }
41
42
        $value = (string)$value;
43
44
        if (null === $constraint->strict) {
45
            $constraint->strict = false;
46
        }
47
48
        if ($constraint->strict) {
49
            if (!class_exists('\Egulias\EmailValidator\EmailValidator')) {
50
                throw new RuntimeException('Strict email validation requires egulias/email-validator ~1.2|~2.0');
51
            }
52
53
            $strictValidator = new \Egulias\EmailValidator\EmailValidator();
54
55
            if (interface_exists(EmailValidation::class) && !$strictValidator->isValid($value, new NoRFCWarningsValidation())) {
56
                $this->context->buildViolation($constraint->message)
57
                    ->setParameter('{{ value }}', $this->formatValue($value))
58
                    ->setCode(Email::INVALID_FORMAT_ERROR)
59
                    ->addViolation();
60
61
                return;
62
            } elseif (!interface_exists(EmailValidation::class) && !$strictValidator->isValid($value, false, true)) {
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a object<Egulias\EmailVali...dation\EmailValidation>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to EmailValidator::isValid() has too many arguments starting with true.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
63
                $this->context->buildViolation($constraint->message)
64
                    ->setParameter('{{ value }}', $this->formatValue($value))
65
                    ->setCode(Email::INVALID_FORMAT_ERROR)
66
                    ->addViolation();
67
68
                return;
69
            }
70 View Code Duplication
        } else {
71
72
            $validator = new NoRFCEmailValidator();
73
74
            if (!$validator->isValid($value)) {
75
                $this->context->buildViolation($constraint->message)
76
                    ->setParameter('{{ value }}', $this->formatValue($value))
77
                    ->setCode(Email::INVALID_FORMAT_ERROR)
78
                    ->addViolation();
79
80
                return;
81
            }
82
        }
83
84
        $host = (string)substr($value, strrpos($value, '@') + 1);
85
86
        // Check for host DNS resource records
87 View Code Duplication
        if ($constraint->checkMX) {
88
            if (!$this->checkMX($host)) {
89
                $this->context->buildViolation($constraint->message)
90
                    ->setParameter('{{ value }}', $this->formatValue($value))
91
                    ->setCode(Email::MX_CHECK_FAILED_ERROR)
92
                    ->addViolation();
93
            }
94
95
            return;
96
        }
97
98 View Code Duplication
        if ($constraint->checkHost && !$this->checkHost($host)) {
99
            $this->context->buildViolation($constraint->message)
100
                ->setParameter('{{ value }}', $this->formatValue($value))
101
                ->setCode(Email::HOST_CHECK_FAILED_ERROR)
102
                ->addViolation();
103
        }
104
    }
105
106
    /**
107
     * Check DNS Records for MX type.
108
     *
109
     * @param string $host Host
110
     *
111
     * @return bool
112
     */
113
    private function checkMX($host)
0 ignored issues
show
Bug introduced by
Consider using a different method name as you override a private method of the parent class.

Overwriting private methods is generally fine as long as you also use private visibility. It might still be preferable for understandability to use a different method name.

Loading history...
114
    {
115
        return '' !== $host && checkdnsrr($host, 'MX');
116
    }
117
118
    /**
119
     * Check if one of MX, A or AAAA DNS RR exists.
120
     *
121
     * @param string $host Host
122
     *
123
     * @return bool
124
     */
125
    private function checkHost($host)
0 ignored issues
show
Bug introduced by
Consider using a different method name as you override a private method of the parent class.

Overwriting private methods is generally fine as long as you also use private visibility. It might still be preferable for understandability to use a different method name.

Loading history...
126
    {
127
        return '' !== $host && ($this->checkMX($host) || (checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA')));
128
    }
129
130
}
131