GlobalContribsController   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 220
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 47
dl 0
loc 220
rs 10
c 0
b 0
f 0
wmc 8

6 Methods

Rating   Name   Duplication   Size   Complexity  
A maxLimit() 0 3 1
A resultsApiAction() 0 18 1
A getIndexRoute() 0 3 1
A indexAction() 0 24 3
A resultsAction() 0 15 1
A getGlobalContribs() 0 15 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace App\Controller;
6
7
use App\Model\Edit;
8
use App\Model\GlobalContribs;
9
use App\Repository\EditRepository;
10
use App\Repository\GlobalContribsRepository;
11
use OpenApi\Annotations as OA;
12
use Symfony\Component\HttpFoundation\JsonResponse;
13
use Symfony\Component\HttpFoundation\Response;
14
use Symfony\Component\Routing\Annotation\Route;
15
16
/**
17
 * This controller serves the search form and results for the Global Contributions tool.
18
 */
19
class GlobalContribsController extends XtoolsController
20
{
21
22
    /**
23
     * @inheritDoc
24
     * @codeCoverageIgnore
25
     */
26
    public function getIndexRoute(): string
27
    {
28
        return 'GlobalContribs';
29
    }
30
31
    /**
32
     * GlobalContribs can be very slow, especially for wide IP ranges, so limit to max 500 results.
33
     * @inheritDoc
34
     * @codeCoverageIgnore
35
     */
36
    public function maxLimit(): int
37
    {
38
        return 500;
39
    }
40
41
    /**
42
     * The search form.
43
     * @Route("/globalcontribs", name="GlobalContribs")
44
     * @Route("/ec-latestglobal", name="EditCounterLatestGlobalIndex")
45
     * @Route("/ec-latestglobal-contributions", name="EditCounterLatestGlobalContribsIndex")
46
     * @Route("/ec-latestglobaledits", name="EditCounterLatestGlobalEditsIndex")
47
     * @param string $centralAuthProject
48
     * @return Response
49
     */
50
    public function indexAction(string $centralAuthProject): Response
51
    {
52
        // Redirect if username is given.
53
        if (isset($this->params['username'])) {
54
            return $this->redirectToRoute('GlobalContribsResult', $this->params);
55
        }
56
57
        // FIXME: Nasty hack until T226072 is resolved.
58
        $project = $this->projectRepo->getProject($this->i18n->getLang().'.wikipedia');
59
        if (!$project->exists()) {
60
            $project = $this->projectRepo->getProject($centralAuthProject);
61
        }
62
63
        return $this->render('globalContribs/index.html.twig', array_merge([
64
            'xtPage' => 'GlobalContribs',
65
            'xtPageTitle' => 'tool-globalcontribs',
66
            'xtSubtitle' => 'tool-globalcontribs-desc',
67
            'project' => $project,
68
69
            // Defaults that will get overridden if in $this->params.
70
            'namespace' => 'all',
71
            'start' => '',
72
            'end' => '',
73
        ], $this->params));
74
    }
75
76
    /**
77
     * @param GlobalContribsRepository $globalContribsRepo
78
     * @param EditRepository $editRepo
79
     * @return GlobalContribs
80
     * @codeCoverageIgnore
81
     */
82
    public function getGlobalContribs(
83
        GlobalContribsRepository $globalContribsRepo,
84
        EditRepository $editRepo
85
    ): GlobalContribs {
86
        return new GlobalContribs(
87
            $globalContribsRepo,
88
            $this->pageRepo,
89
            $this->userRepo,
90
            $editRepo,
91
            $this->user,
0 ignored issues
show
Bug introduced by
It seems like $this->user can also be of type null; however, parameter $user of App\Model\GlobalContribs::__construct() does only seem to accept App\Model\User, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
            /** @scrutinizer ignore-type */ $this->user,
Loading history...
92
            $this->namespace,
93
            $this->start,
94
            $this->end,
95
            $this->offset,
96
            $this->limit
97
        );
98
    }
99
100
    /**
101
     * Display the latest global edits tool. First two routes are legacy.
102
     * @Route(
103
     *     "/ec-latestglobal-contributions/{project}/{username}",
104
     *     name="EditCounterLatestGlobalContribs",
105
     *     requirements={
106
     *         "username"="(ipr-.+\/\d+[^\/])|([^\/]+)",
107
     *     },
108
     *     defaults={
109
     *         "project"="",
110
     *         "namespace"="all"
111
     *     }
112
     * )
113
     * @Route(
114
     *     "/ec-latestglobal/{project}/{username}",
115
     *     name="EditCounterLatestGlobal",
116
     *     requirements={
117
     *         "username"="(ipr-.+\/\d+[^\/])|([^\/]+)",
118
     *     },
119
     *     defaults={
120
     *         "project"="",
121
     *         "namespace"="all"
122
     *     }
123
     * ),
124
     * @Route(
125
     *     "/globalcontribs/{username}/{namespace}/{start}/{end}/{offset}",
126
     *     name="GlobalContribsResult",
127
     *     requirements={
128
     *         "username"="(ipr-.+\/\d+[^\/])|([^\/]+)",
129
     *         "namespace"="|all|\d+",
130
     *         "start"="|\d*|\d{4}-\d{2}-\d{2}",
131
     *         "end"="|\d{4}-\d{2}-\d{2}",
132
     *         "offset"="|\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?",
133
     *     },
134
     *     defaults={
135
     *         "namespace"="all",
136
     *         "start"=false,
137
     *         "end"=false,
138
     *         "offset"=false,
139
     *     }
140
     * ),
141
     * @param GlobalContribsRepository $globalContribsRepo
142
     * @param EditRepository $editRepo
143
     * @param string $centralAuthProject
144
     * @return Response
145
     * @codeCoverageIgnore
146
     */
147
    public function resultsAction(
148
        GlobalContribsRepository $globalContribsRepo,
149
        EditRepository $editRepo,
150
        string $centralAuthProject
151
    ): Response {
152
        $globalContribs = $this->getGlobalContribs($globalContribsRepo, $editRepo);
153
        $defaultProject = $this->projectRepo->getProject($centralAuthProject);
154
155
        return $this->render('globalContribs/result.html.twig', [
156
            'xtTitle' => $this->user->getUsername(),
0 ignored issues
show
Bug introduced by
The method getUsername() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
            'xtTitle' => $this->user->/** @scrutinizer ignore-call */ getUsername(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
157
            'xtPage' => 'GlobalContribs',
158
            'is_sub_request' => $this->isSubRequest,
159
            'user' => $this->user,
160
            'project' => $defaultProject,
161
            'gc' => $globalContribs,
162
        ]);
163
    }
164
165
    /************************ API endpoints ************************/
166
167
    /**
168
     * Get global edits made by a user, IP or IP range.
169
     * @Route(
170
     *     "/api/user/globalcontribs/{username}/{namespace}/{start}/{end}/{offset}",
171
     *     name="UserApiGlobalContribs",
172
     *     requirements={
173
     *         "username"="(ipr-.+\/\d+[^\/])|([^\/]+)",
174
     *         "namespace"="|all|\d+",
175
     *         "start"="|\d*|\d{4}-\d{2}-\d{2}",
176
     *         "end"="|\d{4}-\d{2}-\d{2}",
177
     *         "offset"="|\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?",
178
     *     },
179
     *     defaults={
180
     *         "namespace"="all",
181
     *         "start"=false,
182
     *         "end"=false,
183
     *         "offset"=false,
184
     *         "limit"=50,
185
     *     },
186
     *     methods={"GET"}
187
     * )
188
     * @OA\Tag(name="User API")
189
     * @OA\Get(description="Get contributions made by a user, IP or IP range across all Wikimedia projects.")
190
     * @OA\Parameter(ref="#/components/parameters/UsernameOrIp")
191
     * @OA\Parameter(ref="#/components/parameters/Namespace")
192
     * @OA\Parameter(ref="#/components/parameters/Start")
193
     * @OA\Parameter(ref="#/components/parameters/End")
194
     * @OA\Parameter(ref="#/components/parameters/Offset")
195
     * @OA\Response(
196
     *     response=200,
197
     *     description="Global contributions",
198
     *     @OA\JsonContent(
199
     *         @OA\Property(property="project", type="string", example="meta.wikimedia.org"),
200
     *         @OA\Property(property="username", ref="#/components/parameters/Username/schema"),
201
     *         @OA\Property(property="namespace", ref="#/components/schemas/Namespace"),
202
     *         @OA\Property(property="start", ref="#/components/parameters/Start/schema"),
203
     *         @OA\Property(property="end", ref="#/components/parameters/End/schema"),
204
     *         @OA\Property(property="globalcontribs", type="array",
205
     *             @OA\Items(ref="#/components/schemas/EditWithProject")
206
     *         ),
207
     *         @OA\Property(property="continue", type="date-time", example="2020-01-31T12:59:59Z"),
208
     *         @OA\Property(property="elapsed_time", ref="#/components/schemas/elapsed_time")
209
     *     )
210
     * )
211
     * @OA\Response(response=404, ref="#/components/responses/404")
212
     * @OA\Response(response=501, ref="#/components/responses/501")
213
     * @OA\Response(response=503, ref="#/components/responses/503")
214
     * @OA\Response(response=504, ref="#/components/responses/504")
215
     * @param GlobalContribsRepository $globalContribsRepo
216
     * @param EditRepository $editRepo
217
     * @param string $centralAuthProject
218
     * @return JsonResponse
219
     * @codeCoverageIgnore
220
     */
221
    public function resultsApiAction(
222
        GlobalContribsRepository $globalContribsRepo,
223
        EditRepository $editRepo,
224
        string $centralAuthProject
225
    ): JsonResponse {
226
        $this->recordApiUsage('user/globalcontribs');
227
228
        $globalContribs = $this->getGlobalContribs($globalContribsRepo, $editRepo);
229
        $defaultProject = $this->projectRepo->getProject($centralAuthProject);
230
        $this->project = $defaultProject;
231
232
        $results = $globalContribs->globalEdits();
233
        $results = array_map(function (Edit $edit) {
234
            return $edit->getForJson(true);
235
        }, array_values($results));
236
        $results = $this->addFullPageTitlesAndContinue('globalcontribs', [], $results);
237
238
        return $this->getFormattedApiResponse($results);
239
    }
240
}
241