aboutsummaryrefslogtreecommitdiffstats
path: root/apps/theming/lib/Service/ThemesService.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/theming/lib/Service/ThemesService.php')
-rw-r--r--apps/theming/lib/Service/ThemesService.php188
1 files changed, 188 insertions, 0 deletions
diff --git a/apps/theming/lib/Service/ThemesService.php b/apps/theming/lib/Service/ThemesService.php
new file mode 100644
index 00000000000..f49524cb62c
--- /dev/null
+++ b/apps/theming/lib/Service/ThemesService.php
@@ -0,0 +1,188 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Theming\Service;
+
+use OCA\Theming\AppInfo\Application;
+use OCA\Theming\ITheme;
+use OCA\Theming\Themes\DarkHighContrastTheme;
+use OCA\Theming\Themes\DarkTheme;
+use OCA\Theming\Themes\DefaultTheme;
+use OCA\Theming\Themes\DyslexiaFont;
+use OCA\Theming\Themes\HighContrastTheme;
+use OCA\Theming\Themes\LightTheme;
+use OCP\IConfig;
+use OCP\IUser;
+use OCP\IUserSession;
+use Psr\Log\LoggerInterface;
+
+class ThemesService {
+ /** @var ITheme[] */
+ private array $themesProviders;
+
+ public function __construct(
+ private IUserSession $userSession,
+ private IConfig $config,
+ private LoggerInterface $logger,
+ private DefaultTheme $defaultTheme,
+ LightTheme $lightTheme,
+ private DarkTheme $darkTheme,
+ HighContrastTheme $highContrastTheme,
+ DarkHighContrastTheme $darkHighContrastTheme,
+ DyslexiaFont $dyslexiaFont,
+ ) {
+
+ // Register themes
+ $this->themesProviders = [
+ $defaultTheme->getId() => $defaultTheme,
+ $lightTheme->getId() => $lightTheme,
+ $darkTheme->getId() => $darkTheme,
+ $highContrastTheme->getId() => $highContrastTheme,
+ $darkHighContrastTheme->getId() => $darkHighContrastTheme,
+ $dyslexiaFont->getId() => $dyslexiaFont,
+ ];
+ }
+
+ /**
+ * Get the list of all registered themes
+ *
+ * @return ITheme[]
+ */
+ public function getThemes(): array {
+ // Enforced theme if configured
+ $enforcedTheme = $this->config->getSystemValueString('enforce_theme', '');
+ if ($enforcedTheme !== '') {
+ if (!isset($this->themesProviders[$enforcedTheme])) {
+ $this->logger->error('Enforced theme not found', ['theme' => $enforcedTheme]);
+ return $this->themesProviders;
+ }
+
+ $defaultTheme = $this->themesProviders[$this->defaultTheme->getId()];
+ $darkTheme = $this->themesProviders[$this->darkTheme->getId()];
+ $theme = $this->themesProviders[$enforcedTheme];
+ return [
+ // Leave the default theme as a fallback
+ $defaultTheme->getId() => $defaultTheme,
+ // Make sure we also have the dark theme to allow apps
+ // to scope sections of their UI to the dark theme
+ $darkTheme->getId() => $darkTheme,
+ // Finally, the enforced theme
+ $theme->getId() => $theme,
+ ];
+ }
+
+ return $this->themesProviders;
+ }
+
+ /**
+ * Enable a theme for the logged-in user
+ *
+ * @param ITheme $theme the theme to enable
+ * @return string[] the enabled themes
+ */
+ public function enableTheme(ITheme $theme): array {
+ $themesIds = $this->getEnabledThemes();
+
+ // If already enabled, ignore
+ if (in_array($theme->getId(), $themesIds)) {
+ return $themesIds;
+ }
+
+ /** @var ITheme[] */
+ $themes = array_filter(array_map(function ($themeId) {
+ return $this->getThemes()[$themeId];
+ }, $themesIds));
+
+ // Filtering all themes with the same type
+ $filteredThemes = array_filter($themes, function (ITheme $t) use ($theme) {
+ return $theme->getType() === $t->getType();
+ });
+
+ // Retrieve IDs only
+ /** @var string[] */
+ $filteredThemesIds = array_map(function (ITheme $t) {
+ return $t->getId();
+ }, array_values($filteredThemes));
+
+ $enabledThemes = array_merge(array_diff($themesIds, $filteredThemesIds), [$theme->getId()]);
+ $this->setEnabledThemes($enabledThemes);
+
+ return $enabledThemes;
+ }
+
+ /**
+ * Disable a theme for the logged-in user
+ *
+ * @param ITheme $theme the theme to disable
+ * @return string[] the enabled themes
+ */
+ public function disableTheme(ITheme $theme): array {
+ $themesIds = $this->getEnabledThemes();
+
+ // If enabled, removing it
+ if (in_array($theme->getId(), $themesIds)) {
+ $enabledThemes = array_diff($themesIds, [$theme->getId()]);
+ $this->setEnabledThemes($enabledThemes);
+ return $enabledThemes;
+ }
+
+ return $themesIds;
+ }
+
+ /**
+ * Check whether a theme is enabled or not
+ * for the logged-in user
+ *
+ * @return bool
+ */
+ public function isEnabled(ITheme $theme): bool {
+ $user = $this->userSession->getUser();
+ if ($user instanceof IUser) {
+ // Using keys as it's faster
+ $themes = $this->getEnabledThemes();
+ return in_array($theme->getId(), $themes);
+ }
+ return false;
+ }
+
+ /**
+ * Get the list of all enabled themes IDs for the current user.
+ *
+ * @return string[]
+ */
+ public function getEnabledThemes(): array {
+ $enforcedTheme = $this->config->getSystemValueString('enforce_theme', '');
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ if ($enforcedTheme !== '') {
+ return [$enforcedTheme];
+ }
+ return [];
+ }
+
+ $enabledThemes = json_decode($this->config->getUserValue($user->getUID(), Application::APP_ID, 'enabled-themes', '["default"]'));
+ if ($enforcedTheme !== '') {
+ return array_merge([$enforcedTheme], $enabledThemes);
+ }
+
+ try {
+ return $enabledThemes;
+ } catch (\Exception $e) {
+ return [];
+ }
+ }
+
+ /**
+ * Set the list of enabled themes
+ * for the logged-in user
+ *
+ * @param string[] $themes the list of enabled themes IDs
+ */
+ private function setEnabledThemes(array $themes): void {
+ $user = $this->userSession->getUser();
+ $this->config->setUserValue($user->getUID(), Application::APP_ID, 'enabled-themes', json_encode(array_values(array_unique($themes))));
+ }
+}