Passed
Pull Request — master (#166)
by
unknown
16:07
created

WorkspaceController::batchRelease()   D

Complexity

Conditions 18
Paths 9

Size

Total Lines 102
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 66
c 1
b 0
f 0
nc 9
nop 2
dl 0
loc 102
rs 4.8666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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->getUser()->getUserRole() == Security::ROLE_LIBRARIAN) {
118
            $query = $this->getWorkspaceQuery($from, $bookmarkIdentifiers,
119
                $filters, $excludeFilters, $sortField, $sortOrder);
120
        } elseif ($this->security->getUser()->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('aliasState', $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->getUser()->getUserRole() === Security::ROLE_LIBRARIAN) {
174
            $this->view->assign('isWorkspace', true);
175
        } elseif ($this->security->getUser()->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
            if (sizeof($successful) == 1) {
433
                $locallangKey = 'manager.workspace.batchAction.release.success.singular';
434
            } else {
435
                $locallangKey = 'manager.workspace.batchAction.release.success.plural';
436
            }
437
438
            $message = LocalizationUtility::translate(
439
                $locallangKey,
440
                'dpf',
441
                [sizeof($successful), sizeof($listData['documentIdentifiers'])]
442
            );
443
            $this->addFlashMessage(
444
                $message, '',
445
                (sizeof($successful) > 0 ? AbstractMessage::OK : AbstractMessage::WARNING)
446
            );
447
448
            if (sizeof($successful) === 1 ) {
449
                $this->addFlashMessage(
450
                    "1 ".LocalizationUtility::translate("manager.workspace.bookmarkRemoved.singular", "dpf"),
451
                    '',
452
                    AbstractMessage::INFO
453
                );
454
            }
455
456
            if (sizeof($successful) > 1 ) {
457
                $this->addFlashMessage(
458
                    LocalizationUtility::translate(
459
                        "manager.workspace.bookmarkRemoved.plural", "dpf", [sizeof($successful)]
460
                    ),
461
                    '',
462
                    AbstractMessage::INFO
463
                );
464
            }
465
466
        } else {
467
            $message = LocalizationUtility::translate(
468
                'manager.workspace.batchAction.failure',
469
                'dpf');
470
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
471
        }
472
473
        list($redirectAction, $redirectController) = $this->session->getListAction();
474
        $this->redirect(
475
            $redirectAction, $redirectController, null,
476
            array('message' => $message, 'checkedDocumentIdentifiers' =>  $checkedDocumentIdentifiers));
477
478
    }
479
480
    /**
481
     * get list view data for the workspace
482
     *
483
     * @param int $from
484
     * @param array $bookmarkIdentifiers
485
     * @param array $filters
486
     * @param array $excludeFilters
487
     * @param string $sortField
488
     * @param string $sortOrder
489
     *
490
     * @return array
491
     */
492
    protected function getWorkspaceQuery(
493
        $from = 0, $bookmarkIdentifiers = [], $filters= [], $excludeFilters = [], $sortField = null, $sortOrder = null
494
    )
495
    {
496
        $workspaceFilter = [
497
            'bool' => [
498
                'must' => [
499
                    [
500
                        'bool' => [
501
                            'must' => [
502
                                [
503
                                    'term' => [
504
                                        'creator' => $this->security->getUser()->getUid()
505
                                    ]
506
                                ],
507
                                [
508
                                    'bool' => [
509
                                        'should' => [
510
                                            [
511
                                                'term' => [
512
                                                    'state' => DocumentWorkflow::STATE_NEW_NONE
513
                                                ]
514
                                            ]
515
                                        ]
516
                                    ]
517
                                ]
518
                            ]
519
                        ]
520
                    ]
521
                ]
522
            ]
523
        ];
524
525
        return $this->buildQuery(
526
            $workspaceFilter, $from, $bookmarkIdentifiers, $filters,
527
            $excludeFilters, $sortField, $sortOrder
528
        );
529
    }
530
531
532
    /**
533
     * get list view data for the my publications list.
534
     *
535
     * @param int $from
536
     * @param array $bookmarkIdentifiers
537
     * @param array $filters
538
     * @param array $excludeFilters
539
     * @param string $sortField
540
     * @param string $sortOrder
541
     *
542
     * @return array
543
     */
544
    protected function getMyPublicationsQuery(
545
        $from = 0, $bookmarkIdentifiers = [], $filters = [], $excludeFilters = [], $sortField = null, $sortOrder = null
546
    )
547
    {
548
        $workspaceFilter = [
549
            'bool' => [
550
                'must' => [
551
                    [
552
                        'term' => [
553
                            'creator' => $this->security->getUser()->getUid()
554
                        ]
555
                    ]
556
                ]
557
            ]
558
        ];
559
560
        return $this->buildQuery(
561
            $workspaceFilter, $from, $bookmarkIdentifiers, $filters,
562
            $excludeFilters, $sortField, $sortOrder
563
        );
564
    }
565
566
    /**
567
     * Builds the document list query.
568
     *
569
     * @param array $workspaceFilter
570
     * @param int $from
571
     * @param array $bookmarkIdentifiers
572
     * @param array $filters
573
     * @param array $excludeFilters
574
     * @param string $sortField
575
     * @param string $sortOrder
576
     *
577
     * @return array
578
     */
579
    protected function buildQuery(
580
        $workspaceFilter, $from = 0, $bookmarkIdentifiers = [], $filters = [], $excludeFilters = [], $sortField = null, $sortOrder = null
581
    )
582
    {
583
        // The base filter.
584
        $queryFilter = [
585
            'bool' => [
586
                'must' => [
587
                    [
588
                        'bool' => [
589
                            'should' => [
590
                                0 => $workspaceFilter
591
                            ]
592
                        ]
593
                    ]
594
                ]
595
            ]
596
        ];
597
598
        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...
599
            // Add user document bookmarks.
600
            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...
601
                $queryFilter['bool']['must'][0]['bool']['should'][] = [
602
                    'terms' => [
603
                        '_id' => $bookmarkIdentifiers
604
                    ]
605
                ];
606
            }
607
        } else {
608
            // Show only user document bookmarks.
609
            $queryFilter['bool']['must'][0] = [
610
                'terms' => [
611
                    '_id' => $bookmarkIdentifiers
612
                ]
613
            ];
614
        }
615
616
        $filterPart = $this->buildFilterQueryPart($filters, $excludeFilters);
617
618
        if ($filterPart) {
619
            $queryFilter['bool']['must'][] = $filterPart;
620
        }
621
622
        // Put together the complete query.
623
        $query = [
624
            'body' => [
625
                'size' => $this->itemsPerPage(),
626
                'from' => $from,
627
                'query' => [
628
                    'bool' => [
629
                        'must' => [
630
                            'match_all' => (object)[]
631
                        ],
632
                        'filter' => $queryFilter
633
                    ]
634
                ],
635
                'sort' => $this->buildSortQueryPart($sortField, $sortOrder),
636
                'aggs' => [
637
                    'aliasState' => [
638
                        'terms' => [
639
                            'field' => 'aliasState'
640
                        ]
641
                    ],
642
                    'year' => [
643
                        'terms' => [
644
                            'field' => 'year'
645
                        ]
646
                    ],
647
                    'doctype' => [
648
                        'terms' => [
649
                            'field' => 'doctype'
650
                        ]
651
                    ],
652
                    'hasFiles' => [
653
                        'terms' => [
654
                            'field' => 'hasFiles'
655
                        ]
656
                    ],
657
                    'universityCollection' => [
658
                        'terms' => [
659
                            'script' => [
660
                                'lang' => 'painless',
661
                                'source' =>
662
                                    "for (int i = 0; i < doc['collections'].length; ++i) {".
663
                                    "    if(doc['collections'][i] =='".$this->settings['universityCollection']."') {".
664
                                    "        return 'true';".
665
                                    "    }".
666
                                    "}".
667
                                    "return 'false';"
668
                                ]
669
                        ]
670
                    ],
671
                    'authorAndPublisher' => [
672
                        'terms' => [
673
                            'field' => 'authorAndPublisher'
674
                        ]
675
                    ],
676
                    'creatorRole' => [
677
                        'terms' => [
678
                            'script' => [
679
                                'lang' => 'painless',
680
                                'source' =>
681
                                    "if (".
682
                                    "    doc['creator'].size() > 0 &&".
683
                                    "    doc['creator'].value == '".$this->security->getUser()->getUid()."') {".
684
                                    "    return 'self';".
685
                                    "}".
686
                                    "if (".
687
                                    "    doc['creatorRole'].size() > 0 &&".
688
                                    "    doc['creatorRole'].value == '".Security::ROLE_LIBRARIAN."'".
689
                                    ") {".
690
                                    "    return 'librarian';".
691
                                    "}".
692
                                    "if (".
693
                                    "    doc['creatorRole'].size() > 0 &&".
694
                                    "    doc['creatorRole'].value == '".Security::ROLE_RESEARCHER."'".
695
                                    ") {".
696
                                    "    return 'user';".
697
                                    "}".
698
                                    "return 'unknown';"
699
                            ]
700
                        ]
701
                    ]
702
703
                ]
704
            ]
705
        ];
706
707
        return $query;
708
    }
709
710
    /**
711
     * Composes the filter part based on the given filters.
712
     *
713
     * @param array $filters
714
     * @param array $excludeFilters
715
     * @return array
716
     */
717
    protected function buildFilterQueryPart($filters, $excludeFilters = []) {
718
719
        $queryFilter = [];
720
721
        // Build the column filter part.
722
        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...
723
724
            $validKeys = [
725
                'aliasState', 'authorAndPublisher', 'doctype', 'hasFiles', 'year', 'universityCollection', 'creatorRole'
726
            ];
727
728
            foreach ($filters as $key => $filterValues) {
729
                $queryFilterPart = [];
730
                if (in_array($key, $validKeys, true)) {
731
                    if ($key == 'universityCollection') {
732
                        if ($filterValues && is_array($filterValues)) {
733
                            if (in_array("true", $filterValues)) {
734
                                $filterValue = $this->settings['universityCollection'];
735
                                $queryFilterPart['bool']['should'][] = [
736
                                    'term' => [
737
                                        'collections' => $filterValue
738
                                    ]
739
                                ];
740
                            } else {
741
                                $filterValue = $this->settings['universityCollection'];
742
                                $queryFilterPart['bool']['should'][] = [
743
                                    'bool' => [
744
                                        'must_not' => [
745
                                            'term' => [
746
                                                'collections' => $filterValue
747
                                            ]
748
                                        ]
749
                                    ]
750
                                ];
751
                            }
752
                            $queryFilter['bool']['must'][] = $queryFilterPart;
753
                        }
754
                    } elseif ($key == 'creatorRole') {
755
                        $queryFilterPart = [];
756
                        if ($filterValues && is_array($filterValues)) {
757
                            if (in_array("librarian", $filterValues)) {
758
                                $creatorRolePart['bool']['must'] = [
759
                                    [
760
                                        'term' => [
761
                                            'creatorRole' => Security::ROLE_LIBRARIAN
762
                                        ]
763
                                    ],
764
                                    [
765
                                        'bool' => [
766
                                            'must_not' => [
767
                                                'term' => [
768
                                                    'creator' => $this->security->getUser()->getUid()
769
                                                ]
770
                                            ]
771
                                        ]
772
                                    ]
773
                                ];
774
                                $queryFilterPart['bool']['should'][] = $creatorRolePart;
775
                            } elseif (in_array("user", $filterValues)) {
776
                                $creatorRolePart['bool']['must'] = [
777
                                    [
778
                                        'term' => [
779
                                            'creatorRole' => Security::ROLE_RESEARCHER
780
                                        ]
781
                                    ],
782
                                    [
783
                                        'bool' => [
784
                                            'must_not' => [
785
                                                'term' => [
786
                                                    'creator' => $this->security->getUser()->getUid()
787
                                                ]
788
                                            ]
789
                                        ]
790
                                    ]
791
                                ];
792
                                $queryFilterPart['bool']['should'][] = $creatorRolePart;
793
                            } elseif (in_array("self", $filterValues)) {
794
                                $creatorRolePart['bool']['must'] = [
795
                                    [
796
                                        'term' => [
797
                                            'creator' =>  $this->security->getUser()->getUid()
798
                                        ]
799
                                    ]
800
                                ];
801
                                $queryFilterPart['bool']['should'][] = $creatorRolePart;
802
                            } else {
803
                                $creatorRolePart['bool']['must'] = [
804
                                    [
805
                                        'bool' => [
806
                                            'must_not' => [
807
                                                'term' => [
808
                                                    'creator' => $this->security->getUser()->getUid()
809
                                                ]
810
                                            ]
811
                                        ]
812
                                    ],
813
                                    [
814
                                        'bool' => [
815
                                            'must_not' => [
816
                                                'term' => [
817
                                                    'creatorRole' => Security::ROLE_LIBRARIAN
818
                                                ]
819
                                            ]
820
                                        ]
821
                                    ],
822
                                    [
823
                                        'bool' => [
824
                                            'must_not' => [
825
                                                'term' => [
826
                                                    'creatorRole' => Security::ROLE_RESEARCHER
827
                                                ]
828
                                            ]
829
                                        ]
830
                                    ]
831
                                ];
832
                                $queryFilterPart['bool']['should'][] = $creatorRolePart;
833
                            }
834
835
                            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...
836
                                $queryFilter['bool']['must'][] = $queryFilterPart;
837
                            }
838
                        }
839
                    } else {
840
                        if ($filterValues && is_array($filterValues)) {
841
                            foreach ($filterValues as $filterValue) {
842
                                $queryFilterPart['bool']['should'][] = [
843
                                    'term' => [
844
                                        $key => $filterValue
845
                                    ]
846
                                ];
847
                            }
848
                            $queryFilter['bool']['must'][] = $queryFilterPart;
849
                        }
850
                    }
851
                }
852
            }
853
        }
854
855
        if ($excludeFilters && array_key_exists('aliasState', $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...
856
            if ($excludeFilters['aliasState']) {
857
                foreach ($excludeFilters['aliasState'] as $aliasStateExclude) {
858
                    $queryFilter['bool']['must'][] = [
859
                        'bool' => [
860
                            'must_not' => [
861
                                'bool' => [
862
                                    'must' => [
863
                                        [
864
                                            'term' => [
865
                                                'aliasState' => $aliasStateExclude
866
                                            ]
867
                                        ],
868
                                        [
869
                                            'term' => [
870
                                                'creator' => $this->security->getUser()->getUid()
871
                                            ]
872
                                        ]
873
                                    ]
874
                                ]
875
                            ]
876
                        ]
877
                    ];
878
                }
879
            }
880
        }
881
882
        return $queryFilter;
883
    }
884
885
886
    /**
887
     * Composes the sort query part based on the given sort field and order.
888
     *
889
     * @param string $sortField
890
     * @param string $sortOrder
891
     * @return array
892
     */
893
    protected function buildSortQueryPart($sortField, $sortOrder) {
894
        // Build the sorting part.
895
        $script = "";
896
        if ($sortField == "aliasState") {
897
            $script = $this->getSortScriptState();
898
        } elseif ($sortField == "universityCollection") {
899
            $script = $this->getSortScriptUniversityCollection($this->settings['universityCollection']);
900
        } elseif ($sortField == "hasFiles") {
901
            $script = $this->getSortScriptHasFiles();
902
        } elseif ($sortField == "creatorRole") {
903
            $script = $this->getSortScriptCreatorRole($this->security->getUser()->getUid());
904
        }
905
906
        if ($script) {
907
            $sort = [
908
                "_script" => [
909
                    "type" => "string",
910
                    "order" => $sortOrder,
911
                    "script" => [
912
                        "lang" => "painless",
913
                        "source" => $script
914
                    ]
915
                ],
916
                "title.keyword" => [
917
                    "order" => "asc"
918
                ]
919
            ];
920
        } else {
921
            if ($sortField == 'title') {
922
                $sortField.= ".keyword";
923
            }
924
925
            $sort = [
926
                (($sortField)? $sortField : self::DEFAULT_SORT_FIELD.".keyword") => [
927
                    'order' => (($sortOrder)? $sortOrder : self::DEFAULT_SORT_ORDER)
928
                ]
929
            ];
930
        }
931
932
        return $sort;
933
    }
934
935
936
    protected function getSortScriptUniversityCollection($collection)
937
    {
938
        $script  = "for (int i = 0; i < doc['collections'].length; ++i) {";
939
        $script .= "    if (doc['collections'][i] == '".$collection."') {";
940
        $script .= "        return '1';";
941
        $script .= "    }";
942
        $script .= "}";
943
        $script .= "return '2'";
944
945
        return $script;
946
    }
947
948
    protected function getSortScriptHasFiles()
949
    {
950
        $script = "if (doc['hasFiles'].value == 'true') {";
951
        $script .= "    return '1';";
952
        $script .= "}";
953
        $script .= "return '2'";
954
955
        return $script;
956
    }
957
958
    protected function getSortScriptCreatorRole($feUserUid)
959
    {
960
        $script = "if (doc['creator'].value == '".$feUserUid."') {";
961
        $script .= "    return '1';";
962
        $script .= "}";
963
        $script .= "if (doc['creatorRole'].value == '".Security::ROLE_LIBRARIAN."') {";
964
        $script .= "return '2';";
965
        $script .= "}";
966
        $script .= "if (doc['creatorRole'].value == '".Security::ROLE_RESEARCHER."') {";
967
        $script .= "    return '3';";
968
        $script .= "}";
969
        $script .= "return '4';";
970
971
        return $script;
972
    }
973
974
975
    protected function getSortScriptState()
976
    {
977
        $sortStates = [];
978
        foreach (DocumentWorkflow::PLACES as $state) {
979
            if (array_key_exists($state, DocumentWorkflow::STATE_TO_ALIASSTATE_MAPPING)) {
980
                $aliasState = DocumentWorkflow::STATE_TO_ALIASSTATE_MAPPING[$state];
981
                $key = 'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:manager.documentList.state.'.$aliasState;
982
                $stateName = LocalizationUtility::translate($key, 'dpf');
983
                $sortStates[] = "if (doc['state'].value == '".$state."') return '".$stateName."';";
984
            }
985
        }
986
987
        $sortStates = implode(" ", $sortStates);
988
989
        return $sortStates." return '';";
990
    }
991
992
993
    protected function getSortScriptDoctype()
994
    {
995
        $sortDoctypes = [];
996
        foreach ($this->documentTypeRepository->findAll() as $documentType) {
997
            if ($documentType->getName() && $documentType->getDisplayname()) {
998
                $sortDoctypes[] = "if (doc['doctype'].value == '".$documentType->getName()."')"
999
                    ." return '".$documentType->getDisplayname()."';";
1000
            }
1001
        }
1002
1003
        $sortDoctypes = implode(" ", $sortDoctypes);
1004
1005
        return $sortDoctypes." return '';";
1006
    }
1007
1008
1009
    /**
1010
     * A temporary solution to initialize the index.
1011
     *
1012
     * @param int $start
1013
     * @param int $stop
1014
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
1015
     */
1016
    public function initIndexAction($start = 1, $stop = 100)
1017
    {
1018
        /** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */
1019
        $signalSlotDispatcher = $this->objectManager->get(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class);
1020
1021
        /** @var \EWW\Dpf\Services\Transfer\DocumentTransferManager $documentTransferManager */
1022
        $documentTransferManager = $this->objectManager->get(\EWW\Dpf\Services\Transfer\DocumentTransferManager::class);
1023
1024
        $fedoraRepository = $this->objectManager->get(\EWW\Dpf\Services\Transfer\FedoraRepository::class);
1025
        $documentTransferManager->setRemoteRepository($fedoraRepository);
1026
1027
        for($i = $start; $i < $stop; $i++) {
1028
            try {
1029
                $document = $documentTransferManager->retrieve('qucosa:' . $i);
1030
1031
                if ($document instanceof Document) {
1032
                    $state = $document->getState();
1033
                    $document->setState(
1034
                        str_replace(
1035
                            DocumentWorkflow::LOCAL_STATE_IN_PROGRESS,
1036
                            DocumentWorkflow::LOCAL_STATE_NONE,
1037
                            $state
1038
                        )
1039
                    );
1040
1041
                    // index the document
1042
                    $signalSlotDispatcher->dispatch(
1043
                        \EWW\Dpf\Controller\AbstractController::class,
1044
                        'indexDocument', [$document]
1045
                    );
1046
1047
                    $this->documentRepository->remove($document);
1048
                }
1049
            } catch (\EWW\Dpf\Exceptions\RetrieveDocumentErrorException $e) {
1050
                // Nothing to be done.
1051
            }
1052
        }
1053
1054
        foreach ($this->documentRepository->findAll() as $document) {
1055
            if (!$document->isTemporary() && !$document->isSuggestion()) {
1056
                // index the document
1057
                $signalSlotDispatcher->dispatch(
1058
                    \EWW\Dpf\Controller\AbstractController::class,
1059
                    'indexDocument', [$document]
1060
                );
1061
            }
1062
        }
1063
    }
1064
1065
1066
    /**
1067
     * action uploadFiles
1068
     *
1069
     * @param string $documentIdentifier
1070
     * @return void
1071
     */
1072
    public function uploadFilesAction($documentIdentifier)
1073
    {
1074
        $document = $this->documentManager->read(
1075
            $documentIdentifier,
1076
            $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

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