Passed
Push — master ( 9a481f...a0a42c )
by MusikAnimal
05:51
created

PagesController::getSummaryColumns()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 13
nc 8
nop 1
dl 0
loc 24
ccs 0
cts 0
cp 0
crap 30
rs 8.5125
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\Response;
12
use Symfony\Component\HttpFoundation\RedirectResponse;
13
use Symfony\Component\HttpFoundation\JsonResponse;
14
use Xtools\ProjectRepository;
15
use Xtools\UserRepository;
16
use Xtools\Pages;
17
18
/**
19
 * This controller serves the Pages tool.
20
 */
21
class PagesController extends XtoolsController
22
{
23
    const RESULTS_PER_PAGE = 1000;
24
25
    /**
26
     * Get the tool's shortname.
27
     * @return string
28
     * @codeCoverageIgnore
29
     */
30
    public function getToolShortname()
31
    {
32
        return 'pages';
33
    }
34
35
    /**
36
     * Display the form.
37
     * @Route("/pages", name="pages")
38
     * @Route("/pages", name="Pages")
39
     * @Route("/pages/", name="PagesSlash")
40
     * @Route("/pages/index.php", name="PagesIndexPhp")
41
     * @Route("/pages/{project}", name="PagesProject")
42
     * @return Response
43
     */
44 1
    public function indexAction()
45
    {
46
        // Redirect if at minimum project and username are given.
47 1
        if (isset($this->params['project']) && isset($this->params['username'])) {
48
            return $this->redirectToRoute('PagesResult', $this->params);
49
        }
50
51
        // Convert the given project (or default project) into a Project instance.
52 1
        $this->params['project'] = $this->getProjectFromQuery($this->params);
53
54
        // Otherwise fall through.
55 1
        return $this->render('pages/index.html.twig', array_merge([
56 1
            'xtPageTitle' => 'tool-pages',
57
            'xtSubtitle' => 'tool-pages-desc',
58
            'xtPage' => 'pages',
59
60
            // Defaults that will get overriden if in $this->params.
61
            'namespace' => 0,
62
            'redirects' => 'noredirects',
63
            'deleted' => 'all'
64 1
        ], $this->params));
65
    }
66
67
    /**
68
     * Display the results.
69
     * @Route(
70
     *     "/pages/{project}/{username}/{namespace}/{redirects}/{deleted}/{offset}", name="PagesResult",
71
     *     requirements={
72
     *         "namespace" = "|all|\d+",
73
     *         "redirects" = "|[^/]++",
74
     *         "deleted" = "|all|live|deleted",
75
     *         "offset" = "|\d+"
76
     *     }
77
     * )
78
     * @param string|int $namespace The ID of the namespace, or 'all' for all namespaces.
79
     * @param string $redirects One of 'noredirects', 'onlyredirects' or 'all' for both.
80
     * @param string $deleted One of 'live', 'deleted' or 'all' for both.
81
     * @param int $offset Which page of results to show, when the results are so large they are paginated.
82
     * @return RedirectResponse|Response
83
     * @codeCoverageIgnore
84
     */
85
    public function resultAction(
86
        $namespace = '0',
87
        $redirects = 'noredirects',
88
        $deleted = 'all',
89
        $offset = 0
90
    ) {
91
        $ret = $this->validateProjectAndUser('pages');
92
        if ($ret instanceof RedirectResponse) {
0 ignored issues
show
introduced by
The condition $ret instanceof Symfony\...dation\RedirectResponse can never be false since $ret is always a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
93
            return $ret;
94
        } else {
95
            list($project, $user) = $ret;
96
        }
97
98
        // Check for legacy values for 'redirects', and redirect
99
        // back with correct values if need be. This could be refactored
100
        // out to XtoolsController, but this is the only tool in the suite
101
        // that deals with redirects, so we'll keep it confined here.
102
        $validRedirects = ['', 'noredirects', 'onlyredirects', 'all'];
103
        if ($redirects === 'none' || !in_array($redirects, $validRedirects)) {
104
            return $this->redirectToRoute('PagesResult', [
105
                'project' => $project->getDomain(),
106
                'username' => $user->getUsername(),
107
                'namespace' => $namespace,
108
                'redirects' => 'noredirects',
109
                'deleted' => $deleted,
110
                'offset' => $offset,
111
            ]);
112
        }
113
114
        $pages = new Pages(
115
            $project,
116
            $user,
117
            $namespace,
118
            $redirects,
119
            $deleted,
120
            $offset
121
        );
122
        $pages->prepareData();
123
124
        // Assign the values and display the template
125
        return $this->render('pages/result.html.twig', [
126
            'xtPage' => 'pages',
127
            'xtTitle' => $user->getUsername(),
128
            'project' => $project,
129
            'user' => $user,
130
            'summaryColumns' => $this->getSummaryColumns($pages),
131
            'pages' => $pages,
132
            'namespace' => $namespace,
133
        ]);
134
    }
135
136
    /**
137
     * What columns to show in namespace totals table.
138
     * @param  Pages $pages The Pages instance.
139
     * @return string[]
140
     * @codeCoverageIgnore
141
     */
142
    protected function getSummaryColumns(Pages $pages)
143
    {
144
        $summaryColumns = ['namespace'];
145
        if ($pages->getDeleted() === 'deleted') {
146
            // Showing only deleted pages shows only the deleted column, as redirects are non-applicable.
147
            $summaryColumns[] = 'deleted';
148
        } elseif ($pages->getRedirects() == 'onlyredirects') {
149
            // Don't show redundant pages column if only getting data on redirects or deleted pages.
150
            $summaryColumns[] = 'redirects';
151
        } elseif ($pages->getRedirects() == 'noredirects') {
152
            // Don't show redundant redirects column if only getting data on non-redirects.
153
            $summaryColumns[] = 'pages';
154
        } else {
155
            // Order is important here.
156
            $summaryColumns[] = 'pages';
157
            $summaryColumns[] = 'redirects';
158
        }
159
160
        // Show deleted column only when both deleted and live pages are visible.
161
        if ($pages->getDeleted() === 'all') {
162
            $summaryColumns[] = 'deleted';
163
        }
164
165
        return $summaryColumns;
166
    }
167
168
    /************************ API endpoints ************************/
169
170
    /**
171
     * Get a count of the number of pages created by a user,
172
     * including the number that have been deleted and are redirects.
173
     * @Route("/api/user/pages_count/{project}/{username}/{namespace}/{redirects}/{deleted}", name="PagesApiCount",
174
     *     requirements={"namespace"="|\d+|all"})
175
     * @param int|string $namespace The ID of the namespace of the page, or 'all' for all namespaces.
176
     * @param string $redirects One of 'noredirects', 'onlyredirects' or 'all' for both.
177
     * @param string $deleted One of 'live', 'deleted' or 'all' for both.
178
     * @return Response
179
     * @codeCoverageIgnore
180
     */
181
    public function countPagesApiAction($namespace = 0, $redirects = 'noredirects', $deleted = 'all')
182
    {
183
        $this->recordApiUsage('user/pages_count');
184
185
        $ret = $this->validateProjectAndUser();
186
        if ($ret instanceof RedirectResponse) {
0 ignored issues
show
introduced by
The condition $ret instanceof Symfony\...dation\RedirectResponse can never be false since $ret is always a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
187
            return $ret;
188
        } else {
189
            list($project, $user) = $ret;
190
        }
191
192
        $pages = new Pages(
193
            $project,
194
            $user,
195
            $namespace,
196
            $redirects,
197
            $deleted
198
        );
199
200
        $response = new JsonResponse();
201
        $response->setEncodingOptions(JSON_NUMERIC_CHECK);
202
        $response->setStatusCode(Response::HTTP_OK);
203
204
        $counts = $pages->getCounts();
205
206
        if ($namespace !== 'all' && isset($counts[$namespace])) {
207
            $counts = $counts[$namespace];
208
        }
209
210
        $ret = [
211
            'project' => $project->getDomain(),
212
            'username' => $user->getUsername(),
213
            'namespace' => $namespace,
214
            'redirects' => $redirects,
215
            'deleted' => $deleted,
216
            'counts' => $counts,
217
        ];
218
219
        $response->setData($ret);
220
221
        return $response;
222
    }
223
224
    /**
225
     * Get the pages created by by a user.
226
     * @Route("/api/user/pages/{project}/{username}/{namespace}/{redirects}/{deleted}/{offset}", name="PagesApi",
227
     *     requirements={"namespace"="|\d+|all"})
228
     * @param int|string $namespace The ID of the namespace of the page, or 'all' for all namespaces.
229
     * @param string $redirects One of 'noredirects', 'onlyredirects' or 'all' for both.
230
     * @param string $deleted One of 'live', 'deleted' or blank for both.
231
     * @param int $offset Which page of results to show.
232
     * @return Response
233
     * @codeCoverageIgnore
234
     */
235
    public function getPagesApiAction(
236
        $namespace = 0,
237
        $redirects = 'noredirects',
238
        $deleted = 'all',
239
        $offset = 0
240
    ) {
241
        $this->recordApiUsage('user/pages');
242
243
        // Second parameter causes it return a Redirect to the index if the user has too many edits.
244
        $ret = $this->validateProjectAndUser('pages');
245
        if ($ret instanceof RedirectResponse) {
0 ignored issues
show
introduced by
The condition $ret instanceof Symfony\...dation\RedirectResponse can never be false since $ret is always a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
246
            return $ret;
247
        } else {
248
            list($project, $user) = $ret;
249
        }
250
251
        $pages = new Pages(
252
            $project,
253
            $user,
254
            $namespace,
255
            $redirects,
256
            $deleted,
257
            $offset
258
        );
259
260
        $response = new JsonResponse();
261
        $response->setEncodingOptions(JSON_NUMERIC_CHECK);
262
        $response->setStatusCode(Response::HTTP_OK);
263
264
        $pagesList = $pages->getResults();
265
266
        if ($namespace !== 'all' && isset($pagesList[$namespace])) {
267
            $pagesList = $pagesList[$namespace];
268
        }
269
270
        $ret = [
271
            'project' => $project->getDomain(),
272
            'username' => $user->getUsername(),
273
            'namespace' => $namespace,
274
            'redirects' => $redirects,
275
            'deleted' => $deleted
276
        ];
277
278
        if ($pages->getNumResults() === $pages->resultsPerPage()) {
279
            $ret['continue'] = $offset + 1;
280
        }
281
282
        $ret['pages'] = $pagesList;
283
284
        $response->setData($ret);
285
286
        return $response;
287
    }
288
}
289