Passed
Push — master ( 4e8fd3...86d204 )
by Radu
12:37
created

RequestProcessTrait::processHttp()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 42
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 29
c 1
b 0
f 0
dl 0
loc 42
rs 8.8337
cc 6
nc 6
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WebServCo\Framework\Traits;
6
7
use WebServCo\Framework\Http\Method;
8
9
trait RequestProcessTrait
10
{
11
    abstract public function clearData(): bool;
12
13
    /**
14
     * @param mixed $key Can be an array, a string,
15
     *                          or a special formatted string
16
     *                          (eg 'i18n/lang').
17
     * @param mixed $value The value to be stored.
18
     * @return bool True on success and false on failure.
19
     */
20
    abstract public function setData($key, $value): bool;
21
22
    /**
23
    * @param mixed $key Can be an array, a string,
24
    *                          or a special formatted string
25
    *                          (eg 'i18n/lang').
26
    * @param mixed $defaultValue
27
    * @return mixed
28
    */
29
    abstract public function setting($key, $defaultValue = null);
30
31
    /**
32
    * Data value can be another array, for example _SERVER in CLI ("argv" is an array)
33
    * Important: only first level is sanitized.
34
    *
35
    * @param array<string,array<int,string>|string> $data
36
    * @return array<string,array<int,string>|string>
37
    */
38
    public function sanitize(array $data): array
39
    {
40
        foreach ($data as $key => $value) {
41
            if (\is_string($value)) {
42
                // Sanitize only first level (prevents "argv" from being sanitized)
43
                $value = \WebServCo\Framework\Helpers\RequestHelper::sanitizeString($value);
44
            }
45
            $data[$key] = $value;
46
        }
47
        return $data;
48
    }
49
50
    /**
51
    * @param array<string,mixed> $server
52
    * @param array<string,string> $post
53
    */
54
    protected function init(array $server, array $post = []): bool
55
    {
56
        $this->server = $this->sanitize($server);
0 ignored issues
show
Bug Best Practice introduced by
The property server does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
57
58
        $this->setBody();
59
        $this->setMethod();
60
        $this->setFilename();
61
        $this->setPath();
62
63
        $this->process();
64
65
        switch ($this->method) {
66
            case Method::GET:
67
            case Method::HEAD:
68
                break;
69
            case Method::POST:
70
                $this->processPost($post);
71
                break;
72
        }
73
        if ($this->setting('clear_globals', false)) {
74
            $this->clearGlobals();
75
        }
76
        return true;
77
    }
78
79
    protected function setBody(): bool
80
    {
81
        $this->body = (string) \file_get_contents('php://input');
0 ignored issues
show
Bug Best Practice introduced by
The property body does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
82
        return true;
83
    }
84
85
    protected function setMethod(): bool
86
    {
87
        if (
88
            empty($this->server['REQUEST_METHOD']) ||
89
            !\in_array(
90
                $this->server['REQUEST_METHOD'],
91
                Method::getSupported(),
92
                true,
93
            )
94
        ) {
95
            return false;
96
        }
97
        $this->method = $this->server['REQUEST_METHOD'];
0 ignored issues
show
Bug Best Practice introduced by
The property method does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
98
        return true;
99
    }
100
101
    protected function setFilename(): bool
102
    {
103
        if (empty($this->server['SCRIPT_NAME'])) {
104
            return false;
105
        }
106
        $this->filename = \basename($this->server['SCRIPT_NAME']);
0 ignored issues
show
Bug Best Practice introduced by
The property filename does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
107
        return true;
108
    }
109
110
    protected function setPath(): bool
111
    {
112
        if (empty($this->server['SCRIPT_NAME'])) {
113
            return false;
114
        }
115
116
        $this->path = \rtrim(
0 ignored issues
show
Bug Best Practice introduced by
The property path does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
117
            \str_replace(
118
                $this->filename,
119
                '',
120
                $this->server['SCRIPT_NAME'],
121
            ),
122
            \DIRECTORY_SEPARATOR,
123
        );
124
125
        return true;
126
    }
127
128
    protected function clearGlobals(): bool
129
    {
130
        if (!empty($_GET)) {
131
            foreach ($_GET as $k => $v) {
132
                unset($_REQUEST[$k]);
133
            }
134
135
            $_GET = [];
136
        }
137
138
        if (!empty($_POST)) {
139
            $_POST = [];
140
        }
141
        return true;
142
    }
143
144
    /**
145
    * @param array<string,string> $post
146
    */
147
    protected function processPost(array $post = []): bool
148
    {
149
        $this->clearData();
150
        foreach ($post as $k => $v) {
151
            $this->setData(\WebServCo\Framework\Helpers\RequestHelper::sanitizeString($k), $v);
152
        }
153
        return true;
154
    }
155
156
    protected function process(): bool
157
    {
158
        if (\WebServCo\Framework\Helpers\PhpHelper::isCli()) {
159
            return $this->processCli();
160
        }
161
162
        return $this->processHttp();
163
    }
164
165
    protected function processCli(): bool
166
    {
167
        if (isset($this->server['argv'][1])) {
168
            $this->target = $this->server['argv'][1];
0 ignored issues
show
Bug Best Practice introduced by
The property target does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
169
        }
170
        if (isset($this->server['argv'][2])) {
171
            foreach ($this->server['argv'] as $k => $v) {
172
                if (\in_array($k, [0, 1], true)) {
173
                    continue;
174
                }
175
                $this->args[] = \WebServCo\Framework\Helpers\RequestHelper::sanitizeString($v);
0 ignored issues
show
Bug Best Practice introduced by
The property args does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
176
            }
177
        }
178
        return true;
179
    }
180
181
    protected function processHttp(): bool
182
    {
183
        $string = null;
184
        switch (true) {
185
            case isset($this->server['REDIRECT_URL']):
186
                /**
187
                 * Specific situation:
188
                 * - rewrite is done in an external website,
189
                 * and current project is used a subfolder (symlink) of the main website.
190
                 * In that case the `REQUEST_URI` will contain the source (left part of the rewrite)
191
                 * and `REDIRECT_URL` will contain the actual target path (right part of the rewrite).
192
                 * So this needs to be before the `REQUEST_URI` check.
193
                 */
194
                $string = $this->server['REDIRECT_URL'];
195
                break;
196
            case isset($this->server['REQUEST_URI']):
197
                $string = $this->server['REQUEST_URI'];
198
                break;
199
            case isset($this->server['PATH_INFO']):
200
                $string = $this->server['PATH_INFO'];
201
                break;
202
            case isset($this->server['ORIG_PATH_INFO']):
203
                $string = $this->server['ORIG_PATH_INFO'];
204
                break;
205
            case !empty($this->server['QUERY_STRING']):
206
                $string = $this->server['ORIG_PATH_INFO'];
207
                break;
208
            default:
209
                break;
210
        }
211
        [$target, $queryString, $suffix] = \WebServCo\Framework\Helpers\RequestHelper::parse(
212
            $string,
213
            $this->path,
214
            $this->filename,
215
            $this->setting('suffixes', []),
216
        );
217
        $this->target = \WebServCo\Framework\Helpers\RequestHelper::sanitizeString(\urldecode($target));
0 ignored issues
show
Bug Best Practice introduced by
The property target does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
218
        $this->query = \WebServCo\Framework\Helpers\RequestHelper::format(
0 ignored issues
show
Bug Best Practice introduced by
The property query does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
219
            \WebServCo\Framework\Helpers\RequestHelper::sanitizeString($queryString),
220
        );
221
        $this->suffix = $suffix;
0 ignored issues
show
Bug Best Practice introduced by
The property suffix does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
222
        return true;
223
    }
224
}
225