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:
1 | <?php |
||
20 | class Controller |
||
21 | { |
||
22 | |||
23 | /** |
||
24 | * Controller action is publicly accessible |
||
25 | */ |
||
26 | const ACTION_PUBLIC = 0; |
||
27 | |||
28 | /** |
||
29 | * Controller action requires authentication |
||
30 | * Will redirect to sign in page if not authenticated |
||
31 | */ |
||
32 | const ACTION_PROTECTED = 1; |
||
33 | |||
34 | /** |
||
35 | * Controller action requires authentication |
||
36 | * Will result in an 404 if not authenticated |
||
37 | */ |
||
38 | const ACTION_PRIVATE = 2; |
||
39 | |||
40 | /** |
||
41 | * @var array Controller action access rules |
||
42 | */ |
||
43 | protected $access = []; |
||
44 | |||
45 | /** |
||
46 | * @var \PDO PDO |
||
47 | */ |
||
48 | protected $pdo; |
||
49 | |||
50 | /** |
||
51 | * @var Configuration |
||
52 | */ |
||
53 | protected $configuration; |
||
54 | |||
55 | /** |
||
56 | * @var Request |
||
57 | */ |
||
58 | protected $request; |
||
59 | |||
60 | /** |
||
61 | * @var Entity|null User |
||
62 | */ |
||
63 | protected $user; |
||
64 | |||
65 | /** |
||
66 | * @var array URL Arguments |
||
67 | */ |
||
68 | protected $arguments; |
||
69 | |||
70 | /** |
||
71 | * @var string Controller action |
||
72 | */ |
||
73 | protected $action; |
||
74 | |||
75 | /** |
||
76 | * @var array View variables |
||
77 | */ |
||
78 | protected $variables = []; |
||
79 | |||
80 | /** |
||
81 | * @var bool Should render view for controller action |
||
82 | */ |
||
83 | protected $render = true; |
||
84 | |||
85 | /** |
||
86 | * @var string File path for layout template file |
||
87 | */ |
||
88 | protected $layout; |
||
89 | |||
90 | /** |
||
91 | * @var string File path for view template file |
||
92 | */ |
||
93 | protected $view; |
||
94 | |||
95 | /** |
||
96 | * @var string Content type |
||
97 | */ |
||
98 | protected $contentType = 'html'; |
||
99 | |||
100 | /** |
||
101 | * @var array Headers for output |
||
102 | */ |
||
103 | protected $headers = []; |
||
104 | |||
105 | /** |
||
106 | * Controller constructor. |
||
107 | * |
||
108 | * @param \PDO $pdo |
||
109 | * @param Configuration $configuration |
||
110 | * @param Request $request |
||
111 | * @param Entity|null $user |
||
112 | */ |
||
113 | View Code Duplication | public function __construct(\PDO $pdo, Configuration $configuration, Request $request, Entity $user = null) |
|
120 | |||
121 | /** |
||
122 | * Get short controller name |
||
123 | * |
||
124 | * @return string Controller name without namespace |
||
125 | */ |
||
126 | public function getShortName(): string |
||
130 | |||
131 | /** |
||
132 | * Set URL arguments |
||
133 | * |
||
134 | * @param array $arguments |
||
135 | */ |
||
136 | public function setArguments(array $arguments) |
||
140 | |||
141 | /** |
||
142 | * Set controller action |
||
143 | * |
||
144 | * @param string $action Controller action |
||
145 | * |
||
146 | * @throws ControllerActionNonexistentException |
||
147 | * @throws ControllerActionPrivateInsufficientAuthenticationException |
||
148 | * @throws ControllerActionProtectedInsufficientAuthenticationException |
||
149 | */ |
||
150 | public function setAction(string $action) |
||
175 | |||
176 | /** |
||
177 | * Call action |
||
178 | * |
||
179 | * @return Response |
||
180 | * |
||
181 | * @throws \LogicException If controller action is not set |
||
182 | */ |
||
183 | public function callAction(): Response |
||
250 | |||
251 | /** |
||
252 | * Before controller action hook |
||
253 | * |
||
254 | * Called right before controller action is called |
||
255 | * |
||
256 | * If FALSE is returned, the action will not be called |
||
257 | * |
||
258 | * @return bool |
||
259 | */ |
||
260 | protected function beforeAction(): bool |
||
264 | |||
265 | /** |
||
266 | * After controller action hook |
||
267 | * |
||
268 | * Called right after controller action is called, before rendering of the view |
||
269 | * |
||
270 | * Only called if action is called |
||
271 | */ |
||
272 | protected function afterAction() |
||
275 | |||
276 | /** |
||
277 | * Set view variable |
||
278 | * |
||
279 | * @param string $variable |
||
280 | * @param mixed $value |
||
281 | */ |
||
282 | protected function set(string $variable, $value) |
||
286 | |||
287 | /** |
||
288 | * Set flash message |
||
289 | * |
||
290 | * Recommended types: error, warning, success & info |
||
291 | * |
||
292 | * @param string $message Flash message |
||
293 | * @param string $type Flash type |
||
294 | */ |
||
295 | protected function setFlash(string $message, string $type) |
||
302 | |||
303 | /** |
||
304 | * Set a redirect header in the response |
||
305 | * |
||
306 | * @param string $url URL for redirect |
||
307 | */ |
||
308 | protected function redirect(string $url) |
||
317 | |||
318 | /** |
||
319 | * Get layout template |
||
320 | * |
||
321 | * @return string Layout template file path |
||
322 | */ |
||
323 | protected function getLayoutTemplate(): string |
||
333 | |||
334 | /** |
||
335 | * Get view template |
||
336 | * |
||
337 | * @return string View template file path |
||
338 | */ |
||
339 | protected function getViewTemplate(): string |
||
349 | |||
350 | /** |
||
351 | * Set response code |
||
352 | * |
||
353 | * Supports 200 OK, 403 Forbidden, 404 Not Found & 500 Internal Server Error |
||
354 | * |
||
355 | * @param int $code HTTP response code |
||
356 | * |
||
357 | * @throws \InvalidArgumentException If unsupported code is provided |
||
358 | */ |
||
359 | protected function setResponseCode(int $code) |
||
413 | } |
||
414 |
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.