Passed
Pull Request — main (#442)
by MusikAnimal
12:05 queued 08:03
created

TopEditsController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 10
dl 0
loc 16
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Controller;
6
7
use App\Helper\AutomatedEditsHelper;
8
use App\Helper\I18nHelper;
9
use App\Model\TopEdits;
10
use App\Repository\PageRepository;
11
use App\Repository\ProjectRepository;
12
use App\Repository\TopEditsRepository;
13
use App\Repository\UserRepository;
14
use GuzzleHttp\Client;
15
use Psr\Cache\CacheItemPoolInterface;
16
use Psr\Container\ContainerInterface;
17
use Symfony\Component\HttpFoundation\JsonResponse;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\Routing\Annotation\Route;
21
22
/**
23
 * The Top Edits tool.
24
 */
25
class TopEditsController extends XtoolsController
26
{
27
    protected AutomatedEditsHelper $autoEditsHelper;
28
    protected TopEditsRepository $topEditsRepo;
29
30
    /**
31
     * Get the name of the tool's index route. This is also the name of the associated model.
32
     * @return string
33
     * @codeCoverageIgnore
34
     */
35
    public function getIndexRoute(): string
36
    {
37
        return 'TopEdits';
38
    }
39
40
    /**
41
     * TopEditsController constructor.
42
     * @param RequestStack $requestStack
43
     * @param ContainerInterface $container
44
     * @param CacheItemPoolInterface $cache
45
     * @param Client $guzzle
46
     * @param I18nHelper $i18n
47
     * @param ProjectRepository $projectRepo
48
     * @param UserRepository $userRepo
49
     * @param PageRepository $pageRepo
50
     * @param TopEditsRepository $topEditsRepo
51
     * @param AutomatedEditsHelper $autoEditsHelper
52
     */
53
    public function __construct(
54
        RequestStack $requestStack,
55
        ContainerInterface $container,
56
        CacheItemPoolInterface $cache,
57
        Client $guzzle,
58
        I18nHelper $i18n,
59
        ProjectRepository $projectRepo,
60
        UserRepository $userRepo,
61
        PageRepository $pageRepo,
62
        TopEditsRepository $topEditsRepo,
63
        AutomatedEditsHelper $autoEditsHelper
64
    ) {
65
        $this->topEditsRepo = $topEditsRepo;
66
        $this->autoEditsHelper = $autoEditsHelper;
67
        $this->limit = 1000;
68
        parent::__construct($requestStack, $container, $cache, $guzzle, $i18n, $projectRepo, $userRepo, $pageRepo);
69
    }
70
71
    /**
72
     * @inheritDoc
73
     */
74
    public function tooHighEditCountRoute(): string
75
    {
76
        return $this->getIndexRoute();
77
    }
78
79
    /**
80
     * The Top Edits by page action is exempt from the edit count limitation.
81
     * @inheritDoc
82
     */
83
    public function tooHighEditCountActionAllowlist(): array
84
    {
85
        return ['singlePageTopEdits'];
86
    }
87
88
    /**
89
     * @inheritDoc
90
     */
91
    public function restrictedApiActions(): array
92
    {
93
        return ['namespaceTopEditsUserApi'];
94
    }
95
96
    /**
97
     * Display the form.
98
     * @Route("/topedits", name="topedits")
99
     * @Route("/topedits", name="TopEdits")
100
     * @Route("/topedits/index.php", name="TopEditsIndex")
101
     * @Route("/topedits/{project}", name="TopEditsProject")
102
     * @return Response
103
     */
104
    public function indexAction(): Response
105
    {
106
        // Redirect if at minimum project and username are provided.
107
        if (isset($this->params['project']) && isset($this->params['username'])) {
108
            if (empty($this->params['page'])) {
109
                return $this->redirectToRoute('TopEditsResultNamespace', $this->params);
110
            }
111
            return $this->redirectToRoute('TopEditsResultPage', $this->params);
112
        }
113
114
        return $this->render('topedits/index.html.twig', array_merge([
115
            'xtPageTitle' => 'tool-topedits',
116
            'xtSubtitle' => 'tool-topedits-desc',
117
            'xtPage' => 'TopEdits',
118
119
            // Defaults that will get overriden if in $params.
120
            'namespace' => 0,
121
            'page' => '',
122
            'username' => '',
123
            'start' => '',
124
            'end' => '',
125
        ], $this->params, ['project' => $this->project]));
126
    }
127
128
    /**
129
     * Every action in this controller (other than 'index') calls this first.
130
     * @return TopEdits
131
     * @codeCoverageIgnore
132
     */
133
    public function setUpTopEdits(): TopEdits
134
    {
135
        return new TopEdits(
136
            $this->topEditsRepo,
137
            $this->autoEditsHelper,
138
            $this->project,
139
            $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\TopEdits::__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

139
            /** @scrutinizer ignore-type */ $this->user,
Loading history...
140
            $this->page,
141
            $this->namespace,
142
            $this->start,
143
            $this->end,
144
            $this->limit,
145
            (int)$this->request->query->get('pagination', 0)
146
        );
147
    }
148
149
    /**
150
     * List top edits by this user for all pages in a particular namespace.
151
     * @Route("/topedits/{project}/{username}/{namespace}/{start}/{end}",
152
     *     name="TopEditsResultNamespace",
153
     *     requirements={
154
     *         "username" = "(ipr-.+\/\d+[^\/])|([^\/]+)",
155
     *         "namespace"="|all|\d+",
156
     *         "start"="|\d{4}-\d{2}-\d{2}",
157
     *         "end"="|\d{4}-\d{2}-\d{2}",
158
     *     },
159
     *     defaults={"namespace" = "all", "start"=false, "end"=false}
160
     * )
161
     * @return Response
162
     * @codeCoverageIgnore
163
     */
164
    public function namespaceTopEditsAction(): Response
165
    {
166
        // Max number of rows per namespace to show. `null` here will use the TopEdits default.
167
        $this->limit = $this->isSubRequest ? 10 : $this->limit;
168
169
        $topEdits = $this->setUpTopEdits();
170
        $topEdits->prepareData();
171
172
        $ret = [
173
            'xtPage' => 'TopEdits',
174
            '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

174
            '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...
175
            'te' => $topEdits,
176
            'is_sub_request' => $this->isSubRequest,
177
        ];
178
179
        // Output the relevant format template.
180
        return $this->getFormattedResponse('topedits/result_namespace', $ret);
181
    }
182
183
    /**
184
     * List top edits by this user for a particular page.
185
     * @Route("/topedits/{project}/{username}/{namespace}/{page}/{start}/{end}",
186
     *     name="TopEditsResultPage",
187
     *     requirements={
188
     *         "username" = "(ipr-.+\/\d+[^\/])|([^\/]+)",
189
     *         "namespace"="|all|\d+",
190
     *         "page"="(.+?)(?!\/(?:|\d{4}-\d{2}-\d{2})(?:\/(|\d{4}-\d{2}-\d{2}))?)?$",
191
     *         "start"="|\d{4}-\d{2}-\d{2}",
192
     *         "end"="|\d{4}-\d{2}-\d{2}",
193
     *     },
194
     *     defaults={"namespace"="all", "start"=false, "end"=false}
195
     * )
196
     * @todo Add pagination.
197
     * @return Response
198
     * @codeCoverageIgnore
199
     */
200
    public function singlePageTopEditsAction(): Response
201
    {
202
        $topEdits = $this->setUpTopEdits();
203
        $topEdits->prepareData();
204
205
        // Send all to the template.
206
        return $this->getFormattedResponse('topedits/result_article', [
207
            'xtPage' => 'TopEdits',
208
            'xtTitle' => $this->user->getUsername() . ' - ' . $this->page->getTitle(),
0 ignored issues
show
Bug introduced by
The method getTitle() 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

208
            'xtTitle' => $this->user->getUsername() . ' - ' . $this->page->/** @scrutinizer ignore-call */ getTitle(),

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...
209
            'te' => $topEdits,
210
        ]);
211
    }
212
213
    /************************ API endpoints ************************/
214
215
    /**
216
     * List top edits by this user for all pages in a particular namespace.
217
     * @Route("/api/user/top_edits/{project}/{username}/{namespace}/{start}/{end}",
218
     *     name="UserApiTopEditsNamespace",
219
     *     requirements={
220
     *         "username" = "(ipr-.+\/\d+[^\/])|([^\/]+)",
221
     *         "namespace"="|\d+|all",
222
     *         "start"="|\d{4}-\d{2}-\d{2}",
223
     *         "end"="|\d{4}-\d{2}-\d{2}",
224
     *     },
225
     *     defaults={"namespace"="all", "start"=false, "end"=false}
226
     * )
227
     * @return JsonResponse
228
     * @codeCoverageIgnore
229
     */
230
    public function namespaceTopEditsUserApiAction(): JsonResponse
231
    {
232
        $this->recordApiUsage('user/topedits');
233
234
        $topEdits = $this->setUpTopEdits();
235
        $topEdits->prepareData();
236
237
        return $this->getFormattedApiResponse([
238
            'top_edits' => (object)$topEdits->getTopEdits(),
239
        ]);
240
    }
241
242
    /**
243
     * Get the all edits of a user to a specific page, maximum 1000.
244
     * @Route("/api/user/top_edits/{project}/{username}/{namespace}/{page}/{start}/{end}",
245
     *     name="UserApiTopEditsPage",
246
     *     requirements = {
247
     *         "username" = "(ipr-.+\/\d+[^\/])|([^\/]+)",
248
     *         "namespace"="|\d+|all",
249
     *         "page"="(.+?)(?!\/(?:|\d{4}-\d{2}-\d{2})(?:\/(|\d{4}-\d{2}-\d{2}))?)?$",
250
     *         "start"="|\d{4}-\d{2}-\d{2}",
251
     *         "end"="|\d{4}-\d{2}-\d{2}",
252
     *     },
253
     *     defaults={"namespace"="all", "start"=false, "end"=false}
254
     * )
255
     * @todo Add pagination.
256
     * @return JsonResponse
257
     * @codeCoverageIgnore
258
     */
259
    public function singlePageTopEditsUserApiAction(): JsonResponse
260
    {
261
        $this->recordApiUsage('user/topedits');
262
263
        $topEdits = $this->setUpTopEdits();
264
        $topEdits->prepareData(false);
265
266
        return $this->getFormattedApiResponse([
267
            'top_edits' => $topEdits->getTopEdits(),
268
        ]);
269
    }
270
}
271