Complex classes like RevisionLog 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 RevisionLog, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class RevisionLog |
||
21 | { |
||
22 | |||
23 | const FLAG_VERBOSE = 1; |
||
24 | |||
25 | const FLAG_MERGE_HISTORY = 2; |
||
26 | |||
27 | /** |
||
28 | * Repository path. |
||
29 | * |
||
30 | * @var string |
||
31 | */ |
||
32 | private $_repositoryRootUrl; |
||
33 | |||
34 | /** |
||
35 | * Project path. |
||
36 | * |
||
37 | * @var string |
||
38 | */ |
||
39 | private $_projectPath; |
||
40 | |||
41 | /** |
||
42 | * Ref name. |
||
43 | * |
||
44 | * @var string |
||
45 | */ |
||
46 | private $_refName; |
||
47 | |||
48 | /** |
||
49 | * Repository connector. |
||
50 | * |
||
51 | * @var Connector |
||
52 | */ |
||
53 | private $_repositoryConnector; |
||
54 | |||
55 | /** |
||
56 | * Console IO. |
||
57 | * |
||
58 | * @var ConsoleIO |
||
59 | */ |
||
60 | private $_io; |
||
61 | |||
62 | /** |
||
63 | * Installed plugins. |
||
64 | * |
||
65 | * @var IPlugin[] |
||
66 | */ |
||
67 | private $_plugins = array(); |
||
68 | |||
69 | /** |
||
70 | * Create revision log. |
||
71 | * |
||
72 | * @param string $repository_url Repository url. |
||
73 | * @param Connector $repository_connector Repository connector. |
||
74 | * @param ConsoleIO $io Console IO. |
||
75 | */ |
||
76 | 18 | public function __construct( |
|
90 | |||
91 | /** |
||
92 | * Queries missing revisions. |
||
93 | * |
||
94 | * @param boolean $is_migration Is migration. |
||
95 | * |
||
96 | * @return void |
||
97 | * @throws \LogicException When no plugins are registered. |
||
98 | */ |
||
99 | 6 | public function refresh($is_migration) |
|
122 | |||
123 | /** |
||
124 | * Reports to each plugin, that database is ready for usage. |
||
125 | * |
||
126 | * @return void |
||
127 | */ |
||
128 | 5 | private function _databaseReady() |
|
134 | |||
135 | /** |
||
136 | * Returns aggregated revision from all plugins. |
||
137 | * |
||
138 | * @param string $function Aggregate function. |
||
139 | * |
||
140 | * @return integer |
||
141 | */ |
||
142 | 5 | private function _getAggregateRevision($function) |
|
156 | |||
157 | /** |
||
158 | * Queries missing revision data. |
||
159 | * |
||
160 | * @param integer $from_revision From revision. |
||
161 | * @param integer $to_revision To revision. |
||
162 | * |
||
163 | * @return void |
||
164 | */ |
||
165 | 3 | private function _queryRevisionData($from_revision, $to_revision) |
|
232 | |||
233 | /** |
||
234 | * Returns arguments for "log" command. |
||
235 | * |
||
236 | * @return string |
||
237 | */ |
||
238 | 3 | private function _getLogCommandArguments() |
|
256 | |||
257 | /** |
||
258 | * Returns revision query flags. |
||
259 | * |
||
260 | * @return array |
||
261 | */ |
||
262 | 3 | private function _getRevisionQueryFlags() |
|
272 | |||
273 | /** |
||
274 | * Parses output of "svn log" command. |
||
275 | * |
||
276 | * @param \SimpleXMLElement $log Log. |
||
277 | * |
||
278 | * @return void |
||
279 | */ |
||
280 | 3 | private function _parseLog(\SimpleXMLElement $log) |
|
286 | |||
287 | /** |
||
288 | * Displays plugin activity statistics. |
||
289 | * |
||
290 | * @return void |
||
291 | */ |
||
292 | 1 | private function _displayPluginActivityStatistics() |
|
308 | |||
309 | /** |
||
310 | * Registers a plugin. |
||
311 | * |
||
312 | * @param IPlugin $plugin Plugin. |
||
313 | * |
||
314 | * @return void |
||
315 | * @throws \LogicException When plugin is registered several times. |
||
316 | */ |
||
317 | 12 | public function registerPlugin(IPlugin $plugin) |
|
328 | |||
329 | /** |
||
330 | * Finds information using plugin. |
||
331 | * |
||
332 | * @param string $plugin_name Plugin name. |
||
333 | * @param array|string $criteria Search criteria. |
||
334 | * |
||
335 | * @return array |
||
336 | */ |
||
337 | 3 | public function find($plugin_name, $criteria) |
|
341 | |||
342 | /** |
||
343 | * Returns information about revisions. |
||
344 | * |
||
345 | * @param string $plugin_name Plugin name. |
||
346 | * @param array $revisions Revisions. |
||
347 | * |
||
348 | * @return array |
||
349 | */ |
||
350 | 3 | public function getRevisionsData($plugin_name, array $revisions) |
|
354 | |||
355 | /** |
||
356 | * Determines if plugin is registered. |
||
357 | * |
||
358 | * @param string $plugin_name Plugin name. |
||
359 | * |
||
360 | * @return boolean |
||
361 | */ |
||
362 | 15 | public function pluginRegistered($plugin_name) |
|
366 | |||
367 | /** |
||
368 | * Returns plugin instance. |
||
369 | * |
||
370 | * @param string $plugin_name Plugin name. |
||
371 | * |
||
372 | * @return IPlugin |
||
373 | * @throws \InvalidArgumentException When unknown plugin is given. |
||
374 | */ |
||
375 | 8 | public function getPlugin($plugin_name) |
|
383 | |||
384 | /** |
||
385 | * Returns bugs, from revisions. |
||
386 | * |
||
387 | * @param array $revisions Revisions. |
||
388 | * |
||
389 | * @return array |
||
390 | */ |
||
391 | 1 | public function getBugsFromRevisions(array $revisions) |
|
406 | |||
407 | /** |
||
408 | * Returns repository collector plugins. |
||
409 | * |
||
410 | * @return IRepositoryCollectorPlugin[] |
||
411 | */ |
||
412 | 3 | protected function getRepositoryCollectorPlugins() |
|
418 | |||
419 | /** |
||
420 | * Returns database collector plugins. |
||
421 | * |
||
422 | * @return IDatabaseCollectorPlugin[] |
||
423 | */ |
||
424 | 3 | protected function getDatabaseCollectorPlugins() |
|
430 | |||
431 | /** |
||
432 | * Returns plugin list filtered by interface. |
||
433 | * |
||
434 | * @param string $interface Interface name. |
||
435 | * |
||
436 | * @return IPlugin[] |
||
437 | */ |
||
438 | 3 | protected function getPluginsByInterface($interface) |
|
450 | |||
451 | /** |
||
452 | * Returns project path. |
||
453 | * |
||
454 | * @return string |
||
455 | */ |
||
456 | 1 | public function getProjectPath() |
|
460 | |||
461 | /** |
||
462 | * Returns ref name. |
||
463 | * |
||
464 | * @return string |
||
465 | */ |
||
466 | 1 | public function getRefName() |
|
470 | |||
471 | } |
||
472 |
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.