Passed
Push — developer ( e5c82c...bcac4b )
by Mariusz
32:34
created

Response::emitText()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
cc 4
nc 4
nop 0
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;
0 ignored issues
show
Coding Style introduced by
$EMIT_RAW does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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.

Loading history...
18
19
	/**
20
	 * Emit response wrapper as json string.
21
	 */
22
	public static $EMIT_JSON = 1;
0 ignored issues
show
Coding Style introduced by
$EMIT_JSON does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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.

Loading history...
23
24
	/**
25
	 * Emit response wrapper as html string.
26
	 */
27
	public static $EMIT_HTML = 2;
0 ignored issues
show
Coding Style introduced by
$EMIT_HTML does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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.

Loading history...
28
29
	/**
30
	 * Emit response wrapper as string/jsonstring.
31
	 */
32
	public static $EMIT_JSONTEXT = 3;
0 ignored issues
show
Coding Style introduced by
$EMIT_JSONTEXT does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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.

Loading history...
33
34
	/**
35
	 * Emit response wrapper as padded-json.
36
	 */
37
	public static $EMIT_JSONP = 4;
0 ignored issues
show
Coding Style introduced by
$EMIT_JSONP does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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.

Loading history...
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
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $code a bit more specific; maybe use integer.
Loading history...
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;
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $message. This often makes code more readable.
Loading history...
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
0 ignored issues
show
Documentation introduced by
Should the type for parameter $e not be \Throwable?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
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