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 classes like EchoExtension 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 EchoExtension, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
10 | class EchoExtension extends \Twig_Extension |
||
|
|||
11 | { |
||
12 | /** |
||
13 | * @var bool |
||
14 | */ |
||
15 | private $useExpression; |
||
16 | |||
17 | public function __construct($useExpression = false) |
||
21 | |||
22 | /** |
||
23 | * {@inheritdoc} |
||
24 | */ |
||
25 | public function getFunctions() |
||
34 | |||
35 | /** |
||
36 | * {@inheritdoc} |
||
37 | */ |
||
38 | public function getFilters() |
||
44 | |||
45 | /** |
||
46 | * Try to convert options of form given as string from yaml to a good object |
||
47 | * > Transforms PHP call into PHP : |
||
48 | * addFormOptions: |
||
49 | * myOption: __php(MyStaticClass::myCustomFunction()) |
||
50 | * |
||
51 | * > Tranforms [query_builder|query] into valid Closure: |
||
52 | * addFormOptions: |
||
53 | * query_builder: function($er) { return $er->createMyCustomQueryBuilder(); } |
||
54 | * |
||
55 | * |
||
56 | * @param string $options the string as php |
||
57 | * @param string $formType the form type |
||
58 | * |
||
59 | * @return string the new options |
||
60 | */ |
||
61 | public function convertAsForm($options, $formType) |
||
101 | |||
102 | /** |
||
103 | * Print "trans" tag for string $str with parameters $parameters |
||
104 | * for catalog $catalog. |
||
105 | * |
||
106 | * @param $str |
||
107 | * @param array $parameters |
||
108 | * @param string $catalog |
||
109 | * @return string |
||
110 | */ |
||
111 | public function getEchoTrans($str, array $parameters = array(), $catalog = 'Admingenerator', $escape = null) |
||
142 | |||
143 | /** |
||
144 | * Print "echo tag with path call" to the path $path with params $params. |
||
145 | * |
||
146 | * @param $path |
||
147 | * @param array $params |
||
148 | * @param array|string $filters |
||
149 | * @return string |
||
150 | */ |
||
151 | public function getEchoPath($path, $params = null, $filters = null) |
||
178 | |||
179 | /** |
||
180 | * Print "if" tag with condition to is_expr_granted('$credentials') |
||
181 | * If $modelName is not null, append the $modelName to the function call. |
||
182 | * |
||
183 | * @param $credentials |
||
184 | * @param null $modelName |
||
185 | * @return string |
||
186 | */ |
||
187 | public function getEchoIfGranted($credentials, $modelName = null) |
||
200 | |||
201 | /** |
||
202 | * Print "echo tag with render call" to the controller $controller |
||
203 | * with $params parameters. |
||
204 | * |
||
205 | * @param $controller |
||
206 | * @param array $params |
||
207 | * @return string |
||
208 | */ |
||
209 | public function getEchoRender($controller, array $params = array()) |
||
215 | |||
216 | /** |
||
217 | * Reads parameters from subject and removes parameter bag from string. |
||
218 | * |
||
219 | * @return array |
||
220 | * [string] -> string for echo trans |
||
221 | * [params] -> parameters for echo trans |
||
222 | * |
||
223 | * @return false if subject did not match any of following patterns |
||
224 | * |
||
225 | * ############################## |
||
226 | * Backwards compability pattern: |
||
227 | * |
||
228 | * replaces twig tags {{ parameter_name }} with parameters. |
||
229 | * |
||
230 | * example: You're editing {{ Book.title }} written by {{ Book.author.name }}! |
||
231 | * |
||
232 | * results in: |
||
233 | * string -> You're editing %Book.title% written by %Book.author.name%! |
||
234 | * params -> |
||
235 | * [Book.title] -> Book.title |
||
236 | * [Book.author.name] -> Book.author.name |
||
237 | * |
||
238 | * ################################### |
||
239 | * Feature - key-value syntax pattern: |
||
240 | * |{ %param_key%: param_value, %param_key2%: param_value2, %param_key3%: param_value3 }| |
||
241 | * |
||
242 | * where param_key and param_value consist of any number a-z, A-Z, 0-9 or . (dot) characters |
||
243 | * |
||
244 | * example: You're editing %book% written by %author%!|{ %book%: Book.title, %author%: Book.author.name }| |
||
245 | * results in: |
||
246 | * string -> You're editing %book% written by %author%! |
||
247 | * params -> |
||
248 | * [book] -> Book.title |
||
249 | * [author] -> Book.author.name |
||
250 | * |
||
251 | * example: book.edit.title|{ %book%: Book.title, %author%: Book.author.name }| * |
||
252 | * results in: |
||
253 | * string -> book.edit.title |
||
254 | * params -> |
||
255 | * [book] -> Book.title |
||
256 | * [author] -> Book.author.name |
||
257 | * |
||
258 | * ################################### |
||
259 | * Feature - abbreviated syntax pattern: |
||
260 | * |{ param_value, param_value2, param_value3 }| |
||
261 | * |
||
262 | * where param_value consists of any number a-z, A-Z, 0-9 or . (dot) characters |
||
263 | * |
||
264 | * example: You're editing %Book.title% written by %Book.author.name%!|{ Book.title, Book.author.name }| |
||
265 | * results in: |
||
266 | * string -> You're editing %Book.title% written by %Book.author.name%! |
||
267 | * params -> |
||
268 | * [Book.title] -> Book.title |
||
269 | * [Book.author.name] -> Book.author.name |
||
270 | * |
||
271 | * example: book.edit.title|{ Book.title, Book.author.name }| |
||
272 | * results in: |
||
273 | * string -> book.edit.title |
||
274 | * params -> |
||
275 | * [Book.title] -> Book.title |
||
276 | * [Book.author.name] -> Book.author.name |
||
277 | */ |
||
278 | private function getParameterBag($subject) |
||
342 | |||
343 | /** |
||
344 | * Converts an assoc array to a twig array expression (string) . |
||
345 | * Only in case a value contains '{{' and '}}' the value won't be |
||
346 | * wrapped in quotes. |
||
347 | * |
||
348 | * An array like: |
||
349 | * <code> |
||
350 | * $array = array('a' => 'b', 'c' => 'd', 'e' => '{{f}}'); |
||
351 | * </code> |
||
352 | * |
||
353 | * Will be converted to: |
||
354 | * <code> |
||
355 | * "{ a: 'b', c: 'd', e: f }" |
||
356 | * </code> |
||
357 | * |
||
358 | * @return string |
||
359 | */ |
||
360 | private function getTwigAssociativeArray(array $hashmap) |
||
375 | |||
376 | /** |
||
377 | * Returns the name of the extension. |
||
378 | * |
||
379 | * @return string The extension name |
||
380 | */ |
||
381 | public function getName() |
||
385 | } |
||
386 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.