Passed
Pull Request — master (#195)
by
unknown
07:40
created

ExternalMetadataImportController::retrieveAction()   D

Complexity

Conditions 12
Paths 360

Size

Total Lines 96
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 12
eloc 57
c 3
b 0
f 1
nc 360
nop 1
dl 0
loc 96
rs 4.2448

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\CrossRefMetadata;
18
use EWW\Dpf\Domain\Model\Document;
19
use EWW\Dpf\Domain\Model\PubMedMetadata;
20
use EWW\Dpf\Security\Security;
21
use EWW\Dpf\Domain\Workflow\DocumentWorkflow;
22
use TYPO3\CMS\Core\Messaging\AbstractMessage;
23
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
24
use EWW\Dpf\Domain\Model\ExternalMetadata;
25
use EWW\Dpf\Services\ImportExternalMetadata\Importer;
26
use EWW\Dpf\Services\ImportExternalMetadata\FileImporter;
27
use EWW\Dpf\Services\ImportExternalMetadata\CrossRefImporter;
28
use EWW\Dpf\Services\ImportExternalMetadata\DataCiteImporter;
29
use EWW\Dpf\Services\ImportExternalMetadata\PubMedImporter;
30
use EWW\Dpf\Services\ImportExternalMetadata\K10plusImporter;
31
use EWW\Dpf\Session\BulkImportSessionData;
32
use EWW\Dpf\Services\ImportExternalMetadata\BibTexFileImporter;
33
use EWW\Dpf\Services\ImportExternalMetadata\RisWosFileImporter;
34
use EWW\Dpf\Services\ImportExternalMetadata\RisReader;
35
36
37
/**
38
 * ExternalDataImportController
39
 */
40
class ExternalMetadataImportController extends AbstractController
41
{
42
    /**
43
     * ExternalMetadataRepository
44
     *
45
     * @var \EWW\Dpf\Domain\Repository\ExternalMetadataRepository
46
     * @inject
47
     */
48
    protected $externalMetadataRepository = null;
49
50
    /**
51
     * documentRepository
52
     *
53
     * @var \EWW\Dpf\Domain\Repository\DocumentRepository
54
     * @inject
55
     */
56
    protected $documentRepository = null;
57
58
    /**
59
     * documentTypeRepository
60
     *
61
     * @var \EWW\Dpf\Domain\Repository\DocumentTypeRepository
62
     * @inject
63
     */
64
    protected $documentTypeRepository = null;
65
66
    /**
67
     * persistence manager
68
     *
69
     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
70
     * @inject
71
     */
72
    protected $persistenceManager;
73
74
    /**
75
     * elasticSearch
76
     *
77
     * @var \EWW\Dpf\Services\ElasticSearch\ElasticSearch
78
     * @inject
79
     */
80
    protected $elasticSearch = null;
81
82
    /**
83
     * queryBuilder
84
     *
85
     * @var \EWW\Dpf\Services\ElasticSearch\QueryBuilder
86
     * @inject
87
     */
88
    protected $queryBuilder = null;
89
90
    /**
91
     * bookmarkRepository
92
     *
93
     * @var \EWW\Dpf\Domain\Repository\BookmarkRepository
94
     * @inject
95
     */
96
    protected $bookmarkRepository = null;
97
98
    /**
99
     * workflow
100
     *
101
     * @var \EWW\Dpf\Domain\Workflow\DocumentWorkflow
102
     */
103
    protected $workflow;
104
105
    /**
106
     * metadataGroupRepository
107
     *
108
     * @var \EWW\Dpf\Domain\Repository\MetadataGroupRepository
109
     * @inject
110
     */
111
    protected $metadataGroupRepository;
112
113
114
    /**
115
     * DocumentController constructor.
116
     */
117
    public function __construct()
118
    {
119
        parent::__construct();
120
    }
121
122
    /**
123
     * @param string $crossRefQuery
124
     * @param string $pubMedQuery
125
     */
126
    public function bulkStartAction($crossRefQuery = '', $pubMedQuery = '')
127
    {
128
        /** @var BulkImportSessionData $bulkImportSessionData */
129
        $bulkImportSessionData = $this->session->getBulkImportData();
130
131
        $crossRefAuthorSearch = $bulkImportSessionData->getCrossRefSearchField() === 'author';
132
        $pubMedAuthorSearch = $bulkImportSessionData->getPubMedSearchField() === 'author';
133
134
        $this->externalMetadataRepository->clearExternalMetadataByFeUserUid($this->security->getUser()->getUid());
135
        $this->view->assign('crossRefAuthorSearch', $crossRefAuthorSearch);
136
        $this->view->assign('pubMedAuthorSearch', $pubMedAuthorSearch);
137
        $this->view->assign('crossRefQuery', $crossRefQuery);
138
        $this->view->assign('pubMedQuery', $pubMedQuery);
139
    }
140
141
    /**
142
     * @param string $query
143
     */
144
    public function bulkSearchCrossRefAction($query = '')
145
    {
146
        /** @var BulkImportSessionData $bulkImportSessionData */
147
        $bulkImportSessionData = $this->session->getBulkImportData();
148
149
        $currentPage = null;
150
        $pagination = $this->getParametersSafely('@widget_0');
151
        if ($pagination) {
152
            $currentPage = $pagination['currentPage'];
153
            $query = $bulkImportSessionData->getCrossRefQuery();
154
        } else {
155
            if (empty($query)) {
156
                $this->redirect('bulkStart');
157
            }
158
159
            $bulkImportSessionData->setCrossRefQuery($query);
160
            $currentPage = 1;
161
        }
162
163
        $offset = empty($currentPage)? 0 : ($currentPage-1) * $this->itemsPerPage();
164
165
        /** @var Importer $importer */
166
        $importer = $this->objectManager->get(CrossRefImporter::class);
167
        $results = $importer->search(
168
            $query,
169
            $this->itemsPerPage(),
0 ignored issues
show
Unused Code introduced by
The call to EWW\Dpf\Services\ImportE...data\Importer::search() has too many arguments starting with $this->itemsPerPage(). ( Ignorable by Annotation )

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

169
        /** @scrutinizer ignore-call */ 
170
        $results = $importer->search(

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...
170
            $offset,
171
            $bulkImportSessionData->getCrossRefSearchField()
172
        );
173
174
        $bulkImportSessionData->setCurrentMetadataItems(($results? $results['items'] : []));
175
        $this->session->setBulkImportData($bulkImportSessionData);
176
177
        if ($results) {
178
            $this->forward(
179
                'bulkResults',
180
                null,
181
                null,
182
                [
183
                    'results' => $results,
184
                    'query' => $query,
185
                    'importSourceName' => 'Crossref',
186
                    'currentPage' => $currentPage
187
                ]
188
            );
189
        } else {
190
191
            $message = LocalizationUtility::translate(
192
                'manager.importMetadata.nothingFound', 'dpf'
193
            );
194
195
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
196
197
            $this->forward(
198
                'bulkStart',
199
                null,
200
                null,
201
                [
202
                    'crossRefQuery' => $bulkImportSessionData->getCrossRefQuery()
203
                ]
204
            );
205
        }
206
    }
207
208
    /**
209
     * @param string $query
210
     */
211
    public function bulkSearchPubMedAction($query = '')
212
    {
213
        /** @var BulkImportSessionData $bulkImportSessionData */
214
        $bulkImportSessionData = $this->session->getBulkImportData();
215
216
        $currentPage = null;
217
        $pagination = $this->getParametersSafely('@widget_0');
218
        if ($pagination) {
219
            $currentPage = $pagination['currentPage'];
220
            $query = $bulkImportSessionData->getPubMedQuery();
221
        } else {
222
            if (empty($query)) {
223
                $this->redirect('bulkStart');
224
            }
225
226
            $bulkImportSessionData->setPubMedQuery($query);
227
            $currentPage = 1;
228
        }
229
230
        $offset = empty($currentPage)? 0 : ($currentPage-1) * $this->itemsPerPage();
231
232
        /** @var Importer $importer */
233
        $importer = $this->objectManager->get(PubMedImporter::class);
234
        $results = $importer->search(
235
            $query,
236
            $this->itemsPerPage(),
0 ignored issues
show
Unused Code introduced by
The call to EWW\Dpf\Services\ImportE...data\Importer::search() has too many arguments starting with $this->itemsPerPage(). ( Ignorable by Annotation )

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

236
        /** @scrutinizer ignore-call */ 
237
        $results = $importer->search(

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...
237
            $offset,
238
            $bulkImportSessionData->getPubMedSearchField()
239
        );
240
241
        $bulkImportSessionData->setCurrentMetadataItems(($results? $results['items'] : []));
242
        $this->session->setBulkImportData($bulkImportSessionData);
243
244
        if ($results) {
245
            $this->forward(
246
                'bulkResults',
247
                null,
248
                null,
249
                [
250
                    'results' => $results,
251
                    'query' => $query,
252
                    'importSourceName' => 'PubMed',
253
                    'currentPage' => $currentPage
254
                ]
255
            );
256
        } else {
257
258
            $message = LocalizationUtility::translate(
259
                'manager.importMetadata.nothingFound', 'dpf'
260
            );
261
262
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
263
264
            $this->forward(
265
                'bulkStart',
266
                null,
267
                null,
268
                [
269
                    'pubMedQuery' => $bulkImportSessionData->getPubMedQuery()
270
                ]
271
            );
272
        }
273
    }
274
275
    /**
276
     * @param string $importSourceName
277
     * @param string $query
278
     * @param array $results
279
     * @param int $currentPage
280
     */
281
    public function bulkResultsAction($importSourceName, $query, $results = null, $currentPage = 1)
282
    {
283
        $externalMetadata = $this->externalMetadataRepository->findByFeUser($this->security->getUser()->getUid());
0 ignored issues
show
Bug introduced by
The method findByFeUser() does not exist on EWW\Dpf\Domain\Repositor...ernalMetadataRepository. 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

283
        /** @scrutinizer ignore-call */ 
284
        $externalMetadata = $this->externalMetadataRepository->findByFeUser($this->security->getUser()->getUid());
Loading history...
284
        $checkedPublicationIdentifiers = [];
285
286
        /** @var ExternalMetadata $data */
287
        foreach ($externalMetadata as $data) {
288
            $checkedPublicationIdentifiers[] = $data->getPublicationIdentifier();
289
        }
290
291
        $this->view->assign('importSourceName', $importSourceName);
292
        $this->view->assign('totalResults', $results['total-results']);
293
        $this->view->assign('itemsPerPage', $this->itemsPerPage());
294
        $this->view->assign('currentPage', $currentPage);
295
        $this->view->assign('query', $query);
296
        $this->view->assign('checkedPublicationIdentifiers', $checkedPublicationIdentifiers);
297
        $this->view->assign('results', $results);
298
    }
299
300
    /**
301
     *
302
     */
303
    function bulkImportAction()
304
    {
305
        $importCounter = ['imported' => 0, 'bookmarked' => 0, 'total' => 0];
306
307
        try {
308
            $externalMetadata = $this->externalMetadataRepository->findByFeUser($this->security->getUser()->getUid());
309
310
            $importedDocuments = [];
311
            $importedDocumentIdentifiers = [];
312
313
            /** @var ExternalMetadata $externalMetadataItem */
314
            foreach ($externalMetadata as $externalMetadataItem) {
315
316
                /** @var  Importer $importer */
317
                $importer = $this->objectManager->get($externalMetadataItem->getSource());
318
319
                // Check if the publication already exists in kitodo
320
                if ($this->findDocumentInKitodo($externalMetadataItem->getPublicationIdentifier())) {
321
                    $existingWorkspaceDocument = $this->findDocumentInWorkspace(
322
                        $externalMetadataItem->getPublicationIdentifier()
323
                    );
324
                    if (empty($existingWorkspaceDocument)) {
325
                        $this->bookmarkRepository->addBookmark(
326
                            $existingWorkspaceDocument['_id'],
327
                            $this->security->getUser()->getUid()
328
                        );
329
                        $importCounter['bookmarked'] += 1;
330
                    }
331
332
                } else {
333
334
                    if (!$this->findDocumentInWorkspace($externalMetadataItem->getPublicationIdentifier())) {
335
                        /** @var Document $newDocument */
336
                        $newDocument = $importer->import($externalMetadataItem);
337
338
                        if ($newDocument instanceof Document) {
339
                            $this->documentRepository->add($newDocument);
340
                            $this->externalMetadataRepository->remove($externalMetadataItem);
341
                            $importedDocuments[] = $newDocument;
342
                            $importCounter['imported'] += 1;
343
                        }
344
                    }
345
                }
346
            }
347
348
            $this->persistenceManager->persistAll();
349
350
            // Documents can only be indexed after they have been persisted as we need a valid UID.
351
            /** @var Document $importedDocument */
352
            foreach ($importedDocuments as $importedDocument) {
353
                // index the document
354
                $this->signalSlotDispatcher->dispatch(
355
                    AbstractController::class, 'indexDocument', [$importedDocument]
356
                );
357
                $importedDocumentIdentifiers[] = $importedDocument->getDocumentIdentifier();
358
            }
359
360
            /** @var BulkImportSessionData $bulkImportSessionData */
361
            $bulkImportSessionData = $this->session->getBulkImportData();
362
            $bulkImportSessionData->setLatestImportIdentifiers($importedDocumentIdentifiers);
363
            $this->session->setBulkImportData($bulkImportSessionData);
364
365
        } catch(\Throwable $throwable) {
366
            $this->logger->error($throwable->getMessage());
367
368
            $message = LocalizationUtility::translate(
369
                'manager.importMetadata.publicationNotImported', 'dpf'
370
            );
371
372
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
373
        }
374
375
        $this->redirect(
376
            'bulkImportedDocuments',
377
            null,
378
            null,
379
            ['from' => 0, 'importCounter' => $importCounter]);
380
    }
381
382
    /**
383
     * Cancels the bulk import result list view.
384
     *
385
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
386
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
387
     */
388
    function cancelBulkImportAction()
389
    {
390
        $this->redirect('bulkStart');
391
    }
392
393
394
    /**
395
     * Shows the form to find a publication by an identifier
396
     * @param string $identifier
397
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
398
     */
399
    public function findAction($identifier = '')
400
    {
401
        $this->externalMetadataRepository->clearExternalMetadataByFeUserUid($this->security->getUser()->getUid());
402
        $this->view->assign('identifier', $identifier);
403
    }
404
405
    /**
406
     * Retrieves and caches the the metadata related to the given identifier.
407
     *
408
     * @param string $identifier
409
     */
410
    public function retrieveAction($identifier)
411
    {
412
        $identifier = trim($identifier);
413
414
        if (empty($identifier)) {
415
            $this->redirect('find');
416
        }
417
418
        // Check if the document already exists in the workspace or my publications,
419
        // if this is the case, nothing will be imported, the find results will be shown again
420
        // and an error message will be displayed.
421
        if ($this->findDocumentInWorkspace($identifier)) {
422
            if ($this->security->getUser()->getUserRole() == Security::ROLE_LIBRARIAN) {
423
                $message = LocalizationUtility::translate(
424
                    'manager.importMetadata.alreadyInWorkspace', 'dpf'
425
                );
426
            } else {
427
                $message = LocalizationUtility::translate(
428
                    'manager.importMetadata.alreadyInMyPublications', 'dpf'
429
                );
430
            }
431
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
432
433
            $this->redirect('find', null, null, ['identifier' => $identifier]);
434
        }
435
436
        // Check if the document already exists in kitodo.
437
        /** @var array $existingDocument */
438
        if ($existingDocument = $this->findDocumentInKitodo($identifier)) {
439
440
            $this->bookmarkRepository->addBookmark(
441
                $existingDocument['_id'],
442
                $this->security->getUser()->getUid()
443
            );
444
445
            if ($this->security->getUser()->getUserRole() == Security::ROLE_LIBRARIAN) {
446
                $message = LocalizationUtility::translate(
447
                    'manager.importMetadata.alreadyInSystemWorkspace', 'dpf'
448
                );
449
            } else {
450
                $message = LocalizationUtility::translate(
451
                    'manager.importMetadata.alreadyInSystemMyPublications', 'dpf'
452
                );
453
            }
454
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
455
456
            $this->redirect('find', null, null, ['identifier' => $identifier]);
457
        }
458
459
        /** @var \EWW\Dpf\Services\ImportExternalMetadata\Importer $importer */
460
        $importer = null;
461
462
        // Choose the right data provider depending on the identifier type and retrieve the metadata.
463
        $identifierType = $this->determineIdentifierType($identifier);
464
465
        if ($identifierType === 'DOI') {
466
            $importer = $this->objectManager->get(CrossRefImporter::class);
467
            $externalMetadata = $importer->findByIdentifier($identifier);
468
            if (!$externalMetadata) {
469
                $importer = $this->objectManager->get(DataCiteImporter::class);
470
                $externalMetadata = $importer->findByIdentifier($identifier);
471
            }
472
        } elseif ($identifierType === 'PMID') {
473
            $importer = $this->objectManager->get(PubMedImporter::class);
474
            $externalMetadata = $importer->findByIdentifier($identifier);
475
        } elseif ($identifierType === 'ISBN') {
476
            $importer = $this->objectManager->get(K10plusImporter::class);
477
            $externalMetadata = $importer->findByIdentifier(str_replace('- ', '', $identifier));
478
        } else {
479
            $externalMetadata = null;
480
        }
481
482
        if ($externalMetadata) {
483
            // Save the metadata for further processing
484
            $this->externalMetadataRepository->add($externalMetadata);
485
            $this->persistenceManager->persistAll();
486
        }
487
488
        if ($externalMetadata) {
489
            $this->redirect(
490
                'import',
491
                null,
492
                null,
493
                ['externalMetadata'=>$externalMetadata]
494
            );
495
        } else {
496
            $message = LocalizationUtility::translate(
497
                'manager.importMetadata.nothingFound', 'dpf'
498
            );
499
500
            $this->addFlashMessage(
501
                $message,
502
                '',
503
                AbstractMessage::ERROR
504
            );
505
            $this->redirect('find', null, null, ['identifier' => $identifier]);
506
        }
507
508
    }
509
510
    /**
511
     * The import dialog
512
     *
513
     * @param ExternalMetadata $externalMetadata
514
     */
515
    public function importAction(ExternalMetadata $externalMetadata)
516
    {
517
        $this->view->assign('identifierType', $this->determineIdentifierType($externalMetadata->getPublicationIdentifier()));
518
        $this->view->assign('externalMetadata', $externalMetadata);
519
    }
520
521
    /**
522
     * @param ExternalMetadata $externalMetadata
523
     */
524
    public function createDocumentAction(ExternalMetadata $externalMetadata)
525
    {
526
        /** @var  Importer $importer */
527
        $importer = $this->objectManager->get($externalMetadata->getSource());
528
529
530
        try {
531
            /** @var Document $newDocument */
532
            $newDocument = $importer->import($externalMetadata);
533
534
            if ($newDocument instanceof Document) {
0 ignored issues
show
introduced by
$newDocument is always a sub-type of EWW\Dpf\Domain\Model\Document.
Loading history...
535
536
                $this->documentRepository->add($newDocument);
537
                $this->persistenceManager->persistAll();
538
539
                // index the document
540
                $this->signalSlotDispatcher->dispatch(
541
                    AbstractController::class, 'indexDocument', [$newDocument]
542
                );
543
544
                $this->externalMetadataRepository->remove($externalMetadata);
545
546
                if ($this->security->getUser()->getUserRole() == Security::ROLE_LIBRARIAN) {
547
                    $message = LocalizationUtility::translate(
548
                        'manager.importMetadata.publicationAddedToWorkspace', 'dpf'
549
                    );
550
                } else {
551
                    $message = LocalizationUtility::translate(
552
                        'manager.importMetadata.publicationAddedToMyPublications', 'dpf'
553
                    );
554
                }
555
                $this->addFlashMessage($message, '', AbstractMessage::OK);
556
557
                $this->redirect('showDetails', 'Document', null, ['document' => $newDocument]);
558
559
            } else {
560
                $message = LocalizationUtility::translate(
561
                    'manager.importMetadata.publicationNotImported', 'dpf'
562
                );
563
564
                $this->addFlashMessage($message, '', AbstractMessage::ERROR);
565
                $this->redirect('find');
566
            }
567
568
        } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $e) {
569
            // A redirect always throws this exception, but in this case, however,
570
            // redirection is desired and should not lead to an exception handling
571
        } catch(\Throwable $throwable) {
572
573
            $this->logger->error($throwable->getMessage());
574
575
            $message = LocalizationUtility::translate(
576
                'manager.importMetadata.publicationNotImported', 'dpf'
577
            );
578
579
           $this->addFlashMessage($message, '', AbstractMessage::ERROR);
580
           $this->redirect('find');
581
        }
582
    }
583
584
    /**
585
     * Determines whether the identifier is a DOI, ISBN or PMID.
586
     *
587
     * @param $identifier
588
     * @return null|string
589
     */
590
    protected function determineIdentifierType($identifier)
591
    {
592
        // DOI
593
        if (strpos($identifier,'10.') === 0) {
594
            return 'DOI';
595
        }
596
597
        // ISBN
598
        $length = strlen(str_replace(['-',' '], '', $identifier));
599
600
        if ($length === 13) {
601
            if (strpos($identifier, '978') === 0 ||  strpos($identifier, '979') === 0) {
602
                return 'ISBN';
603
            }
604
        }
605
606
        if ($length === 10) {
607
            return 'ISBN';
608
        }
609
610
        // PMID
611
        if (is_numeric($identifier) && intval($identifier) == $identifier) {
612
            if (strlen($identifier) < 10) {
613
                return 'PMID';
614
            }
615
        }
616
617
        return null;
618
    }
619
620
    /**
621
     * Finds a document with the given $identifier in the current users "Workspace" or "My publicstions"
622
     *
623
     * @param $identifier
624
     * @return array
625
     */
626
    protected function findDocumentInWorkspace($identifier)
627
    {
628
        $bookmarkIdentifiers = [];
629
        foreach ($this->bookmarkRepository->findByFeUserUid($this->security->getUser()->getUid()) as $bookmark) {
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

629
        foreach ($this->bookmarkRepository->/** @scrutinizer ignore-call */ findByFeUserUid($this->security->getUser()->getUid()) as $bookmark) {
Loading history...
630
            $bookmarkIdentifiers[] = $bookmark->getDocumentIdentifier();
631
        }
632
633
        if ($this->security->getUser()->getUserRole() == Security::ROLE_LIBRARIAN) {
634
            // "Workspace" of a librarian
635
            $workspaceFilter = [
636
                'bool' => [
637
                    'must' => [
638
                        [
639
                            'bool' => [
640
                                'must' => [
641
                                    [
642
                                        'term' => [
643
                                            'creator' => $this->security->getUser()->getUid()
644
                                        ]
645
                                    ],
646
                                    [
647
                                        'bool' => [
648
                                            'should' => [
649
                                                [
650
                                                    'term' => [
651
                                                        'state' => DocumentWorkflow::STATE_NEW_NONE
652
                                                    ]
653
                                                ]
654
                                            ]
655
                                        ]
656
                                    ]
657
                                ]
658
                            ]
659
                        ]
660
                    ]
661
                ]
662
            ];
663
        } else {
664
            // "My publications" of a researcher
665
            $workspaceFilter = [
666
                'bool' => [
667
                    'must' => [
668
                        [
669
                            'term' => [
670
                                'creator' => $this->security->getUser()->getUid()
671
                            ]
672
                        ]
673
                    ]
674
                ]
675
            ];
676
        }
677
678
        $query = $this->queryBuilder->buildQuery(
679
            1, $workspaceFilter, 0,
680
            $bookmarkIdentifiers, [], [], null, null,
681
            'identifier:"'.$identifier.'"'
682
        );
683
684
        try {
685
686
            $results =  $this->elasticSearch->search($query, 'object');
687
            if (is_array($results) && $results['hits']['total']['value'] > 0) {
688
                return $results['hits']['hits'][0];
689
            }
690
691
        } catch (\Exception $e) {
692
693
            $message = LocalizationUtility::translate(
694
                'manager.importMetadata.searchError', 'dpf'
695
            );
696
697
            $this->addFlashMessage(
698
                $message, '', AbstractMessage::ERROR
699
            );
700
        }
701
702
        return [];
703
    }
704
705
    /**
706
     * Finds a document with the given $identifier in the kitodo index
707
     *
708
     * @param $identifier
709
     * @return array
710
     */
711
    protected function findDocumentInKitodo($identifier) {
712
713
        $workspaceFilter = [
714
            'bool' => [
715
                'must_not' => [
716
                    [
717
                        'term' => [
718
                            'state' => DocumentWorkflow::STATE_NEW_NONE
719
                        ]
720
                    ]
721
                ]
722
            ]
723
        ];
724
725
        // Search if the document already exists in kitodo.
726
        $query = $this->queryBuilder->buildQuery(
727
            1, $workspaceFilter , 0, [], [], [], null, null, 'identifier:"'.$identifier.'"'
728
        );
729
        $results = $this->elasticSearch->search($query, 'object');
730
731
        if (is_array($results) && $results['hits']['total']['value'] > 0) {
732
            return $results['hits']['hits'][0];
733
        }
734
735
        return [];
736
    }
737
738
    /**
739
     * @param array $importCounter
740
     */
741
    public function bulkImportedDocumentsAction($importCounter = ['imported' => 0, 'bookmarked' => 0, 'total' => 0])
742
    {
743
744
        $publicationSingular = LocalizationUtility::translate('manager.importMetadata.publication.singular', 'dpf');
745
        $publicationPlural = LocalizationUtility::translate('manager.importMetadata.publication.plural', 'dpf');
746
747
        if ($this->security->getUser()->getUserRole() === Security::ROLE_LIBRARIAN) {
748
            $messageKey = 'manager.bulkImport.importMessage.libarian';
749
        } else {
750
            $messageKey = 'manager.bulkImport.importMessage.researcher';
751
        }
752
753
        $message = LocalizationUtility::translate(
754
            $messageKey,
755
            'dpf',
756
            [
757
                0 => $importCounter['imported'],
758
                1 => ($importCounter['imported'] == 1? $publicationSingular : $publicationPlural),
759
                2 => $importCounter['bookmarked'],
760
                3 => ($importCounter['bookmarked'] == 1? $publicationSingular : $publicationPlural)
761
            ]
762
        );
763
764
        if ($importCounter['imported'] > 0 || $importCounter['bookmarked'] > 0) {
765
            $severity = AbstractMessage::INFO;
766
        } else {
767
            $severity = AbstractMessage::WARNING;
768
        }
769
770
        $this->addFlashMessage(
771
            $message, '', $severity
772
        );
773
774
        if ($importCounter['imported'] > 0 || $importCounter['bookmarked'] > 0) {
775
            if ($this->security->getUser()->getUserRole() != Security::ROLE_LIBRARIAN) {
776
                $importNoteMessage = LocalizationUtility::translate('manager.bulkImport.importNote', 'dpf');
777
                $this->addFlashMessage(
778
                    $importNoteMessage, '', AbstractMessage::INFO
779
                );
780
            }
781
        }
782
783
        $this->showImportedDocuments($importCounter);
0 ignored issues
show
Unused Code introduced by
The call to EWW\Dpf\Controller\Exter...showImportedDocuments() has too many arguments starting with $importCounter. ( Ignorable by Annotation )

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

783
        $this->/** @scrutinizer ignore-call */ 
784
               showImportedDocuments($importCounter);

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...
784
    }
785
786
    /**
787
     *
788
     */
789
    protected function showImportedDocuments()
790
    {
791
        $this->session->setStoredAction($this->getCurrentAction(), $this->getCurrentController(),
792
            $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

792
            $this->uriBuilder->getRequest()->/** @scrutinizer ignore-call */ getRequestUri()
Loading history...
793
        );
794
795
        $currentPage = null;
796
        $pagination = $this->getParametersSafely('@widget_0');
797
        if ($pagination) {
798
            $currentPage = $pagination['currentPage'];
799
        } else {
800
            $currentPage = 1;
801
        }
802
803
        // \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($test);
804
805
        /** @var BulkImportSessionData $bulkImportSessionData */
806
        $bulkImportSessionData = $this->session->getBulkImportData();
807
        $importedIdentifiers = $bulkImportSessionData->getLatestImportIdentifiers();
808
809
        $workspaceFilter = [
810
            'bool' => [
811
                'must' => [
812
                    [
813
                        'terms' => [
814
                            '_id' => array_values(array_filter($importedIdentifiers))
815
                        ]
816
                    ]
817
                ]
818
            ]
819
        ];
820
821
        $query = $this->queryBuilder->buildQuery(
822
            $this->itemsPerPage(),
823
            $workspaceFilter,
824
            (empty($currentPage)? 0 : ($currentPage-1) * $this->itemsPerPage())
825
        );
826
827
        try {
828
            $results = $this->elasticSearch->search($query, 'object');
829
            $this->view->assign('currentPage', $currentPage);
830
            $this->view->assign('documentCount', $results['hits']['total']['value']);
831
            $this->view->assign('documents', $results['hits']['hits']);
832
            $this->view->assign('itemsPerPage', $this->itemsPerPage());
833
            $this->view->assign('currentFisPersId', $this->security->getUser()->getFisPersId());
834
835
            $personGroup = $this->metadataGroupRepository->findPersonGroup();
836
            $this->view->assign('personGroup', $personGroup->getUid());
837
838
        } catch (\Throwable $e) {
839
840
            $message = LocalizationUtility::translate(
841
                'manager.importMetadata.searchError', 'dpf'
842
            );
843
844
            $this->addFlashMessage(
845
                $message, '', AbstractMessage::ERROR
846
            );
847
        }
848
    }
849
850
    /**
851
     * Returns the number of items to be shown per page.
852
     *
853
     * @return int
854
     */
855
    protected function itemsPerPage()
856
    {
857
        /** @var BulkImportSessionData $bulkImportSessionData */
858
        $bulkImportSessionData = $this->session->getBulkImportData();
859
860
        if ($bulkImportSessionData->getItemsPerPage()) {
861
            return $bulkImportSessionData->getItemsPerPage();
862
        }
863
864
        if ($this->settings['bulkImportPagination']['itemsPerPage']) {
865
            return $this->settings['bulkImportPagination']['itemsPerPage'];
866
        }
867
868
        return 10;
869
    }
870
871
    /**
872
     * @param string $error
873
     */
874
    public function uploadStartAction($error = '')
875
    {
876
        switch ($error) {
877
            case 'INVALID_FORMAT':
878
                $message = LocalizationUtility::translate(
879
                    'manager.uploadImport.invalidFormat', 'dpf'
880
                );
881
                $this->addFlashMessage($message, '', AbstractMessage::ERROR);
882
                break;
883
            case 'UPLOAD_ERROR':
884
                $message = LocalizationUtility::translate(
885
                    'manager.uploadImport.uploadError', 'dpf'
886
                );
887
                $this->addFlashMessage($message, '', AbstractMessage::ERROR);
888
                break;
889
        }
890
891
        $this->externalMetadataRepository->clearExternalMetadataByFeUserUid($this->security->getUser()->getUid());
892
    }
893
894
    /**
895
     * @param string $fileType (bibtex or riswos)
896
     * @param array $uploadFile
897
     */
898
    public function uploadImportFileAction($fileType, $uploadFile = [])
899
    {
900
        $this->externalMetadataRepository->clearExternalMetadataByFeUserUid($this->security->getUser()->getUid());
901
902
        $uploadFileUrl = new \EWW\Dpf\Helper\UploadFileUrl;
903
        $uploadFilePath = PATH_site . $uploadFileUrl->getDirectory() . "/importFile.".md5($this->security->getUser()->getUid());
904
905
        if ($uploadFile['error'] === UPLOAD_ERR_OK) {
906
            \TYPO3\CMS\Core\Utility\GeneralUtility::upload_copy_move($uploadFile['tmp_name'], $uploadFilePath);
907
            //$finfo       = finfo_open(FILEINFO_MIME_TYPE);
908
            //$contentType = finfo_file($finfo, $uploadFilePath);
909
            //finfo_close($finfo);
910
        } elseif ($uploadFile['error'] == UPLOAD_ERR_NO_FILE) {
911
            $this->redirect('uploadStart');
912
        } else {
913
            $this->redirect('uploadStart', null, null, ['error' => 'UPLOAD_ERROR']);
914
        }
915
916
        try {
917
918
            if ($fileType == 'bibtex') {
919
                /** @var FileImporter $fileImporter */
920
                $fileImporter = $this->objectManager->get(BibTexFileImporter::class);
921
                $results = $fileImporter->loadFile($uploadFilePath, $this->settings['bibTexMandatoryFields']);
922
            } elseif ($fileType == 'riswos') {
923
                /** @var FileImporter $fileImporter */
924
                $fileImporter = $this->objectManager->get(RisWosFileImporter::class);
925
                $results = $fileImporter->loadFile($uploadFilePath, $this->settings['riswosMandatoryFields']);
926
            } else {
927
                $results = [];
928
            }
929
930
            foreach ($results as $externalMetadata) {
931
                $this->externalMetadataRepository->add($externalMetadata);
932
            }
933
934
            if ($mandatoryErrors = $fileImporter->getMandatoryErrors()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $fileImporter does not seem to be defined for all execution paths leading up to this point.
Loading history...
935
                foreach (
936
                    $mandatoryErrors as $mandatoryError
937
                ) {
938
                    $message = 'Konnte die Publikation Nr. ' . $mandatoryError['index'] . ' nicht importieren';
939
                    $message .= $mandatoryError['title'] ? ' (' . $mandatoryError['title'] . ')' : '';
940
                    $message .= ', da die folgenden Felder leer sind: ' . implode(',', $mandatoryError['fields']);
941
                    $this->addFlashMessage($message, '', AbstractMessage::ERROR);
942
                }
943
            } elseif ($results) {
944
                    $this->redirect(
945
                        'importUploadedData',
946
                        null,
947
                        null,
948
                        ['uploadFilePath' => $uploadFilePath]
949
                    );
950
            } else {
951
                $this->redirect('uploadStart', null, null, ['error' => 'INVALID_FORMAT']);
952
            }
953
        } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $exception) {
954
            // A redirect always throws this exception, but in this case, however,
955
            // redirection is desired and should not lead to an exception handling
956
        } catch (\RenanBr\BibTexParser\Exception\ParserException $exception) {
957
            $this->redirect('uploadStart', null, null, ['error' => 'INVALID_FORMAT']);
958
        }
959
960
    }
961
962
    /**
963
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
964
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
965
     */
966
    public function importUploadedDataAction()
967
    {
968
        try {
969
            $externalMetadata = $this->externalMetadataRepository->findByFeUser($this->security->getUser()->getUid());
970
971
            $importedDocuments = [];
972
            $importedDocumentIdentifiers = [];
973
974
            /** @var ExternalMetadata $externalMetadataItem */
975
            foreach ($externalMetadata as $externalMetadataItem) {
976
977
                /** @var  Importer $importer */
978
                $importer = $this->objectManager->get($externalMetadataItem->getSource());
979
980
                /** @var Document $newDocument */
981
                $newDocument = $importer->import($externalMetadataItem);
982
983
                if ($newDocument instanceof Document) {
984
                    $this->documentRepository->add($newDocument);
985
                    $this->externalMetadataRepository->remove($externalMetadataItem);
986
                    $importedDocuments[] = $newDocument;
987
                }
988
            }
989
990
            $this->persistenceManager->persistAll();
991
992
            // Documents can only be indexed after they have been persisted as we need a valid UID.
993
            /** @var Document $importedDocument */
994
            foreach ($importedDocuments as $importedDocument) {
995
                // index the document
996
                $this->signalSlotDispatcher->dispatch(
997
                    AbstractController::class, 'indexDocument', [$importedDocument]
998
                );
999
                $importedDocumentIdentifiers[] = $importedDocument->getDocumentIdentifier();
1000
            }
1001
1002
            /** @var BulkImportSessionData $bulkImportSessionData */
1003
            $bulkImportSessionData = $this->session->getBulkImportData();
1004
            $bulkImportSessionData->setLatestImportIdentifiers($importedDocumentIdentifiers);
1005
            $this->session->setBulkImportData($bulkImportSessionData);
1006
1007
        } catch(\Throwable $throwable) {
1008
1009
            throw $throwable;
1010
1011
            $this->logger->error($throwable->getMessage());
0 ignored issues
show
Unused Code introduced by
$this->logger->error($throwable->getMessage()) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1012
1013
            $message = LocalizationUtility::translate(
1014
                'manager.importMetadata.publicationNotImported', 'dpf'
1015
            );
1016
1017
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
1018
        }
1019
1020
        $this->redirect(
1021
            'uploadedDocuments',
1022
            null,
1023
            null,
1024
            ['from' => 0, 'importCounter' => sizeof($importedDocumentIdentifiers)]);
1025
    }
1026
1027
1028
    /**
1029
     * @param int $importCounter
1030
     */
1031
    public function uploadedDocumentsAction($importCounter = 0)
1032
    {
1033
        $publicationSingular = LocalizationUtility::translate('manager.importMetadata.publication.singular', 'dpf');
1034
        $publicationPlural = LocalizationUtility::translate('manager.importMetadata.publication.plural', 'dpf');
1035
1036
        if ($importCounter != 1) {
1037
            $messageKey = 'manager.uploadImport.importMessage.plural';
1038
        } else {
1039
            $messageKey = 'manager.uploadImport.importMessage.singular';
1040
        }
1041
1042
        $message = LocalizationUtility::translate(
1043
            $messageKey,
1044
            'dpf',
1045
            [
1046
                0 => $importCounter,
1047
                1 => ($importCounter == 1? $publicationSingular : $publicationPlural)
1048
            ]
1049
        );
1050
1051
        if ($importCounter > 0) {
1052
            $severity = AbstractMessage::INFO;
1053
            $this->addFlashMessage($message, '', $severity);
1054
1055
            if ($this->security->getUser()->getUserRole() != Security::ROLE_LIBRARIAN) {
1056
                $importNoteMessage = LocalizationUtility::translate('manager.uploadImport.importNote', 'dpf');
1057
                $this->addFlashMessage(
1058
                    $importNoteMessage, '', AbstractMessage::INFO
1059
                );
1060
            }
1061
            
1062
            $this->showImportedDocuments($importCounter);
0 ignored issues
show
Unused Code introduced by
The call to EWW\Dpf\Controller\Exter...showImportedDocuments() has too many arguments starting with $importCounter. ( Ignorable by Annotation )

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

1062
            $this->/** @scrutinizer ignore-call */ 
1063
                   showImportedDocuments($importCounter);

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...
1063
        } else {
1064
            $severity = AbstractMessage::WARNING;
1065
            $this->addFlashMessage($message, '', $severity);
1066
            $this->redirect('uploadStart');
1067
        }
1068
    }
1069
}
1070