UriFilter::isNonStandardPort()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Furious\Psr7\Filter;
6
7
use Furious\Psr7\Exception\InvalidArgumentException;
8
use Furious\Psr7\Exception\InvalidPortException;
9
use function is_string;
10
use function preg_replace_callback;
11
use function rawurlencode;
12
13
final class UriFilter
14
{
15
    private const SCENARIOS = [
16
        'http' => 80,
17
        'https' => 443
18
    ];
19
    private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
20
    private const CHAR_SUB_DELIMITERS = '!\$&\'\(\)\*\+,;=';
21
22
    public function filterPort(string $scheme, ?int $port): ?int
23
    {
24
        if (null === $port) {
25
            return null;
26
        }
27
28
        $port = (int) $port;
29
        if (0 > $port or 0xffff < $port) {
30
            throw new InvalidPortException(sprintf('Invalid port: %d. Must be between 0 and 65535', $port));
31
        }
32
33
        return $this->isNonStandardPort($scheme, $port) ? $port : null;
34
    }
35
36
    public function filterPath($path): string
37
    {
38
        if (!is_string($path)) {
39
            throw new InvalidArgumentException('Path must be a string');
40
        }
41
42
        return preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMITERS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawUrlEncodeMatchZero'], $path);
43
    }
44
45
    public function filterQuery($string): string
46
    {
47
        if (!is_string($string)) {
48
            throw new InvalidPortException('Query must be a string');
49
        }
50
51
        return preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMITERS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawUrlEncodeMatchZero'], $string);
52
    }
53
54
    public function filterFragment($string): string
55
    {
56
        if (!is_string($string)) {
57
            throw new InvalidPortException('Fragment must be a string');
58
        }
59
60
        return preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMITERS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawUrlEncodeMatchZero'], $string);
61
    }
62
63
    private function isNonStandardPort(string $scheme, int $port): bool
64
    {
65
        return
66
            !isset(self::SCENARIOS[$scheme]) or
67
            self::SCENARIOS[$scheme] !== $port;
68
    }
69
70
    private function rawUrlEncodeMatchZero(array $match): string
71
    {
72
        return rawurlencode($match[0]);
73
    }
74
}