feat(payment): rebuild order details and asset records
This commit is contained in:
1 parent
476e2f961d
commit
7b55cfb190
57 files changed
+2080
-1294
No files matched your search
@@ -388,18 +388,11 @@ trait BalanceServiceCharge {
|
||||
return new \WP_Error('aksrt_order_create_failed', __('创建订单失败', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
if (is_array($existing) && (string) ($order['status'] ?? '') === \AKSRT\Payment\Order::STATUS_PAID) {
|
||||
$ledger_key = \AKSRT\Ledger\OperationKey::deterministic('recharge', [$order_number]);
|
||||
$history = \AKSRT\Ledger\LedgerQuery::get_instance()->history(['operation_key' => $ledger_key, 'page' => 1, 'per_page' => 1]);
|
||||
$transaction_id = (int) ($history['items'][0]['id'] ?? 0);
|
||||
if ($transaction_id <= 0) {
|
||||
return new \WP_Error('aksrt_recharge_state', __('充值订单与账本状态不一致', 'aksrt'), ['status' => 409]);
|
||||
}
|
||||
return [
|
||||
'redirect' => false,
|
||||
'order_number' => $order_number,
|
||||
'amount' => $pay_decimal,
|
||||
'credit_amount' => $credit_decimal,
|
||||
'transaction_id' => $transaction_id,
|
||||
'replayed' => true,
|
||||
'wallet' => \AKSRT\Ledger\LedgerService::get_instance()->balance_decimal($user_id),
|
||||
'message' => __('充值成功', 'aksrt'),
|
||||
@@ -450,15 +443,11 @@ trait BalanceServiceCharge {
|
||||
}
|
||||
|
||||
// The synchronous gateway has already committed the recharge and order state.
|
||||
$ledger_key = \AKSRT\Ledger\OperationKey::deterministic('recharge', [$order_number]);
|
||||
$history = \AKSRT\Ledger\LedgerQuery::get_instance()->history(['operation_key' => $ledger_key, 'page' => 1, 'per_page' => 1]);
|
||||
|
||||
return [
|
||||
'redirect' => false,
|
||||
'order_number' => $order_number,
|
||||
'amount' => $pay_decimal,
|
||||
'credit_amount' => $credit_decimal,
|
||||
'transaction_id' => (int) ($history['items'][0]['id'] ?? 0),
|
||||
'replayed' => false,
|
||||
'wallet' => \AKSRT\Ledger\LedgerService::get_instance()->balance_decimal($user_id),
|
||||
'message' => __('充值成功', 'aksrt'),
|
||||
|
||||
@@ -230,7 +230,6 @@ trait BalanceServiceRest {
|
||||
'data' => [
|
||||
'message' => __('转账成功', 'aksrt'),
|
||||
'reload' => true,
|
||||
'transaction_id' => $result->transaction_id,
|
||||
'replayed' => $result->replayed,
|
||||
'balance' => \AKSRT\Ledger\AssetAmount::from_minor(\AKSRT\Ledger\AssetType::BALANCE, $result->balance($from_id, \AKSRT\Ledger\AssetType::BALANCE))->decimal(),
|
||||
],
|
||||
@@ -281,7 +280,6 @@ trait BalanceServiceRest {
|
||||
'data' => [
|
||||
'message' => __('转账成功', 'aksrt'),
|
||||
'reload' => true,
|
||||
'transaction_id' => $result->transaction_id,
|
||||
'replayed' => $result->replayed,
|
||||
'balance' => $result->balance($from_id, \AKSRT\Ledger\AssetType::POINTS),
|
||||
],
|
||||
@@ -392,14 +390,15 @@ trait BalanceServiceRest {
|
||||
if (is_wp_error($operation_key)) {
|
||||
return $operation_key;
|
||||
}
|
||||
$site_now = current_datetime();
|
||||
$start = (clone $site_now)->setTime(0, 0, 0);
|
||||
$end = (clone $start)->modify('+1 day');
|
||||
$utc = new \DateTimeZone('UTC');
|
||||
$start_gmt = $start->setTimezone($utc)->format('Y-m-d H:i:s.u');
|
||||
$end_gmt = $end->setTimezone($utc)->format('Y-m-d H:i:s.u');
|
||||
$guard = static function () use ($user_id, $points, $daily_max, $start_gmt, $end_gmt) {
|
||||
$used = \AKSRT\Ledger\LedgerQuery::get_instance()->sum_credits($user_id, 'points_exchange', $start_gmt, $end_gmt);
|
||||
$guard = static function () use ($user_id, $points, $daily_max) {
|
||||
$used = 0;
|
||||
$records = get_user_meta($user_id, 'points_record', true);
|
||||
$today = current_time('Y-m-d');
|
||||
foreach (is_array($records) ? $records : [] as $record) {
|
||||
if (substr((string) ($record['time'] ?? ''), 0, 10) !== $today) continue;
|
||||
if (sanitize_key((string) ($record['type'] ?? '')) !== 'points_exchange') continue;
|
||||
$used += max(0, (int) ($record['value'] ?? 0));
|
||||
}
|
||||
if ($used + $points > $daily_max) {
|
||||
return new \WP_Error('aksrt_exchange_daily_limit', sprintf(__('今日购买积分上限为 %d,当前还可购买 %d', 'aksrt'), $daily_max, max(0, $daily_max - $used)), ['status' => 400]);
|
||||
}
|
||||
@@ -451,7 +450,7 @@ trait BalanceServiceRest {
|
||||
'currency' => 'CNY',
|
||||
'status' => \AKSRT\Payment\Order::STATUS_PAID,
|
||||
'payment_method' => 'balance',
|
||||
'payment_transaction_id' => 'ledger_' . $transaction_id,
|
||||
'payment_transaction_id' => '',
|
||||
'paid_at' => current_time('mysql'),
|
||||
'note' => is_string($note) ? $note : '',
|
||||
'request_key' => $operation_key,
|
||||
@@ -481,7 +480,6 @@ trait BalanceServiceRest {
|
||||
}
|
||||
return rest_ensure_response(['success' => true, 'data' => [
|
||||
'message' => sprintf(__('购买成功,获得 %d 积分', 'aksrt'), $points),
|
||||
'transaction_id' => $result->transaction_id,
|
||||
'replayed' => $result->replayed,
|
||||
'wallet_balance' => \AKSRT\Ledger\AssetAmount::from_minor(\AKSRT\Ledger\AssetType::BALANCE, $result->balance($user_id, \AKSRT\Ledger\AssetType::BALANCE))->decimal(),
|
||||
'credit_balance' => $result->balance($user_id, \AKSRT\Ledger\AssetType::POINTS),
|
||||
|
||||
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
/**
|
||||
* User-meta backed wallet and points balances.
|
||||
*
|
||||
* Commission remains in the immutable asset ledger. Balance and points are
|
||||
* deliberately kept on user meta, with a bounded recent-history record.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Credits;
|
||||
|
||||
use AKSRT\Ledger\AssetAmount;
|
||||
use AKSRT\Ledger\AssetType;
|
||||
use AKSRT\Ledger\LedgerAbort;
|
||||
use AKSRT\Ledger\LedgerCommand;
|
||||
use AKSRT\Ledger\LedgerResult;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class MetaAssetService {
|
||||
private const MAX_RECORDS = 50;
|
||||
private static ?self $instance = null;
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
public static function get_instance(): self {
|
||||
return self::$instance ??= new self();
|
||||
}
|
||||
|
||||
public function balance_points(int $user_id): int {
|
||||
return max(0, (int) get_user_meta($user_id, 'points', true));
|
||||
}
|
||||
|
||||
public function balance_minor(int $user_id): int {
|
||||
if ($user_id <= 0) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return AssetAmount::balance((string) get_user_meta($user_id, 'balance', true))->minor();
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function balance_decimal(int $user_id): string {
|
||||
return AssetAmount::from_minor(AssetType::BALANCE, $this->balance_minor($user_id))->decimal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit a balance/points LedgerCommand against user meta. This adapter keeps
|
||||
* existing business callbacks and result DTOs while never writing Ledger or
|
||||
* FinancialFlow rows for these two assets.
|
||||
*
|
||||
* @return LedgerResult|\WP_Error
|
||||
*/
|
||||
public function post_command(LedgerCommand $command, ?callable $guard = null, ?callable $business_mutation = null) {
|
||||
global $wpdb;
|
||||
$entries = $command->entries;
|
||||
if ($entries === []) {
|
||||
return new \WP_Error('aksrt_asset_entries', __('资产明细不能为空', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
$valid = $command->validate();
|
||||
if (is_wp_error($valid)) {
|
||||
return $valid;
|
||||
}
|
||||
foreach ($entries as $entry) {
|
||||
if (!in_array((string) ($entry['asset'] ?? ''), [AssetType::BALANCE->value, AssetType::POINTS->value], true)) {
|
||||
return new \WP_Error('aksrt_asset_mixed_pool', __('余额/积分不能与佣金资金池混合操作', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
}
|
||||
|
||||
$lock_names = [];
|
||||
$lock_names[] = 'aksrt_meta_op_' . substr(hash('sha256', $command->operation_key), 0, 48);
|
||||
foreach ($entries as $entry) {
|
||||
$lock_names[] = 'aksrt_meta_asset_' . (int) $entry['user_id'] . '_' . sanitize_key((string) $entry['asset']);
|
||||
}
|
||||
$lock_names = array_values(array_unique($lock_names));
|
||||
sort($lock_names, SORT_STRING);
|
||||
$user_ids = array_values(array_unique(array_map(static fn(array $entry): int => (int) $entry['user_id'], $entries)));
|
||||
$held = [];
|
||||
foreach ($lock_names as $lock_name) {
|
||||
$got = (int) $wpdb->get_var($wpdb->prepare('SELECT GET_LOCK(%s, 5)', $lock_name));
|
||||
if ($got !== 1) {
|
||||
$this->release_locks($held);
|
||||
return new \WP_Error('aksrt_asset_busy', __('资产正在处理中,请稍后重试', 'aksrt'), ['status' => 409]);
|
||||
}
|
||||
$held[] = $lock_name;
|
||||
}
|
||||
|
||||
$owns_transaction = $wpdb->query('START TRANSACTION') !== false;
|
||||
if (!$owns_transaction) {
|
||||
$this->release_locks($held);
|
||||
return new \WP_Error('aksrt_asset_db', __('资产更新失败,请稍后重试', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
|
||||
try {
|
||||
$payload_hash = $command->payload_hash();
|
||||
$replay = $this->find_operation($entries, $command->operation_key, $payload_hash);
|
||||
if (is_wp_error($replay)) {
|
||||
throw new LedgerAbort($replay);
|
||||
}
|
||||
if (is_array($replay)) {
|
||||
$wpdb->query('COMMIT');
|
||||
return new LedgerResult(0, true, [], $replay, '');
|
||||
}
|
||||
|
||||
$before = [];
|
||||
$totals = [];
|
||||
foreach ($entries as $entry) {
|
||||
$user_id = (int) $entry['user_id'];
|
||||
$asset = (string) $entry['asset'];
|
||||
$key = $user_id . ':' . $asset;
|
||||
if (!isset($before[$key])) {
|
||||
$before[$key] = $this->read_locked_balance($user_id, $asset);
|
||||
$totals[$key] = 0;
|
||||
}
|
||||
$delta = (int) $entry['delta_minor'];
|
||||
if (($delta > 0 && $totals[$key] > PHP_INT_MAX - $delta) || ($delta < 0 && $totals[$key] < PHP_INT_MIN - $delta)) {
|
||||
throw new LedgerAbort(new \WP_Error('aksrt_asset_overflow', __('资产金额超出范围', 'aksrt'), ['status' => 400]));
|
||||
}
|
||||
$totals[$key] += $delta;
|
||||
}
|
||||
|
||||
$balances = [];
|
||||
foreach ($before as $key => $old) {
|
||||
[$user_id_raw, $asset] = explode(':', $key, 2);
|
||||
$user_id = (int) $user_id_raw;
|
||||
$delta = $totals[$key];
|
||||
if ($delta === 0) {
|
||||
$balances[$user_id][$asset] = $old;
|
||||
continue;
|
||||
}
|
||||
if ($delta < 0 && $old < abs($delta)) {
|
||||
$is_points = $asset === AssetType::POINTS->value;
|
||||
$code = $is_points ? 'aksrt_points_insufficient' : 'aksrt_balance_insufficient';
|
||||
throw new LedgerAbort(new \WP_Error($code, $is_points ? __('积分不足', 'aksrt') : __('余额不足', 'aksrt'), [
|
||||
'status' => 402,
|
||||
'balance_minor' => $old,
|
||||
'required_minor' => abs($delta),
|
||||
]));
|
||||
}
|
||||
if ($delta > 0 && $old > PHP_INT_MAX - $delta) {
|
||||
throw new LedgerAbort(new \WP_Error('aksrt_asset_overflow', __('资产金额超出范围', 'aksrt'), ['status' => 400]));
|
||||
}
|
||||
$new = $old + $delta;
|
||||
$this->write_balance($user_id, $asset, $delta, $new);
|
||||
$balances[$user_id][$asset] = $new;
|
||||
}
|
||||
|
||||
if ($guard !== null) {
|
||||
$guard_result = $guard(0, $balances);
|
||||
if (is_wp_error($guard_result)) {
|
||||
throw new LedgerAbort($guard_result);
|
||||
}
|
||||
if ($guard_result !== true) {
|
||||
throw new LedgerAbort(new \WP_Error('aksrt_asset_guard', __('资产操作校验失败', 'aksrt'), ['status' => 409]));
|
||||
}
|
||||
}
|
||||
|
||||
$written = [];
|
||||
$running = $before;
|
||||
foreach ($entries as $entry) {
|
||||
$user_id = (int) $entry['user_id'];
|
||||
$asset = (string) $entry['asset'];
|
||||
$key = $user_id . ':' . $asset;
|
||||
$delta = (int) $entry['delta_minor'];
|
||||
$old = (int) ($running[$key] ?? 0) + $delta;
|
||||
$running[$key] = $old;
|
||||
$order_number = trim((string) ($command->metadata['order_number'] ?? ''));
|
||||
if ($order_number === '' && $command->ref_type === 'order') {
|
||||
$order_number = trim($command->ref_key);
|
||||
}
|
||||
$record = [
|
||||
'order_num' => $order_number,
|
||||
'value' => $asset === AssetType::BALANCE->value ? AssetAmount::from_minor(AssetType::BALANCE, abs($delta))->decimal() : $delta,
|
||||
'type' => in_array(sanitize_key((string) ($entry['entry_type'] ?? '')), ['credit', 'debit'], true)
|
||||
? sanitize_key($command->reason)
|
||||
: sanitize_key((string) ($entry['entry_type'] ?? $command->reason)),
|
||||
'desc' => sanitize_text_field((string) ($entry['remark'] ?? $command->reason)),
|
||||
'time' => current_time('Y-m-d H:i'),
|
||||
];
|
||||
if ($asset === AssetType::BALANCE->value) {
|
||||
$record['value'] = $delta < 0 ? '-' . $record['value'] : $record['value'];
|
||||
$record['balance'] = AssetAmount::from_minor(AssetType::BALANCE, max(0, $old))->decimal();
|
||||
$meta_key = 'balance_record';
|
||||
} else {
|
||||
$record['value'] = $delta;
|
||||
$record['points'] = max(0, $old);
|
||||
$meta_key = 'points_record';
|
||||
}
|
||||
wp_cache_delete($user_id, 'user_meta');
|
||||
$history = get_user_meta($user_id, $meta_key, true);
|
||||
$history = is_array($history) ? $history : [];
|
||||
$history = array_slice($history, 0, self::MAX_RECORDS - 1);
|
||||
$history = array_merge([$record], $history);
|
||||
update_user_meta($user_id, $meta_key, $history);
|
||||
$written[] = [
|
||||
'user_id' => $user_id,
|
||||
'asset' => $asset,
|
||||
'delta_minor' => $delta,
|
||||
'balance_after_minor' => $old,
|
||||
'counterparty_user_id' => max(0, (int) ($entry['counterparty_user_id'] ?? 0)),
|
||||
'entry_type' => sanitize_key((string) ($entry['entry_type'] ?? 'adjustment')),
|
||||
'remark' => sanitize_text_field((string) ($entry['remark'] ?? '')),
|
||||
];
|
||||
}
|
||||
|
||||
if ($business_mutation !== null) {
|
||||
$mutation_result = $business_mutation(0, new LedgerResult(0, false, $written, $balances));
|
||||
if (is_wp_error($mutation_result)) {
|
||||
throw new LedgerAbort($mutation_result);
|
||||
}
|
||||
if ($mutation_result !== true) {
|
||||
throw new LedgerAbort(new \WP_Error('aksrt_asset_mutation', __('资产关联操作失败', 'aksrt'), ['status' => 409]));
|
||||
}
|
||||
}
|
||||
$this->write_operation_markers($entries, $command->operation_key, $payload_hash);
|
||||
|
||||
if ($wpdb->query('COMMIT') === false) {
|
||||
throw new \RuntimeException('meta_asset_commit_failed');
|
||||
}
|
||||
foreach ($user_ids as $user_id) {
|
||||
clean_user_cache((int) $user_id);
|
||||
}
|
||||
return new LedgerResult(0, false, $written, $balances, '');
|
||||
} catch (LedgerAbort $e) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
foreach ($user_ids as $user_id) clean_user_cache((int) $user_id);
|
||||
return $e->error;
|
||||
} catch (\Throwable $e) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
foreach ($user_ids as $user_id) clean_user_cache((int) $user_id);
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('[AKSRT Meta Assets] ' . $e->getMessage());
|
||||
}
|
||||
return new \WP_Error('aksrt_asset_db', __('资产更新失败,请稍后重试', 'aksrt'), ['status' => 500]);
|
||||
} finally {
|
||||
$this->release_locks($held);
|
||||
}
|
||||
}
|
||||
|
||||
/** @return array<string,int>|\WP_Error|null */
|
||||
private function find_operation(array $entries, string $operation_key, string $payload_hash): array|\WP_Error|null {
|
||||
$balances = [];
|
||||
$users = [];
|
||||
foreach ($entries as $entry) {
|
||||
$users[(int) $entry['user_id']] = true;
|
||||
}
|
||||
$marker_key = 'aksrt_asset_op_' . hash('sha256', $operation_key);
|
||||
$found = 0;
|
||||
foreach (array_keys($users) as $user_id) {
|
||||
$stored_hash = (string) get_user_meta((int) $user_id, $marker_key, true);
|
||||
if ($stored_hash === '') {
|
||||
continue;
|
||||
}
|
||||
if (!hash_equals($stored_hash, $payload_hash)) {
|
||||
return new \WP_Error('aksrt_asset_idempotency_conflict', __('相同资产操作标识已用于其他请求', 'aksrt'), ['status' => 409]);
|
||||
}
|
||||
$found++;
|
||||
}
|
||||
if ($found > 0 && $found !== count($users)) {
|
||||
return new \WP_Error('aksrt_asset_idempotency_conflict', __('资产操作记录不完整,请联系管理员核查', 'aksrt'), ['status' => 409]);
|
||||
}
|
||||
if ($found === count($users)) {
|
||||
foreach ($entries as $entry) {
|
||||
$user_id = (int) $entry['user_id'];
|
||||
$asset = (string) $entry['asset'];
|
||||
$balances[$user_id][$asset] = $asset === AssetType::POINTS->value
|
||||
? $this->balance_points($user_id)
|
||||
: $this->balance_minor($user_id);
|
||||
}
|
||||
}
|
||||
return $balances !== [] ? $balances : null;
|
||||
}
|
||||
|
||||
/** @param array<int,array<string,mixed>> $entries */
|
||||
private function write_operation_markers(array $entries, string $operation_key, string $payload_hash): void {
|
||||
$marker_key = 'aksrt_asset_op_' . hash('sha256', $operation_key);
|
||||
foreach (array_unique(array_map(static fn(array $entry): int => (int) $entry['user_id'], $entries)) as $user_id) {
|
||||
update_user_meta($user_id, $marker_key, $payload_hash);
|
||||
}
|
||||
}
|
||||
|
||||
private function read_locked_balance(int $user_id, string $asset): int {
|
||||
global $wpdb;
|
||||
$key = $asset === AssetType::POINTS->value ? 'points' : 'balance';
|
||||
$row = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT umeta_id, meta_value FROM {$wpdb->usermeta} WHERE user_id = %d AND meta_key = %s ORDER BY umeta_id ASC LIMIT 1 FOR UPDATE",
|
||||
$user_id,
|
||||
$key
|
||||
), ARRAY_A);
|
||||
if (!is_array($row)) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return $asset === AssetType::POINTS->value
|
||||
? max(0, (int) $row['meta_value'])
|
||||
: AssetAmount::balance((string) $row['meta_value'])->minor();
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private function write_balance(int $user_id, string $asset, int $delta, int $minor): void {
|
||||
global $wpdb;
|
||||
$key = $asset === AssetType::POINTS->value ? 'points' : 'balance';
|
||||
$value = $asset === AssetType::POINTS->value
|
||||
? (string) $minor
|
||||
: AssetAmount::from_minor(AssetType::BALANCE, $minor)->decimal();
|
||||
$row = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT umeta_id FROM {$wpdb->usermeta} WHERE user_id = %d AND meta_key = %s ORDER BY umeta_id ASC LIMIT 1 FOR UPDATE",
|
||||
$user_id,
|
||||
$key
|
||||
), ARRAY_A);
|
||||
if (is_array($row)) {
|
||||
$meta_id = (int) $row['umeta_id'];
|
||||
if ($asset === AssetType::POINTS->value) {
|
||||
$sql = "UPDATE {$wpdb->usermeta} SET meta_value = CAST(meta_value AS SIGNED) + %d WHERE umeta_id = %d AND (%d >= 0 OR CAST(meta_value AS SIGNED) >= %d)";
|
||||
$updated = $wpdb->query($wpdb->prepare($sql, $delta, $meta_id, $delta, abs($delta)));
|
||||
} else {
|
||||
$delta_decimal = AssetAmount::from_minor(AssetType::BALANCE, abs($delta))->decimal();
|
||||
if ($delta < 0) {
|
||||
$delta_decimal = '-' . $delta_decimal;
|
||||
}
|
||||
$minimum = AssetAmount::from_minor(AssetType::BALANCE, abs($delta))->decimal();
|
||||
$sql = "UPDATE {$wpdb->usermeta} SET meta_value = CAST(ROUND(CAST(meta_value AS DECIMAL(20,2)) + CAST(%s AS DECIMAL(20,2)), 2) AS CHAR) WHERE umeta_id = %d AND (%s >= '0.00' OR CAST(meta_value AS DECIMAL(20,2)) >= CAST(%s AS DECIMAL(20,2)))";
|
||||
$updated = $wpdb->query($wpdb->prepare($sql, $delta_decimal, $meta_id, $delta_decimal, $minimum));
|
||||
}
|
||||
if ($updated !== 1) {
|
||||
throw new \RuntimeException('meta_asset_update_failed');
|
||||
}
|
||||
wp_cache_delete($user_id, 'user_meta');
|
||||
return;
|
||||
}
|
||||
if ($minor < 0 || $wpdb->insert($wpdb->usermeta, ['user_id' => $user_id, 'meta_key' => $key, 'meta_value' => $value], ['%d', '%s', '%s']) !== 1) {
|
||||
throw new \RuntimeException('meta_asset_insert_failed');
|
||||
}
|
||||
wp_cache_delete($user_id, 'user_meta');
|
||||
}
|
||||
|
||||
private function release_locks(array $locks): void {
|
||||
global $wpdb;
|
||||
foreach (array_reverse($locks) as $lock_name) {
|
||||
$wpdb->get_var($wpdb->prepare('SELECT RELEASE_LOCK(%s)', $lock_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ defined('ABSPATH') || exit;
|
||||
|
||||
class PointsFree {
|
||||
|
||||
public const META_DETAIL = 'aksrt_free_points_detail';
|
||||
public const META_DETAIL = 'free_points_detail';
|
||||
public const META_LOGIN = 'aksrt_free_points_login_date';
|
||||
public const META_SIGNIN = 'aksrt_free_points_signin_date';
|
||||
public const META_TASKS = 'aksrt_free_points_task_dates';
|
||||
|
||||
@@ -124,7 +124,6 @@ class Signin {
|
||||
}
|
||||
|
||||
$operation_key = \AKSRT\Ledger\OperationKey::deterministic('signin', [$user_id, $today_str]);
|
||||
$transaction_id = null;
|
||||
$replayed = false;
|
||||
if ($reward > 0) {
|
||||
$guard = static function () use ($wpdb, $table, $user_id, $today_str) {
|
||||
@@ -164,7 +163,6 @@ class Signin {
|
||||
if (is_wp_error($ledger_result)) {
|
||||
return $ledger_result;
|
||||
}
|
||||
$transaction_id = $ledger_result->transaction_id;
|
||||
$replayed = $ledger_result->replayed;
|
||||
} else {
|
||||
$stored = $this->store_zero_reward_signin($user_id, $today_str, $new_streak);
|
||||
@@ -189,7 +187,6 @@ class Signin {
|
||||
'streak' => $new_streak,
|
||||
'reward' => $reward,
|
||||
'balance' => \AKSRT\Ledger\LedgerService::get_instance()->balance($user_id, \AKSRT\Ledger\AssetType::POINTS),
|
||||
'transaction_id' => $transaction_id,
|
||||
'replayed' => $replayed,
|
||||
], 200);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user