Completed
Push — master ( 0058c9...b0ad91 )
by
unknown
02:49
created

UserRepository::getPagesCreated()   F

Complexity

Conditions 11
Paths 385

Size

Total Lines 99
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 99
rs 3.8181
c 0
b 0
f 0
cc 11
eloc 61
nc 385
nop 4

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file contains only the UserRepository class.
4
 */
5
6
namespace Xtools;
7
8
use DateInterval;
9
use Mediawiki\Api\SimpleRequest;
10
use Symfony\Component\DependencyInjection\Container;
11
use Symfony\Component\HttpFoundation\Session\Session;
12
13
/**
14
 * This class provides data for the User class.
15
 */
16
class UserRepository extends Repository
17
{
18
19
    /**
20
     * Convenience method to get a new User object.
21
     * @param string $username The username.
22
     * @param Container $container The DI container.
23
     * @return User
24
     */
25
    public static function getUser($username, Container $container)
26
    {
27
        $user = new User($username);
28
        $userRepo = new UserRepository();
29
        $userRepo->setContainer($container);
30
        $user->setRepository($userRepo);
31
        return $user;
32
    }
33
34
    /**
35
     * Get the user's ID.
36
     * @param string $databaseName The database to query.
37
     * @param string $username The username to find.
38
     * @return int
39
     */
40
    public function getId($databaseName, $username)
41
    {
42
        $cacheKey = 'user_id.'.$databaseName.'.'.$username;
43
        if ($this->cache->hasItem($cacheKey)) {
44
            return $this->cache->getItem($cacheKey)->get();
45
        }
46
47
        $userTable = $this->getTableName($databaseName, 'user');
48
        $sql = "SELECT user_id FROM $userTable WHERE user_name = :username LIMIT 1";
49
        $resultQuery = $this->getProjectsConnection()->prepare($sql);
50
        $resultQuery->bindParam("username", $username);
51
        $resultQuery->execute();
52
        $userId = (int)$resultQuery->fetchColumn();
53
54
        // Cache for 10 minutes.
55
        $cacheItem = $this->cache
56
            ->getItem($cacheKey)
57
            ->set($userId)
58
            ->expiresAfter(new DateInterval('PT10M'));
59
        $this->cache->save($cacheItem);
60
        return $userId;
61
    }
62
63
    /**
64
     * Get group names of the given user.
65
     * @param Project $project The project.
66
     * @param string $username The username.
67
     * @return string[]
68
     */
69
    public function getGroups(Project $project, $username)
70
    {
71
        $cacheKey = 'usergroups.'.$project->getDatabaseName().'.'.$username;
72
        if ($this->cache->hasItem($cacheKey)) {
73
            return $this->cache->getItem($cacheKey)->get();
74
        }
75
76
        $this->stopwatch->start($cacheKey, 'XTools');
77
        $api = $this->getMediawikiApi($project);
78
        $params = [ "list"=>"users", "ususers"=>$username, "usprop"=>"groups" ];
79
        $query = new SimpleRequest('query', $params);
80
        $result = [];
81
        $res = $api->getRequest($query);
82
        if (isset($res["batchcomplete"]) && isset($res["query"]["users"][0]["groups"])) {
83
            $result = $res["query"]["users"][0]["groups"];
84
        }
85
86
        // Cache for 10 minutes, and return.
1 ignored issue
show
Unused Code Comprehensibility introduced by
36% 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...
87
        $cacheItem = $this->cache->getItem($cacheKey)
88
            ->set($result)
89
            ->expiresAfter(new DateInterval('PT10M'));
90
        $this->cache->save($cacheItem);
91
        $this->stopwatch->stop($cacheKey);
92
93
        return $result;
94
    }
95
96
    /**
97
     * Get a user's global group membership (starting at XTools' default project if none is
98
     * provided). This requires the CentralAuth extension to be installed.
99
     * @link https://www.mediawiki.org/wiki/Extension:CentralAuth
100
     * @param string $username The username.
101
     * @param Project $project The project to query.
102
     * @return string[]
103
     */
104
    public function getGlobalGroups($username, Project $project = null)
105
    {
106
        // Get the default project if not provided.
107
        if (!$project instanceof Project) {
108
            $project = ProjectRepository::getDefaultProject($this->container);
109
        }
110
111
        // Create the API query.
112
        $api = $this->getMediawikiApi($project);
113
        $params = [ "meta"=>"globaluserinfo", "guiuser"=>$username, "guiprop"=>"groups" ];
114
        $query = new SimpleRequest('query', $params);
115
116
        // Get the result.
117
        $res = $api->getRequest($query);
118
        $result = [];
119
        if (isset($res["batchcomplete"]) && isset($res["query"]["globaluserinfo"]["groups"])) {
120
            $result = $res["query"]["globaluserinfo"]["groups"];
121
        }
122
        return $result;
123
    }
124
125
    /**
126
     * Search the ipblocks table to see if the user is currently blocked
127
     *   and return the expiry if they are
128
     * @param $databaseName The database to query.
129
     * @param $userid The ID of the user to search for.
130
     * @return bool|string Expiry of active block or false
131
     */
132
    public function getBlockExpiry($databaseName, $userid)
133
    {
134
        $ipblocksTable = $this->getTableName($databaseName, 'ipblocks');
135
        $sql = "SELECT ipb_expiry
136
                FROM $ipblocksTable
137
                WHERE ipb_user = :userid
138
                LIMIT 1";
139
        $resultQuery = $this->getProjectsConnection()->prepare($sql);
140
        $resultQuery->bindParam('userid', $userid);
141
        $resultQuery->execute();
142
        return $resultQuery->fetchColumn();
143
    }
144
145
    /**
146
     * Get pages created by a user
147
     * @param Project $project
148
     * @param User $user
149
     * @param string|int $namespace Namespace ID or 'all'
150
     * @param string $redirects One of 'noredirects', 'onlyredirects' or blank for both
151
     */
152
    public function getPagesCreated(Project $project, User $user, $namespace, $redirects)
153
    {
154
        $username = $user->getUsername();
155
156
        $cacheKey = 'pages.' . $project->getDatabaseName() . '.'
157
            . $username . '.' . $namespace . '.' . $redirects;
158
        if ($this->cache->hasItem($cacheKey)) {
159
            return $this->cache->getItem($cacheKey)->get();
160
        }
161
        $this->stopwatch->start($cacheKey, 'XTools');
162
163
        $dbName = $project->getDatabaseName();
164
        $projectRepo = $project->getRepository();
165
166
        $pageTable = $projectRepo->getTableName($dbName, 'page');
167
        $pageAssessmentsTable = $projectRepo->getTableName($dbName, 'page_assessments');
168
        $revisionTable = $projectRepo->getTableName($dbName, 'revision');
169
        $archiveTable = $projectRepo->getTableName($dbName, 'archive');
170
        $logTable = $projectRepo->getTableName($dbName, 'logging', 'userindex');
171
172
        $userId = $user->getId($project);
173
174
        $namespaceConditionArc = '';
175
        $namespaceConditionRev = '';
176
177
        if ($namespace != 'all') {
178
            $namespaceConditionRev = " AND page_namespace = '".intval($namespace)."' ";
179
            $namespaceConditionArc = " AND ar_namespace = '".intval($namespace)."' ";
180
        }
181
182
        $redirectCondition = '';
183
184
        if ($redirects == 'onlyredirects') {
185
            $redirectCondition = " AND page_is_redirect = '1' ";
186
        } elseif ($redirects == 'noredirects') {
187
            $redirectCondition = " AND page_is_redirect = '0' ";
188
        }
189
190
        if ($userId == 0) { // IP Editor or undefined username.
191
            $whereRev = " rev_user_text = '$username' AND rev_user = '0' ";
192
            $whereArc = " ar_user_text = '$username' AND ar_user = '0' ";
193
            $having = " rev_user_text = '$username' ";
194
        } else {
195
            $whereRev = " rev_user = '$userId' AND rev_timestamp > 1 ";
196
            $whereArc = " ar_user = '$userId' AND ar_timestamp > 1 ";
197
            $having = " rev_user = '$userId' ";
198
        }
199
200
        $hasPageAssessments = $this->isLabs() && $project->hasPageAssessments();
201
        $paSelects = $hasPageAssessments ? ', pa_class, pa_importance, pa_page_revision' : '';
202
        $paSelectsArchive = $hasPageAssessments ?
203
            ', NULL AS pa_class, NULL AS pa_page_id, NULL AS pa_page_revision'
204
            : '';
205
        $paJoin = $hasPageAssessments ? "LEFT JOIN $pageAssessmentsTable ON rev_page = pa_page_id" : '';
206
207
        $sql = "
208
            (SELECT DISTINCT page_namespace AS namespace, 'rev' AS type, page_title AS page_title,
209
                page_len, page_is_redirect, rev_timestamp AS rev_timestamp,
210
                rev_user, rev_user_text AS username, rev_len, rev_id $paSelects
211
            FROM $pageTable
212
            JOIN $revisionTable ON page_id = rev_page
213
            $paJoin
214
            WHERE $whereRev AND rev_parent_id = '0' $namespaceConditionRev $redirectCondition
215
            " . ($hasPageAssessments ? 'GROUP BY rev_page' : '') . "
216
            )
217
218
            UNION
219
220
            (SELECT a.ar_namespace AS namespace, 'arc' AS type, a.ar_title AS page_title,
221
                0 AS page_len, '0' AS page_is_redirect, MIN(a.ar_timestamp) AS rev_timestamp,
222
                a.ar_user AS rev_user, a.ar_user_text AS username, a.ar_len AS rev_len,
223
                a.ar_rev_id AS rev_id $paSelectsArchive
224
            FROM $archiveTable a
225
            JOIN
226
            (
227
                SELECT b.ar_namespace, b.ar_title
228
                FROM $archiveTable AS b
229
                LEFT JOIN $logTable ON log_namespace = b.ar_namespace AND log_title = b.ar_title
230
                    AND log_user = b.ar_user AND (log_action = 'move' OR log_action = 'move_redir')
231
                WHERE $whereArc AND b.ar_parent_id = '0' $namespaceConditionArc AND log_action IS NULL
232
            ) AS c ON c.ar_namespace= a.ar_namespace AND c.ar_title = a.ar_title
233
            GROUP BY a.ar_namespace, a.ar_title
234
            HAVING $having
235
            )
236
            ";
237
238
        $resultQuery = $this->getProjectsConnection()->prepare($sql);
239
        $resultQuery->execute();
240
        $result = $resultQuery->fetchAll();
241
242
        // Cache for 10 minutes, and return.
1 ignored issue
show
Unused Code Comprehensibility introduced by
36% 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...
243
        $cacheItem = $this->cache->getItem($cacheKey)
244
            ->set($result)
245
            ->expiresAfter(new DateInterval('PT10M'));
246
        $this->cache->save($cacheItem);
247
        $this->stopwatch->stop($cacheKey);
248
249
        return $result;
250
    }
251
252
    /**
253
     * Get information about the currently-logged in user.
254
     * @return array
255
     */
256
    public function getXtoolsUserInfo()
257
    {
258
        /** @var Session $session */
259
        $session = $this->container->get('session');
260
        return $session->get('logged_in_user');
261
    }
262
}
263