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 |
||
9 | class PseudoMatcher { |
||
10 | private $pseudo; |
||
11 | private $dataFunction; |
||
12 | |||
13 | public function __construct($pseudo, DataFunction $dataFunction) { |
||
17 | |||
18 | public function matches($element) { |
||
19 | $matches = true; |
||
20 | $functions = ['attribute', 'nth', 'not']; |
||
21 | |||
22 | foreach ($this->pseudo as $pseudo) { |
||
23 | foreach ($functions as $func) { |
||
24 | $matches = $matches && $this->$func($pseudo, $element); |
||
25 | } |
||
26 | } |
||
27 | return $matches; |
||
28 | } |
||
29 | |||
30 | private function attribute($pseudo, $element) { |
||
31 | $pos = strpos($pseudo, '['); |
||
32 | if ($pos === false) return true; |
||
33 | |||
34 | $name = substr($pseudo, 0, $pos); |
||
35 | if (!is_callable([$this->dataFunction, $name])) return true; |
||
36 | |||
37 | $bracketMatcher = new \Transphporm\Parser\BracketMatcher($pseudo); |
||
38 | $criteria = $bracketMatcher->match('[', ']'); |
||
39 | |||
40 | if (strpos($pseudo, '=') === false) { |
||
41 | $lookupValue = $this->dataFunction->$name([$criteria], $element); |
||
42 | return $lookupValue !== null; |
||
43 | } |
||
44 | list ($field, $value) = explode('=', $criteria); |
||
45 | |||
46 | $operator = $this->getOperator($field); |
||
47 | $lookupValue = $this->dataFunction->$name([trim($field, $operator)], $element); |
||
48 | |||
49 | return $this->processOperator($operator, $lookupValue, $this->parseValue(trim($value, '"'))); |
||
50 | } |
||
51 | |||
52 | //Currently only not is supported, but this is separated out to support others in future |
||
53 | private function processOperator($operator, $lookupValue, $value) { |
||
54 | $matched = $lookupValue == $value; |
||
55 | return $operator === '!' ? !$matched : $matched; |
||
56 | } |
||
57 | |||
58 | private function parseValue($value) { |
||
63 | |||
64 | private function getOperator($field) { |
||
70 | |||
71 | private function nth($pseudo, $element) { |
||
72 | if (strpos($pseudo, 'nth-child') === 0) { |
||
73 | $bracketMatcher = new \Transphporm\Parser\BracketMatcher($pseudo); |
||
84 | |||
85 | private function not($pseudo, $element) { |
||
103 | |||
104 | public function attr() { |
||
115 | |||
116 | public function header($element) { |
||
126 | |||
127 | private function odd($num) { |
||
130 | |||
131 | private function even($num) { |
||
134 | |||
135 | public function getPseudo() { |
||
138 | } |
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.