Completed
Push — master ( 588b5e...a331b6 )
by Matthew
04:08
created

ServerRequest::create()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 30
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 30
ccs 23
cts 23
cp 1
rs 8.8571
cc 3
eloc 22
nc 2
nop 2
crap 3
1
<?php
2
namespace Fyuze\Http\Message;
3
4
use Psr\Http\Message\ServerRequestInterface;
5
use Psr\Http\Message\UriInterface;
6
7
class ServerRequest extends Request implements ServerRequestInterface
8
{
9
10
    /**
11
     * @var
12
     */
13
    protected $serverParams;
14
15
    /**
16
     * @var
17
     */
18
    protected $cookieParams;
19
20
    /**
21
     * @var
22
     */
23
    protected $queryParams;
24
25
    /**
26
     * @var
27
     */
28
    protected $uploadedFiles;
29
30
    /**
31
     * @var
32
     */
33
    protected $parsedBody;
34
35
    /**
36
     * @var
37
     */
38
    protected $attributes = [];
39
40
    /**
41
     * ServerRequest constructor.
42
     * @param string $uri
43
     * @param string $method
44
     * @param array $server
45
     */
46 27
    public function __construct($uri = '/', $method = 'GET', $server = [])
0 ignored issues
show
Unused Code introduced by
The parameter $method is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
47
    {
48 27
        $this->uri = ($uri instanceof UriInterface) ? $uri : new Uri($uri);
49 27
        $this->serverParams = $server;
50 27
    }
51
52
    /**
53
     * @param string $uri
54
     * @param string $method
55
     * @return static
56
     */
57 16
    public static function create($uri = '/', $method = 'GET')
0 ignored issues
show
Coding Style introduced by
create uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
create uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
create uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
create uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
create uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
58
    {
59 16
        $server = array_replace([
60 16
            'SERVER_NAME' => 'localhost',
61 16
            'SERVER_PORT' => 80,
62 16
            'HTTP_HOST' => 'localhost',
63 16
            'HTTP_USER_AGENT' => 'Fyuze/0.1.x',
64 16
            'REMOTE_ADDR' => '127.0.0.1',
65 16
            'SERVER_PROTOCOL' => 'HTTP/1.1',
66 16
            'REQUEST_TIME' => time(),
67 16
            'REQUEST_URI' => (string)$uri,
68
            'REQUEST_METHOD' => $method
69 16
        ], $_SERVER);
70
71
72
        /** @todo need a better way to handle this */
73 16
        if (mb_stripos($uri, '/index.php') === 0) {
74 3
            $uri = str_replace('/index.php', '', $uri);
75 3
        }
76
77 16
        return (new static(
78 16
            ($uri === '') ? '/' : $uri, $method, '', $server, [], []
0 ignored issues
show
Documentation introduced by
'' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Unused Code introduced by
The call to ServerRequest::__construct() has too many arguments starting with $server.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
79 16
        ))
80 16
            ->withMethod($method)
81 16
            ->withRequestTarget($uri)
82 16
            ->withCookieParams($_COOKIE)
83 16
            ->withQueryParams($_GET)
84 16
            ->withParsedBody($_POST)
85 16
            ->withUploadedFiles($_FILES);
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     *
91
     * @return array
92
     */
93 1
    public function getServerParams()
94
    {
95 1
        return $this->serverParams;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     *
101
     * @return array
102
     */
103 1
    public function getCookieParams()
104
    {
105 1
        return $this->cookieParams;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     *
111
     * @param array $cookies Array of key/value pairs representing cookies.
112
     * @return self
113
     */
114 17
    public function withCookieParams(array $cookies)
115
    {
116 17
        return $this->_clone('cookieParams', $cookies);
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     *
122
     * @return array
123
     */
124 3
    public function getQueryParams()
125
    {
126 3
        return $this->queryParams;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     *
132
     * @param array $query Array of query string arguments, typically from
133
     *     $_GET.
134
     * @return self
135
     */
136 17
    public function withQueryParams(array $query)
137
    {
138 17
        return $this->_clone('queryParams', $query);
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     *
144
     * @return array An array tree of UploadedFileInterface instances; an empty
145
     *     array MUST be returned if no data is present.
146
     */
147 1
    public function getUploadedFiles()
148
    {
149 1
        $this->uploadedFiles;
150 1
    }
151
152
    /**
153
     * {@inheritdoc}
154
     *
155
     * @param array An array tree of UploadedFileInterface instances.
156
     * @return self
157
     * @throws \InvalidArgumentException if an invalid structure is provided.
158
     */
159 17
    public function withUploadedFiles(array $uploadedFiles)
160
    {
161 17
        return $this->_clone('uploadedFiles', $uploadedFiles);
162
    }
163
164
    /**
165
     * {@inheritdoc}
166
     *
167
     * @return null|array|object The deserialized body parameters, if any.
168
     *     These will typically be an array or object.
169
     */
170 1
    public function getParsedBody()
171
    {
172 1
        return $this->parsedBody;
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     *
178
     * @param null|array|object $data The deserialized body data. This will
179
     *     typically be in an array or object.
180
     * @return self
181
     * @throws \InvalidArgumentException if an unsupported argument type is
182
     *     provided.
183
     */
184 17
    public function withParsedBody($data)
185
    {
186 17
        return $this->_clone('parsedBody', $data);
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     *
192
     * @return array Attributes derived from the request.
193
     */
194 1
    public function getAttributes()
195
    {
196 1
        return $this->attributes;
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     *
202
     * @see getAttributes()
203
     * @param string $name The attribute name.
204
     * @param mixed $default Default value to return if the attribute does not exist.
205
     * @return mixed
206
     */
207 1
    public function getAttribute($name, $default = null)
208
    {
209 1
        if (array_key_exists($name, $this->attributes) === false) {
210 1
            return $default;
211
        }
212
213 1
        return $this->attributes[$name];
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     *
219
     * @see getAttributes()
220
     * @param string $name The attribute name.
221
     * @param mixed $value The value of the attribute.
222
     * @return self
223
     */
224 1
    public function withAttribute($name, $value)
225
    {
226 1
        $instance = clone($this);
227 1
        $instance->attributes[$name] = $value;
228 1
        return $instance;
229
    }
230
231
    /**
232
     * {@inheritdoc}
233
     *
234
     * @see getAttributes()
235
     * @param string $name The attribute name.
236
     * @return self
237
     */
238 1
    public function withoutAttribute($name)
239
    {
240 1
        if (array_key_exists($name, $this->attributes) === false) {
241 1
            return clone $this;
242
        }
243
244 1
        $instance = clone $this;
245 1
        unset($instance->attributes[$name]);
246 1
        return $instance;
247
    }
248
}
249