From c5928766562c71cb80ed4ada0dbe724914262082 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Wed, 25 Mar 2026 17:29:49 +0200 Subject: [PATCH] feat(admin): enable toggling signatures --- lib/Config/ConfigLexicon.php | 1 + lib/Controller/AdminController.php | 6 +++- lib/Service/AdminSettingsService.php | 11 ++++-- lib/Service/UserService.php | 36 ++++++++++--------- openapi-full.json | 6 ++++ openapi.json | 6 ++++ src/composables/usePublicSettings.ts | 2 ++ src/views/UserPreferencesView.vue | 5 ++- src/views/admin/AdminGeneralSettings.vue | 22 +++++++++++- .../unit/Service/AdminSettingsServiceTest.php | 10 +++--- 10 files changed, 80 insertions(+), 25 deletions(-) diff --git a/lib/Config/ConfigLexicon.php b/lib/Config/ConfigLexicon.php index 8b3f5f5..1a83f8e 100644 --- a/lib/Config/ConfigLexicon.php +++ b/lib/Config/ConfigLexicon.php @@ -25,6 +25,7 @@ class ConfigLexicon implements ILexicon { new Entry('is_initialized', ValueType::BOOL, false, 'Whether the forum has been initialized with seed data', lazy: true), new Entry('public_edit_history', ValueType::BOOL, true, 'Whether all users can view edit history of posts', lazy: true), new Entry('allow_edit_history_user_override', ValueType::BOOL, false, 'Whether users can hide their own edit history from others', lazy: true), + new Entry('enable_signatures', ValueType::BOOL, true, 'Whether signatures are displayed on posts', lazy: true), ]; } diff --git a/lib/Controller/AdminController.php b/lib/Controller/AdminController.php index cf24da5..9050682 100644 --- a/lib/Controller/AdminController.php +++ b/lib/Controller/AdminController.php @@ -201,6 +201,7 @@ class AdminController extends OCSController { * @param bool|null $allow_guest_access Allow unauthenticated users to view forum content * @param bool|null $public_edit_history Whether all users can view edit history of posts * @param bool|null $allow_edit_history_user_override Whether users can hide their own edit history from others + * @param bool|null $enable_signatures Whether signatures are displayed on posts * @return DataResponse, array{}> * * 200: Settings updated @@ -208,7 +209,7 @@ class AdminController extends OCSController { #[NoAdminRequired] #[RequirePermission('canAccessAdminTools')] #[ApiRoute(verb: 'PUT', url: '/api/admin/settings')] - public function updateSettings(?string $title = null, ?string $subtitle = null, ?bool $allow_guest_access = null, ?bool $public_edit_history = null, ?bool $allow_edit_history_user_override = null): DataResponse { + public function updateSettings(?string $title = null, ?string $subtitle = null, ?bool $allow_guest_access = null, ?bool $public_edit_history = null, ?bool $allow_edit_history_user_override = null, ?bool $enable_signatures = null): DataResponse { try { // Build settings array with only non-null values $settingsToUpdate = []; @@ -227,6 +228,9 @@ class AdminController extends OCSController { if ($allow_edit_history_user_override !== null) { $settingsToUpdate[AdminSettingsService::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE] = $allow_edit_history_user_override; } + if ($enable_signatures !== null) { + $settingsToUpdate[AdminSettingsService::SETTING_ENABLE_SIGNATURES] = $enable_signatures; + } // Update settings and return all settings $settings = $this->settingsService->updateSettings($settingsToUpdate); diff --git a/lib/Service/AdminSettingsService.php b/lib/Service/AdminSettingsService.php index 92ea2c2..3414802 100644 --- a/lib/Service/AdminSettingsService.php +++ b/lib/Service/AdminSettingsService.php @@ -30,6 +30,9 @@ class AdminSettingsService { /** Setting key for allowing user override of edit history visibility */ public const SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE = 'allow_edit_history_user_override'; + /** Setting key for enabling signatures on posts */ + public const SETTING_ENABLE_SIGNATURES = 'enable_signatures'; + /** @var array List of valid setting keys */ private const VALID_KEYS = [ self::SETTING_TITLE, @@ -38,6 +41,7 @@ class AdminSettingsService { self::SETTING_IS_INITIALIZED, self::SETTING_PUBLIC_EDIT_HISTORY, self::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE, + self::SETTING_ENABLE_SIGNATURES, ]; public function __construct( @@ -61,6 +65,7 @@ class AdminSettingsService { self::SETTING_IS_INITIALIZED => false, self::SETTING_PUBLIC_EDIT_HISTORY => true, self::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE => false, + self::SETTING_ENABLE_SIGNATURES => true, default => null, }; } @@ -98,7 +103,8 @@ class AdminSettingsService { self::SETTING_ALLOW_GUEST_ACCESS, self::SETTING_IS_INITIALIZED, self::SETTING_PUBLIC_EDIT_HISTORY, - self::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE => $this->config->getAppValueBool($key, $default, true), + self::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE, + self::SETTING_ENABLE_SIGNATURES => $this->config->getAppValueBool($key, $default, true), default => $this->config->getAppValueString($key, $default, true), }; } @@ -140,7 +146,8 @@ class AdminSettingsService { } if ($key === self::SETTING_ALLOW_GUEST_ACCESS || $key === self::SETTING_IS_INITIALIZED - || $key === self::SETTING_PUBLIC_EDIT_HISTORY || $key === self::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE) { + || $key === self::SETTING_PUBLIC_EDIT_HISTORY || $key === self::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE + || $key === self::SETTING_ENABLE_SIGNATURES) { $this->config->setAppValueBool($key, (bool)$value, true); } else { $this->config->setAppValueString($key, (string)$value, true); diff --git a/lib/Service/UserService.php b/lib/Service/UserService.php index 09e67db..be95819 100644 --- a/lib/Service/UserService.php +++ b/lib/Service/UserService.php @@ -28,6 +28,7 @@ class UserService { private UserRoleMapper $userRoleMapper, private BBCodeMapper $bbCodeMapper, private BBCodeService $bbCodeService, + private AdminSettingsService $adminSettingsService, private GuestService $guestService, private IL10N $l10n, ) { @@ -114,21 +115,24 @@ class UserService { } } - // Get signature from forum user + // Get signature from forum user (only if signatures are enabled) $signatureRaw = null; $signature = null; - try { - $forumUser = $this->forumUserMapper->find($userId); - $signatureRaw = $forumUser->getSignature(); - if ($signatureRaw !== null && $signatureRaw !== '') { - // Parse BBCode in signature - if ($bbcodes === null) { - $bbcodes = $this->bbCodeMapper->findAllEnabled(); + $signaturesEnabled = (bool)$this->adminSettingsService->getSetting(AdminSettingsService::SETTING_ENABLE_SIGNATURES); + if ($signaturesEnabled) { + try { + $forumUser = $this->forumUserMapper->find($userId); + $signatureRaw = $forumUser->getSignature(); + if ($signatureRaw !== null && $signatureRaw !== '') { + // Parse BBCode in signature + if ($bbcodes === null) { + $bbcodes = $this->bbCodeMapper->findAllEnabled(); + } + $signature = $this->bbCodeService->parse($signatureRaw, $bbcodes); } - $signature = $this->bbCodeService->parse($signatureRaw, $bbcodes); + } catch (DoesNotExistException $e) { + // No forum user record, no signature } - } catch (DoesNotExistException $e) { - // No forum user record, no signature } return [ @@ -194,11 +198,11 @@ class UserService { $rolesMap = $this->fetchRolesForUsers($realUserIds); } - // Fetch all forum users at once for signatures - $signaturesMap = $this->fetchSignaturesForUsers($realUserIds); + // Fetch signatures only if enabled + $signaturesEnabled = (bool)$this->adminSettingsService->getSetting(AdminSettingsService::SETTING_ENABLE_SIGNATURES); + $signaturesMap = $signaturesEnabled ? $this->fetchSignaturesForUsers($realUserIds) : []; - // Fetch BBCodes once for parsing all signatures (if not provided) - if ($bbcodes === null) { + if ($signaturesEnabled && $bbcodes === null) { $bbcodes = $this->bbCodeMapper->findAllEnabled(); } @@ -208,7 +212,7 @@ class UserService { $signatureRaw = $signaturesMap[$userId] ?? null; $signature = null; - if ($signatureRaw !== null && $signatureRaw !== '') { + if ($signaturesEnabled && $signatureRaw !== null && $signatureRaw !== '') { $signature = $this->bbCodeService->parse($signatureRaw, $bbcodes); } diff --git a/openapi-full.json b/openapi-full.json index dceab41..a2e24ec 100644 --- a/openapi-full.json +++ b/openapi-full.json @@ -383,6 +383,12 @@ "nullable": true, "default": null, "description": "Whether users can hide their own edit history from others" + }, + "enable_signatures": { + "type": "boolean", + "nullable": true, + "default": null, + "description": "Whether signatures are displayed on posts" } } } diff --git a/openapi.json b/openapi.json index 348dc2e..874b6ab 100644 --- a/openapi.json +++ b/openapi.json @@ -383,6 +383,12 @@ "nullable": true, "default": null, "description": "Whether users can hide their own edit history from others" + }, + "enable_signatures": { + "type": "boolean", + "nullable": true, + "default": null, + "description": "Whether signatures are displayed on posts" } } } diff --git a/src/composables/usePublicSettings.ts b/src/composables/usePublicSettings.ts index f0f06d9..8856e28 100644 --- a/src/composables/usePublicSettings.ts +++ b/src/composables/usePublicSettings.ts @@ -17,6 +17,8 @@ export interface PublicSettings { public_edit_history: boolean /** Whether users can hide their own edit history from others */ allow_edit_history_user_override: boolean + /** Whether signatures are displayed on posts */ + enable_signatures: boolean } const settings = ref(null) diff --git a/src/views/UserPreferencesView.vue b/src/views/UserPreferencesView.vue index 459f49f..2488e63 100644 --- a/src/views/UserPreferencesView.vue +++ b/src/views/UserPreferencesView.vue @@ -81,7 +81,7 @@ -
+

{{ strings.signatureTitle }}

{{ strings.signatureDesc }}

@@ -266,6 +266,9 @@ export default defineComponent({ this.formData.hide_edit_history !== this.originalData.hide_edit_history ) }, + signaturesEnabled(): boolean { + return this.publicSettings?.enable_signatures ?? true + }, showPrivacySection(): boolean { return ( !!this.publicSettings?.public_edit_history && diff --git a/src/views/admin/AdminGeneralSettings.vue b/src/views/admin/AdminGeneralSettings.vue index 2fc2a8e..5349d26 100644 --- a/src/views/admin/AdminGeneralSettings.vue +++ b/src/views/admin/AdminGeneralSettings.vue @@ -76,6 +76,15 @@
+ +
+ + {{ strings.enableSignatures }} + +

{{ strings.enableSignaturesHint }}

+
+
+
@@ -122,6 +131,7 @@ interface Settings { allow_guest_access: boolean public_edit_history: boolean allow_edit_history_user_override: boolean + enable_signatures: boolean } export default defineComponent({ @@ -157,6 +167,7 @@ export default defineComponent({ allow_guest_access: false, public_edit_history: true, allow_edit_history_user_override: false, + enable_signatures: true, } as Settings, formData: { title: '', @@ -164,6 +175,7 @@ export default defineComponent({ allow_guest_access: false, public_edit_history: true, allow_edit_history_user_override: false, + enable_signatures: true, } as Settings, strings: { @@ -199,6 +211,13 @@ export default defineComponent({ 'forum', 'When enabled, accounts can choose to hide their edit history from other accounts in their preferences.', ), + signaturesTitle: t('forum', 'Posts'), + signaturesDesc: t('forum', 'Configure posting features'), + enableSignatures: t('forum', 'Enable signatures'), + enableSignaturesHint: t( + 'forum', + 'When enabled, accounts can set a signature in their preferences that appears at the bottom of their posts.', + ), save: t('forum', 'Save'), cancel: t('forum', 'Cancel'), saveSuccess: t('forum', 'Settings saved'), @@ -213,7 +232,8 @@ export default defineComponent({ this.formData.allow_guest_access !== this.originalData.allow_guest_access || this.formData.public_edit_history !== this.originalData.public_edit_history || this.formData.allow_edit_history_user_override !== - this.originalData.allow_edit_history_user_override + this.originalData.allow_edit_history_user_override || + this.formData.enable_signatures !== this.originalData.enable_signatures ) }, }, diff --git a/tests/unit/Service/AdminSettingsServiceTest.php b/tests/unit/Service/AdminSettingsServiceTest.php index 2fbb8d3..4de8e22 100644 --- a/tests/unit/Service/AdminSettingsServiceTest.php +++ b/tests/unit/Service/AdminSettingsServiceTest.php @@ -49,7 +49,7 @@ class AdminSettingsServiceTest extends TestCase { }; }); - $this->config->expects($this->exactly(4)) + $this->config->expects($this->exactly(5)) ->method('getAppValueBool') ->willReturnCallback(function ($key, $default, $lazy) { return match ($key) { @@ -57,6 +57,7 @@ class AdminSettingsServiceTest extends TestCase { AdminSettingsService::SETTING_IS_INITIALIZED => false, AdminSettingsService::SETTING_PUBLIC_EDIT_HISTORY => true, AdminSettingsService::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE => false, + AdminSettingsService::SETTING_ENABLE_SIGNATURES => true, default => $default, }; }); @@ -64,13 +65,14 @@ class AdminSettingsServiceTest extends TestCase { $result = $this->service->getAllSettings(); $this->assertIsArray($result); - $this->assertCount(6, $result); + $this->assertCount(7, $result); $this->assertEquals('My Forum', $result[AdminSettingsService::SETTING_TITLE]); $this->assertEquals('Welcome!', $result[AdminSettingsService::SETTING_SUBTITLE]); $this->assertTrue($result[AdminSettingsService::SETTING_ALLOW_GUEST_ACCESS]); $this->assertFalse($result[AdminSettingsService::SETTING_IS_INITIALIZED]); $this->assertTrue($result[AdminSettingsService::SETTING_PUBLIC_EDIT_HISTORY]); $this->assertFalse($result[AdminSettingsService::SETTING_ALLOW_EDIT_HISTORY_USER_OVERRIDE]); + $this->assertTrue($result[AdminSettingsService::SETTING_ENABLE_SIGNATURES]); } public function testGetSettingReturnsCorrectStringValue(): void { @@ -187,7 +189,7 @@ class AdminSettingsServiceTest extends TestCase { }; }); - $this->config->expects($this->exactly(4)) + $this->config->expects($this->exactly(5)) ->method('getAppValueBool') ->willReturnCallback(function ($key, $default, $lazy) { return match ($key) { @@ -238,7 +240,7 @@ class AdminSettingsServiceTest extends TestCase { }; }); - $this->config->expects($this->exactly(4)) + $this->config->expects($this->exactly(5)) ->method('getAppValueBool') ->willReturnCallback(function ($key, $default, $lazy) { return match ($key) {