'crop_image_previews', 'default' => true, 'allowed' => [true, false], ], [ // The view to start the files app in 'key' => 'default_view', 'default' => 'files', 'allowed' => ['files', 'personal'], ], [ // Whether to show the folder tree 'key' => 'folder_tree', 'default' => true, 'allowed' => [true, false], ], [ // Whether to show the files list in grid view or not 'key' => 'grid_view', 'default' => false, 'allowed' => [true, false], ], [ // Whether to show the "confirm file deletion" warning 'key' => 'show_dialog_deletion', 'default' => false, 'allowed' => [true, false], ], [ // Whether to show the "confirm file extension change" warning 'key' => 'show_dialog_file_extension', 'default' => true, 'allowed' => [true, false], ], [ // Whether to show the files extensions in the files list or not 'key' => 'show_files_extensions', 'default' => true, 'allowed' => [true, false], ], [ // Whether to show the hidden files or not in the files list 'key' => 'show_hidden', 'default' => false, 'allowed' => [true, false], ], [ // Whether to show the mime column or not 'key' => 'show_mime_column', 'default' => false, 'allowed' => [true, false], ], [ // Whether to sort favorites first in the list or not 'key' => 'sort_favorites_first', 'default' => true, 'allowed' => [true, false], ], [ // Whether to sort folders before files in the list or not 'key' => 'sort_folders_first', 'default' => true, 'allowed' => [true, false], ], [ // Whether to group images on recent files list or not 'key' => 'group_recent_files_images', 'default' => false, 'allowed' => [true, false], ], [ // Which image mime types to group in the recent files list 'key' => 'recent_files_group_mimetypes', 'default' => '', 'allowed' => [ 'image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/avif', 'image/heic', 'image/heif', ] ], [ // Time window in minutes to group files uploaded close together in the recent files list 'key' => 'recent_files_group_timespan_minutes', 'default' => 2, 'min' => 1, 'max' => 999, ], ]; protected ?IUser $user = null; public function __construct( protected IConfig $config, IUserSession $userSession, ) { $this->user = $userSession->getUser(); } /** * Get the list of all allowed user config keys * @return string[] */ public function getAllowedConfigKeys(): array { return array_map(function ($config) { return $config['key']; }, self::ALLOWED_CONFIGS); } /** * Get the list of allowed config values for a given key * * @param string $key a valid config key * @return array */ private function getAllowedConfigValues(string $key): array { foreach (self::ALLOWED_CONFIGS as $config) { if ($config['key'] === $key) { return $config['allowed']; } } return []; } /** * Get the default config value for a given key * * @param string $key a valid config key * @return string|bool|int */ private function getDefaultConfigValue(string $key) { foreach (self::ALLOWED_CONFIGS as $config) { if ($config['key'] === $key) { return $config['default']; } } return ''; } /** * Set a user config * * @param string $key * @param string|bool $value * @throws \Exception * @throws \InvalidArgumentException */ public function setConfig(string $key, $value): void { if ($this->user === null) { throw new \Exception('No user logged in'); } if (!in_array($key, $this->getAllowedConfigKeys())) { throw new \InvalidArgumentException('Unknown config key'); } if (is_string($value) && str_starts_with($value, '[') && str_ends_with($value, ']')) { $value = json_decode($value, true) ?? $value; } $config = $this->getConfigDefinition($key); if (isset($config['min'], $config['max'])) { if ((int)$value < $config['min'] || (int)$value > $config['max']) { throw new \InvalidArgumentException('Invalid config value'); } } elseif (is_array($value)) { $allowedValues = $this->getAllowedConfigValues($key); foreach ($value as $v) { if (!in_array($v, $allowedValues)) { throw new \InvalidArgumentException('Invalid config value'); } } $value = json_encode($value); } elseif (!in_array($value, $this->getAllowedConfigValues($key))) { throw new \InvalidArgumentException('Invalid config value'); } if (is_bool($value)) { $value = $value ? '1' : '0'; } $this->config->setUserValue($this->user->getUID(), Application::APP_ID, $key, $value); } /** * Get the current user configs array * * @return array */ public function getConfigs(): array { if ($this->user === null) { throw new \Exception('No user logged in'); } $userId = $this->user->getUID(); $userConfigs = array_map(function (string $key) use ($userId) { $value = $this->config->getUserValue($userId, Application::APP_ID, $key, $this->getDefaultConfigValue($key)); // If the default is expected to be a boolean, we need to cast the value if (is_bool($this->getDefaultConfigValue($key)) && is_string($value)) { return $value === '1'; } if (is_string($value) && str_starts_with($value, '[') && str_ends_with($value, ']')) { $value = json_decode($value, true) ?? $value; } return $value; }, $this->getAllowedConfigKeys()); return array_combine($this->getAllowedConfigKeys(), $userConfigs); } /** * Get the config definition for a given key * * @param string $key * @return array */ private function getConfigDefinition(string $key): array { foreach (self::ALLOWED_CONFIGS as $config) { if ($config['key'] === $key) { return $config; } } return []; } }