Complex classes like ViewHandler 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 ViewHandler, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
37 | class ViewHandler implements ConfigurableViewHandlerInterface, ContainerAwareInterface |
||
38 | { |
||
39 | use ContainerAwareTrait; |
||
40 | |||
41 | /** |
||
42 | * Key format, value a callable that returns a Response instance. |
||
43 | * |
||
44 | * @var array |
||
45 | */ |
||
46 | protected $customHandlers = []; |
||
47 | |||
48 | /** |
||
49 | * The supported formats as keys and if the given formats |
||
50 | * uses templating is denoted by a true value. |
||
51 | * |
||
52 | * @var array |
||
53 | */ |
||
54 | protected $formats; |
||
55 | |||
56 | /** |
||
57 | * HTTP response status code for a failed validation. |
||
58 | * |
||
59 | * @var int |
||
60 | */ |
||
61 | protected $failedValidationCode; |
||
62 | |||
63 | /** |
||
64 | * HTTP response status code when the view data is null. |
||
65 | * |
||
66 | * @var int |
||
67 | */ |
||
68 | protected $emptyContentCode; |
||
69 | |||
70 | /** |
||
71 | * Whether or not to serialize null view data. |
||
72 | * |
||
73 | * @var bool |
||
74 | */ |
||
75 | protected $serializeNull; |
||
76 | |||
77 | /** |
||
78 | * If to force a redirect for the given key format, |
||
79 | * with value being the status code to use. |
||
80 | * |
||
81 | * @var array |
||
82 | */ |
||
83 | protected $forceRedirects; |
||
84 | |||
85 | /** |
||
86 | * @var string |
||
87 | */ |
||
88 | protected $defaultEngine; |
||
89 | |||
90 | /** |
||
91 | * @var array |
||
92 | */ |
||
93 | protected $exclusionStrategyGroups = []; |
||
94 | |||
95 | /** |
||
96 | * @var string |
||
97 | */ |
||
98 | protected $exclusionStrategyVersion; |
||
99 | |||
100 | /** |
||
101 | * @var bool |
||
102 | */ |
||
103 | protected $serializeNullStrategy; |
||
104 | |||
105 | /** |
||
106 | * @var SerializationContextAdapterInterface |
||
107 | */ |
||
108 | protected $contextAdapter; |
||
109 | |||
110 | /** |
||
111 | * Constructor. |
||
112 | * |
||
113 | * @param array $formats the supported formats as keys and if the given formats uses templating is denoted by a true value |
||
114 | * @param int $failedValidationCode The HTTP response status code for a failed validation |
||
115 | * @param int $emptyContentCode HTTP response status code when the view data is null |
||
116 | * @param bool $serializeNull Whether or not to serialize null view data |
||
117 | * @param array $forceRedirects If to force a redirect for the given key format, with value being the status code to use |
||
118 | * @param string $defaultEngine default engine (twig, php ..) |
||
119 | */ |
||
120 | 71 | public function __construct( |
|
135 | |||
136 | /** |
||
137 | * Sets the default serialization groups. |
||
138 | * |
||
139 | * @param array|string $groups |
||
140 | */ |
||
141 | 1 | public function setExclusionStrategyGroups($groups) |
|
145 | |||
146 | /** |
||
147 | * Sets the default serialization version. |
||
148 | * |
||
149 | * @param string $version |
||
150 | */ |
||
151 | 5 | public function setExclusionStrategyVersion($version) |
|
155 | |||
156 | /** |
||
157 | * If nulls should be serialized. |
||
158 | * |
||
159 | * @param bool $isEnabled |
||
160 | */ |
||
161 | 16 | public function setSerializeNullStrategy($isEnabled) |
|
165 | |||
166 | /** |
||
167 | * Sets context adapter. |
||
168 | * |
||
169 | * @param SerializationContextAdapterInterface $contextAdapter |
||
170 | */ |
||
171 | 44 | public function setSerializationContextAdapter(SerializationContextAdapterInterface $contextAdapter) |
|
175 | |||
176 | /** |
||
177 | * {@inheritdoc} |
||
178 | */ |
||
179 | 32 | public function supports($format) |
|
183 | |||
184 | /** |
||
185 | * Registers a custom handler. |
||
186 | * |
||
187 | * The handler must have the following signature: handler(ViewHandler $viewHandler, View $view, Request $request, $format) |
||
188 | * It can use the public methods of this class to retrieve the needed data and return a |
||
189 | * Response object ready to be sent. |
||
190 | * |
||
191 | * @param string $format |
||
192 | * @param callable $callable |
||
193 | * |
||
194 | * @throws \InvalidArgumentException |
||
195 | */ |
||
196 | 16 | public function registerHandler($format, $callable) |
|
204 | |||
205 | /** |
||
206 | * Gets a response HTTP status code from a View instance. |
||
207 | * |
||
208 | * By default it will return 200. However if there is a FormInterface stored for |
||
209 | * the key 'form' in the View's data it will return the failed_validation |
||
210 | * configuration if the form instance has errors. |
||
211 | * |
||
212 | * @param View $view |
||
213 | * @param mixed $content |
||
214 | * |
||
215 | * @return int HTTP status code |
||
216 | */ |
||
217 | 43 | protected function getStatusCode(View $view, $content = null) |
|
231 | |||
232 | /** |
||
233 | * If the given format uses the templating system for rendering. |
||
234 | * |
||
235 | * @param string $format |
||
236 | * |
||
237 | * @return bool |
||
238 | */ |
||
239 | 34 | public function isFormatTemplating($format) |
|
243 | |||
244 | /** |
||
245 | * Gets the router service. |
||
246 | * |
||
247 | * @return \Symfony\Component\Routing\RouterInterface |
||
248 | */ |
||
249 | 1 | protected function getRouter() |
|
253 | |||
254 | /** |
||
255 | * Gets the serializer service. |
||
256 | * |
||
257 | * @param View $view view instance from which the serializer should be configured |
||
258 | * |
||
259 | * @return object that must provide a "serialize()" method |
||
260 | */ |
||
261 | 21 | protected function getSerializer(View $view = null) |
|
265 | |||
266 | /** |
||
267 | * Gets or creates a JMS\Serializer\SerializationContext and initializes it with |
||
268 | * the view exclusion strategies, groups & versions if a new context is created. |
||
269 | * |
||
270 | * @param View $view |
||
271 | * |
||
272 | * @return ContextInterface |
||
273 | */ |
||
274 | 24 | protected function getSerializationContext(View $view) |
|
295 | |||
296 | /** |
||
297 | * Gets the templating service. |
||
298 | * |
||
299 | * @return \Symfony\Bundle\FrameworkBundle\Templating\EngineInterface |
||
300 | */ |
||
301 | 11 | protected function getTemplating() |
|
305 | |||
306 | /** |
||
307 | * Handles a request with the proper handler. |
||
308 | * |
||
309 | * Decides on which handler to use based on the request format. |
||
310 | * |
||
311 | * @param View $view |
||
312 | * @param Request $request |
||
313 | * |
||
314 | * @throws UnsupportedMediaTypeHttpException |
||
315 | * |
||
316 | * @return Response |
||
317 | */ |
||
318 | 28 | public function handle(View $view, Request $request = null) |
|
337 | |||
338 | /** |
||
339 | * Creates the Response from the view. |
||
340 | * |
||
341 | * @param View $view |
||
342 | * @param string $location |
||
343 | * @param string $format |
||
344 | * |
||
345 | * @return Response |
||
346 | */ |
||
347 | 7 | public function createRedirectResponse(View $view, $location, $format) |
|
369 | |||
370 | /** |
||
371 | * Renders the view data with the given template. |
||
372 | * |
||
373 | * @param View $view |
||
374 | * @param string $format |
||
375 | * |
||
376 | * @return string |
||
377 | */ |
||
378 | 11 | public function renderTemplate(View $view, $format) |
|
396 | |||
397 | /** |
||
398 | * Prepares view data for use by templating engine. |
||
399 | * |
||
400 | * @param View $view |
||
401 | * |
||
402 | * @return array |
||
403 | */ |
||
404 | 18 | public function prepareTemplateParameters(View $view) |
|
425 | |||
426 | /** |
||
427 | * Handles creation of a Response using either redirection or the templating/serializer service. |
||
428 | * |
||
429 | * @param View $view |
||
430 | * @param Request $request |
||
431 | * @param string $format |
||
432 | * |
||
433 | * @return Response |
||
434 | */ |
||
435 | 39 | public function createResponse(View $view, Request $request, $format) |
|
454 | |||
455 | /** |
||
456 | * Initializes a response object that represents the view and holds the view's status code. |
||
457 | * |
||
458 | * @param View $view |
||
459 | * @param string $format |
||
460 | * |
||
461 | * @return Response |
||
462 | */ |
||
463 | 33 | private function initResponse(View $view, $format) |
|
489 | |||
490 | /** |
||
491 | * Returns the form from the given view if present, false otherwise. |
||
492 | * |
||
493 | * @param View $view |
||
494 | * |
||
495 | * @return bool|FormInterface |
||
496 | */ |
||
497 | 43 | protected function getFormFromView(View $view) |
|
511 | |||
512 | /** |
||
513 | * Returns the data from a view. If the data is form with errors, it will return it wrapped in an ExceptionWrapper. |
||
514 | * |
||
515 | * @param View $view |
||
516 | * |
||
517 | * @return mixed|null |
||
518 | */ |
||
519 | 21 | private function getDataFromView(View $view) |
|
542 | } |
||
543 |
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 theid
property of an instance of theAccount
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.