mirror of
https://github.com/chenasraf/nextcloud-forum.git
synced 2026-05-18 01:28:58 +00:00
220 lines
6.2 KiB
PHP
220 lines
6.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
// SPDX-FileCopyrightText: Chen Asraf <contact@casraf.dev>
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
namespace OCA\Forum\Service;
|
|
|
|
use OCA\Forum\AppInfo\Application;
|
|
use OCA\Forum\Db\ForumUserMapper;
|
|
use OCP\AppFramework\Db\DoesNotExistException;
|
|
use OCP\IConfig;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class UserPreferencesService {
|
|
/** Preference key for auto-subscribing to created threads */
|
|
public const PREF_AUTO_SUBSCRIBE_CREATED_THREADS = 'auto_subscribe_created_threads';
|
|
|
|
/** Preference key for auto-subscribing to threads when replying */
|
|
public const PREF_AUTO_SUBSCRIBE_REPLIED_THREADS = 'auto_subscribe_replied_threads';
|
|
|
|
/** Preference key for upload directory path */
|
|
public const PREF_UPLOAD_DIRECTORY = 'upload_directory';
|
|
|
|
/** Preference key for user signature (stored in forum_users table) */
|
|
public const PREF_SIGNATURE = 'signature';
|
|
|
|
/** Preference key for hiding edit history from others */
|
|
public const PREF_HIDE_EDIT_HISTORY = 'hide_edit_history';
|
|
|
|
/** @var array<string, mixed> Default preference values */
|
|
private const DEFAULTS = [
|
|
self::PREF_AUTO_SUBSCRIBE_CREATED_THREADS => true,
|
|
self::PREF_AUTO_SUBSCRIBE_REPLIED_THREADS => false,
|
|
self::PREF_UPLOAD_DIRECTORY => 'Forum',
|
|
self::PREF_SIGNATURE => '',
|
|
self::PREF_HIDE_EDIT_HISTORY => false,
|
|
];
|
|
|
|
/** @var array<string> List of valid preference keys */
|
|
private const VALID_KEYS = [
|
|
self::PREF_AUTO_SUBSCRIBE_CREATED_THREADS,
|
|
self::PREF_AUTO_SUBSCRIBE_REPLIED_THREADS,
|
|
self::PREF_UPLOAD_DIRECTORY,
|
|
self::PREF_SIGNATURE,
|
|
self::PREF_HIDE_EDIT_HISTORY,
|
|
];
|
|
|
|
/** @var array<string> Keys stored in forum_users table instead of config */
|
|
private const FORUM_USER_KEYS = [
|
|
self::PREF_SIGNATURE,
|
|
];
|
|
|
|
public function __construct(
|
|
private IConfig $config,
|
|
private ForumUserMapper $forumUserMapper,
|
|
private LoggerInterface $logger,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Get all user preferences
|
|
*
|
|
* @param string $userId The user ID
|
|
* @return array<string, mixed> All user preferences
|
|
*/
|
|
public function getAllPreferences(string $userId): array {
|
|
$preferences = [];
|
|
|
|
foreach (self::VALID_KEYS as $key) {
|
|
$preferences[$key] = $this->getPreference($userId, $key);
|
|
}
|
|
|
|
return $preferences;
|
|
}
|
|
|
|
/**
|
|
* Get a single user preference
|
|
*
|
|
* @param string $userId The user ID
|
|
* @param string $key The preference key
|
|
* @return mixed The preference value
|
|
* @throws \InvalidArgumentException If the preference key is invalid
|
|
*/
|
|
public function getPreference(string $userId, string $key): mixed {
|
|
if (!in_array($key, self::VALID_KEYS, true)) {
|
|
throw new \InvalidArgumentException("Invalid preference key: $key");
|
|
}
|
|
|
|
// Handle keys stored in forum_users table
|
|
if (in_array($key, self::FORUM_USER_KEYS, true)) {
|
|
return $this->getForumUserValue($userId, $key);
|
|
}
|
|
|
|
$default = self::DEFAULTS[$key] ?? null;
|
|
$value = $this->config->getUserValue($userId, Application::APP_ID, $key, $default);
|
|
|
|
return $this->parseValue($value);
|
|
}
|
|
|
|
/**
|
|
* Update multiple user preferences
|
|
*
|
|
* @param string $userId The user ID
|
|
* @param array<string, mixed> $preferences Key-value pairs of preferences to update
|
|
* @return array<string, mixed> All user preferences after update
|
|
* @throws \InvalidArgumentException If any preference key is invalid
|
|
*/
|
|
public function updatePreferences(string $userId, array $preferences): array {
|
|
// Validate all keys before updating
|
|
foreach ($preferences as $key => $value) {
|
|
if (!in_array($key, self::VALID_KEYS, true)) {
|
|
throw new \InvalidArgumentException("Invalid preference key: $key");
|
|
}
|
|
}
|
|
|
|
// Update each preference
|
|
foreach ($preferences as $key => $value) {
|
|
$this->setPreference($userId, $key, $value);
|
|
}
|
|
|
|
// Return all preferences after update
|
|
return $this->getAllPreferences($userId);
|
|
}
|
|
|
|
/**
|
|
* Set a single user preference
|
|
*
|
|
* @param string $userId The user ID
|
|
* @param string $key The preference key
|
|
* @param mixed $value The preference value
|
|
* @throws \InvalidArgumentException If the preference key is invalid
|
|
*/
|
|
public function setPreference(string $userId, string $key, mixed $value): void {
|
|
if (!in_array($key, self::VALID_KEYS, true)) {
|
|
throw new \InvalidArgumentException("Invalid preference key: $key");
|
|
}
|
|
|
|
// Handle keys stored in forum_users table
|
|
if (in_array($key, self::FORUM_USER_KEYS, true)) {
|
|
$this->setForumUserValue($userId, $key, $value);
|
|
return;
|
|
}
|
|
|
|
$stringValue = $this->stringifyValue($value);
|
|
$this->config->setUserValue($userId, Application::APP_ID, $key, $stringValue);
|
|
}
|
|
|
|
/**
|
|
* Parse a string value back to its proper type
|
|
*
|
|
* @param mixed $value The value to parse
|
|
* @return mixed The parsed value
|
|
*/
|
|
private function parseValue(mixed $value): mixed {
|
|
if ($value === 'true') {
|
|
return true;
|
|
}
|
|
if ($value === 'false') {
|
|
return false;
|
|
}
|
|
if (is_numeric($value)) {
|
|
return strpos($value, '.') !== false ? (float)$value : (int)$value;
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Convert a value to string for storage
|
|
*
|
|
* @param mixed $value The value to stringify
|
|
* @return string The stringified value
|
|
*/
|
|
private function stringifyValue(mixed $value): string {
|
|
if (is_bool($value)) {
|
|
return $value ? 'true' : 'false';
|
|
}
|
|
return (string)$value;
|
|
}
|
|
|
|
/**
|
|
* Get a value from forum_users table
|
|
*
|
|
* @param string $userId The user ID
|
|
* @param string $key The preference key
|
|
* @return mixed The value
|
|
*/
|
|
private function getForumUserValue(string $userId, string $key): mixed {
|
|
try {
|
|
$forumUser = $this->forumUserMapper->find($userId);
|
|
return match ($key) {
|
|
self::PREF_SIGNATURE => $forumUser->getSignature() ?? '',
|
|
default => self::DEFAULTS[$key] ?? null,
|
|
};
|
|
} catch (DoesNotExistException $e) {
|
|
return self::DEFAULTS[$key] ?? null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a value in forum_users table
|
|
*
|
|
* @param string $userId The user ID
|
|
* @param string $key The preference key
|
|
* @param mixed $value The value to set
|
|
*/
|
|
private function setForumUserValue(string $userId, string $key, mixed $value): void {
|
|
$forumUser = $this->forumUserMapper->createOrUpdate($userId);
|
|
|
|
match ($key) {
|
|
self::PREF_SIGNATURE => $forumUser->setSignature((string)$value),
|
|
default => null,
|
|
};
|
|
|
|
$forumUser->setUpdatedAt(time());
|
|
$this->forumUserMapper->update($forumUser);
|
|
}
|
|
}
|