Completed
Push — master ( 356d79...201886 )
by Changwan
03:54
created

ResponseFactory::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 3
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Wandu\Http\Factory;
3
4
use Closure;
5
use Generator;
6
use InvalidArgumentException;
7
use JsonSerializable;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\StreamInterface;
10
use Psr\Http\Message\UriInterface;
11
use RuntimeException;
12
use Traversable;
13
use Wandu\Http\Psr\Response;
14
use Wandu\Http\Psr\Stream\IteratorStream;
15
use Wandu\Http\Psr\Stream\ResourceStream;
16
use Wandu\Http\Psr\Stream\StringStream;
17
18
class ResponseFactory
19
{
20
    /** @var \Wandu\Http\Factory\ResponseFactory */
21
    public static $instance;
22
23
    /**
24
     * @param mixed $contents
25
     * @param int $status
26
     * @param array $headers
27
     * @return \Psr\Http\Message\ResponseInterface
28
     */
29 41
    public function auto($contents = null, $status = 200, array $headers = [])
30
    {
31 41
        if ($contents instanceof ResponseInterface) {
32 7
            return $contents;
33
        }
34 40
        if ($contents instanceof StreamInterface || !isset($contents)) {
35 2
            return $this->create($contents, $status, $headers);
36
        }
37 39
        while (is_callable($contents)) {
38 3
            $nextResponse = call_user_func($contents);
39 3
            $contents = $nextResponse;
40
        }
41
        // int, float, boolean, string
42 39
        if (is_scalar($contents)) {
43 34
            if ($contents === true) {
44 2
                $contents = 'true';
45 33
            } elseif ($contents === false) {
46 2
                $contents = 'false';
47
            }
48 34
            return $this->string((string)$contents, $status, $headers);
49
        }
50 6
        if (is_array($contents)) {
51 2
            return $this->json($contents, $status, $headers);
52
        }
53 5
        if (is_object($contents)) {
54 4
            if ($contents instanceof Traversable) {
55 2
                return $this->iterator($contents, $status, $headers);
56 2
            } elseif (method_exists($contents, '__toString')) {
57 1
                return $this->string($contents, $status, $headers);
0 ignored issues
show
Documentation introduced by
$contents is of type object, but the function expects a string.

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...
58
            } else {
59 2
                return $this->json($contents, $status, $headers);
60
            }
61
        }
62 2
        if (is_resource($contents)) {
63 2
            return $this->resource($contents, $status, $headers);
64
        }
65
        throw new RuntimeException('unsupported type of response.');
66
    }
67
    
68
    /**
69
     * @param \Psr\Http\Message\StreamInterface $stream
70
     * @param int $status
71
     * @param array $headers
72
     * @return \Psr\Http\Message\ResponseInterface
73
     */
74 57
    public function create(StreamInterface $stream = null, $status = 200, array $headers = [])
75
    {
76 57
        return new Response($status, $stream, $headers, '', '1.1');
77
    }
78
79
    /**
80
     * @param \Closure $area
81
     * @param int $status
82
     * @param array $headers
83
     * @return \Psr\Http\Message\ResponseInterface
84
     */
85 2
    public function capture(Closure $area, $status = 200, array $headers = [])
86
    {
87 2
        ob_start();
88 2
        $area();
89 2
        $contents = ob_get_contents();
90 2
        ob_end_clean();
91 2
        return $this->string($contents, $status, $headers);
92
    }
93
94
    /**
95
     * @param string $contents
96
     * @param int $status
97
     * @param array $headers
98
     * @return \Psr\Http\Message\ResponseInterface
99
     */
100 43
    public function string(string $contents, $status = 200, array $headers = [])
101
    {
102 43
        return $this->create(new StringStream($contents), $status, $headers);
103
    }
104
    
105
    /**
106
     * @param mixed $data
107
     * @param int $status
108
     * @param array $headers
109
     * @return \Psr\Http\Message\ResponseInterface
110
     */
111 5
    public function json($data = [], $status = 200, array $headers = [])
112
    {
113 5
        return $this->create(new StringStream(json_encode($data)), $status, $headers)
114 5
            ->withHeader('Content-Type', 'application/json');
115
    }
116
117
    /**
118
     * @param string $file
119
     * @param string $name
120
     * @param array $headers
121
     * @return \Psr\Http\Message\ResponseInterface
122
     */
123
    public function download($file, $name = null, array $headers = [])
124
    {
125
        if (!is_file($file)) {
126
            new InvalidArgumentException("\"{$file}\" is not a file.");
127
        }
128
        return $this->create(new StringStream(file_get_contents($file)), 200, $headers)
129
            ->withHeader('Pragma', 'public')
130
            ->withHeader('Expires', '0')
131
            ->withHeader('Content-Type', 'application/octet-stream')
132
            ->withHeader(
133
                'Content-Disposition',
134
                'attachment; filename=' . (isset($name) ? $name : basename($file))
135
            )
136
            ->withHeader('Content-Transfer-Encoding', 'binary')
137
            ->withHeader('Content-Length', filesize($file) . '');
138
    }
139
140
    /**
141
     * @param \Psr\Http\Message\UriInterface|string $path
142
     * @param int $status
143
     * @param array $headers
144
     * @return \Psr\Http\Message\ResponseInterface
145
     */
146 2
    public function redirect($path, $status = 302, $headers = [])
147
    {
148 2
        if ($path instanceof UriInterface) {
149
            $path = $path->__toString();
150
        }
151 2
        return $this->create(null, $status, $headers)
152 2
            ->withStatus($status)
153 2
            ->withAddedHeader('Location', $path);
154
    }
155
156
    /**
157
     * @deprecated use iterator
158
     * 
159
     * @param \Generator $generator
160
     * @param int $status
161
     * @param array $headers
162
     * @return \Psr\Http\Message\ResponseInterface
163
     */
164
    public function generator(Generator $generator, $status = 200, array $headers = [])
165
    {
166
        return $this->create(new Iteratorstream($generator), $status, $headers);
167
    }
168
169
    /**
170
     * @param \Traversable $iterator
171
     * @param int $status
172
     * @param array $headers
173
     * @return \Psr\Http\Message\ResponseInterface
174
     */
175 4
    public function iterator(Traversable $iterator, $status = 200, array $headers = [])
176
    {
177 4
        return $this->create(new IteratorStream($iterator), $status, $headers);
178
    }
179
180
    /**
181
     * @param resource $resource
182
     * @param int $status
183
     * @param array $headers
184
     * @return \Psr\Http\Message\ResponseInterface
185
     */
186 2
    public function resource($resource, $status = 200, array $headers = [])
187
    {
188 2
        return $this->create(new ResourceStream($resource), $status, $headers);
189
    }
190
}
191