Passed
Push — feature/optimize ( d24737...e2ac6c )
by Fu
03:38
created

Response::handleNotFound()   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 3
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: frowhy
5
 * Date: 2017/8/1
6
 * Time: 下午3:25
7
 */
8
9
namespace Modules\Core\Supports;
10
11
use Asm89\Stack\CorsService;
12
use Illuminate\Contracts\Support\{
13
    Arrayable, Renderable, Responsable
14
};
15
use Illuminate\Http\Response as BaseResponse;
16
use Illuminate\Support\{
17
    Arr,
18
    Str
19
};
20
use Modules\Core\Contracts\Support\Boolable;
21
use Modules\Core\Enums\StatusCodeEnum;
22
use Modules\Core\Traits\Supports\ResponseHandle;
23
use SoapBox\Formatter\Formatter;
24
25
class Response implements Responsable, Arrayable, Renderable, Boolable
26
{
27
    protected $response;
28
    protected $statusCode;
29
30
    use ResponseHandle;
31
32
    public function __construct(array $response)
33
    {
34
        $this->response = $response;
35
        $this->statusCode = $response['meta']['status_code'] ?? StatusCodeEnum::HTTP_OK;
36
37
        return $this;
38
    }
39
40
    private static function parseMeta($data)
41
    {
42
        if ((is_array($data) && Arr::has($data, 'meta'))) {
43
            return Arr::get($data, 'meta');
44
        } else {
45
            return [];
46
        }
47
    }
48
49
    private static function parseData($data)
50
    {
51
        if (is_array($data) && Arr::has($data, 'data')) {
52
            return Arr::get($data, 'data');
53
        } else {
54
            if (is_string($data) && json_decode($data)) {
55
                return json_decode($data);
56
            } else {
57
                return $data;
58
            }
59
        }
60
    }
61
62
    /**
63
     * 格式化响应
64
     *
65
     * @return \Illuminate\Http\Response
66
     */
67
    private function format(): BaseResponse
68
    {
69
        list($response, $statusCode) = [$this->response, $this->statusCode];
70
        $formatter = Formatter::make($response, Formatter::ARR);
71
        $format = self::param('output_format') ?? (config('core.api.output_format'));
72
        $statusCode =
73
            (self::param('status_sync') ?? config('core.api.status_sync')) ? $statusCode : StatusCodeEnum::HTTP_OK;
74
        if (in_array($format, ['application/xml', 'xml'])) {
75
            $response = response($formatter->toXml(), $statusCode, ['Content-Type' => 'application/xml']);
76
        } elseif (in_array($format, ['application/x-yaml', 'yaml'])) {
77
            $response = response($formatter->toYaml(), $statusCode, ['Content-Type' => 'application/x-yaml']);
78
        } elseif (in_array($format, ['text/csv', 'csv'])) {
79
            $response = response($formatter->toCsv(), $statusCode, ['Content-Type' => 'text/csv']);
80
        } elseif (in_array($format, ['application/json', 'json'])) {
81
            $response = response($formatter->toJson(), $statusCode, ['Content-Type' => 'application/json']);
82
        } else {
83
            $response = response($response, $statusCode);
84
        }
85
        return $response;
86
    }
87
88
    /**
89
     * s
90
     * 允许跨域请求
91
     *
92
     * @param \Illuminate\Http\Response $response
93
     * @return \Illuminate\Http\Response
94
     */
95
    private function cors(BaseResponse $response): BaseResponse
96
    {
97
        if (config('core.api.cors_enabled')) {
98
            /** @var CorsService $cors */
99
            $cors = app(CorsService::class);
100
            $request = request();
101
102
            if ($cors->isCorsRequest(request())) {
103
                if (!$response->headers->has('Access-Control-Allow-Origin')) {
104
                    $response = $cors->addActualRequestHeaders($response, $request);
105
                }
106
            }
107
        }
108
109
        return $response;
110
    }
111
112
    /**
113
     * Create an HTTP response that represents the object.
114
     *
115
     * @param \Illuminate\Http\Request $request
116
     *
117
     * @return \Illuminate\Http\Response
118
     */
119
    public function toResponse($request): BaseResponse
120
    {
121
        return $this->render();
122
    }
123
124
    /**
125
     * Get the instance as an array.
126
     *
127
     * @return array
128
     */
129
    public function toArray(): array
130
    {
131
        return (array) Arr::get($this->response, 'data');
132
    }
133
134
    /**
135
     * Get the evaluated contents of the object.
136
     *
137
     * @return \Illuminate\Http\Response
138
     */
139
    public function render(): BaseResponse
140
    {
141
        return $this->cors($this->format());
142
    }
143
144
    /**
145
     * Get the true and false of the instance.
146
     *
147
     * @return bool
148
     */
149
    public function toBool(): bool
150
    {
151
        return Str::startsWith(Arr::get($this->response, 'meta.status_code'), 2);
152
    }
153
154
    /**
155
     * Return an response.
156
     *
157
     * @param array $response
158
     *
159
     * @return Response
160
     */
161
    private static function call(array $response): Response
162
    {
163
        return new self($response);
164
    }
165
166
    public static function param(string $param)
167
    {
168
        $request = app('Illuminate\Http\Request');
169
        if ($request->has($param)) {
170
            return $request->get($param);
171
        } else {
172
            $header_param = Str::title(Str::kebab(Str::studly($param)));
173
            if ($request->hasHeader($header_param)) {
174
                return $request->header($header_param);
175
            }
176
        }
177
178
        return null;
179
    }
180
181
    /**
182
     * Response Handle
183
     *
184
     * @param int $statusCode
185
     * @param $data
186
     * @param bool $overwrite
187
     * @param string|null $message
188
     * @return \Modules\Core\Supports\Response
189
     */
190
    public static function handle(
191
        int $statusCode,
192
        $data = null,
193
        bool $overwrite = false,
194
        string $message = null
195
    ): Response {
196
        if (($overwrite && is_array($data))) {
197
            $_data = $data;
198
        } else {
199
            $_data = self::parseData($data);
200
        }
201
202
        $_meta = self::parseMeta($data);
203
204
        $_meta = Arr::prepend($_meta, $statusCode, 'status_code');
205
        $_meta = Arr::prepend($_meta, $message ?? StatusCodeEnum::__($statusCode), 'message');
206
207
        Arr::set($response, 'meta', $_meta);
208
209
        if (!is_null($_data)) {
210
            Arr::set($response, 'data', $_data);
211
        }
212
213
        return self::call($response);
214
    }
215
}
216