Complex classes like ArticleInfo 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 ArticleInfo, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 16 | class ArticleInfo extends Model |
||
| 17 | { |
||
| 18 | /** @var Container The application's DI container. */ |
||
| 19 | protected $container; |
||
| 20 | |||
| 21 | /** @var Page The page. */ |
||
| 22 | protected $page; |
||
| 23 | |||
| 24 | /** @var int Number of revisions that belong to the page. */ |
||
| 25 | protected $numRevisions; |
||
| 26 | |||
| 27 | /** @var int Maximum number of revisions to process, as configured. */ |
||
| 28 | protected $maxRevisions; |
||
| 29 | |||
| 30 | /** @var int Number of revisions that were actually processed. */ |
||
| 31 | protected $numRevisionsProcessed; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * Various statistics about editors to the page. These are not User objects |
||
| 35 | * so as to preserve memory. |
||
| 36 | * @var mixed[] |
||
| 37 | */ |
||
| 38 | protected $editors; |
||
| 39 | |||
| 40 | /** @var mixed[] The top 10 editors to the page by number of edits. */ |
||
| 41 | protected $topTenEditorsByEdits; |
||
| 42 | |||
| 43 | /** @var mixed[] The top 10 editors to the page by added text. */ |
||
| 44 | protected $topTenEditorsByAdded; |
||
| 45 | |||
| 46 | /** @var int Number of edits made by the top 10 editors. */ |
||
| 47 | protected $topTenCount; |
||
| 48 | |||
| 49 | /** @var mixed[] Various statistics about bots that edited the page. */ |
||
| 50 | protected $bots; |
||
| 51 | |||
| 52 | /** @var int Number of edits made to the page by bots. */ |
||
| 53 | protected $botRevisionCount; |
||
| 54 | |||
| 55 | /** @var mixed[] Various counts about each individual year and month of the page's history. */ |
||
| 56 | protected $yearMonthCounts; |
||
| 57 | |||
| 58 | /** @var Edit The first edit to the page. */ |
||
| 59 | protected $firstEdit; |
||
| 60 | |||
| 61 | /** @var Edit The last edit to the page. */ |
||
| 62 | protected $lastEdit; |
||
| 63 | |||
| 64 | /** @var Edit Edit that made the largest addition by number of bytes. */ |
||
| 65 | protected $maxAddition; |
||
| 66 | |||
| 67 | /** @var Edit Edit that made the largest deletion by number of bytes. */ |
||
| 68 | protected $maxDeletion; |
||
| 69 | |||
| 70 | /** @var int[] Number of in and outgoing links and redirects to the page. */ |
||
| 71 | protected $linksAndRedirects; |
||
| 72 | |||
| 73 | /** @var string[] Assessments of the page (see Page::getAssessments). */ |
||
| 74 | protected $assessments; |
||
| 75 | |||
| 76 | /** |
||
| 77 | * Maximum number of edits that were created across all months. This is used as a comparison |
||
| 78 | * for the bar charts in the months section. |
||
| 79 | * @var int |
||
| 80 | */ |
||
| 81 | protected $maxEditsPerMonth; |
||
| 82 | |||
| 83 | /** @var string[] List of (semi-)automated tools that were used to edit the page. */ |
||
| 84 | protected $tools; |
||
| 85 | |||
| 86 | /** |
||
| 87 | * Total number of bytes added throughout the page's history. This is used as a comparison |
||
| 88 | * when computing the top 10 editors by added text. |
||
| 89 | * @var int |
||
| 90 | */ |
||
| 91 | protected $addedBytes = 0; |
||
| 92 | |||
| 93 | /** @var int Number of days between first and last edit. */ |
||
| 94 | protected $totalDays; |
||
| 95 | |||
| 96 | /** @var int Number of minor edits to the page. */ |
||
| 97 | protected $minorCount = 0; |
||
| 98 | |||
| 99 | /** @var int Number of anonymous edits to the page. */ |
||
| 100 | protected $anonCount = 0; |
||
| 101 | |||
| 102 | /** @var int Number of automated edits to the page. */ |
||
| 103 | protected $automatedCount = 0; |
||
| 104 | |||
| 105 | /** @var int Number of edits to the page that were reverted with the subsequent edit. */ |
||
| 106 | protected $revertCount = 0; |
||
| 107 | |||
| 108 | /** @var int[] The "edits per <time>" counts. */ |
||
| 109 | protected $countHistory = [ |
||
| 110 | 'day' => 0, |
||
| 111 | 'week' => 0, |
||
| 112 | 'month' => 0, |
||
| 113 | 'year' => 0 |
||
| 114 | ]; |
||
| 115 | |||
| 116 | /** @var string[] List of wikidata and Checkwiki errors. */ |
||
| 117 | protected $bugs; |
||
| 118 | |||
| 119 | /** |
||
| 120 | * ArticleInfo constructor. |
||
| 121 | * @param Page $page The page to process. |
||
| 122 | * @param Container $container The DI container. |
||
| 123 | */ |
||
| 124 | public function __construct(Page $page, Container $container) |
||
| 133 | |||
| 134 | /** |
||
| 135 | * Shorthand to get the page's project. |
||
| 136 | * @return Project |
||
| 137 | */ |
||
| 138 | public function getProject() |
||
| 142 | |||
| 143 | /** |
||
| 144 | * Get the number of revisions belonging to the page. |
||
| 145 | * @return int |
||
| 146 | */ |
||
| 147 | public function getNumRevisions() |
||
| 154 | |||
| 155 | /** |
||
| 156 | * Get the maximum number of revisions that we should process. |
||
| 157 | * @return int |
||
| 158 | */ |
||
| 159 | public function getMaxRevisions() |
||
| 166 | |||
| 167 | /** |
||
| 168 | * Get the number of revisions that are actually getting processed. |
||
| 169 | * This goes by the app.max_page_revisions parameter, or the actual |
||
| 170 | * number of revisions, whichever is smaller. |
||
| 171 | * @return int |
||
| 172 | */ |
||
| 173 | public function getNumRevisionsProcessed() |
||
| 187 | |||
| 188 | /** |
||
| 189 | * Are there more revisions than we should process, based on the config? |
||
| 190 | * @return bool |
||
| 191 | */ |
||
| 192 | public function tooManyRevisions() |
||
| 196 | |||
| 197 | /** |
||
| 198 | * Fetch and store all the data we need to show the ArticleInfo view. |
||
| 199 | */ |
||
| 200 | public function prepareData() |
||
| 207 | |||
| 208 | /** |
||
| 209 | * Get the number of editors that edited the page. |
||
| 210 | * @return int |
||
| 211 | */ |
||
| 212 | public function numEditors() |
||
| 216 | |||
| 217 | /** |
||
| 218 | * Get the number of bots that edited the page. |
||
| 219 | * @return int |
||
| 220 | */ |
||
| 221 | public function numBots() |
||
| 225 | |||
| 226 | /** |
||
| 227 | * Get the number of days between the first and last edit. |
||
| 228 | * @return int |
||
| 229 | */ |
||
| 230 | public function getTotalDays() |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Get the average number of days between edits to the page. |
||
| 243 | * @return double |
||
| 244 | */ |
||
| 245 | public function averageDaysPerEdit() |
||
| 249 | |||
| 250 | /** |
||
| 251 | * Get the average number of edits per day to the page. |
||
| 252 | * @return double |
||
| 253 | */ |
||
| 254 | public function editsPerDay() |
||
| 261 | |||
| 262 | /** |
||
| 263 | * Get the average number of edits per month to the page. |
||
| 264 | * @return double |
||
| 265 | */ |
||
| 266 | public function editsPerMonth() |
||
| 273 | |||
| 274 | /** |
||
| 275 | * Get the average number of edits per year to the page. |
||
| 276 | * @return double |
||
| 277 | */ |
||
| 278 | public function editsPerYear() |
||
| 285 | |||
| 286 | /** |
||
| 287 | * Get the average number of edits per editor. |
||
| 288 | * @return double |
||
| 289 | */ |
||
| 290 | public function editsPerEditor() |
||
| 294 | |||
| 295 | /** |
||
| 296 | * Get the percentage of minor edits to the page. |
||
| 297 | * @return double |
||
| 298 | */ |
||
| 299 | public function minorPercentage() |
||
| 306 | |||
| 307 | /** |
||
| 308 | * Get the percentage of anonymous edits to the page. |
||
| 309 | * @return double |
||
| 310 | */ |
||
| 311 | public function anonPercentage() |
||
| 318 | |||
| 319 | /** |
||
| 320 | * Get the percentage of edits made by the top 10 editors. |
||
| 321 | * @return double |
||
| 322 | */ |
||
| 323 | public function topTenPercentage() |
||
| 327 | |||
| 328 | /** |
||
| 329 | * Get the number of times the page has been viewed in the given timeframe. |
||
| 330 | * @param int $latest Last N days. |
||
| 331 | * @return int |
||
| 332 | */ |
||
| 333 | public function getPageviews($latest) |
||
| 337 | |||
| 338 | /** |
||
| 339 | * Get the page assessments of the page. |
||
| 340 | * @see https://www.mediawiki.org/wiki/Extension:PageAssessments |
||
| 341 | * @return string[]|false False if unsupported. |
||
| 342 | */ |
||
| 343 | public function getAssessments() |
||
| 350 | |||
| 351 | /** |
||
| 352 | * Get the number of automated edits made to the page. |
||
| 353 | * @return int |
||
| 354 | */ |
||
| 355 | public function getAutomatedCount() |
||
| 359 | |||
| 360 | /** |
||
| 361 | * Get the number of edits to the page that were reverted with the subsequent edit. |
||
| 362 | * @return int |
||
| 363 | */ |
||
| 364 | public function getRevertCount() |
||
| 368 | |||
| 369 | /** |
||
| 370 | * Get the number of edits to the page made by logged out users. |
||
| 371 | * @return int |
||
| 372 | */ |
||
| 373 | public function getAnonCount() |
||
| 377 | |||
| 378 | /** |
||
| 379 | * Get the number of minor edits to the page. |
||
| 380 | * @return int |
||
| 381 | */ |
||
| 382 | public function getMinorCount() |
||
| 386 | |||
| 387 | /** |
||
| 388 | * Get the number edits to the page made by bots. |
||
| 389 | * @return int |
||
| 390 | */ |
||
| 391 | public function getBotRevisionCount() |
||
| 395 | |||
| 396 | /** |
||
| 397 | * Get the number of edits to the page made in the past day, week, month and year. |
||
| 398 | * @return int[] With keys 'day', 'week', 'month' and 'year'. |
||
| 399 | */ |
||
| 400 | public function getCountHistory() |
||
| 404 | |||
| 405 | /** |
||
| 406 | * Get the number of edits to the page made by the top 10 editors. |
||
| 407 | * @return int |
||
| 408 | */ |
||
| 409 | public function getTopTenCount() |
||
| 413 | |||
| 414 | /** |
||
| 415 | * Get the first edit to the page. |
||
| 416 | * @return Edit |
||
| 417 | */ |
||
| 418 | public function getFirstEdit() |
||
| 422 | |||
| 423 | /** |
||
| 424 | * Get the last edit to the page. |
||
| 425 | * @return Edit |
||
| 426 | */ |
||
| 427 | public function getLastEdit() |
||
| 431 | |||
| 432 | /** |
||
| 433 | * Get the edit that made the largest addition to the page (by number of bytes). |
||
| 434 | * @return Edit |
||
| 435 | */ |
||
| 436 | public function getMaxAddition() |
||
| 440 | |||
| 441 | /** |
||
| 442 | * Get the edit that made the largest removal to the page (by number of bytes). |
||
| 443 | * @return Edit |
||
| 444 | */ |
||
| 445 | public function getMaxDeletion() |
||
| 449 | |||
| 450 | /** |
||
| 451 | * Get the list of editors to the page, including various statistics. |
||
| 452 | * @return mixed[] |
||
| 453 | */ |
||
| 454 | public function getEditors() |
||
| 458 | |||
| 459 | /** |
||
| 460 | * Get the list of the top editors to the page (by edits), including various statistics. |
||
| 461 | * @return mixed[] |
||
| 462 | */ |
||
| 463 | public function topTenEditorsByEdits() |
||
| 467 | |||
| 468 | /** |
||
| 469 | * Get the list of the top editors to the page (by added text), including various statistics. |
||
| 470 | * @return mixed[] |
||
| 471 | */ |
||
| 472 | public function topTenEditorsByAdded() |
||
| 476 | |||
| 477 | /** |
||
| 478 | * Get the list of bots that edited the page, including various statistics. |
||
| 479 | * @return mixed[] |
||
| 480 | */ |
||
| 481 | public function getBots() |
||
| 485 | |||
| 486 | /** |
||
| 487 | * Get various counts about each individual year and month of the page's history. |
||
| 488 | * @return mixed[] |
||
| 489 | */ |
||
| 490 | public function getYearMonthCounts() |
||
| 494 | |||
| 495 | /** |
||
| 496 | * Get the maximum number of edits that were created across all months. This is used as a |
||
| 497 | * comparison for the bar charts in the months section. |
||
| 498 | * @return int |
||
| 499 | */ |
||
| 500 | public function getMaxEditsPerMonth() |
||
| 504 | |||
| 505 | /** |
||
| 506 | * Get a list of (semi-)automated tools that were used to edit the page, including |
||
| 507 | * the number of times they were used, and a link to the tool's homepage. |
||
| 508 | * @return mixed[] |
||
| 509 | */ |
||
| 510 | public function getTools() |
||
| 514 | |||
| 515 | /** |
||
| 516 | * Get the list of page's wikidata and Checkwiki errors. |
||
| 517 | * @see Page::getErrors() |
||
| 518 | * @return string[] |
||
| 519 | */ |
||
| 520 | public function getBugs() |
||
| 527 | |||
| 528 | /** |
||
| 529 | * Get the number of wikidata nad CheckWiki errors. |
||
| 530 | * @return int |
||
| 531 | */ |
||
| 532 | public function numBugs() |
||
| 536 | |||
| 537 | /** |
||
| 538 | * Get the number of external links on the page. |
||
| 539 | * @return int |
||
| 540 | */ |
||
| 541 | public function linksExtCount() |
||
| 545 | |||
| 546 | /** |
||
| 547 | * Get the number of incoming links to the page. |
||
| 548 | * @return int |
||
| 549 | */ |
||
| 550 | public function linksInCount() |
||
| 554 | |||
| 555 | /** |
||
| 556 | * Get the number of outgoing links from the page. |
||
| 557 | * @return int |
||
| 558 | */ |
||
| 559 | public function linksOutCount() |
||
| 563 | |||
| 564 | /** |
||
| 565 | * Get the number of redirects to the page. |
||
| 566 | * @return int |
||
| 567 | */ |
||
| 568 | public function redirectsCount() |
||
| 572 | |||
| 573 | /** |
||
| 574 | * Get the number of external, incoming and outgoing links, along with |
||
| 575 | * the number of redirects to the page. |
||
| 576 | * @return int |
||
| 577 | */ |
||
| 578 | private function getLinksAndRedirects() |
||
| 585 | |||
| 586 | /** |
||
| 587 | * Parse the revision history, collecting our core statistics. |
||
| 588 | * @todo Break this out into separate functions, perhaps with the loop body |
||
| 589 | * as a separate class. |
||
| 590 | * @return mixed[] Associative "master" array of metadata about the page. |
||
| 591 | */ |
||
| 592 | private function parseHistory() |
||
| 818 | |||
| 819 | /** |
||
| 820 | * Get info about bots that edited the page. |
||
| 821 | * This also sets $this->botRevisionCount and $this->botPercentage. |
||
| 822 | * @return mixed[] Contains the bot's username, edit count to the page, |
||
| 823 | * and whether or not they are currently a bot. |
||
| 824 | */ |
||
| 825 | private function getBotData() |
||
| 864 | |||
| 865 | /** |
||
| 866 | * Query for log events during each year of the article's history, |
||
| 867 | * and set the results in $this->yearMonthCounts. |
||
| 868 | */ |
||
| 869 | private function setLogsEvents() |
||
| 915 | |||
| 916 | /** |
||
| 917 | * Set statistics about the top 10 editors by added text and number of edits. |
||
| 918 | * This is ran *after* parseHistory() since we need the grand totals first. |
||
| 919 | * Various stats are also set for each editor in $this->editors to be used in the charts. |
||
| 920 | * @return integer Number of edits |
||
| 921 | */ |
||
| 922 | private function setTopTenCounts() |
||
| 991 | } |
||
| 992 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: