进行了一些小优化
This commit is contained in:
+5
-5
@@ -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));
|
||||
|
||||
@@ -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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user