进行了一些小优化

This commit is contained in:
2026-08-25 17:02:33 +08:00
parent 4a4009133c
commit 11f1c23fa7
12 changed files with 463 additions and 10 deletions
+5 -5
View File
@@ -188,11 +188,11 @@ class Center {
'priority' => 55,
'type' => 'panel',
],
'notif' => [
'msg' => [
'label' => __('消息通知', 'aksrt'),
'icon' => 'bell',
'priority' => 60,
'type' => 'link',
'type' => 'panel',
],
'auth' => [
'label' => __('官方认证', 'aksrt'),
@@ -307,6 +307,9 @@ class Center {
if (!in_array('settings', $order, true)) {
$order[] = 'settings';
}
if (!in_array('msg', $order, true)) {
$order[] = 'msg';
}
foreach ($order as $key) {
if (!isset($definitions[$key])) {
@@ -339,9 +342,6 @@ class Center {
$this->panels[$key] = $panel;
}
// Notif is a link entry (messages page), not a dashboard panel body.
$this->panels['notif'] = $definitions['notif'];
// Keep stable order by priority.
uasort($this->panels, static function (array $a, array $b): int {
return ((int) ($a['priority'] ?? 100)) <=> ((int) ($b['priority'] ?? 100));
+135
View File
@@ -0,0 +1,135 @@
<?php
/**
* User notification category preferences and REST persistence.
*
* @package AKSRT
*/
namespace AKSRT\User;
defined('ABSPATH') || exit;
final class NotificationPreferences {
private const META_KEY = 'aksrt_notification_preferences';
private const CATEGORIES = ['posts', 'like', 'system'];
public static function init(): void {
add_action('rest_api_init', [self::class, 'register_rest_route']);
}
public static function register_rest_route(): void {
register_rest_route('aksrt/v1', '/user/notification-preferences', [
'methods' => \WP_REST_Server::CREATABLE,
'callback' => [self::class, 'save'],
'permission_callback' => static function (): bool {
return get_current_user_id() > 0 && current_user_can('read');
},
'args' => [
'preferences' => [
'type' => 'object',
'required' => true,
'properties' => [
'posts' => ['type' => 'boolean', 'required' => true],
'like' => ['type' => 'boolean', 'required' => true],
'system' => ['type' => 'boolean', 'required' => true],
],
'additionalProperties' => false,
'validate_callback' => [self::class, 'validate_preferences'],
'sanitize_callback' => [self::class, 'sanitize_preferences'],
],
],
]);
}
/** @return array{posts:bool,like:bool,system:bool} */
public static function get(int $user_id): array {
$defaults = array_fill_keys(self::CATEGORIES, true);
$stored = get_user_meta($user_id, self::META_KEY, true);
if (!is_array($stored)) {
return $defaults;
}
foreach (self::CATEGORIES as $category) {
if (array_key_exists($category, $stored)) {
$defaults[$category] = (bool) $stored[$category];
}
}
return $defaults;
}
public static function allows(int $user_id, string $notification_type): bool {
if ($user_id <= 0) {
return false;
}
$preferences = self::get($user_id);
return $preferences[self::category_for_type($notification_type)];
}
public static function category_for_type(string $notification_type): string {
$type = sanitize_key($notification_type);
if (
in_array($type, ['posts', 'post', 'comment', 'favorite', 'pending_comments'], true)
|| str_starts_with($type, 'post_')
|| str_starts_with($type, 'comment_')
|| str_starts_with($type, 'favorite_')
) {
return 'posts';
}
if (
in_array($type, ['like', 'follow', 'followed', 'hot'], true)
|| str_starts_with($type, 'like_')
|| str_starts_with($type, 'follow_')
|| str_starts_with($type, 'followed_')
) {
return 'like';
}
return 'system';
}
public static function validate_preferences($value): bool {
if (
!is_array($value)
|| count($value) !== count(self::CATEGORIES)
|| array_diff(array_keys($value), self::CATEGORIES)
|| array_diff(self::CATEGORIES, array_keys($value))
) {
return false;
}
foreach (self::CATEGORIES as $category) {
if (!is_bool($value[$category])) {
return false;
}
}
return true;
}
/** @return array{posts:bool,like:bool,system:bool} */
public static function sanitize_preferences($value): array {
$value = is_array($value) ? $value : [];
return [
'posts' => (bool) ($value['posts'] ?? false),
'like' => (bool) ($value['like'] ?? false),
'system' => (bool) ($value['system'] ?? false),
];
}
public static function save(\WP_REST_Request $request) {
$user_id = get_current_user_id();
if ($user_id <= 0) {
return new \WP_Error('aksrt_notification_preferences_auth', __('请先登录', 'aksrt'), ['status' => 401]);
}
$preferences = self::sanitize_preferences($request->get_param('preferences'));
$result = update_user_meta($user_id, self::META_KEY, $preferences);
if ($result === false && self::get($user_id) !== $preferences) {
return new \WP_Error('aksrt_notification_preferences_save', __('消息通知设置保存失败', 'aksrt'), ['status' => 500]);
}
return rest_ensure_response([
'success' => true,
'message' => __('消息通知设置已保存', 'aksrt'),
'preferences' => $preferences,
]);
}
}