ValidatorHelper::getAbsolutePathValidator()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 1
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TheAentMachine\Prompt\Helper;
4
5
use GuzzleHttp\Exception\RequestException;
6
use Symfony\Component\Console\Exception\InvalidArgumentException;
7
use TheAentMachine\Registry\RegistryClient;
8
use function Safe\sprintf;
9
10
final class ValidatorHelper
11
{
12
    private const DEFAULT_ERROR_MESSAGE = 'Value "%s" is invalid';
13
14
    /**
15
     * @param callable|null $v1
16
     * @param callable|null $v2
17
     * @return callable
18
     */
19
    public static function merge(?callable $v1, ?callable $v2): callable
20
    {
21
        return function (?string $response) use ($v1, $v2) {
22
            if (!empty($v1)) {
23
                $response = $v1($response);
24
            }
25
            if (!empty($v2)) {
26
                $response = $v2($response);
27
            }
28
            return $response;
29
        };
30
    }
31
32
    /**
33
     * @param callable $func
34
     * @param null|string $errorMessage
35
     * @return callable
36
     */
37
    public static function getFuncShouldReturnTrueValidator(callable $func, ?string $errorMessage = null): callable
38
    {
39
        return function (string $response) use ($func, $errorMessage) {
40
            $response = \trim($response);
41
            $message = sprintf((!empty($errorMessage) ? $errorMessage : self::DEFAULT_ERROR_MESSAGE), $response);
42
            if (!$func($response)) {
43
                throw new InvalidArgumentException($message);
44
            }
45
            return $response;
46
        };
47
    }
48
49
    /**
50
     * @param callable $func
51
     * @param null|string $errorMessage
52
     * @return callable
53
     */
54
    public static function getFuncShouldNotReturnTrueValidator(callable $func, ?string $errorMessage = null): callable
55
    {
56
        return function (string $response) use ($func, $errorMessage) {
57
            $response = \trim($response);
58
            $message = sprintf((!empty($errorMessage) ? $errorMessage : self::DEFAULT_ERROR_MESSAGE), $response);
59
            if ($func($response)) {
60
                throw new InvalidArgumentException($message);
61
            }
62
            return $response;
63
        };
64
    }
65
66
    /**
67
     * @param null|string $errorMessage
68
     * @return callable
69
     */
70
    public static function getAlphaValidator(?string $errorMessage = null): callable
71
    {
72
        return function (string $response) use ($errorMessage) {
73
            $response = \trim($response);
74
            $pattern = '/^[a-zA-Z0-9]+$/';
75
            if (!preg_match($pattern, $response)) {
76
                $message = sprintf((!empty($errorMessage) ? $errorMessage : self::DEFAULT_ERROR_MESSAGE . '. Hint: only alphanumerical characters are allowed'), $response);
77
                throw new InvalidArgumentException($message);
78
            }
79
            return $response;
80
        };
81
    }
82
83
    /**
84
     * @param string[] $additionalCharacters
85
     * @param null|string $errorMessage
86
     * @return callable
87
     */
88
    public static function getAlphaWithAdditionalCharactersValidator(array $additionalCharacters, ?string $errorMessage = null): callable
89
    {
90
        return function (string $response) use ($additionalCharacters, $errorMessage) {
91
            $response = \trim($response);
92
            $pattern = '/^[a-zA-Z0-9';
93
            foreach ($additionalCharacters as $character) {
94
                $pattern .= $character;
95
            }
96
            $pattern .= ']+$/';
97
            if (!preg_match($pattern, $response)) {
98
                $message = sprintf((!empty($errorMessage) ? $errorMessage : self::DEFAULT_ERROR_MESSAGE . '. Hint: only alphanumerical characters and "%s" characters are allowed'), $response, \implode(', ', $additionalCharacters));
99
                throw new InvalidArgumentException($message);
100
            }
101
            return $response;
102
        };
103
    }
104
105
    /**
106
     * @param null|string $errorMessage
107
     * @return callable
108
     */
109
    public static function getDomainNameValidator(?string $errorMessage = null): callable
110
    {
111
        return function (string $response) use ($errorMessage) {
112
            $response = trim($response);
113
            if (!preg_match('/^(?!:\/\/)([a-zA-Z0-9-_]+\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+\.[a-zA-Z]{2,11}?$/im', $response)) {
114
                $message = sprintf((!empty($errorMessage) ? $errorMessage : self::DEFAULT_ERROR_MESSAGE . '. Hint: the domain name must not start with "http(s)://".'), $response);
115
                throw new InvalidArgumentException($message);
116
            }
117
            return $response;
118
        };
119
    }
120
121
    /**
122
     * @param null|string $errorMessage
123
     * @return callable
124
     */
125
    public static function getDomainNameWithPortValidator(?string $errorMessage = null): callable
126
    {
127
        return function (string $response) use ($errorMessage) {
128
            $response = trim($response);
129
            if (!preg_match('/^(?!:\/\/)([a-zA-Z0-9-_]+\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+\.[a-zA-Z]{2,11}?(:\d*)?$/im', $response)) {
130
                $message = sprintf((!empty($errorMessage) ? $errorMessage : self::DEFAULT_ERROR_MESSAGE . '. Hint: the domain name must not start with "http(s)://".'), $response);
131
                throw new InvalidArgumentException($message);
132
            }
133
            return $response;
134
        };
135
    }
136
137
    /**
138
     * @return callable
139
     */
140
    public static function getDockerImageWithoutTagValidator(): callable
141
    {
142
        return function (string $response) {
143
            $response = \trim($response);
144
            if (!preg_match('/^[a-z0-9]+\/([a-z0-9]+(?:[._-][a-z0-9]+)*)$/', $response)) {
145
                $message = sprintf(self::DEFAULT_ERROR_MESSAGE . '. Hint: the docker image should be of type "username/repository"', $response);
146
                throw new InvalidArgumentException($message);
147
            }
148
            try {
149
                $registryClient = new RegistryClient();
150
                $registryClient->getImageTagsOnDockerHub($response);
151
            } catch (RequestException $e) {
152
                throw new InvalidArgumentException("The image \"$response\" does not seem to exist on Docker Hub. Try again!", $e->getCode(), $e);
153
            }
154
            return $response;
155
        };
156
    }
157
158
    /**
159
     * @param null|string $errorMessage
160
     * @return callable
161
     */
162
    public static function getIPv4Validator(?string $errorMessage = null): callable
163
    {
164
        return function (string $response) use ($errorMessage) {
165
            $response = \trim($response);
166
            if (!preg_match('/^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/', $response)) {
167
                $message = sprintf((!empty($errorMessage) ? $errorMessage : self::DEFAULT_ERROR_MESSAGE), $response);
168
                throw new InvalidArgumentException($message);
169
            }
170
            return $response;
171
        };
172
    }
173
174
    /**
175
     * @param null|string $errorMessage
176
     * @return callable
177
     */
178
    public static function getAbsolutePathValidator(?string $errorMessage = null): callable
179
    {
180
        return function (string $response) use ($errorMessage) {
181
            $response = \trim($response);
182
            if (!preg_match('/^[\'"]?(?:\/[^\/\n]+)*[\'"]?$/', $response)) {
183
                $message = sprintf((!empty($errorMessage) ? $errorMessage : self::DEFAULT_ERROR_MESSAGE . '". Hint: path has to be absolute without trailing "/".'), $response);
184
                throw new InvalidArgumentException($message);
185
            }
186
            return $response;
187
        };
188
    }
189
}
190