RequestHelper   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 20
eloc 58
c 3
b 0
f 0
dl 0
loc 152
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A explode() 0 10 3
A removeSuffix() 0 13 4
A getRemoteAddress() 0 11 3
A format() 0 15 4
A parse() 0 17 3
A split() 0 5 1
A sanitizeString() 0 44 1
A transform() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WebServCo\Framework\Helpers;
6
7
final class RequestHelper
8
{
9
    /**
10
    * @return array<int,string>
11
    */
12
    public static function explode(string $string): array
13
    {
14
        if (false !== \strpos($string, '?')) {
15
            return \explode('?', $string, 2);
16
        }
17
18
        if (false !== \strpos($string, '&')) {
19
            return \explode('&', $string, 2);
20
        }
21
        return [$string, ''];
22
    }
23
24
    /**
25
    * @return array<string, string|null>
26
    */
27
    public static function format(string $string): array
28
    {
29
        $data = [];
30
        $parts = self::split($string);
31
        $num = \count($parts);
32
        for ($position = 0; $position < $num; $position += 2) {
33
            if (!\array_key_exists($position, $parts)) {
34
                // Prevents "Notice: Undefined offset: 2." in request like "&lang=/'/"
35
                continue;
36
            }
37
            $data[$parts[$position]] = $position === $num - 1
38
                ? null
39
                : $parts[$position + 1];
40
        }
41
        return $data;
42
    }
43
44
    public static function getRemoteAddress(): string
45
    {
46
        if (PhpHelper::isCli()) {
47
            return \gethostbyname(\php_uname('n'));
48
        }
49
50
        if (\array_key_exists('REMOTE_ADDR', $_SERVER)) {
51
            return self::sanitizeString($_SERVER['REMOTE_ADDR']);
52
        }
53
54
        return '';
55
    }
56
57
    /**
58
    * @param array<int,string> $suffixes
59
    * @return array<int,string>
60
    */
61
    public static function parse(string $string, string $path, string $filename, array $suffixes): array
62
    {
63
        $pathLen = \strlen($path);
64
        if (0 === \strncasecmp($path, $string, $pathLen)) {
65
            $string = \substr($string, $pathLen);
66
        }
67
        $filenameLen = \strlen($filename);
68
        if (0 === \strncasecmp($filename, $string, $filenameLen)) {
69
            $string = \substr($string, $filenameLen);
70
        }
71
        [$target, $query] = self::explode($string);
72
        [$target, $suffix] = self::removeSuffix(
73
            self::transform($target),
74
            $suffixes,
75
        );
76
        $query = self::transform($query);
77
        return [$target, $query, $suffix];
78
    }
79
80
    /**
81
    * @param array<int,string> $suffixes
82
    * @return array<int,string>
83
    */
84
    public static function removeSuffix(string $string, array $suffixes = []): array
85
    {
86
        if ($suffixes) {
87
            $stringRev = \strrev($string);
88
            foreach ($suffixes as $suffix) {
89
                $suffixRev = \strrev($suffix);
90
                $suffixLen = \strlen($suffix);
91
                if (0 === \strncasecmp($suffixRev, $stringRev, $suffixLen)) {
92
                    return [\strrev(\substr($stringRev, $suffixLen)), $suffix];
93
                }
94
            }
95
        }
96
        return [$string, ''];
97
    }
98
99
    public static function sanitizeString(string $string): string
100
    {
101
        // Strip tags, optionally strip or encode special characters.
102
        /**
103
         * FILTER_SANITIZE_STRING is deprecated since PHP 8.1.
104
         *
105
         * $string = \filter_var($string, \FILTER_SANITIZE_STRING);
106
         * Use a polyfill instead.
107
         * Source: https://stackoverflow.com/a/69207369
108
         */
109
        $string = \preg_replace('/\x00|<[^>]*>?/', '', $string);
110
        $string = \str_replace(["'", '"'], ['&#39;', '&#34;'], $string);
111
112
        $unwanted = [
113
            "`",
114
            //"'",
115
            //'"',
116
            "\b",
117
            "\n",
118
            "\r",
119
            "\t",
120
            //"?",
121
            //"!",
122
            //"~",
123
            //"#",
124
            //"^",
125
            //"&",
126
            //"*",
127
            //"=",
128
            //"[",
129
            //"]",
130
            //":",
131
            //";",
132
            //",",
133
            //"|",
134
            "\\",
135
            //"{",
136
            //"}",
137
            //"(",
138
            //")",
139
            "\$",
140
        ];
141
        $string = \str_replace($unwanted, '', (string) $string);
142
        return $string;
143
    }
144
145
    /**
146
    * @return array<int,string>
147
    */
148
    public static function split(string $string): array
149
    {
150
        $parts = \explode('/', $string);
151
        $parts = \array_map('urldecode', $parts);
152
        return \array_diff($parts, ['']);
153
    }
154
155
    public static function transform(string $string): string
156
    {
157
        $string = \str_replace(['?', '&', '=', '//'], ['', '/', '/', '/0/'], $string);
158
        return \trim($string, ' /');
159
    }
160
}
161