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 PHP_CodeSniffer_Fixer 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 PHP_CodeSniffer_Fixer, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
29 | class PHP_CodeSniffer_Fixer |
||
|
|||
30 | { |
||
31 | |||
32 | /** |
||
33 | * Is the fixer enabled and fixing a file? |
||
34 | * |
||
35 | * Sniffs should check this value to ensure they are not |
||
36 | * doing extra processing to prepare for a fix when fixing is |
||
37 | * not required. |
||
38 | * |
||
39 | * @var boolean |
||
40 | */ |
||
41 | public $enabled = false; |
||
42 | |||
43 | /** |
||
44 | * The number of times we have looped over a file. |
||
45 | * |
||
46 | * @var int |
||
47 | */ |
||
48 | public $loops = 0; |
||
49 | |||
50 | /** |
||
51 | * The file being fixed. |
||
52 | * |
||
53 | * @var PHP_CodeSniffer_File |
||
54 | */ |
||
55 | private $_currentFile = null; |
||
56 | |||
57 | /** |
||
58 | * The list of tokens that make up the file contents. |
||
59 | * |
||
60 | * This is a simplified list which just contains the token content and nothing |
||
61 | * else. This is the array that is updated as fixes are made, not the file's |
||
62 | * token array. Imploding this array will give you the file content back. |
||
63 | * |
||
64 | * @var array(int => string) |
||
65 | */ |
||
66 | private $_tokens = array(); |
||
67 | |||
68 | /** |
||
69 | * A list of tokens that have already been fixed. |
||
70 | * |
||
71 | * We don't allow the same token to be fixed more than once each time |
||
72 | * through a file as this can easily cause conflicts between sniffs. |
||
73 | * |
||
74 | * @var array(int) |
||
75 | */ |
||
76 | private $_fixedTokens = array(); |
||
77 | |||
78 | /** |
||
79 | * The last value of each fixed token. |
||
80 | * |
||
81 | * If a token is being "fixed" back to its last value, the fix is |
||
82 | * probably conflicting with another. |
||
83 | * |
||
84 | * @var array(int => string) |
||
85 | */ |
||
86 | private $_oldTokenValues = array(); |
||
87 | |||
88 | /** |
||
89 | * A list of tokens that have been fixed during a changeset. |
||
90 | * |
||
91 | * All changes in changeset must be able to be applied, or else |
||
92 | * the entire changeset is rejected. |
||
93 | * |
||
94 | * @var array() |
||
95 | */ |
||
96 | private $_changeset = array(); |
||
97 | |||
98 | /** |
||
99 | * Is there an open changeset. |
||
100 | * |
||
101 | * @var boolean |
||
102 | */ |
||
103 | private $_inChangeset = false; |
||
104 | |||
105 | /** |
||
106 | * Is the current fixing loop in conflict? |
||
107 | * |
||
108 | * @var boolean |
||
109 | */ |
||
110 | private $_inConflict = false; |
||
111 | |||
112 | /** |
||
113 | * The number of fixes that have been performed. |
||
114 | * |
||
115 | * @var int |
||
116 | */ |
||
117 | private $_numFixes = 0; |
||
118 | |||
119 | |||
120 | /** |
||
121 | * Starts fixing a new file. |
||
122 | * |
||
123 | * @param PHP_CodeSniffer_File $phpcsFile The file being fixed. |
||
124 | * |
||
125 | * @return void |
||
126 | */ |
||
127 | public function startFile($phpcsFile) |
||
144 | |||
145 | |||
146 | /** |
||
147 | * Attempt to fix the file by processing it until no fixes are made. |
||
148 | * |
||
149 | * @return boolean |
||
150 | */ |
||
151 | public function fixFile() |
||
228 | |||
229 | |||
230 | /** |
||
231 | * Generates a text diff of the original file and the new content. |
||
232 | * |
||
233 | * @param string $filePath Optional file path to diff the file against. |
||
234 | * If not specified, the original version of the |
||
235 | * file will be used. |
||
236 | * @param boolean $colors Print colored output or not. |
||
237 | * |
||
238 | * @return string |
||
239 | */ |
||
240 | public function generateDiff($filePath=null, $colors=true) |
||
303 | |||
304 | |||
305 | /** |
||
306 | * Get a count of fixes that have been performed on the file. |
||
307 | * |
||
308 | * This value is reset every time a new file is started, or an existing |
||
309 | * file is restarted. |
||
310 | * |
||
311 | * @return int |
||
312 | */ |
||
313 | public function getFixCount() |
||
318 | |||
319 | |||
320 | /** |
||
321 | * Get the current content of the file, as a string. |
||
322 | * |
||
323 | * @return string |
||
324 | */ |
||
325 | public function getContents() |
||
331 | |||
332 | |||
333 | /** |
||
334 | * Get the current fixed content of a token. |
||
335 | * |
||
336 | * This function takes changesets into account so should be used |
||
337 | * instead of directly accessing the token array. |
||
338 | * |
||
339 | * @param int $stackPtr The position of the token in the token stack. |
||
340 | * |
||
341 | * @return string |
||
342 | */ |
||
343 | public function getTokenContent($stackPtr) |
||
354 | |||
355 | |||
356 | /** |
||
357 | * Start recording actions for a changeset. |
||
358 | * |
||
359 | * @return void |
||
360 | */ |
||
361 | public function beginChangeset() |
||
381 | |||
382 | |||
383 | /** |
||
384 | * Stop recording actions for a changeset, and apply logged changes. |
||
385 | * |
||
386 | * @return boolean |
||
387 | */ |
||
388 | public function endChangeset() |
||
428 | |||
429 | |||
430 | /** |
||
431 | * Stop recording actions for a changeset, and discard logged changes. |
||
432 | * |
||
433 | * @return void |
||
434 | */ |
||
435 | public function rollbackChangeset() |
||
463 | |||
464 | |||
465 | /** |
||
466 | * Replace the entire contents of a token. |
||
467 | * |
||
468 | * @param int $stackPtr The position of the token in the token stack. |
||
469 | * @param string $content The new content of the token. |
||
470 | * |
||
471 | * @return bool If the change was accepted. |
||
472 | */ |
||
473 | public function replaceToken($stackPtr, $content) |
||
590 | |||
591 | |||
592 | /** |
||
593 | * Reverts the previous fix made to a token. |
||
594 | * |
||
595 | * @param int $stackPtr The position of the token in the token stack. |
||
596 | * |
||
597 | * @return bool If a change was reverted. |
||
598 | */ |
||
599 | public function revertToken($stackPtr) |
||
645 | |||
646 | |||
647 | /** |
||
648 | * Replace the content of a token with a part of its current content. |
||
649 | * |
||
650 | * @param int $stackPtr The position of the token in the token stack. |
||
651 | * @param int $start The first character to keep. |
||
652 | * @param int $length The number of chacters to keep. If NULL, the content of |
||
653 | * the token from $start to the end of the content is kept. |
||
654 | * |
||
655 | * @return bool If the change was accepted. |
||
656 | */ |
||
657 | public function substrToken($stackPtr, $start, $length=null) |
||
670 | |||
671 | |||
672 | /** |
||
673 | * Adds a newline to end of a token's content. |
||
674 | * |
||
675 | * @param int $stackPtr The position of the token in the token stack. |
||
676 | * |
||
677 | * @return bool If the change was accepted. |
||
678 | */ |
||
679 | public function addNewline($stackPtr) |
||
685 | |||
686 | |||
687 | /** |
||
688 | * Adds a newline to the start of a token's content. |
||
689 | * |
||
690 | * @param int $stackPtr The position of the token in the token stack. |
||
691 | * |
||
692 | * @return bool If the change was accepted. |
||
693 | */ |
||
694 | public function addNewlineBefore($stackPtr) |
||
700 | |||
701 | |||
702 | /** |
||
703 | * Adds content to the end of a token's current content. |
||
704 | * |
||
705 | * @param int $stackPtr The position of the token in the token stack. |
||
706 | * @param string $content The content to add. |
||
707 | * |
||
708 | * @return bool If the change was accepted. |
||
709 | */ |
||
710 | public function addContent($stackPtr, $content) |
||
716 | |||
717 | |||
718 | /** |
||
719 | * Adds content to the start of a token's current content. |
||
720 | * |
||
721 | * @param int $stackPtr The position of the token in the token stack. |
||
722 | * @param string $content The content to add. |
||
723 | * |
||
724 | * @return bool If the change was accepted. |
||
725 | */ |
||
726 | public function addContentBefore($stackPtr, $content) |
||
732 | |||
733 | |||
734 | }//end class |
||
735 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.