Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
94.59% |
70 / 74 |
|
90.00% |
9 / 10 |
CRAP | |
0.00% |
0 / 1 |
RequestHandler | |
94.59% |
70 / 74 |
|
90.00% |
9 / 10 |
30.14 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
prepare | |
100.00% |
20 / 20 |
|
100.00% |
1 / 1 |
3 | |||
setRequest | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getRequest | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
request | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasRequest | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
prepareHeaderAsString | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
prepareAsString | |
78.95% |
15 / 19 |
|
0.00% |
0 / 1 |
9.76 | |||
log | |
100.00% |
21 / 21 |
|
100.00% |
1 / 1 |
9 | |||
getRequestTimestamp | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Debug\Handler; |
15 | |
16 | use Pop\Http\Server\Request; |
17 | use Pop\Http\Uri; |
18 | use Pop\Log\Logger; |
19 | use Pop\Session\Session; |
20 | |
21 | /** |
22 | * Debug request handler class |
23 | * |
24 | * @category Pop |
25 | * @package Pop\Debug |
26 | * @author Nick Sagona, III <dev@nolainteractive.com> |
27 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
28 | * @license http://www.popphp.org/license New BSD License |
29 | * @version 2.2.0 |
30 | */ |
31 | class RequestHandler extends AbstractHandler |
32 | { |
33 | |
34 | /** |
35 | * Request |
36 | * @var ?Request |
37 | */ |
38 | protected ?Request $request = null; |
39 | |
40 | /** |
41 | * Request timestamp |
42 | * @var ?float |
43 | */ |
44 | protected ?float $requestTimestamp = null; |
45 | |
46 | /** |
47 | * Constructor |
48 | * |
49 | * Instantiate a request handler object |
50 | * |
51 | * @param ?Request $request |
52 | * @param ?string $name |
53 | */ |
54 | public function __construct(?Request $request = null, ?string $name = null, ?Logger $logger = null, array $loggingParams = []) |
55 | { |
56 | parent::__construct($name, $logger, $loggingParams); |
57 | if ($request === null) { |
58 | $request = new Request(new Uri()); |
59 | } |
60 | $this->setRequest($request); |
61 | |
62 | $this->requestTimestamp = microtime(true); |
63 | } |
64 | |
65 | /** |
66 | * Prepare handler data for storage |
67 | * |
68 | * @return array |
69 | */ |
70 | public function prepare(): array |
71 | { |
72 | Session::getInstance(); |
73 | |
74 | return [ |
75 | 'uri' => $this->request->getUri()->getUri(), |
76 | 'method' => $this->request->getMethod(), |
77 | 'headers' => $this->request->getHeaders(), |
78 | 'server' => $this->request->getServer(), |
79 | 'env' => $this->request->getEnv(), |
80 | 'get' => $this->request->getQuery(), |
81 | 'post' => $this->request->getPost(), |
82 | 'put' => $this->request->getPut(), |
83 | 'patch' => $this->request->getPatch(), |
84 | 'delete' => $this->request->getDelete(), |
85 | 'files' => $this->request->getFiles(), |
86 | 'cookie' => (isset($_COOKIE)) ? $_COOKIE : [], |
87 | 'session' => (isset($_SESSION)) ? $_SESSION : [], |
88 | 'raw' => $this->request->getRawData(), |
89 | 'parsed' => $this->request->getParsedData(), |
90 | 'timestamp' => number_format($this->requestTimestamp, 5, '.', ''), |
91 | 'elapsed' => number_format((microtime(true) - $this->requestTimestamp), 5, '.', '') |
92 | ]; |
93 | } |
94 | |
95 | /** |
96 | * Set request |
97 | * |
98 | * @param Request $request |
99 | * @return RequestHandler |
100 | */ |
101 | public function setRequest(Request $request): RequestHandler |
102 | { |
103 | $this->request = $request; |
104 | return $this; |
105 | } |
106 | |
107 | /** |
108 | * Get request |
109 | * |
110 | * @return Request |
111 | */ |
112 | public function getRequest(): Request |
113 | { |
114 | return $this->request; |
115 | } |
116 | |
117 | /** |
118 | * Get request (alias) |
119 | * |
120 | * @return Request |
121 | */ |
122 | public function request(): Request |
123 | { |
124 | return $this->request; |
125 | } |
126 | |
127 | /** |
128 | * Has request |
129 | * |
130 | * @return bool |
131 | */ |
132 | public function hasRequest(): bool |
133 | { |
134 | return ($this->request !== null); |
135 | } |
136 | |
137 | /** |
138 | * Prepare header string |
139 | * |
140 | * @return string |
141 | */ |
142 | public function prepareHeaderAsString(): string |
143 | { |
144 | $string = ((!empty($this->name)) ? $this->name . ' ' : '') . 'Request Handler'; |
145 | $string .= PHP_EOL . str_repeat('=', strlen($string)) . PHP_EOL; |
146 | |
147 | return $string; |
148 | } |
149 | |
150 | /** |
151 | * Prepare handler data as string |
152 | * |
153 | * @return string |
154 | */ |
155 | public function prepareAsString(): string |
156 | { |
157 | $string = ''; |
158 | if (!empty($this->request->getUri()) && !empty($this->request->getUri()->getUri())) { |
159 | $requestData = $this->prepare(); |
160 | |
161 | $string .= $this->request->getMethod() . ' ' . $this->request->getUri()->getUri() . ' [' . |
162 | $requestData['timestamp'] . ' (' . $requestData['elapsed'] . ')]' . PHP_EOL . PHP_EOL; |
163 | |
164 | foreach ($requestData as $key => $data) { |
165 | if (is_array($data) && (count($data) > 0)) { |
166 | $string .= str_replace('DATA', '', strtoupper($key)) . ":" . PHP_EOL; |
167 | $string .= str_repeat('-', (strlen(str_replace('DATA', '', strtoupper($key))) + 1)) . PHP_EOL; |
168 | foreach ($data as $k => $v) { |
169 | $string .= $k . ": " . ((is_array($v)) ? http_build_query($v) : $v) . PHP_EOL; |
170 | } |
171 | $string .= PHP_EOL; |
172 | } |
173 | } |
174 | if (!empty($this->request->getRawData())) { |
175 | $string .= "RAW:" . PHP_EOL; |
176 | $string .= "----" . PHP_EOL; |
177 | $string .= $this->request->getRawData() . PHP_EOL; |
178 | } |
179 | } else { |
180 | $string .= "No Request URI Detected." . PHP_EOL; |
181 | } |
182 | |
183 | $string .= PHP_EOL; |
184 | |
185 | return $string; |
186 | } |
187 | |
188 | /** |
189 | * Trigger handler logging |
190 | * |
191 | * @throws Exception |
192 | * @return void |
193 | */ |
194 | public function log(): void |
195 | { |
196 | if (($this->hasLogger()) && ($this->hasLoggingParams())) { |
197 | $logLevel = $this->loggingParams['level'] ?? null; |
198 | $useContext = $this->loggingParams['context'] ?? null; |
199 | $timeLimit = $this->loggingParams['limit'] ?? null; |
200 | |
201 | if ($logLevel !== null) { |
202 | $context = []; |
203 | $requestData = $this->prepare(); |
204 | if ($timeLimit !== null) { |
205 | $elapsedTime = $requestData['elapsed']; |
206 | if ($elapsedTime >= $timeLimit) { |
207 | $this->logger->log($logLevel, 'The request \'' . $this->request->getUri()->getUri() . |
208 | '\' has exceeded the time limit of ' . $timeLimit . ' second(s) by ' . |
209 | $elapsedTime - $timeLimit . ' second(s). The request was a total of ' . $elapsedTime . ' second(s).', |
210 | $context |
211 | ); |
212 | } |
213 | } else { |
214 | $context['request'] = (($useContext !== null) && (strtolower($useContext) == 'text')) ? |
215 | $this->prepareAsString() : $this->prepare(); |
216 | |
217 | if (is_string($useContext)) { |
218 | $context['format'] = $useContext; |
219 | } |
220 | |
221 | $this->logger->log($logLevel, "The request '" . $this->request->getUri()->getUri() . "' was triggered.", $context); |
222 | } |
223 | } else { |
224 | throw new Exception('Error: The log level parameter was not set.'); |
225 | } |
226 | } |
227 | } |
228 | |
229 | /** |
230 | * Get request timestamp |
231 | * |
232 | * @return float |
233 | */ |
234 | public function getRequestTimestamp(): float |
235 | { |
236 | return $this->requestTimestamp; |
237 | } |
238 | |
239 | } |