Passed
Push — master ( ff58cd...f7cca5 )
by John
17:34 queued 12s
created

ViewConfig::getAllowedConfigValues()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 7
rs 10
c 1
b 0
f 1
1
<?php
2
/**
3
 * @copyright Copyright (c) 2023 John Molakvoæ <[email protected]>
4
 *
5
 * @author John Molakvoæ <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
namespace OCA\Files\Service;
24
25
use OCA\Files\AppInfo\Application;
26
use OCP\IConfig;
27
use OCP\IUser;
28
use OCP\IUserSession;
29
30
class ViewConfig {
31
	const CONFIG_KEY = 'files_views_configs';
32
	const ALLOWED_CONFIGS = [
33
		[
34
			// The default sorting key for the files list view
35
			'key' => 'sorting_mode',
36
			// null by default as views can provide default sorting key
37
			// and will fallback to it if user hasn't change it
38
			'default' => null,
39
		],
40
		[
41
			// The default sorting direction for the files list view
42
			'key' => 'sorting_direction',
43
			'default' => 'asc',
44
			'allowed' => ['asc', 'desc'],
45
		],
46
		[
47
			// If the navigation entry for this view is expanded or not
48
			'key' => 'expanded',
49
			'default' => true,
50
			'allowed' => [true, false],
51
		],
52
	];
53
54
	protected IConfig $config;
55
	protected ?IUser $user = null;
56
57
	public function __construct(IConfig $config, IUserSession $userSession) {
58
		$this->config = $config;
59
		$this->user = $userSession->getUser();
60
	}
61
62
	/**
63
	 * Get the list of all allowed user config keys
64
	 * @return string[]
65
	 */
66
	public function getAllowedConfigKeys(): array {
67
		return array_map(function($config) {
68
			return $config['key'];
69
		}, self::ALLOWED_CONFIGS);
70
	}
71
72
	/**
73
	 * Get the list of allowed config values for a given key
74
	 *
75
	 * @param string $key a valid config key
76
	 * @return array
77
	 */
78
	private function getAllowedConfigValues(string $key): array {
79
		foreach (self::ALLOWED_CONFIGS as $config) {
80
			if ($config['key'] === $key) {
81
				return $config['allowed'] ?? [];
82
			}
83
		}
84
		return [];
85
	}
86
87
	/**
88
	 * Get the default config value for a given key
89
	 *
90
	 * @param string $key a valid config key
91
	 * @return string|bool|null
92
	 */
93
	private function getDefaultConfigValue(string $key) {
94
		foreach (self::ALLOWED_CONFIGS as $config) {
95
			if ($config['key'] === $key) {
96
				return $config['default'];
97
			}
98
		}
99
		return '';
100
	}
101
102
	/**
103
	 * Set a user config
104
	 *
105
	 * @param string $view
106
	 * @param string $key
107
	 * @param string|bool $value
108
	 * @throws \Exception
109
	 * @throws \InvalidArgumentException
110
	 */
111
	public function setConfig(string $view, string $key, $value): void {
112
		if ($this->user === null) {
113
			throw new \Exception('No user logged in');
114
		}
115
116
		if (!$view) {
117
			throw new \Exception('Unknown view');
118
		}
119
120
		if (!in_array($key, $this->getAllowedConfigKeys())) {
121
			throw new \InvalidArgumentException('Unknown config key');
122
		}
123
	
124
		if (!in_array($value, $this->getAllowedConfigValues($key))
125
			&& !empty($this->getAllowedConfigValues($key))) {
126
			throw new \InvalidArgumentException('Invalid config value');
127
		}
128
129
		// Cast boolean values
130
		if (is_bool($this->getDefaultConfigValue($key))) {
131
			$value = $value === '1';
132
		}
133
134
		$config = $this->getConfigs();
135
		$config[$view][$key] = $value;
136
137
		$this->config->setUserValue($this->user->getUID(), Application::APP_ID, self::CONFIG_KEY, json_encode($config));
138
	}
139
140
	/**
141
	 * Get the current user configs array for a given view
142
	 *
143
	 * @return array
144
	 */
145
	public function getConfig(string $view): array {
146
		if ($this->user === null) {
147
			throw new \Exception('No user logged in');
148
		}
149
150
		$userId = $this->user->getUID();
151
		$configs = json_decode($this->config->getUserValue($userId, Application::APP_ID, self::CONFIG_KEY, '[]'), true);
152
		
153
		if (!isset($configs[$view])) {
154
			$configs[$view] = [];
155
		}
156
157
		// Extend undefined values with defaults
158
		return array_reduce(self::ALLOWED_CONFIGS, function($carry, $config) use ($view, $configs) {
159
			$key = $config['key'];
160
			$carry[$key] = $configs[$view][$key] ?? $this->getDefaultConfigValue($key);
161
			return $carry;
162
		}, []);
163
	}
164
165
	/**
166
	 * Get the current user configs array
167
	 *
168
	 * @return array
169
	 */
170
	public function getConfigs(): array {
171
		if ($this->user === null) {
172
			throw new \Exception('No user logged in');
173
		}
174
175
		$userId = $this->user->getUID();
176
		$configs = json_decode($this->config->getUserValue($userId, Application::APP_ID, self::CONFIG_KEY, '[]'), true);
177
		$views = array_keys($configs);
178
		
179
		return array_reduce($views, function($carry, $view) use ($configs) {
0 ignored issues
show
Unused Code introduced by
The import $configs is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
180
			$carry[$view] = $this->getConfig($view);
181
			return $carry;
182
		}, []);
183
	}
184
}
185