Completed
Push — feature/send_corpus ( 0e2c78...458a19 )
by Manuel
08:57
created

Validator::validateInputServerPort()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace EndelWar\Spammer;
4
5
use Symfony\Component\Console\Input\InputInterface;
6
7
class Validator
8
{
9
    /** @var InputInterface $input */
10
    private $input;
11
12
    public function __construct(InputInterface $input)
13
    {
14
        $this->input = $input;
15
    }
16
17
    /**
18
     * @throws \InvalidArgumentException
19
     * @return array
20
     */
21
    public function validateInput(): array
22
    {
23
        $validInput = [];
24
        $validInput['smtpServerIp'] = $this->input->getOption('server');
25
        $this->validateInputServerIP($validInput['smtpServerIp']);
0 ignored issues
show
Bug introduced by
It seems like $validInput['smtpServerIp'] can also be of type string[]; however, parameter $ip of EndelWar\Spammer\Validat...validateInputServerIP() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

25
        $this->validateInputServerIP(/** @scrutinizer ignore-type */ $validInput['smtpServerIp']);
Loading history...
26
27
        $validInput['smtpServerPort'] = $this->input->getOption('port');
28
        $this->validateInputServerPort($validInput['smtpServerPort']);
29
30
        $validInput['corpusPath'] = $this->validateInputCorpusPath($this->input->getOption('set-corpus-path'));
0 ignored issues
show
Bug introduced by
It seems like $this->input->getOption('set-corpus-path') can also be of type string[]; however, parameter $path of EndelWar\Spammer\Validat...lidateInputCorpusPath() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

30
        $validInput['corpusPath'] = $this->validateInputCorpusPath(/** @scrutinizer ignore-type */ $this->input->getOption('set-corpus-path'));
Loading history...
31
32
        $validInput['count'] = false;
33
        $validInput['locale'] = false;
34
        if (false === $validInput['corpusPath']) {
35
            $validInput['count'] = (int)$this->input->getOption('count');
36
            $this->validateInputCount($validInput['count']);
37
38
            $validInput['locale'] = $this->input->getOption('locale');
39
        }
40
41
        $validInput['to'] = $this->validateInputToFrom($this->input->getOption('to'));
42
43
        $validInput['from'] = $this->validateInputToFrom($this->input->getOption('from'));
44
45
        if (false !== $validInput['corpusPath'] && (false !== $validInput['count'] || false !== $validInput['locale'])) {
46
            throw new \InvalidArgumentException('Cannot set both corpus path and count or locale');
47
        }
48
49
        return $validInput;
50
    }
51
52
    /**
53
     * @param string $ip
54
     * @throws \InvalidArgumentException
55
     */
56
    private function validateInputServerIP($ip)
57
    {
58
        if (!filter_var($ip, FILTER_VALIDATE_IP)) {
59
            throw new \InvalidArgumentException('server option is not a valid IP');
60
        }
61
    }
62
63
    /**
64
     * @param int $port
65
     * @throws \InvalidArgumentException
66
     */
67
    private function validateInputServerPort($port)
68
    {
69
        if (!is_numeric($port) || ($port < 0 || $port > 65535)) {
0 ignored issues
show
introduced by
The condition is_numeric($port) is always true.
Loading history...
70
            throw new \InvalidArgumentException('server port must be a number between 0 and 65536');
71
        }
72
    }
73
74
    /**
75
     * @param int $count
76
     * @throws \InvalidArgumentException
77
     */
78
    private function validateInputCount($count)
79
    {
80
        if ($count < 1) {
81
            throw new \InvalidArgumentException('count must be equal or greater than 1 (you want to send email, right?)');
82
        }
83
    }
84
85
    /**
86
     * @param $string
87
     * @throws \InvalidArgumentException
88
     * @return string
89
     */
90
    private function validateInputToFrom($string): string
91
    {
92
        if (null === $string) {
93
            return '';
94
        }
95
96
        $string = strtolower($string);
97
        if (strpos($string, '@') !== false) {
98
            if (filter_var($string, FILTER_VALIDATE_EMAIL)) {
99
                return $string;
100
            }
101
        } elseif ($this->isValidDomain($string)) {
102
            return $string;
103
        }
104
105
        throw new \InvalidArgumentException('To and from must be a valid email address or a FQDN');
106
    }
107
108
    /**
109
     * @param $domain
110
     * @return bool|mixed
111
     */
112
    private function isValidDomain($domain)
113
    {
114
        $domain = strtolower($domain);
115
        $regex = "/^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}$/";
116
117
        return preg_match($regex, $domain);
118
    }
119
120
    /**
121
     * @param string $path
122
     * @throws \InvalidArgumentException
123
     * @return bool|string
124
     */
125
    private function validateInputCorpusPath($path)
126
    {
127
        if (null === $path) {
0 ignored issues
show
introduced by
The condition null === $path is always false.
Loading history...
128
            return false;
129
        }
130
131
        $path = realpath($path);
132
        if (!is_dir($path)) {
133
            throw new \InvalidArgumentException('Set a valid directory as corpus path');
134
        }
135
136
        return $path;
137
    }
138
}
139