ViewConfig.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
  4. *
  5. * @author John Molakvoæ <skjnldsv@protonmail.com>
  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. use OCA\Files\AppInfo\Application;
  25. use OCP\IConfig;
  26. use OCP\IUser;
  27. use OCP\IUserSession;
  28. class ViewConfig {
  29. public const CONFIG_KEY = 'files_views_configs';
  30. public const ALLOWED_CONFIGS = [
  31. [
  32. // The default sorting key for the files list view
  33. 'key' => 'sorting_mode',
  34. // null by default as views can provide default sorting key
  35. // and will fallback to it if user hasn't change it
  36. 'default' => null,
  37. ],
  38. [
  39. // The default sorting direction for the files list view
  40. 'key' => 'sorting_direction',
  41. 'default' => 'asc',
  42. 'allowed' => ['asc', 'desc'],
  43. ],
  44. [
  45. // If the navigation entry for this view is expanded or not
  46. 'key' => 'expanded',
  47. 'default' => true,
  48. 'allowed' => [true, false],
  49. ],
  50. ];
  51. protected IConfig $config;
  52. protected ?IUser $user = null;
  53. public function __construct(IConfig $config, IUserSession $userSession) {
  54. $this->config = $config;
  55. $this->user = $userSession->getUser();
  56. }
  57. /**
  58. * Get the list of all allowed user config keys
  59. * @return string[]
  60. */
  61. public function getAllowedConfigKeys(): array {
  62. return array_map(function ($config) {
  63. return $config['key'];
  64. }, self::ALLOWED_CONFIGS);
  65. }
  66. /**
  67. * Get the list of allowed config values for a given key
  68. *
  69. * @param string $key a valid config key
  70. * @return array
  71. */
  72. private function getAllowedConfigValues(string $key): array {
  73. foreach (self::ALLOWED_CONFIGS as $config) {
  74. if ($config['key'] === $key) {
  75. return $config['allowed'] ?? [];
  76. }
  77. }
  78. return [];
  79. }
  80. /**
  81. * Get the default config value for a given key
  82. *
  83. * @param string $key a valid config key
  84. * @return string|bool|null
  85. */
  86. private function getDefaultConfigValue(string $key) {
  87. foreach (self::ALLOWED_CONFIGS as $config) {
  88. if ($config['key'] === $key) {
  89. return $config['default'];
  90. }
  91. }
  92. return '';
  93. }
  94. /**
  95. * Set a user config
  96. *
  97. * @param string $view
  98. * @param string $key
  99. * @param string|bool $value
  100. * @throws \Exception
  101. * @throws \InvalidArgumentException
  102. */
  103. public function setConfig(string $view, string $key, $value): void {
  104. if ($this->user === null) {
  105. throw new \Exception('No user logged in');
  106. }
  107. if (!$view) {
  108. throw new \Exception('Unknown view');
  109. }
  110. if (!in_array($key, $this->getAllowedConfigKeys())) {
  111. throw new \InvalidArgumentException('Unknown config key');
  112. }
  113. if (!in_array($value, $this->getAllowedConfigValues($key))
  114. && !empty($this->getAllowedConfigValues($key))) {
  115. throw new \InvalidArgumentException('Invalid config value');
  116. }
  117. // Cast boolean values
  118. if (is_bool($this->getDefaultConfigValue($key))) {
  119. $value = $value === '1';
  120. }
  121. $config = $this->getConfigs();
  122. $config[$view][$key] = $value;
  123. $this->config->setUserValue($this->user->getUID(), Application::APP_ID, self::CONFIG_KEY, json_encode($config));
  124. }
  125. /**
  126. * Get the current user configs array for a given view
  127. *
  128. * @return array
  129. */
  130. public function getConfig(string $view): array {
  131. if ($this->user === null) {
  132. throw new \Exception('No user logged in');
  133. }
  134. $userId = $this->user->getUID();
  135. $configs = json_decode($this->config->getUserValue($userId, Application::APP_ID, self::CONFIG_KEY, '[]'), true);
  136. if (!isset($configs[$view])) {
  137. $configs[$view] = [];
  138. }
  139. // Extend undefined values with defaults
  140. return array_reduce(self::ALLOWED_CONFIGS, function ($carry, $config) use ($view, $configs) {
  141. $key = $config['key'];
  142. $carry[$key] = $configs[$view][$key] ?? $this->getDefaultConfigValue($key);
  143. return $carry;
  144. }, []);
  145. }
  146. /**
  147. * Get the current user configs array
  148. *
  149. * @return array
  150. */
  151. public function getConfigs(): array {
  152. if ($this->user === null) {
  153. throw new \Exception('No user logged in');
  154. }
  155. $userId = $this->user->getUID();
  156. $configs = json_decode($this->config->getUserValue($userId, Application::APP_ID, self::CONFIG_KEY, '[]'), true);
  157. $views = array_keys($configs);
  158. return array_reduce($views, function ($carry, $view) use ($configs) {
  159. $carry[$view] = $this->getConfig($view);
  160. return $carry;
  161. }, []);
  162. }
  163. }