Passed
Push — master ( e6ce91...429907 )
by MusikAnimal
04:46
created

CategoryEditsController::normalizeAndSetParams()   B

Complexity

Conditions 9
Paths 25

Size

Total Lines 54
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 28
nc 25
nop 1
dl 0
loc 54
rs 8.0555
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A CategoryEditsController::categoryContributionsAction() 0 5 1
A CategoryEditsController::resultAction() 0 6 1

How to fix   Long Method   

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 CategoryEditsController class.
4
 */
5
6
namespace AppBundle\Controller;
7
8
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
9
use Symfony\Component\DependencyInjection\ContainerInterface;
10
use Symfony\Component\HttpFoundation\JsonResponse;
11
use Symfony\Component\HttpFoundation\RedirectResponse;
12
use Symfony\Component\HttpFoundation\RequestStack;
13
use Symfony\Component\HttpFoundation\Response;
14
use Xtools\CategoryEdits;
15
use Xtools\CategoryEditsRepository;
16
17
/**
18
 * This controller serves the Category Edits tool.
19
 */
20
class CategoryEditsController extends XtoolsController
21
{
22
    /** @var CategoryEdits The CategoryEdits instance. */
23
    protected $categoryEdits;
24
25
    /** @var string[] The categories, with or without namespace. */
26
    protected $categories;
27
28
    /** @var array Data that is passed to the view. */
29
    private $output;
30
31
    /**
32
     * Get the name of the tool's index route.
33
     * This is also the name of the associated model.
34
     * @return string
35
     * @codeCoverageIgnore
36
     */
37
    public function getIndexRoute()
38
    {
39
        return 'CategoryEdits';
40
    }
41
42
    /**
43
     * CategoryEditsController constructor.
44
     * @param RequestStack $requestStack
45
     * @param ContainerInterface $container
46
     */
47
    public function __construct(RequestStack $requestStack, ContainerInterface $container)
48
    {
49
        // Will redirect back to index if the user has too high of an edit count.
50
        $this->tooHighEditCountAction = $this->getIndexRoute();
51
52
        parent::__construct($requestStack, $container);
53
    }
54
55
    /**
56
     * Display the search form.
57
     * @Route("/categoryedits", name="CategoryEdits")
58
     * @Route("/categoryedits/", name="CategoryEditsSlash")
59
     * @Route("/categoryedits/{project}", name="CategoryEditsProject")
60
     * @return Response
61
     * @codeCoverageIgnore
62
     */
63
    public function indexAction()
64
    {
65
        // Redirect if at minimum project, username and categories are provided.
66
        if (isset($this->params['project']) && isset($this->params['username']) && isset($this->params['categories'])) {
67
            return $this->redirectToRoute('CategoryEditsResult', $this->params);
68
        }
69
70
        return $this->render('categoryEdits/index.html.twig', array_merge([
71
            'xtPageTitle' => 'tool-categoryedits',
72
            'xtSubtitle' => 'tool-categoryedits-desc',
73
            'xtPage' => 'categoryedits',
74
75
            // Defaults that will get overridden if in $params.
76
            'namespace' => 0,
77
            'start' => '',
78
            'end' => '',
79
            'username' => '',
80
        ], $this->params, ['project' => $this->project]));
81
    }
82
83
    /**
84
     * Set defaults, and instantiate the CategoryEdits model. This is called at the top of every view action.
85
     * @codeCoverageIgnore
86
     */
87
    private function setupCategoryEdits()
88
    {
89
        $this->extractCategories();
90
91
        $this->categoryEdits = new CategoryEdits(
92
            $this->project,
93
            $this->user,
94
            $this->categories,
95
            $this->start,
96
            $this->end,
97
            isset($this->offset) ? $this->offset : 0
98
        );
99
        $categoryEditsRepo = new CategoryEditsRepository();
100
        $categoryEditsRepo->setContainer($this->container);
101
        $this->categoryEdits->setRepository($categoryEditsRepo);
102
103
        $this->output = [
104
            'xtPage' => 'categoryedits',
105
            'xtTitle' => $this->user->getUsername(),
106
            'project' => $this->project,
107
            'user' => $this->user,
108
            'ce' => $this->categoryEdits,
109
            'is_sub_request' => $this->isSubRequest,
110
        ];
111
    }
112
113
    /**
114
     * Go through the categories and normalize values, and set them on class properties.
115
     * @return null|RedirectResponse Redirect if categories were normalized.
116
     * @codeCoverageIgnore
117
     */
118
    private function extractCategories()
119
    {
120
        // Split categories by pipe.
121
        $categories = explode('|', $this->request->get('categories'));
122
123
        // Loop through the given categories, stripping out the namespace.
124
        // If a namespace was removed, it is flagged it as normalize
125
        // We look for the wiki's category namespace name, and the MediaWiki default
126
        // 'Category:', which sometimes is used cross-wiki (because it still works).
127
        $normalized = false;
128
        $nsName = $this->project->getNamespaces()[14].':';
129
        $this->categories = array_map(function ($category) use ($nsName, &$normalized) {
130
            if (strpos($category, $nsName) === 0 || strpos($category, 'Category:') === 0) {
131
                $normalized = true;
132
            }
133
            return ltrim(ltrim($category, $nsName.':'), 'Category:');
134
        }, $categories);
135
136
        // Redirect if normalized, since we don't want the Category: prefix in the URL.
137
        if ($normalized) {
138
            return $this->redirectToRoute($this->request->get('_route'), array_merge(
139
                $this->request->attributes->get('_route_params'),
140
                ['categories' => implode('|', $this->categories)]
141
            ));
142
        }
143
144
        return null;
145
    }
146
147
    /**
148
     * Display the results.
149
     * @Route(
150
     *     "/categoryedits/{project}/{username}/{categories}/{start}/{end}",
151
     *     name="CategoryEditsResult",
152
     *     requirements={
153
     *         "categories"="(.+?)(?!\/(?:|\d{4}-\d{2}-\d{2})(?:\/(|\d{4}-\d{2}-\d{2}))?)?$",
154
     *         "start"="|\d{4}-\d{2}-\d{2}",
155
     *         "end"="|\d{4}-\d{2}-\d{2}"
156
     *     },
157
     *     defaults={"start" = false, "end" = false}
158
     * )
159
     * @return Response
160
     * @codeCoverageIgnore
161
     */
162
    public function resultAction()
163
    {
164
        $this->setupCategoryEdits();
165
166
        // Render the view with all variables set.
167
        return $this->render('categoryEdits/result.html.twig', $this->output);
168
    }
169
170
    /**
171
     * Get edits my by a user to pages in given categories.
172
     * @Route(
173
     *   "/categoryedits-contributions/{project}/{username}/{categories}/{start}/{end}/{offset}",
174
     *   name="CategoryContributionsResult",
175
     *   requirements={
176
     *       "categories" = "(.+?)(?!\/(?:|\d{4}-\d{2}-\d{2})(?:\/(|\d{4}-\d{2}-\d{2}))?)?$",
177
     *       "start" = "|\d{4}-\d{2}-\d{2}",
178
     *       "end" = "|\d{4}-\d{2}-\d{2}",
179
     *       "offset" = "|\d+"
180
     *   },
181
     *   defaults={"start" = false, "end" = false, "offset" = 0}
182
     * )
183
     * @return Response
184
     * @codeCoverageIgnore
185
     */
186
    public function categoryContributionsAction()
187
    {
188
        $this->setupCategoryEdits();
189
190
        return $this->render('categoryEdits/contributions.html.twig', $this->output);
191
    }
192
193
    /************************ API endpoints ************************/
194
195
    /**
196
     * Count the number of category edits the given user has made.
197
     * @Route(
198
     *   "/api/user/category_editcount/{project}/{username}/{categories}/{start}/{end}",
199
     *   name="UserApiCategoryEditCount",
200
     *   requirements={
201
     *       "categories" = "(.+?)(?!\/(?:|\d{4}-\d{2}-\d{2})(?:\/(|\d{4}-\d{2}-\d{2}))?)?$",
202
     *       "start" = "|\d{4}-\d{2}-\d{2}",
203
     *       "end" = "|\d{4}-\d{2}-\d{2}"
204
     *   },
205
     *   defaults={"start" = false, "end" = false}
206
     * )
207
     * @return JsonResponse
208
     * @codeCoverageIgnore
209
     */
210
    public function categoryEditCountApiAction()
211
    {
212
        $this->recordApiUsage('user/category_editcount');
213
214
        $this->setupCategoryEdits();
215
216
        $ret = [
217
            'total_editcount' => $this->categoryEdits->getEditCount(),
218
            'category_editcount' => $this->categoryEdits->getCategoryEditCount(),
219
        ];
220
221
        return $this->getFormattedApiResponse($ret);
222
    }
223
}
224