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 |
||
38 | { |
||
39 | /** |
||
40 | * Key format, value a callable that returns a Response instance. |
||
41 | * |
||
42 | * @var array |
||
43 | */ |
||
44 | protected $customHandlers = []; |
||
45 | |||
46 | /** |
||
47 | * The supported formats as keys and if the given formats |
||
48 | * uses templating is denoted by a true value. |
||
49 | * |
||
50 | * @var array |
||
51 | */ |
||
52 | protected $formats; |
||
53 | |||
54 | /** |
||
55 | * @var int |
||
56 | */ |
||
57 | protected $failedValidationCode; |
||
58 | |||
59 | /** |
||
60 | * @var int |
||
61 | */ |
||
62 | protected $emptyContentCode; |
||
63 | |||
64 | /** |
||
65 | * @var bool |
||
66 | */ |
||
67 | protected $serializeNull; |
||
68 | |||
69 | /** |
||
70 | * If to force a redirect for the given key format, |
||
71 | * with value being the status code to use. |
||
72 | * |
||
73 | * @var array<string,int> |
||
74 | */ |
||
75 | protected $forceRedirects; |
||
76 | |||
77 | /** |
||
78 | * @var string|null |
||
79 | */ |
||
80 | protected $defaultEngine; |
||
81 | |||
82 | /** |
||
83 | * @var array |
||
84 | */ |
||
85 | protected $exclusionStrategyGroups = []; |
||
86 | |||
87 | /** |
||
88 | * @var string |
||
89 | */ |
||
90 | protected $exclusionStrategyVersion; |
||
91 | |||
92 | /** |
||
93 | * @var bool |
||
94 | */ |
||
95 | protected $serializeNullStrategy; |
||
96 | |||
97 | private $urlGenerator; |
||
98 | private $serializer; |
||
99 | private $templating; |
||
100 | private $requestStack; |
||
101 | |||
102 | private $options; |
||
103 | |||
104 | /** |
||
105 | * @param EngineInterface|Environment $templating The configured templating engine |
||
106 | */ |
||
107 | 87 | public function __construct( |
|
108 | UrlGeneratorInterface $urlGenerator, |
||
109 | Serializer $serializer, |
||
110 | $templating, |
||
111 | RequestStack $requestStack, |
||
112 | array $formats = null, |
||
113 | int $failedValidationCode = Response::HTTP_BAD_REQUEST, |
||
114 | int $emptyContentCode = Response::HTTP_NO_CONTENT, |
||
115 | bool $serializeNull = false, |
||
116 | array $forceRedirects = null, |
||
117 | ?string $defaultEngine = 'twig', |
||
118 | array $options = [] |
||
119 | ) { |
||
120 | 87 | if (11 >= func_num_args() || func_get_arg(11)) { |
|
121 | 14 | @trigger_error(sprintf('The constructor of the %s class is deprecated, use the static create() factory method instead.', __CLASS__), E_USER_DEPRECATED); |
|
|
|||
122 | } |
||
123 | |||
124 | 87 | if (null !== $templating && !$templating instanceof EngineInterface && !$templating instanceof Environment) { |
|
125 | throw new \TypeError(sprintf('If provided, the templating engine must be an instance of %s or %s, but %s was given.', EngineInterface::class, Environment::class, get_class($templating))); |
||
126 | } |
||
127 | |||
128 | 87 | $this->urlGenerator = $urlGenerator; |
|
129 | 87 | $this->serializer = $serializer; |
|
130 | 87 | $this->templating = $templating; |
|
131 | 87 | $this->requestStack = $requestStack; |
|
132 | 87 | $this->formats = (array) $formats; |
|
133 | 87 | $this->failedValidationCode = $failedValidationCode; |
|
134 | 87 | $this->emptyContentCode = $emptyContentCode; |
|
135 | 87 | $this->serializeNull = $serializeNull; |
|
136 | 87 | $this->forceRedirects = (array) $forceRedirects; |
|
137 | 87 | $this->defaultEngine = $defaultEngine; |
|
138 | 87 | $this->options = $options + [ |
|
139 | 87 | 'exclusionStrategyGroups' => [], |
|
140 | 'exclusionStrategyVersion' => null, |
||
141 | 'serializeNullStrategy' => null, |
||
142 | ]; |
||
143 | 87 | $this->reset(); |
|
144 | 87 | } |
|
145 | |||
146 | 51 | public static function create( |
|
147 | UrlGeneratorInterface $urlGenerator, |
||
148 | Serializer $serializer, |
||
149 | RequestStack $requestStack, |
||
150 | array $formats = null, |
||
151 | int $failedValidationCode = Response::HTTP_BAD_REQUEST, |
||
152 | int $emptyContentCode = Response::HTTP_NO_CONTENT, |
||
153 | bool $serializeNull = false, |
||
154 | array $options = [] |
||
155 | ): self { |
||
156 | 51 | return new self($urlGenerator, $serializer, null, $requestStack, $formats, $failedValidationCode, $emptyContentCode, $serializeNull, [], 'twig', $options, false); |
|
157 | } |
||
158 | |||
159 | /** |
||
160 | * @param string[]|string $groups |
||
161 | */ |
||
162 | 1 | public function setExclusionStrategyGroups($groups) |
|
166 | |||
167 | /** |
||
168 | * @param string $version |
||
169 | */ |
||
170 | 8 | public function setExclusionStrategyVersion($version) |
|
174 | |||
175 | /** |
||
176 | * @param bool $isEnabled |
||
177 | */ |
||
178 | 3 | public function setSerializeNullStrategy($isEnabled) |
|
182 | |||
183 | /** |
||
184 | * {@inheritdoc} |
||
185 | */ |
||
186 | 49 | public function supports($format) |
|
190 | |||
191 | /** |
||
192 | * Registers a custom handler. |
||
193 | * |
||
194 | * The handler must have the following signature: handler(ViewHandler $viewHandler, View $view, Request $request, $format) |
||
195 | * It can use the public methods of this class to retrieve the needed data and return a |
||
196 | * Response object ready to be sent. |
||
197 | * |
||
198 | * @param string $format |
||
199 | * @param callable $callable |
||
200 | * |
||
201 | * @throws \InvalidArgumentException |
||
202 | */ |
||
203 | 15 | public function registerHandler($format, $callable) |
|
211 | |||
212 | /** |
||
213 | * Gets a response HTTP status code from a View instance. |
||
214 | * |
||
215 | * By default it will return 200. However if there is a FormInterface stored for |
||
216 | * the key 'form' in the View's data it will return the failed_validation |
||
217 | * configuration if the form instance has errors. |
||
218 | * |
||
219 | * @param string|false|null |
||
220 | * |
||
221 | * @return int HTTP status code |
||
222 | */ |
||
223 | 61 | protected function getStatusCode(View $view, $content = null) |
|
238 | |||
239 | /** |
||
240 | * @deprecated since 2.8 |
||
241 | * |
||
242 | * @param string $format |
||
243 | * |
||
244 | * @return bool |
||
245 | */ |
||
246 | 59 | public function isFormatTemplating($format) |
|
254 | |||
255 | /** |
||
256 | * @return Context |
||
257 | */ |
||
258 | 42 | protected function getSerializationContext(View $view) |
|
281 | |||
282 | /** |
||
283 | * Handles a request with the proper handler. |
||
284 | * |
||
285 | * Decides on which handler to use based on the request format. |
||
286 | * |
||
287 | * @throws UnsupportedMediaTypeHttpException |
||
288 | * |
||
289 | * @return Response |
||
290 | */ |
||
291 | 45 | public function handle(View $view, Request $request = null) |
|
311 | |||
312 | /** |
||
313 | * @param string $location |
||
314 | * @param string $format |
||
315 | * |
||
316 | * @return Response |
||
317 | */ |
||
318 | 9 | public function createRedirectResponse(View $view, $location, $format) |
|
340 | |||
341 | /** |
||
342 | * @deprecated since 2.8 |
||
343 | * |
||
344 | * @param string $format |
||
345 | * |
||
346 | * @return string |
||
347 | */ |
||
348 | 12 | public function renderTemplate(View $view, $format) |
|
374 | |||
375 | /** |
||
376 | * @deprecated since 2.8 |
||
377 | * |
||
378 | * @return array |
||
379 | */ |
||
380 | 18 | public function prepareTemplateParameters(View $view) |
|
405 | |||
406 | /** |
||
407 | * @param string $format |
||
408 | * |
||
409 | * @return Response |
||
410 | */ |
||
411 | 64 | public function createResponse(View $view, Request $request, $format) |
|
436 | |||
437 | /** |
||
438 | * @param string $format |
||
439 | * |
||
440 | * @return Response |
||
441 | */ |
||
442 | 56 | private function initResponse(View $view, $format) |
|
469 | |||
470 | /** |
||
471 | * @return bool|FormInterface |
||
472 | */ |
||
473 | 61 | protected function getFormFromView(View $view) |
|
487 | |||
488 | 39 | private function getDataFromView(View $view) |
|
498 | |||
499 | 87 | public function reset() |
|
505 | } |
||
506 |
If you suppress an error, we recommend checking for the error condition explicitly: