Issues (3936)

Classes/Controller/SearchController.php (21 issues)

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\Services\ElasticSearch\ElasticSearch;
18
use EWW\Dpf\Exceptions\DPFExceptionInterface;
19
use EWW\Dpf\Security\DocumentVoter;
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\Session\SearchSessionData;
25
26
/**
27
 * SearchController
28
 */
29
class SearchController extends \EWW\Dpf\Controller\AbstractController
30
{
31
32
    /**
33
     * documentRepository
34
     *
35
     * @var \EWW\Dpf\Domain\Repository\DocumentRepository
36
     * @TYPO3\CMS\Extbase\Annotation\Inject
37
     */
38
    protected $documentRepository = null;
39
40
    /**
41
     * documenTypeRepository
42
     *
43
     * @var \EWW\Dpf\Domain\Repository\DocumentTypeRepository
44
     * @TYPO3\CMS\Extbase\Annotation\Inject
45
     */
46
    protected $documentTypeRepository;
47
48
    /**
49
     * clientRepository
50
     *
51
     * @var \EWW\Dpf\Domain\Repository\ClientRepository
52
     * @TYPO3\CMS\Extbase\Annotation\Inject
53
     */
54
    protected $clientRepository = null;
55
56
57
    /**
58
     * elasticSearch
59
     *
60
     * @var \EWW\Dpf\Services\ElasticSearch\ElasticSearch
61
     * @TYPO3\CMS\Extbase\Annotation\Inject
62
     */
63
    protected $elasticSearch = null;
64
65
66
    /**
67
     * queryBuilder
68
     *
69
     * @var \EWW\Dpf\Services\ElasticSearch\QueryBuilder
70
     * @TYPO3\CMS\Extbase\Annotation\Inject
71
     */
72
    protected $queryBuilder = null;
73
74
75
    /**
76
     * persistence manager
77
     *
78
     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
79
     * @TYPO3\CMS\Extbase\Annotation\Inject
80
     */
81
    protected $persistenceManager;
82
83
84
    /**
85
     * bookmarkRepository
86
     *
87
     * @var \EWW\Dpf\Domain\Repository\BookmarkRepository
88
     * @TYPO3\CMS\Extbase\Annotation\Inject
89
     */
90
    protected $bookmarkRepository = null;
91
92
    /**
93
     * fisDataService
94
     *
95
     * @var \EWW\Dpf\Services\FeUser\FisDataService
96
     * @TYPO3\CMS\Extbase\Annotation\Inject
97
     */
98
    protected $fisDataService = null;
99
100
    /**
101
     * metadataGroupRepository
102
     *
103
     * @var \EWW\Dpf\Domain\Repository\MetadataGroupRepository
104
     * @TYPO3\CMS\Extbase\Annotation\Inject
105
     */
106
    protected $metadataGroupRepository;
107
108
    const RESULT_COUNT      = 500;
109
    const NEXT_RESULT_COUNT = 500;
110
111
    /**
112
     * list
113
     *
114
     * @param int $from
115
     * @param int $queryString
116
     *
117
     * @return void
118
     */
119
    protected function list($from = 0, $queryString = '')
120
    {
121
        /** @var SearchSessionData $workspaceSessionData */
122
        $workspaceSessionData = $this->session->getWorkspaceData();
123
        $filters = $workspaceSessionData->getFilters();
124
        $excludeFilters = $workspaceSessionData->getExcludeFilters();
125
126
        if (array_key_exists('bookmarks', $excludeFilters)) {
127
            unset($excludeFilters['bookmarks']);
128
        }
129
130
        $sortField = $workspaceSessionData->getSortField();
131
        $sortOrder = $workspaceSessionData->getSortOrder();
132
133
        if ($this->security->getUserRole() == Security::ROLE_LIBRARIAN) {
134
            $query = $this->getSearchQuery($from, [],
135
                $filters, $excludeFilters, $sortField, $sortOrder, $queryString);
136
        } elseif ($this->security->getUserRole() == Security::ROLE_RESEARCHER) {
137
            $query = $this->getSearchQuery($from, [],
138
                $filters, $excludeFilters, $sortField, $sortOrder, $queryString);
139
        }
140
141
        try {
142
            $results = $this->elasticSearch->search($query, 'object');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $query does not seem to be defined for all execution paths leading up to this point.
Loading history...
143
        } catch (\Exception $e) {
144
            $workspaceSessionData->clearSort();
145
            $workspaceSessionData->clearFilters();
146
            $this->session->setWorkspaceData($workspaceSessionData);
147
148
            $this->addFlashMessage(
149
                "Error while building the list!", '', AbstractMessage::ERROR
150
            );
151
        }
152
153
        if ($this->request->hasArgument('message')) {
154
            $this->view->assign('message', $this->request->getArgument('message'));
155
        }
156
157
        if ($this->request->hasArgument('errorFiles')) {
158
            $this->view->assign('errorFiles', $this->request->getArgument('errorFiles'));
159
        }
160
161
162
        $this->view->assign('documentCount', $results['hits']['total']['value']);
163
        $this->view->assign('documents', $results['hits']['hits']);
164
        $this->view->assign('pages', range(1, $results['hits']['total']['value']));
165
        $this->view->assign('itemsPerPage', $this->itemsPerPage());
166
        $this->view->assign('aggregations', $results['aggregations']);
167
        $this->view->assign('filters', $filters);
168
        $this->view->assign('isHideDiscarded', array_key_exists('aliasState', $excludeFilters));
169
        $this->view->assign('isBookmarksOnly', array_key_exists('bookmarks', $excludeFilters));
170
        $this->view->assign('bookmarkIdentifiers', []);
171
172
        if ($this->fisDataService->getPersonData($this->security->getFisPersId())) {
173
            $this->view->assign('currentFisPersId', $this->security->getFisPersId());
174
        }
175
176
        try {
177
            $personGroup = $this->metadataGroupRepository->findPersonGroup();
178
            $this->view->assign('personGroup', $personGroup->getUid());
179
        } catch (\Throwable $e) {
180
            $this->addFlashMessage(
181
                "Missing configuration: Person group.", '', AbstractMessage::ERROR
182
            );
183
        }
184
    }
185
186
    /**
187
     * action list
188
     *
189
     * @return void
190
     */
191
    public function searchAction()
192
    {
193
        $args = $this->request->getArguments();
194
195
        /** @var SearchSessionData $workspaceSessionData */
196
        $workspaceSessionData = $this->session->getWorkspaceData();
197
198
        if ($args['query'] && array_key_exists('fulltext', $args['query'])) {
199
            $queryString = $args['query']['fulltext'];
200
            $workspaceSessionData->setSimpleQuery($queryString);
201
        }
202
203
        if ($args['refresh']) {
204
            $workspaceSessionData->clearSort();
205
            $workspaceSessionData->clearFilters();
206
            $workspaceSessionData->setSimpleQuery("");
207
        }
208
        $this->session->setWorkspaceData($workspaceSessionData);
209
210
        $simpleSearch = $workspaceSessionData->getSimpleQuery();
211
212
        $this->session->setStoredAction($this->getCurrentAction(), $this->getCurrentController(),
213
            $this->uriBuilder->getRequest()->getRequestUri()
0 ignored issues
show
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

213
            $this->uriBuilder->getRequest()->/** @scrutinizer ignore-call */ getRequestUri()
Loading history...
214
        );
215
216
        $currentPage = null;
217
        $checkedDocumentIdentifiers = [];
218
        $pagination = $this->getParametersSafely('@widget_0');
219
        if ($pagination) {
220
            $checkedDocumentIdentifiers = [];
221
            $currentPage = $pagination['currentPage'];
222
        } else {
223
            $currentPage = 1;
224
        }
225
226
        $this->list(
227
            (empty($currentPage)? 0 : ($currentPage-1) * $this->itemsPerPage()),
228
            $this->escapeQuery(trim($simpleSearch))
0 ignored issues
show
$this->escapeQuery(trim($simpleSearch)) of type string is incompatible with the type integer expected by parameter $queryString of EWW\Dpf\Controller\SearchController::list(). ( Ignorable by Annotation )

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

228
            /** @scrutinizer ignore-type */ $this->escapeQuery(trim($simpleSearch))
Loading history...
229
        );
230
231
        $this->view->assign('simpleSearch', $simpleSearch);
232
        $this->view->assign('currentPage', $currentPage);
233
        $this->view->assign('workspaceListAction', $this->getCurrentAction());
234
        $this->view->assign('checkedDocumentIdentifiers', $checkedDocumentIdentifiers);
235
    }
236
237
238
    /**
239
     * get list view data for the workspace
240
     *
241
     * @param int $from
242
     * @param array $bookmarkIdentifiers
243
     * @param array $filters
244
     * @param array $excludeFilters
245
     * @param string $sortField
246
     * @param string $sortOrder
247
     * @param string $queryString
248
     *
249
     * @return array
250
     */
251
    protected function getSearchQuery(
252
        $from = 0, $bookmarkIdentifiers = [], $filters= [], $excludeFilters = [],
253
        $sortField = null, $sortOrder = null, $queryString = null
254
    )
255
    {
256
        $workspaceFilter = [
257
            'bool' => [
258
                'must' => [
259
                    [
260
                        'bool' => [
261
                            'should' => [
262
                                [
263
                                    'term' => [
264
                                        'creator' => $this->security->getUser()->getUid()
265
                                    ]
266
                                ],
267
                                [
268
                                    'bool' => [
269
                                        'must_not' => [
270
                                            [
271
                                                'term' => [
272
                                                    'state' => DocumentWorkflow::STATE_NEW_NONE
273
                                                ]
274
                                            ]
275
                                        ]
276
                                    ]
277
                                ]
278
                            ]
279
                        ]
280
                    ]
281
                ]
282
            ]
283
        ];
284
285
        return $this->queryBuilder->buildQuery(
286
            $this->itemsPerPage(), $workspaceFilter, $from, $bookmarkIdentifiers, $filters,
287
            $excludeFilters, $sortField, $sortOrder, $queryString
288
        );
289
    }
290
291
292
    /**
293
     * Batch operations action.
294
     * @param array $listData
295
     */
296
    public function batchAction($listData)
297
    {
298
        if (array_key_exists('action', $listData)) {
299
            $this->forward($listData['action'], null, null, ['listData' => $listData]);
300
        }
301
    }
302
303
304
    /**
305
     * Batch operation, bookmark documents.
306
     * @param array $listData
307
     */
308
    public function batchBookmarkAction($listData)
309
    {
310
        $successful = [];
311
        $checkedDocumentIdentifiers = [];
312
313
        if (array_key_exists('documentIdentifiers', $listData) && is_array($listData['documentIdentifiers']) ) {
314
            $checkedDocumentIdentifiers = $listData['documentIdentifiers'];
315
316
            foreach ($listData['documentIdentifiers'] as $documentIdentifier) {
317
318
                if ( $listData['documentAliasState'][$documentIdentifier] != DocumentWorkflow::ALIAS_STATE_NEW) {
319
                    if (
320
                        $this->bookmarkRepository->addBookmark(
321
                            $documentIdentifier,
322
                            $this->security->getUser()->getUid()
323
                        )
324
                    ) {
325
                        $successful[] = $documentIdentifier;
326
                    }
327
                }
328
            }
329
330
            if (sizeof($successful) == 1) {
331
                $locallangKey = 'manager.workspace.batchAction.bookmark.success.singular';
332
            } else {
333
                $locallangKey = 'manager.workspace.batchAction.bookmark.success.plural';
334
            }
335
336
            $message = LocalizationUtility::translate(
337
                $locallangKey,
338
                'dpf',
339
                [sizeof($successful), sizeof($listData['documentIdentifiers'])]
340
            );
341
            $this->addFlashMessage(
342
                $message, '',
343
                (sizeof($successful) > 0 ? AbstractMessage::OK : AbstractMessage::WARNING)
344
            );
345
346
        } else {
347
            $message = LocalizationUtility::translate(
348
                'manager.workspace.batchAction.failure',
349
                'dpf');
350
            $this->addFlashMessage($message, '', AbstractMessage::ERROR);
351
        }
352
353
        list($redirectAction, $redirectController) = $this->session->getStoredAction();
354
        $this->redirect(
355
            $redirectAction, $redirectController, null,
356
            array('message' => $message, 'checkedDocumentIdentifiers' =>  $checkedDocumentIdentifiers));
357
    }
358
359
        /**
360
     * extended search action
361
     */
362
    public function extendedSearchAction()
363
    {
364
        /** @var FrontendUser $feUser */
365
        $feUser = $this->security->getUser();
0 ignored issues
show
The assignment to $feUser is dead and can be removed.
Loading history...
366
367
        $args = $this->request->getArguments();
368
369
        /** @var SearchSessionData $workspaceSessionData */
370
        $workspaceSessionData = $this->session->getWorkspaceData();
371
372
        if ($args['query'] && array_key_exists('fulltext', $args['query'])) {
373
            $queryString = $args['query']['fulltext'];
374
            $workspaceSessionData->setSimpleQuery($queryString);
375
        }
376
377
        if ($args['refresh']) {
378
            $workspaceSessionData->clearSort();
379
            $workspaceSessionData->clearFilters();
380
            $workspaceSessionData->setSimpleQuery("");
381
        }
382
        $this->session->setWorkspaceData($workspaceSessionData);
383
384
        $simpleSearch = $workspaceSessionData->getSimpleQuery();
385
386
        $documentTypes = $this->documentTypeRepository->findAll();
387
388
        $docTypes = [];
389
        foreach ($documentTypes as $documentType) {
390
            $docTypes[$documentType->getName()] = $documentType->getDisplayName();
391
        }
392
        asort($docTypes, SORT_LOCALE_STRING);
393
        $this->view->assign('documentTypes', $docTypes);
394
395
        $states[DocumentWorkflow::ALIAS_STATE_NEW] = LocalizationUtility::translate(
0 ignored issues
show
Comprehensibility Best Practice introduced by
$states was never initialized. Although not strictly required by PHP, it is generally a good practice to add $states = array(); before regardless.
Loading history...
396
            "manager.documentList.state.".DocumentWorkflow::ALIAS_STATE_NEW, 'dpf'
397
        );
398
        $states[DocumentWorkflow::ALIAS_STATE_REGISTERED] = LocalizationUtility::translate(
399
            "manager.documentList.state.".DocumentWorkflow::ALIAS_STATE_REGISTERED, 'dpf'
400
        );
401
        $states[DocumentWorkflow::ALIAS_STATE_IN_PROGRESS] = LocalizationUtility::translate(
402
            "manager.documentList.state.".DocumentWorkflow::ALIAS_STATE_IN_PROGRESS, 'dpf'
403
        );
404
        $states[DocumentWorkflow::ALIAS_STATE_RELEASED] = LocalizationUtility::translate(
405
            "manager.documentList.state.".DocumentWorkflow::ALIAS_STATE_RELEASED, 'dpf'
406
        );
407
        $states[DocumentWorkflow::ALIAS_STATE_POSTPONED] = LocalizationUtility::translate(
408
            "manager.documentList.state.".DocumentWorkflow::ALIAS_STATE_POSTPONED, 'dpf'
409
        );
410
        $states[DocumentWorkflow::ALIAS_STATE_DISCARDED] = LocalizationUtility::translate(
411
            "manager.documentList.state.".DocumentWorkflow::ALIAS_STATE_DISCARDED, 'dpf'
412
        );
413
414
        $this->view->assign('states', $states);
415
416
        $this->session->setStoredAction($this->getCurrentAction(), $this->getCurrentController(),
417
            $this->uriBuilder->getRequest()->getRequestUri()
418
        );
419
420
        $currentPage = null;
421
        $checkedDocumentIdentifiers = [];
422
        $pagination = $this->getParametersSafely('@widget_0');
423
        if ($pagination) {
424
            $checkedDocumentIdentifiers = [];
425
            $currentPage = $pagination['currentPage'];
426
        } else {
427
            $currentPage = 1;
428
        }
429
430
        $this->list((empty($currentPage)? 0 : ($currentPage-1) * $this->itemsPerPage()), $simpleSearch);
0 ignored issues
show
$simpleSearch of type string is incompatible with the type integer expected by parameter $queryString of EWW\Dpf\Controller\SearchController::list(). ( Ignorable by Annotation )

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

430
        $this->list((empty($currentPage)? 0 : ($currentPage-1) * $this->itemsPerPage()), /** @scrutinizer ignore-type */ $simpleSearch);
Loading history...
431
432
        $this->view->assign('simpleSearch', $simpleSearch);
433
        $this->view->assign('currentPage', $currentPage);
434
        $this->view->assign('workspaceListAction', $this->getCurrentAction());
435
        $this->view->assign('checkedDocumentIdentifiers', $checkedDocumentIdentifiers);
436
    }
437
438
    /**
439
     * gets a list of latest documents
440
     */
441
    public function latestAction()
442
    {
443
        try {
444
            $query = $this->searchLatest();
445
446
            // set type local vs object
447
            $type = 'object';
448
449
            $results = $this->getResultList($query, $type);
0 ignored issues
show
The method getResultList() does not exist on EWW\Dpf\Controller\SearchController. ( Ignorable by Annotation )

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

449
            /** @scrutinizer ignore-call */ 
450
            $results = $this->getResultList($query, $type);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
450
        } catch (\Exception $exception) {
451
            $severity = \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR;
452
453
            if ($exception instanceof DPFExceptionInterface) {
454
                $key = $exception->messageLanguageKey();
455
            } else {
456
                $key = 'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:error.unexpected';
457
            }
458
459
            $message = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate($key, 'dpf');
460
461
            $this->addFlashMessage(
462
                $message,
463
                '',
464
                $severity,
465
                true
466
            );
467
        }
468
469
        if ($extSearch) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $extSearch seems to be never defined.
Loading history...
470
            // redirect to extended search view
471
            $this->forward("extendedSearch", null, null, array('results' => $results, 'query' => $args['query']));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $results does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $args seems to be never defined.
Loading history...
472
        } else {
473
            // redirect to list view
474
            $this->forward("list", null, null, array('results' => $results, 'query' => $args['query']));
475
        }
476
    }
477
478
    /**
479
     * action import
480
     *
481
     * @param  string $documentObjectIdentifier
482
     * @param  string $objectState
483
     * @return void
484
     */
485
    public function importAction($documentObjectIdentifier, $objectState)
0 ignored issues
show
The parameter $objectState is not used and could be removed. ( Ignorable by Annotation )

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

485
    public function importAction($documentObjectIdentifier, /** @scrutinizer ignore-unused */ $objectState)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
486
    {
487
        $documentTransferManager = $this->objectManager->get(DocumentTransferManager::class);
0 ignored issues
show
The type EWW\Dpf\Controller\DocumentTransferManager was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
488
        $remoteRepository        = $this->objectManager->get(FedoraRepository::class);
0 ignored issues
show
The type EWW\Dpf\Controller\FedoraRepository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
489
        $documentTransferManager->setRemoteRepository($remoteRepository);
490
491
        $args = array();
492
493
        try {
494
            if ($documentTransferManager->retrieve($documentObjectIdentifier)) {
495
                $key      = 'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:document_retrieve.success';
496
                $severity = \TYPO3\CMS\Core\Messaging\AbstractMessage::OK;
497
                $document = $this->documentRepository->findOneByObjectIdentifier($documentObjectIdentifier);
0 ignored issues
show
The method findOneByObjectIdentifier() does not exist on EWW\Dpf\Domain\Repository\DocumentRepository. 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

497
                /** @scrutinizer ignore-call */ 
498
                $document = $this->documentRepository->findOneByObjectIdentifier($documentObjectIdentifier);
Loading history...
498
                $args[] = $document->getObjectIdentifier()." (".$document->getTitle().")";
0 ignored issues
show
The method getObjectIdentifier() does not exist on TYPO3\CMS\Extbase\Persistence\QueryResultInterface. ( Ignorable by Annotation )

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

498
                $args[] = $document->/** @scrutinizer ignore-call */ getObjectIdentifier()." (".$document->getTitle().")";

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getTitle() does not exist on TYPO3\CMS\Extbase\Persistence\QueryResultInterface. ( Ignorable by Annotation )

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

498
                $args[] = $document->getObjectIdentifier()." (".$document->/** @scrutinizer ignore-call */ getTitle().")";

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
499
            } else {
500
                $severity = \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR;
501
                $key = 'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:error.retrieve_failed';
502
            }
503
        } catch (\Exception $exception) {
504
            $severity = \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR;
505
506
            if ($exception instanceof DPFExceptionInterface) {
507
                $key = $exception->messageLanguageKey();
508
            } else {
509
                $key = 'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:error.unexpected';
510
            }
511
        }
512
513
        // Show success or failure of the action in a flash message
514
515
        $message = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate($key, 'dpf', $args);
516
517
        $this->addFlashMessage(
518
            $message,
519
            '',
520
            $severity,
521
            true
522
        );
523
524
        $this->forward('updateIndex', null, null, array('documentObjectIdentifier' => $documentObjectIdentifier));
525
    }
526
527
    /**
528
     *
529
     * @param  string $documentObjectIdentifier
530
     * @return void
531
     */
532
    public function updateIndexAction($documentObjectIdentifier)
533
    {
534
        $document = $this->documentRepository->findByObjectIdentifier($documentObjectIdentifier);
0 ignored issues
show
The method findByObjectIdentifier() does not exist on EWW\Dpf\Domain\Repository\DocumentRepository. 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

534
        /** @scrutinizer ignore-call */ 
535
        $document = $this->documentRepository->findByObjectIdentifier($documentObjectIdentifier);
Loading history...
535
536
        if (is_a($document, Document::class)) {
537
            $elasticsearchRepository = $this->objectManager->get(ElasticsearchRepository::class);
0 ignored issues
show
The type EWW\Dpf\Controller\ElasticsearchRepository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
538
            $elasticsearchMapper     = $this->objectManager->get(ElasticsearchMapper::class);
0 ignored issues
show
The type EWW\Dpf\Controller\ElasticsearchMapper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
539
            $json                    = $elasticsearchMapper->getElasticsearchJson($document);
540
            // send document to index
541
            $elasticsearchRepository->add($document, $json);
542
        }
543
544
        $this->redirect('search');
545
    }
546
547
548
    /**
549
     * action doubletCheck
550
     *
551
     * @param  \EWW\Dpf\Domain\Model\Document $document
552
     * @return void
553
     */
554
    public function doubletCheckAction(\EWW\Dpf\Domain\Model\Document $document)
555
    {
556
        $this->authorizationChecker->denyAccessUnlessGranted(DocumentVoter::DOUBLET_CHECK, $document);
557
558
        try {
559
            $elasticSearch = $this->objectManager->get(ElasticSearch::class);
560
561
            $client = $this->clientRepository->findAll()->current();
562
563
            // es source fields
564
            // title
565
            // abstract
566
            // author
567
            // language
568
            // publisher
569
            // publisher_place
570
            // distributor
571
            // distributor_place
572
            // distributor_date
573
            // classification
574
            // tag
575
            // identifier
576
            // submitter
577
            // project
578
579
            // is doublet existing?
580
            $query['body']['query']['bool']['must'][]['match']['title'] = $document->getTitle();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$query was never initialized. Although not strictly required by PHP, it is generally a good practice to add $query = array(); before regardless.
Loading history...
581
582
            // set owner id
583
            $query['body']['query']['bool']['must'][]['term']['OWNER_ID'] = $client->getOwnerId();
584
585
            $results = $elasticSearch->search($query, '');
586
587
            $searchList = array();
588
589
            // filter out identical document from the search result list
590
            foreach ($results['hits'] as $entry) {
591
592
                if ($document->getObjectIdentifier() && ($document->getObjectIdentifier() === $entry['_source']['PID'])) {
593
                    continue;
594
                }
595
596
                $entryIdentifier = $entry['_source']['_dissemination']['_content']['identifier'][0];
597
                if (is_numeric($entryIdentifier) && $document->getUid() == $entryIdentifier) {
598
                    continue;
599
                }
600
601
                $searchList[] = $entry;
602
            }
603
604
605
            $objectIdentifiers = $this->documentRepository->getObjectIdentifiers();
606
607
            $this->view->assign('document', $document);
608
            $this->view->assign('searchList', $searchList);
609
            $this->view->assign('alreadyImported', $objectIdentifiers);
610
611
        } catch (\Exception $exception) {
612
            $severity = \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR;
613
614
            if ($exception instanceof DPFExceptionInterface) {
615
                $key = $exception->messageLanguageKey();
616
            } else {
617
                $key = 'LLL:EXT:dpf/Resources/Private/Language/locallang.xlf:error.unexpected';
618
            }
619
620
            $message = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate($key, 'dpf');
621
622
            $this->addFlashMessage(
623
                $message,
624
                '',
625
                $severity,
626
                true
627
            );
628
629
            $this->redirect('list', 'Document', null);
630
        }
631
632
    }
633
634
    /**
635
     * returns the query to get latest documents
636
     * @return mixed
637
     */
638
    public function searchLatest()
639
    {
640
        $client = $this->clientRepository->findAll()->current();
641
642
        // get the latest documents /CREATED_DATE
643
        $query['body']['sort'] = array('CREATED_DATE' => array('order' => 'desc'));
0 ignored issues
show
Comprehensibility Best Practice introduced by
$query was never initialized. Although not strictly required by PHP, it is generally a good practice to add $query = array(); before regardless.
Loading history...
644
645
        // add owner id
646
        $query['body']['query']['bool']['must']['term']['OWNER_ID'] = $client->getOwnerId();
647
648
        $query['body']['query']['bool']['should'][0]['query_string']['query']                       = '*';
649
        $query['body']['query']['bool']['should'][1]['has_child']['query']['query_string']['query'] = '*';
650
651
        $query['body']['query']['bool']['minimum_should_match'] = "1"; // 1
652
653
        // child_type is invalid in elasticsearch 7.5
654
        $query['body']['query']['bool']['should'][1]['has_child']['type'] = "datastream"; // 1
655
656
        return $query;
657
    }
658
659
660
    /**
661
     * Returns the number of items to be shown per page.
662
     *
663
     * @return int
664
     */
665
    protected function itemsPerPage()
666
    {
667
        /** @var SearchSessionData $workspaceData */
668
        $workspaceData = $this->session->getWorkspaceData();
669
        $itemsPerPage = $workspaceData->getItemsPerPage();
670
671
        $default = ($this->settings['workspaceItemsPerPage'])? $this->settings['workspaceItemsPerPage'] : 10;
672
        return ($itemsPerPage)? $itemsPerPage : $default;
673
    }
674
675
676
    /**
677
     * escapes lucene reserved characters from string
678
     * @param $string
679
     * @return mixed
680
     */
681
    private function escapeQuery($string)
682
    {
683
        $luceneReservedCharacters = preg_quote('+-&|!(){}[]^~?:\\');
684
        $string                   = preg_replace_callback(
685
            '/([' . $luceneReservedCharacters . '])/',
686
            function ($matches) {
687
                return '\\' . $matches[0];
688
            },
689
            $string
690
        );
691
692
        $string = str_replace("/", "\/", $string);
693
694
        return $string;
695
    }
696
697
}
698