Completed
Push — master ( 9fe0d2...0e0f1f )
by Sam
03:08
created

AdminScoreController::getToolShortname()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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\HttpKernel\Exception\NotFoundHttpException;
13
use DateTime;
14
use Xtools\ProjectRepository;
15
use Xtools\UserRepository;
16
17
/**
18
 * The AdminScoreController serves the search form and results page of the AdminScore tool
19
 */
20
class AdminScoreController extends Controller
21
{
22
23
    /**
24
     * Get the tool's shortname.
25
     * @return string
26
     */
27
    public function getToolShortname()
28
    {
29
        return 'adminscore';
30
    }
31
32
    /**
33
     * Display the AdminScore search form.
34
     * @Route("/adminscore", name="adminscore")
35
     * @Route("/adminscore", name="AdminScore")
36
     * @Route("/adminscore/", name="AdminScoreSlash")
37
     * @Route("/adminscore/index.php", name="AdminScoreIndexPhp")
38
     * @Route("/scottywong tools/adminscore.php", name="AdminScoreLegacy")
39
     * @Route("/adminscore/{project}", name="AdminScoreProject")
40
     * @param Request $request The HTTP request.
41
     * @param string $project The project name.
42
     * @return Response
43
     */
44
    public function indexAction(Request $request, $project = null)
45
    {
46
        $projectQuery = $request->query->get('project', $project);
47
        $username = $request->query->get('username', $request->query->get('user'));
48
49 View Code Duplication
        if ($projectQuery != '' && $username != '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
50
            return $this->redirectToRoute('AdminScoreResult', [ 'project' => $projectQuery, 'username' => $username ]);
51
        } elseif ($projectQuery != '') {
52
            return $this->redirectToRoute('AdminScoreProject', [ 'project' => $projectQuery ]);
53
        }
54
55
        // Set default project so we can populate the namespace selector.
56
        if ($projectQuery == '') {
57
            $projectQuery = $this->container->getParameter('default_project');
58
        }
59
        // and set it as a Project object
60
        $project = ProjectRepository::getProject($projectQuery, $this->container);
61
62
        // Otherwise fall through.
63
        return $this->render('adminscore/index.html.twig', [
64
            'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..'),
65
            'xtPage' => 'adminscore',
66
            'xtPageTitle' => 'tool-adminscore',
67
            'xtSubtitle' => 'tool-adminscore-desc',
68
            'project' => $project,
69
        ]);
70
    }
71
72
    /**
73
     * Display the AdminScore results.
74
     * @Route("/adminscore/{project}/{username}", name="AdminScoreResult")
75
     * @param string $project The project name.
76
     * @param string $username The username.
77
     * @return Response
78
     */
79
    public function resultAction($project, $username)
80
    {
81
        $lh = $this->get("app.labs_helper");
82
83
        $projectData = ProjectRepository::getProject($project, $this->container);
84
85 View Code Duplication
        if (!$projectData->exists()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
            $this->addFlash("notice", ["invalid-project", $project]);
0 ignored issues
show
Documentation introduced by
array('invalid-project', $project) is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
87
            return $this->redirectToRoute("adminscore");
88
        }
89
90
        $dbName = $projectData->getDatabaseName();
91
        $wikiName = $projectData->getDatabaseName();
92
        $url = $projectData->getUrl();
93
94
        $userTable = $lh->getTable("user", $dbName);
95
        $pageTable = $lh->getTable("page", $dbName);
96
        $loggingTable = $lh->getTable("logging", $dbName, "userindex");
97
        $revisionTable = $lh->getTable("revision", $dbName);
98
        $archiveTable = $lh->getTable("archive", $dbName);
99
100
        // MULTIPLIERS (to review)
101
        $ACCT_AGE_MULT = 1.25;   # 0 if = 365 jours
102
        $EDIT_COUNT_MULT = 1.25;     # 0 if = 10 000
1 ignored issue
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
103
        $USER_PAGE_MULT = 0.1;     # 0 if =
104
        $PATROLS_MULT = 1; # 0 if =
105
        $BLOCKS_MULT = 1.4;     # 0 if = 10
1 ignored issue
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
106
        $AFD_MULT = 1.15;
107
        $RECENT_ACTIVITY_MULT = 0.9;     # 0 if =
108
        $AIV_MULT = 1.15;
109
        $EDIT_SUMMARIES_MULT = 0.8;   # 0 if =
110
        $NAMESPACES_MULT = 1.0;     # 0 if =
111
        $PAGES_CREATED_LIVE_MULT = 1.4; # 0 if =
112
        $PAGES_CREATED_ARCHIVE_MULT = 1.4; # 0 if =
113
        $RPP_MULT = 1.15;     # 0 if =
114
        $USERRIGHTS_MULT = 0.75;   # 0 if =
115
116
        // Grab the connection to the replica database (which is separate from the above)
117
        $conn = $this->get('doctrine')->getManager("replicas")->getConnection();
118
119
        // Prepare the query and execute
120
        $resultQuery = $conn->prepare("
121
        SELECT 'id' AS source, user_id AS value FROM $userTable
122
            WHERE user_name = :username
123
        UNION
124
        SELECT 'account-age' AS source, user_registration AS value FROM $userTable
125
            WHERE user_name=:username
126
        UNION
127
        SELECT 'edit-count' AS source, user_editcount AS value FROM $userTable
128
            WHERE user_name=:username
129
        UNION
130
        SELECT 'user-page' AS source, page_len AS value FROM $pageTable
131
            WHERE page_namespace=2 AND page_title=:username
132
        UNION
133
        SELECT 'patrols' AS source, COUNT(*) AS value FROM $loggingTable
134
            WHERE log_type='patrol'
135
                AND log_action='patrol'
136
                AND log_namespace=0
137
                AND log_deleted=0 AND log_user_text=:username
138
        UNION
139
        SELECT 'blocks' AS source, COUNT(*) AS value FROM $loggingTable l
140
            INNER JOIN $userTable u ON l.log_user = u.user_id
141
            WHERE l.log_type='block' AND l.log_action='block'
142
            AND l.log_namespace=2 AND l.log_deleted=0 AND u.user_name=:username
143
        UNION
144
        SELECT 'afd' AS source, COUNT(*) AS value FROM $revisionTable
145
            WHERE rev_page LIKE 'Articles for deletion/%'
146
                AND rev_page NOT LIKE 'Articles_for_deletion/Log/%'
147
                AND rev_user_text=:username
148
        UNION
149
        SELECT 'recent-activity' AS source, COUNT(*) AS value FROM $revisionTable
150
            WHERE rev_user_text=:username AND rev_timestamp > (now()-INTERVAL 730 day) AND rev_timestamp < now()
151
        UNION
152
        SELECT 'aiv' AS source, COUNT(*) AS value FROM $revisionTable
153
            WHERE rev_page LIKE 'Administrator intervention against vandalism%' AND rev_user_text=:username
154
        UNION
155
        SELECT 'edit-summaries' AS source, COUNT(*) AS value FROM $revisionTable JOIN $pageTable ON rev_page=page_id
156
            WHERE page_namespace=0 AND rev_user_text=:username
157
        UNION
158
        SELECT 'namespaces' AS source, count(*) AS value FROM $revisionTable JOIN $pageTable ON rev_page=page_id
159
            WHERE rev_user_text=:username AND page_namespace=0
160
        UNION
161
        SELECT 'pages-created-live' AS source, COUNT(*) AS value FROM $revisionTable
162
            WHERE rev_user_text=:username AND rev_parent_id=0
163
        UNION
164
        SELECT 'pages-created-deleted' AS source, COUNT(*) AS value FROM $archiveTable
165
            WHERE ar_user_text=:username AND ar_parent_id=0
166
        UNION
167
        SELECT 'rpp' AS source, COUNT(*) AS value FROM $revisionTable
168
            WHERE rev_page LIKE 'Requests_for_page_protection%' AND rev_user_text=:username
169
        ");
170
171
        $user = UserRepository::getUser($username, $this->container);
1 ignored issue
show
Compatibility introduced by
$this->container of type object<Symfony\Component...ion\ContainerInterface> is not a sub-type of object<Symfony\Component...ncyInjection\Container>. It seems like you assume a concrete implementation of the interface Symfony\Component\Depend...tion\ContainerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
172
        $username = $user->getUsername();
173
        $resultQuery->bindParam("username", $username);
174
        $resultQuery->execute();
175
176
        // Fetch the result data
177
        $results = $resultQuery->fetchAll();
178
179
        $master = [];
180
        $total = 0;
181
182
        $id = 0;
183
184
        foreach ($results as $row) {
185
            $key = $row["source"];
186
            $value = $row["value"];
187
188
            if ($key == "acct_age") {
189
                $now = new DateTime();
190
                $date = new DateTime($value);
191
                $diff = $date->diff($now);
192
                $formula = 365*$diff->format("%y")+30*$diff->format("%m")+$diff->format("%d");
193
                $value = $formula-365;
194
            }
195
196
            if ($key == "id") {
197
                $id = $value;
198
            } else {
199
                $multiplierKey = strtoupper($row["source"] . "_MULT");
200
                $multiplier = ( isset($$multiplierKey) ? $$multiplierKey : 1 );
201
                $score = max(min($value * $multiplier, 100), -100);
202
                $master[$key]["mult"] = $multiplier;
203
                $master[$key]["value"] = $value;
204
                $master[$key]["score"] = $score;
205
                $total += $score;
206
            }
207
        }
208
209 View Code Duplication
        if ($id == 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
210
            $this->addFlash("notice", [ "no-result", $username ]);
0 ignored issues
show
Documentation introduced by
array('no-result', $username) is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
211
            return $this->redirectToRoute("AdminScore", [ "project"=>$project ]);
212
        }
213
214
        return $this->render('adminscore/result.html.twig', [
215
            'xtPage' => 'adminscore',
216
            'xtTitle' => $username,
217
            'projectUrl' => $url,
218
            'username' => $username,
219
            'project' => $wikiName,
220
            'master' => $master,
221
            'total' => $total,
222
        ]);
223
    }
224
}
225