1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Response class. |
4
|
|
|
* |
5
|
|
|
* @copyright YetiForce Sp. z o.o. |
6
|
|
|
* @license YetiForce Public License 3.0 (licenses/LicenseEN.txt or yetiforce.com) |
7
|
|
|
* @author Radosław Skrzypczak <[email protected]> |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace App; |
11
|
|
|
|
12
|
|
|
class Response |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* Emit response wrapper as raw string. |
16
|
|
|
*/ |
17
|
|
|
public static $EMIT_RAW = 0; |
|
|
|
|
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Emit response wrapper as json string. |
21
|
|
|
*/ |
22
|
|
|
public static $EMIT_JSON = 1; |
|
|
|
|
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Emit response wrapper as html string. |
26
|
|
|
*/ |
27
|
|
|
public static $EMIT_HTML = 2; |
|
|
|
|
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Emit response wrapper as string/jsonstring. |
31
|
|
|
*/ |
32
|
|
|
public static $EMIT_JSONTEXT = 3; |
|
|
|
|
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Emit response wrapper as padded-json. |
36
|
|
|
*/ |
37
|
|
|
public static $EMIT_JSONP = 4; |
|
|
|
|
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Error data. |
41
|
|
|
*/ |
42
|
|
|
private $error; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Result data. |
46
|
|
|
*/ |
47
|
|
|
private $result; |
48
|
|
|
|
49
|
|
|
// Active emit type |
50
|
|
|
private $emitType = 1; // EMIT_JSON |
51
|
|
|
|
52
|
|
|
// JSONP padding |
53
|
|
|
private $emitJSONPFn = false; // for EMIT_JSONP |
54
|
|
|
|
55
|
|
|
// List of response headers |
56
|
|
|
private $headers = []; |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Set headers to send. |
60
|
|
|
* |
61
|
|
|
* @param mixed $header |
62
|
|
|
*/ |
63
|
|
|
public function setHeader($header) |
64
|
|
|
{ |
65
|
|
|
$this->headers[] = $header; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Set padding method name for JSONP emit type. |
70
|
|
|
* |
71
|
|
|
* @param mixed $fn |
72
|
|
|
*/ |
73
|
|
|
public function setEmitJSONP($fn) |
74
|
|
|
{ |
75
|
|
|
$this->setEmitType(self::$EMIT_JSONP); |
76
|
|
|
$this->emitJSONPFn = $fn; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Set emit type. |
81
|
|
|
* |
82
|
|
|
* @param mixed $type |
83
|
|
|
*/ |
84
|
|
|
public function setEmitType($type) |
85
|
|
|
{ |
86
|
|
|
$this->emitType = $type; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Is emit type configured to JSON? |
91
|
|
|
*/ |
92
|
|
|
public function isJSON() |
93
|
|
|
{ |
94
|
|
|
return $this->emitType == self::$EMIT_JSON; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Get the error data. |
99
|
|
|
*/ |
100
|
|
|
public function getError() |
101
|
|
|
{ |
102
|
|
|
return $this->error; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Set error data to send. |
107
|
|
|
* |
108
|
|
|
* @param mixed $code |
|
|
|
|
109
|
|
|
* @param mixed|null $message |
110
|
|
|
* @param mixed $trace |
111
|
|
|
* |
112
|
|
|
* @return void |
113
|
|
|
*/ |
114
|
|
|
public function setError($code = 500, $message = null, $trace = false): void |
115
|
|
|
{ |
116
|
|
|
if (null === $message) { |
117
|
|
|
$message = $code; |
|
|
|
|
118
|
|
|
} |
119
|
|
|
$error = ['code' => $code, 'message' => $message, 'trace' => $trace]; |
120
|
|
|
$this->error = $error; |
121
|
|
|
if (is_numeric($code)) { |
122
|
|
|
http_response_code($code); |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Set exception error to send. |
128
|
|
|
* |
129
|
|
|
* @param Throwable $e |
|
|
|
|
130
|
|
|
* |
131
|
|
|
* @return void |
132
|
|
|
*/ |
133
|
|
|
public function setException(\Throwable $e): void |
134
|
|
|
{ |
135
|
|
|
$reasonPhrase = \App\Language::translate('ERR_OCCURRED_ERROR'); |
136
|
|
|
$message = $e->getMessage(); |
137
|
|
|
$error = [ |
138
|
|
|
'message' => $reasonPhrase, |
139
|
|
|
'code' => $e->getCode(), |
140
|
|
|
]; |
141
|
|
|
if (\Conf\Config::$displayTrackingException) { |
142
|
|
|
$error['message'] = (Config::get('displayDetailsException') || 0 === strpos($message, 'ERR_')) ? $message : \App\Language::translate('ERR_OCCURRED_ERROR'); |
143
|
|
|
} |
144
|
|
|
if (\Conf\Config::$displayTrackingException) { |
145
|
|
|
$error['trace'] = str_replace(ROOT_DIRECTORY . \DIRECTORY_SEPARATOR, '', $e->getTraceAsString()); |
146
|
|
|
} |
147
|
|
|
$this->setHeader($_SERVER['SERVER_PROTOCOL'] . ' ' . $e->getCode() . ' ' . str_ireplace(["\r\n", "\r", "\n"], ' ', $reasonPhrase)); |
148
|
|
|
$this->error = $error; |
149
|
|
|
http_response_code($e->getCode()); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Check the presence of error data. |
154
|
|
|
*/ |
155
|
|
|
public function hasError() |
156
|
|
|
{ |
157
|
|
|
return null !== $this->error; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* Update the result data. |
162
|
|
|
* |
163
|
|
|
* @param mixed $key |
164
|
|
|
* @param mixed $value |
165
|
|
|
*/ |
166
|
|
|
public function updateResult($key, $value) |
167
|
|
|
{ |
168
|
|
|
$this->result[$key] = $value; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Get the result data. |
173
|
|
|
*/ |
174
|
|
|
public function getResult() |
175
|
|
|
{ |
176
|
|
|
return $this->result; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Set the result data. |
181
|
|
|
* |
182
|
|
|
* @param mixed $result |
183
|
|
|
*/ |
184
|
|
|
public function setResult($result) |
185
|
|
|
{ |
186
|
|
|
$this->result = $result; |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* Send response to client. |
191
|
|
|
*/ |
192
|
|
|
public function emit() |
193
|
|
|
{ |
194
|
|
|
$contentTypeSent = false; |
195
|
|
|
foreach ($this->headers as $header) { |
196
|
|
|
if (!$contentTypeSent && 0 === stripos($header, 'content-type')) { |
197
|
|
|
$contentTypeSent = true; |
198
|
|
|
} |
199
|
|
|
header($header); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
// Set right charset (UTF-8) to avoid IE complaining about c00ce56e error |
203
|
|
|
if ($this->emitType == self::$EMIT_JSON) { |
204
|
|
|
if (!$contentTypeSent) { |
205
|
|
|
header('Content-type: text/json; charset=UTF-8'); |
206
|
|
|
} |
207
|
|
|
$this->emitJSON(); |
208
|
|
|
} elseif ($this->emitType == self::$EMIT_JSONTEXT) { |
209
|
|
|
if (!$contentTypeSent) { |
210
|
|
|
header('Content-type: text/json; charset=UTF-8'); |
211
|
|
|
} |
212
|
|
|
$this->emitText(); |
213
|
|
|
} elseif ($this->emitType == self::$EMIT_HTML) { |
214
|
|
|
if (!$contentTypeSent) { |
215
|
|
|
header('Content-type: text/html; charset=UTF-8'); |
216
|
|
|
} |
217
|
|
|
$this->emitRaw(); |
218
|
|
|
} elseif ($this->emitType == self::$EMIT_RAW) { |
219
|
|
|
if (!$contentTypeSent) { |
220
|
|
|
header('Content-type: text/plain; charset=UTF-8'); |
221
|
|
|
} |
222
|
|
|
$this->emitRaw(); |
223
|
|
|
} elseif ($this->emitType == self::$EMIT_JSONP) { |
224
|
|
|
if (!$contentTypeSent) { |
225
|
|
|
header('Content-type: application/javascript; charset=UTF-8'); |
226
|
|
|
} |
227
|
|
|
echo $this->emitJSONPFn . '('; |
228
|
|
|
$this->emitJSON(); |
229
|
|
|
echo ')'; |
230
|
|
|
} |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* Emit response wrapper as JSONString. |
235
|
|
|
*/ |
236
|
|
|
protected function emitJSON() |
237
|
|
|
{ |
238
|
|
|
echo Json::encode($this->prepareResponse()); |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Prepare the response wrapper. |
243
|
|
|
*/ |
244
|
|
|
protected function prepareResponse() |
245
|
|
|
{ |
246
|
|
|
$response = []; |
247
|
|
|
if (null !== $this->error) { |
248
|
|
|
$response['success'] = false; |
249
|
|
|
$response['error'] = $this->error; |
250
|
|
|
} else { |
251
|
|
|
$response['success'] = true; |
252
|
|
|
$response['result'] = $this->result; |
253
|
|
|
} |
254
|
|
|
return $response; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Emit response wrapper as String/JSONString. |
259
|
|
|
*/ |
260
|
|
|
protected function emitText() |
261
|
|
|
{ |
262
|
|
|
if (null === $this->result) { |
263
|
|
|
if (\is_string($this->error)) { |
264
|
|
|
echo $this->error; |
265
|
|
|
} else { |
266
|
|
|
echo Json::encode($this->prepareResponse()); |
267
|
|
|
} |
268
|
|
|
} else { |
269
|
|
|
if (\is_string($this->result)) { |
270
|
|
|
echo $this->result; |
271
|
|
|
} else { |
272
|
|
|
echo Json::encode($this->prepareResponse()); |
273
|
|
|
} |
274
|
|
|
} |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Emit response wrapper as String. |
279
|
|
|
*/ |
280
|
|
|
protected function emitRaw() |
281
|
|
|
{ |
282
|
|
|
if (null === $this->result) { |
283
|
|
|
echo (\is_string($this->error)) ? $this->error : var_export($this->error, true); |
284
|
|
|
} |
285
|
|
|
echo $this->result; |
286
|
|
|
} |
287
|
|
|
} |
288
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.