Files
wordpress-theme-aksrt/src/Auth/OAuthPart2.php
T
kate522 8c5b1555c9 refactor: flatten src/AKSRT → src (drop theme-identifier dir)
Move all domain folders from src/AKSRT/{Domain} to src/{Domain}; remap
Composer PSR-4 "AKSRT\\": "src/"; update audit script + README + ADR
paths; remove dead tools/build-psr4-map.php (scanned deleted inc/classes).
2026-08-02 22:06:06 +08:00

173 lines
6.6 KiB
PHP

<?php
/**
* @package AKSRT
*/
namespace AKSRT\Auth;
defined('ABSPATH') || exit;
trait OAuthPart2 {
public function get_frontend_bindings_data(int $user_id): array {
$providers = get_option('aksrt_oauth', []);
$bound_list = get_user_meta($user_id, 'aksrt_oauth_bindings', true) ?: [];
if (!is_array($bound_list)) $bound_list = [];
$platform_names = [
'github' => 'GitHub', 'gitee' => 'Gitee',
'qq' => 'QQ', 'google' => 'Google',
'weibo' => 'Weibo', 'weixin' => 'WeChat',
'baidu' => 'Baidu', 'alipay' => 'Alipay',
];
$icons = [
'github' => aksrt_brand_icon('github'),
'gitee' => aksrt_brand_icon('gitee'),
'qq' => aksrt_brand_icon('qq'),
'google' => aksrt_brand_icon('google'),
'weibo' => aksrt_brand_icon('weibo'),
'weixin' => aksrt_brand_icon('weixin'),
'baidu' => aksrt_brand_icon('baidu'),
'alipay' => aksrt_brand_icon('alipay'),
];
$bindings = [];
foreach ($bound_list as $binding) {
if (in_array($binding, ['github', 'gitee', 'qq', 'google', 'weibo', 'weixin', 'baidu', 'alipay'], true) && !empty($providers[$binding]['enabled'])) {
$bindings[] = [
'key' => $binding,
'name' => $platform_names[$binding] ?? ucfirst($binding),
'icon' => $icons[$binding] ?? '',
];
}
}
$available = [];
foreach (['github', 'gitee', 'qq', 'google', 'weibo', 'weixin', 'baidu', 'alipay'] as $key) {
if (in_array($key, $bound_list, true)) continue;
if (empty($providers[$key]['enabled']) || empty($providers[$key]['client_id'])) continue;
$url = $this->get_auth_url($key, 'bind');
if (empty($url)) continue;
$available[] = [
'key' => $key,
'name' => $platform_names[$key],
'icon' => $icons[$key] ?? '',
'url' => esc_url($url),
];
}
return [
'bindings' => $bindings,
'available' => $available,
];
}
public function profile_bindings(\WP_User $user): void {
$bindings = get_user_meta($user->ID, 'aksrt_oauth_bindings', true) ?: [];
if (empty($bindings)) return;
$unbind_nonce = wp_create_nonce('aksrt_oauth_unbind');
?>
<h2><?php _e('社交账号绑定', 'aksrt'); ?></h2>
<table class="form-table">
<?php foreach ($bindings as $binding): ?>
<tr>
<th scope="row"><?php echo esc_html(ucfirst($binding)); ?></th>
<td><span class="badge" style="background:#d1fae5;color:#065f46;padding:4px 12px;border-radius:12px;font-size:12px;">&#10003; <?php esc_html_e('已绑定', 'aksrt'); ?></span></td>
<td>
<button type="button" class="button button-link-delete aksrt-oauth-unbind-btn"
data-provider="<?php echo esc_attr($binding); ?>"
data-user-id="<?php echo esc_attr((string) $user->ID); ?>">
<?php _e('解除绑定', 'aksrt'); ?>
</button>
</td>
</tr>
<?php endforeach; ?>
</table>
<script>
(function(){
var nonce = <?php echo wp_json_encode($unbind_nonce); ?>;
var ajaxUrl = <?php echo wp_json_encode(admin_url('admin-ajax.php')); ?>;
document.querySelectorAll('.aksrt-oauth-unbind-btn').forEach(function(btn){
btn.addEventListener('click', function(){
var msg = <?php echo wp_json_encode(__('确定要解除绑定吗?', 'aksrt')); ?>;
if(!window.confirm(msg)) return;
var fd = new FormData();
fd.append('action', 'aksrt_oauth_unbind');
fd.append('nonce', nonce);
fd.append('provider', btn.getAttribute('data-provider'));
fd.append('userId', btn.getAttribute('data-user-id'));
fetch(ajaxUrl, { method: 'POST', credentials: 'same-origin', body: fd })
.then(function(r){ return r.json(); })
.then(function(d){ if(d && d.success){ location.reload(); } });
});
});
})();
</script>
<?php
}
public function ajax_unbind(): void {
check_ajax_referer('aksrt_oauth_unbind', 'nonce');
$provider = sanitize_key($_POST['provider'] ?? '');
$user_id = isset($_POST['userId']) ? (int) $_POST['userId'] : 0;
$current_id = get_current_user_id();
if (empty($provider) || !in_array($provider, ['github', 'gitee', 'qq', 'google', 'weibo', 'weixin', 'baidu', 'alipay'], true)) {
wp_send_json_error(400);
}
if ($current_id !== $user_id || !current_user_can('read')) {
wp_send_json_error(403);
}
$bindings = get_user_meta($current_id, 'aksrt_oauth_bindings', true) ?: [];
$bindings = array_values(array_diff($bindings, [$provider]));
update_user_meta($current_id, 'aksrt_oauth_bindings', $bindings);
delete_user_meta($current_id, "aksrt_{$provider}_id");
delete_user_meta($current_id, "aksrt_{$provider}_token");
wp_send_json_success(['unbound' => true]);
}
private function find_user_by_provider(string $provider, string $provider_id): ?\WP_User {
if (empty($provider_id)) return null;
$users = get_users([
'meta_key' => "aksrt_{$provider}_id",
'meta_value' => $provider_id,
'number' => 1,
]);
return !empty($users[0]) ? $users[0] : null;
}
private function bind_provider_to_user(int $user_id, string $provider, array $user_data): void {
if (!empty($user_data['provider_id'])) {
update_user_meta($user_id, "aksrt_{$provider}_id", $user_data['provider_id']);
}
$bindings = get_user_meta($user_id, 'aksrt_oauth_bindings', true) ?: [];
if (!is_array($bindings)) $bindings = [];
if (!in_array($provider, $bindings, true)) {
$bindings[] = $provider;
update_user_meta($user_id, 'aksrt_oauth_bindings', $bindings);
}
if (!empty($user_data['avatar_url'])) {
update_user_meta($user_id, 'aksrt_oauth_avatar', esc_url_raw($user_data['avatar_url']));
}
}
private function get_profile_url(): string {
if (function_exists('aksrt_get_user_center_url')) {
return aksrt_get_user_center_url();
}
$user = wp_get_current_user();
if ($user->ID) {
return home_url('/user/' . $user->user_nicename . '/');
}
return home_url('/');
}
}