Passed
Push — master ( 35c320...7deb12 )
by MusikAnimal
04:42
created

AdminScoreController   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 190
ccs 0
cts 10
cp 0
rs 10
c 0
b 0
f 0
wmc 11

3 Methods

Rating   Name   Duplication   Size   Complexity  
A indexAction() 0 17 3
C resultAction() 0 139 7
A getIndexRoute() 0 3 1
1
<?php
2
/**
3
 * This file contains only the AdminScoreController class.
4
 */
5
6
namespace AppBundle\Controller;
7
8
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
9
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\HttpFoundation\RedirectResponse;
13
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
14
use DateTime;
15
use Xtools\ProjectRepository;
16
use Xtools\UserRepository;
17
18
/**
19
 * The AdminScoreController serves the search form and results page of the AdminScore tool
20
 */
21
class AdminScoreController extends XtoolsController
22
{
23
24
    /**
25
     * Get the name of the tool's index route.
26
     * @return string
27
     * @codeCoverageIgnore
28
     */
29
    public function getIndexRoute()
30
    {
31
        return 'AdminScore';
32
    }
33
34
    /**
35
     * Display the AdminScore search form.
36
     * @Route("/adminscore", name="AdminScore")
37
     * @Route("/adminscore/", name="AdminScoreSlash")
38
     * @Route("/adminscore/index.php", name="AdminScoreIndexPhp")
39
     * @Route("/scottywong tools/adminscore.php", name="AdminScoreLegacy")
40
     * @Route("/adminscore/{project}", name="AdminScoreProject")
41
     * @param Request $request The HTTP request.
42
     * @return Response
43
     */
44
    public function indexAction(Request $request)
45
    {
46
        $params = $this->parseQueryParams($request);
47
48
        // Redirect if we have a project and user.
49
        if (isset($params['project']) && isset($params['username'])) {
50
            return $this->redirectToRoute('AdminScoreResult', $params);
51
        }
52
53
        // Convert the given project (or default project) into a Project instance.
54
        $params['project'] = $this->getProjectFromQuery($params);
55
56
        return $this->render('adminscore/index.html.twig', [
57
            'xtPage' => 'adminscore',
58
            'xtPageTitle' => 'tool-adminscore',
59
            'xtSubtitle' => 'tool-adminscore-desc',
60
            'project' => $params['project'],
61
        ]);
62
    }
63
64
    /**
65
     * Display the AdminScore results.
66
     * @Route("/adminscore/{project}/{username}", name="AdminScoreResult")
67
     * @param Request $request The HTTP request.
68
     * @return Response
69
     * @todo Move SQL to a model.
70
     * @codeCoverageIgnore
71
     */
72
    public function resultAction(Request $request)
73
    {
74
        // Second parameter causes it return a Redirect to the index if the user has too many edits.
75
        $ret = $this->validateProjectAndUser($request, 'adminscore');
76
        if ($ret instanceof RedirectResponse) {
0 ignored issues
show
introduced by
$ret is always a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
77
            return $ret;
78
        } else {
79
            list($projectData, $user) = $ret;
80
        }
81
82
        $dbName = $projectData->getDatabaseName();
83
        $projectRepo = $projectData->getRepository();
84
85
        $userTable = $projectRepo->getTableName($dbName, 'user');
86
        $pageTable = $projectRepo->getTableName($dbName, 'page');
87
        $loggingTable = $projectRepo->getTableName($dbName, 'logging', 'userindex');
88
        $revisionTable = $projectRepo->getTableName($dbName, 'revision');
89
        $archiveTable = $projectRepo->getTableName($dbName, 'archive');
90
91
        // MULTIPLIERS (to review)
92
        $multipliers = [
93
            'account-age-mult' => 1.25,             # 0 if = 365 jours
94
            'edit-count-mult' => 1.25,              # 0 if = 10 000
95
            'user-page-mult' => 0.1,                # 0 if =
96
            'patrols-mult' => 1,                    # 0 if =
97
            'blocks-mult' => 1.4,                   # 0 if = 10
98
            'afd-mult' => 1.15,
99
            'recent-activity-mult' => 0.9,          # 0 if =
100
            'aiv-mult' => 1.15,
101
            'edit-summaries-mult' => 0.8,           # 0 if =
102
            'namespaces-mult' => 1.0,               # 0 if =
103
            'pages-created-live-mult' => 1.4,       # 0 if =
104
            'pages-created-deleted-mult' => 1.4,    # 0 if =
105
            'rpp-mult' => 1.15,                     # 0 if =
106
            'user-rights-mult' => 0.75,             # 0 if =
107
        ];
108
109
        // Grab the connection to the replica database (which is separate from the above)
110
        $conn = $this->get('doctrine')->getManager("replicas")->getConnection();
111
112
        // Prepare the query and execute
113
        $resultQuery = $conn->prepare("
114
        SELECT 'account-age' AS source, user_registration AS value FROM $userTable
115
            WHERE user_name = :username
116
        UNION
117
        SELECT 'edit-count' AS source, user_editcount AS value FROM $userTable
118
            WHERE user_name = :username
119
        UNION
120
        SELECT 'user-page' AS source, page_len AS value FROM $pageTable
121
            WHERE page_namespace = 2 AND page_title = :username
122
        UNION
123
        SELECT 'patrols' AS source, COUNT(*) AS value FROM $loggingTable
124
            WHERE log_type = 'patrol'
125
                AND log_action = 'patrol'
126
                AND log_namespace = 0
127
                AND log_deleted = 0 AND log_user_text = :username
128
        UNION
129
        SELECT 'blocks' AS source, COUNT(*) AS value FROM $loggingTable l
130
            INNER JOIN $userTable u ON l.log_user = u.user_id
131
            WHERE l.log_type = 'block' AND l.log_action = 'block'
132
            AND l.log_namespace = 2 AND l.log_deleted = 0 AND u.user_name = :username
133
        UNION
134
        SELECT 'afd' AS source, COUNT(*) AS value FROM $revisionTable r
135
          INNER JOIN $pageTable p on p.page_id = r.rev_page
136
            WHERE p.page_title LIKE 'Articles_for_deletion/%'
137
                AND p.page_title NOT LIKE 'Articles_for_deletion/Log/%'
138
                AND r.rev_user_text = :username
139
        UNION
140
        SELECT 'recent-activity' AS source, COUNT(*) AS value FROM $revisionTable
141
            WHERE rev_user_text = :username AND rev_timestamp > (now()-INTERVAL 730 day) AND rev_timestamp < now()
142
        UNION
143
        SELECT 'aiv' AS source, COUNT(*) AS value FROM $revisionTable r
144
          INNER JOIN $pageTable p on p.page_id = r.rev_page
145
            WHERE p.page_title LIKE 'Administrator_intervention_against_vandalism%'
146
                AND r.rev_user_text = :username
147
        UNION
148
        SELECT 'edit-summaries' AS source, COUNT(*) AS value FROM $revisionTable JOIN $pageTable ON rev_page = page_id
149
            WHERE page_namespace = 0 AND rev_user_text = :username
150
        UNION
151
        SELECT 'namespaces' AS source, count(*) AS value FROM $revisionTable JOIN $pageTable ON rev_page = page_id
152
            WHERE rev_user_text = :username AND page_namespace = 0
153
        UNION
154
        SELECT 'pages-created-live' AS source, COUNT(*) AS value FROM $revisionTable
155
            WHERE rev_user_text = :username AND rev_parent_id = 0
156
        UNION
157
        SELECT 'pages-created-deleted' AS source, COUNT(*) AS value FROM $archiveTable
158
            WHERE ar_user_text = :username AND ar_parent_id = 0
159
        UNION
160
        SELECT 'rpp' AS source, COUNT(*) AS value FROM $revisionTable r
161
          INNER JOIN $pageTable p on p.page_id = r.rev_page
162
            WHERE p.page_title LIKE 'Requests_for_page_protection%'
163
                AND r.rev_user_text = :username;
164
        ");
165
166
        $username = $user->getUsername();
167
        $resultQuery->bindParam("username", $username);
168
        $resultQuery->execute();
169
170
        // Fetch the result data
171
        $results = $resultQuery->fetchAll();
172
173
        $master = [];
174
        $total = 0;
175
176
        foreach ($results as $row) {
177
            $key = $row['source'];
178
            $value = $row['value'];
179
180
            if ($key === 'account-age') {
181
                if ($value == null) {
182
                    $value = 0;
183
                } else {
184
                    $now = new DateTime();
185
                    $date = new DateTime($value);
186
                    $diff = $date->diff($now);
187
                    $formula = 365 * $diff->format('%y') + 30 * $diff->format('%m') + $diff->format('%d');
188
                    if ($formula < 365) {
189
                        $multipliers["account-age-mult"] = 0;
190
                    }
191
                    $value = $formula;
192
                }
193
            }
194
195
            $multiplierKey = $row['source'] . '-mult';
196
            $multiplier = isset($multipliers[$multiplierKey]) ? $multipliers[$multiplierKey] : 1;
197
            $score = max(min($value * $multiplier, 100), -100);
198
            $master[$key]['mult'] = $multiplier;
199
            $master[$key]['value'] = $value;
200
            $master[$key]['score'] = $score;
201
            $total += $score;
202
        }
203
204
        return $this->render('adminscore/result.html.twig', [
205
            'xtPage' => 'adminscore',
206
            'xtTitle' => $username,
207
            'project' => $projectData,
208
            'user' => $user,
209
            'master' => $master,
210
            'total' => $total,
211
        ]);
212
    }
213
}
214