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