Test Failed
Push — dependency-injection ( 7565fa )
by MusikAnimal
07:05
created

CategoryEditsController::__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\Exception\XtoolsHttpException;
8
use App\Helper\I18nHelper;
9
use App\Model\CategoryEdits;
10
use App\Repository\CategoryEditsRepository;
11
use App\Repository\EditRepository;
12
use App\Repository\PageRepository;
13
use App\Repository\ProjectRepository;
14
use App\Repository\UserRepository;
15
use GuzzleHttp\Client;
16
use Psr\Cache\CacheItemPoolInterface;
17
use Psr\Container\ContainerInterface;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpFoundation\RequestStack;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\Routing\Annotation\Route;
22
23
/**
24
 * This controller serves the Category Edits tool.
25
 */
26
class CategoryEditsController extends XtoolsController
27
{
28
    protected CategoryEdits $categoryEdits;
29
    protected CategoryEditsRepository $categoryEditsRepo;
30
    protected EditRepository $editRepo;
31
32
    /** @var string[] The categories, with or without namespace. */
33
    protected array $categories;
34
35
    /** @var array Data that is passed to the view. */
36
    private array $output;
37
38
    /**
39
     * Get the name of the tool's index route.
40
     * This is also the name of the associated model.
41
     * @return string
42
     * @codeCoverageIgnore
43
     */
44
    public function getIndexRoute(): string
45
    {
46
        return 'CategoryEdits';
47
    }
48
49
    /**
50
     * @param RequestStack $requestStack
51
     * @param ContainerInterface $container
52
     * @param CacheItemPoolInterface $cache
53
     * @param Client $guzzle
54
     * @param I18nHelper $i18n
55
     * @param ProjectRepository $projectRepo
56
     * @param UserRepository $userRepo
57
     * @param PageRepository $pageRepo
58
     * @param EditRepository $editRepo
59
     * @param CategoryEditsRepository $categoryEditsRepo
60
     */
61
    public function __construct(
62
        RequestStack $requestStack,
63
        ContainerInterface $container,
64
        CacheItemPoolInterface $cache,
65
        Client $guzzle,
66
        I18nHelper $i18n,
67
        ProjectRepository $projectRepo,
68
        UserRepository $userRepo,
69
        PageRepository $pageRepo,
70
        EditRepository $editRepo,
71
        CategoryEditsRepository $categoryEditsRepo
72
    ) {
73
        $this->editRepo = $editRepo;
74
        $this->pageRepo = $pageRepo;
75
        $this->categoryEditsRepo = $categoryEditsRepo;
76
        parent::__construct($requestStack, $container, $cache, $guzzle, $i18n, $projectRepo, $userRepo, $pageRepo);
77
    }
78
79
    /**
80
     * Will redirect back to index if the user has too high of an edit count.
81
     * @return string
82
     */
83
    public function tooHighEditCountRoute(): string
84
    {
85
        return $this->getIndexRoute();
86
    }
87
88
    /**
89
     * Display the search form.
90
     * @Route("/categoryedits", name="CategoryEdits")
91
     * @Route("/categoryedits/{project}", name="CategoryEditsProject")
92
     * @return Response
93
     * @codeCoverageIgnore
94
     */
95
    public function indexAction(): Response
96
    {
97
        // Redirect if at minimum project, username and categories are provided.
98
        if (isset($this->params['project']) && isset($this->params['username']) && isset($this->params['categories'])) {
99
            return $this->redirectToRoute('CategoryEditsResult', $this->params);
100
        }
101
102
        return $this->render('categoryEdits/index.html.twig', array_merge([
103
            'xtPageTitle' => 'tool-categoryedits',
104
            'xtSubtitle' => 'tool-categoryedits-desc',
105
            'xtPage' => 'CategoryEdits',
106
107
            // Defaults that will get overridden if in $params.
108
            'namespace' => 0,
109
            'start' => '',
110
            'end' => '',
111
            'username' => '',
112
            'categories' => '',
113
        ], $this->params, ['project' => $this->project]));
114
    }
115
116
    /**
117
     * Set defaults, and instantiate the CategoryEdits model. This is called at the top of every view action.
118
     * @codeCoverageIgnore
119
     */
120
    private function setupCategoryEdits(): void
121
    {
122
        $this->extractCategories();
123
124
        $this->categoryEdits = new CategoryEdits(
125
            $this->categoryEditsRepo,
126
            $this->editRepo,
127
            $this->pageRepo,
128
            $this->userRepo,
129
            $this->project,
130
            $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\CategoryEdits::__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

130
            /** @scrutinizer ignore-type */ $this->user,
Loading history...
131
            $this->categories,
132
            $this->start,
133
            $this->end,
134
            $this->offset
135
        );
136
137
        $this->output = [
138
            'xtPage' => 'CategoryEdits',
139
            '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

139
            '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...
140
            'project' => $this->project,
141
            'user' => $this->user,
142
            'ce' => $this->categoryEdits,
143
            'is_sub_request' => $this->isSubRequest,
144
        ];
145
    }
146
147
    /**
148
     * Go through the categories and normalize values, and set them on class properties.
149
     * @codeCoverageIgnore
150
     */
151
    private function extractCategories(): void
152
    {
153
        // Split categories by pipe.
154
        $categories = explode('|', $this->request->get('categories'));
0 ignored issues
show
Bug introduced by
It seems like $this->request->get('categories') can also be of type null; however, parameter $string of explode() does only seem to accept string, 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

154
        $categories = explode('|', /** @scrutinizer ignore-type */ $this->request->get('categories'));
Loading history...
155
156
        // Loop through the given categories, stripping out the namespace.
157
        // If a namespace was removed, it is flagged it as normalize
158
        // We look for the wiki's category namespace name, and the MediaWiki default
159
        // 'Category:', which sometimes is used cross-wiki (because it still works).
160
        $normalized = false;
161
        $nsName = $this->project->getNamespaces()[14].':';
162
        $this->categories = array_map(function ($category) use ($nsName, &$normalized) {
163
            if (0 === strpos($category, $nsName) || 0 === strpos($category, 'Category:')) {
164
                $normalized = true;
165
            }
166
            return preg_replace('/^'.$nsName.'/', '', $category);
167
        }, $categories);
168
169
        // Redirect if normalized, since we don't want the Category: prefix in the URL.
170
        if ($normalized) {
171
            throw new XtoolsHttpException(
172
                '',
173
                $this->generateUrl($this->request->get('_route'), array_merge(
0 ignored issues
show
Bug introduced by
It seems like $this->request->get('_route') can also be of type null; however, parameter $route of Symfony\Bundle\Framework...ntroller::generateUrl() does only seem to accept string, 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

173
                $this->generateUrl(/** @scrutinizer ignore-type */ $this->request->get('_route'), array_merge(
Loading history...
174
                    $this->request->attributes->get('_route_params'),
175
                    ['categories' => implode('|', $this->categories)]
176
                ))
177
            );
178
        }
179
    }
180
181
    /**
182
     * Display the results.
183
     * @Route(
184
     *     "/categoryedits/{project}/{username}/{categories}/{start}/{end}/{offset}",
185
     *     name="CategoryEditsResult",
186
     *     requirements={
187
     *         "username" = "(ipr-.+\/\d+[^\/])|([^\/]+)",
188
     *         "categories"="(.+?)(?!\/(?:|\d{4}-\d{2}-\d{2})(?:\/(|\d{4}-\d{2}-\d{2}))?)?$",
189
     *         "start"="|\d{4}-\d{2}-\d{2}",
190
     *         "end"="|\d{4}-\d{2}-\d{2}",
191
     *         "offset"="|\d{4}-?\d{2}-?\d{2}T?\d{2}:?\d{2}:?\d{2}",
192
     *     },
193
     *     defaults={"start"=false, "end"=false, "offset"=false}
194
     * )
195
     * @param CategoryEditsRepository $categoryEditsRepo
196
     * @return Response
197
     * @codeCoverageIgnore
198
     */
199
    public function resultAction(CategoryEditsRepository $categoryEditsRepo): Response
200
    {
201
        $this->setupCategoryEdits($categoryEditsRepo);
0 ignored issues
show
Unused Code introduced by
The call to App\Controller\CategoryE...r::setupCategoryEdits() has too many arguments starting with $categoryEditsRepo. ( Ignorable by Annotation )

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

201
        $this->/** @scrutinizer ignore-call */ 
202
               setupCategoryEdits($categoryEditsRepo);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
202
203
        return $this->getFormattedResponse('categoryEdits/result', $this->output);
204
    }
205
206
    /**
207
     * Get edits by a user to pages in given categories.
208
     * @Route(
209
     *   "/categoryedits-contributions/{project}/{username}/{categories}/{start}/{end}/{offset}",
210
     *   name="CategoryContributionsResult",
211
     *   requirements={
212
     *       "username" = "(ipr-.+\/\d+[^\/])|([^\/]+)",
213
     *       "categories"="(.+?)(?!\/(?:|\d{4}-\d{2}-\d{2}))?",
214
     *       "start"="|\d{4}-\d{2}-\d{2}",
215
     *       "end"="|\d{4}-\d{2}-\d{2}",
216
     *       "offset"="|\d{4}-?\d{2}-?\d{2}T?\d{2}:?\d{2}:?\d{2}",
217
     *   },
218
     *   defaults={"start"=false, "end"=false, "offset"=false}
219
     * )
220
     * @param CategoryEditsRepository $categoryEditsRepo
221
     * @return Response
222
     * @codeCoverageIgnore
223
     */
224
    public function categoryContributionsAction(CategoryEditsRepository $categoryEditsRepo): Response
225
    {
226
        $this->setupCategoryEdits($categoryEditsRepo);
0 ignored issues
show
Unused Code introduced by
The call to App\Controller\CategoryE...r::setupCategoryEdits() has too many arguments starting with $categoryEditsRepo. ( Ignorable by Annotation )

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

226
        $this->/** @scrutinizer ignore-call */ 
227
               setupCategoryEdits($categoryEditsRepo);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
227
228
        return $this->render('categoryEdits/contributions.html.twig', $this->output);
229
    }
230
231
    /************************ API endpoints ************************/
232
233
    /**
234
     * Count the number of category edits the given user has made.
235
     * @Route(
236
     *   "/api/user/category_editcount/{project}/{username}/{categories}/{start}/{end}",
237
     *   name="UserApiCategoryEditCount",
238
     *   requirements={
239
     *       "username" = "(ipr-.+\/\d+[^\/])|([^\/]+)",
240
     *       "categories" = "(.+?)(?!\/(?:|\d{4}-\d{2}-\d{2})(?:\/(|\d{4}-\d{2}-\d{2}))?)?$",
241
     *       "start" = "|\d{4}-\d{2}-\d{2}",
242
     *       "end" = "|\d{4}-\d{2}-\d{2}"
243
     *   },
244
     *   defaults={"start" = false, "end" = false}
245
     * )
246
     * @param CategoryEditsRepository $categoryEditsRepo
247
     * @return JsonResponse
248
     * @codeCoverageIgnore
249
     */
250
    public function categoryEditCountApiAction(CategoryEditsRepository $categoryEditsRepo): JsonResponse
251
    {
252
        $this->recordApiUsage('user/category_editcount');
253
254
        $this->setupCategoryEdits($categoryEditsRepo);
0 ignored issues
show
Unused Code introduced by
The call to App\Controller\CategoryE...r::setupCategoryEdits() has too many arguments starting with $categoryEditsRepo. ( Ignorable by Annotation )

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

254
        $this->/** @scrutinizer ignore-call */ 
255
               setupCategoryEdits($categoryEditsRepo);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
255
256
        $ret = [
257
            'total_editcount' => $this->categoryEdits->getEditCount(),
258
            'category_editcount' => $this->categoryEdits->getCategoryEditCount(),
259
        ];
260
261
        return $this->getFormattedApiResponse($ret);
262
    }
263
}
264