Completed
Push — master ( 94b632...a799ec )
by Maxence
02:11
created

SearchService::getDocument()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
/**
3
 * FullTextSearch_ElasticSearch - Use Elasticsearch to index the content of your nextcloud
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2018
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\FullTextSearch_ElasticSearch\Service;
28
29
use Elasticsearch\Client;
30
use Exception;
31
use OCA\FullTextSearch\IFullTextSearchProvider;
32
use OCA\FullTextSearch\Model\DocumentAccess;
33
use OCA\FullTextSearch\Model\IndexDocument;
34
use OCA\FullTextSearch\Model\SearchRequest;
35
use OCA\FullTextSearch\Model\SearchResult;
36
use OCA\FullTextSearch_ElasticSearch\Exceptions\ConfigurationException;
37
use OCA\FullTextSearch_ElasticSearch\Exceptions\SearchQueryGenerationException;
38
39
class SearchService {
40
41
42
	/** @var SearchMappingService */
43
	private $searchMappingService;
44
45
	/** @var MiscService */
46
	private $miscService;
47
48
49
	/**
50
	 * SearchService constructor.
51
	 *
52
	 * @param SearchMappingService $searchMappingService
53
	 * @param MiscService $miscService
54
	 */
55
	public function __construct(
56
		SearchMappingService $searchMappingService, MiscService $miscService
57
	) {
58
		$this->searchMappingService = $searchMappingService;
59
		$this->miscService = $miscService;
60
	}
61
62
63
	/**
64
	 * @param Client $client
65
	 * @param IFullTextSearchProvider $provider
66
	 * @param DocumentAccess $access
67
	 * @param SearchRequest $request
68
	 *
69
	 * @return SearchResult
0 ignored issues
show
Documentation introduced by
Should the return type not be SearchResult|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
70
	 * @throws ConfigurationException
71
	 * @throws Exception
72
	 */
73
	public function searchDocuments(
74
		Client $client, IFullTextSearchProvider $provider, DocumentAccess $access,
75
		SearchRequest $request
76
	) {
77
		try {
78
			$query = $this->searchMappingService->generateSearchQuery($provider, $access, $request);
79
		} catch (SearchQueryGenerationException $e) {
80
			return null;
81
		}
82
83
		try {
84
			$result = $client->search($query['params']);
85
		} catch (Exception $e) {
86
			$this->miscService->log(
87
				'debug - request: ' . json_encode($request) . '   - query: ' . json_encode($query)
88
			);
89
			throw $e;
90
		}
91
92
		$searchResult = $this->generateSearchResultFromResult($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...
93
94
		foreach ($result['hits']['hits'] as $entry) {
95
			$searchResult->addDocument($this->parseSearchEntry($entry, $access->getViewerId()));
96
		}
97
98
		return $searchResult;
99
	}
100
101
102
	/**
103
	 * @param Client $client
104
	 * @param string $providerId
105
	 * @param string $documentId
106
	 *
107
	 * @return IndexDocument
108
	 */
109
	public function getDocument(Client $client, $providerId, $documentId) {
110
		$query = [
111
			'index' => 'my_index',
112
			'type'  => 'standard',
113
			'id'    => $providerId . ':' . $documentId
114
		];
115
116
		$result = $client->get($query);
117
118
		$access = new DocumentAccess($result['_source']['owner']);
119
		$access->setUsers($result['_source']['users']);
120
		$access->setGroups($result['_source']['groups']);
121
		$access->setCircles($result['_source']['circles']);
122
123
		$index = new IndexDocument($providerId, $documentId);
124
		$index->setAccess($access);
125
		$index->setTags($result['_source']['tags']);
126
		$index->setHash($result['_source']['hash']);
127
		$index->setSource($result['_source']['source']);
128
		$index->setTitle($result['_source']['title']);
129
		$index->setParts($result['_source']['parts']);
130
		$index->setContent($result['_source']['content']);
131
132
		return $index;
133
	}
134
135
136
	/**
137
	 * @param array $result
138
	 *
139
	 * @return SearchResult
140
	 */
141
	private function generateSearchResultFromResult($result) {
142
		$searchResult = new SearchResult();
143
		$searchResult->setRawResult(json_encode($result));
144
145
		$searchResult->setTotal($result['hits']['total']);
146
		$searchResult->setMaxScore($result['hits']['max_score']);
147
		$searchResult->setTime($result['took']);
148
		$searchResult->setTimedOut($result['timed_out']);
149
150
		return $searchResult;
151
	}
152
153
154
	/**
155
	 * @param array $entry
156
	 * @param string $viewerId
157
	 *
158
	 * @return IndexDocument
159
	 */
160
	private function parseSearchEntry($entry, $viewerId) {
161
		$access = new DocumentAccess();
162
		$access->setViewerId($viewerId);
163
164
		list($providerId, $documentId) = explode(':', $entry['_id'], 2);
165
		$document = new IndexDocument($providerId, $documentId);
166
		$document->setAccess($access);
167
		$document->setExcerpts(
168
			(array_key_exists('highlight', $entry)) ? $entry['highlight']['content'] : []
169
		);
170
		$document->setHash(MiscService::get($entry['_source'], 'hash'));
171
		$document->setScore($entry['_score']);
172
		$document->setSource(MiscService::get($entry['_source'], 'source'));
173
		$document->setTitle(MiscService::get($entry['_source'], 'title'));
174
175
		return $document;
176
	}
177
178
179
}
180