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 |
||
| 25 | class EditCounterController extends Controller |
||
| 26 | { |
||
| 27 | |||
| 28 | /** @var User The user being queried. */ |
||
| 29 | protected $user; |
||
| 30 | |||
| 31 | /** @var Project The project being queried. */ |
||
| 32 | protected $project; |
||
| 33 | |||
| 34 | /** @var EditCounter The edit-counter, that does all the work. */ |
||
| 35 | protected $editCounter; |
||
| 36 | |||
| 37 | /** |
||
| 38 | * Get the tool's shortname. |
||
| 39 | * @return string |
||
| 40 | */ |
||
| 41 | public function getToolShortname() |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Every action in this controller (other than 'index') calls this first. |
||
| 48 | * If a response is returned, the calling action is expected to return it. |
||
| 49 | * @param string|bool $project The project name. |
||
| 50 | * @param string|bool $username The username. |
||
| 51 | * @return null|RedirectResponse |
||
| 52 | */ |
||
| 53 | protected function setUpEditCounter($project = false, $username = false) |
||
| 73 | |||
| 74 | /** |
||
| 75 | * The initial GET request that displays the search form. |
||
| 76 | * |
||
| 77 | * @Route("/ec", name="ec") |
||
| 78 | * @Route("/ec", name="EditCounter") |
||
| 79 | * @Route("/ec/", name="EditCounterSlash") |
||
| 80 | * @Route("/ec/index.php", name="EditCounterIndexPhp") |
||
| 81 | * @Route("/ec/{project}", name="EditCounterProject") |
||
| 82 | * |
||
| 83 | * @param Request $request |
||
| 84 | * @param string|null $project |
||
| 85 | * @return RedirectResponse|Response |
||
| 86 | */ |
||
| 87 | public function indexAction(Request $request, $project = null) |
||
| 112 | |||
| 113 | /** |
||
| 114 | * Display all results. |
||
| 115 | * @Route("/ec/{project}/{username}", name="EditCounterResult") |
||
| 116 | * @param Request $request |
||
| 117 | * @param string $project |
||
| 118 | * @param string $username |
||
| 119 | * @return Response |
||
| 120 | */ |
||
| 121 | public function resultAction(Request $request, $project, $username) |
||
| 148 | |||
| 149 | /** |
||
| 150 | * Display the general statistics section. |
||
| 151 | * @Route("/ec-generalstats/{project}/{username}", name="EditCounterGeneralStats") |
||
| 152 | * @param string $project |
||
| 153 | * @param string $username |
||
| 154 | * @return Response |
||
| 155 | */ |
||
| 156 | View Code Duplication | public function generalStatsAction($project, $username) |
|
| 173 | |||
| 174 | /** |
||
| 175 | * Display the namespace totals section. |
||
| 176 | * @Route("/ec-namespacetotals/{project}/{username}", name="EditCounterNamespaceTotals") |
||
| 177 | * @param Request $request |
||
| 178 | * @param string $project |
||
| 179 | * @param string $username |
||
| 180 | * @return Response |
||
| 181 | */ |
||
| 182 | View Code Duplication | public function namespaceTotalsAction(Request $request, $project, $username) |
|
| 199 | |||
| 200 | /** |
||
| 201 | * Display the timecard section. |
||
| 202 | * @Route("/ec-timecard/{project}/{username}", name="EditCounterTimecard") |
||
| 203 | * @param string $project |
||
| 204 | * @param string $username |
||
| 205 | * @return Response |
||
| 206 | */ |
||
| 207 | View Code Duplication | public function timecardAction($project, $username) |
|
| 228 | |||
| 229 | /** |
||
| 230 | * Display the year counts section. |
||
| 231 | * @Route("/ec-yearcounts/{project}/{username}", name="EditCounterYearCounts") |
||
| 232 | * @param string $project |
||
| 233 | * @param string $username |
||
| 234 | * @return Response |
||
| 235 | */ |
||
| 236 | View Code Duplication | public function yearcountsAction($project, $username) |
|
| 253 | |||
| 254 | /** |
||
| 255 | * Display the month counts section. |
||
| 256 | * @Route("/ec-monthcounts/{project}/{username}", name="EditCounterMonthCounts") |
||
| 257 | * @param Request $request |
||
| 258 | * @param string $project |
||
| 259 | * @param string $username |
||
| 260 | * @return Response |
||
| 261 | */ |
||
| 262 | View Code Duplication | public function monthcountsAction(Request $request, $project, $username) |
|
| 283 | |||
| 284 | /** |
||
| 285 | * Display the latest global edits section. |
||
| 286 | * @Route("/ec-latestglobal/{project}/{username}", name="EditCounterLatestGlobal") |
||
| 287 | * @param Request $request The HTTP request. |
||
| 288 | * @param string $project The project name. |
||
| 289 | * @param string $username The username. |
||
| 290 | * @return Response |
||
| 291 | */ |
||
| 292 | View Code Duplication | public function latestglobalAction(Request $request, $project, $username) |
|
| 310 | |||
| 311 | |||
| 312 | /** |
||
| 313 | * Below are internal API endpoints for the Edit Counter. |
||
| 314 | * All only respond with JSON and only to requests from the localhost |
||
| 315 | * (see access_control in security.yml). |
||
| 316 | */ |
||
| 317 | |||
| 318 | /** |
||
| 319 | * Get (most) of the general statistics as JSON. |
||
| 320 | * @Route("/api/ec/pairdata/{project}/{username}", name="EditCounterApiPairData") |
||
| 321 | * @param Request $request |
||
| 322 | * @param string $project |
||
| 323 | * @param string $username |
||
| 324 | * @return JsonResponse |
||
| 325 | */ |
||
| 326 | View Code Duplication | public function pairDataApiAction(Request $request, $project, $username) |
|
| 338 | |||
| 339 | /** |
||
| 340 | * Get various log counts for the user as JSON. |
||
| 341 | * @Route("/api/ec/logcounts/{project}/{username}", name="EditCounterApiLogCounts") |
||
| 342 | * @param Request $request |
||
| 343 | * @param string $project |
||
| 344 | * @param string $username |
||
| 345 | * @return JsonResponse |
||
| 346 | */ |
||
| 347 | View Code Duplication | public function logCountsApiAction(Request $request, $project, $username) |
|
| 359 | |||
| 360 | /** |
||
| 361 | * Get edit sizes for the user as JSON. |
||
| 362 | * @Route("/api/ec/editsizes/{project}/{username}", name="EditCounterApiEditSizes") |
||
| 363 | * @param Request $request |
||
| 364 | * @param string $project |
||
| 365 | * @param string $username |
||
| 366 | * @return JsonResponse |
||
| 367 | */ |
||
| 368 | View Code Duplication | public function editSizesApiAction(Request $request, $project, $username) |
|
| 380 | |||
| 381 | /** |
||
| 382 | * Get the namespace totals for the user as JSON. |
||
| 383 | * @Route("/api/ec/namespacetotals/{project}/{username}", name="EditCounterApiNamespaceTotals") |
||
| 384 | * @param Request $request |
||
| 385 | * @param string $project |
||
| 386 | * @param string $username |
||
| 387 | * @return Response |
||
| 388 | */ |
||
| 389 | View Code Duplication | public function namespaceTotalsApiAction(Request $request, $project, $username) |
|
| 401 | |||
| 402 | /** |
||
| 403 | * Display or fetch the month counts for the user. |
||
| 404 | * @Route("/api/ec/monthcounts/{project}/{username}", name="EditCounterApiMonthCounts") |
||
| 405 | * @param Request $request |
||
| 406 | * @param string $project |
||
| 407 | * @param string $username |
||
| 408 | * @return Response |
||
| 409 | */ |
||
| 410 | View Code Duplication | public function monthcountsApiAction(Request $request, $project, $username) |
|
| 422 | } |
||
| 423 |
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.