Completed
Push — master ( 5f4425...3d1cfa )
by Michael
17:13 queued 10:55
created
src/ServerRequest.php 2 patches
Doc Comments   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -122,7 +122,6 @@  discard block
 block discarded – undo
122 122
 	/**
123 123
 	 * Initialize the headers.
124 124
 	 *
125
-	 * @param string $uri
126 125
 	 * @return array the headers.
127 126
 	 */
128 127
 	private function initQueryParams($serverParams)
@@ -332,7 +331,7 @@  discard block
 block discarded – undo
332 331
 	 * Checks if a content type header exists with the given content type.
333 332
 	 *
334 333
 	 * @param string $contentType
335
-	 * @return true if a content type header exists with the given content type.
334
+	 * @return boolean if a content type header exists with the given content type.
336 335
 	 */
337 336
 	private function hasContentType($contentType)
338 337
 	{
Please login to merge, or discard this patch.
Indentation   +408 added lines, -408 removed lines patch added patch discarded remove patch
@@ -22,412 +22,412 @@
 block discarded – undo
22 22
  */
23 23
 class ServerRequest extends Request implements ServerRequestInterface
24 24
 {
25
-	/** @var array The server parameters. */
26
-	private $serverParams;
27
-
28
-	/** @var array The cookie parameters. */
29
-	private $cookieParams;
30
-
31
-	/** @var array The query parameters. */
32
-	private $queryParams;
33
-
34
-	/** @var array The post parameters. */
35
-	private $postParams;
36
-
37
-	/** @var array The files parameters. */
38
-	private $filesParams;
39
-
40
-	/** @var array The uploaded files. */
41
-	private $uploadedFiles;
42
-
43
-	/** @var null|array|object The parsed body. */
44
-	private $parsedBody;
45
-
46
-	/** @var array The attributes. */
47
-	private $attributes;
48
-
49
-	/**
50
-	 * Construct a Request object with the given method, uri, version, headers & body.
51
-	 *
52
-	 * @global array $_SERVER The server parameters.
53
-	 * @global array $_COOKIE The cookie parameters.
54
-	 * @global array $_GET The query parameters.
55
-	 * @global array $_POST The post parameters.
56
-	 * @global array $_FILES The files parameters.
57
-	 *
58
-	 * @param string $method = ''
59
-	 * @param UriInterface|null $uri = null
60
-	 * @param string $version = self::DEFAULT_VERSION
61
-	 * @param array $headers = []
62
-	 * @param StreamInterface|null $body = null
63
-	 */
64
-	public function __construct($method = '', UriInterface $uri = null, $version = self::DEFAULT_VERSION, array $headers = [], StreamInterface $body = null)
65
-	{
66
-		if ($body === null) {
67
-			$body = new Stream(fopen('php://input', 'r'));
68
-		}
69
-
70
-		$this->serverParams = $_SERVER;
71
-		$this->cookieParams = $_COOKIE;
72
-		$this->queryParams = $this->initQueryParams($this->serverParams);
73
-		$this->postParams = $_POST;
74
-		$this->filesParams = $_FILES;
75
-		$this->uploadedFiles = $this->initUploadedFiles($this->filesParams);
76
-		$this->attributes = [];
77
-
78
-		parent::__construct($this->initMethod($method), $this->initUri($uri), $version, $this->initHeaders($headers), $body);
79
-	}
80
-
81
-	/**
82
-	 * Initialize the method.
83
-	 *
84
-	 * @param string $method
85
-	 * @return string the method.
86
-	 */
87
-	private function initMethod($method)
88
-	{
89
-		return $method === '' && isset($this->getServerParams()['REQUEST_METHOD']) ? $this->getServerParams()['REQUEST_METHOD'] : $method;
90
-	}
91
-
92
-	/**
93
-	 * Initialize the URI.
94
-	 *
95
-	 * @param UriInterface|null $uri
96
-	 * @return UriInterface the URI.
97
-	 */
98
-	private function initUri($uri)
99
-	{
100
-		if ($uri !== null) {
101
-			return $uri;
102
-		}
103
-
104
-		$scheme = isset($this->getServerParams()['HTTPS']) ? 'https://' : 'http://';
105
-		$host = isset($this->getServerParams()['HTTP_HOST']) ? $scheme . $this->getServerParams()['HTTP_HOST'] : '';
106
-		$path = isset($this->getServerParams()['REQUEST_URI']) ? $this->getServerParams()['REQUEST_URI'] : '';
107
-
108
-		return new URI($host . $path);
109
-	}
110
-
111
-	/**
112
-	 * Initialize the headers.
113
-	 *
114
-	 * @param array $headers
115
-	 * @return array the headers.
116
-	 */
117
-	private function initHeaders($headers)
118
-	{
119
-		return $headers ?: getallheaders();
120
-	}
121
-
122
-	/**
123
-	 * Initialize the headers.
124
-	 *
125
-	 * @param string $uri
126
-	 * @return array the headers.
127
-	 */
128
-	private function initQueryParams($serverParams)
129
-	{
130
-		if (!isset($serverParams['REQUEST_URI']) || !($query = parse_url($serverParams['REQUEST_URI'], \PHP_URL_QUERY))) {
131
-			return [];
132
-		}
133
-
134
-		parse_str($query, $result);
135
-
136
-		return $result;
137
-	}
138
-
139
-	/**
140
-	 * Initialize the uploaded files.
141
-	 *
142
-	 * @param array $files
143
-	 * @return array the uploaded files.
144
-	 */
145
-	private function initUploadedFiles(array $files)
146
-	{
147
-		$result = [];
148
-
149
-		foreach ($files as $key => $value) {
150
-			$result[$key] = $this->parseUploadedFiles($value);
151
-		}
152
-
153
-		return $result;
154
-	}
155
-
156
-	/**
157
-	 * Parse uploaded files.
158
-	 *
159
-	 * @param array $files
160
-	 * @return UploadedFile|array uploaded files.
161
-	 */
162
-	private function parseUploadedFiles($files)
163
-	{
164
-		// Empty
165
-		$first = reset($files);
166
-
167
-		// Single
168
-		if (!is_array($first)) {
169
-			return $this->parseSingleUploadedFiles($files);
170
-		}
171
-
172
-		// Multiple
173
-		if (count(array_filter(array_keys($first), 'is_string')) === 0) {
174
-			return $this->parseMultipleUploadedFiles($files);
175
-		}
176
-
177
-		// Namespace
178
-		return $this->initUploadedFiles($files);
179
-	}
180
-
181
-	/**
182
-	 * Parse single uploaded file.
183
-	 *
184
-	 * @param array $file
185
-	 * @return UploadedFile single uploaded file.
186
-	 */
187
-	private function parseSingleUploadedFiles(array $file)
188
-	{
189
-		return new UploadedFile($file['name'], $file['type'], $file['tmp_name'], $file['error'], $file['size']);
190
-	}
191
-
192
-	/**
193
-	 * Parse multiple uploaded files.
194
-	 *
195
-	 * @param array $files
196
-	 * @return UploadedFiles[] multiple uploaded files.
197
-	 */
198
-	private function parseMultipleUploadedFiles(array $files)
199
-	{
200
-		$count = count($files['name']);
201
-		$result = [];
202
-
203
-		for ($i = 0; $i < $count; $i++) {
204
-			$result[] = new UploadedFile($files['name'][$i], $files['type'][$i], $files['tmp_name'][$i], $files['error'][$i], $files['size'][$i]);
205
-		}
206
-
207
-		return $result;
208
-	}
209
-
210
-	/**
211
-	 * {@inheritdoc}
212
-	 */
213
-	public function getServerParams()
214
-	{
215
-		return $this->serverParams;
216
-	}
217
-
218
-	/**
219
-	 * {@inheritdoc}
220
-	 */
221
-	public function getCookieParams()
222
-	{
223
-		return $this->cookieParams;
224
-	}
225
-
226
-	/**
227
-	 * Set the cookie params.
228
-	 *
229
-	 * @param array $cookieParams
230
-	 * @return $this
231
-	 */
232
-	private function setCookieParams(array $cookieParams)
233
-	{
234
-		$this->cookieParams = $cookieParams;
235
-
236
-		return $this;
237
-	}
238
-
239
-	/**
240
-	 * {@inheritdoc}
241
-	 */
242
-	public function withCookieParams(array $cookieParams)
243
-	{
244
-		$result = clone $this;
245
-
246
-		return $result->setCookieParams($cookieParams);
247
-	}
248
-
249
-	/**
250
-	 * {@inheritdoc}
251
-	 */
252
-	public function getQueryParams()
253
-	{
254
-		return $this->queryParams;
255
-	}
256
-
257
-	/**
258
-	 * Set the query params.
259
-	 *
260
-	 * @param array $queryParams
261
-	 * @return $this
262
-	 */
263
-	private function setQueryParams(array $queryParams)
264
-	{
265
-		$this->queryParams = $queryParams;
266
-
267
-		return $this;
268
-	}
269
-
270
-	/**
271
-	 * {@inheritdoc}
272
-	 */
273
-	public function withQueryParams(array $queryParams)
274
-	{
275
-		$result = clone $this;
276
-
277
-		return $result->setQueryParams($queryParams);
278
-	}
279
-
280
-	/**
281
-	 * {@inheritdoc}
282
-	 */
283
-	public function getUploadedFiles()
284
-	{
285
-		return $this->uploadedFiles;
286
-	}
287
-
288
-	/**
289
-	 * Set the uploaded files.
290
-	 *
291
-	 * @param array $uploadedFiles
292
-	 * @return $this
293
-	 */
294
-	private function setUploadedFiles(array $uploadedFiles)
295
-	{
296
-		$this->uploadedFiles = $uploadedFiles;
297
-
298
-		return $this;
299
-	}
300
-
301
-	/**
302
-	 * {@inheritdoc}
303
-	 */
304
-	public function withUploadedFiles(array $uploadedFiles)
305
-	{
306
-		$result = clone $this;
307
-
308
-		return $result->setUploadedFiles($uploadedFiles);
309
-	}
310
-
311
-	/**
312
-	 * {@inheritdoc}
313
-	 */
314
-	public function getParsedBody()
315
-	{
316
-		if ($this->parsedBody !== null) {
317
-			return $this->parsedBody;
318
-		}
319
-
320
-		if ($this->getMethod() === 'POST' && ($this->hasContentType('application/x-www-form-urlencoded') || $this->hasContentType('multipart/form-data'))) {
321
-			return $this->postParams;
322
-		}
323
-
324
-		if ($this->hasContentType('application/json')) {
325
-			return json_decode((string) $this->getBody());
326
-		}
327
-
328
-		return null;
329
-	}
330
-
331
-	/**
332
-	 * Checks if a content type header exists with the given content type.
333
-	 *
334
-	 * @param string $contentType
335
-	 * @return true if a content type header exists with the given content type.
336
-	 */
337
-	private function hasContentType($contentType)
338
-	{
339
-		foreach ($this->getHeader('Content-Type') as $key => $value) {
340
-			if (substr($value, 0, strlen($contentType)) == $contentType) {
341
-				return true;
342
-			}
343
-		}
344
-
345
-		return false;
346
-	}
347
-
348
-	/**
349
-	 * Set the parsed body.
350
-	 *
351
-	 * @param null|array|object $parsedBody
352
-	 * @return $this
353
-	 */
354
-	private function setParsedBody($parsedBody)
355
-	{
356
-		$this->parsedBody = $parsedBody;
357
-
358
-		return $this;
359
-	}
360
-
361
-	/**
362
-	 * {@inheritdoc}
363
-	 */
364
-	public function withParsedBody($parsedBody)
365
-	{
366
-		$result = clone $this;
367
-
368
-		return $result->setParsedBody($parsedBody);
369
-	}
370
-
371
-	/**
372
-	 * {@inheritdoc}
373
-	 */
374
-	public function getAttributes()
375
-	{
376
-		return $this->attributes;
377
-	}
378
-
379
-	/**
380
-	 * {@inheritdoc}
381
-	 */
382
-	public function getAttribute($name, $default = null)
383
-	{
384
-		return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
385
-	}
386
-
387
-	/**
388
-	 * Set the attribute.
389
-	 *
390
-	 * @param string $name
391
-	 * @param mixed $value
392
-	 * @return $this
393
-	 */
394
-	private function setAttribute($name, $value)
395
-	{
396
-		$this->attributes[$name] = $value;
397
-
398
-		return $this;
399
-	}
400
-
401
-	/**
402
-	 * {@inheritdoc}
403
-	 */
404
-	public function withAttribute($name, $value)
405
-	{
406
-		$result = clone $this;
407
-
408
-		return $result->setAttribute($name, $value);
409
-	}
410
-
411
-	/**
412
-	 * Remove the attribute.
413
-	 *
414
-	 * @param string $name
415
-	 * @return $this
416
-	 */
417
-	private function removeAttribute($name)
418
-	{
419
-		unset($this->attributes[$name]);
420
-
421
-		return $this;
422
-	}
423
-
424
-	/**
425
-	 * {@inheritdoc}
426
-	 */
427
-	public function withoutAttribute($name)
428
-	{
429
-		$result = clone $this;
430
-
431
-		return $result->removeAttribute($name);
432
-	}
25
+    /** @var array The server parameters. */
26
+    private $serverParams;
27
+
28
+    /** @var array The cookie parameters. */
29
+    private $cookieParams;
30
+
31
+    /** @var array The query parameters. */
32
+    private $queryParams;
33
+
34
+    /** @var array The post parameters. */
35
+    private $postParams;
36
+
37
+    /** @var array The files parameters. */
38
+    private $filesParams;
39
+
40
+    /** @var array The uploaded files. */
41
+    private $uploadedFiles;
42
+
43
+    /** @var null|array|object The parsed body. */
44
+    private $parsedBody;
45
+
46
+    /** @var array The attributes. */
47
+    private $attributes;
48
+
49
+    /**
50
+     * Construct a Request object with the given method, uri, version, headers & body.
51
+     *
52
+     * @global array $_SERVER The server parameters.
53
+     * @global array $_COOKIE The cookie parameters.
54
+     * @global array $_GET The query parameters.
55
+     * @global array $_POST The post parameters.
56
+     * @global array $_FILES The files parameters.
57
+     *
58
+     * @param string $method = ''
59
+     * @param UriInterface|null $uri = null
60
+     * @param string $version = self::DEFAULT_VERSION
61
+     * @param array $headers = []
62
+     * @param StreamInterface|null $body = null
63
+     */
64
+    public function __construct($method = '', UriInterface $uri = null, $version = self::DEFAULT_VERSION, array $headers = [], StreamInterface $body = null)
65
+    {
66
+        if ($body === null) {
67
+            $body = new Stream(fopen('php://input', 'r'));
68
+        }
69
+
70
+        $this->serverParams = $_SERVER;
71
+        $this->cookieParams = $_COOKIE;
72
+        $this->queryParams = $this->initQueryParams($this->serverParams);
73
+        $this->postParams = $_POST;
74
+        $this->filesParams = $_FILES;
75
+        $this->uploadedFiles = $this->initUploadedFiles($this->filesParams);
76
+        $this->attributes = [];
77
+
78
+        parent::__construct($this->initMethod($method), $this->initUri($uri), $version, $this->initHeaders($headers), $body);
79
+    }
80
+
81
+    /**
82
+     * Initialize the method.
83
+     *
84
+     * @param string $method
85
+     * @return string the method.
86
+     */
87
+    private function initMethod($method)
88
+    {
89
+        return $method === '' && isset($this->getServerParams()['REQUEST_METHOD']) ? $this->getServerParams()['REQUEST_METHOD'] : $method;
90
+    }
91
+
92
+    /**
93
+     * Initialize the URI.
94
+     *
95
+     * @param UriInterface|null $uri
96
+     * @return UriInterface the URI.
97
+     */
98
+    private function initUri($uri)
99
+    {
100
+        if ($uri !== null) {
101
+            return $uri;
102
+        }
103
+
104
+        $scheme = isset($this->getServerParams()['HTTPS']) ? 'https://' : 'http://';
105
+        $host = isset($this->getServerParams()['HTTP_HOST']) ? $scheme . $this->getServerParams()['HTTP_HOST'] : '';
106
+        $path = isset($this->getServerParams()['REQUEST_URI']) ? $this->getServerParams()['REQUEST_URI'] : '';
107
+
108
+        return new URI($host . $path);
109
+    }
110
+
111
+    /**
112
+     * Initialize the headers.
113
+     *
114
+     * @param array $headers
115
+     * @return array the headers.
116
+     */
117
+    private function initHeaders($headers)
118
+    {
119
+        return $headers ?: getallheaders();
120
+    }
121
+
122
+    /**
123
+     * Initialize the headers.
124
+     *
125
+     * @param string $uri
126
+     * @return array the headers.
127
+     */
128
+    private function initQueryParams($serverParams)
129
+    {
130
+        if (!isset($serverParams['REQUEST_URI']) || !($query = parse_url($serverParams['REQUEST_URI'], \PHP_URL_QUERY))) {
131
+            return [];
132
+        }
133
+
134
+        parse_str($query, $result);
135
+
136
+        return $result;
137
+    }
138
+
139
+    /**
140
+     * Initialize the uploaded files.
141
+     *
142
+     * @param array $files
143
+     * @return array the uploaded files.
144
+     */
145
+    private function initUploadedFiles(array $files)
146
+    {
147
+        $result = [];
148
+
149
+        foreach ($files as $key => $value) {
150
+            $result[$key] = $this->parseUploadedFiles($value);
151
+        }
152
+
153
+        return $result;
154
+    }
155
+
156
+    /**
157
+     * Parse uploaded files.
158
+     *
159
+     * @param array $files
160
+     * @return UploadedFile|array uploaded files.
161
+     */
162
+    private function parseUploadedFiles($files)
163
+    {
164
+        // Empty
165
+        $first = reset($files);
166
+
167
+        // Single
168
+        if (!is_array($first)) {
169
+            return $this->parseSingleUploadedFiles($files);
170
+        }
171
+
172
+        // Multiple
173
+        if (count(array_filter(array_keys($first), 'is_string')) === 0) {
174
+            return $this->parseMultipleUploadedFiles($files);
175
+        }
176
+
177
+        // Namespace
178
+        return $this->initUploadedFiles($files);
179
+    }
180
+
181
+    /**
182
+     * Parse single uploaded file.
183
+     *
184
+     * @param array $file
185
+     * @return UploadedFile single uploaded file.
186
+     */
187
+    private function parseSingleUploadedFiles(array $file)
188
+    {
189
+        return new UploadedFile($file['name'], $file['type'], $file['tmp_name'], $file['error'], $file['size']);
190
+    }
191
+
192
+    /**
193
+     * Parse multiple uploaded files.
194
+     *
195
+     * @param array $files
196
+     * @return UploadedFiles[] multiple uploaded files.
197
+     */
198
+    private function parseMultipleUploadedFiles(array $files)
199
+    {
200
+        $count = count($files['name']);
201
+        $result = [];
202
+
203
+        for ($i = 0; $i < $count; $i++) {
204
+            $result[] = new UploadedFile($files['name'][$i], $files['type'][$i], $files['tmp_name'][$i], $files['error'][$i], $files['size'][$i]);
205
+        }
206
+
207
+        return $result;
208
+    }
209
+
210
+    /**
211
+     * {@inheritdoc}
212
+     */
213
+    public function getServerParams()
214
+    {
215
+        return $this->serverParams;
216
+    }
217
+
218
+    /**
219
+     * {@inheritdoc}
220
+     */
221
+    public function getCookieParams()
222
+    {
223
+        return $this->cookieParams;
224
+    }
225
+
226
+    /**
227
+     * Set the cookie params.
228
+     *
229
+     * @param array $cookieParams
230
+     * @return $this
231
+     */
232
+    private function setCookieParams(array $cookieParams)
233
+    {
234
+        $this->cookieParams = $cookieParams;
235
+
236
+        return $this;
237
+    }
238
+
239
+    /**
240
+     * {@inheritdoc}
241
+     */
242
+    public function withCookieParams(array $cookieParams)
243
+    {
244
+        $result = clone $this;
245
+
246
+        return $result->setCookieParams($cookieParams);
247
+    }
248
+
249
+    /**
250
+     * {@inheritdoc}
251
+     */
252
+    public function getQueryParams()
253
+    {
254
+        return $this->queryParams;
255
+    }
256
+
257
+    /**
258
+     * Set the query params.
259
+     *
260
+     * @param array $queryParams
261
+     * @return $this
262
+     */
263
+    private function setQueryParams(array $queryParams)
264
+    {
265
+        $this->queryParams = $queryParams;
266
+
267
+        return $this;
268
+    }
269
+
270
+    /**
271
+     * {@inheritdoc}
272
+     */
273
+    public function withQueryParams(array $queryParams)
274
+    {
275
+        $result = clone $this;
276
+
277
+        return $result->setQueryParams($queryParams);
278
+    }
279
+
280
+    /**
281
+     * {@inheritdoc}
282
+     */
283
+    public function getUploadedFiles()
284
+    {
285
+        return $this->uploadedFiles;
286
+    }
287
+
288
+    /**
289
+     * Set the uploaded files.
290
+     *
291
+     * @param array $uploadedFiles
292
+     * @return $this
293
+     */
294
+    private function setUploadedFiles(array $uploadedFiles)
295
+    {
296
+        $this->uploadedFiles = $uploadedFiles;
297
+
298
+        return $this;
299
+    }
300
+
301
+    /**
302
+     * {@inheritdoc}
303
+     */
304
+    public function withUploadedFiles(array $uploadedFiles)
305
+    {
306
+        $result = clone $this;
307
+
308
+        return $result->setUploadedFiles($uploadedFiles);
309
+    }
310
+
311
+    /**
312
+     * {@inheritdoc}
313
+     */
314
+    public function getParsedBody()
315
+    {
316
+        if ($this->parsedBody !== null) {
317
+            return $this->parsedBody;
318
+        }
319
+
320
+        if ($this->getMethod() === 'POST' && ($this->hasContentType('application/x-www-form-urlencoded') || $this->hasContentType('multipart/form-data'))) {
321
+            return $this->postParams;
322
+        }
323
+
324
+        if ($this->hasContentType('application/json')) {
325
+            return json_decode((string) $this->getBody());
326
+        }
327
+
328
+        return null;
329
+    }
330
+
331
+    /**
332
+     * Checks if a content type header exists with the given content type.
333
+     *
334
+     * @param string $contentType
335
+     * @return true if a content type header exists with the given content type.
336
+     */
337
+    private function hasContentType($contentType)
338
+    {
339
+        foreach ($this->getHeader('Content-Type') as $key => $value) {
340
+            if (substr($value, 0, strlen($contentType)) == $contentType) {
341
+                return true;
342
+            }
343
+        }
344
+
345
+        return false;
346
+    }
347
+
348
+    /**
349
+     * Set the parsed body.
350
+     *
351
+     * @param null|array|object $parsedBody
352
+     * @return $this
353
+     */
354
+    private function setParsedBody($parsedBody)
355
+    {
356
+        $this->parsedBody = $parsedBody;
357
+
358
+        return $this;
359
+    }
360
+
361
+    /**
362
+     * {@inheritdoc}
363
+     */
364
+    public function withParsedBody($parsedBody)
365
+    {
366
+        $result = clone $this;
367
+
368
+        return $result->setParsedBody($parsedBody);
369
+    }
370
+
371
+    /**
372
+     * {@inheritdoc}
373
+     */
374
+    public function getAttributes()
375
+    {
376
+        return $this->attributes;
377
+    }
378
+
379
+    /**
380
+     * {@inheritdoc}
381
+     */
382
+    public function getAttribute($name, $default = null)
383
+    {
384
+        return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
385
+    }
386
+
387
+    /**
388
+     * Set the attribute.
389
+     *
390
+     * @param string $name
391
+     * @param mixed $value
392
+     * @return $this
393
+     */
394
+    private function setAttribute($name, $value)
395
+    {
396
+        $this->attributes[$name] = $value;
397
+
398
+        return $this;
399
+    }
400
+
401
+    /**
402
+     * {@inheritdoc}
403
+     */
404
+    public function withAttribute($name, $value)
405
+    {
406
+        $result = clone $this;
407
+
408
+        return $result->setAttribute($name, $value);
409
+    }
410
+
411
+    /**
412
+     * Remove the attribute.
413
+     *
414
+     * @param string $name
415
+     * @return $this
416
+     */
417
+    private function removeAttribute($name)
418
+    {
419
+        unset($this->attributes[$name]);
420
+
421
+        return $this;
422
+    }
423
+
424
+    /**
425
+     * {@inheritdoc}
426
+     */
427
+    public function withoutAttribute($name)
428
+    {
429
+        $result = clone $this;
430
+
431
+        return $result->removeAttribute($name);
432
+    }
433 433
 }
Please login to merge, or discard this patch.