CommonSettingsTrait.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OCA\Settings\Controller;
  7. use OCA\Settings\AppInfo\Application;
  8. use OCP\AppFramework\Http\TemplateResponse;
  9. use OCP\AppFramework\Services\IInitialState;
  10. use OCP\Group\ISubAdmin;
  11. use OCP\IGroupManager;
  12. use OCP\INavigationManager;
  13. use OCP\IUserSession;
  14. use OCP\Settings\IDeclarativeManager;
  15. use OCP\Settings\IDeclarativeSettingsForm;
  16. use OCP\Settings\IIconSection;
  17. use OCP\Settings\IManager as ISettingsManager;
  18. use OCP\Settings\ISettings;
  19. use OCP\Util;
  20. /**
  21. * @psalm-import-type DeclarativeSettingsFormField from IDeclarativeSettingsForm
  22. */
  23. trait CommonSettingsTrait {
  24. /** @var ISettingsManager */
  25. private $settingsManager;
  26. /** @var INavigationManager */
  27. private $navigationManager;
  28. /** @var IUserSession */
  29. private $userSession;
  30. /** @var IGroupManager */
  31. private $groupManager;
  32. /** @var ISubAdmin */
  33. private $subAdmin;
  34. private IDeclarativeManager $declarativeSettingsManager;
  35. /** @var IInitialState */
  36. private $initialState;
  37. /**
  38. * @return array{forms: array{personal: array, admin: array}}
  39. */
  40. private function getNavigationParameters(string $currentType, string $currentSection): array {
  41. return [
  42. 'forms' => [
  43. 'personal' => $this->formatPersonalSections($currentType, $currentSection),
  44. 'admin' => $this->formatAdminSections($currentType, $currentSection),
  45. ],
  46. ];
  47. }
  48. /**
  49. * @param IIconSection[][] $sections
  50. * @psalm-param 'admin'|'personal' $type
  51. * @return list<array{anchor: string, section-name: string, active: bool, icon: string}>
  52. */
  53. protected function formatSections(array $sections, string $currentSection, string $type, string $currentType): array {
  54. $templateParameters = [];
  55. foreach ($sections as $prioritizedSections) {
  56. foreach ($prioritizedSections as $section) {
  57. if ($type === 'admin') {
  58. $settings = $this->settingsManager->getAllowedAdminSettings($section->getID(), $this->userSession->getUser());
  59. } elseif ($type === 'personal') {
  60. $settings = $this->settingsManager->getPersonalSettings($section->getID());
  61. }
  62. /** @psalm-suppress PossiblyNullArgument */
  63. $declarativeFormIDs = $this->declarativeSettingsManager->getFormIDs($this->userSession->getUser(), $type, $section->getID());
  64. if (empty($settings) && empty($declarativeFormIDs) && !($section->getID() === 'additional' && count(\OC_App::getForms('admin')) > 0)) {
  65. continue;
  66. }
  67. $icon = $section->getIcon();
  68. $active = $section->getID() === $currentSection
  69. && $type === $currentType;
  70. $templateParameters[] = [
  71. 'anchor' => $section->getID(),
  72. 'section-name' => $section->getName(),
  73. 'active' => $active,
  74. 'icon' => $icon,
  75. ];
  76. }
  77. }
  78. return $templateParameters;
  79. }
  80. protected function formatPersonalSections(string $currentType, string $currentSection): array {
  81. $sections = $this->settingsManager->getPersonalSections();
  82. return $this->formatSections($sections, $currentSection, 'personal', $currentType);
  83. }
  84. protected function formatAdminSections(string $currentType, string $currentSection): array {
  85. $sections = $this->settingsManager->getAdminSections();
  86. return $this->formatSections($sections, $currentSection, 'admin', $currentType);
  87. }
  88. /**
  89. * @param array<int, list<\OCP\Settings\ISettings>> $settings
  90. * @return array{content: string}
  91. */
  92. private function formatSettings(array $settings): array {
  93. $html = '';
  94. foreach ($settings as $prioritizedSettings) {
  95. foreach ($prioritizedSettings as $setting) {
  96. /** @var ISettings $setting */
  97. $form = $setting->getForm();
  98. $html .= $form->renderAs('')->render();
  99. }
  100. }
  101. return ['content' => $html];
  102. }
  103. /**
  104. * @psalm-param 'admin'|'personal' $type
  105. */
  106. private function getIndexResponse(string $type, string $section): TemplateResponse {
  107. if ($type === 'personal') {
  108. if ($section === 'theming') {
  109. $this->navigationManager->setActiveEntry('accessibility_settings');
  110. } else {
  111. $this->navigationManager->setActiveEntry('settings');
  112. }
  113. } elseif ($type === 'admin') {
  114. $this->navigationManager->setActiveEntry('admin_settings');
  115. }
  116. $this->declarativeSettingsManager->loadSchemas();
  117. $templateParams = [];
  118. $templateParams = array_merge($templateParams, $this->getNavigationParameters($type, $section));
  119. $templateParams = array_merge($templateParams, $this->getSettings($section));
  120. /** @psalm-suppress PossiblyNullArgument */
  121. $declarativeFormIDs = $this->declarativeSettingsManager->getFormIDs($this->userSession->getUser(), $type, $section);
  122. if (!empty($declarativeFormIDs)) {
  123. foreach ($declarativeFormIDs as $app => $ids) {
  124. /** @psalm-suppress PossiblyUndefinedArrayOffset */
  125. $templateParams['content'] .= join(array_map(fn (string $id) => '<div id="' . $app . '_' . $id . '"></div>', $ids));
  126. }
  127. Util::addScript(Application::APP_ID, 'declarative-settings-forms');
  128. /** @psalm-suppress PossiblyNullArgument */
  129. $this->initialState->provideInitialState('declarative-settings-forms', $this->declarativeSettingsManager->getFormsWithValues($this->userSession->getUser(), $type, $section));
  130. }
  131. $activeSection = $this->settingsManager->getSection($type, $section);
  132. if ($activeSection) {
  133. $templateParams['pageTitle'] = $activeSection->getName();
  134. $templateParams['activeSectionId'] = $activeSection->getID();
  135. $templateParams['activeSectionType'] = $type;
  136. }
  137. return new TemplateResponse('settings', 'settings/frame', $templateParams);
  138. }
  139. abstract protected function getSettings($section);
  140. }