| Total Complexity | 40 |
| Total Lines | 529 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like EditCounterRepository 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.
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 EditCounterRepository, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 15 | class EditCounterRepository extends UserRightsRepository |
||
| 16 | { |
||
| 17 | /** |
||
| 18 | * Get data about revisions, pages, etc. |
||
| 19 | * @param Project $project The project. |
||
| 20 | * @param User $user The user. |
||
| 21 | * @return string[] With keys: 'deleted', 'live', 'total', 'first', 'last', '24h', '7d', '30d', |
||
| 22 | * '365d', 'small', 'large', 'with_comments', and 'minor_edits', ... |
||
| 23 | */ |
||
| 24 | public function getPairData(Project $project, User $user) |
||
| 25 | { |
||
| 26 | // Set up cache. |
||
| 27 | $cacheKey = $this->getCacheKey(func_get_args(), 'ec_pairdata'); |
||
| 28 | if ($this->cache->hasItem($cacheKey)) { |
||
| 29 | return $this->cache->getItem($cacheKey)->get(); |
||
| 30 | } |
||
| 31 | |||
| 32 | // Prepare the queries and execute them. |
||
| 33 | $archiveTable = $this->getTableName($project->getDatabaseName(), 'archive'); |
||
| 34 | $revisionTable = $this->getTableName($project->getDatabaseName(), 'revision'); |
||
| 35 | |||
| 36 | // For IPs we use rev_user_text, and for accounts rev_user which is slightly faster. |
||
| 37 | $revUserClause = $user->isAnon() ? 'rev_user_text = :username' : 'rev_user = :userId'; |
||
| 38 | $arUserClause = $user->isAnon() ? 'ar_user_text = :username' : 'ar_user = :userId'; |
||
| 39 | |||
| 40 | $sql = " |
||
| 41 | -- Revision counts. |
||
| 42 | (SELECT 'deleted' AS `key`, COUNT(ar_id) AS val FROM $archiveTable |
||
| 43 | WHERE $arUserClause |
||
| 44 | ) UNION ( |
||
| 45 | SELECT 'live' AS `key`, COUNT(rev_id) AS val FROM $revisionTable |
||
| 46 | WHERE $revUserClause |
||
| 47 | ) UNION ( |
||
| 48 | SELECT 'day' AS `key`, COUNT(rev_id) AS val FROM $revisionTable |
||
| 49 | WHERE $revUserClause AND rev_timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY) |
||
| 50 | ) UNION ( |
||
| 51 | SELECT 'week' AS `key`, COUNT(rev_id) AS val FROM $revisionTable |
||
| 52 | WHERE $revUserClause AND rev_timestamp >= DATE_SUB(NOW(), INTERVAL 1 WEEK) |
||
| 53 | ) UNION ( |
||
| 54 | SELECT 'month' AS `key`, COUNT(rev_id) AS val FROM $revisionTable |
||
| 55 | WHERE $revUserClause AND rev_timestamp >= DATE_SUB(NOW(), INTERVAL 1 MONTH) |
||
| 56 | ) UNION ( |
||
| 57 | SELECT 'year' AS `key`, COUNT(rev_id) AS val FROM $revisionTable |
||
| 58 | WHERE $revUserClause AND rev_timestamp >= DATE_SUB(NOW(), INTERVAL 1 YEAR) |
||
| 59 | ) UNION ( |
||
| 60 | SELECT 'with_comments' AS `key`, COUNT(rev_id) AS val FROM $revisionTable |
||
| 61 | WHERE $revUserClause AND rev_comment != '' |
||
| 62 | ) UNION ( |
||
| 63 | SELECT 'minor' AS `key`, COUNT(rev_id) AS val FROM $revisionTable |
||
| 64 | WHERE $revUserClause AND rev_minor_edit = 1 |
||
| 65 | |||
| 66 | -- Dates. |
||
| 67 | ) UNION ( |
||
| 68 | SELECT 'first' AS `key`, rev_timestamp AS `val` FROM $revisionTable |
||
| 69 | WHERE $revUserClause ORDER BY rev_timestamp ASC LIMIT 1 |
||
| 70 | ) UNION ( |
||
| 71 | SELECT 'last' AS `key`, rev_timestamp AS `date` FROM $revisionTable |
||
| 72 | WHERE $revUserClause ORDER BY rev_timestamp DESC LIMIT 1 |
||
| 73 | |||
| 74 | -- Page counts. |
||
| 75 | ) UNION ( |
||
| 76 | SELECT 'edited-live' AS `key`, COUNT(DISTINCT rev_page) AS `val` |
||
| 77 | FROM $revisionTable |
||
| 78 | WHERE $revUserClause |
||
| 79 | ) UNION ( |
||
| 80 | SELECT 'edited-deleted' AS `key`, COUNT(DISTINCT ar_page_id) AS `val` |
||
| 81 | FROM $archiveTable |
||
| 82 | WHERE $arUserClause |
||
| 83 | ) UNION ( |
||
| 84 | SELECT 'created-live' AS `key`, COUNT(DISTINCT rev_page) AS `val` |
||
| 85 | FROM $revisionTable |
||
| 86 | WHERE $revUserClause AND rev_parent_id = 0 |
||
| 87 | ) UNION ( |
||
| 88 | SELECT 'created-deleted' AS `key`, COUNT(DISTINCT ar_page_id) AS `val` |
||
| 89 | FROM $archiveTable |
||
| 90 | WHERE $arUserClause AND ar_parent_id = 0 |
||
| 91 | ) |
||
| 92 | "; |
||
| 93 | |||
| 94 | $params = $user->isAnon() ? ['username' => $user->getUsername()] : ['userId' => $user->getId($project)]; |
||
| 95 | $resultQuery = $this->executeProjectsQuery($sql, $params); |
||
| 96 | |||
| 97 | $revisionCounts = []; |
||
| 98 | while ($result = $resultQuery->fetch()) { |
||
| 99 | $revisionCounts[$result['key']] = $result['val']; |
||
| 100 | } |
||
| 101 | |||
| 102 | // Cache and return. |
||
| 103 | return $this->setCache($cacheKey, $revisionCounts); |
||
| 104 | } |
||
| 105 | |||
| 106 | /** |
||
| 107 | * Get log totals for a user. |
||
| 108 | * @param Project $project The project. |
||
| 109 | * @param User $user The user. |
||
| 110 | * @return integer[] Keys are "<log>-<action>" strings, values are counts. |
||
| 111 | */ |
||
| 112 | public function getLogCounts(Project $project, User $user) |
||
| 189 | } |
||
| 190 | |||
| 191 | /** |
||
| 192 | * Get data for all blocks set on the given user. |
||
| 193 | * @param Project $project |
||
| 194 | * @param User $user |
||
| 195 | * @return array |
||
| 196 | */ |
||
| 197 | public function getBlocksReceived(Project $project, User $user) |
||
| 198 | { |
||
| 199 | $loggingTable = $this->getTableName($project->getDatabaseName(), 'logging', 'logindex'); |
||
| 200 | $sql = "SELECT log_action, log_timestamp, log_params FROM $loggingTable |
||
| 201 | WHERE log_type = 'block' |
||
| 202 | AND log_action IN ('block', 'reblock', 'unblock') |
||
| 203 | AND log_timestamp > 0 |
||
| 204 | AND log_title = :username |
||
| 205 | AND log_namespace = 2 |
||
| 206 | ORDER BY log_timestamp ASC"; |
||
| 207 | $username = str_replace(' ', '_', $user->getUsername()); |
||
| 208 | |||
| 209 | return $this->executeProjectsQuery($sql, [ |
||
| 210 | 'username' => $username |
||
| 211 | ])->fetchAll(); |
||
| 212 | } |
||
| 213 | |||
| 214 | /** |
||
| 215 | * Get a user's total edit count on all projects. |
||
| 216 | * @see EditCounterRepository::globalEditCountsFromCentralAuth() |
||
| 217 | * @see EditCounterRepository::globalEditCountsFromDatabases() |
||
| 218 | * @param User $user The user. |
||
| 219 | * @param Project $project The project to start from. |
||
| 220 | * @return mixed[] Elements are arrays with 'project' (Project), and 'total' (int). |
||
| 221 | */ |
||
| 222 | public function globalEditCounts(User $user, Project $project) |
||
| 223 | { |
||
| 224 | // Get the edit counts from CentralAuth or database. |
||
| 225 | $editCounts = $this->globalEditCountsFromCentralAuth($user, $project); |
||
| 226 | if ($editCounts === false) { |
||
|
|
|||
| 227 | $editCounts = $this->globalEditCountsFromDatabases($user, $project); |
||
| 228 | } |
||
| 229 | |||
| 230 | // Pre-populate all projects' metadata, to prevent each project call from fetching it. |
||
| 231 | $project->getRepository()->getAll(); |
||
| 232 | |||
| 233 | // Compile the output. |
||
| 234 | $out = []; |
||
| 235 | foreach ($editCounts as $editCount) { |
||
| 236 | $out[] = [ |
||
| 237 | 'project' => ProjectRepository::getProject($editCount['dbName'], $this->container), |
||
| 238 | 'total' => $editCount['total'], |
||
| 239 | ]; |
||
| 240 | } |
||
| 241 | return $out; |
||
| 242 | } |
||
| 243 | |||
| 244 | /** |
||
| 245 | * Get a user's total edit count on one or more project. |
||
| 246 | * Requires the CentralAuth extension to be installed on the project. |
||
| 247 | * |
||
| 248 | * @param User $user The user. |
||
| 249 | * @param Project $project The project to start from. |
||
| 250 | * @return mixed[] Elements are arrays with 'dbName' (string), and 'total' (int). |
||
| 251 | */ |
||
| 252 | protected function globalEditCountsFromCentralAuth(User $user, Project $project) |
||
| 253 | { |
||
| 254 | if ($user->isAnon() === true) { |
||
| 255 | return false; |
||
| 256 | } |
||
| 257 | |||
| 258 | // Set up cache and stopwatch. |
||
| 259 | $cacheKey = $this->getCacheKey(func_get_args(), 'ec_globaleditcounts'); |
||
| 260 | if ($this->cache->hasItem($cacheKey)) { |
||
| 261 | return $this->cache->getItem($cacheKey)->get(); |
||
| 262 | } |
||
| 263 | $this->stopwatch->start($cacheKey, 'XTools'); |
||
| 264 | |||
| 265 | $this->log->debug(__METHOD__." Getting global edit counts from for ".$user->getUsername()); |
||
| 266 | |||
| 267 | // Load all projects, so it doesn't have to request metadata about each one as it goes. |
||
| 268 | $project->getRepository()->getAll(); |
||
| 269 | |||
| 270 | $api = $this->getMediawikiApi($project); |
||
| 271 | $params = [ |
||
| 272 | 'meta' => 'globaluserinfo', |
||
| 273 | 'guiprop' => 'editcount|merged', |
||
| 274 | 'guiuser' => $user->getUsername(), |
||
| 275 | ]; |
||
| 276 | $query = new SimpleRequest('query', $params); |
||
| 277 | $result = $api->getRequest($query); |
||
| 278 | if (!isset($result['query']['globaluserinfo']['merged'])) { |
||
| 279 | return []; |
||
| 280 | } |
||
| 281 | $out = []; |
||
| 282 | foreach ($result['query']['globaluserinfo']['merged'] as $result) { |
||
| 283 | $out[] = [ |
||
| 284 | 'dbName' => $result['wiki'], |
||
| 285 | 'total' => $result['editcount'], |
||
| 286 | ]; |
||
| 287 | } |
||
| 288 | |||
| 289 | // Cache and return. |
||
| 290 | $this->stopwatch->stop($cacheKey); |
||
| 291 | return $this->setCache($cacheKey, $out); |
||
| 292 | } |
||
| 293 | |||
| 294 | /** |
||
| 295 | * Get total edit counts from all projects for this user. |
||
| 296 | * @see EditCounterRepository::globalEditCountsFromCentralAuth() |
||
| 297 | * @param User $user The user. |
||
| 298 | * @param Project $project The project to start from. |
||
| 299 | * @return mixed[] Elements are arrays with 'dbName' (string), and 'total' (int). |
||
| 300 | */ |
||
| 301 | protected function globalEditCountsFromDatabases(User $user, Project $project) |
||
| 302 | { |
||
| 303 | $this->log->debug(__METHOD__." Getting global edit counts for ".$user->getUsername()); |
||
| 304 | $allProjects = $project->getRepository()->getAll(); |
||
| 305 | $topEditCounts = []; |
||
| 306 | foreach ($allProjects as $projectMeta) { |
||
| 307 | $revisionTableName = $this->getTableName($projectMeta['dbName'], 'revision'); |
||
| 308 | $sql = "SELECT COUNT(rev_id) FROM $revisionTableName WHERE rev_user_text = :username"; |
||
| 309 | |||
| 310 | $resultQuery = $this->executeProjectsQuery($sql, [ |
||
| 311 | 'username' => $user->getUsername() |
||
| 312 | ]); |
||
| 313 | $total = (int)$resultQuery->fetchColumn(); |
||
| 314 | $topEditCounts[] = [ |
||
| 315 | 'dbName' => $projectMeta['dbName'], |
||
| 316 | 'total' => $total, |
||
| 317 | ]; |
||
| 318 | } |
||
| 319 | return $topEditCounts; |
||
| 320 | } |
||
| 321 | |||
| 322 | /** |
||
| 323 | * Get the given user's total edit counts per namespace on the given project. |
||
| 324 | * @param Project $project The project. |
||
| 325 | * @param User $user The user. |
||
| 326 | * @return integer[] Array keys are namespace IDs, values are the edit counts. |
||
| 327 | */ |
||
| 328 | public function getNamespaceTotals(Project $project, User $user) |
||
| 329 | { |
||
| 330 | // Cache? |
||
| 331 | $cacheKey = $this->getCacheKey(func_get_args(), 'ec_namespacetotals'); |
||
| 332 | $this->stopwatch->start($cacheKey, 'XTools'); |
||
| 333 | if ($this->cache->hasItem($cacheKey)) { |
||
| 334 | return $this->cache->getItem($cacheKey)->get(); |
||
| 335 | } |
||
| 336 | |||
| 337 | // Query. |
||
| 338 | $revisionTable = $this->getTableName($project->getDatabaseName(), 'revision'); |
||
| 339 | $revUserClause = $user->isAnon() ? 'r.rev_user_text = :username' : 'r.rev_user = :userId'; |
||
| 340 | $pageTable = $this->getTableName($project->getDatabaseName(), 'page'); |
||
| 341 | $sql = "SELECT page_namespace, COUNT(rev_id) AS total |
||
| 342 | FROM $pageTable p JOIN $revisionTable r ON (r.rev_page = p.page_id) |
||
| 343 | WHERE $revUserClause |
||
| 344 | GROUP BY page_namespace"; |
||
| 345 | |||
| 346 | $params = $user->isAnon() ? ['username' => $user->getUsername()] : ['userId' => $user->getId($project)]; |
||
| 347 | $results = $this->executeProjectsQuery($sql, $params)->fetchAll(); |
||
| 348 | |||
| 349 | $namespaceTotals = array_combine(array_map(function ($e) { |
||
| 350 | return $e['page_namespace']; |
||
| 351 | }, $results), array_map(function ($e) { |
||
| 352 | return $e['total']; |
||
| 353 | }, $results)); |
||
| 354 | |||
| 355 | // Cache and return. |
||
| 356 | $this->stopwatch->stop($cacheKey); |
||
| 357 | return $this->setCache($cacheKey, $namespaceTotals); |
||
| 358 | } |
||
| 359 | |||
| 360 | /** |
||
| 361 | * Get revisions by this user. |
||
| 362 | * @param Project[] $projects The projects. |
||
| 363 | * @param User $user The user. |
||
| 364 | * @param int $lim The maximum number of revisions to fetch from each project. |
||
| 365 | * @return array|mixed |
||
| 366 | */ |
||
| 367 | public function getRevisions($projects, User $user, $lim = 40) |
||
| 368 | { |
||
| 369 | // Check cache. |
||
| 370 | $cacheKey = $this->getCacheKey('ec_globalcontribs.'.$user->getCacheKey().'.'.$lim); |
||
| 371 | $this->stopwatch->start($cacheKey, 'XTools'); |
||
| 372 | if ($this->cache->hasItem($cacheKey)) { |
||
| 373 | return $this->cache->getItem($cacheKey)->get(); |
||
| 374 | } |
||
| 375 | |||
| 376 | // Assemble queries. |
||
| 377 | $queries = []; |
||
| 378 | foreach ($projects as $project) { |
||
| 379 | $revisionTable = $project->getTableName('revision'); |
||
| 380 | $pageTable = $project->getTableName('page'); |
||
| 381 | $sql = "SELECT |
||
| 382 | '".$project->getDatabaseName()."' AS project_name, |
||
| 383 | revs.rev_id AS id, |
||
| 384 | revs.rev_timestamp AS timestamp, |
||
| 385 | UNIX_TIMESTAMP(revs.rev_timestamp) AS unix_timestamp, |
||
| 386 | revs.rev_minor_edit AS minor, |
||
| 387 | revs.rev_deleted AS deleted, |
||
| 388 | revs.rev_len AS length, |
||
| 389 | (CAST(revs.rev_len AS SIGNED) - IFNULL(parentrevs.rev_len, 0)) AS length_change, |
||
| 390 | revs.rev_parent_id AS parent_id, |
||
| 391 | revs.rev_comment AS comment, |
||
| 392 | revs.rev_user_text AS username, |
||
| 393 | page.page_title, |
||
| 394 | page.page_namespace |
||
| 395 | FROM $revisionTable AS revs |
||
| 396 | JOIN $pageTable AS page ON (rev_page = page_id) |
||
| 397 | LEFT JOIN $revisionTable AS parentrevs ON (revs.rev_parent_id = parentrevs.rev_id) |
||
| 398 | WHERE revs.rev_user_text = :username |
||
| 399 | ORDER BY revs.rev_timestamp DESC"; |
||
| 400 | if (is_numeric($lim)) { |
||
| 401 | $sql .= " LIMIT $lim"; |
||
| 402 | } |
||
| 403 | $queries[] = $sql; |
||
| 404 | } |
||
| 405 | $sql = "(\n" . join("\n) UNION (\n", $queries) . ")\n"; |
||
| 406 | |||
| 407 | $revisions = $this->executeProjectsQuery($sql, [ |
||
| 408 | 'username' => $user->getUsername(), |
||
| 409 | ])->fetchAll(); |
||
| 410 | |||
| 411 | // Cache and return. |
||
| 412 | $this->stopwatch->stop($cacheKey); |
||
| 413 | return $this->setCache($cacheKey, $revisions); |
||
| 414 | } |
||
| 415 | |||
| 416 | /** |
||
| 417 | * Get data for a bar chart of monthly edit totals per namespace. |
||
| 418 | * @param Project $project The project. |
||
| 419 | * @param User $user The user. |
||
| 420 | * @return string[] [ |
||
| 421 | * [ |
||
| 422 | * 'year' => <year>, |
||
| 423 | * 'month' => <month>, |
||
| 424 | * 'page_namespace' => <namespace>, |
||
| 425 | * 'count' => <count>, |
||
| 426 | * ], |
||
| 427 | * ... |
||
| 428 | * ] |
||
| 429 | */ |
||
| 430 | public function getMonthCounts(Project $project, User $user) |
||
| 431 | { |
||
| 432 | $cacheKey = $this->getCacheKey(func_get_args(), 'ec_monthcounts'); |
||
| 433 | $this->stopwatch->start($cacheKey, 'XTools'); |
||
| 434 | if ($this->cache->hasItem($cacheKey)) { |
||
| 435 | return $this->cache->getItem($cacheKey)->get(); |
||
| 436 | } |
||
| 437 | |||
| 438 | $revisionTable = $project->getTableName('revision'); |
||
| 439 | $pageTable = $project->getTableName('page'); |
||
| 440 | $sql = |
||
| 441 | "SELECT " |
||
| 442 | . " YEAR(rev_timestamp) AS `year`," |
||
| 443 | . " MONTH(rev_timestamp) AS `month`," |
||
| 444 | . " page_namespace," |
||
| 445 | . " COUNT(rev_id) AS `count` " |
||
| 446 | . " FROM $revisionTable JOIN $pageTable ON (rev_page = page_id)" |
||
| 447 | . " WHERE rev_user_text = :username" |
||
| 448 | . " GROUP BY YEAR(rev_timestamp), MONTH(rev_timestamp), page_namespace"; |
||
| 449 | |||
| 450 | $totals = $this->executeProjectsQuery($sql, [ |
||
| 451 | 'username' => $user->getUsername(), |
||
| 452 | ])->fetchAll(); |
||
| 453 | |||
| 454 | // Cache and return. |
||
| 455 | $this->stopwatch->stop($cacheKey); |
||
| 456 | return $this->setCache($cacheKey, $totals); |
||
| 457 | } |
||
| 458 | |||
| 459 | /** |
||
| 460 | * Get data for the timecard chart, with totals grouped by day and to the nearest two-hours. |
||
| 461 | * @param Project $project |
||
| 462 | * @param User $user |
||
| 463 | * @return string[] |
||
| 464 | */ |
||
| 465 | public function getTimeCard(Project $project, User $user) |
||
| 466 | { |
||
| 467 | $cacheKey = $this->getCacheKey(func_get_args(), 'ec_timecard'); |
||
| 468 | $this->stopwatch->start($cacheKey, 'XTools'); |
||
| 469 | if ($this->cache->hasItem($cacheKey)) { |
||
| 470 | return $this->cache->getItem($cacheKey)->get(); |
||
| 471 | } |
||
| 472 | |||
| 473 | $hourInterval = 2; |
||
| 474 | $xCalc = "ROUND(HOUR(rev_timestamp)/$hourInterval) * $hourInterval"; |
||
| 475 | $revisionTable = $this->getTableName($project->getDatabaseName(), 'revision'); |
||
| 476 | $sql = "SELECT " |
||
| 477 | . " DAYOFWEEK(rev_timestamp) AS `y`, " |
||
| 478 | . " $xCalc AS `x`, " |
||
| 479 | . " COUNT(rev_id) AS `value` " |
||
| 480 | . " FROM $revisionTable" |
||
| 481 | . " WHERE rev_user_text = :username" |
||
| 482 | . " GROUP BY DAYOFWEEK(rev_timestamp), $xCalc "; |
||
| 483 | |||
| 484 | $totals = $this->executeProjectsQuery($sql, [ |
||
| 485 | 'username' => $user->getUsername(), |
||
| 486 | ])->fetchAll(); |
||
| 487 | |||
| 488 | // Cache and return. |
||
| 489 | $this->stopwatch->stop($cacheKey); |
||
| 490 | return $this->setCache($cacheKey, $totals); |
||
| 491 | } |
||
| 492 | |||
| 493 | /** |
||
| 494 | * Get various data about edit sizes of the past 5,000 edits. |
||
| 495 | * Will cache the result for 10 minutes. |
||
| 496 | * @param Project $project The project. |
||
| 497 | * @param User $user The user. |
||
| 498 | * @return string[] Values with for keys 'average_size', |
||
| 499 | * 'small_edits' and 'large_edits' |
||
| 500 | */ |
||
| 501 | public function getEditSizeData(Project $project, User $user) |
||
| 502 | { |
||
| 503 | // Set up cache. |
||
| 504 | $cacheKey = $this->getCacheKey(func_get_args(), 'ec_editsizes'); |
||
| 505 | $this->stopwatch->start($cacheKey, 'XTools'); |
||
| 506 | if ($this->cache->hasItem($cacheKey)) { |
||
| 507 | return $this->cache->getItem($cacheKey)->get(); |
||
| 508 | } |
||
| 509 | |||
| 510 | // Prepare the queries and execute them. |
||
| 511 | $revisionTable = $this->getTableName($project->getDatabaseName(), 'revision'); |
||
| 512 | $revUserClause = $user->isAnon() ? 'revs.rev_user_text = :username' : 'revs.rev_user = :userId'; |
||
| 513 | $sql = "SELECT AVG(sizes.size) AS average_size, |
||
| 514 | COUNT(CASE WHEN sizes.size < 20 THEN 1 END) AS small_edits, |
||
| 515 | COUNT(CASE WHEN sizes.size > 1000 THEN 1 END) AS large_edits |
||
| 516 | FROM ( |
||
| 517 | SELECT (CAST(revs.rev_len AS SIGNED) - IFNULL(parentrevs.rev_len, 0)) AS size |
||
| 518 | FROM $revisionTable AS revs |
||
| 519 | LEFT JOIN $revisionTable AS parentrevs ON (revs.rev_parent_id = parentrevs.rev_id) |
||
| 520 | WHERE $revUserClause |
||
| 521 | ORDER BY revs.rev_timestamp DESC |
||
| 522 | LIMIT 5000 |
||
| 523 | ) sizes"; |
||
| 524 | |||
| 525 | $params = $user->isAnon() ? ['username' => $user->getUsername()] : ['userId' => $user->getId($project)]; |
||
| 526 | $results = $this->executeProjectsQuery($sql, $params)->fetch(); |
||
| 527 | |||
| 528 | // Cache and return. |
||
| 529 | $this->stopwatch->stop($cacheKey); |
||
| 530 | return $this->setCache($cacheKey, $results); |
||
| 531 | } |
||
| 532 | |||
| 533 | /** |
||
| 534 | * Get the number of edits this user made using semi-automated tools. |
||
| 535 | * @param Project $project |
||
| 536 | * @param User $user |
||
| 537 | * @return int Result of query, see below. |
||
| 538 | */ |
||
| 539 | public function countAutomatedEdits(Project $project, User $user) |
||
| 544 | } |
||
| 545 | } |
||
| 546 |