Passed
Push — ip-ranges ( 157734...88dad8 )
by MusikAnimal
06:12 queued 01:19
created

SimpleEditCounterRepository::fetchDataNormal()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 46
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 25
c 0
b 0
f 0
nc 8
nop 5
dl 0
loc 46
rs 9.52
1
<?php
2
/**
3
 * This file contains only the SimpleEditCounterRepository class.
4
 */
5
6
declare(strict_types = 1);
7
8
namespace AppBundle\Repository;
9
10
use AppBundle\Model\Project;
11
use AppBundle\Model\User;
12
use Wikimedia\IPUtils;
13
14
/**
15
 * SimpleEditCounterRepository is responsible for retrieving data
16
 * from the database for the Simple Edit Counter tool.
17
 * @codeCoverageIgnore
18
 */
19
class SimpleEditCounterRepository extends Repository
20
{
21
    /**
22
     * Execute and return results of the query used for the Simple Edit Counter.
23
     * @param Project $project
24
     * @param User $user
25
     * @param int|string $namespace Namespace ID or 'all' for all namespaces.
26
     * @param int|false $start Unix timestamp.
27
     * @param int|false $end Unix timestamp.
28
     * @return string[] Counts, each row with keys 'source' and 'value'.
29
     */
30
    public function fetchData(Project $project, User $user, $namespace = 'all', $start = false, $end = false): array
31
    {
32
        $cacheKey = $this->getCacheKey(func_get_args(), 'simple_editcount');
33
        if ($this->cache->hasItem($cacheKey)) {
34
            return $this->cache->getItem($cacheKey)->get();
35
        }
36
37
        if ($user->isIpRange()) {
38
            $result = $this->fetchDataIpRange($project, $user, $namespace, $start, $end);
39
        } else {
40
            $result = $this->fetchDataNormal($project, $user, $namespace, $start, $end);
41
        }
42
43
        // Cache and return.
44
        return $this->setCache($cacheKey, $result);
45
    }
46
47
    /**
48
     * @param Project $project
49
     * @param User $user
50
     * @param int|string $namespace
51
     * @param int|false $start
52
     * @param int|false $end
53
     * @return string[] Counts, each row with keys 'source' and 'value'.
54
     */
55
    private function fetchDataNormal(
56
        Project $project,
57
        User $user,
58
        $namespace = 'all',
59
        $start = false,
60
        $end = false
61
    ): array {
62
        $userTable = $project->getTableName('user');
63
        $pageTable = $project->getTableName('page');
64
        $archiveTable = $project->getTableName('archive');
65
        $revisionTable = $project->getTableName('revision');
66
        $userGroupsTable = $project->getTableName('user_groups');
67
68
        $arDateConditions = $this->getDateConditions($start, $end, false, '', 'ar_timestamp');
69
        $revDateConditions = $this->getDateConditions($start, $end);
70
71
        $revNamespaceJoinSql = 'all' === $namespace ? '' : "JOIN $pageTable ON rev_page = page_id";
72
        $revNamespaceWhereSql = 'all' === $namespace ? '' : "AND page_namespace = $namespace";
73
        $arNamespaceWhereSql = 'all' === $namespace ? '' : "AND ar_namespace = $namespace";
74
75
        $sql = "SELECT 'id' AS source, user_id as value
76
                    FROM $userTable
77
                    WHERE user_name = :username
78
                UNION
79
                SELECT 'arch' AS source, COUNT(*) AS value
80
                    FROM $archiveTable
81
                    WHERE ar_actor = :actorId
82
                    $arNamespaceWhereSql
83
                    $arDateConditions
84
                UNION
85
                SELECT 'rev' AS source, COUNT(*) AS value
86
                    FROM $revisionTable
87
                    $revNamespaceJoinSql
88
                    WHERE rev_actor = :actorId
89
                    $revNamespaceWhereSql
90
                    $revDateConditions
91
                UNION
92
                SELECT 'groups' AS source, ug_group AS value
93
                    FROM $userGroupsTable
94
                    JOIN $userTable ON user_id = ug_user
95
                    WHERE user_name = :username";
96
97
        return $this->executeProjectsQuery($project, $sql, [
98
            'username' => $user->getUsername(),
99
            'actorId' => $user->getActorId($project),
100
        ])->fetchAll();
101
    }
102
103
    /**
104
     * @param Project $project
105
     * @param User $user
106
     * @param int|string $namespace
107
     * @param int|false $start
108
     * @param int|false $end
109
     * @return string[] Counts, each row with keys 'source' and 'value'.
110
     */
111
    private function fetchDataIpRange(
112
        Project $project,
113
        User $user,
114
        $namespace = 'all',
115
        $start = false,
116
        $end = false
117
    ): array {
118
        $ipcTable = $project->getTableName('ip_changes');
119
        $revTable = $project->getTableName('revision', '');
120
        $pageTable = $project->getTableName('page');
121
122
        $revDateConditions = $this->getDateConditions($start, $end, false, "$ipcTable.", 'ipc_rev_timestamp');
123
        [$startHex, $endHex] = IPUtils::parseRange($user->getUsername());
124
125
        $revNamespaceJoinSql = 'all' === $namespace ? '' : "JOIN $revTable ON rev_id = ipc_rev_id " .
126
            "JOIN $pageTable ON rev_page = page_id";
127
        $revNamespaceWhereSql = 'all' === $namespace ? '' : "AND page_namespace = $namespace";
128
129
        $sql = "SELECT 'rev' AS source, COUNT(*) AS value
130
                FROM $ipcTable
131
                $revNamespaceJoinSql
132
                WHERE ipc_hex BETWEEN :start AND :end 
133
                $revDateConditions
134
                $revNamespaceWhereSql";
135
136
        return $this->executeProjectsQuery($project, $sql, [
137
            'start' => $startHex,
138
            'end' => $endHex,
139
        ])->fetchAll();
140
    }
141
}
142