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 Lexical extends Analyse implements AnalyseInterface |
||
10 | { |
||
11 | /** |
||
12 | * @var string The description for fields with invalid formats. |
||
13 | */ |
||
14 | const ERROR_INVALID_PATTERN = 'There are <strong>%d</strong> fields that don\'t have the correct pattern:'; |
||
15 | |||
16 | /** |
||
17 | * @var string The description for fields with invalid formats. |
||
18 | */ |
||
19 | const ERROR_INVALID_FORMAT = 'There are <strong>%d</strong> fields that don\'t have the correct format:'; |
||
20 | |||
21 | /** |
||
22 | * @var string The description for rows with missing columns. |
||
23 | */ |
||
24 | const ERROR_REQUIRED_FIELD_MISSING_DATA = 'There are <strong>%d</strong> required fields with missing data:'; |
||
25 | |||
26 | /** |
||
27 | * @var string The description for rows with missing columns. |
||
28 | */ |
||
29 | const ERROR_INCORRECT_COLUMN_COUNT = 'There are the wrong number of columns'; |
||
30 | |||
31 | /** |
||
32 | * @var array The current CSV row being analysed. |
||
33 | */ |
||
34 | private $currentCsvRow; |
||
35 | |||
36 | /** |
||
37 | * @var int The position of the CSV column currently being analysed. |
||
38 | */ |
||
39 | private $csvColumnPosition; |
||
40 | |||
41 | /** |
||
42 | * @var int The position of the current CSV row row in the CSV file. |
||
43 | */ |
||
44 | private $rowNumber; |
||
45 | |||
46 | /** |
||
47 | * @var object The schema definition for the column currently being analysed. |
||
48 | */ |
||
49 | private $schemaColumn; |
||
50 | |||
51 | /** |
||
52 | * @var int The number of columns in the currently analysed row. |
||
53 | */ |
||
54 | private $columnCount; |
||
55 | |||
56 | /** |
||
57 | * @var int The number of columns expected in each row. |
||
58 | * This is taken from the CSV header row. |
||
59 | */ |
||
60 | private $expectedColumnCount; |
||
61 | |||
62 | /** |
||
63 | * @var string The pattern to validate the current field against. |
||
64 | */ |
||
65 | private $pattern; |
||
66 | |||
67 | /** |
||
68 | * @var string The format to validate the current field against. |
||
69 | */ |
||
70 | private $format; |
||
71 | |||
72 | /** |
||
73 | * @var bool Whether the file is valid. |
||
74 | */ |
||
75 | private $valid; |
||
76 | |||
77 | |||
78 | /** |
||
79 | * Validate that all fields are of the correct type, format and pattern. |
||
80 | * This also checks that each CSV row has the expected number of columns. |
||
81 | * |
||
82 | * @return boolean Is all data lexically valid. |
||
83 | */ |
||
84 | 28 | public function validate() |
|
133 | |||
134 | |||
135 | /** |
||
136 | * Check that the specified row has the expected number of columns. |
||
137 | * The expected number of columns is the number of columns in the CSV header row. |
||
138 | * |
||
139 | * @return boolean Whether the current row has the expected number of columns. |
||
140 | */ |
||
141 | 28 | private function checkRowHasExpectedColumnCount() |
|
148 | |||
149 | |||
150 | /** |
||
151 | * Set an error and update the application as the current row has an unexpected number of columns. |
||
152 | * |
||
153 | * @return void |
||
154 | */ |
||
155 | private function handleUnexpectedColumnCount() |
||
161 | |||
162 | |||
163 | /** |
||
164 | * Check whether the current column is mandatory and if so, whether it has data in it. |
||
165 | * |
||
166 | * @return boolean Whether the column has data in it. |
||
167 | */ |
||
168 | 28 | private function checkMandatoryColumnHasData() |
|
176 | |||
177 | |||
178 | /** |
||
179 | * Set an error and update the application as the current column is mandatory and has no data in it. |
||
180 | * |
||
181 | * @return void |
||
182 | */ |
||
183 | 2 | View Code Duplication | private function handleInvalidMandatoryColumn() |
190 | |||
191 | |||
192 | /** |
||
193 | * Check that the data in the current field is of a valid format as specified in the schema for this column. |
||
194 | * This instantiates and passed the data to the format validator for this field type. |
||
195 | * |
||
196 | * @return boolean Whether the current field is of a valid format. |
||
197 | */ |
||
198 | 28 | private function validateSpecificFormat() |
|
207 | |||
208 | |||
209 | /** |
||
210 | * Set an error and update the application as the current data didn't match the specified format. |
||
211 | * |
||
212 | * @return void |
||
213 | */ |
||
214 | 8 | View Code Duplication | private function handleInvalidFormat() |
222 | |||
223 | |||
224 | /** |
||
225 | * Get the pattern of the specified column. |
||
226 | * |
||
227 | * @return string The pattern or null if no pattern is specified. |
||
228 | */ |
||
229 | 28 | private function getColumnPattern() |
|
236 | |||
237 | |||
238 | /** |
||
239 | * Check that the input matches the specified pattern. |
||
240 | * |
||
241 | * @return boolean Is the data valid. |
||
242 | */ |
||
243 | 28 | private function validatePattern() |
|
254 | |||
255 | |||
256 | /** |
||
257 | * Set an error and update the application as the current data didn't match the specified pattern. |
||
258 | * |
||
259 | * @return void |
||
260 | */ |
||
261 | View Code Duplication | private function handleInvalidPattern() |
|
269 | |||
270 | |||
271 | /** |
||
272 | * Add the number of rows analysed to the statistics. |
||
273 | * |
||
274 | * @return void |
||
275 | */ |
||
276 | 28 | private function setRowsAnalysedStatistic() |
|
280 | } |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.