Passed
Pull Request — master (#139)
by MusikAnimal
04:19
created

PagesController::indexAction()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 2
nop 1
dl 0
loc 22
ccs 7
cts 8
cp 0.875
crap 3.0175
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file contains only the PagesController class.
4
 */
5
6
namespace AppBundle\Controller;
7
8
use DateTime;
9
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
10
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\HttpFoundation\RedirectResponse;
14
use Symfony\Component\HttpFoundation\JsonResponse;
15
use Xtools\ProjectRepository;
16
use Xtools\UserRepository;
17
use Xtools\Pages;
18
19
/**
20
 * This controller serves the Pages tool.
21
 */
22
class PagesController extends XtoolsController
23
{
24
    const RESULTS_PER_PAGE = 1000;
25
26
    /**
27
     * Get the tool's shortname.
28
     * @return string
29
     * @codeCoverageIgnore
30
     */
31
    public function getToolShortname()
32
    {
33
        return 'pages';
34
    }
35
36
    /**
37
     * Display the form.
38
     * @Route("/pages", name="pages")
39
     * @Route("/pages", name="Pages")
40
     * @Route("/pages/", name="PagesSlash")
41
     * @Route("/pages/index.php", name="PagesIndexPhp")
42
     * @Route("/pages/{project}", name="PagesProject")
43
     * @param Request $request
44
     * @return Response
45
     */
46 1
    public function indexAction(Request $request)
47
    {
48 1
        $params = $this->parseQueryParams($request);
49
50
        // Redirect if at minimum project and username are given.
51 1
        if (isset($params['project']) && isset($params['username'])) {
52
            return $this->redirectToRoute('PagesResult', $params);
53
        }
54
55
        // Convert the given project (or default project) into a Project instance.
56 1
        $params['project'] = $this->getProjectFromQuery($params);
57
58
        // Otherwise fall through.
59 1
        return $this->render('pages/index.html.twig', array_merge([
60 1
            'xtPageTitle' => 'tool-pages',
61
            'xtSubtitle' => 'tool-pages-desc',
62
            'xtPage' => 'pages',
63
64
            // Defaults that will get overriden if in $params.
65
            'namespace' => 0,
66
            'redirects' => 'noredirects',
67 1
        ], $params));
68
    }
69
70
    /**
71
     * Display the results.
72
     * @Route("/pages/{project}/{username}/{namespace}/{redirects}/{offset}", name="PagesResult")
73
     * @param Request $request
74
     * @param string|int $namespace The ID of the namespace, or 'all' for all namespaces.
75
     * @param string $redirects Whether to follow redirects or not.
76
     * @param int $offset Which page of results to show, when the results are so large they are paginated.
77
     * @return RedirectResponse|Response
78
     * @codeCoverageIgnore
79
     */
80 View Code Duplication
    public function resultAction(Request $request, $namespace = '0', $redirects = 'noredirects', $offset = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
    {
82
        $ret = $this->validateProjectAndUser($request, 'pages');
83
        if ($ret instanceof RedirectResponse) {
84
            return $ret;
85
        } else {
86
            list($projectData, $user) = $ret;
87
        }
88
89
        $pages = new Pages(
90
            $projectData,
91
            $user,
92
            $namespace,
93
            $redirects,
94
            $offset
95
        );
96
        $pages->prepareData();
97
98
        // Assign the values and display the template
99
        return $this->render('pages/result.html.twig', [
100
            'xtPage' => 'pages',
101
            'xtTitle' => $user->getUsername(),
102
            'project' => $projectData,
103
            'user' => $user,
104
            'summaryColumns' => $this->getSummaryColumns($redirects),
105
            'pages' => $pages,
106
        ]);
107
    }
108
109
    /**
110
     * What columns to show in namespace totals table.
111
     * @param  string $redirects One of 'noredirects', 'onlyredirects' or blank for both.
112
     * @return string[]
113
     * @codeCoverageIgnore
114
     */
115
    protected function getSummaryColumns($redirects)
116
    {
117
        $summaryColumns = ['namespace'];
118
        if ($redirects == 'onlyredirects') {
119
            // Don't show redundant pages column if only getting data on redirects.
120
            $summaryColumns[] = 'redirects';
121
        } elseif ($redirects == 'noredirects') {
122
            // Don't show redundant redirects column if only getting data on non-redirects.
123
            $summaryColumns[] = 'pages';
124
        } else {
125
            // Order is important here.
126
            $summaryColumns[] = 'pages';
127
            $summaryColumns[] = 'redirects';
128
        }
129
130
        // Always show deleted as the last column.
131
        $summaryColumns[] = 'deleted';
132
133
        return $summaryColumns;
134
    }
135
136
    /************************ API endpoints ************************/
137
138
    /**
139
     * Get a count of the number of pages created by a user,
140
     * including the number that have been deleted and are redirects.
141
     * @Route("/api/pages_count/{project}/{username}/{namespace}/{redirects}", name="PagesApiCount",
142
     *     requirements={"namespace"="|\d+|all"})
143
     * @param Request $request
144
     * @param int|string $namespace The ID of the namespace of the page, or 'all' for all namespaces.
145
     * @param string     $redirects One of 'noredirects', 'onlyredirects' or 'all' for both.
146
     * @return Response
147
     * @codeCoverageIgnore
148
     */
149
    public function countPagesApiAction(Request $request, $namespace = 0, $redirects = 'noredirects')
150
    {
151
        $ret = $this->validateProjectAndUser($request);
152
        if ($ret instanceof RedirectResponse) {
153
            return $ret;
154
        } else {
155
            list($project, $user) = $ret;
156
        }
157
158
        $pages = new Pages(
159
            $project,
160
            $user,
161
            $namespace,
162
            $redirects
163
        );
164
165
        $response = new JsonResponse();
166
        $response->setEncodingOptions(JSON_NUMERIC_CHECK);
167
        $response->setStatusCode(Response::HTTP_OK);
168
169
        $counts = $pages->getCounts();
170
171
        if ($namespace !== 'all' && isset($counts[$namespace])) {
172
            $counts = $counts[$namespace];
173
        }
174
175
        $ret = [
176
            'project' => $project->getDomain(),
177
            'username' => $user->getUsername(),
178
            'namespace' => $namespace,
179
            'redirects' => $redirects,
180
            'counts' => $counts,
181
        ];
182
183
        $response->setData($ret);
184
185
        return $response;
186
    }
187
188
    /**
189
     * Get the pages created by by a user.
190
     * @Route("/api/pages/{project}/{username}/{namespace}/{redirects}/{offset}", name="PagesApi",
191
     *     requirements={"namespace"="|\d+|all"})
192
     * @param Request $request
193
     * @param int|string $namespace The ID of the namespace of the page, or 'all' for all namespaces.
194
     * @param string     $redirects One of 'noredirects', 'onlyredirects' or 'all' for both.
195
     * @param int        $offset Which page of results to show.
196
     * @return Response
197
     * @codeCoverageIgnore
198
     */
199
    public function getPagesApiAction(Request $request, $namespace = 0, $redirects = 'noredirects', $offset = 0)
200
    {
201
        // Second parameter causes it return a Redirect to the index if the user has too many edits.
202
        $ret = $this->validateProjectAndUser($request, 'pages');
203
        if ($ret instanceof RedirectResponse) {
204
            return $ret;
205
        } else {
206
            list($project, $user) = $ret;
207
        }
208
209
        $pages = new Pages(
210
            $project,
211
            $user,
212
            $namespace,
213
            $redirects,
214
            $offset
215
        );
216
217
        $response = new JsonResponse();
218
        $response->setEncodingOptions(JSON_NUMERIC_CHECK);
219
        $response->setStatusCode(Response::HTTP_OK);
220
221
        $pagesList = $pages->getResults();
222
223
        if ($namespace !== 'all' && isset($pagesList[$namespace])) {
224
            $pagesList = $pagesList[$namespace];
225
        }
226
227
        $ret = [
228
            'project' => $project->getDomain(),
229
            'username' => $user->getUsername(),
230
            'namespace' => $namespace,
231
            'redirects' => $redirects,
232
        ];
233
234
        if ($pages->getNumResults() === $pages->resultsPerPage()) {
235
            $ret['continue'] = $offset + 1;
236
        }
237
238
        $ret['pages'] = $pagesList;
239
240
        $response->setData($ret);
241
242
        return $response;
243
    }
244
}
245