Passed
Pull Request — master (#195)
by
unknown
06:45
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
use EWW\Dpf\Services\ImportExternalMetadata\PublicationIdentifier;
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 = PublicationIdentifier::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',
518
            PublicationIdentifier::determineIdentifierType($externalMetadata->getPublicationIdentifier())
519
        );
520
        $this->view->assign('externalMetadata', $externalMetadata);
521
    }
522
523
    /**
524
     * @param ExternalMetadata $externalMetadata
525
     */
526
    public function createDocumentAction(ExternalMetadata $externalMetadata)
527
    {
528
        /** @var  Importer $importer */
529
        $importer = $this->objectManager->get($externalMetadata->getSource());
530
531
532
        try {
533
            /** @var Document $newDocument */
534
            $newDocument = $importer->import($externalMetadata);
535
536
            if ($newDocument instanceof Document) {
0 ignored issues
show
introduced by
$newDocument is always a sub-type of EWW\Dpf\Domain\Model\Document.
Loading history...
537
538
                $this->documentRepository->add($newDocument);
539
                $this->persistenceManager->persistAll();
540
541
                // index the document
542
                $this->signalSlotDispatcher->dispatch(
543
                    AbstractController::class, 'indexDocument', [$newDocument]
544
                );
545
546
                $this->externalMetadataRepository->remove($externalMetadata);
547
548
                if ($this->security->getUser()->getUserRole() == Security::ROLE_LIBRARIAN) {
549
                    $message = LocalizationUtility::translate(
550
                        'manager.importMetadata.publicationAddedToWorkspace', 'dpf'
551
                    );
552
                } else {
553
                    $message = LocalizationUtility::translate(
554
                        'manager.importMetadata.publicationAddedToMyPublications', 'dpf'
555
                    );
556
                }
557
                $this->addFlashMessage($message, '', AbstractMessage::OK);
558
559
                $this->redirect('showDetails', 'Document', null, ['document' => $newDocument]);
560
561
            } else {
562
                $message = LocalizationUtility::translate(
563
                    'manager.importMetadata.publicationNotImported', 'dpf'
564
                );
565
566
                $this->addFlashMessage($message, '', AbstractMessage::ERROR);
567
                $this->redirect('find');
568
            }
569
570
        } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $e) {
571
            // A redirect always throws this exception, but in this case, however,
572
            // redirection is desired and should not lead to an exception handling
573
        } catch(\Throwable $throwable) {
574
575
            $this->logger->error($throwable->getMessage());
576
577
            $message = LocalizationUtility::translate(
578
                'manager.importMetadata.publicationNotImported', 'dpf'
579
            );
580
581
           $this->addFlashMessage($message, '', AbstractMessage::ERROR);
582
           $this->redirect('find');
583
        }
584
    }
585
586
    /**
587
     * Finds a document with the given $identifier in the current users "Workspace" or "My publicstions"
588
     *
589
     * @param $identifier
590
     * @return array
591
     */
592
    protected function findDocumentInWorkspace($identifier)
593
    {
594
        $bookmarkIdentifiers = [];
595
        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

595
        foreach ($this->bookmarkRepository->/** @scrutinizer ignore-call */ findByFeUserUid($this->security->getUser()->getUid()) as $bookmark) {
Loading history...
596
            $bookmarkIdentifiers[] = $bookmark->getDocumentIdentifier();
597
        }
598
599
        if ($this->security->getUser()->getUserRole() == Security::ROLE_LIBRARIAN) {
600
            // "Workspace" of a librarian
601
            $workspaceFilter = [
602
                'bool' => [
603
                    'must' => [
604
                        [
605
                            'bool' => [
606
                                'must' => [
607
                                    [
608
                                        'term' => [
609
                                            'creator' => $this->security->getUser()->getUid()
610
                                        ]
611
                                    ],
612
                                    [
613
                                        'bool' => [
614
                                            'should' => [
615
                                                [
616
                                                    'term' => [
617
                                                        'state' => DocumentWorkflow::STATE_NEW_NONE
618
                                                    ]
619
                                                ]
620
                                            ]
621
                                        ]
622
                                    ]
623
                                ]
624
                            ]
625
                        ]
626
                    ]
627
                ]
628
            ];
629
        } else {
630
            // "My publications" of a researcher
631
            $workspaceFilter = [
632
                'bool' => [
633
                    'must' => [
634
                        [
635
                            'term' => [
636
                                'creator' => $this->security->getUser()->getUid()
637
                            ]
638
                        ]
639
                    ]
640
                ]
641
            ];
642
        }
643
644
        $query = $this->queryBuilder->buildQuery(
645
            1, $workspaceFilter, 0,
646
            $bookmarkIdentifiers, [], [], null, null,
647
            'identifier:"'.$identifier.'"'
648
        );
649
650
        try {
651
652
            $results =  $this->elasticSearch->search($query, 'object');
653
            if (is_array($results) && $results['hits']['total']['value'] > 0) {
654
                return $results['hits']['hits'][0];
655
            }
656
657
        } catch (\Exception $e) {
658
659
            $message = LocalizationUtility::translate(
660
                'manager.importMetadata.searchError', 'dpf'
661
            );
662
663
            $this->addFlashMessage(
664
                $message, '', AbstractMessage::ERROR
665
            );
666
        }
667
668
        return [];
669
    }
670
671
    /**
672
     * Finds a document with the given $identifier in the kitodo index
673
     *
674
     * @param $identifier
675
     * @return array
676
     */
677
    protected function findDocumentInKitodo($identifier) {
678
679
        $workspaceFilter = [
680
            'bool' => [
681
                'must_not' => [
682
                    [
683
                        'term' => [
684
                            'state' => DocumentWorkflow::STATE_NEW_NONE
685
                        ]
686
                    ]
687
                ]
688
            ]
689
        ];
690
691
        // Search if the document already exists in kitodo.
692
        $query = $this->queryBuilder->buildQuery(
693
            1, $workspaceFilter , 0, [], [], [], null, null, 'identifier:"'.$identifier.'"'
694
        );
695
        $results = $this->elasticSearch->search($query, 'object');
696
697
        if (is_array($results) && $results['hits']['total']['value'] > 0) {
698
            return $results['hits']['hits'][0];
699
        }
700
701
        return [];
702
    }
703
704
    /**
705
     * @param array $importCounter
706
     */
707
    public function bulkImportedDocumentsAction($importCounter = ['imported' => 0, 'bookmarked' => 0, 'total' => 0])
708
    {
709
710
        $publicationSingular = LocalizationUtility::translate('manager.importMetadata.publication.singular', 'dpf');
711
        $publicationPlural = LocalizationUtility::translate('manager.importMetadata.publication.plural', 'dpf');
712
713
        if ($this->security->getUser()->getUserRole() === Security::ROLE_LIBRARIAN) {
714
            $messageKey = 'manager.bulkImport.importMessage.libarian';
715
        } else {
716
            $messageKey = 'manager.bulkImport.importMessage.researcher';
717
        }
718
719
        $message = LocalizationUtility::translate(
720
            $messageKey,
721
            'dpf',
722
            [
723
                0 => $importCounter['imported'],
724
                1 => ($importCounter['imported'] == 1? $publicationSingular : $publicationPlural),
725
                2 => $importCounter['bookmarked'],
726
                3 => ($importCounter['bookmarked'] == 1? $publicationSingular : $publicationPlural)
727
            ]
728
        );
729
730
        if ($importCounter['imported'] > 0 || $importCounter['bookmarked'] > 0) {
731
            $severity = AbstractMessage::INFO;
732
        } else {
733
            $severity = AbstractMessage::WARNING;
734
        }
735
736
        $this->addFlashMessage(
737
            $message, '', $severity
738
        );
739
740
        if ($importCounter['imported'] > 0 || $importCounter['bookmarked'] > 0) {
741
            if ($this->security->getUser()->getUserRole() != Security::ROLE_LIBRARIAN) {
742
                $importNoteMessage = LocalizationUtility::translate('manager.bulkImport.importNote', 'dpf');
743
                $this->addFlashMessage(
744
                    $importNoteMessage, '', AbstractMessage::INFO
745
                );
746
            }
747
        }
748
749
        $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

749
        $this->/** @scrutinizer ignore-call */ 
750
               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...
750
    }
751
752
    /**
753
     *
754
     */
755
    protected function showImportedDocuments()
756
    {
757
        $this->session->setStoredAction($this->getCurrentAction(), $this->getCurrentController(),
758
            $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

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

1028
            $this->/** @scrutinizer ignore-call */ 
1029
                   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...
1029
        } else {
1030
            $severity = AbstractMessage::WARNING;
1031
            $this->addFlashMessage($message, '', $severity);
1032
            $this->redirect('uploadStart');
1033
        }
1034
    }
1035
}
1036