Failed Conditions
Push — master ( 508499...365050 )
by Arnold
07:49
created

Connector::createPsrRequest()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
1
<?php
2
3
namespace Jasny\Codeception;
4
5
use Psr\Http\Message\ResponseInterface;
6
use Psr\Http\Message\UploadedFileInterface;
7
use Jasny\HttpMessage\Response;
8
use Jasny\HttpMessage\ServerRequest;
9
use Jasny\HttpMessage\UploadedFile;
10
use Jasny\HttpMessage\Uri;
11
use Jasny\HttpMessage\Stream;
12
use Jasny\Router;
13
use Symfony\Component\BrowserKit\Client;
14
use Symfony\Component\BrowserKit\Request as BrowserKitRequest;
15
use Symfony\Component\BrowserKit\Response as BrowserKitResponse;
16
17
/**
18
 * Codeception connector for Jasny\MVC
19
 */
20
class Connector extends Client
21
{
22
    /**
23
     * @var Router
24
     */
25
    protected $router;
26
    
27
    /**
28
     * @var false
29
     */
30
    protected $useGlobalEnvironment = false;
31
    
32
    
33
    /**
34
     * Set the router
35
     * 
36
     * @param Router $router
37
     * @param string $legacy
0 ignored issues
show
Bug introduced by
There is no parameter named $legacy. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
38
     */
39
    public function setRouter(Router $router)
40
    {
41
        $this->router = $router;
42
    }
43
    
44
    /**
45
     * Get the router
46
     * 
47
     * @return Router
48
     */
49
    public function getRouter()
50
    {
51
        return $this->router;
52
    }
53
    
54
    
55
    /**
56
     * Get or set the global environment flag
57
     * 
58
     * @param boolean $enable
59
     */
60
    public function useGlobalEnvironment($enable = null)
61
    {
62
        if (isset($enable)) {
63
            $this->useGlobalEnvironment = $enable;
0 ignored issues
show
Documentation Bug introduced by
The property $useGlobalEnvironment was declared of type false, but $enable is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
64
        }
65
        
66
        return $this->useGlobalEnvironment;
67
    }
68
69
70
    /**
71
     * Build a full URI from a request
72
     * 
73
     * @param BrowserKitRequest $request
74
     * @return array [Uri, queryParams]
75
     */
76
    protected function buildFullUri(BrowserKitRequest $request)
77
    {
78
        $uri = new Uri($request->getUri());
79
        parse_str($uri->getQuery(), $queryParams);
80
        
81
        if ($request->getMethod() === 'GET') {
82
            $queryParams = array_merge($queryParams, $request->getParameters());
83
            $uri = $uri->withQuery(http_build_query($queryParams));
84
        }
85
        
86
        return [$uri, $queryParams];
87
    }
88
    
89
    /**
90
     * Create a PSR-7 Server request object.
91
     * 
92
     * @return ServerRequest
93
     */
94
    protected function createPsrRequest()
95
    {
96
        $psrRequest = new ServerRequest();
97
        
98
        if ($this->useGlobalEnvironment) {
99
            $psrRequest = $psrRequest->withGlobalEnvironment(true);
100
        }
101
        
102
        return $psrRequest;
103
    }
104
    
105
    /**
106
     * Convert a codeception request to a Jasny PSR-7 server request
107
     * 
108
     * @param BrowserKitRequest $request
109
     * @return ServerRequest
110
     */
111
    protected function convertRequest(BrowserKitRequest $request)
112
    {
113
        list($uri, $queryParams) = $this->buildFullUri($request);
114
        
115
        $stream = fopen('php://temp', 'r+');
116
        fwrite($stream, $request->getContent());
117
        
118
        $psrRequest = $this->createPsrRequest()
119
            ->withServerParams($request->getServer())
120
            ->withMethod($request->getMethod())
121
            ->withRequestTarget((string)($uri->withScheme('')->withHost('')->withPort('')->withUserInfo('')))
122
            ->withCookieParams($request->getCookies())
123
            ->withUri($uri)
124
            ->withQueryParams($queryParams)
0 ignored issues
show
Bug introduced by
It seems like $queryParams can also be of type null; however, Jasny\HttpMessage\Server...rams::withQueryParams() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
125
            ->withBody(new Stream($stream))
126
            ->withUploadedFiles($this->convertUploadedFiles($request->getFiles()));
127
        
128
        if ($request->getMethod() !== 'GET' && $request->getParameters() !== null) {
129
            $psrRequest = $psrRequest->withParsedBody($request->getParameters());
130
        }
131
        
132
        return $psrRequest;
133
    }
134
    
135
    /**
136
     * Convert a Jasny PSR-7 response to a codeception response
137
     * 
138
     * @param ResponseInterface $psrResponse
139
     * @return BrowserKitResponse
140
     */
141
    protected function convertResponse(ResponseInterface $psrResponse)
142
    {
143
        return new BrowserKitResponse(
144
            (string)$psrResponse->getBody(),
145
            $psrResponse->getStatusCode(),
146
            $psrResponse->getHeaders()
147
        );
148
    }
149
    
150
    /**
151
     * Convert a list of uploaded files to a Jasny PSR-7 uploaded files
152
     * 
153
     * @param array $files
154
     * @return UploadedFile[]|array
155
     */
156
    protected function convertUploadedFiles(array $files)
157
    {
158
        $fileObjects = [];
159
        
160
        foreach ($files as $fieldName => $file) {
161
            if ($file instanceof UploadedFileInterface) {
162
                $fileObjects[$fieldName] = $file;
163
            } elseif (!isset($file['tmp_name']) && !isset($file['name'])) {
164
                $fileObjects[$fieldName] = $this->convertUploadedFiles($file);
165
            } else {
166
                $fileObjects[$fieldName] = new UploadedFile($file);
167
            }
168
        }
169
        
170
        return $fileObjects;
171
    }
172
    
173
    
174
    /**
175
     * Makes a request.
176
     * 
177
     * @param BrowserKitRequest $request
178
     * @return BrowserKitResponse
179
     */
180
    protected function doRequest($request)
181
    {
182
        if ($this->getRouter() === null) {
183
            throw new \Exception("Router not set");
184
        }
185
        
186
        $psrRequest = $this->convertRequest($request);
187
        
188
        $router = $this->getRouter();
189
        $psrResponse = $router->handle($psrRequest, new Response());
190
        
191
        return $this->convertResponse($psrResponse);
192
    }
193
}
194