Merge pull request 'Worktree identity close p2' (#182) from worktree-identity-close-p2 into main
Reviewed-on: CYL/wordpress-theme-aksrt#182
This commit is contained in:
commit
a7489798fe
17 files changed
+709
-36
No files matched your search
@@ -325,3 +325,37 @@
|
|||||||
color: var(--color-ink-4);
|
color: var(--color-ink-4);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Tip QR upload on profile */
|
||||||
|
.aksrt-reward-upload-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.aksrt-reward-upload__preview {
|
||||||
|
min-height: 140px;
|
||||||
|
border: 1px dashed rgba(127,127,127,.35);
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 8px 0;
|
||||||
|
background: rgba(127,127,127,.04);
|
||||||
|
}
|
||||||
|
.aksrt-reward-upload__preview img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 180px;
|
||||||
|
object-fit: contain;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.aksrt-reward-upload__file {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.aksrt-reward-upload .btn-sm,
|
||||||
|
.aksrt-reward-upload .btn-primary {
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
@@ -120,6 +120,82 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ==================== 个人信息保存 ==================== */
|
/* ==================== 个人信息保存 ==================== */
|
||||||
|
|
||||||
|
/* ==================== 打赏收款码上传 ==================== */
|
||||||
|
function initRewardQrUpload() {
|
||||||
|
var form = document.getElementById('profile-form');
|
||||||
|
if (!form) return;
|
||||||
|
var nonceInput = form.querySelector('input[name="_profile_nonce"]');
|
||||||
|
var nonce = nonceInput ? nonceInput.value : '';
|
||||||
|
|
||||||
|
function setPreview(kind, url) {
|
||||||
|
var box = form.querySelector('[data-reward-preview="' + kind + '"]');
|
||||||
|
if (!box) return;
|
||||||
|
if (url) {
|
||||||
|
box.innerHTML = '<img src="' + url + '" alt="" />';
|
||||||
|
} else {
|
||||||
|
box.innerHTML = '<span class="muted-2-color em09">未上传</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form.querySelectorAll('[data-reward-upload]').forEach(function (btn) {
|
||||||
|
btn.addEventListener('click', function () {
|
||||||
|
var kind = btn.getAttribute('data-reward-upload');
|
||||||
|
var fileInput = form.querySelector('input[data-reward-kind="' + kind + '"]');
|
||||||
|
if (fileInput) fileInput.click();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
form.querySelectorAll('[data-reward-clear]').forEach(function (btn) {
|
||||||
|
btn.addEventListener('click', function () {
|
||||||
|
var kind = btn.getAttribute('data-reward-clear');
|
||||||
|
var hidden = form.querySelector('#rewards-' + kind);
|
||||||
|
var fileInput = form.querySelector('input[data-reward-kind="' + kind + '"]');
|
||||||
|
if (hidden) hidden.value = '';
|
||||||
|
if (fileInput) fileInput.value = '';
|
||||||
|
setPreview(kind, '');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
form.querySelectorAll('input[data-reward-kind]').forEach(function (input) {
|
||||||
|
input.addEventListener('change', function () {
|
||||||
|
var kind = input.getAttribute('data-reward-kind');
|
||||||
|
var file = input.files && input.files[0];
|
||||||
|
if (!file || !kind) return;
|
||||||
|
if (file.size > 2 * 1024 * 1024) {
|
||||||
|
showToast('图片不能超过 2MB');
|
||||||
|
input.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var body = new FormData();
|
||||||
|
body.append('action', 'aksrt_upload_reward_qr');
|
||||||
|
body.append('_profile_nonce', nonce);
|
||||||
|
body.append('kind', kind);
|
||||||
|
body.append('file', file);
|
||||||
|
showToast(i18n.saving || '上传中…');
|
||||||
|
fetch(ajaxUrl, { method: 'POST', body: body, credentials: 'same-origin' })
|
||||||
|
.then(function (r) { return r.json(); })
|
||||||
|
.then(function (res) {
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
var hidden = form.querySelector('#rewards-' + kind);
|
||||||
|
if (hidden) hidden.value = String(res.data.id || '');
|
||||||
|
setPreview(kind, res.data.url || '');
|
||||||
|
showToast(res.data.message || '上传成功');
|
||||||
|
} else {
|
||||||
|
showToast((res && res.data && res.data.message) || '上传失败');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
showToast(i18n.networkError || '网络错误');
|
||||||
|
})
|
||||||
|
.finally(function () {
|
||||||
|
input.value = '';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function initProfileForm() {
|
function initProfileForm() {
|
||||||
var form = document.getElementById('profile-form');
|
var form = document.getElementById('profile-form');
|
||||||
if (!form) return;
|
if (!form) return;
|
||||||
@@ -676,6 +752,7 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
initDashboardNavigation();
|
initDashboardNavigation();
|
||||||
initProfileForm();
|
initProfileForm();
|
||||||
|
initRewardQrUpload();
|
||||||
initUnfavorite();
|
initUnfavorite();
|
||||||
initNotifications();
|
initNotifications();
|
||||||
initSettings();
|
initSettings();
|
||||||
@@ -683,6 +760,7 @@
|
|||||||
} else {
|
} else {
|
||||||
initDashboardNavigation();
|
initDashboardNavigation();
|
||||||
initProfileForm();
|
initProfileForm();
|
||||||
|
initRewardQrUpload();
|
||||||
initUnfavorite();
|
initUnfavorite();
|
||||||
initNotifications();
|
initNotifications();
|
||||||
initSettings();
|
initSettings();
|
||||||
|
|||||||
@@ -373,6 +373,9 @@ if (class_exists('AKSRT_User_Badges_Admin')) {
|
|||||||
if (class_exists('AKSRT_User_Level')) {
|
if (class_exists('AKSRT_User_Level')) {
|
||||||
AKSRT_User_Level::get_instance()->init();
|
AKSRT_User_Level::get_instance()->init();
|
||||||
}
|
}
|
||||||
|
if (class_exists('AKSRT_User_Metrics')) {
|
||||||
|
AKSRT_User_Metrics::get_instance()->init();
|
||||||
|
}
|
||||||
|
|
||||||
// WordPress 原生侧栏:支付/订单运营中心(zibll zibpay 对齐)
|
// WordPress 原生侧栏:支付/订单运营中心(zibll zibpay 对齐)
|
||||||
if (is_admin() && class_exists('AKSRT_Admin_Pay_Menus')) {
|
if (is_admin() && class_exists('AKSRT_Admin_Pay_Menus')) {
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ require_once AKSRT_DIR . '/inc/classes/class-aksrt-user-balance-admin.php';
|
|||||||
require_once AKSRT_DIR . '/inc/classes/class-aksrt-user-badges.php';
|
require_once AKSRT_DIR . '/inc/classes/class-aksrt-user-badges.php';
|
||||||
require_once AKSRT_DIR . '/inc/classes/class-aksrt-user-badges-admin.php';
|
require_once AKSRT_DIR . '/inc/classes/class-aksrt-user-badges-admin.php';
|
||||||
require_once AKSRT_DIR . '/inc/classes/class-aksrt-user-level.php';
|
require_once AKSRT_DIR . '/inc/classes/class-aksrt-user-level.php';
|
||||||
|
require_once AKSRT_DIR . '/inc/classes/class-aksrt-user-metrics.php';
|
||||||
|
|
||||||
// 加载数据表迁移器(CMS / 积分 / 下载 token)
|
// 加载数据表迁移器(CMS / 积分 / 下载 token)
|
||||||
require_once AKSRT_DIR . '/inc/classes/db-traits/trait-aksrt-db-migrator-part-2.php';
|
require_once AKSRT_DIR . '/inc/classes/db-traits/trait-aksrt-db-migrator-part-2.php';
|
||||||
|
|||||||
@@ -67,9 +67,7 @@ class AKSRT_Comment_Actions {
|
|||||||
register_rest_route('aksrt/v1', '/comment/moderate', [
|
register_rest_route('aksrt/v1', '/comment/moderate', [
|
||||||
'methods' => 'POST',
|
'methods' => 'POST',
|
||||||
'callback' => [$this, 'moderate_comment'],
|
'callback' => [$this, 'moderate_comment'],
|
||||||
'permission_callback' => function () {
|
'permission_callback' => [$this, 'check_moderate_permission'],
|
||||||
return current_user_can('moderate_comments');
|
|
||||||
},
|
|
||||||
'args' => [
|
'args' => [
|
||||||
'comment_id' => ['required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint'],
|
'comment_id' => ['required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint'],
|
||||||
'status' => ['required' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field'],
|
'status' => ['required' => true, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field'],
|
||||||
|
|||||||
@@ -64,7 +64,15 @@ class AKSRT_Rebate {
|
|||||||
'note' => $note,
|
'note' => $note,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $result ? (int) $wpdb->insert_id : 0;
|
$id = $result ? (int) $wpdb->insert_id : 0;
|
||||||
|
if ($id > 0) {
|
||||||
|
do_action('aksrt_pay_rebate_added', $user_id, $amount, [
|
||||||
|
'rebate_id' => $id,
|
||||||
|
'order_number' => $order_number,
|
||||||
|
'type' => $type,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,7 +39,15 @@ class AKSRT_Revenue {
|
|||||||
'created_at' => current_time('mysql'),
|
'created_at' => current_time('mysql'),
|
||||||
], ['%d', '%s', '%f', '%s', '%s', '%s']);
|
], ['%d', '%s', '%f', '%s', '%s', '%s']);
|
||||||
|
|
||||||
return (int) $wpdb->insert_id;
|
$id = (int) $wpdb->insert_id;
|
||||||
|
if ($id > 0) {
|
||||||
|
do_action('aksrt_creator_income_added', $user_id, $amount, [
|
||||||
|
'order_number' => $order_number,
|
||||||
|
'type' => $type,
|
||||||
|
'revenue_id' => $id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ class AKSRT_Signin {
|
|||||||
return new WP_Error('aksrt_signin_dup', __('签到失败', 'aksrt'), ['status' => 409]);
|
return new WP_Error('aksrt_signin_dup', __('签到失败', 'aksrt'), ['status' => 409]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_action('aksrt_user_signed_in', $user_id);
|
||||||
|
|
||||||
if ($reward > 0) {
|
if ($reward > 0) {
|
||||||
if (class_exists('AKSRT_Points_Free')) {
|
if (class_exists('AKSRT_Points_Free')) {
|
||||||
$granted = AKSRT_Points_Free::grant_amount($user_id, $reward, 'sign_in', ['type' => 'user', 'id' => $user_id]);
|
$granted = AKSRT_Points_Free::grant_amount($user_id, $reward, 'sign_in', ['type' => 'user', 'id' => $user_id]);
|
||||||
|
|||||||
@@ -477,11 +477,10 @@ class AKSRT_User_Badges {
|
|||||||
return (float) $counts;
|
return (float) $counts;
|
||||||
|
|
||||||
case 'followed':
|
case 'followed':
|
||||||
$meta = get_user_meta($user_id, 'followed-user', true);
|
if (class_exists('AKSRT_Follow')) {
|
||||||
if (!is_array($meta)) {
|
return (float) AKSRT_Follow::get_instance()->get_follower_count($user_id);
|
||||||
$meta = get_user_meta($user_id, 'aksrt_followed_users', true);
|
|
||||||
}
|
}
|
||||||
return is_array($meta) ? (float) count($meta) : 0.0;
|
return 0.0;
|
||||||
|
|
||||||
case 'like':
|
case 'like':
|
||||||
return (float) get_user_meta($user_id, 'aksrt_posts_like_sum', true);
|
return (float) get_user_meta($user_id, 'aksrt_posts_like_sum', true);
|
||||||
@@ -505,7 +504,23 @@ class AKSRT_User_Badges {
|
|||||||
return (float) get_user_meta($user_id, 'aksrt_bbs_score_sum', true);
|
return (float) get_user_meta($user_id, 'aksrt_bbs_score_sum', true);
|
||||||
|
|
||||||
case 'views':
|
case 'views':
|
||||||
return (float) get_user_meta($user_id, 'aksrt_posts_views_sum', true);
|
$sum = (float) get_user_meta($user_id, 'aksrt_posts_views_sum', true);
|
||||||
|
if ($sum > 0) {
|
||||||
|
return $sum;
|
||||||
|
}
|
||||||
|
// Lazy backfill once from postmeta.
|
||||||
|
global $wpdb;
|
||||||
|
$sum = (float) $wpdb->get_var($wpdb->prepare(
|
||||||
|
"SELECT COALESCE(SUM(CAST(pm.meta_value AS UNSIGNED)),0)
|
||||||
|
FROM {$wpdb->posts} p
|
||||||
|
INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = 'aksrt_post_views'
|
||||||
|
WHERE p.post_author = %d AND p.post_type = 'post' AND p.post_status = 'publish'",
|
||||||
|
$user_id
|
||||||
|
));
|
||||||
|
if ($sum > 0) {
|
||||||
|
update_user_meta($user_id, 'aksrt_posts_views_sum', $sum);
|
||||||
|
}
|
||||||
|
return $sum;
|
||||||
|
|
||||||
case 'pay_income':
|
case 'pay_income':
|
||||||
return (float) get_user_meta($user_id, 'aksrt_pay_income_sum', true);
|
return (float) get_user_meta($user_id, 'aksrt_pay_income_sum', true);
|
||||||
|
|||||||
@@ -0,0 +1,361 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* User metric accumulators for medal get_type + integral XP.
|
||||||
|
*
|
||||||
|
* Maintains user_meta counters used by AKSRT_User_Badges::metric_value()
|
||||||
|
* and grants level XP / re-evaluates medals on the same events as free points.
|
||||||
|
*
|
||||||
|
* @package AKSRT
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined('ABSPATH') || exit;
|
||||||
|
|
||||||
|
class AKSRT_User_Metrics {
|
||||||
|
|
||||||
|
public const META_POST_LIKE_SUM = 'aksrt_posts_like_sum';
|
||||||
|
public const META_COMMENT_LIKE_SUM = 'aksrt_comment_like_sum';
|
||||||
|
public const META_POSTS_VIEWS_SUM = 'aksrt_posts_views_sum';
|
||||||
|
public const META_BBS_ADOPT = 'aksrt_bbs_adopt_count';
|
||||||
|
public const META_BBS_COMMENT_HOT = 'aksrt_bbs_comment_hot_count';
|
||||||
|
public const META_BBS_POST_HOT = 'aksrt_bbs_post_hot_count';
|
||||||
|
public const META_BBS_ESSENCE = 'aksrt_bbs_essence_count';
|
||||||
|
public const META_BBS_SCORE = 'aksrt_bbs_score_sum';
|
||||||
|
public const META_PAY_INCOME = 'aksrt_pay_income_sum';
|
||||||
|
public const META_PAY_REBATE = 'aksrt_pay_rebate_sum';
|
||||||
|
public const META_CHECKIN_ALL_DAY = 'aksrt_checkin_all_day';
|
||||||
|
|
||||||
|
/** @var self|null */
|
||||||
|
private static $instance = null;
|
||||||
|
|
||||||
|
public static function get_instance(): self {
|
||||||
|
if (null === self::$instance) {
|
||||||
|
self::$instance = new self();
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function init(): void {
|
||||||
|
add_action('aksrt_post_liked', [$this, 'on_post_liked'], 20, 3);
|
||||||
|
add_action('aksrt_comment_liked', [$this, 'on_comment_liked'], 20, 3);
|
||||||
|
add_action('aksrt_post_favorited', [$this, 'on_post_favorited'], 20, 3);
|
||||||
|
add_action('aksrt_user_followed', [$this, 'on_user_followed'], 20, 2);
|
||||||
|
add_action('aksrt_post_viewed', [$this, 'on_post_viewed'], 20, 2);
|
||||||
|
|
||||||
|
add_action('aksrt_forum_topic_featured', [$this, 'on_forum_topic_featured'], 20, 2);
|
||||||
|
add_action('aksrt_forum_reply_adopted', [$this, 'on_forum_reply_adopted'], 20, 3);
|
||||||
|
add_action('aksrt_forum_comment_hot', [$this, 'on_forum_comment_hot'], 20, 2);
|
||||||
|
add_action('aksrt_forum_topic_hot', [$this, 'on_forum_topic_hot'], 20, 2);
|
||||||
|
add_action('aksrt_forum_topic_scored', [$this, 'on_forum_topic_scored'], 20, 3);
|
||||||
|
|
||||||
|
add_action('aksrt_user_signed_in', [$this, 'on_user_signed_in'], 20, 1);
|
||||||
|
add_action('aksrt_creator_income_added', [$this, 'on_creator_income_added'], 20, 3);
|
||||||
|
add_action('aksrt_pay_rebate_added', [$this, 'on_pay_rebate_added'], 20, 3);
|
||||||
|
|
||||||
|
// Free-points / social hooks also feed level XP.
|
||||||
|
add_action('aksrt_post_liked', [$this, 'level_on_post_liked'], 25, 3);
|
||||||
|
add_action('aksrt_comment_liked', [$this, 'level_on_comment_liked'], 25, 3);
|
||||||
|
add_action('aksrt_post_favorited', [$this, 'level_on_post_favorited'], 25, 3);
|
||||||
|
add_action('aksrt_user_followed', [$this, 'level_on_user_followed'], 25, 2);
|
||||||
|
add_action('aksrt_forum_topic_featured', [$this, 'level_on_forum_topic_featured'], 25, 2);
|
||||||
|
add_action('aksrt_forum_reply_adopted', [$this, 'level_on_forum_reply_adopted'], 25, 3);
|
||||||
|
add_action('aksrt_forum_comment_hot', [$this, 'level_on_forum_comment_hot'], 25, 2);
|
||||||
|
add_action('aksrt_forum_topic_hot', [$this, 'level_on_forum_topic_hot'], 25, 2);
|
||||||
|
add_action('aksrt_forum_topic_scored', [$this, 'level_on_forum_topic_scored'], 25, 3);
|
||||||
|
add_action('aksrt_forum_topic_created', [$this, 'level_on_forum_topic_created'], 25, 2);
|
||||||
|
add_action('aksrt_user_signed_in', [$this, 'level_on_user_signed_in'], 25, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function bump_user_meta(int $user_id, string $meta_key, float $delta = 1.0): float {
|
||||||
|
if ($user_id <= 0 || $meta_key === '' || $delta == 0.0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
$current = (float) get_user_meta($user_id, $meta_key, true);
|
||||||
|
$next = max(0.0, $current + $delta);
|
||||||
|
update_user_meta($user_id, $meta_key, $next);
|
||||||
|
return $next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function reevaluate_medals(int $user_id): void {
|
||||||
|
if ($user_id > 0 && class_exists('AKSRT_User_Badges') && method_exists('AKSRT_User_Badges', 'auto_evaluate')) {
|
||||||
|
AKSRT_User_Badges::auto_evaluate($user_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function on_post_liked(int $post_id, int $actor_id, bool $active): void {
|
||||||
|
$post = get_post($post_id);
|
||||||
|
if (!$post instanceof WP_Post || $post->post_type !== 'post') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$author = (int) $post->post_author;
|
||||||
|
if ($author <= 0 || $author === $actor_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($author, self::META_POST_LIKE_SUM, $active ? 1.0 : -1.0);
|
||||||
|
if ($active) {
|
||||||
|
self::reevaluate_medals($author);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function on_comment_liked(int $comment_id, int $actor_id, bool $active): void {
|
||||||
|
$comment = get_comment($comment_id);
|
||||||
|
if (!$comment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$author = (int) $comment->user_id;
|
||||||
|
if ($author <= 0 || $author === $actor_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($author, self::META_COMMENT_LIKE_SUM, $active ? 1.0 : -1.0);
|
||||||
|
if ($active) {
|
||||||
|
self::reevaluate_medals($author);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function on_post_favorited(int $post_id, int $actor_id, bool $active): void {
|
||||||
|
unset($post_id, $actor_id, $active);
|
||||||
|
// Favorite is free-points / level only; no dedicated medal get_type.
|
||||||
|
}
|
||||||
|
|
||||||
|
public function on_user_followed(int $follower_id, int $following_id): void {
|
||||||
|
unset($follower_id);
|
||||||
|
if ($following_id > 0) {
|
||||||
|
self::reevaluate_medals($following_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function on_post_viewed(int $post_id, int $viewer_id = 0): void {
|
||||||
|
unset($viewer_id);
|
||||||
|
$post = get_post($post_id);
|
||||||
|
if (!$post instanceof WP_Post || $post->post_type !== 'post') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$author = (int) $post->post_author;
|
||||||
|
if ($author <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($author, self::META_POSTS_VIEWS_SUM, 1.0);
|
||||||
|
// Cheap throttle: reevaluate every 50 views on author sum.
|
||||||
|
$sum = (float) get_user_meta($author, self::META_POSTS_VIEWS_SUM, true);
|
||||||
|
if (((int) $sum % 50) === 0) {
|
||||||
|
self::reevaluate_medals($author);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $topic_id
|
||||||
|
* @param int $author_id
|
||||||
|
*/
|
||||||
|
public function on_forum_topic_featured($topic_id, $author_id = 0): void {
|
||||||
|
$author_id = (int) $author_id;
|
||||||
|
if ($author_id <= 0) {
|
||||||
|
$post = get_post((int) $topic_id);
|
||||||
|
$author_id = $post ? (int) $post->post_author : 0;
|
||||||
|
}
|
||||||
|
if ($author_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($author_id, self::META_BBS_ESSENCE, 1.0);
|
||||||
|
self::reevaluate_medals($author_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $topic_id
|
||||||
|
* @param int $comment_id
|
||||||
|
* @param int $adoptee_id
|
||||||
|
*/
|
||||||
|
public function on_forum_reply_adopted($topic_id, $comment_id, $adoptee_id): void {
|
||||||
|
unset($topic_id, $comment_id);
|
||||||
|
$adoptee_id = (int) $adoptee_id;
|
||||||
|
if ($adoptee_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($adoptee_id, self::META_BBS_ADOPT, 1.0);
|
||||||
|
self::reevaluate_medals($adoptee_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $comment_id
|
||||||
|
* @param int $author_id
|
||||||
|
*/
|
||||||
|
public function on_forum_comment_hot($comment_id, $author_id = 0): void {
|
||||||
|
$author_id = (int) $author_id;
|
||||||
|
if ($author_id <= 0) {
|
||||||
|
$c = get_comment((int) $comment_id);
|
||||||
|
$author_id = $c ? (int) $c->user_id : 0;
|
||||||
|
}
|
||||||
|
if ($author_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($author_id, self::META_BBS_COMMENT_HOT, 1.0);
|
||||||
|
self::reevaluate_medals($author_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $topic_id
|
||||||
|
* @param int $author_id
|
||||||
|
*/
|
||||||
|
public function on_forum_topic_hot($topic_id, $author_id = 0): void {
|
||||||
|
$author_id = (int) $author_id;
|
||||||
|
if ($author_id <= 0) {
|
||||||
|
$post = get_post((int) $topic_id);
|
||||||
|
$author_id = $post ? (int) $post->post_author : 0;
|
||||||
|
}
|
||||||
|
if ($author_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($author_id, self::META_BBS_POST_HOT, 1.0);
|
||||||
|
self::reevaluate_medals($author_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $topic_id
|
||||||
|
* @param int $author_id
|
||||||
|
* @param float $delta
|
||||||
|
*/
|
||||||
|
public function on_forum_topic_scored($topic_id, $author_id, $delta = 0): void {
|
||||||
|
unset($topic_id);
|
||||||
|
$author_id = (int) $author_id;
|
||||||
|
$delta = (float) $delta;
|
||||||
|
if ($author_id <= 0 || $delta == 0.0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($author_id, self::META_BBS_SCORE, $delta);
|
||||||
|
self::reevaluate_medals($author_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function on_user_signed_in(int $user_id): void {
|
||||||
|
if ($user_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($user_id, self::META_CHECKIN_ALL_DAY, 1.0);
|
||||||
|
self::reevaluate_medals($user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $user_id
|
||||||
|
* @param float $amount
|
||||||
|
* @param array $context
|
||||||
|
*/
|
||||||
|
public function on_creator_income_added($user_id, $amount, $context = []): void {
|
||||||
|
unset($context);
|
||||||
|
$user_id = (int) $user_id;
|
||||||
|
$amount = (float) $amount;
|
||||||
|
if ($user_id <= 0 || $amount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($user_id, self::META_PAY_INCOME, $amount);
|
||||||
|
self::reevaluate_medals($user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $user_id
|
||||||
|
* @param float $amount
|
||||||
|
* @param array $context
|
||||||
|
*/
|
||||||
|
public function on_pay_rebate_added($user_id, $amount, $context = []): void {
|
||||||
|
unset($context);
|
||||||
|
$user_id = (int) $user_id;
|
||||||
|
$amount = (float) $amount;
|
||||||
|
if ($user_id <= 0 || $amount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::bump_user_meta($user_id, self::META_PAY_REBATE, $amount);
|
||||||
|
self::reevaluate_medals($user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- level XP bridges ---------- */
|
||||||
|
|
||||||
|
private static function level_add(int $user_id, string $key): void {
|
||||||
|
if ($user_id > 0 && class_exists('AKSRT_User_Level')) {
|
||||||
|
AKSRT_User_Level::add($user_id, $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_post_liked(int $post_id, int $actor_id, bool $active): void {
|
||||||
|
if (!$active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$post = get_post($post_id);
|
||||||
|
if (!$post instanceof WP_Post) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$author = (int) $post->post_author;
|
||||||
|
if ($author > 0 && $author !== $actor_id) {
|
||||||
|
self::level_add($author, 'post_like');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_comment_liked(int $comment_id, int $actor_id, bool $active): void {
|
||||||
|
if (!$active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$c = get_comment($comment_id);
|
||||||
|
if (!$c) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$author = (int) $c->user_id;
|
||||||
|
if ($author > 0 && $author !== $actor_id) {
|
||||||
|
self::level_add($author, 'comment_like');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_post_favorited(int $post_id, int $actor_id, bool $active): void {
|
||||||
|
if (!$active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$post = get_post($post_id);
|
||||||
|
if (!$post instanceof WP_Post) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$author = (int) $post->post_author;
|
||||||
|
if ($author > 0 && $author !== $actor_id) {
|
||||||
|
self::level_add($author, 'post_favorite');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_user_followed(int $follower_id, int $following_id): void {
|
||||||
|
unset($follower_id);
|
||||||
|
self::level_add((int) $following_id, 'followed');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_forum_topic_featured($topic_id, $author_id = 0): void {
|
||||||
|
unset($topic_id);
|
||||||
|
self::level_add((int) $author_id, 'bbs_essence');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_forum_reply_adopted($topic_id, $comment_id, $adoptee_id): void {
|
||||||
|
unset($topic_id, $comment_id);
|
||||||
|
self::level_add((int) $adoptee_id, 'bbs_adopt');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_forum_comment_hot($comment_id, $author_id = 0): void {
|
||||||
|
unset($comment_id);
|
||||||
|
self::level_add((int) $author_id, 'bbs_comment_hot');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_forum_topic_hot($topic_id, $author_id = 0): void {
|
||||||
|
unset($topic_id);
|
||||||
|
self::level_add((int) $author_id, 'bbs_posts_hot');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_forum_topic_scored($topic_id, $author_id, $delta = 0): void {
|
||||||
|
unset($topic_id);
|
||||||
|
if ((float) $delta > 0) {
|
||||||
|
self::level_add((int) $author_id, 'bbs_score_extra');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $user_id
|
||||||
|
* @param int $topic_id
|
||||||
|
*/
|
||||||
|
public function level_on_forum_topic_created($user_id, $topic_id = 0): void {
|
||||||
|
unset($topic_id);
|
||||||
|
self::level_add((int) $user_id, 'bbs_posts_new');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function level_on_user_signed_in(int $user_id): void {
|
||||||
|
// Sign-in XP: use sign_in key once/day via existing login guard path as well.
|
||||||
|
self::level_add($user_id, 'sign_in');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -942,6 +942,59 @@ add_action('wp_ajax_aksrt_save_profile', function () {
|
|||||||
wp_send_json_success(['message' => __('保存成功!', 'aksrt')]);
|
wp_send_json_success(['message' => __('保存成功!', 'aksrt')]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// AJAX: 上传打赏收款码
|
||||||
|
// ============================================================
|
||||||
|
add_action('wp_ajax_aksrt_upload_reward_qr', function () {
|
||||||
|
if (!isset($_POST['_profile_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_profile_nonce'])), 'aksrt_profile_save')) {
|
||||||
|
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
|
||||||
|
}
|
||||||
|
$user_id = get_current_user_id();
|
||||||
|
if ($user_id <= 0) {
|
||||||
|
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
|
||||||
|
}
|
||||||
|
if (function_exists('aksrt_rewards_enabled') && !aksrt_rewards_enabled()) {
|
||||||
|
wp_send_json_error(['message' => __('打赏功能未启用', 'aksrt')]);
|
||||||
|
}
|
||||||
|
$kind = isset($_POST['kind']) ? sanitize_key((string) $_POST['kind']) : '';
|
||||||
|
if (!in_array($kind, ['weixin', 'alipay'], true)) {
|
||||||
|
wp_send_json_error(['message' => __('无效类型', 'aksrt')]);
|
||||||
|
}
|
||||||
|
if (empty($_FILES['file']['name'])) {
|
||||||
|
wp_send_json_error(['message' => __('请选择图片', 'aksrt')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||||
|
|
||||||
|
$file = $_FILES['file'];
|
||||||
|
$check = wp_check_filetype_and_ext($file['tmp_name'], $file['name']);
|
||||||
|
$allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
||||||
|
$mime = (string) ($check['type'] ?? $file['type'] ?? '');
|
||||||
|
if ($mime === '' || !in_array($mime, $allowed, true)) {
|
||||||
|
wp_send_json_error(['message' => __('仅支持 JPG/PNG/GIF/WebP 图片', 'aksrt')]);
|
||||||
|
}
|
||||||
|
if (!empty($file['size']) && (int) $file['size'] > 2 * 1024 * 1024) {
|
||||||
|
wp_send_json_error(['message' => __('图片不能超过 2MB', 'aksrt')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$attachment_id = media_handle_upload('file', 0);
|
||||||
|
if (is_wp_error($attachment_id)) {
|
||||||
|
wp_send_json_error(['message' => $attachment_id->get_error_message()]);
|
||||||
|
}
|
||||||
|
$meta = $kind === 'weixin' ? 'aksrt_rewards_weixin' : 'aksrt_rewards_alipay';
|
||||||
|
update_user_meta($user_id, $meta, (int) $attachment_id);
|
||||||
|
$url = wp_get_attachment_image_url((int) $attachment_id, 'full');
|
||||||
|
wp_send_json_success([
|
||||||
|
'message' => __('上传成功', 'aksrt'),
|
||||||
|
'id' => (int) $attachment_id,
|
||||||
|
'url' => is_string($url) ? $url : '',
|
||||||
|
'kind' => $kind,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// AJAX: 发送邮箱验证码(修改密码/更改邮箱通用)
|
// AJAX: 发送邮箱验证码(修改密码/更改邮箱通用)
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
@@ -309,6 +309,7 @@ class AKSRT_Forum_Comment_Service {
|
|||||||
|
|
||||||
update_comment_meta($comment_id, '_aksrt_adopted', '1');
|
update_comment_meta($comment_id, '_aksrt_adopted', '1');
|
||||||
update_post_meta($topic_id, '_aksrt_adopted_comment', $comment_id);
|
update_post_meta($topic_id, '_aksrt_adopted_comment', $comment_id);
|
||||||
|
do_action('aksrt_forum_reply_adopted', $topic_id, $comment_id, (int) $comment->user_id);
|
||||||
update_post_meta($topic_id, '_aksrt_question_status', 1); // QUESTION_SOLVED
|
update_post_meta($topic_id, '_aksrt_question_status', 1); // QUESTION_SOLVED
|
||||||
|
|
||||||
$adoptee_id = (int) $comment->user_id;
|
$adoptee_id = (int) $comment->user_id;
|
||||||
@@ -507,6 +508,8 @@ class AKSRT_Forum_Comment_Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_comment_meta($comment_id, '_aksrt_is_hot', '1');
|
update_comment_meta($comment_id, '_aksrt_is_hot', '1');
|
||||||
|
$hot_author = (int) (get_comment($comment_id)->user_id ?? 0);
|
||||||
|
do_action('aksrt_forum_comment_hot', $comment_id, $hot_author);
|
||||||
|
|
||||||
// Credit the comment author (free-task day cap).
|
// Credit the comment author (free-task day cap).
|
||||||
$author_id = (int) $comment->user_id;
|
$author_id = (int) $comment->user_id;
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ class AKSRT_Forum_Score_Service {
|
|||||||
$total = (int) get_post_meta($topic_id, '_aksrt_score', true);
|
$total = (int) get_post_meta($topic_id, '_aksrt_score', true);
|
||||||
$total += $amount;
|
$total += $amount;
|
||||||
update_post_meta($topic_id, '_aksrt_score', $total);
|
update_post_meta($topic_id, '_aksrt_score', $total);
|
||||||
|
do_action('aksrt_forum_topic_scored', $topic_id, (int) $author_id, (float) $amount);
|
||||||
|
|
||||||
$reputation = (int) get_user_meta($author_id, 'aksrt_reputation', true);
|
$reputation = (int) get_user_meta($author_id, 'aksrt_reputation', true);
|
||||||
$reputation += $amount;
|
$reputation += $amount;
|
||||||
@@ -236,6 +237,7 @@ class AKSRT_Forum_Score_Service {
|
|||||||
if ($author_id <= 0) {
|
if ($author_id <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
do_action('aksrt_forum_topic_hot', $topic_id, (int) $author_id);
|
||||||
update_post_meta($topic_id, '_aksrt_hot_rewarded', '1');
|
update_post_meta($topic_id, '_aksrt_hot_rewarded', '1');
|
||||||
$config = $this->forum->get_config();
|
$config = $this->forum->get_config();
|
||||||
$amount = (int) ($config['credits']['posts_hot'] ?? 5);
|
$amount = (int) ($config['credits']['posts_hot'] ?? 5);
|
||||||
|
|||||||
@@ -604,6 +604,7 @@ if (!function_exists('aksrt_set_post_views')) :
|
|||||||
if (function_exists('aksrt_update_post_counter')) {
|
if (function_exists('aksrt_update_post_counter')) {
|
||||||
aksrt_update_post_counter($post_id, '_aksrt_res_view_count', 1);
|
aksrt_update_post_counter($post_id, '_aksrt_res_view_count', 1);
|
||||||
aksrt_update_post_counter($post_id, 'aksrt_post_views', 1);
|
aksrt_update_post_counter($post_id, 'aksrt_post_views', 1);
|
||||||
|
do_action('aksrt_post_viewed', (int) $post_id, get_current_user_id());
|
||||||
} else {
|
} else {
|
||||||
$resource_count = (int) get_post_meta($post_id, '_aksrt_res_view_count', true);
|
$resource_count = (int) get_post_meta($post_id, '_aksrt_res_view_count', true);
|
||||||
update_post_meta($post_id, '_aksrt_res_view_count', $resource_count + 1);
|
update_post_meta($post_id, '_aksrt_res_view_count', $resource_count + 1);
|
||||||
@@ -613,6 +614,7 @@ if (!function_exists('aksrt_set_post_views')) :
|
|||||||
} else {
|
} else {
|
||||||
if (function_exists('aksrt_update_post_counter')) {
|
if (function_exists('aksrt_update_post_counter')) {
|
||||||
aksrt_update_post_counter($post_id, 'aksrt_post_views', 1);
|
aksrt_update_post_counter($post_id, 'aksrt_post_views', 1);
|
||||||
|
do_action('aksrt_post_viewed', (int) $post_id, get_current_user_id());
|
||||||
} else {
|
} else {
|
||||||
$count = (int) get_post_meta($post_id, 'aksrt_post_views', true);
|
$count = (int) get_post_meta($post_id, 'aksrt_post_views', true);
|
||||||
update_post_meta($post_id, 'aksrt_post_views', $count + 1);
|
update_post_meta($post_id, 'aksrt_post_views', $count + 1);
|
||||||
|
|||||||
@@ -91,6 +91,32 @@ if (!function_exists('aksrt_save_user_center_profile')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update_user_meta($user_id, 'aksrt_user_contacts', aksrt_normalize_user_contacts($input['contacts'] ?? []));
|
update_user_meta($user_id, 'aksrt_user_contacts', aksrt_normalize_user_contacts($input['contacts'] ?? []));
|
||||||
|
|
||||||
|
// Tip QR images (attachment id or URL). Empty clears.
|
||||||
|
if (array_key_exists('rewards_weixin', $input) || array_key_exists('rewards_alipay', $input)) {
|
||||||
|
foreach (['rewards_weixin' => 'aksrt_rewards_weixin', 'rewards_alipay' => 'aksrt_rewards_alipay'] as $field => $meta) {
|
||||||
|
if (!array_key_exists($field, $input)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$raw = is_string($input[$field]) ? trim(wp_unslash($input[$field])) : '';
|
||||||
|
if ($raw === '' || $raw === '0') {
|
||||||
|
delete_user_meta($user_id, $meta);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ctype_digit($raw)) {
|
||||||
|
$att = (int) $raw;
|
||||||
|
if ($att > 0 && wp_attachment_is_image($att)) {
|
||||||
|
update_user_meta($user_id, $meta, $att);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$url = esc_url_raw($raw);
|
||||||
|
if ($url !== '') {
|
||||||
|
update_user_meta($user_id, $meta, $url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,22 +52,48 @@ $aksrt_points_task_action = static function (string $key): array {
|
|||||||
'href' => $submit !== '' ? $submit : $home,
|
'href' => $submit !== '' ? $submit : $home,
|
||||||
];
|
];
|
||||||
case 'comment_new':
|
case 'comment_new':
|
||||||
return [
|
$posts = get_posts(['numberposts' => 1, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC']);
|
||||||
'type' => 'link',
|
$href = $home;
|
||||||
'label' => __('去完成', 'aksrt'),
|
if (!empty($posts[0]) && $posts[0] instanceof WP_Post) {
|
||||||
'href' => $home,
|
$link = get_permalink($posts[0]);
|
||||||
];
|
if (is_string($link) && $link !== '') {
|
||||||
case 'login':
|
$href = $link . '#comments';
|
||||||
case 'post_like':
|
}
|
||||||
case 'post_favorite':
|
}
|
||||||
case 'followed':
|
return [
|
||||||
case 'comment_like':
|
'type' => 'link',
|
||||||
return [
|
'label' => __('去完成', 'aksrt'),
|
||||||
'type' => 'link',
|
'href' => $href,
|
||||||
'label' => __('去看看', 'aksrt'),
|
];
|
||||||
'href' => $home,
|
case 'login':
|
||||||
];
|
return [
|
||||||
case 'bbs_posts_new':
|
'type' => 'none',
|
||||||
|
'label' => __('登录即可领取', 'aksrt'),
|
||||||
|
];
|
||||||
|
case 'post_like':
|
||||||
|
case 'post_favorite':
|
||||||
|
case 'comment_like':
|
||||||
|
$posts = get_posts(['numberposts' => 1, 'post_status' => 'publish', 'orderby' => 'comment_count', 'order' => 'DESC']);
|
||||||
|
$href = $home;
|
||||||
|
if (!empty($posts[0]) && $posts[0] instanceof WP_Post) {
|
||||||
|
$link = get_permalink($posts[0]);
|
||||||
|
if (is_string($link) && $link !== '') {
|
||||||
|
$href = $link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'type' => 'link',
|
||||||
|
'label' => __('去看看', 'aksrt'),
|
||||||
|
'href' => $href,
|
||||||
|
];
|
||||||
|
case 'followed':
|
||||||
|
$center = function_exists('aksrt_get_user_center_url') ? (string) aksrt_get_user_center_url() : $home;
|
||||||
|
return [
|
||||||
|
'type' => 'link',
|
||||||
|
'label' => __('去主页', 'aksrt'),
|
||||||
|
'href' => $center !== '' ? $center : $home,
|
||||||
|
];
|
||||||
|
case 'bbs_posts_new':
|
||||||
case 'bbs_reply':
|
case 'bbs_reply':
|
||||||
if (!$forum_on) {
|
if (!$forum_on) {
|
||||||
return ['type' => 'none', 'label' => ''];
|
return ['type' => 'none', 'label' => ''];
|
||||||
@@ -180,16 +206,19 @@ $pane = isset($points_tasks_pane) ? sanitize_key((string) $points_tasks_pane)
|
|||||||
<div class="focus-color em14">
|
<div class="focus-color em14">
|
||||||
<i class="fas fa-coins mr6 em09" aria-hidden="true"></i>+ <?php echo esc_html((string) (int) $task['points']); ?>
|
<i class="fas fa-coins mr6 em09" aria-hidden="true"></i>+ <?php echo esc_html((string) (int) $task['points']); ?>
|
||||||
</div>
|
</div>
|
||||||
<?php if (($action['type'] ?? 'none') === 'signin') : ?>
|
<?php if ($done) : ?>
|
||||||
<button type="button" class="uc-points-tasks__action muted-color em09 mt6" data-aksrt-signin-goto>
|
<span class="uc-points-tasks__action muted-color em09 mt6"><?php esc_html_e('今日已完成', 'aksrt'); ?></span>
|
||||||
<?php echo esc_html((string) $action['label']); ?><i class="fa fa-angle-right em12 ml3" aria-hidden="true"></i>
|
<?php elseif (($action['type'] ?? 'none') === 'signin') : ?>
|
||||||
</button>
|
<button type="button" class="uc-points-tasks__action muted-color em09 mt6" data-aksrt-signin-goto>
|
||||||
<?php elseif (($action['type'] ?? 'none') === 'link' && !empty($action['href'])) : ?>
|
<?php echo esc_html((string) $action['label']); ?><i class="fa fa-angle-right em12 ml3" aria-hidden="true"></i>
|
||||||
<a class="uc-points-tasks__action muted-color em09 mt6" href="<?php echo esc_url((string) $action['href']); ?>">
|
</button>
|
||||||
<?php echo esc_html((string) $action['label']); ?><i class="fa fa-angle-right em12 ml3" aria-hidden="true"></i>
|
<?php elseif (($action['type'] ?? 'none') === 'link' && !empty($action['href'])) : ?>
|
||||||
</a>
|
<a class="uc-points-tasks__action muted-color em09 mt6" href="<?php echo esc_url((string) $action['href']); ?>">
|
||||||
<?php endif; ?>
|
<?php echo esc_html((string) $action['label']); ?><i class="fa fa-angle-right em12 ml3" aria-hidden="true"></i>
|
||||||
</div>
|
</a>
|
||||||
|
<?php elseif (($action['type'] ?? 'none') === 'none' && !empty($action['label'])) : ?>
|
||||||
|
<span class="uc-points-tasks__action muted-color em09 mt6"><?php echo esc_html((string) $action['label']); ?></span>
|
||||||
|
<?php endif; ?> </div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|||||||
@@ -32,6 +32,56 @@ extract($context, EXTR_SKIP); // phpcs:ignore WordPress.PHP.DontExtract.extract_
|
|||||||
|
|
||||||
<?php require __DIR__ . '/form-contacts.php'; ?>
|
<?php require __DIR__ . '/form-contacts.php'; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$rewards_on = function_exists('aksrt_rewards_enabled') ? aksrt_rewards_enabled() : false;
|
||||||
|
$rw = (string) get_user_meta((int) $user_id, 'aksrt_rewards_weixin', true);
|
||||||
|
$ra = (string) get_user_meta((int) $user_id, 'aksrt_rewards_alipay', true);
|
||||||
|
$rw_url = '';
|
||||||
|
$ra_url = '';
|
||||||
|
if (function_exists('aksrt_get_user_rewards_img_urls')) {
|
||||||
|
$urls = aksrt_get_user_rewards_img_urls((int) $user_id);
|
||||||
|
$rw_url = (string) ($urls['weixin'] ?? '');
|
||||||
|
$ra_url = (string) ($urls['alipay'] ?? '');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if ($rewards_on) : ?>
|
||||||
|
<div class="widget-card">
|
||||||
|
<h3 class="widget-title"><?php esc_html_e('打赏收款码', 'aksrt'); ?></h3>
|
||||||
|
<p class="profile-hint"><?php esc_html_e('上传微信/支付宝收款码后,读者可在文章与作者卡赞赏你。留空则不显示赞赏按钮。', 'aksrt'); ?></p>
|
||||||
|
<div class="aksrt-reward-upload-grid">
|
||||||
|
<div class="aksrt-reward-upload">
|
||||||
|
<label class="aksrt-reward-upload__label"><?php esc_html_e('微信收款码', 'aksrt'); ?></label>
|
||||||
|
<div class="aksrt-reward-upload__preview" data-reward-preview="weixin">
|
||||||
|
<?php if ($rw_url !== '') : ?>
|
||||||
|
<img src="<?php echo esc_url($rw_url); ?>" alt="" />
|
||||||
|
<?php else : ?>
|
||||||
|
<span class="muted-2-color em09"><?php esc_html_e('未上传', 'aksrt'); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="rewards_weixin" id="rewards-weixin" value="<?php echo esc_attr($rw); ?>" />
|
||||||
|
<input type="file" id="rewards-weixin-file" accept="image/*" class="aksrt-reward-upload__file" data-reward-kind="weixin" />
|
||||||
|
<button type="button" class="btn-primary btn-sm" data-reward-upload="weixin"><?php esc_html_e('选择图片', 'aksrt'); ?></button>
|
||||||
|
<button type="button" class="btn-sm" data-reward-clear="weixin"><?php esc_html_e('清除', 'aksrt'); ?></button>
|
||||||
|
</div>
|
||||||
|
<div class="aksrt-reward-upload">
|
||||||
|
<label class="aksrt-reward-upload__label"><?php esc_html_e('支付宝收款码', 'aksrt'); ?></label>
|
||||||
|
<div class="aksrt-reward-upload__preview" data-reward-preview="alipay">
|
||||||
|
<?php if ($ra_url !== '') : ?>
|
||||||
|
<img src="<?php echo esc_url($ra_url); ?>" alt="" />
|
||||||
|
<?php else : ?>
|
||||||
|
<span class="muted-2-color em09"><?php esc_html_e('未上传', 'aksrt'); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="rewards_alipay" id="rewards-alipay" value="<?php echo esc_attr($ra); ?>" />
|
||||||
|
<input type="file" id="rewards-alipay-file" accept="image/*" class="aksrt-reward-upload__file" data-reward-kind="alipay" />
|
||||||
|
<button type="button" class="btn-primary btn-sm" data-reward-upload="alipay"><?php esc_html_e('选择图片', 'aksrt'); ?></button>
|
||||||
|
<button type="button" class="btn-sm" data-reward-clear="alipay"><?php esc_html_e('清除', 'aksrt'); ?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
|
||||||
<div class="profile-form__submit">
|
<div class="profile-form__submit">
|
||||||
<button type="submit" class="btn-primary btn-lg" id="profile-save-btn">
|
<button type="submit" class="btn-primary btn-lg" id="profile-save-btn">
|
||||||
<?php esc_html_e('保存修改', 'aksrt'); ?>
|
<?php esc_html_e('保存修改', 'aksrt'); ?>
|
||||||
|
|||||||
Reference in new issue
Block a user