Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 172 |
|
0.00% |
0 / 13 |
CRAP | |
0.00% |
0 / 1 |
TagsController | |
0.00% |
0 / 172 |
|
0.00% |
0 / 13 |
1482 | |
0.00% |
0 / 1 |
getParam | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
homeAction | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
manageAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
listAction | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
2 | |||
deleteAction | |
0.00% |
0 / 40 |
|
0.00% |
0 / 1 |
156 | |||
getConfirmDeleteMessages | |
0.00% |
0 / 38 |
|
0.00% |
0 / 1 |
110 | |||
confirmTagsDelete | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
2 | |||
confirmTagsDeleteByFilter | |
0.00% |
0 / 22 |
|
0.00% |
0 / 1 |
2 | |||
getUniqueResources | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
getUniqueTags | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
getUniqueUsers | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
convertFilter | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
20 | |||
deleteResourceTagsByFilter | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * Admin Tag Controller |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Villanova University 2010. |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2, |
12 | * as published by the Free Software Foundation. |
13 | * |
14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | * |
23 | * @category VuFind |
24 | * @package Controller |
25 | * @author Demian Katz <demian.katz@villanova.edu> |
26 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
27 | * @link https://vufind.org Main Site |
28 | */ |
29 | |
30 | namespace VuFindAdmin\Controller; |
31 | |
32 | use VuFind\Db\Service\ResourceServiceInterface; |
33 | use VuFind\Db\Service\ResourceTagsServiceInterface; |
34 | use VuFind\Db\Service\TagServiceInterface; |
35 | use VuFind\Db\Service\UserServiceInterface; |
36 | use VuFind\Tags\TagsService; |
37 | |
38 | use function count; |
39 | use function intval; |
40 | use function is_array; |
41 | |
42 | /** |
43 | * Class controls distribution of tags and resource tags. |
44 | * |
45 | * @category VuFind |
46 | * @package Controller |
47 | * @author Demian Katz <demian.katz@villanova.edu> |
48 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
49 | * @link https://vufind.org Main Site |
50 | */ |
51 | class TagsController extends AbstractAdmin |
52 | { |
53 | /** |
54 | * Params |
55 | * |
56 | * @var array |
57 | */ |
58 | protected $params; |
59 | |
60 | /** |
61 | * Get the url parameters |
62 | * |
63 | * @param string $param A key to check the url params for |
64 | * @param bool $prioritizePost If true, check the POST params first |
65 | * @param mixed $default Default value if no value found |
66 | * |
67 | * @return string |
68 | */ |
69 | protected function getParam($param, $prioritizePost = true, $default = null) |
70 | { |
71 | $primary = $prioritizePost ? 'fromPost' : 'fromQuery'; |
72 | $secondary = $prioritizePost ? 'fromQuery' : 'fromPost'; |
73 | return $this->params()->$primary($param) |
74 | ?? $this->params()->$secondary($param, $default); |
75 | } |
76 | |
77 | /** |
78 | * Tag Details |
79 | * |
80 | * @return \Laminas\View\Model\ViewModel |
81 | */ |
82 | public function homeAction() |
83 | { |
84 | $view = $this->createViewModel(); |
85 | $view->setTemplate('admin/tags/home'); |
86 | $view->statistics = $this->serviceLocator->get(TagsService::class)->getStatistics(true); |
87 | return $view; |
88 | } |
89 | |
90 | /** |
91 | * Manage Tags |
92 | * |
93 | * @return \Laminas\View\Model\ViewModel |
94 | */ |
95 | public function manageAction() |
96 | { |
97 | $view = $this->createViewModel(); |
98 | $view->setTemplate('admin/tags/manage'); |
99 | $view->type = $this->params()->fromPost('type', null) |
100 | ?? $this->params()->fromQuery('type', null); |
101 | $view->uniqueTags = $this->getUniqueTags(); |
102 | $view->uniqueUsers = $this->getUniqueUsers(); |
103 | $view->uniqueResources = $this->getUniqueResources(); |
104 | $view->params = $this->params()->fromQuery(); |
105 | return $view; |
106 | } |
107 | |
108 | /** |
109 | * List Tags |
110 | * |
111 | * @return \Laminas\View\Model\ViewModel |
112 | */ |
113 | public function listAction() |
114 | { |
115 | $view = $this->createViewModel(); |
116 | $view->setTemplate('admin/tags/list'); |
117 | $view->uniqueTags = $this->getUniqueTags(); |
118 | $view->uniqueUsers = $this->getUniqueUsers(); |
119 | $view->uniqueResources = $this->getUniqueResources(); |
120 | $page = intval($this->getParam('page', false, '1')); |
121 | $view->results = $this->serviceLocator->get(TagsService::class)->getResourceTagsPaginator( |
122 | $this->convertFilter($this->getParam('user_id', false)), |
123 | $this->convertFilter($this->getParam('resource_id', false)), |
124 | $this->convertFilter($this->getParam('tag_id', false)), |
125 | $this->getParam('order', false), |
126 | $page |
127 | ); |
128 | $view->params = $this->params()->fromQuery(); |
129 | return $view; |
130 | } |
131 | |
132 | /** |
133 | * Delete Tags |
134 | * |
135 | * @return \Laminas\View\Model\ViewModel |
136 | */ |
137 | public function deleteAction() |
138 | { |
139 | $origin = $this->getParam('origin'); |
140 | |
141 | $action = ('list' == $origin) ? 'List' : 'Manage'; |
142 | |
143 | $originUrl = $this->url()->fromRoute('admin/tags', ['action' => $action]); |
144 | if ($action == 'List') { |
145 | $originUrl .= '?' . http_build_query( |
146 | [ |
147 | 'user_id' => $this->getParam('user_id'), |
148 | 'resource_id' => $this->getParam('resource_id'), |
149 | 'tag_id' => $this->getParam('tag_id'), |
150 | ] |
151 | ); |
152 | } |
153 | $newUrl = $this->url()->fromRoute('admin/tags', ['action' => 'Delete']); |
154 | |
155 | $confirm = $this->params()->fromPost('confirm', false); |
156 | |
157 | // Delete All |
158 | if ( |
159 | 'manage' == $origin |
160 | || null !== $this->getRequest()->getPost('deleteFilter') |
161 | || null !== $this->getRequest()->getQuery('deleteFilter') |
162 | ) { |
163 | if (false === $confirm) { |
164 | return $this->confirmTagsDeleteByFilter($originUrl, $newUrl); |
165 | } |
166 | $delete = $this->deleteResourceTagsByFilter(); |
167 | } else { |
168 | // Delete by ID |
169 | // Fail if we have nothing to delete: |
170 | $ids = null === $this->getRequest()->getPost('deletePage') |
171 | ? $this->params()->fromPost('ids') |
172 | : $this->params()->fromPost('idsAll'); |
173 | |
174 | if (!is_array($ids) || empty($ids)) { |
175 | $this->flashMessenger()->addMessage('bulk_noitems_advice', 'error'); |
176 | return $this->redirect()->toUrl($originUrl); |
177 | } |
178 | |
179 | if (false === $confirm) { |
180 | return $this->confirmTagsDelete($ids, $originUrl, $newUrl); |
181 | } |
182 | $delete = $this->getDbService(ResourceTagsServiceInterface::class)->deleteLinksByResourceTagsIdArray($ids); |
183 | } |
184 | |
185 | if (0 == $delete) { |
186 | $this->flashMessenger()->addMessage('tags_delete_fail', 'error'); |
187 | return $this->redirect()->toUrl($originUrl); |
188 | } |
189 | |
190 | // If we got this far, we should clean up orphans: |
191 | $this->getDbService(TagServiceInterface::class)->deleteOrphanedTags(); |
192 | |
193 | $this->flashMessenger()->addMessage( |
194 | [ |
195 | 'msg' => 'tags_deleted', |
196 | 'tokens' => ['%count%' => $delete], |
197 | ], |
198 | 'success' |
199 | ); |
200 | return $this->redirect()->toUrl($originUrl); |
201 | } |
202 | |
203 | /** |
204 | * Get confirmation messages. |
205 | * |
206 | * @param int $count Count of tags that are about to be deleted |
207 | * |
208 | * @return array |
209 | */ |
210 | protected function getConfirmDeleteMessages($count) |
211 | { |
212 | // Default all messages to "All"; we'll make them more specific as needed: |
213 | $userMsg = $tagMsg = $resourceMsg = $this->translate('All'); |
214 | |
215 | $userId = intval($this->getParam('user_id')); |
216 | if ($userId) { |
217 | $user = $this->getDbService(UserServiceInterface::class)->getUserById($userId); |
218 | if (!$user) { |
219 | throw new \Exception("Unexpected error retrieving user $userId"); |
220 | } |
221 | $userMsg = "{$user->getUsername()} ({$user->getId()})"; |
222 | } |
223 | |
224 | $tagId = intval($this->getParam('tag_id')); |
225 | if ($tagId) { |
226 | $tag = $this->getDbService(TagServiceInterface::class)->getTagById($tagId); |
227 | if (!$tag) { |
228 | throw new \Exception("Unexpected error retrieving tag $tagId"); |
229 | } |
230 | $tagMsg = "{$tag->getTag()} ({$tag->getId()})"; |
231 | } |
232 | |
233 | $resourceId = intval($this->getParam('resource_id')); |
234 | if ($resourceId) { |
235 | $resource = $this->getDbService(ResourceServiceInterface::class)->getResourceById($resourceId); |
236 | if (!$resource) { |
237 | throw new \Exception( |
238 | "Unexpected error retrieving resource $resourceId" |
239 | ); |
240 | } |
241 | $resourceMsg = "{$resource->getTitle()} ({$resource->getId()})"; |
242 | } |
243 | |
244 | $messages = [ |
245 | [ |
246 | 'msg' => 'tag_delete_warning', |
247 | 'tokens' => ['%count%' => $count], |
248 | ], |
249 | ]; |
250 | if ($userId || $tagId || $resourceId) { |
251 | $messages[] = [ |
252 | 'msg' => 'tag_delete_filter', |
253 | 'tokens' => [ |
254 | '%username%' => $userMsg, |
255 | '%tag%' => $tagMsg, |
256 | '%resource%' => $resourceMsg, |
257 | ], |
258 | ]; |
259 | } |
260 | $messages[] = ['msg' => 'confirm_delete']; |
261 | return $messages; |
262 | } |
263 | |
264 | /** |
265 | * Confirm Delete by Id |
266 | * |
267 | * @param array $ids A list of resource tag Ids |
268 | * @param string $originUrl An origin url |
269 | * @param string $newUrl The url of the desired action |
270 | * |
271 | * @return mixed |
272 | */ |
273 | protected function confirmTagsDelete($ids, $originUrl, $newUrl) |
274 | { |
275 | $count = count($ids); |
276 | |
277 | $data = [ |
278 | 'data' => [ |
279 | 'confirm' => $newUrl, |
280 | 'cancel' => $originUrl, |
281 | 'title' => 'confirm_delete_tags_brief', |
282 | 'messages' => $this->getConfirmDeleteMessages($count), |
283 | 'ids' => $ids, |
284 | 'extras' => [ |
285 | 'origin' => 'list', |
286 | 'user_id' => $this->getParam('user_id'), |
287 | 'tag_id' => $this->getParam('tag_id'), |
288 | 'resource_id' => $this->getParam('resource_id'), |
289 | 'ids' => $ids, |
290 | ], |
291 | ], |
292 | ]; |
293 | |
294 | return $this->forwardTo('Confirm', 'Confirm', $data); |
295 | } |
296 | |
297 | /** |
298 | * Confirm Tag Delete by Filter |
299 | * |
300 | * @param string $originUrl An origin url |
301 | * @param string $newUrl The url of the desired action |
302 | * |
303 | * @return mixed |
304 | */ |
305 | protected function confirmTagsDeleteByFilter($originUrl, $newUrl) |
306 | { |
307 | $count = $this->serviceLocator->get(TagsService::class)->getResourceTagsPaginator( |
308 | $this->convertFilter($this->getParam('user_id')), |
309 | $this->convertFilter($this->getParam('resource_id')), |
310 | $this->convertFilter($this->getParam('tag_id')) |
311 | )->getTotalItemCount(); |
312 | |
313 | $data = [ |
314 | 'data' => [ |
315 | 'confirm' => $newUrl, |
316 | 'cancel' => $originUrl, |
317 | 'title' => 'confirm_delete_tags_brief', |
318 | 'messages' => $this->getConfirmDeleteMessages($count), |
319 | 'extras' => [ |
320 | 'origin' => 'manage', |
321 | 'type' => $this->getParam('type'), |
322 | 'user_id' => $this->getParam('user_id'), |
323 | 'tag_id' => $this->getParam('tag_id'), |
324 | 'resource_id' => $this->getParam('resource_id'), |
325 | 'deleteFilter' => $this->getParam('deleteFilter'), |
326 | ], |
327 | ], |
328 | ]; |
329 | |
330 | return $this->forwardTo('Confirm', 'Confirm', $data); |
331 | } |
332 | |
333 | /** |
334 | * Gets a list of unique resources based on the url params |
335 | * |
336 | * @return array[] |
337 | */ |
338 | protected function getUniqueResources(): array |
339 | { |
340 | return $this->getDbService(ResourceTagsServiceInterface::class)->getUniqueResources( |
341 | $this->convertFilter($this->getParam('user_id', false)), |
342 | $this->convertFilter($this->getParam('resource_id', false)), |
343 | $this->convertFilter($this->getParam('tag_id', false)) |
344 | ); |
345 | } |
346 | |
347 | /** |
348 | * Gets a list of unique tags based on the url params |
349 | * |
350 | * @return array[] |
351 | */ |
352 | protected function getUniqueTags(): array |
353 | { |
354 | return $this->serviceLocator->get(TagsService::class)->getUniqueTags( |
355 | $this->convertFilter($this->getParam('user_id', false)), |
356 | $this->convertFilter($this->getParam('resource_id', false)), |
357 | $this->convertFilter($this->getParam('tag_id', false)) |
358 | ); |
359 | } |
360 | |
361 | /** |
362 | * Gets a list of unique users based on the url params |
363 | * |
364 | * @return array[] |
365 | */ |
366 | protected function getUniqueUsers(): array |
367 | { |
368 | return $this->getDbService(ResourceTagsServiceInterface::class)->getUniqueUsers( |
369 | $this->convertFilter($this->getParam('user_id', false)), |
370 | $this->convertFilter($this->getParam('resource_id', false)), |
371 | $this->convertFilter($this->getParam('tag_id', false)) |
372 | ); |
373 | } |
374 | |
375 | /** |
376 | * Converts empty params and "ALL" to null |
377 | * |
378 | * @param string $value A parameter to check |
379 | * |
380 | * @return string|null A modified parameter |
381 | */ |
382 | protected function convertFilter($value) |
383 | { |
384 | return ('ALL' !== $value && '' !== $value && null !== $value) |
385 | ? $value : null; |
386 | } |
387 | |
388 | /** |
389 | * Delete tags based on filter settings. |
390 | * |
391 | * @return int Number of IDs deleted |
392 | */ |
393 | protected function deleteResourceTagsByFilter(): int |
394 | { |
395 | return $this->getDbService(ResourceTagsServiceInterface::class)->deleteResourceTags( |
396 | $this->convertFilter($this->getParam('user_id')), |
397 | $this->convertFilter($this->getParam('resource_id')), |
398 | $this->convertFilter($this->getParam('tag_id')) |
399 | ); |
400 | } |
401 | } |