Passed
Pull Request — master (#166)
by
unknown
14:46 queued 04:32
created

WorkspaceController   F

Complexity

Total Complexity 120

Size/Duplication

Total Lines 1109
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 534
c 3
b 0
f 0
dl 0
loc 1109
rs 2
wmc 120

21 Methods

Rating   Name   Duplication   Size   Complexity  
A batchAction() 0 4 2
B buildSortQueryPart() 0 40 9
A getMyPublicationsQuery() 0 19 1
B uploadFilesAction() 0 50 6
A batchReleaseUnvalidatedAction() 0 3 1
A getSortScriptDoctype() 0 13 4
A getSortScriptCreatorRole() 0 14 1
A getWorkspaceQuery() 0 36 1
D batchRelease() 0 103 18
B buildQuery() 0 129 5
A getSortScriptUniversityCollection() 0 10 1
D buildFilterQueryPart() 0 166 23
A listWorkspaceAction() 0 31 5
A getSortScriptHasFiles() 0 8 1
B batchRemoveAction() 0 43 7
D list() 0 64 11
B batchRegisterAction() 0 76 10
A getSortScriptState() 0 15 3
A batchReleaseValidatedAction() 0 3 1
A itemsPerPage() 0 5 3
B initIndexAction() 0 44 7

How to fix   Complexity   

Complex Class

Complex classes like WorkspaceController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WorkspaceController, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace EWW\Dpf\Controller;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use EWW\Dpf\Domain\Model\Bookmark;
18
use EWW\Dpf\Domain\Model\Document;
19
use EWW\Dpf\Security\DocumentVoter;
20
use EWW\Dpf\Security\Security;
21
use EWW\Dpf\Services\Email\Notifier;
22
use EWW\Dpf\Domain\Workflow\DocumentWorkflow;
23
use TYPO3\CMS\Core\Messaging\AbstractMessage;
24
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
25
26
/**
27
 * Controller for the "workspace"/"my publications" area.
28
 */
29
class WorkspaceController  extends AbstractController
30
{
31
    const MAXIMUM_NUMBER_OF_LINKS = 5;
32
    const DEFAULT_SORT_FIELD = 'title';
33
    const DEFAULT_SORT_ORDER = 'asc';
34
35
    /**
36
     * documentRepository
37
     *
38
     * @var \EWW\Dpf\Domain\Repository\DocumentRepository
39
     * @inject
40
     */
41
    protected $documentRepository = null;
42
43
    /**
44
     * documentTypeRepository
45
     *
46
     * @var \EWW\Dpf\Domain\Repository\DocumentTypeRepository
47
     * @inject
48
     */
49
    protected $documentTypeRepository = null;
50
51
    /**
52
     * bookmarkRepository
53
     *
54
     * @var \EWW\Dpf\Domain\Repository\BookmarkRepository
55
     * @inject
56
     */
57
    protected $bookmarkRepository = null;
58
59
    /**
60
     * elasticSearch
61
     *
62
     * @var \EWW\Dpf\Services\ElasticSearch\ElasticSearch
63
     * @inject
64
     */
65
    protected $elasticSearch = null;
66
67
    /**
68
     * documentManager
69
     *
70
     * @var \EWW\Dpf\Services\Document\DocumentManager
71
     * @inject
72
     */
73
    protected $documentManager = null;
74
75
    /**
76
     * documentValidator
77
     *
78
     * @var \EWW\Dpf\Helper\DocumentValidator
79
     * @inject
80
     */
81
    protected $documentValidator;
82
83
    /**
84
     * editingLockService
85
     *
86
     * @var \EWW\Dpf\Services\Document\EditingLockService
87
     * @inject
88
     */
89
    protected $editingLockService = null;
90
91
92
    /**
93
     * list
94
     *
95
     * @param int $from
96
     * @return void
97
     */
98
    protected function list($from = 0)
99
    {
100
        $bookmarkIdentifiers = array();
101
        $bookmarks = $this->bookmarkRepository->findByFeUserUid($this->security->getUser()->getUid());
0 ignored issues
show
Bug introduced by
The method findByFeUserUid() does not exist on EWW\Dpf\Domain\Repository\BookmarkRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
        /** @scrutinizer ignore-call */ 
102
        $bookmarks = $this->bookmarkRepository->findByFeUserUid($this->security->getUser()->getUid());
Loading history...
102
        foreach ($bookmarks as $bookmark) {
103
            $bookmarkIdentifiers[] = $bookmark->getDocumentIdentifier();
104
        }
105
106
        $filters = $this->getSessionData('workspaceFilters');
107
        if (!$filters) {
108
            $filters = [];
109
        }
110
        $excludeFilters = $this->session->getWorkspaceExcludeFilters();
111
        if (!$excludeFilters) {
112
            $excludeFilters = [];
113
        }
114
115
        list($sortField, $sortOrder) = $this->session->getWorkspaceSort();
116
117
        if ($this->security->getUserRole() == Security::ROLE_LIBRARIAN) {
118
            $query = $this->getWorkspaceQuery($from, $bookmarkIdentifiers,
119
                $filters, $excludeFilters, $sortField, $sortOrder);
120
        } elseif ($this->security->getUserRole() == Security::ROLE_RESEARCHER) {
121
            $query = $this->getMyPublicationsQuery($from, $bookmarkIdentifiers,
122
                $filters, $excludeFilters, $sortField, $sortOrder);
123
        }
124
125
        try {
126
            $results = $this->elasticSearch->search($query, 'object');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $query does not seem to be defined for all execution paths leading up to this point.
Loading history...
127
        } catch (\Exception $e) {
128
            $this->session->clearWorkspaceSort();
129
            $this->addFlashMessage(
130
                "Error while buildig the list!", '', AbstractMessage::ERROR
131
            );
132
        }
133
134
        if ($this->request->hasArgument('message')) {
135
            $this->view->assign('message', $this->request->getArgument('message'));
136
        }
137
138
        if ($this->request->hasArgument('errorFiles')) {
139
            $this->view->assign('errorFiles', $this->request->getArgument('errorFiles'));
140
        }
141
142
143
        if ($filters && $results['hits']['total']['value'] < 1) {
144
            $this->session->clearFilter();
145
            list($redirectAction, $redirectController) = $this->session->getListAction();
146
            $this->redirect(
147
                $redirectAction, $redirectController, null,
148
                array('message' => [], 'checkedDocumentIdentifiers' => [])
149
            );
150
        }
151
152
        $this->view->assign('documentCount', $results['hits']['total']['value']);
153
        $this->view->assign('documents', $results['hits']['hits']);
154
        $this->view->assign('pages', range(1, $results['hits']['total']['value']));
155
        $this->view->assign('itemsPerPage', $this->itemsPerPage());
156
        $this->view->assign('maximumNumberOfLinks', self::MAXIMUM_NUMBER_OF_LINKS);
157
        $this->view->assign('aggregations', $results['aggregations']);
158
        $this->view->assign('filters', $filters);
159
        $this->view->assign('isHideDiscarded', array_key_exists('simpleState', $excludeFilters));
160
        $this->view->assign('isBookmarksOnly', array_key_exists('bookmarks', $excludeFilters));
161
        $this->view->assign('bookmarkIdentifiers', $bookmarkIdentifiers);
162
    }
163
164
    /**
165
     * Lists documents of the workspace
166
     *
167
     * @param array $checkedDocumentIdentifiers
168
     *
169
     * @return void
170
     */
171
    protected function listWorkspaceAction($checkedDocumentIdentifiers = [])
172
    {
173
        if ($this->security->getUserRole() === Security::ROLE_LIBRARIAN) {
174
            $this->view->assign('isWorkspace', true);
175
        } elseif ($this->security->getUserRole() === Security::ROLE_RESEARCHER){
176
            $this->view->assign('isWorkspace', false);
177
        } else {
178
            $message = LocalizationUtility::translate(
179
                'manager.workspace.accessDenied', 'dpf'
180
            );
181
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
182
        }
183
184
        $this->session->setListAction($this->getCurrentAction(), $this->getCurrentController(),
185
            $this->uriBuilder->getRequest()->getRequestUri()
0 ignored issues
show
introduced by
The method getRequestUri() does not exist on TYPO3\CMS\Extbase\Mvc\Request. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

185
            $this->uriBuilder->getRequest()->/** @scrutinizer ignore-call */ getRequestUri()
Loading history...
186
        );
187
188
        $currentPage = null;
189
        $pagination = $this->getParametersSafely('@widget_0');
190
        if ($pagination) {
191
            $checkedDocumentIdentifiers = [];
192
            $currentPage = $pagination['currentPage'];
193
        } else {
194
            $currentPage = 1;
195
        }
196
197
        $this->list((empty($currentPage)? 0 : ($currentPage-1) * $this->itemsPerPage()));
198
199
        $this->view->assign('currentPage', $currentPage);
200
        $this->view->assign('workspaceListAction', $this->getCurrentAction());
201
        $this->view->assign('checkedDocumentIdentifiers', $checkedDocumentIdentifiers);
202
    }
203
204
205
    /**
206
     * Batch operations action.
207
     * @param array $listData
208
     */
209
    public function batchAction($listData)
210
    {
211
        if (array_key_exists('action', $listData)) {
212
            $this->forward($listData['action'], null, null, ['listData' => $listData]);
213
        }
214
    }
215
216
    /**
217
     * Batch operation, register documents.
218
     * @param array $listData
219
     * @throws \EWW\Dpf\Exceptions\DocumentMaxSizeErrorException
220
     */
221
    public function batchRegisterAction($listData)
222
    {
223
        $successful = [];
224
        $checkedDocumentIdentifiers = [];
225
226
        if (array_key_exists('documentIdentifiers', $listData) && is_array($listData['documentIdentifiers']) ) {
227
            $checkedDocumentIdentifiers = $listData['documentIdentifiers'];
228
            foreach ($listData['documentIdentifiers'] as $documentIdentifier) {
229
230
                $this->editingLockService->lock(
231
                    $documentIdentifier, $this->security->getUser()->getUid()
232
                );
233
234
                if (is_numeric($documentIdentifier)) {
235
                    $document = $this->documentManager->read($documentIdentifier);
236
237
                    if ($this->authorizationChecker->isGranted(DocumentVoter::REGISTER, $document)) {
238
239
                        if ($this->documentValidator->validate($document, false)) {
0 ignored issues
show
Bug introduced by
It seems like $document can also be of type null; however, parameter $document of EWW\Dpf\Helper\DocumentValidator::validate() does only seem to accept EWW\Dpf\Domain\Model\Document, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

239
                        if ($this->documentValidator->validate(/** @scrutinizer ignore-type */ $document, false)) {
Loading history...
240
241
                            if (
242
                                $this->documentManager->update(
243
                                    $document,
0 ignored issues
show
Bug introduced by
It seems like $document can also be of type null; however, parameter $document of EWW\Dpf\Services\Documen...cumentManager::update() does only seem to accept EWW\Dpf\Domain\Model\Document, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

243
                                    /** @scrutinizer ignore-type */ $document,
Loading history...
244
                                    DocumentWorkflow::TRANSITION_REGISTER
245
                                )
246
                            ) {
247
                                $this->bookmarkRepository->addBookmark(
248
                                    $this->security->getUser()->getUid(), $document
249
                                );
250
251
                                $successful[] = $documentIdentifier;
252
253
                                $notifier = $this->objectManager->get(Notifier::class);
254
                                $notifier->sendRegisterNotification($document);
255
256
                                // index the document
257
                                $this->signalSlotDispatcher->dispatch(
258
                                    \EWW\Dpf\Controller\AbstractController::class,
259
                                    'indexDocument', [$document]
260
                                );
261
                            }
262
                        }
263
                    }
264
                }
265
            }
266
267
268
            if (sizeof($successful) == 1) {
269
                $locallangKey = 'manager.workspace.batchAction.register.success.singular';
270
            } else {
271
                $locallangKey = 'manager.workspace.batchAction.register.success.plural';
272
            }
273
274
            $message = LocalizationUtility::translate(
275
                $locallangKey,
276
                'dpf',
277
                [sizeof($successful), sizeof($listData['documentIdentifiers'])]
278
            );
279
280
281
            $this->addFlashMessage(
282
                $message, '',
283
                (sizeof($successful) > 0 ? AbstractMessage::OK : AbstractMessage::WARNING)
284
            );
285
286
        } else {
287
            $message = LocalizationUtility::translate(
288
                'manager.workspace.batchAction.failure',
289
                'dpf');
290
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
291
        }
292
293
        list($redirectAction, $redirectController) = $this->session->getListAction();
294
        $this->redirect(
295
            $redirectAction, $redirectController, null,
296
            array('message' => $message, 'checkedDocumentIdentifiers' =>  $checkedDocumentIdentifiers));
297
    }
298
299
    /**
300
     * Batch operation, remove documents.
301
     * @param array $listData
302
     */
303
    public function batchRemoveAction($listData)
304
    {
305
        $successful = [];
306
        $checkedDocumentIdentifiers = [];
307
308
        if (array_key_exists('documentIdentifiers', $listData) && is_array($listData['documentIdentifiers']) ) {
309
            $checkedDocumentIdentifiers = $listData['documentIdentifiers'];
310
            foreach ($listData['documentIdentifiers'] as $documentIdentifier) {
311
                $feUserUid = $this->security->getUser()->getUid();
312
                $bookmark = $this->bookmarkRepository->findBookmark($feUserUid, $documentIdentifier);
313
                if ($bookmark instanceof Bookmark) {
314
                    $this->bookmarkRepository->remove($bookmark);
315
                    $successful[] = $documentIdentifier;
316
                }
317
            }
318
319
320
            if (sizeof($successful) == 1) {
321
                $locallangKey = 'manager.workspace.batchAction.remove.success.singular';
322
            } else {
323
                $locallangKey = 'manager.workspace.batchAction.remove.success.plural';
324
            }
325
326
            $message = LocalizationUtility::translate(
327
                $locallangKey,
328
                'dpf',
329
                [sizeof($successful), sizeof($listData['documentIdentifiers'])]
330
            );
331
            $this->addFlashMessage(
332
                $message, '',
333
                (sizeof($successful) > 0 ? AbstractMessage::OK : AbstractMessage::WARNING)
334
            );
335
        } else {
336
            $message = LocalizationUtility::translate(
337
                'manager.workspace.batchAction.failure',
338
                'dpf');
339
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
340
        }
341
342
        list($redirectAction, $redirectController) = $this->session->getListAction();
343
        $this->redirect(
344
            $redirectAction, $redirectController, null,
345
            array('message' => $message, 'checkedDocumentIdentifiers' =>  $checkedDocumentIdentifiers));
346
    }
347
348
349
    /**
350
     * Batch operation, release documents.
351
     * @param array $listData
352
     */
353
    public function batchReleaseValidatedAction($listData)
354
    {
355
        $this->batchRelease($listData, true);
356
    }
357
358
    /**
359
     * Batch operation, release as unvalidated documents.
360
     * @param array $listData
361
     */
362
    public function batchReleaseUnvalidatedAction($listData)
363
    {
364
        $this->batchRelease($listData, false);
365
    }
366
367
368
369
370
    /**
371
     * Batch operation, release documents.
372
     * @param array $listData
373
     * @param bool $validated
374
     */
375
    protected function batchRelease($listData, $validated)
376
    {
377
        $successful = [];
378
        $checkedDocumentIdentifiers = [];
379
380
        if (array_key_exists('documentIdentifiers', $listData) && is_array($listData['documentIdentifiers']) ) {
381
            $checkedDocumentIdentifiers = $listData['documentIdentifiers'];
382
            foreach ($listData['documentIdentifiers'] as $documentIdentifier) {
383
384
                $this->editingLockService->lock(
385
                    $documentIdentifier, $this->security->getUser()->getUid()
386
                );
387
388
                $document = $this->documentManager->read($documentIdentifier);
389
390
                switch ($document->getState()) {
391
                    case DocumentWorkflow::STATE_REGISTERED_NONE:
392
                    case DocumentWorkflow::STATE_DISCARDED_NONE:
393
                    case DocumentWorkflow::STATE_POSTPONED_NONE:
394
                        $documentVoterAttribute = DocumentVoter::RELEASE_PUBLISH;
395
                        $documentWorkflowTransition = DocumentWorkflow::TRANSITION_RELEASE_PUBLISH;
396
                        break;
397
398
                    case DocumentWorkflow::STATE_NONE_DELETED:
399
                    case DocumentWorkflow::STATE_NONE_INACTIVE:
400
                    case DocumentWorkflow::STATE_IN_PROGRESS_DELETED:
401
                    case DocumentWorkflow::STATE_IN_PROGRESS_INACTIVE:
402
                    case DocumentWorkflow::STATE_IN_PROGRESS_ACTIVE:
403
                        $documentVoterAttribute = DocumentVoter::RELEASE_ACTIVATE;
404
                        $documentWorkflowTransition = DocumentWorkflow::TRANSITION_RELEASE_ACTIVATE;
405
                        break;
406
                    default:
407
                        $documentVoterAttribute = null;
408
                        $documentWorkflowTransition = null;
409
                        break;
410
                }
411
412
                if ($this->authorizationChecker->isGranted($documentVoterAttribute, $document)) {
413
414
                    $slub = new \EWW\Dpf\Helper\Slub($document->getSlubInfoData());
415
416
                    $slub->setValidation($validated);
417
                    $document->setSlubInfoData($slub->getSlubXml());
418
419
                    if ($this->documentManager->update($document, $documentWorkflowTransition)) {
0 ignored issues
show
Bug introduced by
It seems like $document can also be of type null; however, parameter $document of EWW\Dpf\Services\Documen...cumentManager::update() does only seem to accept EWW\Dpf\Domain\Model\Document, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

419
                    if ($this->documentManager->update(/** @scrutinizer ignore-type */ $document, $documentWorkflowTransition)) {
Loading history...
420
                        $successful[] = $documentIdentifier;
421
422
                        $this->bookmarkRepository->removeBookmark(
423
                            $document, $this->security->getUser()->getUid()
424
                        );
425
426
                        //$notifier = $this->objectManager->get(Notifier::class);
427
                        //$notifier->sendRegisterNotification($document);
428
                    }
429
                }
430
            }
431
432
433
            if (sizeof($successful) == 1) {
434
                $locallangKey = 'manager.workspace.batchAction.release.success.singular';
435
            } else {
436
                $locallangKey = 'manager.workspace.batchAction.release.success.plural';
437
            }
438
439
            $message = LocalizationUtility::translate(
440
                $locallangKey,
441
                'dpf',
442
                [sizeof($successful), sizeof($listData['documentIdentifiers'])]
443
            );
444
            $this->addFlashMessage(
445
                $message, '',
446
                (sizeof($successful) > 0 ? AbstractMessage::OK : AbstractMessage::WARNING)
447
            );
448
449
            if (sizeof($successful) === 1 ) {
450
                $this->addFlashMessage(
451
                    "1 ".LocalizationUtility::translate("manager.workspace.bookmarkRemoved.singular", "dpf"),
452
                    '',
453
                    AbstractMessage::INFO
454
                );
455
            }
456
457
            if (sizeof($successful) > 1 ) {
458
                $this->addFlashMessage(
459
                    LocalizationUtility::translate(
460
                        "manager.workspace.bookmarkRemoved.plural", "dpf", [sizeof($successful)]
461
                    ),
462
                    '',
463
                    AbstractMessage::INFO
464
                );
465
            }
466
467
        } else {
468
            $message = LocalizationUtility::translate(
469
                'manager.workspace.batchAction.failure',
470
                'dpf');
471
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
472
        }
473
474
        list($redirectAction, $redirectController) = $this->session->getListAction();
475
        $this->redirect(
476
            $redirectAction, $redirectController, null,
477
            array('message' => $message, 'checkedDocumentIdentifiers' =>  $checkedDocumentIdentifiers));
478
479
    }
480
481
    /**
482
     * get list view data for the workspace
483
     *
484
     * @param int $from
485
     * @param array $bookmarkIdentifiers
486
     * @param array $filters
487
     * @param array $excludeFilters
488
     * @param string $sortField
489
     * @param string $sortOrder
490
     *
491
     * @return array
492
     */
493
    protected function getWorkspaceQuery(
494
        $from = 0, $bookmarkIdentifiers = [], $filters= [], $excludeFilters = [], $sortField = null, $sortOrder = null
495
    )
496
    {
497
        $workspaceFilter = [
498
            'bool' => [
499
                'must' => [
500
                    [
501
                        'bool' => [
502
                            'must' => [
503
                                [
504
                                    'term' => [
505
                                        'creator' => $this->security->getUser()->getUid()
506
                                    ]
507
                                ],
508
                                [
509
                                    'bool' => [
510
                                        'should' => [
511
                                            [
512
                                                'term' => [
513
                                                    'state' => DocumentWorkflow::STATE_NEW_NONE
514
                                                ]
515
                                            ]
516
                                        ]
517
                                    ]
518
                                ]
519
                            ]
520
                        ]
521
                    ]
522
                ]
523
            ]
524
        ];
525
526
        return $this->buildQuery(
527
            $workspaceFilter, $from, $bookmarkIdentifiers, $filters,
528
            $excludeFilters, $sortField, $sortOrder
529
        );
530
    }
531
532
533
    /**
534
     * get list view data for the my publications list.
535
     *
536
     * @param int $from
537
     * @param array $bookmarkIdentifiers
538
     * @param array $filters
539
     * @param array $excludeFilters
540
     * @param string $sortField
541
     * @param string $sortOrder
542
     *
543
     * @return array
544
     */
545
    protected function getMyPublicationsQuery(
546
        $from = 0, $bookmarkIdentifiers = [], $filters= [], $excludeFilters = [], $sortField = null, $sortOrder = null
547
    )
548
    {
549
        $workspaceFilter = [
550
            'bool' => [
551
                'must' => [
552
                    [
553
                        'term' => [
554
                            'creator' => $this->security->getUser()->getUid()
555
                        ]
556
                    ]
557
                ]
558
            ]
559
        ];
560
561
        return $this->buildQuery(
562
            $workspaceFilter, $from, $bookmarkIdentifiers, $filters,
563
            $excludeFilters, $sortField, $sortOrder
564
        );
565
    }
566
567
    /**
568
     * Builds the document list query.
569
     *
570
     * @param array $workspaceFilter
571
     * @param int $from
572
     * @param array $bookmarkIdentifiers
573
     * @param array $filters
574
     * @param array $excludeFilters
575
     * @param string $sortField
576
     * @param string $sortOrder
577
     *
578
     * @return array
579
     */
580
    protected function buildQuery(
581
        $workspaceFilter, $from = 0, $bookmarkIdentifiers = [], $filters = [], $excludeFilters = [], $sortField = null, $sortOrder = null
582
    )
583
    {
584
        // The base filter.
585
        $queryFilter = [
586
            'bool' => [
587
                'must' => [
588
                    [
589
                        'bool' => [
590
                            'should' => [
591
                                0 => $workspaceFilter
592
                            ]
593
                        ]
594
                    ]
595
                ]
596
            ]
597
        ];
598
599
        if (!($excludeFilters && array_key_exists('bookmarks', $excludeFilters))) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $excludeFilters of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
600
            // Add user document bookmarks.
601
            if ($bookmarkIdentifiers) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $bookmarkIdentifiers of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
602
                $queryFilter['bool']['must'][0]['bool']['should'][] = [
603
                    'terms' => [
604
                        '_id' => $bookmarkIdentifiers
605
                    ]
606
                ];
607
            }
608
        } else {
609
            // Show only user document bookmarks.
610
            $queryFilter['bool']['must'][0] = [
611
                'terms' => [
612
                    '_id' => $bookmarkIdentifiers
613
                ]
614
            ];
615
        }
616
617
        $filterPart = $this->buildFilterQueryPart($filters, $excludeFilters);
618
619
        if ($filterPart) {
620
            $queryFilter['bool']['must'][] = $filterPart;
621
        }
622
623
        // Put together the complete query.
624
        $query = [
625
            'body' => [
626
                'size' => $this->itemsPerPage(),
627
                'from' => $from,
628
                'query' => [
629
                    'bool' => [
630
                        'must' => [
631
                            'match_all' => (object)[]
632
                        ],
633
                        'filter' => $queryFilter
634
                    ]
635
                ],
636
                'sort' => $this->buildSortQueryPart($sortField, $sortOrder),
637
                'aggs' => [
638
                    'simpleState' => [
639
                        'terms' => [
640
                            'field' => 'simpleState'
641
                        ]
642
                    ],
643
                    'year' => [
644
                        'terms' => [
645
                            'field' => 'year'
646
                        ]
647
                    ],
648
                    'doctype' => [
649
                        'terms' => [
650
                            'field' => 'doctype'
651
                        ]
652
                    ],
653
                    'hasFiles' => [
654
                        'terms' => [
655
                            'field' => 'hasFiles'
656
                        ]
657
                    ],
658
                    'universityCollection' => [
659
                        'terms' => [
660
                            'script' => [
661
                                'lang' => 'painless',
662
                                'source' =>
663
                                    "for (int i = 0; i < doc['collections'].length; ++i) {".
664
                                    "    if(doc['collections'][i] =='".$this->settings['universityCollection']."') {".
665
                                    "        return 'true';".
666
                                    "    }".
667
                                    "}".
668
                                    "return 'false';"
669
                                ]
670
                        ]
671
                    ],
672
                    'authorAndPublisher' => [
673
                        'terms' => [
674
                            'field' => 'authorAndPublisher'
675
                        ]
676
                    ],
677
                    'creatorRole' => [
678
                        'terms' => [
679
                            'script' => [
680
                                'lang' => 'painless',
681
                                'source' =>
682
                                    "if (".
683
                                    "    doc['creator'].size() > 0 &&".
684
                                    "    doc['creator'].value == '".$this->security->getUser()->getUid()."') {".
685
                                    "    return 'self';".
686
                                    "}".
687
                                    "if (".
688
                                    "    doc['creatorRole'].size() > 0 &&".
689
                                    "    doc['creatorRole'].value == '".Security::ROLE_LIBRARIAN."'".
690
                                    ") {".
691
                                    "    return 'librarian';".
692
                                    "}".
693
                                    "if (".
694
                                    "    doc['creatorRole'].size() > 0 &&".
695
                                    "    doc['creatorRole'].value == '".Security::ROLE_RESEARCHER."'".
696
                                    ") {".
697
                                    "    return 'user';".
698
                                    "}".
699
                                    "return 'unknown';"
700
                            ]
701
                        ]
702
                    ]
703
704
                ]
705
            ]
706
        ];
707
708
        return $query;
709
    }
710
711
    /**
712
     * Composes the filter part based on the given filters.
713
     *
714
     * @param array $filters
715
     * @param array $excludeFilters
716
     * @return array
717
     */
718
    protected function buildFilterQueryPart($filters, $excludeFilters = []) {
719
720
        $queryFilter = [];
721
722
        // Build the column filter part.
723
        if ($filters && is_array($filters)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $filters of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
724
725
            $validKeys = [
726
                'simpleState', 'authorAndPublisher', 'doctype', 'hasFiles', 'year', 'universityCollection', 'creatorRole'
727
            ];
728
729
            foreach ($filters as $key => $filterValues) {
730
                $queryFilterPart = [];
731
                if (in_array($key, $validKeys, true)) {
732
                    if ($key == 'universityCollection') {
733
                        if ($filterValues && is_array($filterValues)) {
734
                            if (in_array("true", $filterValues)) {
735
                                $filterValue = $this->settings['universityCollection'];
736
                                $queryFilterPart['bool']['should'][] = [
737
                                    'term' => [
738
                                        'collections' => $filterValue
739
                                    ]
740
                                ];
741
                            } else {
742
                                $filterValue = $this->settings['universityCollection'];
743
                                $queryFilterPart['bool']['should'][] = [
744
                                    'bool' => [
745
                                        'must_not' => [
746
                                            'term' => [
747
                                                'collections' => $filterValue
748
                                            ]
749
                                        ]
750
                                    ]
751
                                ];
752
                            }
753
                            $queryFilter['bool']['must'][] = $queryFilterPart;
754
                        }
755
                    } elseif ($key == 'creatorRole') {
756
                        $queryFilterPart = [];
757
                        if ($filterValues && is_array($filterValues)) {
758
                            if (in_array("librarian", $filterValues)) {
759
                                $creatorRolePart['bool']['must'] = [
760
                                    [
761
                                        'term' => [
762
                                            'creatorRole' => Security::ROLE_LIBRARIAN
763
                                        ]
764
                                    ],
765
                                    [
766
                                        'bool' => [
767
                                            'must_not' => [
768
                                                'term' => [
769
                                                    'creator' => $this->security->getUser()->getUid()
770
                                                ]
771
                                            ]
772
                                        ]
773
                                    ]
774
                                ];
775
                                $queryFilterPart['bool']['should'][] = $creatorRolePart;
776
                            } elseif (in_array("user", $filterValues)) {
777
                                $creatorRolePart['bool']['must'] = [
778
                                    [
779
                                        'term' => [
780
                                            'creatorRole' => Security::ROLE_RESEARCHER
781
                                        ]
782
                                    ],
783
                                    [
784
                                        'bool' => [
785
                                            'must_not' => [
786
                                                'term' => [
787
                                                    'creator' => $this->security->getUser()->getUid()
788
                                                ]
789
                                            ]
790
                                        ]
791
                                    ]
792
                                ];
793
                                $queryFilterPart['bool']['should'][] = $creatorRolePart;
794
                            } elseif (in_array("self", $filterValues)) {
795
                                $creatorRolePart['bool']['must'] = [
796
                                    [
797
                                        'term' => [
798
                                            'creator' =>  $this->security->getUser()->getUid()
799
                                        ]
800
                                    ]
801
                                ];
802
                                $queryFilterPart['bool']['should'][] = $creatorRolePart;
803
                            } else {
804
                                $creatorRolePart['bool']['must'] = [
805
                                    [
806
                                        'bool' => [
807
                                            'must_not' => [
808
                                                'term' => [
809
                                                    'creator' => $this->security->getUser()->getUid()
810
                                                ]
811
                                            ]
812
                                        ]
813
                                    ],
814
                                    [
815
                                        'bool' => [
816
                                            'must_not' => [
817
                                                'term' => [
818
                                                    'creatorRole' => Security::ROLE_LIBRARIAN
819
                                                ]
820
                                            ]
821
                                        ]
822
                                    ],
823
                                    [
824
                                        'bool' => [
825
                                            'must_not' => [
826
                                                'term' => [
827
                                                    'creatorRole' => Security::ROLE_RESEARCHER
828
                                                ]
829
                                            ]
830
                                        ]
831
                                    ]
832
                                ];
833
                                $queryFilterPart['bool']['should'][] = $creatorRolePart;
834
                            }
835
836
                            if ($queryFilterPart) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $queryFilterPart of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
837
                                $queryFilter['bool']['must'][] = $queryFilterPart;
838
                            }
839
                        }
840
                    } else {
841
                        if ($filterValues && is_array($filterValues)) {
842
                            foreach ($filterValues as $filterValue) {
843
                                $queryFilterPart['bool']['should'][] = [
844
                                    'term' => [
845
                                        $key => $filterValue
846
                                    ]
847
                                ];
848
                            }
849
                            $queryFilter['bool']['must'][] = $queryFilterPart;
850
                        }
851
                    }
852
                }
853
            }
854
        }
855
856
        if ($excludeFilters && array_key_exists('simpleState', $excludeFilters)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $excludeFilters of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
857
            if ($excludeFilters['simpleState']) {
858
                foreach ($excludeFilters['simpleState'] as $simpleStateExclude) {
859
                    $queryFilter['bool']['must'][] = [
860
                        'bool' => [
861
                            'must_not' => [
862
                                'bool' => [
863
                                    'must' => [
864
                                        [
865
                                            'term' => [
866
                                                'simpleState' => $simpleStateExclude
867
                                            ]
868
                                        ],
869
                                        [
870
                                            'term' => [
871
                                                'creator' => $this->security->getUser()->getUid()
872
                                            ]
873
                                        ]
874
                                    ]
875
                                ]
876
                            ]
877
                        ]
878
                    ];
879
                }
880
            }
881
        }
882
883
        return $queryFilter;
884
    }
885
886
887
    /**
888
     * Composes the sort query part based on the given sort field and order.
889
     *
890
     * @param string $sortField
891
     * @param string $sortOrder
892
     * @return array
893
     */
894
    protected function buildSortQueryPart($sortField, $sortOrder) {
895
        // Build the sorting part.
896
        $script = "";
897
        if ($sortField == "simpleState") {
898
            $script = $this->getSortScriptState();
899
        } elseif ($sortField == "universityCollection") {
900
            $script = $this->getSortScriptUniversityCollection($this->settings['universityCollection']);
901
        } elseif ($sortField == "hasFiles") {
902
            $script = $this->getSortScriptHasFiles();
903
        } elseif ($sortField == "creatorRole") {
904
            $script = $this->getSortScriptCreatorRole($this->security->getUser()->getUid());
905
        }
906
907
        if ($script) {
908
            $sort = [
909
                "_script" => [
910
                    "type" => "string",
911
                    "order" => $sortOrder,
912
                    "script" => [
913
                        "lang" => "painless",
914
                        "source" => $script
915
                    ]
916
                ],
917
                "title.keyword" => [
918
                    "order" => "asc"
919
                ]
920
            ];
921
        } else {
922
            if ($sortField == 'title') {
923
                $sortField.= ".keyword";
924
            }
925
926
            $sort = [
927
                (($sortField)? $sortField : self::DEFAULT_SORT_FIELD.".keyword") => [
928
                    'order' => (($sortOrder)? $sortOrder : self::DEFAULT_SORT_ORDER)
929
                ]
930
            ];
931
        }
932
933
        return $sort;
934
    }
935
936
937
    protected function getSortScriptUniversityCollection($collection)
938
    {
939
        $script  = "for (int i = 0; i < doc['collections'].length; ++i) {";
940
        $script .= "    if (doc['collections'][i] == '".$collection."') {";
941
        $script .= "        return '1';";
942
        $script .= "    }";
943
        $script .= "}";
944
        $script .= "return '2'";
945
946
        return $script;
947
    }
948
949
    protected function getSortScriptHasFiles()
950
    {
951
        $script = "if (doc['hasFiles'].value == 'true') {";
952
        $script .= "    return '1';";
953
        $script .= "}";
954
        $script .= "return '2'";
955
956
        return $script;
957
    }
958
959
    protected function getSortScriptCreatorRole($feUserUid)
960
    {
961
        $script = "if (doc['creator'].value == '".$feUserUid."') {";
962
        $script .= "    return '1';";
963
        $script .= "}";
964
        $script .= "if (doc['creatorRole'].value == '".Security::ROLE_LIBRARIAN."') {";
965
        $script .= "return '2';";
966
        $script .= "}";
967
        $script .= "if (doc['creatorRole'].value == '".Security::ROLE_RESEARCHER."') {";
968
        $script .= "    return '3';";
969
        $script .= "}";
970
        $script .= "return '4';";
971
972
        return $script;
973
    }
974
975
976
    protected function getSortScriptState()
977
    {
978
        $sortStates = [];
979
        foreach (DocumentWorkflow::PLACES as $state) {
980
            if (array_key_exists($state, DocumentWorkflow::STATE_TO_SIMPLESTATE_MAPPING)) {
981
                $simpleState = DocumentWorkflow::STATE_TO_SIMPLESTATE_MAPPING[$state];
982
                $key = 'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:manager.documentList.state.'.$simpleState;
983
                $stateName = LocalizationUtility::translate($key, 'dpf');
984
                $sortStates[] = "if (doc['state'].value == '".$state."') return '".$stateName."';";
985
            }
986
        }
987
988
        $sortStates = implode(" ", $sortStates);
989
990
        return $sortStates." return '';";
991
    }
992
993
994
    protected function getSortScriptDoctype()
995
    {
996
        $sortDoctypes = [];
997
        foreach ($this->documentTypeRepository->findAll() as $documentType) {
998
            if ($documentType->getName() && $documentType->getDisplayname()) {
999
                $sortDoctypes[] = "if (doc['doctype'].value == '".$documentType->getName()."')"
1000
                    ." return '".$documentType->getDisplayname()."';";
1001
            }
1002
        }
1003
1004
        $sortDoctypes = implode(" ", $sortDoctypes);
1005
1006
        return $sortDoctypes." return '';";
1007
    }
1008
1009
1010
    /**
1011
     * A temporary solution to initialize the index.
1012
     *
1013
     * @param int $start
1014
     * @param int $stop
1015
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
1016
     */
1017
    public function initIndexAction($start=1, $stop=100)
1018
    {
1019
        /** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */
1020
        $signalSlotDispatcher = $this->objectManager->get(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class);
1021
1022
        /** @var \EWW\Dpf\Services\Transfer\DocumentTransferManager $documentTransferManager */
1023
        $documentTransferManager = $this->objectManager->get(\EWW\Dpf\Services\Transfer\DocumentTransferManager::class);
1024
1025
        $fedoraRepository = $this->objectManager->get(\EWW\Dpf\Services\Transfer\FedoraRepository::class);
1026
        $documentTransferManager->setRemoteRepository($fedoraRepository);
1027
1028
        for($i=$start; $i<$stop; $i++) {
1029
            try {
1030
                $document = $documentTransferManager->retrieve('qucosa:' . $i);
1031
1032
                if ($document instanceof Document) {
1033
                    $state = $document->getState();
1034
                    $document->setState(
1035
                        str_replace(
1036
                            DocumentWorkflow::LOCAL_STATE_IN_PROGRESS,
1037
                            DocumentWorkflow::LOCAL_STATE_NONE,
1038
                            $state
1039
                        )
1040
                    );
1041
1042
                    // index the document
1043
                    $signalSlotDispatcher->dispatch(
1044
                        \EWW\Dpf\Controller\AbstractController::class,
1045
                        'indexDocument', [$document]
1046
                    );
1047
1048
                    $this->documentRepository->remove($document);
1049
                }
1050
            } catch (\EWW\Dpf\Exceptions\RetrieveDocumentErrorException $e) {
1051
                // Nothing to be done.
1052
            }
1053
        }
1054
1055
        foreach ($this->documentRepository->findAll() as $document) {
1056
            if (!$document->isTemporary() && !$document->isSuggestion()) {
1057
                // index the document
1058
                $signalSlotDispatcher->dispatch(
1059
                    \EWW\Dpf\Controller\AbstractController::class,
1060
                    'indexDocument', [$document]
1061
                );
1062
            }
1063
        }
1064
    }
1065
1066
1067
    /**
1068
     * action uploadFiles
1069
     *
1070
     * @param string $documentIdentifier
1071
     * @return void
1072
     */
1073
    public function uploadFilesAction($documentIdentifier)
1074
    {
1075
        $document = $this->documentManager->read(
1076
            $documentIdentifier,
1077
            $this->security->getUser()->getUID()
0 ignored issues
show
Unused Code introduced by
The call to EWW\Dpf\Services\Document\DocumentManager::read() has too many arguments starting with $this->security->getUser()->getUID(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1077
        /** @scrutinizer ignore-call */ 
1078
        $document = $this->documentManager->read(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1078
        );
1079
1080
        if ($document instanceof Document) {
1081
            if ($this->authorizationChecker->isGranted(DocumentVoter::EDIT, $document)) {
1082
                $this->redirect(
1083
                    'edit',
1084
                    'DocumentFormBackoffice',
1085
                    null,
1086
                    ['document' => $document, 'activeFileTab' => true]);
1087
            } elseif ($this->authorizationChecker->isGranted(DocumentVoter::SUGGEST_MODIFICATION, $document)) {
1088
                $this->redirect(
1089
                    'edit',
1090
                    'DocumentFormBackoffice',
1091
                    null,
1092
                    ['document' => $document, 'suggestMod' => true, 'activeFileTab' => true]);
1093
            } else {
1094
                if ($document->getCreator() !== $this->security->getUser()->getUid()) {
1095
                    $message = LocalizationUtility::translate(
1096
                        'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:document_edit.accessDenied',
1097
                        'dpf',
1098
                        array($document->getTitle())
1099
                    );
1100
                } else {
1101
                    $message = LocalizationUtility::translate(
1102
                        'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:document_edit.failureBlocked',
1103
                        'dpf',
1104
                        array($document->getTitle())
1105
                    );
1106
                }
1107
            }
1108
        } else {
1109
            $message = LocalizationUtility::translate(
1110
                'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:error.unexpected',
1111
                'dpf'
1112
            );
1113
        }
1114
1115
        $this->addFlashMessage($message, '', AbstractMessage::ERROR);
1116
1117
        list($action, $controller, $redirectUri) = $this->session->getListAction();
1118
1119
        if ($redirectUri) {
1120
            $this->redirectToUri($redirectUri);
1121
        } else {
1122
            $this->redirect($action, $controller, null, array('message' => $message));;
1123
        }
1124
1125
    }
1126
1127
1128
    /**
1129
     * Returns the number of items to be shown per page.
1130
     *
1131
     * @return int
1132
     */
1133
    protected function itemsPerPage()
1134
    {
1135
        $itemsPerPage = $this->session->getWorkspaceItemsPerPage();
1136
        $default = ($this->settings['workspaceItemsPerPage'])? $this->settings['workspaceItemsPerPage'] : 10;
1137
        return ($itemsPerPage)? $itemsPerPage : $default;
1138
    }
1139
1140
}
1141