fix(theming): use IAppConfig for all ThemingDefaults

Fixes issues where values have the wrong type.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
pull/56132/head
Ferdinand Thiessen 2025-10-28 00:35:07 +07:00 committed by backportbot[bot]
parent cd75423c85
commit a6721c95b6
6 changed files with 326 additions and 215 deletions

@ -10,6 +10,7 @@ return array(
'OCA\\Theming\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
'OCA\\Theming\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
'OCA\\Theming\\Command\\UpdateConfig' => $baseDir . '/../lib/Command/UpdateConfig.php',
'OCA\\Theming\\ConfigLexicon' => $baseDir . '/../lib/ConfigLexicon.php',
'OCA\\Theming\\Controller\\IconController' => $baseDir . '/../lib/Controller/IconController.php',
'OCA\\Theming\\Controller\\ThemingController' => $baseDir . '/../lib/Controller/ThemingController.php',
'OCA\\Theming\\Controller\\UserThemeController' => $baseDir . '/../lib/Controller/UserThemeController.php',

@ -25,6 +25,7 @@ class ComposerStaticInitTheming
'OCA\\Theming\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
'OCA\\Theming\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
'OCA\\Theming\\Command\\UpdateConfig' => __DIR__ . '/..' . '/../lib/Command/UpdateConfig.php',
'OCA\\Theming\\ConfigLexicon' => __DIR__ . '/..' . '/../lib/ConfigLexicon.php',
'OCA\\Theming\\Controller\\IconController' => __DIR__ . '/..' . '/../lib/Controller/IconController.php',
'OCA\\Theming\\Controller\\ThemingController' => __DIR__ . '/..' . '/../lib/Controller/ThemingController.php',
'OCA\\Theming\\Controller\\UserThemeController' => __DIR__ . '/..' . '/../lib/Controller/UserThemeController.php',

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Theming;
use OCP\Config\Lexicon\Entry;
use OCP\Config\Lexicon\ILexicon;
use OCP\Config\Lexicon\Strictness;
use OCP\Config\ValueType;
/**
* Config Lexicon for theming.
*
* Please Add & Manage your Config Keys in that file and keep the Lexicon up to date!
*
* {@see ILexicon}
*/
class ConfigLexicon implements ILexicon {
/** The cache buster index */
public const CACHE_BUSTER = 'cachebuster';
public const USER_THEMING_DISABLED = 'disable-user-theming';
/** Name of the software running on this instance (usually "Nextcloud") */
public const PRODUCT_NAME = 'productName';
/** Short name of this instance */
public const INSTANCE_NAME = 'name';
/** Slogan of this instance */
public const INSTANCE_SLOGAN = 'slogan';
/** Imprint URL of this instance */
public const INSTANCE_IMPRINT_URL = 'imprintUrl';
/** Privacy URL of this instance */
public const INSTANCE_PRIVACY_URL = 'privacyUrl';
// legacy theming
/** Base URL of this instance */
public const BASE_URL = 'url';
/** Base URL for documentation */
public const DOC_BASE_URL = 'docBaseUrl';
public function getStrictness(): Strictness {
return Strictness::NOTICE;
}
public function getAppConfigs(): array {
return [
// internals
new Entry(
self::CACHE_BUSTER,
ValueType::INT,
defaultRaw: 0,
definition: 'The current cache buster key for theming assets.',
),
new Entry(
self::USER_THEMING_DISABLED,
ValueType::BOOL,
defaultRaw: false,
definition: 'Whether user theming is disabled.',
),
// instance theming
new Entry(
self::PRODUCT_NAME,
ValueType::STRING,
defaultRaw: 'Nextcloud',
definition: 'The name of the software running on this instance (usually "Nextcloud").',
),
new Entry(
self::INSTANCE_NAME,
ValueType::STRING,
defaultRaw: '',
definition: 'Short name of this instance.',
),
new Entry(
self::INSTANCE_SLOGAN,
ValueType::STRING,
defaultRaw: '',
definition: 'Slogan of this instance.',
),
new Entry(
self::INSTANCE_IMPRINT_URL,
ValueType::STRING,
defaultRaw: '',
definition: 'Imprint URL of this instance.',
),
new Entry(
self::INSTANCE_PRIVACY_URL,
ValueType::STRING,
defaultRaw: '',
definition: 'Privacy URL of this instance.',
),
// legacy theming
new Entry(
self::BASE_URL,
ValueType::STRING,
defaultRaw: '',
definition: 'Base URL of this instance.',
),
new Entry(
self::DOC_BASE_URL,
ValueType::STRING,
defaultRaw: '',
definition: 'Base URL for documentation.',
),
];
}
public function getUserConfigs(): array {
return [];
}
}

@ -69,27 +69,27 @@ class ThemingDefaults extends \OC_Defaults {
}
public function getName() {
return strip_tags($this->config->getAppValue('theming', 'name', $this->name));
return strip_tags($this->appConfig->getValueString('theming', ConfigLexicon::INSTANCE_NAME, $this->name));
}
public function getHTMLName() {
return $this->config->getAppValue('theming', 'name', $this->name);
return $this->appConfig->getValueString('theming', ConfigLexicon::INSTANCE_NAME, $this->name);
}
public function getTitle() {
return strip_tags($this->config->getAppValue('theming', 'name', $this->title));
return strip_tags($this->appConfig->getValueString('theming', ConfigLexicon::INSTANCE_NAME, $this->title));
}
public function getEntity() {
return strip_tags($this->config->getAppValue('theming', 'name', $this->entity));
return strip_tags($this->appConfig->getValueString('theming', ConfigLexicon::INSTANCE_NAME, $this->entity));
}
public function getProductName() {
return strip_tags($this->config->getAppValue('theming', 'productName', $this->productName));
return strip_tags($this->appConfig->getValueString('theming', ConfigLexicon::PRODUCT_NAME, $this->productName));
}
public function getBaseUrl() {
return $this->config->getAppValue('theming', 'url', $this->url);
return $this->appConfig->getValueString('theming', ConfigLexicon::BASE_URL, $this->url);
}
/**
@ -97,20 +97,20 @@ class ThemingDefaults extends \OC_Defaults {
* @psalm-suppress InvalidReturnStatement
* @psalm-suppress InvalidReturnType
*/
public function getSlogan(?string $lang = null) {
return \OCP\Util::sanitizeHTML($this->config->getAppValue('theming', 'slogan', parent::getSlogan($lang)));
public function getSlogan(?string $lang = null): string {
return \OCP\Util::sanitizeHTML($this->appConfig->getValueString('theming', ConfigLexicon::INSTANCE_SLOGAN, parent::getSlogan($lang)));
}
public function getImprintUrl() {
return (string)$this->config->getAppValue('theming', 'imprintUrl', '');
public function getImprintUrl(): string {
return $this->appConfig->getValueString('theming', ConfigLexicon::INSTANCE_IMPRINT_URL, '');
}
public function getPrivacyUrl() {
return (string)$this->config->getAppValue('theming', 'privacyUrl', '');
public function getPrivacyUrl(): string {
return $this->appConfig->getValueString('theming', ConfigLexicon::INSTANCE_PRIVACY_URL, '');
}
public function getDocBaseUrl() {
return (string)$this->config->getAppValue('theming', 'docBaseUrl', $this->docBaseUrl);
public function getDocBaseUrl(): string {
return $this->appConfig->getValueString('theming', ConfigLexicon::DOC_BASE_URL, $this->docBaseUrl);
}
public function getShortFooter() {
@ -132,11 +132,11 @@ class ThemingDefaults extends \OC_Defaults {
$links = [
[
'text' => $this->l->t('Legal notice'),
'url' => (string)$this->getImprintUrl()
'url' => $this->getImprintUrl()
],
[
'text' => $this->l->t('Privacy policy'),
'url' => (string)$this->getPrivacyUrl()
'url' => $this->getPrivacyUrl()
],
];
@ -252,14 +252,14 @@ class ThemingDefaults extends \OC_Defaults {
* @return string
*/
public function getLogo($useSvg = true): string {
$logo = $this->config->getAppValue('theming', 'logoMime', '');
$logo = $this->appConfig->getValueString('theming', 'logoMime', '');
// short cut to avoid setting up the filesystem just to check if the logo is there
//
// explanation: if an SVG is requested and the app config value for logoMime is set then the logo is there.
// otherwise we need to check it and maybe also generate a PNG from the SVG (that's done in getImage() which
// needs to be called then)
if ($useSvg === true && $logo !== false) {
if ($useSvg === true && $logo !== '') {
$logoExists = true;
} else {
try {
@ -270,8 +270,7 @@ class ThemingDefaults extends \OC_Defaults {
}
}
$cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
$cacheBusterCounter = (string)$this->appConfig->getValueInt('theming', ConfigLexicon::CACHE_BUSTER);
if (!$logo || !$logoExists) {
if ($useSvg) {
$logo = $this->urlGenerator->imagePath('core', 'logo/logo.svg');
@ -298,28 +297,28 @@ class ThemingDefaults extends \OC_Defaults {
* @return string
*/
public function getiTunesAppId() {
return $this->config->getAppValue('theming', 'iTunesAppId', $this->iTunesAppId);
return $this->appConfig->getValueString('theming', 'iTunesAppId', $this->iTunesAppId);
}
/**
* @return string
*/
public function getiOSClientUrl() {
return $this->config->getAppValue('theming', 'iOSClientUrl', $this->iOSClientUrl);
return $this->appConfig->getValueString('theming', 'iOSClientUrl', $this->iOSClientUrl);
}
/**
* @return string
*/
public function getAndroidClientUrl() {
return $this->config->getAppValue('theming', 'AndroidClientUrl', $this->AndroidClientUrl);
return $this->appConfig->getValueString('theming', 'AndroidClientUrl', $this->AndroidClientUrl);
}
/**
* @return string
*/
public function getFDroidClientUrl() {
return $this->config->getAppValue('theming', 'FDroidClientUrl', $this->FDroidClientUrl);
return $this->appConfig->getValueString('theming', 'FDroidClientUrl', $this->FDroidClientUrl);
}
/**
@ -327,18 +326,18 @@ class ThemingDefaults extends \OC_Defaults {
* @deprecated since Nextcloud 22 - https://github.com/nextcloud/server/issues/9940
*/
public function getScssVariables() {
$cacheBuster = $this->config->getAppValue('theming', 'cachebuster', '0');
$cache = $this->cacheFactory->createDistributed('theming-' . $cacheBuster . '-' . $this->urlGenerator->getBaseUrl());
$cacheBuster = $this->appConfig->getValueInt('theming', ConfigLexicon::CACHE_BUSTER);
$cache = $this->cacheFactory->createDistributed('theming-' . (string)$cacheBuster . '-' . $this->urlGenerator->getBaseUrl());
if ($value = $cache->get('getScssVariables')) {
return $value;
}
$variables = [
'theming-cachebuster' => "'" . $cacheBuster . "'",
'theming-logo-mime' => "'" . $this->config->getAppValue('theming', 'logoMime') . "'",
'theming-background-mime' => "'" . $this->config->getAppValue('theming', 'backgroundMime') . "'",
'theming-logoheader-mime' => "'" . $this->config->getAppValue('theming', 'logoheaderMime') . "'",
'theming-favicon-mime' => "'" . $this->config->getAppValue('theming', 'faviconMime') . "'"
'theming-logo-mime' => "'" . $this->appConfig->getValueString('theming', 'logoMime') . "'",
'theming-background-mime' => "'" . $this->appConfig->getValueString('theming', 'backgroundMime') . "'",
'theming-logoheader-mime' => "'" . $this->appConfig->getValueString('theming', 'logoheaderMime') . "'",
'theming-favicon-mime' => "'" . $this->appConfig->getValueString('theming', 'faviconMime') . "'"
];
$variables['image-logo'] = "url('" . $this->imageManager->getImageUrl('logo') . "')";
@ -353,7 +352,7 @@ class ThemingDefaults extends \OC_Defaults {
$variables['color-primary-element'] = $this->util->elementColor($this->getColorPrimary());
}
if ($this->config->getAppValue('theming', 'backgroundMime', '') === 'backgroundColor') {
if ($this->appConfig->getValueString('theming', 'backgroundMime', '') === 'backgroundColor') {
$variables['image-login-plain'] = 'true';
}
@ -378,7 +377,6 @@ class ThemingDefaults extends \OC_Defaults {
if ($app === '' || $app === 'files_sharing') {
$app = 'core';
}
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
$route = false;
if ($image === 'favicon.ico' && ($this->imageManager->shouldReplaceIcons() || $this->getCustomFavicon() !== null)) {
@ -420,8 +418,8 @@ class ThemingDefaults extends \OC_Defaults {
* Increases the cache buster key
*/
public function increaseCacheBuster(): void {
$cacheBusterKey = (int)$this->config->getAppValue('theming', 'cachebuster', '0');
$this->config->setAppValue('theming', 'cachebuster', (string)($cacheBusterKey + 1));
$cacheBusterKey = $this->appConfig->getValueInt('theming', ConfigLexicon::CACHE_BUSTER);
$this->appConfig->setValueInt('theming', ConfigLexicon::CACHE_BUSTER, $cacheBusterKey + 1);
$this->cacheFactory->createDistributed('theming-')->clear();
$this->cacheFactory->createDistributed('imagePath')->clear();
}
@ -433,7 +431,18 @@ class ThemingDefaults extends \OC_Defaults {
* @param string $value
*/
public function set($setting, $value): void {
$this->appConfig->setValueString('theming', $setting, $value);
switch ($value) {
case ConfigLexicon::CACHE_BUSTER:
$this->appConfig->setValueInt('theming', ConfigLexicon::CACHE_BUSTER, (int)$value);
break;
case ConfigLexicon::USER_THEMING_DISABLED:
$value = $value === 'true' || $value === 'yes' || $value === '1';
$this->appConfig->setValueBool('theming', ConfigLexicon::USER_THEMING_DISABLED, $value);
break;
default:
$this->appConfig->setValueString('theming', $setting, $value);
break;
}
$this->increaseCacheBuster();
}
@ -443,9 +452,9 @@ class ThemingDefaults extends \OC_Defaults {
public function undoAll(): void {
// Remember the current cachebuster value, as we do not want to reset this value
// Otherwise this can lead to caching issues as the value might be known to a browser already
$cacheBusterKey = $this->config->getAppValue('theming', 'cachebuster', '0');
$this->config->deleteAppValues('theming');
$this->config->setAppValue('theming', 'cachebuster', $cacheBusterKey);
$cacheBusterKey = $this->appConfig->getValueInt('theming', ConfigLexicon::CACHE_BUSTER);
$this->appConfig->deleteApp('theming');
$this->appConfig->setValueInt('theming', ConfigLexicon::CACHE_BUSTER, $cacheBusterKey);
$this->increaseCacheBuster();
}
@ -456,7 +465,7 @@ class ThemingDefaults extends \OC_Defaults {
* @return string default value
*/
public function undo($setting): string {
$this->config->deleteAppValue('theming', $setting);
$this->appConfig->deleteKey('theming', $setting);
$this->increaseCacheBuster();
$returnValue = '';
@ -485,7 +494,7 @@ class ThemingDefaults extends \OC_Defaults {
case 'background':
case 'favicon':
$this->imageManager->delete($setting);
$this->config->deleteAppValue('theming', $setting . 'Mime');
$this->appConfig->deleteKey('theming', $setting . 'Mime');
break;
}
@ -523,6 +532,6 @@ class ThemingDefaults extends \OC_Defaults {
* Has the admin disabled user customization
*/
public function isUserThemingDisabled(): bool {
return $this->appConfig->getValueBool(Application::APP_ID, 'disable-user-theming');
return $this->appConfig->getValueBool(Application::APP_ID, ConfigLexicon::USER_THEMING_DISABLED, false);
}
}

@ -28,8 +28,7 @@ use Test\TestCase;
class ThemingDefaultsTest extends TestCase {
private IAppConfig&MockObject $appConfig;
private IConfig&MockObject $config;
private \OC_Defaults $defaults;
private IL10N|MockObject $l10n;
private IL10N&MockObject $l10n;
private IUserSession&MockObject $userSession;
private IURLGenerator&MockObject $urlGenerator;
private ICacheFactory&MockObject $cacheFactory;
@ -39,6 +38,8 @@ class ThemingDefaultsTest extends TestCase {
private ImageManager&MockObject $imageManager;
private INavigationManager&MockObject $navigationManager;
private BackgroundService&MockObject $backgroundService;
private \OC_Defaults $defaults;
private ThemingDefaults $template;
protected function setUp(): void {
@ -76,9 +77,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetNameWithDefault(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('Nextcloud');
@ -86,9 +87,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetNameWithCustom(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('MyCustomCloud');
@ -96,9 +97,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetHTMLNameWithDefault(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('Nextcloud');
@ -106,9 +107,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetHTMLNameWithCustom(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('MyCustomCloud');
@ -116,9 +117,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetTitleWithDefault(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('Nextcloud');
@ -126,9 +127,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetTitleWithCustom(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('MyCustomCloud');
@ -137,9 +138,9 @@ class ThemingDefaultsTest extends TestCase {
public function testGetEntityWithDefault(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('Nextcloud');
@ -147,9 +148,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetEntityWithCustom(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('MyCustomCloud');
@ -157,9 +158,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetBaseUrlWithDefault(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'url', $this->defaults->getBaseUrl())
->willReturn($this->defaults->getBaseUrl());
@ -167,9 +168,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetBaseUrlWithCustom(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'url', $this->defaults->getBaseUrl())
->willReturn('https://example.com/');
@ -185,9 +186,9 @@ class ThemingDefaultsTest extends TestCase {
#[\PHPUnit\Framework\Attributes\DataProvider('legalUrlProvider')]
public function testGetImprintURL(string $imprintUrl): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'imprintUrl', '')
->willReturn($imprintUrl);
@ -196,9 +197,9 @@ class ThemingDefaultsTest extends TestCase {
#[\PHPUnit\Framework\Attributes\DataProvider('legalUrlProvider')]
public function testGetPrivacyURL(string $privacyUrl): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'privacyUrl', '')
->willReturn($privacyUrl);
@ -206,9 +207,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetSloganWithDefault(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'slogan', $this->defaults->getSlogan())
->willReturn($this->defaults->getSlogan());
@ -216,9 +217,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetSloganWithCustom(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'slogan', $this->defaults->getSlogan())
->willReturn('My custom Slogan');
@ -226,9 +227,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetShortFooter(): void {
$this->config
$this->appConfig
->expects($this->exactly(5))
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
@ -242,9 +243,9 @@ class ThemingDefaultsTest extends TestCase {
public function testGetShortFooterEmptyUrl(): void {
$this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
$this->config
$this->appConfig
->expects($this->exactly(5))
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), ''],
['theming', 'name', 'Nextcloud', 'Name'],
@ -258,9 +259,9 @@ class ThemingDefaultsTest extends TestCase {
public function testGetShortFooterEmptySlogan(): void {
$this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
$this->config
$this->appConfig
->expects($this->exactly(5))
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
@ -274,9 +275,9 @@ class ThemingDefaultsTest extends TestCase {
public function testGetShortFooterImprint(): void {
$this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
$this->config
$this->appConfig
->expects($this->exactly(5))
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
@ -295,9 +296,9 @@ class ThemingDefaultsTest extends TestCase {
public function testGetShortFooterPrivacy(): void {
$this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
$this->config
$this->appConfig
->expects($this->exactly(5))
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
@ -316,9 +317,9 @@ class ThemingDefaultsTest extends TestCase {
public function testGetShortFooterAllLegalLinks(): void {
$this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
$this->config
$this->appConfig
->expects($this->exactly(5))
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
@ -345,9 +346,9 @@ class ThemingDefaultsTest extends TestCase {
#[\PHPUnit\Framework\Attributes\DataProvider('invalidLegalUrlProvider')]
public function testGetShortFooterInvalidImprint(string $invalidImprintUrl): void {
$this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
$this->config
$this->appConfig
->expects($this->exactly(5))
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
@ -362,9 +363,9 @@ class ThemingDefaultsTest extends TestCase {
#[\PHPUnit\Framework\Attributes\DataProvider('invalidLegalUrlProvider')]
public function testGetShortFooterInvalidPrivacy(string $invalidPrivacyUrl): void {
$this->navigationManager->expects($this->once())->method('getAll')->with(INavigationManager::TYPE_GUEST)->willReturn([]);
$this->config
$this->appConfig
->expects($this->exactly(5))
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'url', $this->defaults->getBaseUrl(), 'url'],
['theming', 'name', 'Nextcloud', 'Name'],
@ -476,19 +477,19 @@ class ThemingDefaultsTest extends TestCase {
}
public function testSet(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('setAppValue')
->method('setValueInt')
->with('theming', 'cachebuster', 16);
$this->appConfig
->expects($this->once())
->method('setValueString')
->with('theming', 'MySetting', 'MyValue');
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->with('theming', 'cachebuster', '0')
->willReturn('15');
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(15);
$this->cacheFactory
->expects($this->exactly(2))
->method('createDistributed')
@ -504,96 +505,105 @@ class ThemingDefaultsTest extends TestCase {
}
public function testUndoName(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('deleteAppValue')
->method('deleteKey')
->with('theming', 'name');
$this->config
->expects($this->exactly(2))
->method('getAppValue')
->willReturnMap([
['theming', 'cachebuster', '0', '15'],
['theming', 'name', 'Nextcloud', 'Nextcloud'],
]);
$this->config
$this->appConfig
->expects($this->once())
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(15);
$this->appConfig
->expects($this->once())
->method('setAppValue')
->method('getValueString')
->with('theming', 'name', 'Nextcloud')
->willReturn('Nextcloud');
$this->appConfig
->expects($this->once())
->method('setValueInt')
->with('theming', 'cachebuster', 16);
$this->assertSame('Nextcloud', $this->template->undo('name'));
}
public function testUndoBaseUrl(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('deleteAppValue')
->method('deleteKey')
->with('theming', 'url');
$this->config
->expects($this->exactly(2))
->method('getAppValue')
->willReturnMap([
['theming', 'cachebuster', '0', '15'],
['theming', 'url', $this->defaults->getBaseUrl(), $this->defaults->getBaseUrl()],
]);
$this->config
$this->appConfig
->expects($this->once())
->method('setAppValue')
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(15);
$this->appConfig
->expects($this->once())
->method('getValueString')
->with('theming', 'url', $this->defaults->getBaseUrl())
->willReturn($this->defaults->getBaseUrl());
$this->appConfig
->expects($this->once())
->method('setValueInt')
->with('theming', 'cachebuster', 16);
$this->assertSame($this->defaults->getBaseUrl(), $this->template->undo('url'));
}
public function testUndoSlogan(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('deleteAppValue')
->method('deleteKey')
->with('theming', 'slogan');
$this->config
->expects($this->exactly(2))
->method('getAppValue')
->willReturnMap([
['theming', 'cachebuster', '0', '15'],
['theming', 'slogan', $this->defaults->getSlogan(), $this->defaults->getSlogan()],
]);
$this->config
$this->appConfig
->expects($this->once())
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(15);
$this->appConfig
->expects($this->once())
->method('setAppValue')
->method('getValueString')
->with('theming', 'slogan', $this->defaults->getSlogan())
->willReturn($this->defaults->getSlogan());
$this->appConfig
->expects($this->once())
->method('setValueInt')
->with('theming', 'cachebuster', 16);
$this->assertSame($this->defaults->getSlogan(), $this->template->undo('slogan'));
}
public function testUndoPrimaryColor(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('deleteAppValue')
->method('deleteKey')
->with('theming', 'primary_color');
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->with('theming', 'cachebuster', '0')
->willReturn('15');
$this->config
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(15);
$this->appConfig
->expects($this->once())
->method('setAppValue')
->method('setValueInt')
->with('theming', 'cachebuster', 16);
$this->assertSame($this->defaults->getColorPrimary(), $this->template->undo('primary_color'));
}
public function testUndoDefaultAction(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('deleteAppValue')
->method('deleteKey')
->with('theming', 'defaultitem');
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueInt')
->with('theming', 'cachebuster', '0')
->willReturn('15');
$this->config
->willReturn(15);
$this->appConfig
->expects($this->once())
->method('setAppValue')
->method('setValueInt')
->with('theming', 'cachebuster', 16);
$this->assertSame('', $this->template->undo('defaultitem'));
@ -613,13 +623,16 @@ class ThemingDefaultsTest extends TestCase {
->method('getImage')
->with('logo')
->willThrowException(new NotFoundException());
$this->config
->expects($this->exactly(2))
->method('getAppValue')
->willReturnMap([
['theming', 'logoMime', '', ''],
['theming', 'cachebuster', '0', '0'],
]);
$this->appConfig
->expects($this->once())
->method('getValueString')
->with('theming', 'logoMime', '')
->willReturn('');
$this->appConfig
->expects($this->once())
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(0);
$this->urlGenerator->expects($this->once())
->method('imagePath')
->with('core', $withName)
@ -636,13 +649,16 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetLogoCustom(): void {
$this->config
->expects($this->exactly(2))
->method('getAppValue')
->willReturnMap([
['theming', 'logoMime', '', 'image/svg+xml'],
['theming', 'cachebuster', '0', '0'],
]);
$this->appConfig
->expects($this->once())
->method('getValueString')
->with('theming', 'logoMime', '')
->willReturn('image/svg+xml');
$this->appConfig
->expects($this->once())
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(0);
$this->urlGenerator->expects($this->once())
->method('linkToRoute')
->with('theming.Theming.getImage')
@ -651,7 +667,10 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetScssVariablesCached(): void {
$this->config->expects($this->any())->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('1');
$this->appConfig->expects($this->any())
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(1);
$this->cacheFactory->expects($this->once())
->method('createDistributed')
->with('theming-1-')
@ -661,21 +680,20 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetScssVariables(): void {
$this->config
$this->appConfig->expects($this->any())
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(0);
$this->appConfig
->expects($this->any())
->method('getAppValue')
->method('getValueString')
->willReturnMap([
['theming', 'cachebuster', '0', '0'],
['theming', 'imprintUrl', '', ''],
['theming', 'privacyUrl', '', ''],
['theming', 'logoMime', '', 'jpeg'],
['theming', 'backgroundMime', '', 'jpeg'],
['theming', 'logoheaderMime', '', 'jpeg'],
['theming', 'faviconMime', '', 'jpeg'],
]);
$this->appConfig
->expects(self::atLeastOnce())
->method('getValueString')
->willReturnMap([
['theming', 'primary_color', '', false, $this->defaults->getColorPrimary()],
['theming', 'primary_color', $this->defaults->getColorPrimary(), false, $this->defaults->getColorPrimary()],
]);
@ -716,9 +734,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetDefaultAndroidURL(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'AndroidClientUrl', 'https://play.google.com/store/apps/details?id=com.nextcloud.client')
->willReturn('https://play.google.com/store/apps/details?id=com.nextcloud.client');
@ -726,9 +744,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetCustomAndroidURL(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'AndroidClientUrl', 'https://play.google.com/store/apps/details?id=com.nextcloud.client')
->willReturn('https://play.google.com/store/apps/details?id=com.mycloud.client');
@ -736,9 +754,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetDefaultiOSURL(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'iOSClientUrl', 'https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8')
->willReturn('https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8');
@ -746,9 +764,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetCustomiOSURL(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'iOSClientUrl', 'https://geo.itunes.apple.com/us/app/nextcloud/id1125420102?mt=8')
->willReturn('https://geo.itunes.apple.com/us/app/nextcloud/id1234567890?mt=8');
@ -756,9 +774,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetDefaultiTunesAppId(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'iTunesAppId', '1125420102')
->willReturn('1125420102');
@ -766,9 +784,9 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetCustomiTunesAppId(): void {
$this->config
$this->appConfig
->expects($this->once())
->method('getAppValue')
->method('getValueString')
->with('theming', 'iTunesAppId', '1125420102')
->willReturn('1234567890');
@ -790,11 +808,11 @@ class ThemingDefaultsTest extends TestCase {
->method('get')
->with('shouldReplaceIcons')
->willReturn(true);
$this->config
$this->appConfig
->expects($this->any())
->method('getAppValue')
->with('theming', 'cachebuster', '0')
->willReturn('0');
->method('getValueInt')
->with('theming', 'cachebuster')
->willReturn(0);
$this->urlGenerator
->expects($this->any())
->method('linkToRoute')

@ -2366,40 +2366,6 @@
<code><![CDATA[getAppValue]]></code>
</DeprecatedMethod>
</file>
<file src="apps/theming/lib/ThemingDefaults.php">
<DeprecatedMethod>
<code><![CDATA[deleteAppValue]]></code>
<code><![CDATA[deleteAppValue]]></code>
<code><![CDATA[deleteAppValues]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[setAppValue]]></code>
<code><![CDATA[setAppValue]]></code>
</DeprecatedMethod>
</file>
<file src="apps/theming/lib/Util.php">
<DeprecatedMethod>
<code><![CDATA[getAppValue]]></code>