|
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) |
|
|
|
|
|
|
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
|
|
|
|
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.