Passed
Push — master ( be1142...a546ea )
by MusikAnimal
04:34
created

TopEditsController::resultAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 6
ccs 0
cts 0
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file contains only the TopEditsController 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\RequestStack;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\HttpFoundation\JsonResponse;
13
use Xtools\TopEdits;
14
use Xtools\TopEditsRepository;
15
16
/**
17
 * The Top Edits tool.
18
 */
19
class TopEditsController extends XtoolsController
20
{
21
    /**
22
     * Get the name of the tool's index route.
23
     * This is also the name of the associated model.
24
     * @return string
25
     * @codeCoverageIgnore
26
     */
27
    public function getIndexRoute()
28
    {
29
        return 'TopEdits';
30
    }
31
32
    /**
33
     * TopEditsController constructor.
34
     * @param RequestStack $requestStack
35
     * @param ContainerInterface $container
36
     */
37 1
    public function __construct(RequestStack $requestStack, ContainerInterface $container)
38
    {
39 1
        $this->tooHighEditCountAction = $this->getIndexRoute();
40
41
        // The Top Edits by page action is exempt from the edit count limitation.
42 1
        $this->tooHighEditCountActionBlacklist = ['singlePageTopEdits'];
43
44 1
        parent::__construct($requestStack, $container);
45 1
    }
46
47
    /**
48
     * Display the form.
49
     * @Route("/topedits", name="topedits")
50
     * @Route("/topedits", name="TopEdits")
51
     * @Route("/topedits/", name="topEditsSlash")
52
     * @Route("/topedits/index.php", name="TopEditsIndex")
53
     * @Route("/topedits/{project}", name="TopEditsProject")
54
     * @return Response
55
     */
56 1
    public function indexAction()
57
    {
58
        // Redirect if at minimum project and username are provided.
59 1
        if (isset($this->params['project']) && isset($this->params['username'])) {
60
            if (empty($this->params['page'])) {
61
                return $this->redirectToRoute('TopEditsResultNamespace', $this->params);
62
            }
63
            return $this->redirectToRoute('TopEditsResultPage', $this->params);
64
        }
65
66 1
        return $this->render('topedits/index.html.twig', array_merge([
67 1
            'xtPageTitle' => 'tool-topedits',
68
            'xtSubtitle' => 'tool-topedits-desc',
69
            'xtPage' => 'topedits',
70
71
            // Defaults that will get overriden if in $params.
72
            'namespace' => 0,
73
            'page' => '',
74
            'username' => '',
75 1
        ], $this->params, ['project' => $this->project]));
76
    }
77
78
    /**
79
     * List top edits by this user for all pages in a particular namespace.
80
     * @Route("/topedits/{project}/{username}/{namespace}", name="TopEditsResultNamespace",
81
     *     requirements = {"page"="|.+", "namespace" = "|all|\d+"},
82
     *     defaults = {"page" = "", "namespace" = "all"}
83
     * )
84
     * @return Response
85
     * @codeCoverageIgnore
86
     */
87
    public function namespaceTopEditsAction()
88
    {
89
        // Make sure they've opted in to see this data.
90
        if (!$this->project->userHasOptedIn($this->user)) {
91
            $optedInPage = $this->project
92
                ->getRepository()
93
                ->getPage($this->project, $this->project->userOptInPage($this->user));
94
95
            return $this->getFormattedResponse('topedits/result_namespace', [
96
                'xtPage' => 'topedits',
97
                'xtTitle' => $this->user->getUsername(),
98
                'project' => $this->project,
99
                'user' => $this->user,
100
                'namespace' => $this->namespace,
101
                'opted_in_page' => $optedInPage,
102
                'is_sub_request' => $this->isSubRequest,
103
            ]);
104
        }
105
106
        /**
107
         * Max number of rows per namespace to show. `null` here will cause to
108
         * use the TopEdits default.
109
         * @var int
110
         */
111
        $limit = $this->isSubRequest ? 10 : null;
112
113
        $topEdits = new TopEdits($this->project, $this->user, null, $this->namespace, $limit);
114
        $topEditsRepo = new TopEditsRepository();
115
        $topEditsRepo->setContainer($this->container);
116
        $topEdits->setRepository($topEditsRepo);
117
118
        $topEdits->prepareData();
119
120
        $ret = [
121
            'xtPage' => 'topedits',
122
            'xtTitle' => $this->user->getUsername(),
123
            'project' => $this->project,
124
            'user' => $this->user,
125
            'namespace' => $this->namespace,
126
            'te' => $topEdits,
127
            'is_sub_request' => $this->isSubRequest,
128
        ];
129
130
        // Output the relevant format template.
131
        return $this->getFormattedResponse('topedits/result_namespace', $ret);
132
    }
133
134
    /**
135
     * List top edits by this user for a particular page.
136
     * @Route("/topedits/{project}/{username}/{namespace}/{page}", name="TopEditsResultPage",
137
     *     requirements = {"page"="|.+", "namespace" = "|all|\d+"},
138
     *     defaults = {"page" = "", "namespace" = "all"}
139
     * )
140
     * @return Response
141
     * @codeCoverageIgnore
142
     */
143
    public function singlePageTopEditsAction()
144
    {
145
        // FIXME: add pagination.
146
        $topEdits = new TopEdits($this->project, $this->user, $this->page);
147
        $topEditsRepo = new TopEditsRepository();
148
        $topEditsRepo->setContainer($this->container);
149
        $topEdits->setRepository($topEditsRepo);
150
151
        $topEdits->prepareData();
152
153
        // Send all to the template.
154
        return $this->getFormattedResponse('topedits/result_article', [
155
            'xtPage' => 'topedits',
156
            'xtTitle' => $this->user->getUsername() . ' - ' . $this->page->getTitle(),
157
            'project' => $this->project,
158
            'user' => $this->user,
159
            'page' => $this->page,
160
            'te' => $topEdits,
161
        ]);
162
    }
163
164
    /************************ API endpoints ************************/
165
166
    /**
167
     * Get the all edits of a user to a specific page, maximum 1000.
168
     * @Route("/api/user/topedits/{project}/{username}/{namespace}/{page}", name="UserApiTopEditsArticle",
169
     *     requirements = {"page"="|.+", "namespace"="|\d+|all"},
170
     *     defaults={"page"="", "namespace"="all"}
171
     * )
172
     * @Route("/api/user/top_edits/{project}/{username}/{namespace}/{page}", name="UserApiTopEditsArticleUnderscored",
173
     *     requirements={"page"="|.+", "namespace"="|\d+|all"},
174
     *     defaults={"page"="", "namespace"="all"}
175
     * )
176
     * @return JsonResponse
177
     * @codeCoverageIgnore
178
     */
179
    public function topEditsUserApiAction()
180
    {
181
        $this->recordApiUsage('user/topedits');
182
183
        if (!$this->project->userHasOptedIn($this->user)) {
184
            return new JsonResponse(
185
                [
186
                    'error' => 'User:'.$this->user->getUsername().' has not opted in to detailed statistics.'
187
                ],
188
                Response::HTTP_FORBIDDEN
189
            );
190
        }
191
192
        $limit = isset($this->page) ? 1000 : 20;
193
        $topEdits = new TopEdits($this->project, $this->user, null, $this->namespace, $limit);
194
        $topEditsRepo = new TopEditsRepository();
195
        $topEditsRepo->setContainer($this->container);
196
        $topEdits->setRepository($topEditsRepo);
197
198
        if (isset($this->page)) {
199
            $topEdits->setPage($this->page);
200
            $topEdits->prepareData(false);
201
        } else {
202
            // Do format the results.
203
            $topEdits->prepareData();
204
        }
205
206
        return $this->getFormattedApiResponse([
207
            'top_edits' => $topEdits->getTopEdits(),
208
        ]);
209
    }
210
}
211