feat(admin): enable toggling signatures

This commit is contained in:
2026-03-25 17:29:49 +02:00
parent 461b28af71
commit c592876656
10 changed files with 80 additions and 25 deletions

View File

@@ -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),
];
}

View File

@@ -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<Http::STATUS_OK, array<string, mixed>, 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);

View File

@@ -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<string> 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);

View File

@@ -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);
}

View File

@@ -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"
}
}
}

View File

@@ -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"
}
}
}

View File

@@ -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<PublicSettings | null>(null)

View File

@@ -81,7 +81,7 @@
</div>
<!-- Signature Section -->
<div class="form-section">
<div v-if="signaturesEnabled" class="form-section">
<h3>{{ strings.signatureTitle }}</h3>
<p class="section-description muted">{{ strings.signatureDesc }}</p>
@@ -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 &&

View File

@@ -76,6 +76,15 @@
</div>
</FormSection>
<FormSection :title="strings.signaturesTitle" :subtitle="strings.signaturesDesc">
<div class="form-group">
<NcCheckboxRadioSwitch v-model="formData.enable_signatures" type="switch">
{{ strings.enableSignatures }}
</NcCheckboxRadioSwitch>
<p class="hint">{{ strings.enableSignaturesHint }}</p>
</div>
</FormSection>
<!-- Actions -->
<div class="form-actions">
<NcButton :disabled="saving || !hasChanges" @click="resetForm">
@@ -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
)
},
},

View File

@@ -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) {