Completed
Pull Request — master (#47)
by Maxence
02:53 queued 01:03
created

SearchService::parseSearchEntryExcerpts()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
declare(strict_types=1);
3
4
5
/**
6
 * FullTextSearch_ElasticSearch - Use Elasticsearch to index the content of your nextcloud
7
 *
8
 * This file is licensed under the Affero General Public License version 3 or
9
 * later. See the COPYING file.
10
 *
11
 * @author Maxence Lange <[email protected]>
12
 * @copyright 2018
13
 * @license GNU AGPL version 3 or any later version
14
 *
15
 * This program is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License as
17
 * published by the Free Software Foundation, either version 3 of the
18
 * License, or (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
 *
28
 */
29
30
31
namespace OCA\FullTextSearch_ElasticSearch\Service;
32
33
34
use daita\MySmallPhpTools\Traits\TArrayTools;
35
use Elasticsearch\Client;
36
use Exception;
37
use OCA\FullTextSearch_ElasticSearch\Exceptions\ConfigurationException;
38
use OCA\FullTextSearch_ElasticSearch\Exceptions\SearchQueryGenerationException;
39
use OCP\FullTextSearch\Model\DocumentAccess;
40
use OCP\FullTextSearch\Model\IndexDocument;
41
use OCP\FullTextSearch\Model\ISearchResult;
42
43
44
/**
45
 * Class SearchService
46
 *
47
 * @package OCA\FullTextSearch_ElasticSearch\Service
48
 */
49
class SearchService {
50
51
52
	use TArrayTools;
53
54
55
	/** @var SearchMappingService */
56
	private $searchMappingService;
57
58
	/** @var MiscService */
59
	private $miscService;
60
61
62
	/**
63
	 * SearchService constructor.
64
	 *
65
	 * @param SearchMappingService $searchMappingService
66
	 * @param MiscService $miscService
67
	 */
68
	public function __construct(
69
		SearchMappingService $searchMappingService, MiscService $miscService
70
	) {
71
		$this->searchMappingService = $searchMappingService;
72
		$this->miscService = $miscService;
73
	}
74
75
	/**
76
	 * @param Client $client
77
	 * @param ISearchResult $searchResult
78
	 * @param DocumentAccess $access
79
	 *
80
	 * @throws Exception
81
	 */
82
	public function searchRequest(
83
		Client $client, ISearchResult $searchResult, DocumentAccess $access
84
	) {
85
		try {
86
			$query = $this->searchMappingService->generateSearchQuery(
87
				$searchResult->getRequest(), $access, $searchResult->getProvider()
88
																   ->getId()
89
			);
90
		} catch (SearchQueryGenerationException $e) {
91
			return;
92
		}
93
94
		try {
95
			$result = $client->search($query['params']);
96
		} catch (Exception $e) {
97
			$this->miscService->log(
98
				'debug - request: ' . json_encode($searchResult->getRequest()) . '   - query: '
99
				. json_encode($query)
100
			);
101
			throw $e;
102
		}
103
104
		$this->updateSearchResult($searchResult, $result);
0 ignored issues
show
Documentation introduced by
$result is of type callable, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
105
106
		foreach ($result['hits']['hits'] as $entry) {
107
			$searchResult->addDocument($this->parseSearchEntry($entry, $access->getViewerId()));
108
		}
109
	}
110
111
112
//	/**
113
//	 * @param Client $client
114
//	 * @param IFullTextSearchProvider $provider
115
//	 * @param DocumentAccess $access
116
//	 * @param SearchResult $result
117
//	 *
118
//	 * @return SearchResult
119
//	 * @throws ConfigurationException
120
//	 */
121
//	public function fillSearchResult(
122
//		Client $client, IFullTextSearchProvider $provider, DocumentAccess $access,
123
//		SearchResult $searchResult
124
//	) {
125
//		try {
126
//			$query = $this->searchMappingService->generateSearchQuery(
127
//				$provider, $access, $searchResult->getRequest()
128
//			);
129
//		} catch (SearchQueryGenerationException $e) {
130
//			return null;
131
//		}
132
//
133
//		try {
134
//			$result = $client->search($query['params']);
135
//		} catch (Exception $e) {
136
//			$this->miscService->log(
137
//				'debug - request: ' . json_encode($searchResult->getRequest()) . '   - query: '
138
//				. json_encode($query)
139
//			);
140
//			throw $e;
141
//		}
142
//
143
//		$this->updateSearchResult($searchResult, $result);
144
//
145
//		foreach ($result['hits']['hits'] as $entry) {
146
//			$searchResult->addDocument($this->parseSearchEntry($entry, $access->getViewerId()));
147
//		}
148
//
149
//		return $searchResult;
150
//	}
151
152
153
	/**
154
	 * @param Client $client
155
	 * @param string $providerId
156
	 * @param string $documentId
157
	 *
158
	 * @return IndexDocument
159
	 * @throws ConfigurationException
160
	 */
161
	public function getDocument(Client $client, string $providerId, string $documentId
162
	): IndexDocument {
163
		$query = $this->searchMappingService->getDocumentQuery($providerId, $documentId);
164
		$result = $client->get($query);
165
166
		$access = new DocumentAccess($result['_source']['owner']);
167
		$access->setUsers($result['_source']['users']);
168
		$access->setGroups($result['_source']['groups']);
169
		$access->setCircles($result['_source']['circles']);
170
		$access->setLinks($result['_source']['links']);
171
172
		$index = new IndexDocument($providerId, $documentId);
173
		$index->setAccess($access);
174
		$index->setMetaTags($result['_source']['metatags']);
175
		$index->setSubTags($result['_source']['subtags']);
176
		$index->setTags($result['_source']['tags']);
177
//		$index->setMore($result['_source']['more']);
178
//		$index->setInfo($result['_source']['info']);
179
		$index->setHash($result['_source']['hash']);
180
		$index->setSource($result['_source']['source']);
181
		$index->setTitle($result['_source']['title']);
182
		$index->setParts($result['_source']['parts']);
183
184
		$content = $this->get('content', $result['_source'], '');
185
		$index->setContent($content);
186
187
		return $index;
188
	}
189
190
191
	/**
192
	 * @param ISearchResult $searchResult
193
	 * @param array $result
194
	 */
195
	private function updateSearchResult(ISearchResult $searchResult, array $result) {
196
		$searchResult->setRawResult(json_encode($result));
197
198
		$searchResult->setTotal($result['hits']['total']);
199
		$searchResult->setMaxScore($this->getInt('max_score', $result['hits'], 0));
200
		$searchResult->setTime($result['took']);
201
		$searchResult->setTimedOut($result['timed_out']);
202
	}
203
204
205
	/**
206
	 * @param array $entry
207
	 * @param string $viewerId
208
	 *
209
	 * @return IndexDocument
210
	 */
211
	private function parseSearchEntry(array $entry, string $viewerId): IndexDocument {
212
		$access = new DocumentAccess();
213
		$access->setViewerId($viewerId);
214
215
		list($providerId, $documentId) = explode(':', $entry['_id'], 2);
216
		$document = new IndexDocument($providerId, $documentId);
217
		$document->setAccess($access);
218
		$document->setHash($this->get('hash', $entry['_source']));
219
		$document->setScore($this->get('_score', $entry, '0'));
220
		$document->setSource($this->get('source', $entry['_source']));
221
		$document->setTitle($this->get('title', $entry['_source']));
222
223
		$document->setExcerpts(
224
			$this->parseSearchEntryExcerpts(
225
				(array_key_exists('highlight', $entry)) ? $entry['highlight'] : []
226
			)
227
		);
228
229
		return $document;
230
	}
231
232
233
	private function parseSearchEntryExcerpts(array $highlight): array {
234
		$result = [];
235
		foreach (array_keys($highlight) as $k) {
236
			$result = array_merge($highlight[$k]);
237
		}
238
239
		return $result;
240
	}
241
242
}
243
244