Completed
Push — master ( 58d870...e50603 )
by
unknown
02:12
created

ProviderService::getProviders()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * FullTextSearch - Full text search framework for 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\Service;
28
29
use Exception;
30
use OC\App\AppManager;
31
use OC_App;
32
use OCA\FullTextSearch\Exceptions\ProviderDoesNotExistException;
33
use OCA\FullTextSearch\Exceptions\ProviderIsNotCompatibleException;
34
use OCA\FullTextSearch\Exceptions\ProviderIsNotUniqueException;
35
use OCA\FullTextSearch\Exceptions\ProviderOptionsDoesNotExistException;
36
use OCA\FullTextSearch\IFullTextSearchProvider;
37
use OCP\AppFramework\QueryException;
38
39
class ProviderService {
40
41
	/** @var AppManager */
42
	private $appManager;
43
44
	/** @var ConfigService */
45
	private $configService;
46
47
	/** @var MiscService */
48
	private $miscService;
49
50
	/** @var IFullTextSearchProvider[] */
51
	private $providers = [];
52
53
	/** @var bool */
54
	private $providersLoaded = false;
55
56
57
	/**
58
	 * ProviderService constructor.
59
	 *
60
	 * @param AppManager $appManager
61
	 * @param ConfigService $configService
62
	 * @param MiscService $miscService
63
	 *
64
	 */
65
	public function __construct(
66
		AppManager $appManager, ConfigService $configService, MiscService $miscService
67
	) {
68
		$this->appManager = $appManager;
69
		$this->configService = $configService;
70
		$this->miscService = $miscService;
71
	}
72
73
74
	/**
75
	 * Load all FullTextSearchProviders set in any info.xml file
76
	 *
77
	 * @throws Exception
78
	 */
79
	private function loadProviders() {
80
		if ($this->providersLoaded) {
81
			return;
82
		}
83
84
		try {
85
			$apps = $this->appManager->getInstalledApps();
86
			foreach ($apps as $appId) {
87
				$this->loadProvidersFromApp($appId);
88
			}
89
		} catch (Exception $e) {
90
			$this->miscService->log($e->getMessage());
91
		}
92
93
		$this->providersLoaded = true;
94
	}
95
96
97
	/**
98
	 * @param string $providerId
99
	 *
100
	 * @throws ProviderIsNotCompatibleException
101
	 * @throws ProviderIsNotUniqueException
102
	 * @throws QueryException
103
	 */
104
	public function loadProvider($providerId) {
105
106
		$provider = \OC::$server->query((string)$providerId);
107
		if (!($provider instanceof IFullTextSearchProvider)) {
108
			throw new ProviderIsNotCompatibleException(
109
				$providerId . ' is not a compatible IFullTextSearchProvider'
110
			);
111
		}
112
113
		$this->providerIdMustBeUnique($provider);
114
		try {
115
			$provider->loadProvider();
116
			$this->providers[] = $provider;
117
		} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
118
		}
119
	}
120
121
122
	/**
123
	 * @return IFullTextSearchProvider[]
124
	 * @throws Exception
125
	 */
126
	public function getProviders() {
127
		$this->loadProviders();
128
129
		return $this->providers;
130
	}
131
132
	/**
133
	 * @return IFullTextSearchProvider[]
134
	 * @throws Exception
135
	 */
136
	public function getConfiguredProviders() {
137
		$this->loadProviders();
138
139
		$providers = [];
140
		foreach ($this->providers as $provider) {
141
			if ($this->isProviderIndexed($provider->getId())) {
142
				$providers[] = $provider;
143
			}
144
		}
145
146
		return $providers;
147
	}
148
149
150
	/**
151
	 * @param array $providerList
152
	 *
153
	 * @return IFullTextSearchProvider[]
154
	 * @throws Exception
155
	 * @throws ProviderDoesNotExistException
156
	 */
157
	public function getFilteredProviders($providerList) {
158
		$this->loadProviders();
159
160
		$providers = $this->getConfiguredProviders();
161
		if (in_array('all', $providerList)) {
162
			return $providers;
163
		}
164
165
		$ret = [];
166
		foreach ($providerList as $providerId) {
167
			if ($this->isProviderIndexed($providerId)) {
168
				$ret[] = $this->getProvider($providerId);
169
			}
170
		}
171
172
		return $ret;
173
	}
174
175
176
	/**
177
	 * @param string $providerId
178
	 *
179
	 * @return IFullTextSearchProvider
180
	 * @throws Exception
181
	 * @throws ProviderDoesNotExistException
182
	 */
183
	public function getProvider($providerId) {
184
185
		$providers = $this->getProviders();
186
		foreach ($providers as $provider) {
187
			if ($provider->getId() === $providerId) {
188
				return $provider;
189
			}
190
		}
191
192
		throw new ProviderDoesNotExistException('Provider \'' . $providerId . '\' does not exist');
193
	}
194
195
196
	/**
197
	 * @param string $providerId
198
	 *
199
	 * @return bool
200
	 */
201
	public function isProviderIndexed($providerId) {
202
		try {
203
			$indexed = $this->configService->getProviderOptions(
204
				$providerId, ConfigService::PROVIDER_INDEXED
205
			);
206
		} catch (ProviderOptionsDoesNotExistException $e) {
207
			return false;
208
		}
209
210
		if ($indexed === '1') {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $indexed === '1';.
Loading history...
211
			return true;
212
		}
213
214
		return false;
215
216
	}
217
218
219
	public function setProviderAsIndexed(IFullTextSearchProvider $provider, $boolean) {
220
		$this->configService->setProviderOptions(
221
			$provider->getId(), ConfigService::PROVIDER_INDEXED, (($boolean) ? '1' : '0')
222
		);
223
	}
224
225
226
	public function setProvidersAsNotIndexed() {
227
		$this->configService->resetProviderOptions(ConfigService::PROVIDER_INDEXED);
228
	}
229
230
231
	/**
232
	 * @param string $appId
233
	 *
234
	 * @throws ProviderIsNotCompatibleException
235
	 * @throws ProviderIsNotUniqueException
236
	 * @throws QueryException
237
	 */
238
	private function loadProvidersFromApp($appId) {
239
		$appInfo = OC_App::getAppInfo($appId);
240 View Code Duplication
		if (!is_array($appInfo) || !key_exists('fulltextsearch', $appInfo)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
241
			|| !key_exists('provider', $appInfo['fulltextsearch'])) {
242
			return;
243
		}
244
245
		$providers = $appInfo['fulltextsearch']['provider'];
246
		$this->loadProvidersFromList($providers);
247
	}
248
249
250
	/**
251
	 * @param string|array $providers
252
	 *
253
	 * @throws ProviderIsNotCompatibleException
254
	 * @throws ProviderIsNotUniqueException
255
	 * @throws QueryException
256
	 */
257
	private function loadProvidersFromList($providers) {
258
		if (!is_array($providers)) {
259
			$providers = [$providers];
260
		}
261
262
		foreach ($providers AS $provider) {
263
			$this->loadProvider($provider);
264
		}
265
	}
266
267
268
	/**
269
	 * @param IFullTextSearchProvider $provider
270
	 *
271
	 * @throws ProviderIsNotUniqueException
272
	 */
273
	private function providerIdMustBeUnique(IFullTextSearchProvider $provider) {
274
		foreach ($this->providers AS $knownProvider) {
275
			if ($knownProvider->getId() === $provider->getId()) {
276
				throw new ProviderIsNotUniqueException(
277
					'FullTextSearchProvider ' . $provider->getId() . ' already exist'
278
				);
279
			}
280
		}
281
	}
282
283
284
	/**
285
	 * @param IFullTextSearchProvider[] $providers
286
	 *
287
	 * @return array
288
	 */
289
	public function serialize($providers) {
290
		$arr = [];
291
		foreach ($providers as $provider) {
292
			$arr[] = [
293
				'id'   => $provider->getId(),
294
				'name' => $provider->getName()
295
			];
296
		}
297
298
		return $arr;
299
	}
300
301
}