• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Entropyphp / EntropyPHP / 16649712814

31 Jul 2025 01:01PM UTC coverage: 67.599% (-4.7%) from 72.319%
16649712814

push

github

willy68
First commit

0 of 41 new or added lines in 1 file covered. (0.0%)

290 of 429 relevant lines covered (67.6%)

2.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Middleware/BodyParserMiddleware.php
1
<?php
2

3
/**
4
 * CakePHP(tm): Rapid Development Framework (http://cakephp.org)
5
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
6
 *
7
 * Licensed under The MIT License
8
 * For full copyright and license information, please see the LICENSE.txt
9
 * Redistributions of files must retain the above copyright notice.
10
 *
11
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
12
 * @link          http://cakephp.org CakePHP(tm) Project
13
 * @since         3.6.0
14
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
15
 */
16

17
declare(strict_types=1);
18

19
namespace Entropy\Middleware;
20

21
use Closure;
22
use InvalidArgumentException;
23
use Psr\Http\Message\ResponseInterface;
24
use Psr\Http\Message\ServerRequestInterface;
25
use Psr\Http\Server\MiddlewareInterface;
26
use Psr\Http\Server\RequestHandlerInterface;
27

28
/**
29
 * Parse encoded request body data.
30
 *
31
 * Enables JSON request payloads to be parsed into the request's
32
 * You must provide CSRF protection and validation.
33
 *
34
 * You can also add your own request body parsers using the `addParser()` method.
35
 */
36
class BodyParserMiddleware implements MiddlewareInterface
37
{
38
    /**
39
     * Registered Parsers
40
     *
41
     * @var Closure[]
42
     */
43
    protected array $parsers = [];
44

45
    /**
46
     * The HTTP methods to parse data on.
47
     *
48
     * @var string[]
49
     */
50
    protected array $methods = ['PUT', 'POST', 'PATCH', 'DELETE'];
51

52
    /**
53
     * Constructor
54
     *
55
     * ### Options
56
     *
57
     * - `json` Set false to disable JSON body parsing.
58
     *   Handling requires more care than JSON does.
59
     * - `methods` The HTTP methods to parse on. Defaults to PUT, POST, PATCH DELETE.
60
     *
61
     * @param array $options The options to use. See above.
62
     */
NEW
63
    public function __construct(array $options = [])
×
64
    {
NEW
65
        $options += ['json' => true, 'methods' => $this->methods];
×
NEW
66
        if ($options['json']) {
×
NEW
67
            $this->addParser(
×
NEW
68
                ['application/json', 'text/json'],
×
NEW
69
                Closure::fromCallable([$this, 'decodeJson'])
×
NEW
70
            );
×
71
        }
NEW
72
        if ($options['methods']) {
×
NEW
73
            $this->setMethods($options['methods']);
×
74
        }
75
    }
76

77
    /**
78
     * Set the HTTP methods to parse request bodies on.
79
     *
80
     * @param string[] $methods The methods to parse data on.
81
     * @return $this
82
     */
NEW
83
    public function setMethods(array $methods): static
×
84
    {
NEW
85
        $this->methods = $methods;
×
86

NEW
87
        return $this;
×
88
    }
89

90
    /**
91
     * Get the HTTP methods to parse request bodies on.
92
     *
93
     * @return string[]
94
     */
NEW
95
    public function getMethods(): array
×
96
    {
NEW
97
        return $this->methods;
×
98
    }
99

100
    /**
101
     * Add a parser.
102
     *
103
     * Map a set of content-type header values to be parsed by the $parser.
104
     *
105
     * ### Example
106
     *
107
     * A naive CSV request body parser could be built like so:
108
     *
109
     * ```
110
     * $parser->addParser(['text/csv'], function ($body) {
111
     *   return str_getcsv($body);
112
     * });
113
     * ```
114
     *
115
     * @param string[] $types An array of content-type header values to match. eg. application/json
116
     * @param Closure $parser The parser function. Must return an array of data to be inserted
117
     *   into the request.
118
     * @return $this
119
     */
NEW
120
    public function addParser(array $types, Closure $parser): static
×
121
    {
NEW
122
        foreach ($types as $type) {
×
NEW
123
            $type = strtolower($type);
×
NEW
124
            $this->parsers[$type] = $parser;
×
125
        }
126

NEW
127
        return $this;
×
128
    }
129

130
    /**
131
     * Get the current parsers
132
     *
133
     * @return Closure[]
134
     */
NEW
135
    public function getParsers(): array
×
136
    {
NEW
137
        return $this->parsers;
×
138
    }
139

140
    /**
141
     * Apply the middleware.
142
     *
143
     * Will modify the request adding a parsed body if the content-type is known.
144
     *
145
     * @param ServerRequestInterface $request The request.
146
     * @param RequestHandlerInterface $handler The request handler.
147
     * @return ResponseInterface A response.
148
     */
NEW
149
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
×
150
    {
NEW
151
        if (!in_array($request->getMethod(), $this->methods, true)) {
×
NEW
152
            return $handler->handle($request);
×
153
        }
NEW
154
        [$type] = explode(';', $request->getHeaderLine('Content-Type'));
×
NEW
155
        $type = strtolower($type);
×
NEW
156
        if (!isset($this->parsers[$type])) {
×
NEW
157
            return $handler->handle($request);
×
158
        }
159

NEW
160
        $parser = $this->parsers[$type];
×
NEW
161
        $result = $parser($request->getBody()->getContents());
×
NEW
162
        if (!is_array($result)) {
×
NEW
163
            throw new InvalidArgumentException();
×
164
        }
NEW
165
        $request = $request->withParsedBody($result);
×
166

NEW
167
        return $handler->handle($request);
×
168
    }
169

170
    /**
171
     * Decode JSON into an array.
172
     *
173
     * @param string $body The request body to decode
174
     * @return array|null
175
     */
NEW
176
    protected function decodeJson(string $body): ?array
×
177
    {
NEW
178
        if ($body === '') {
×
NEW
179
            return [];
×
180
        }
NEW
181
        $decoded = json_decode($body, true);
×
NEW
182
        if (json_last_error() === JSON_ERROR_NONE) {
×
NEW
183
            return (array)$decoded;
×
184
        }
185

NEW
186
        return null;
×
187
    }
188
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc