|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of the FOSRestBundle package. |
|
5
|
|
|
* |
|
6
|
|
|
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/> |
|
7
|
|
|
* |
|
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
9
|
|
|
* file that was distributed with this source code. |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace FOS\RestBundle\View; |
|
13
|
|
|
|
|
14
|
|
|
use FOS\RestBundle\Context\Context; |
|
15
|
|
|
use Symfony\Component\HttpFoundation\Response; |
|
16
|
|
|
use Symfony\Component\Templating\TemplateReferenceInterface; |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* Default View implementation. |
|
20
|
|
|
* |
|
21
|
|
|
* @author Johannes M. Schmitt <[email protected]> |
|
22
|
|
|
* @author Lukas K. Smith <[email protected]> |
|
23
|
|
|
*/ |
|
24
|
|
|
class View |
|
25
|
|
|
{ |
|
26
|
|
|
/** |
|
27
|
|
|
* @var mixed|null |
|
28
|
|
|
*/ |
|
29
|
|
|
private $data; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* @var int|null |
|
33
|
|
|
*/ |
|
34
|
|
|
private $statusCode; |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* @var mixed|null |
|
38
|
|
|
*/ |
|
39
|
|
|
private $templateData = []; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* @var TemplateReference|string|null |
|
43
|
|
|
*/ |
|
44
|
|
|
private $template; |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* @var string|null |
|
48
|
|
|
*/ |
|
49
|
|
|
private $templateVar; |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* @var string|null |
|
53
|
|
|
*/ |
|
54
|
|
|
private $engine; |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* @var string|null |
|
58
|
|
|
*/ |
|
59
|
|
|
private $format; |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* @var string|null |
|
63
|
|
|
*/ |
|
64
|
|
|
private $location; |
|
65
|
|
|
|
|
66
|
|
|
/** |
|
67
|
|
|
* @var string|null |
|
68
|
|
|
*/ |
|
69
|
|
|
private $route; |
|
70
|
|
|
|
|
71
|
|
|
/** |
|
72
|
|
|
* @var array|null |
|
73
|
|
|
*/ |
|
74
|
|
|
private $routeParameters; |
|
75
|
|
|
|
|
76
|
|
|
/** |
|
77
|
|
|
* @var Context |
|
78
|
|
|
*/ |
|
79
|
|
|
private $context; |
|
80
|
|
|
|
|
81
|
|
|
/** |
|
82
|
|
|
* @var Response |
|
83
|
|
|
*/ |
|
84
|
|
|
private $response; |
|
85
|
|
|
|
|
86
|
|
|
/** |
|
87
|
|
|
* Convenience method to allow for a fluent interface. |
|
88
|
|
|
* |
|
89
|
|
|
* @param mixed $data |
|
90
|
|
|
* @param int $statusCode |
|
91
|
|
|
* @param array $headers |
|
92
|
|
|
* |
|
93
|
|
|
* @return static |
|
94
|
|
|
*/ |
|
95
|
11 |
|
public static function create($data = null, $statusCode = null, array $headers = []) |
|
96
|
|
|
{ |
|
97
|
11 |
|
return new static($data, $statusCode, $headers); |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
/** |
|
101
|
|
|
* Convenience method to allow for a fluent interface while creating a redirect to a |
|
102
|
|
|
* given url. |
|
103
|
|
|
* |
|
104
|
|
|
* @param string $url |
|
105
|
|
|
* @param int $statusCode |
|
106
|
|
|
* @param array $headers |
|
107
|
|
|
* |
|
108
|
|
|
* @return static |
|
109
|
|
|
*/ |
|
110
|
1 |
|
public static function createRedirect($url, $statusCode = Response::HTTP_FOUND, array $headers = []) |
|
111
|
|
|
{ |
|
112
|
1 |
|
$view = static::create(null, $statusCode, $headers); |
|
113
|
1 |
|
$view->setLocation($url); |
|
114
|
|
|
|
|
115
|
1 |
|
return $view; |
|
116
|
|
|
} |
|
117
|
|
|
|
|
118
|
|
|
/** |
|
119
|
|
|
* Convenience method to allow for a fluent interface while creating a redirect to a |
|
120
|
|
|
* given route. |
|
121
|
|
|
* |
|
122
|
|
|
* @param string $route |
|
123
|
|
|
* @param array $parameters |
|
124
|
|
|
* @param int $statusCode |
|
125
|
|
|
* @param array $headers |
|
126
|
|
|
* |
|
127
|
|
|
* @return static |
|
128
|
|
|
*/ |
|
129
|
2 |
|
public static function createRouteRedirect( |
|
130
|
|
|
$route, |
|
131
|
|
|
array $parameters = [], |
|
132
|
|
|
$statusCode = Response::HTTP_FOUND, |
|
133
|
|
|
array $headers = [] |
|
134
|
|
|
) { |
|
135
|
2 |
|
$view = static::create(null, $statusCode, $headers); |
|
136
|
2 |
|
$view->setRoute($route); |
|
137
|
2 |
|
$view->setRouteParameters($parameters); |
|
138
|
|
|
|
|
139
|
2 |
|
return $view; |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
/** |
|
143
|
|
|
* Constructor. |
|
144
|
|
|
* |
|
145
|
|
|
* @param mixed $data |
|
146
|
|
|
* @param int $statusCode |
|
147
|
|
|
* @param array $headers |
|
148
|
|
|
*/ |
|
149
|
81 |
|
public function __construct($data = null, $statusCode = null, array $headers = []) |
|
150
|
|
|
{ |
|
151
|
81 |
|
$this->setData($data); |
|
152
|
81 |
|
$this->setStatusCode($statusCode); |
|
153
|
81 |
|
$this->setTemplateVar('data'); |
|
154
|
|
|
|
|
155
|
81 |
|
if (!empty($headers)) { |
|
156
|
1 |
|
$this->getResponse()->headers->replace($headers); |
|
157
|
1 |
|
} |
|
158
|
81 |
|
} |
|
159
|
|
|
|
|
160
|
|
|
/** |
|
161
|
|
|
* Sets the data. |
|
162
|
|
|
* |
|
163
|
|
|
* @param mixed $data |
|
164
|
|
|
* |
|
165
|
|
|
* @return View |
|
166
|
|
|
*/ |
|
167
|
81 |
|
public function setData($data) |
|
168
|
|
|
{ |
|
169
|
81 |
|
$this->data = $data; |
|
170
|
|
|
|
|
171
|
81 |
|
return $this; |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
/** |
|
175
|
|
|
* Set template variable. |
|
176
|
|
|
* |
|
177
|
|
|
* @param array|callable $data |
|
178
|
|
|
* |
|
179
|
|
|
* @return View |
|
180
|
|
|
*/ |
|
181
|
6 |
|
public function setTemplateData($data = []) |
|
182
|
|
|
{ |
|
183
|
6 |
|
$this->templateData = $data; |
|
184
|
|
|
|
|
185
|
6 |
|
return $this; |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
/** |
|
189
|
|
|
* Sets a header. |
|
190
|
|
|
* |
|
191
|
|
|
* @param string $name |
|
192
|
|
|
* @param string $value |
|
193
|
|
|
* |
|
194
|
|
|
* @return View |
|
195
|
|
|
*/ |
|
196
|
|
|
public function setHeader($name, $value) |
|
197
|
|
|
{ |
|
198
|
|
|
$this->getResponse()->headers->set($name, $value); |
|
199
|
|
|
|
|
200
|
|
|
return $this; |
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
|
|
/** |
|
204
|
|
|
* Sets the headers. |
|
205
|
|
|
* |
|
206
|
|
|
* @param array $headers |
|
207
|
|
|
* |
|
208
|
|
|
* @return View |
|
209
|
|
|
*/ |
|
210
|
1 |
|
public function setHeaders(array $headers) |
|
211
|
|
|
{ |
|
212
|
1 |
|
$this->getResponse()->headers->replace($headers); |
|
213
|
|
|
|
|
214
|
1 |
|
return $this; |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
/** |
|
218
|
|
|
* Sets the HTTP status code. |
|
219
|
|
|
* |
|
220
|
|
|
* @param int|null $code |
|
221
|
|
|
* |
|
222
|
|
|
* @return View |
|
223
|
|
|
*/ |
|
224
|
81 |
|
public function setStatusCode($code) |
|
225
|
|
|
{ |
|
226
|
81 |
|
if (null !== $code) { |
|
227
|
17 |
|
$this->statusCode = $code; |
|
228
|
17 |
|
} |
|
229
|
|
|
|
|
230
|
81 |
|
return $this; |
|
231
|
|
|
} |
|
232
|
|
|
|
|
233
|
|
|
/** |
|
234
|
|
|
* Sets the serialization context. |
|
235
|
|
|
* |
|
236
|
|
|
* @param Context $context |
|
237
|
|
|
* |
|
238
|
|
|
* @return View |
|
239
|
|
|
*/ |
|
240
|
|
|
public function setContext(Context $context) |
|
241
|
|
|
{ |
|
242
|
|
|
$this->context = $context; |
|
243
|
|
|
|
|
244
|
|
|
return $this; |
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
/** |
|
248
|
|
|
* Sets template to use for the encoding. |
|
249
|
|
|
* |
|
250
|
|
|
* @param string|TemplateReferenceInterface $template |
|
251
|
|
|
* |
|
252
|
|
|
* @return View |
|
253
|
|
|
* |
|
254
|
|
|
* @throws \InvalidArgumentException if the template is neither a string nor an instance of TemplateReferenceInterface |
|
255
|
|
|
*/ |
|
256
|
4 |
|
public function setTemplate($template) |
|
257
|
|
|
{ |
|
258
|
4 |
|
if (!(is_string($template) || $template instanceof TemplateReferenceInterface)) { |
|
259
|
1 |
|
throw new \InvalidArgumentException('The template should be a string or implement TemplateReferenceInterface'); |
|
260
|
|
|
} |
|
261
|
4 |
|
$this->template = $template; |
|
|
|
|
|
|
262
|
|
|
|
|
263
|
4 |
|
return $this; |
|
264
|
|
|
} |
|
265
|
|
|
|
|
266
|
|
|
/** |
|
267
|
|
|
* Sets template variable name to be used in templating formats. |
|
268
|
|
|
* |
|
269
|
|
|
* @param string $templateVar |
|
270
|
|
|
* |
|
271
|
|
|
* @return View |
|
272
|
|
|
*/ |
|
273
|
81 |
|
public function setTemplateVar($templateVar) |
|
274
|
|
|
{ |
|
275
|
81 |
|
$this->templateVar = $templateVar; |
|
276
|
|
|
|
|
277
|
81 |
|
return $this; |
|
278
|
|
|
} |
|
279
|
|
|
|
|
280
|
|
|
/** |
|
281
|
|
|
* Sets the engine. |
|
282
|
|
|
* |
|
283
|
|
|
* @param string $engine |
|
284
|
|
|
* |
|
285
|
|
|
* @return View |
|
286
|
|
|
*/ |
|
287
|
1 |
|
public function setEngine($engine) |
|
288
|
|
|
{ |
|
289
|
1 |
|
$this->engine = $engine; |
|
290
|
|
|
|
|
291
|
1 |
|
return $this; |
|
292
|
|
|
} |
|
293
|
|
|
|
|
294
|
|
|
/** |
|
295
|
|
|
* Sets the format. |
|
296
|
|
|
* |
|
297
|
|
|
* @param string $format |
|
298
|
|
|
* |
|
299
|
|
|
* @return View |
|
300
|
|
|
*/ |
|
301
|
36 |
|
public function setFormat($format) |
|
302
|
|
|
{ |
|
303
|
36 |
|
$this->format = $format; |
|
304
|
|
|
|
|
305
|
36 |
|
return $this; |
|
306
|
|
|
} |
|
307
|
|
|
|
|
308
|
|
|
/** |
|
309
|
|
|
* Sets the location (implicitly removes the route). |
|
310
|
|
|
* |
|
311
|
|
|
* @param string $location |
|
312
|
|
|
* |
|
313
|
|
|
* @return View |
|
314
|
|
|
*/ |
|
315
|
8 |
|
public function setLocation($location) |
|
316
|
|
|
{ |
|
317
|
8 |
|
$this->location = $location; |
|
318
|
8 |
|
$this->route = null; |
|
319
|
|
|
|
|
320
|
8 |
|
return $this; |
|
321
|
|
|
} |
|
322
|
|
|
|
|
323
|
|
|
/** |
|
324
|
|
|
* Sets the route (implicitly removes the location). |
|
325
|
|
|
* |
|
326
|
|
|
* @param string $route |
|
327
|
|
|
* |
|
328
|
|
|
* @return View |
|
329
|
|
|
*/ |
|
330
|
3 |
|
public function setRoute($route) |
|
331
|
|
|
{ |
|
332
|
3 |
|
$this->route = $route; |
|
333
|
3 |
|
$this->location = null; |
|
334
|
|
|
|
|
335
|
3 |
|
return $this; |
|
336
|
|
|
} |
|
337
|
|
|
|
|
338
|
|
|
/** |
|
339
|
|
|
* Sets route data. |
|
340
|
|
|
* |
|
341
|
|
|
* @param array $parameters |
|
342
|
|
|
* |
|
343
|
|
|
* @return View |
|
344
|
|
|
*/ |
|
345
|
3 |
|
public function setRouteParameters($parameters) |
|
346
|
|
|
{ |
|
347
|
3 |
|
$this->routeParameters = $parameters; |
|
348
|
|
|
|
|
349
|
3 |
|
return $this; |
|
350
|
|
|
} |
|
351
|
|
|
|
|
352
|
|
|
/** |
|
353
|
|
|
* Sets the response. |
|
354
|
|
|
* |
|
355
|
|
|
* @param Response $response |
|
356
|
|
|
* |
|
357
|
|
|
* @return View |
|
358
|
|
|
*/ |
|
359
|
|
|
public function setResponse(Response $response) |
|
360
|
|
|
{ |
|
361
|
|
|
$this->response = $response; |
|
362
|
|
|
|
|
363
|
|
|
return $this; |
|
364
|
|
|
} |
|
365
|
|
|
|
|
366
|
|
|
/** |
|
367
|
|
|
* Gets the data. |
|
368
|
|
|
* |
|
369
|
|
|
* @return mixed|null |
|
370
|
|
|
*/ |
|
371
|
59 |
|
public function getData() |
|
372
|
|
|
{ |
|
373
|
59 |
|
return $this->data; |
|
374
|
|
|
} |
|
375
|
|
|
|
|
376
|
|
|
/** |
|
377
|
|
|
* Gets the template data. |
|
378
|
|
|
* |
|
379
|
|
|
* @return mixed|null |
|
380
|
|
|
*/ |
|
381
|
23 |
|
public function getTemplateData() |
|
382
|
|
|
{ |
|
383
|
23 |
|
return $this->templateData; |
|
384
|
|
|
} |
|
385
|
|
|
|
|
386
|
|
|
/** |
|
387
|
|
|
* Gets the HTTP status code. |
|
388
|
|
|
* |
|
389
|
|
|
* @return int|null |
|
390
|
|
|
*/ |
|
391
|
60 |
|
public function getStatusCode() |
|
392
|
|
|
{ |
|
393
|
60 |
|
return $this->statusCode; |
|
394
|
|
|
} |
|
395
|
|
|
|
|
396
|
|
|
/** |
|
397
|
|
|
* Gets the headers. |
|
398
|
|
|
* |
|
399
|
|
|
* @return array |
|
400
|
|
|
*/ |
|
401
|
2 |
|
public function getHeaders() |
|
402
|
|
|
{ |
|
403
|
2 |
|
return $this->getResponse()->headers->all(); |
|
404
|
|
|
} |
|
405
|
|
|
|
|
406
|
|
|
/** |
|
407
|
|
|
* Gets the template. |
|
408
|
|
|
* |
|
409
|
|
|
* @return TemplateReferenceInterface|string|null |
|
410
|
|
|
*/ |
|
411
|
14 |
|
public function getTemplate() |
|
412
|
|
|
{ |
|
413
|
14 |
|
return $this->template; |
|
414
|
|
|
} |
|
415
|
|
|
|
|
416
|
|
|
/** |
|
417
|
|
|
* Gets the template variable name. |
|
418
|
|
|
* |
|
419
|
|
|
* @return string|null |
|
420
|
|
|
*/ |
|
421
|
13 |
|
public function getTemplateVar() |
|
422
|
|
|
{ |
|
423
|
13 |
|
return $this->templateVar; |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
/** |
|
427
|
|
|
* Gets the engine. |
|
428
|
|
|
* |
|
429
|
|
|
* @return string|null |
|
430
|
|
|
*/ |
|
431
|
1 |
|
public function getEngine() |
|
432
|
|
|
{ |
|
433
|
1 |
|
return $this->engine; |
|
434
|
|
|
} |
|
435
|
|
|
|
|
436
|
|
|
/** |
|
437
|
|
|
* Gets the format. |
|
438
|
|
|
* |
|
439
|
|
|
* @return string|null |
|
440
|
|
|
*/ |
|
441
|
36 |
|
public function getFormat() |
|
442
|
|
|
{ |
|
443
|
36 |
|
return $this->format; |
|
444
|
|
|
} |
|
445
|
|
|
|
|
446
|
|
|
/** |
|
447
|
|
|
* Gets the location. |
|
448
|
|
|
* |
|
449
|
|
|
* @return string|null |
|
450
|
|
|
*/ |
|
451
|
44 |
|
public function getLocation() |
|
452
|
|
|
{ |
|
453
|
44 |
|
return $this->location; |
|
454
|
|
|
} |
|
455
|
|
|
|
|
456
|
|
|
/** |
|
457
|
|
|
* Gets the route. |
|
458
|
|
|
* |
|
459
|
|
|
* @return string|null |
|
460
|
|
|
*/ |
|
461
|
46 |
|
public function getRoute() |
|
462
|
|
|
{ |
|
463
|
46 |
|
return $this->route; |
|
464
|
|
|
} |
|
465
|
|
|
|
|
466
|
|
|
/** |
|
467
|
|
|
* Gets route parameters. |
|
468
|
|
|
* |
|
469
|
|
|
* @return array|null |
|
470
|
|
|
*/ |
|
471
|
2 |
|
public function getRouteParameters() |
|
472
|
|
|
{ |
|
473
|
2 |
|
return $this->routeParameters; |
|
474
|
|
|
} |
|
475
|
|
|
|
|
476
|
|
|
/** |
|
477
|
|
|
* Gets the response. |
|
478
|
|
|
* |
|
479
|
|
|
* @return Response |
|
480
|
|
|
*/ |
|
481
|
51 |
|
public function getResponse() |
|
482
|
|
|
{ |
|
483
|
51 |
|
if (null === $this->response) { |
|
484
|
51 |
|
$this->response = new Response(); |
|
485
|
|
|
|
|
486
|
51 |
|
if (null !== ($code = $this->getStatusCode())) { |
|
487
|
13 |
|
$this->response->setStatusCode($code); |
|
488
|
13 |
|
} |
|
489
|
51 |
|
} |
|
490
|
|
|
|
|
491
|
51 |
|
return $this->response; |
|
492
|
|
|
} |
|
493
|
|
|
|
|
494
|
|
|
/** |
|
495
|
|
|
* Gets the serialization context. |
|
496
|
|
|
* |
|
497
|
|
|
* @return Context |
|
498
|
|
|
*/ |
|
499
|
37 |
|
public function getContext() |
|
500
|
|
|
{ |
|
501
|
37 |
|
if (null === $this->context) { |
|
502
|
37 |
|
$this->context = new Context(); |
|
503
|
37 |
|
} |
|
504
|
|
|
|
|
505
|
37 |
|
return $this->context; |
|
506
|
|
|
} |
|
507
|
|
|
} |
|
508
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.