Passed
Push — dev ( 3596bc...b20a94 )
by 世昌
02:18
created

Response::getWrapper()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
namespace suda\framework;
3
4
use Exception;
5
use suda\framework\http\Cookie;
6
use suda\framework\http\Stream;
7
use suda\framework\http\stream\DataStream;
8
use suda\framework\response\MimeType;
9
use suda\framework\response\ContentWrapper;
10
use suda\framework\response\ResponseWrapper;
11
use suda\framework\http\Response as ResponseInterface;
12
13
class Response extends ResponseWrapper
14
{
15
    /**
16
     * 包装器
17
     *
18
     * @var ContentWrapper
19
     */
20
    protected $wrapper;
21
22
    /**
23
     * @var Context
24
     */
25
    private $context;
26
    
27
    /**
28
     * 响应数据
29
     *
30
     * @var Stream|string
31
     */
32
    protected $data;
33
34
35
    public function __construct(ResponseInterface $response, Context $context)
36
    {
37
        parent::__construct($response);
38
        $this->wrapper = new ContentWrapper;
39
        $this->context = $context;
40
    }
41
42
    /**
43
     * 设置类型
44
     *
45
     * @param string $extension
46
     * @return $this
47
     */
48
    public function setType(string $extension)
49
    {
50
        $this->header('content-type', MimeType::getMimeType($extension), true);
51
        return $this;
52
    }
53
54
    /**
55
     * 设置头部
56
     *
57
     * @param string $name
58
     * @param string $content
59
     * @param boolean $replace
60
     * @return $this
61
     */
62
    public function setHeader(string $name, string $content, bool $replace = false)
63
    {
64
        $this->header($name, $content, $replace);
65
        return $this;
66
    }
67
68
    /**
69
     * 设置请求内容
70
     *
71
     * @param mixed $content
72
     * @return $this
73
     */
74
    public function setContent($content)
75
    {
76
        if (is_string($content) || $content instanceof Stream) {
77
            $this->data = $content;
78
        } else {
79
            $wrapper = $this->wrapper->getWrapper($content);
80
            $this->data = $wrapper->getWrappedContent($this);
81
        }
82
        return $this;
83
    }
84
85
86
    /**
87
     * 发送内容数据
88
     *
89
     * @param array|string|Stream|null $data
90
     * @return $this
91
     */
92
    protected function sendContentLength($data)
93
    {
94
        if ($data === null) {
95
            $this->setHeader('content-length', 0);
96
        } elseif (is_array($data)) {
97
            $this->setHeader('content-length', $this->getDataLengthArray($data), true);
98
        } else {
99
            $this->setHeader('content-length', $this->getDataLengthItem($data), true);
100
        }
101
        return $this;
102
    }
103
104
    /**
105
     * 获取数据长度
106
     *
107
     * @param Stream[] $data
108
     * @return int
109
     */
110
    protected function getDataLengthArray(array $data):int
111
    {
112
        $length = 0;
113
        foreach ($data as $item) {
114
            $length += $this->getDataLengthItem($item);
115
        }
116
        return $length;
117
    }
118
119
    /**
120
     * 获取数据长度
121
     *
122
     * @param Stream|string $data
123
     * @return integer
124
     */
125
    protected function getDataLengthItem($data):int
126
    {
127
        if (is_string($data)) {
128
            return strlen($data);
129
        } else {
130
            return $data->length();
131
        }
132
    }
133
134
    /**
135
     * 设置 Cookie
136
     *
137
     * @param string $name
138
     * @param string $value
139
     * @param integer $expire
140
     * @return Cookie
141
     */
142
    public function setCookie(string $name, string $value, int $expire = 0):Cookie
143
    {
144
        $cookie = new Cookie($name, $value, $expire);
145
        $this->cookie($cookie);
146
        return $cookie;
147
    }
148
149
    /**
150
     * 直接发送数据
151
     *
152
     * @param mixed $content
153
     * @return void
154
     */
155
    public function sendContent($content = null)
156
    {
157
        if ($content !== null) {
158
            $this->setContent($content);
159
        }
160
        $this->sendContentLength($this->data);
161
        $this->send($this->data);
162
    }
163
164
165
    /**
166
     * 发送文件内容
167
     *
168
     * @param string $filename
169
     * @param integer $offset
170
     * @param integer $length
171
     * @return void
172
     * @throws Exception
173
     */
174
    public function sendFile(string $filename, int $offset = 0, int $length = null)
175
    {
176
        $this->triggerSendEvent();
177
        $data = new DataStream($filename, $offset, $length);
178
        $this->setHeader('content-length', $data->length());
179
        $this->response->sendFile($filename, $offset, $length);
180
    }
181
182
    /**
183
     * @param string $url
184
     * @param int $httpCode
185
     */
186
    public function redirect(string $url, int $httpCode = 302)
187
    {
188
        $this->triggerSendEvent();
189
        parent::redirect($url, $httpCode);
190
    }
191
192
    /**
193
     * 发送缓存的内容
194
     */
195
    public function end()
196
    {
197
        $this->sendContent($this->data);
198
    }
199
200
    /**
201
     * @param string|Stream $data
202
     */
203
    public function send($data)
204
    {
205
        $this->triggerSendEvent();
206
        parent::send($data);
207
    }
208
209
    /**
210
     * 出发发送内容事件
211
     */
212
    private function triggerSendEvent()
213
    {
214
        if ($this->isSend() === false) {
215
            $this->context->event()->exec('response::before-send', [$this]);
216
        }
217
    }
218
219
    /**
220
     * @return Context
221
     */
222
    public function getContext(): Context
223
    {
224
        return $this->context;
225
    }
226
227
    /**
228
     * @param Context $context
229
     */
230
    public function setContext(Context $context): void
231
    {
232
        $this->context = $context;
233
    }
234
235
    /**
236
     * @return ContentWrapper
237
     */
238
    public function getWrapper(): ContentWrapper
239
    {
240
        return $this->wrapper;
241
    }
242
243
    /**
244
     * @param ContentWrapper $wrapper
245
     */
246
    public function setWrapper(ContentWrapper $wrapper)
247
    {
248
        $this->wrapper = $wrapper;
249
    }
250
}
251