Completed
Push — master ( 8e0f41...aafb5f )
by Christian
08:40 queued 10s
created

View   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 528
Duplicated Lines 8.33 %

Coupling/Cohesion

Components 7
Dependencies 3

Test Coverage

Coverage 91.18%

Importance

Changes 0
Metric Value
wmc 50
lcom 7
cbo 3
dl 44
loc 528
ccs 93
cts 102
cp 0.9118
rs 8.4
c 0
b 0
f 0

31 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 4 1
A createRedirect() 0 7 1
A createRouteRedirect() 0 12 1
A __construct() 0 10 2
A setData() 0 6 1
A setTemplateData() 10 10 3
A setHeader() 0 6 1
A setHeaders() 0 6 1
A setStatusCode() 0 8 2
A setContext() 0 6 1
A setTemplate() 0 13 5
A setTemplateVar() 10 10 3
A setEngine() 0 8 1
A setFormat() 0 6 1
A setLocation() 0 7 1
A setRoute() 0 7 1
A setRouteParameters() 0 6 1
A setResponse() 0 6 1
A getData() 0 4 1
A getTemplateData() 8 8 3
A getStatusCode() 0 4 1
A getHeaders() 0 4 1
A getTemplate() 8 8 3
A getTemplateVar() 8 8 3
A getEngine() 0 6 1
A getFormat() 0 4 1
A getLocation() 0 4 1
A getRoute() 0 4 1
A getRouteParameters() 0 4 1
A getResponse() 0 12 3
A getContext() 0 8 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like View often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use View, and based on these observations, apply Extract Interface, too.

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 6
    public static function create($data = null, $statusCode = null, array $headers = [])
96
    {
97 6
        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 87
    public function __construct($data = null, $statusCode = null, array $headers = [])
150
    {
151 87
        $this->setData($data);
152 87
        $this->setStatusCode($statusCode);
153 87
        $this->setTemplateVar('data', false);
0 ignored issues
show
Deprecated Code introduced by
The method FOS\RestBundle\View\View::setTemplateVar() has been deprecated with message: since 2.8

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
154
155 87
        if (!empty($headers)) {
156 1
            $this->getResponse()->headers->replace($headers);
157 1
        }
158 87
    }
159
160
    /**
161
     * Sets the data.
162
     *
163
     * @param mixed $data
164
     *
165
     * @return View
166
     */
167 87
    public function setData($data)
168
    {
169 87
        $this->data = $data;
170
171 87
        return $this;
172
    }
173
174
    /**
175
     * Set template variable.
176
     *
177
     * @deprecated since 2.8
178
     *
179
     * @param array|callable $data
180
     *
181 15
     * @return View
182
     */
183 15 View Code Duplication
    public function setTemplateData($data = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
    {
185 15
        if (1 === func_num_args() || func_get_arg(1)) {
186
            @trigger_error(sprintf('The %s() method is deprecated since FOSRestBundle 2.8.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
187
        }
188
189
        $this->templateData = $data;
190
191
        return $this;
192
    }
193
194
    /**
195
     * Sets a header.
196
     *
197
     * @param string $name
198
     * @param string $value
199
     *
200
     * @return View
201
     */
202
    public function setHeader($name, $value)
203
    {
204
        $this->getResponse()->headers->set($name, $value);
205
206
        return $this;
207
    }
208
209
    /**
210 1
     * Sets the headers.
211
     *
212 1
     * @param array $headers
213
     *
214 1
     * @return View
215
     */
216
    public function setHeaders(array $headers)
217
    {
218
        $this->getResponse()->headers->replace($headers);
219
220
        return $this;
221
    }
222
223
    /**
224 87
     * Sets the HTTP status code.
225
     *
226 87
     * @param int|null $code
227 22
     *
228 22
     * @return View
229
     */
230 87
    public function setStatusCode($code)
231
    {
232
        if (null !== $code) {
233
            $this->statusCode = $code;
234
        }
235
236
        return $this;
237
    }
238
239
    /**
240
     * Sets the serialization context.
241
     *
242
     * @param Context $context
243
     *
244
     * @return View
245
     */
246
    public function setContext(Context $context)
247
    {
248
        $this->context = $context;
249
250
        return $this;
251
    }
252
253
    /**
254
     * Sets template to use for the encoding.
255
     *
256 11
     * @deprecated since 2.8
257
     *
258 11
     * @param string|TemplateReferenceInterface $template
259 1
     *
260
     * @return View
261 11
     *
262
     * @throws \InvalidArgumentException if the template is neither a string nor an instance of TemplateReferenceInterface
263 11
     */
264
    public function setTemplate($template)
265
    {
266
        if (1 === func_num_args() || func_get_arg(1)) {
267
            @trigger_error(sprintf('The %s() method is deprecated since FOSRestBundle 2.8.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
268
        }
269
270
        if (!(is_string($template) || $template instanceof TemplateReferenceInterface)) {
271
            throw new \InvalidArgumentException('The template should be a string or implement TemplateReferenceInterface');
272
        }
273 87
        $this->template = $template;
0 ignored issues
show
Documentation Bug introduced by
It seems like $template can also be of type object<Symfony\Component...lateReferenceInterface>. However, the property $template is declared as type object<FOS\RestBundle\Vi...eReference>|string|null. Maybe add an additional type check?

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 $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. 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.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
274
275 87
        return $this;
276
    }
277 87
278
    /**
279
     * Sets template variable name to be used in templating formats.
280
     *
281
     * @deprecated since 2.8
282
     *
283
     * @param string $templateVar
284
     *
285
     * @return View
286
     */
287 1 View Code Duplication
    public function setTemplateVar($templateVar)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
288
    {
289 1
        if (1 === func_num_args() || func_get_arg(1)) {
290
            @trigger_error(sprintf('The %s() method is deprecated since FOSRestBundle 2.8.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
291 1
        }
292
293
        $this->templateVar = $templateVar;
294
295
        return $this;
296
    }
297
298
    /**
299
     * Sets the engine.
300
     *
301 33
     * @deprecated since 2.8
302
     *
303 33
     * @param string $engine
304
     *
305 33
     * @return View
306
     */
307
    public function setEngine($engine)
308
    {
309
        @trigger_error(sprintf('The %s() method is deprecated since FOSRestBundle 2.8.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
310
311
        $this->engine = $engine;
312
313
        return $this;
314
    }
315 8
316
    /**
317 8
     * Sets the format.
318 8
     *
319
     * @param string $format
320 8
     *
321
     * @return View
322
     */
323
    public function setFormat($format)
324
    {
325
        $this->format = $format;
326
327
        return $this;
328
    }
329
330 3
    /**
331
     * Sets the location (implicitly removes the route).
332 3
     *
333 3
     * @param string $location
334
     *
335 3
     * @return View
336
     */
337
    public function setLocation($location)
338
    {
339
        $this->location = $location;
340
        $this->route = null;
341
342
        return $this;
343
    }
344
345 3
    /**
346
     * Sets the route (implicitly removes the location).
347 3
     *
348
     * @param string $route
349 3
     *
350
     * @return View
351
     */
352
    public function setRoute($route)
353
    {
354
        $this->route = $route;
355
        $this->location = null;
356
357
        return $this;
358
    }
359
360
    /**
361
     * Sets route data.
362
     *
363
     * @param array $parameters
364
     *
365
     * @return View
366
     */
367
    public function setRouteParameters($parameters)
368
    {
369
        $this->routeParameters = $parameters;
370
371 65
        return $this;
372
    }
373 65
374
    /**
375
     * Sets the response.
376
     *
377
     * @param Response $response
378
     *
379
     * @return View
380
     */
381 53
    public function setResponse(Response $response)
382
    {
383 53
        $this->response = $response;
384
385
        return $this;
386
    }
387
388
    /**
389
     * Gets the data.
390
     *
391 66
     * @return mixed|null
392
     */
393 66
    public function getData()
394
    {
395
        return $this->data;
396
    }
397
398
    /**
399
     * Gets the template data.
400
     *
401 2
     * @deprecated since 2.8
402
     *
403 2
     * @return mixed|null
404
     */
405 View Code Duplication
    public function getTemplateData()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
406
    {
407
        if (0 === func_num_args() || func_get_arg(0)) {
408
            @trigger_error(sprintf('The %s() method is deprecated since FOSRestBundle 2.8.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
409
        }
410
411 16
        return $this->templateData;
412
    }
413 16
414
    /**
415
     * Gets the HTTP status code.
416
     *
417
     * @return int|null
418
     */
419
    public function getStatusCode()
420
    {
421 14
        return $this->statusCode;
422
    }
423 14
424
    /**
425
     * Gets the headers.
426
     *
427
     * @return array
428
     */
429
    public function getHeaders()
430
    {
431 1
        return $this->getResponse()->headers->all();
432
    }
433 1
434
    /**
435
     * Gets the template.
436
     *
437
     * @deprecated since 2.8
438
     *
439
     * @return TemplateReferenceInterface|string|null
440
     */
441 42 View Code Duplication
    public function getTemplate()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
442
    {
443 42
        if (0 === func_num_args() || func_get_arg(0)) {
444
            @trigger_error(sprintf('The %s() method is deprecated since FOSRestBundle 2.8.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
445
        }
446
447
        return $this->template;
448
    }
449
450
    /**
451 50
     * Gets the template variable name.
452
     *
453 50
     * @deprecated since 2.8
454
     *
455
     * @return string|null
456
     */
457 View Code Duplication
    public function getTemplateVar()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
458
    {
459
        if (0 === func_num_args() || func_get_arg(0)) {
460
            @trigger_error(sprintf('The %s() method is deprecated since FOSRestBundle 2.8.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
461 52
        }
462
463 52
        return $this->templateVar;
464
    }
465
466
    /**
467
     * Gets the engine.
468
     *
469
     * @deprecated since 2.8
470
     *
471 2
     * @return string|null
472
     */
473 2
    public function getEngine()
474
    {
475
        @trigger_error(sprintf('The %s() method is deprecated since FOSRestBundle 2.8.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
476
477
        return $this->engine;
478
    }
479
480
    /**
481 57
     * Gets the format.
482
     *
483 57
     * @return string|null
484 57
     */
485
    public function getFormat()
486 57
    {
487 18
        return $this->format;
488 18
    }
489 57
490
    /**
491 57
     * Gets the location.
492
     *
493
     * @return string|null
494
     */
495
    public function getLocation()
496
    {
497
        return $this->location;
498
    }
499 42
500
    /**
501 42
     * Gets the route.
502 42
     *
503 42
     * @return string|null
504
     */
505 42
    public function getRoute()
506
    {
507
        return $this->route;
508
    }
509
510
    /**
511
     * Gets route parameters.
512
     *
513
     * @return array|null
514
     */
515
    public function getRouteParameters()
516
    {
517
        return $this->routeParameters;
518
    }
519
520
    /**
521
     * Gets the response.
522
     *
523
     * @return Response
524
     */
525
    public function getResponse()
526
    {
527
        if (null === $this->response) {
528
            $this->response = new Response();
529
530
            if (null !== ($code = $this->getStatusCode())) {
531
                $this->response->setStatusCode($code);
532
            }
533
        }
534
535
        return $this->response;
536
    }
537
538
    /**
539
     * Gets the serialization context.
540
     *
541
     * @return Context
542
     */
543
    public function getContext()
544
    {
545
        if (null === $this->context) {
546
            $this->context = new Context();
547
        }
548
549
        return $this->context;
550
    }
551
}
552