Passed
Pull Request — master (#168)
by
unknown
08:57
created

ElasticSearch::initializeIndex()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 89
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 56
nc 2
nop 1
dl 0
loc 89
rs 8.9599
c 2
b 0
f 0

How to fix   Long Method   

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\Services\ElasticSearch;
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 Elasticsearch\ClientBuilder;
18
use EWW\Dpf\Domain\Workflow\DocumentWorkflow;
19
use TYPO3\CMS\Extbase\Object\ObjectManager;
20
use EWW\Dpf\Configuration\ClientConfigurationManager;
21
use EWW\Dpf\Domain\Model\Document;
22
use EWW\Dpf\Helper\Mods;
23
use TYPO3\CMS\Core\Utility\GeneralUtility;
24
use TYPO3\CMS\Core\Log\LogManager;
25
26
class ElasticSearch
27
{
28
    /**
29
     *
30
     * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
31
     * @inject
32
     */
33
    protected $configurationManager;
34
35
    /**
36
     * frontendUserRepository
37
     *
38
     * @var \EWW\Dpf\Domain\Repository\FrontendUserRepository
39
     * @inject
40
     */
41
    protected $frontendUserRepository = null;
42
43
    protected $client;
44
45
    protected $server = 'host.docker.internal'; //127.0.0.1';
46
47
    protected $port = '9200';
48
49
    protected $indexName = 'kitodo_publication';
50
51
    //protected $mapping = '';
52
53
    //protected $hits;
54
55
    protected $results;
56
57
    protected $elasticsearchMapper;
58
59
60
    /**
61
     * elasticsearch client constructor
62
     */
63
    public function __construct()
64
    {
65
        $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class);
66
67
        $this->elasticsearchMapper = $objectManager->get(ElasticsearchMapper::class);
68
69
        $clientConfigurationManager = $objectManager->get(ClientConfigurationManager::class);
70
71
        $this->server = $clientConfigurationManager->getElasticSearchHost();
72
        $this->port = $clientConfigurationManager->getElasticSearchPort();
73
74
        $hosts = array(
75
            $this->server . ':' . $this->port,
76
        );
77
78
        $clientBuilder = ClientBuilder::create();
79
        $clientBuilder->setHosts($hosts);
80
        $this->client = $clientBuilder->build();
81
82
        $this->initializeIndex($this->indexName);
83
84
    }
85
86
    /**
87
     * Get typoscript settings
88
     *
89
     * @return mixed
90
     */
91
    public function getSettings()
92
    {
93
        $frameworkConfiguration = $this->configurationManager->getConfiguration(
94
            \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
95
        );
96
        return $frameworkConfiguration['settings'];
97
    }
98
99
100
    /**
101
     * Creates an index named by $indexName if it doesn't exist.
102
     *
103
     * @param $indexName
104
     */
105
    protected function initializeIndex($indexName)
106
    {
107
        $paramsIndex = [
108
            'index' => $indexName,
109
            'body' => [
110
                'settings' => [
111
                    //'index.requests.cache.enable' => false,
112
                    'analysis' => [
113
                        'filter' => [
114
                            'ngram' => [
115
                                'type' => 'ngram',
116
                                'min_gram' => 3,
117
                                'max_gram' => 3,
118
                                'token_chars' => [
119
                                    'letter',
120
                                    'digit'
121
                                ],
122
                            ]
123
                        ],
124
                        'analyzer' => [
125
                            'keyword_lowercase' => [
126
                                'tokenizer' => 'keyword',
127
                                'filter' => ['lowercase']
128
                            ]
129
                        ],
130
                        'normalizer' => [
131
                            'lowercase_normalizer' => [
132
                                'type' => 'custom',
133
                                'char_filter' => [],
134
                                'filter' => [
135
                                    'lowercase',
136
                                    'asciifolding'
137
                                ]
138
                            ]
139
                        ]
140
                    ]
141
                ],
142
                'mappings' => [
143
                    '_source' => [
144
                        'enabled' => true
145
                    ],
146
                    //'dynamic' => 'strict',
147
                    'properties' => [
148
                        'title' => [
149
                            'type' => 'text',
150
                            'fields' => [
151
                                'keyword' => [
152
                                    'type' => 'keyword',
153
                                    'normalizer' => 'lowercase_normalizer'
154
                                ]
155
                            ]
156
                        ],
157
                        'state' => [
158
                            'type' => 'keyword'
159
                        ],
160
                        'aliasState' => [
161
                            'type' => 'keyword'
162
                        ],
163
                        'year' => [
164
                            'type' => 'integer'
165
                        ],
166
                        'authorAndPublisher' => [
167
                            'type' => 'keyword'
168
                        ],
169
                        'doctype' => [
170
                            'type' => 'keyword'
171
                        ],
172
                        'collections' => [
173
                            'type' => 'keyword'
174
                        ],
175
                        'hasFiles' => [
176
                            'type' => 'keyword'
177
                        ],
178
                        'creator' => [
179
                            'type' => 'keyword'
180
                        ],
181
                        'creatorRole' => [
182
                            'type' => 'keyword'
183
                        ],
184
                        'source' => [
185
                            'type' => 'text'
186
                        ]
187
                    ]
188
                ]
189
            ]
190
        ];
191
192
        if (!$this->client->indices()->exists(['index' => $indexName])) {
193
            $this->client->indices()->create($paramsIndex);
194
        }
195
196
    }
197
198
    /**
199
     * Adds an document to the index.
200
     *
201
     * @param Document $document
202
     */
203
    public function index($document)
204
    {
205
        $data = json_decode($this->elasticsearchMapper->getElasticsearchJson($document));
206
207
        if ($data) {
208
209
            $data->state = $document->getState();
210
            $data->aliasState = DocumentWorkflow::STATE_TO_ALIASSTATE_MAPPING[$document->getState()];
211
            $data->objectIdentifier = $document->getObjectIdentifier();
212
213
214
            if ($data->identifier && is_array($data->identifier)) {
215
                $data->identifier[] = $document->getObjectIdentifier();
216
            } else {
217
                $data->identifier = [$document->getObjectIdentifier()];
218
            }
219
220
221
            if ($document->getCreator()) {
222
                $data->creator = $document->getCreator();
223
            } else {
224
                $data->creator = null;
225
            }
226
227
228
            if ($document->getCreator()) {
229
                /** @var \EWW\Dpf\Domain\Model\FrontendUser $creatorFeUser */
230
                $creatorFeUser = $this->frontendUserRepository->findByUid($document->getCreator());
231
                $data->creatorRole = $creatorFeUser->getUserRole();
232
            } else {
233
                $data->creatorRole = '';
234
            }
235
236
            $data->year = $document->getPublicationYear();
237
238
            $notes = $document->getNotes();
239
240
            if ($notes && is_array($notes)) {
241
                $data->notes = $notes;
242
            } else {
243
                $data->notes = array();
244
            }
245
246
            $files = $document->getFile();
247
            if ($files->count() > 0) {
248
                $data->hasFiles = true;
249
            } else {
250
                $data->hasFiles = false;
251
            }
252
253
254
            /** @var @var Mods $mods */
255
            $mods = new Mods($document->getXmlData());
256
257
            $authors = $mods->getAuthors();
258
            $publishers = $mods->getPublishers();
259
260
            $data->authorAndPublisher = array_merge($authors, $publishers);
261
262
            $data->source = $document->getSourceDetails();
263
264
265
            $data->universityCollection = false;
266
            if ($data->collections && is_array($data->collections)) {
267
                foreach ($data->collections as $collection) {
268
                    if ($collection == $this->getSettings()['universityCollection']) {
269
                        $data->universityCollection = true;
270
                        break;
271
                    }
272
                }
273
            }
274
275
            $embargoDate = $document->getEmbargoDate();
276
            if ($embargoDate instanceof \DateTime) {
0 ignored issues
show
introduced by
$embargoDate is always a sub-type of DateTime.
Loading history...
277
                $data->embargoDate = $embargoDate->format("Y-m-d");
278
            } else {
279
                $data->embargoDate = null;
280
            }
281
282
            $data->originalSourceTitle = $mods->getOriginalSourceTitle();
283
284
            $this->client->index([
285
                'refresh' => 'wait_for',
286
                'index' => $this->indexName,
287
                'id' => $document->getDocumentIdentifier(),
288
                'body' => $data
289
            ]);
290
291
        }
292
293
    }
294
295
296
    /**
297
     * Deletes a document from the index
298
     *
299
     * @param string $identifier
300
     */
301
    public function delete($identifier)
302
    {
303
        try {
304
305
            $params = [
306
                'refresh' => 'wait_for',
307
                'index' => $this->indexName,
308
                'id' => $identifier
309
            ];
310
311
            $this->client->delete($params);
312
313
        } catch (\Exception $e) {
314
            /** @var $logger \TYPO3\CMS\Core\Log\Logger */
315
            $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
316
            $logger->warning('Document could not be deleted from the index.',
317
                [
318
                    'Document identifier' => $identifier
319
                ]
320
            );
321
        }
322
    }
323
324
325
    /**
326
     * @param $identifier
327
     */
328
    public function getDocument($identifier)
329
    {
330
        $params = [
331
            'index' => $this->indexName,
332
            'id'    => $identifier
333
        ];
334
335
        return $this->client->get($params);
336
    }
337
338
339
    /**
340
     * performs the
341
     * @param  array $query search query
342
     * @return array        result list
343
     */
344
    public function search($query, $type = null)
345
    {
346
        try {
347
            // define type and index
348
            if (empty($query['index'])) {
349
                $query['index'] = $this->indexName;
350
            }
351
            if (!empty($type)) {
352
                //$query['type'] = $type;
353
                // $query['type'] = $this->type;
354
            }
355
356
            // Search request
357
            $results = $this->client->search($query);
358
359
            //$this->hits = $results['hits']['total'];
360
361
            //$this->resultList = $results['hits'];
362
363
            $this->results = $results;
364
365
            return $this->results;
366
        } catch ( \Elasticsearch\Common\Exceptions\Curl\CouldNotConnectToHost $exception) {
367
            throw new \EWW\Dpf\Exceptions\ElasticSearchConnectionErrorException("Could not connect to repository server.");
368
        } catch (\Elasticsearch\Common\Exceptions\Curl\CouldNotResolveHostException $exception) {
369
            throw new \EWW\Dpf\Exceptions\ElasticSearchConnectionErrorException("Could not connect to repository server.");
370
        }
371
    }
372
373
    /**
374
     * Get the results
375
     * @return mixed
376
     */
377
    public function getResults()
378
    {
379
        // return results from the last search request
380
        return $this->results;
381
    }
382
}
383