Extend the WordPress bridge plugin to provide seamless integration with the backend wallet system. This update introduces user-specific functionality via shortcodes and AJAX. - feat(bridge): implement `IFNEX_User_Bridge` for Sanctum token management - feat(bridge): add `[ifnex_wallet_balance]` shortcode for balance display - feat(bridge): add `[ifnex_transactions]` shortcode for transaction history - feat(bridge): implement AJAX handlers for real-time balance and transaction updates - feat(bridge): add plugin-specific CSS assets and enqueueing logic - docs: update project status with new bridge capabilities - chore: add plugin testing utility and asset directory structure
300 lines
11 KiB
PHP
300 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* IFNEX Tracking Form Handler
|
|
* JavaScript و منطق فرم رهگیری
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
add_action('wp_footer', 'ifnex_tracking_form_scripts');
|
|
|
|
function ifnex_tracking_form_scripts() {
|
|
// فقط اگر شورتکد در صفحه وجود دارد، اسکریپت را لود کن
|
|
global $post;
|
|
if (is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'ifnex_tracking_form')) {
|
|
?>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var form = document.getElementById('ifnex-tracking-form');
|
|
if (!form) return;
|
|
|
|
form.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
var input = document.getElementById('ifnex-awb-input');
|
|
var resultDiv = document.getElementById('ifnex-tracking-result');
|
|
var btn = document.getElementById('ifnex-track-btn');
|
|
var awb = input.value.trim();
|
|
|
|
if (!awb) {
|
|
resultDiv.innerHTML = '<p class="ifnex-error">لطفاً شماره بارنامه را وارد کنید.</p>';
|
|
resultDiv.style.display = 'block';
|
|
return;
|
|
}
|
|
|
|
btn.disabled = true;
|
|
btn.textContent = 'در حال جستجو...';
|
|
resultDiv.style.display = 'block';
|
|
resultDiv.innerHTML = '<p>در حال جستجو...</p>';
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('POST', '<?php echo esc_url(admin_url('admin-ajax.php')); ?>', true);
|
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
xhr.onload = function() {
|
|
btn.disabled = false;
|
|
btn.textContent = '<?php echo esc_js(__('رهگیری', 'ifnex-bridge')); ?>';
|
|
|
|
if (xhr.status === 200) {
|
|
var data = JSON.parse(xhr.responseText);
|
|
if (data.success) {
|
|
resultDiv.innerHTML = data.html;
|
|
} else {
|
|
resultDiv.innerHTML = '<p class="ifnex-error">' + data.message + '</p>';
|
|
}
|
|
} else {
|
|
resultDiv.innerHTML = '<p class="ifnex-error">خطا در ارتباط با سرور.</p>';
|
|
}
|
|
};
|
|
xhr.onerror = function() {
|
|
btn.disabled = false;
|
|
btn.textContent = '<?php echo esc_js(__('رهگیری', 'ifnex-bridge')); ?>';
|
|
resultDiv.innerHTML = '<p class="ifnex-error">خطا در ارتباط با سرور.</p>';
|
|
};
|
|
xhr.send('action=ifnex_track_shipment&awb=' + encodeURIComponent(awb));
|
|
});
|
|
});
|
|
</script>
|
|
<style>
|
|
.ifnex-tracking-container {
|
|
max-width: 600px;
|
|
margin: 20px auto;
|
|
padding: 20px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 8px;
|
|
font-family: inherit;
|
|
}
|
|
.ifnex-tracking-form {
|
|
margin-bottom: 20px;
|
|
}
|
|
.ifnex-form-group {
|
|
display: flex;
|
|
gap: 10px;
|
|
}
|
|
.ifnex-form-group input {
|
|
flex: 1;
|
|
padding: 10px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
font-size: 16px;
|
|
}
|
|
.ifnex-form-group button {
|
|
padding: 10px 20px;
|
|
background: #0073aa;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
}
|
|
.ifnex-form-group button:hover {
|
|
background: #005a87;
|
|
}
|
|
.ifnex-form-group button:disabled {
|
|
background: #ccc;
|
|
cursor: not-allowed;
|
|
}
|
|
.ifnex-tracking-result {
|
|
margin-top: 20px;
|
|
padding: 15px;
|
|
background: #f9f9f9;
|
|
border-radius: 4px;
|
|
}
|
|
.ifnex-error {
|
|
color: #dc3232;
|
|
}
|
|
.ifnex-tracking-status h3 {
|
|
margin-top: 0;
|
|
}
|
|
.ifnex-status-badge {
|
|
display: inline-block;
|
|
padding: 5px 10px;
|
|
background: #0073aa;
|
|
color: white;
|
|
border-radius: 4px;
|
|
margin-bottom: 10px;
|
|
}
|
|
.ifnex-timeline {
|
|
margin-top: 20px;
|
|
}
|
|
.ifnex-timeline ul {
|
|
list-style: none;
|
|
padding: 0;
|
|
}
|
|
.ifnex-timeline li {
|
|
padding: 10px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
.ifnex-timeline li:last-child {
|
|
border-bottom: none;
|
|
}
|
|
</style>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
// AJAX Handler
|
|
add_action('wp_ajax_ifnex_track_shipment', 'ifnex_track_shipment_ajax');
|
|
add_action('wp_ajax_nopriv_ifnex_track_shipment', 'ifnex_track_shipment_ajax');
|
|
|
|
function ifnex_track_shipment_ajax() {
|
|
$awb = isset($_POST['awb']) ? sanitize_text_field($_POST['awb']) : '';
|
|
|
|
if (empty($awb)) {
|
|
wp_send_json(array('success' => false, 'message' => 'شماره بارنامه وارد نشده است.'));
|
|
return;
|
|
}
|
|
|
|
$client = new IFNEX_API_Client();
|
|
$result = $client->track_shipment($awb);
|
|
|
|
if (is_wp_error($result)) {
|
|
wp_send_json(array('success' => false, 'message' => $result->get_error_message()));
|
|
return;
|
|
}
|
|
|
|
// ساخت HTML نتیجه
|
|
ob_start();
|
|
?>
|
|
<div class="ifnex-tracking-status">
|
|
<h3>وضعیت مرسوله <?php echo esc_html($result['awb_no'] ?? ''); ?></h3>
|
|
<div class="ifnex-status-badge">
|
|
<?php echo esc_html($result['status'] ?? 'نامشخص'); ?>
|
|
</div>
|
|
<div class="ifnex-details">
|
|
<p><strong>نوع:</strong> <?php echo esc_html($result['type'] ?? ''); ?></p>
|
|
<p><strong>جهت:</strong> <?php echo esc_html($result['direction'] ?? ''); ?></p>
|
|
<?php if (!empty($result['sender']['name'])): ?>
|
|
<p><strong>فرستنده:</strong> <?php echo esc_html($result['sender']['name']); ?></p>
|
|
<?php endif; ?>
|
|
<?php if (!empty($result['receiver']['name'])): ?>
|
|
<p><strong>گیرنده:</strong> <?php echo esc_html($result['receiver']['name']); ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php if (!empty($result['timeline']) && is_array($result['timeline'])): ?>
|
|
<div class="ifnex-timeline">
|
|
<h4>تاریخچه رهگیری</h4>
|
|
<ul>
|
|
<?php foreach (array_reverse($result['timeline']) as $event): ?>
|
|
<li>
|
|
<strong><?php echo esc_html($event['event_date'] ?? ''); ?></strong>
|
|
<span><?php echo esc_html($event['event_description'] ?? ''); ?></span>
|
|
<?php if (!empty($event['location'])): ?>
|
|
<small><?php echo esc_html($event['location']); ?></small>
|
|
<?php endif; ?>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php
|
|
$html = ob_get_clean();
|
|
|
|
wp_send_json(array('success' => true, 'html' => $html));
|
|
}
|
|
|
|
// AJAX Handler: موجودی کیف پول
|
|
add_action('wp_ajax_ifnex_get_wallet_balance', 'ifnex_get_wallet_balance_ajax');
|
|
add_action('wp_ajax_nopriv_ifnex_get_wallet_balance', 'ifnex_get_wallet_balance_ajax');
|
|
|
|
function ifnex_get_wallet_balance_ajax() {
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json(array('success' => false, 'message' => 'برای مشاهده موجودی باید وارد شوید.'));
|
|
return;
|
|
}
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$balance = $bridge->get_wallet_balance(get_current_user_id());
|
|
|
|
if (is_wp_error($balance)) {
|
|
wp_send_json(array('success' => false, 'message' => $balance->get_error_message()));
|
|
return;
|
|
}
|
|
|
|
wp_send_json(array(
|
|
'success' => true,
|
|
'balance' => $balance['balance'],
|
|
'formatted_balance' => number_format($balance['balance']) . ' ریال',
|
|
'total_deposited' => number_format($balance['total_deposited']) . ' ریال',
|
|
'total_withdrawn' => number_format($balance['total_withdrawn']) . ' ریال',
|
|
'is_frozen' => $balance['is_frozen'],
|
|
));
|
|
}
|
|
|
|
// AJAX Handler: لیست تراکنشها
|
|
add_action('wp_ajax_ifnex_get_transactions', 'ifnex_get_transactions_ajax');
|
|
add_action('wp_ajax_nopriv_ifnex_get_transactions', 'ifnex_get_transactions_ajax');
|
|
|
|
function ifnex_get_transactions_ajax() {
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json(array('success' => false, 'message' => 'برای مشاهده تراکنشها باید وارد شوید.'));
|
|
return;
|
|
}
|
|
|
|
$per_page = isset($_POST['per_page']) ? intval($_POST['per_page']) : 10;
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$transactions = $bridge->get_transactions(get_current_user_id(), $per_page);
|
|
|
|
if (is_wp_error($transactions)) {
|
|
wp_send_json(array('success' => false, 'message' => $transactions->get_error_message()));
|
|
return;
|
|
}
|
|
|
|
// ساخت HTML لیست تراکنشها
|
|
if (empty($transactions['transactions'])) {
|
|
wp_send_json(array(
|
|
'success' => true,
|
|
'html' => '<p>هنوز تراکنشی ثبت نشده است.</p>',
|
|
));
|
|
return;
|
|
}
|
|
|
|
ob_start();
|
|
?>
|
|
<div class="ifnex-transactions-list">
|
|
<?php foreach ($transactions['transactions'] as $transaction): ?>
|
|
<div class="ifnex-transaction-item">
|
|
<div class="ifnex-transaction-header">
|
|
<span class="ifnex-transaction-type">
|
|
<?php echo esc_html($transaction['type']); ?>
|
|
</span>
|
|
<span class="ifnex-transaction-amount <?php echo $transaction['amount'] >= 0 ? 'positive' : 'negative'; ?>">
|
|
<?php echo $transaction['amount'] >= 0 ? '+' : ''; ?>
|
|
<?php echo number_format($transaction['amount']); ?> ریال
|
|
</span>
|
|
</div>
|
|
<div class="ifnex-transaction-details">
|
|
<p class="ifnex-transaction-description"><?php echo esc_html($transaction['description']); ?></p>
|
|
<div class="ifnex-transaction-meta">
|
|
<span class="ifnex-transaction-status"><?php echo esc_html($transaction['status']); ?></span>
|
|
<span class="ifnex-transaction-date"><?php echo esc_html($transaction['created_at_jalali']); ?></span>
|
|
</div>
|
|
<?php if (!empty($transaction['reference_id'])): ?>
|
|
<p class="ifnex-transaction-ref">کد پیگیری: <?php echo esc_html($transaction['reference_id']); ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php
|
|
$html = ob_get_clean();
|
|
|
|
wp_send_json(array(
|
|
'success' => true,
|
|
'html' => $html,
|
|
));
|
|
}
|