Passed
Push — main ( ec4ebd...49d96d )
by MusikAnimal
04:21
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
     * @inheritDoc
32
     * @codeCoverageIgnore
33
     */
34
    public function getIndexRoute(): string
35
    {
36
        return 'TopEdits';
37
    }
38
39
    /**
40
     * TopEditsController constructor.
41
     * @param RequestStack $requestStack
42
     * @param ContainerInterface $container
43
     * @param CacheItemPoolInterface $cache
44
     * @param Client $guzzle
45
     * @param I18nHelper $i18n
46
     * @param ProjectRepository $projectRepo
47
     * @param UserRepository $userRepo
48
     * @param PageRepository $pageRepo
49
     * @param TopEditsRepository $topEditsRepo
50
     * @param AutomatedEditsHelper $autoEditsHelper
51
     */
52
    public function __construct(
53
        RequestStack $requestStack,
54
        ContainerInterface $container,
55
        CacheItemPoolInterface $cache,
56
        Client $guzzle,
57
        I18nHelper $i18n,
58
        ProjectRepository $projectRepo,
59
        UserRepository $userRepo,
60
        PageRepository $pageRepo,
61
        TopEditsRepository $topEditsRepo,
62
        AutomatedEditsHelper $autoEditsHelper
63
    ) {
64
        $this->topEditsRepo = $topEditsRepo;
65
        $this->autoEditsHelper = $autoEditsHelper;
66
        $this->limit = 1000;
67
        parent::__construct($requestStack, $container, $cache, $guzzle, $i18n, $projectRepo, $userRepo, $pageRepo);
68
    }
69
70
    /**
71
     * @inheritDoc
72
     * @codeCoverageIgnore
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
     * @codeCoverageIgnore
83
     */
84
    public function tooHighEditCountActionAllowlist(): array
85
    {
86
        return ['singlePageTopEdits'];
87
    }
88
89
    /**
90
     * @inheritDoc
91
     * @codeCoverageIgnore
92
     */
93
    public function restrictedApiActions(): array
94
    {
95
        return ['namespaceTopEditsUserApi'];
96
    }
97
98
    /**
99
     * Display the form.
100
     * @Route("/topedits", name="topedits")
101
     * @Route("/topedits", name="TopEdits")
102
     * @Route("/topedits/index.php", name="TopEditsIndex")
103
     * @Route("/topedits/{project}", name="TopEditsProject")
104
     * @return Response
105
     */
106
    public function indexAction(): Response
107
    {
108
        // Redirect if at minimum project and username are provided.
109
        if (isset($this->params['project']) && isset($this->params['username'])) {
110
            if (empty($this->params['page'])) {
111
                return $this->redirectToRoute('TopEditsResultNamespace', $this->params);
112
            }
113
            return $this->redirectToRoute('TopEditsResultPage', $this->params);
114
        }
115
116
        return $this->render('topedits/index.html.twig', array_merge([
117
            'xtPageTitle' => 'tool-topedits',
118
            'xtSubtitle' => 'tool-topedits-desc',
119
            'xtPage' => 'TopEdits',
120
121
            // Defaults that will get overriden if in $params.
122
            'namespace' => 0,
123
            'page' => '',
124
            'username' => '',
125
            'start' => '',
126
            'end' => '',
127
        ], $this->params, ['project' => $this->project]));
128
    }
129
130
    /**
131
     * Every action in this controller (other than 'index') calls this first.
132
     * @return TopEdits
133
     * @codeCoverageIgnore
134
     */
135
    public function setUpTopEdits(): TopEdits
136
    {
137
        return new TopEdits(
138
            $this->topEditsRepo,
139
            $this->autoEditsHelper,
140
            $this->project,
141
            $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

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

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

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