Completed
Pull Request — master (#87)
by Robin
01:28
created

ConfigService   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 299
Duplicated Lines 6.02 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 35
lcom 1
cbo 0
dl 18
loc 299
rs 9.6
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A getValueForUser() 0 3 1
A __construct() 0 5 1
A getConfig() 0 10 2
A setConfig() 0 9 3
A getAppValue() 8 8 2
A setAppValue() 0 3 1
A deleteAppValue() 0 3 1
A optionIsSelected() 0 3 1
A getUserValue() 10 10 2
A setValueForUser() 0 3 1
A getSystemValue() 0 3 1
A setDocumentIndexOption() 0 4 1
A compareIndexOptions() 0 13 4
A getFullCloudVersion() 0 5 1
A isCloudVersionAtLeast() 0 7 2
A isPathExcluded() 0 10 3
A getExcludedPaths() 0 12 3
A isPathMatch() 0 19 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
declare(strict_types=1);
3
4
5
/**
6
 * Files_FullTextSearch - Index the content of your files
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\Files_FullTextSearch\Service;
32
33
34
use OCA\Files_FullTextSearch\AppInfo\Application;
35
use OCA\Files_FullTextSearch\Model\FilesDocument;
36
use OCP\FullTextSearch\Model\IIndex;
37
use OCP\IConfig;
38
use OCP\PreConditionNotMetException;
39
use OCP\Util;
40
41
42
/**
43
 * Class ConfigService
44
 *
45
 * @package OCA\Files_FullTextSearch\Service
46
 */
47
class ConfigService {
48
49
	const FILES_LOCAL = 'files_local';
50
	const FILES_EXTERNAL = 'files_external';
51
	const FILES_GROUP_FOLDERS = 'files_group_folders';
52
	const FILES_EXCLUDED = 'files_excluded';
53
	const FILES_ENCRYPTED = 'files_encrypted';
54
	const FILES_FEDERATED = 'files_federated';
55
	const FILES_SIZE = 'files_size';
56
	const FILES_OFFICE = 'files_office';
57
	const FILES_PDF = 'files_pdf';
58
	const FILES_ZIP = 'files_zip';
59
	const FILES_IMAGE = 'files_image';
60
	const FILES_AUDIO = 'files_audio';
61
62
	public $defaults = [
63
		self::FILES_LOCAL         => '1',
64
		self::FILES_EXTERNAL      => '0',
65
		self::FILES_GROUP_FOLDERS => '0',
66
		self::FILES_EXCLUDED	  => '',
67
		self::FILES_ENCRYPTED     => '0',
68
		self::FILES_FEDERATED     => '0',
69
		self::FILES_SIZE          => '20',
70
		self::FILES_PDF           => '1',
71
		self::FILES_OFFICE        => '1',
72
		self::FILES_IMAGE         => '0',
73
		self::FILES_AUDIO         => '0'
74
	];
75
76
77
	/** @var IConfig */
78
	private $config;
79
80
	/** @var string */
81
	private $userId;
82
83
	/** @var MiscService */
84
	private $miscService;
85
86
	/** @var array */
87
	private $excludedFilesCache;
88
89
90
	/**
91
	 * ConfigService constructor.
92
	 *
93
	 * @param IConfig $config
94
	 * @param string $userId
95
	 * @param MiscService $miscService
96
	 */
97
	public function __construct(IConfig $config, $userId, MiscService $miscService) {
98
		$this->config = $config;
99
		$this->userId = $userId;
100
		$this->miscService = $miscService;
101
	}
102
103
104
	/**
105
	 * @return array
106
	 */
107
	public function getConfig(): array {
108
		$keys = array_keys($this->defaults);
109
		$data = [];
110
111
		foreach ($keys as $k) {
112
			$data[$k] = $this->getAppValue($k);
113
		}
114
115
		return $data;
116
	}
117
118
119
	/**
120
	 * @param array $save
121
	 */
122
	public function setConfig(array $save) {
123
		$keys = array_keys($this->defaults);
124
125
		foreach ($keys as $k) {
126
			if (array_key_exists($k, $save)) {
127
				$this->setAppValue($k, $save[$k]);
128
			}
129
		}
130
	}
131
132
133
	/**
134
	 * Get a value by key
135
	 *
136
	 * @param string $key
137
	 *
138
	 * @return string
139
	 */
140 View Code Duplication
	public function getAppValue(string $key): string {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
141
		$defaultValue = null;
142
		if (array_key_exists($key, $this->defaults)) {
143
			$defaultValue = $this->defaults[$key];
144
		}
145
146
		return (string)$this->config->getAppValue(Application::APP_NAME, $key, $defaultValue);
147
	}
148
149
	/**
150
	 * Set a value by key
151
	 *
152
	 * @param string $key
153
	 * @param string $value
154
	 */
155
	public function setAppValue(string $key, string $value) {
156
		$this->config->setAppValue(Application::APP_NAME, $key, $value);
157
	}
158
159
	/**
160
	 * remove a key
161
	 *
162
	 * @param string $key
163
	 */
164
	public function deleteAppValue(string $key) {
165
		$this->config->deleteAppValue(Application::APP_NAME, $key);
166
	}
167
168
169
	/**
170
	 * return if option is enabled.
171
	 *
172
	 * @param string $key
173
	 *
174
	 * @return bool
175
	 */
176
	public function optionIsSelected(string $key): bool {
177
		return ($this->getAppValue($key) === '1');
178
	}
179
180
181
	/**
182
	 * Get a user value by key
183
	 *
184
	 * @param string $key
185
	 *
186
	 * @return string
187
	 */
188 View Code Duplication
	public function getUserValue(string $key): string {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
189
		$defaultValue = null;
190
		if (array_key_exists($key, $this->defaults)) {
191
			$defaultValue = $this->defaults[$key];
192
		}
193
194
		return $this->config->getUserValue(
195
			$this->userId, Application::APP_NAME, $key, $defaultValue
196
		);
197
	}
198
199
200
	/**
201
	 * Get a user value by key and user
202
	 *
203
	 * @param string $userId
204
	 * @param string $key
205
	 *
206
	 * @return string
207
	 */
208
	public function getValueForUser(string $userId, string $key): string {
209
		return $this->config->getUserValue($userId, Application::APP_NAME, $key);
210
	}
211
212
	/**
213
	 * Set a user value by key
214
	 *
215
	 * @param string $userId
216
	 * @param string $key
217
	 * @param string $value
218
	 *
219
	 * @throws PreConditionNotMetException
220
	 */
221
	public function setValueForUser(string $userId, string $key, string $value) {
222
		$this->config->setUserValue($userId, Application::APP_NAME, $key, $value);
223
	}
224
225
226
	/**
227
	 * @param string $key
228
	 *
229
	 * @param string $default
230
	 *
231
	 * @return string
232
	 */
233
	public function getSystemValue(string $key, string $default = ''): string {
234
		return $this->config->getSystemValue($key, $default);
235
	}
236
237
238
	/**
239
	 * @param FilesDocument $document
240
	 * @param string $option
241
	 */
242
	public function setDocumentIndexOption(FilesDocument $document, string $option) {
243
		$document->getIndex()
244
				 ->addOption('_' . $option, (string)$this->getAppValue($option));
245
	}
246
247
248
	/**
249
	 * @param IIndex $index
250
	 *
251
	 * @return bool
252
	 */
253
	public function compareIndexOptions(IIndex $index): bool {
254
		$options = $index->getOptions();
255
256
		$ak = array_keys($options);
257
		foreach ($ak as $k) {
258
			if (substr($k, 0, 1) === '_'
259
				&& $options[$k] !== $this->getAppValue(substr($k, 1))) {
260
				return false;
261
			}
262
		}
263
264
		return true;
265
	}
266
267
	/**
268
	 * return the cloud version.
269
	 *
270
	 * @return int
271
	 */
272
	public function getFullCloudVersion(): int {
273
		$ver = Util::getVersion();
274
275
		return ($ver[0] * 1000000) + ($ver[1] * 1000) + $ver[2];
276
	}
277
278
279
	/**
280
	 * @param $major
281
	 * @param $sub
282
	 * @param $minor
283
	 *
284
	 * @return bool
285
	 */
286
	public function isCloudVersionAtLeast($major, $sub, $minor): bool {
287
		if ($this->getFullCloudVersion() >= (($major * 1000000) + ($sub * 1000) + $minor)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $this->getFullClo...+ $sub * 1000 + $minor;.
Loading history...
288
			return true;
289
		}
290
291
		return false;
292
	}
293
294
	/**
295
	 * Check if the path is excluded via configuration
296
	 * and therefore the file shouldn't be indexed
297
	 * 
298
	 * @param $filePath The file to be indexed
299
	 * 
300
	 * @return bool
301
	 */
302
	public function isPathExcluded($filePath): bool {
303
		$excludedPaths = $this->getExcludedPaths();
304
		foreach($excludedPaths as $excludedPath) {
305
			if ($this->isPathMatch($filePath, $excludedPath)) {
306
				return true;
307
			}
308
		}
309
310
		return false;
311
	}
312
313
	private function getExcludedPaths(): array {
314
		if (is_array($this->excludedFilesCache)) {
315
			return $this->excludedFilesCache;
316
		}
317
		$csvPaths = $this->getAppValue('files_excluded');
318
		if (!$csvPaths) {
319
			return array();
320
		}
321
		$this->excludedFilesCache = array_map('trim', explode(';', $csvPaths));
322
323
		return $this->excludedFilesCache;
324
	}
325
326
	private function isPathMatch($filePath, $excludePath): bool {
327
		$len = strlen($excludePath); 
328
		if (!$len) {
329
			return false;
330
		}
331
332
		// check 'startsWith'
333
    	if ($len <= strlen($filePath) && substr($filePath, 0, $len) === $excludePath) {
334
			return true;
335
		}
336
337
		// check regex match
338
		$regexPattern = '/' . str_replace('/', '\/', $excludePath) . '/';
339
		if (preg_match($regexPattern, $filePath)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return (bool) preg_match...gexPattern, $filePath);.
Loading history...
340
			return true;
341
		}
342
343
		return false;
344
	}
345
}
346
347