Passed
Pull Request — master (#166)
by
unknown
21:05
created

ElasticSearch   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 290
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 125
dl 0
loc 290
rs 10
c 2
b 0
f 0
wmc 18

7 Methods

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