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 |
||
35 | 1 | abstract class ConfirmerAttributes extends BaseControl |
|
36 | { |
||
37 | /** |
||
38 | * @var array localization strings |
||
39 | */ |
||
40 | public static $strings = [ |
||
41 | 'yes' => 'Yes', |
||
42 | 'no' => 'No', |
||
43 | 'expired' => 'Confirmation token has expired. Please try action again.', |
||
44 | ]; |
||
45 | |||
46 | /** |
||
47 | * @var string |
||
48 | */ |
||
49 | protected $cssClass; |
||
50 | |||
51 | /** |
||
52 | * @var string|callable heading |
||
53 | */ |
||
54 | protected $heading; |
||
55 | |||
56 | /** |
||
57 | * @var string|callable question |
||
58 | */ |
||
59 | protected $question; |
||
60 | |||
61 | /** |
||
62 | * @var string|callable icon |
||
63 | */ |
||
64 | protected $icon; |
||
65 | |||
66 | /** |
||
67 | * @var callable |
||
68 | */ |
||
69 | protected $handler; |
||
70 | |||
71 | /** |
||
72 | * @var bool |
||
73 | */ |
||
74 | protected $useAjax = TRUE; |
||
75 | |||
76 | /** |
||
77 | * @var Storage\IStorage |
||
78 | */ |
||
79 | protected $storage; |
||
80 | |||
81 | /** |
||
82 | * @param Storage\IStorage $storage |
||
83 | */ |
||
84 | public function injectStorage(Storage\IStorage $storage) |
||
89 | |||
90 | /** |
||
91 | * Set dialog heading |
||
92 | * |
||
93 | * @param string|callable $heading |
||
94 | * |
||
95 | * @return void |
||
96 | * |
||
97 | * @throws Exceptions\InvalidArgumentException |
||
98 | */ |
||
99 | public function setHeading($heading) |
||
100 | { |
||
101 | // Check variable type |
||
102 | 1 | if ($this->checkCallableOrString($heading)) { |
|
103 | // Update confirmation heading |
||
104 | 1 | $this->heading = $heading; |
|
105 | } |
||
106 | 1 | } |
|
107 | |||
108 | /** |
||
109 | * Get dialog heding |
||
110 | * |
||
111 | * @return string|NULL |
||
112 | * |
||
113 | * @throws Exceptions\InvalidStateException |
||
114 | */ |
||
115 | View Code Duplication | public function getHeading() |
|
127 | |||
128 | /** |
||
129 | * Set dialog question |
||
130 | * |
||
131 | * @param string|callable $question |
||
132 | * |
||
133 | * @return void |
||
134 | * |
||
135 | * @throws Exceptions\InvalidArgumentException |
||
136 | */ |
||
137 | public function setQuestion($question) |
||
138 | { |
||
139 | // Check variable type |
||
140 | 1 | if ($this->checkCallableOrString($question)) { |
|
141 | // Update confirmation question |
||
142 | 1 | $this->question = $question; |
|
143 | } |
||
144 | 1 | } |
|
145 | |||
146 | /** |
||
147 | * @return string|bool |
||
148 | * |
||
149 | * @throws Exceptions\InvalidStateException |
||
150 | */ |
||
151 | public function getQuestion() |
||
152 | { |
||
153 | 1 | $question = FALSE; |
|
154 | |||
155 | // Check if attribute is callable |
||
156 | 1 | if (is_callable($this->question)) { |
|
157 | $question = $this->callCallableAttribute($this->question); |
||
158 | |||
159 | if (!is_bool($question)) { |
||
160 | $question = (string) $question; |
||
161 | } |
||
162 | |||
163 | 1 | } elseif (!is_bool($this->question)) { |
|
164 | 1 | $question = (string) $this->question; |
|
165 | } |
||
166 | |||
167 | 1 | return $question; |
|
168 | } |
||
169 | |||
170 | /** |
||
171 | * Set dialog icon |
||
172 | * |
||
173 | * @param string|callable $icon |
||
174 | * |
||
175 | * @return void |
||
176 | * |
||
177 | * @throws Exceptions\InvalidArgumentException |
||
178 | */ |
||
179 | public function setIcon($icon) |
||
180 | { |
||
181 | // Check variable type |
||
182 | if ($this->checkCallableOrString($icon)) { |
||
183 | // Update confirmation icon |
||
184 | $this->icon = $icon; |
||
185 | } |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * @return string|NULL |
||
190 | * |
||
191 | * @throws Exceptions\InvalidStateException |
||
192 | */ |
||
193 | View Code Duplication | public function getIcon() |
|
205 | |||
206 | /** |
||
207 | * Set dialog handler |
||
208 | * |
||
209 | * @param callable $handler |
||
210 | * |
||
211 | * @return void |
||
212 | * |
||
213 | * @throws Exceptions\InvalidArgumentException |
||
214 | */ |
||
215 | public function setHandler($handler) |
||
216 | { |
||
217 | 1 | if (!is_callable($handler)) { |
|
218 | throw new Exceptions\InvalidArgumentException('$handler must be callable.'); |
||
219 | } |
||
220 | |||
221 | // Update confirmation handler |
||
222 | 1 | $this->handler = $handler; |
|
223 | 1 | } |
|
224 | |||
225 | /** |
||
226 | * @return callable |
||
227 | */ |
||
228 | public function getHandler() : callable |
||
229 | { |
||
230 | 1 | return $this->handler; |
|
231 | } |
||
232 | |||
233 | /** |
||
234 | * @param Nette\ComponentModel\IContainer $obj |
||
235 | * @param array $params |
||
236 | * |
||
237 | * @return mixed |
||
238 | * |
||
239 | * @throws Exceptions\HandlerNotCallableException |
||
240 | */ |
||
241 | public function callHandler(Nette\ComponentModel\IContainer $obj, array $params) |
||
261 | |||
262 | /** |
||
263 | * @return void |
||
264 | */ |
||
265 | public function enableAjax() |
||
266 | { |
||
267 | 1 | $this->useAjax = TRUE; |
|
268 | 1 | } |
|
269 | |||
270 | /** |
||
271 | * @return void |
||
272 | */ |
||
273 | public function disableAjax() |
||
277 | |||
278 | /** |
||
279 | * @return Application\UI\Form |
||
280 | */ |
||
281 | protected function createComponentForm() |
||
282 | { |
||
283 | // Create confirmation form |
||
284 | 1 | $form = new Application\UI\Form(); |
|
301 | |||
302 | /** |
||
303 | * @param callable|string $var |
||
304 | * |
||
305 | * @return bool |
||
306 | * |
||
307 | * @throws Exceptions\InvalidArgumentException |
||
308 | */ |
||
309 | protected function checkCallableOrString($var) : bool |
||
317 | |||
318 | /** |
||
319 | * @param callable $attribute |
||
320 | * |
||
321 | * @return string |
||
322 | * |
||
323 | * @throws Exceptions\InvalidStateException |
||
324 | */ |
||
325 | protected function callCallableAttribute($attribute) : string |
||
339 | |||
340 | /** |
||
341 | * @param string $token |
||
342 | * |
||
343 | * @return array |
||
344 | * |
||
345 | * @throws Exceptions\InvalidStateException |
||
346 | */ |
||
347 | protected function getConfirmerValues(string $token) : array |
||
359 | } |
||
360 |
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.