feat(wp): add ifnex-bridge plugin for Laravel API integration
Implement a new WordPress plugin to bridge the frontend with the Laravel logistics API. This includes: - API client for secure shipment tracking via Bearer token - Admin settings page for configuring API URL and Key - Shortcodes for embedding tracking forms and status displays - AJAX-based tracking form with real-time results and timeline view
This commit is contained in:
parent
8f66efac00
commit
97e641de42
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Plugin Name: IFNEX Logistics Bridge
|
||||||
|
* Description: اتصال فرانتاند سایت ایفنکس به API لاراول
|
||||||
|
* Version: 1.0
|
||||||
|
* Author: VernaSoft group (Kazem Alghasi)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// لود کردن فایلهای پلاگین
|
||||||
|
require_once plugin_dir_path( __FILE__ ) . 'includes/api-client.php';
|
||||||
|
require_once plugin_dir_path( __FILE__ ) . 'includes/shortcodes.php';
|
||||||
|
require_once plugin_dir_path( __FILE__ ) . 'includes/tracking-form.php';
|
||||||
|
|
||||||
|
// اضافه کردن لینک به منوی پیشخوان وردپرس
|
||||||
|
add_action( 'admin_menu', 'ifnex_plugin_setup_menu' );
|
||||||
|
function ifnex_plugin_setup_menu() {
|
||||||
|
add_menu_page( 'تنظیمات IFNEX', 'IFNEX', 'manage_options', 'ifnex-settings', 'ifnex_settings_page_html', 'dashicons-location-alt', 30 );
|
||||||
|
}
|
||||||
|
|
||||||
|
function ifnex_settings_page_html() {
|
||||||
|
if (isset($_POST['ifnex_api_url']) && check_admin_referer('ifnex_settings_save')) {
|
||||||
|
update_option('ifnex_api_url', sanitize_url($_POST['ifnex_api_url']));
|
||||||
|
update_option('ifnex_api_key', sanitize_text_field($_POST['ifnex_api_key']));
|
||||||
|
echo '<div class="notice notice-success"><p>تنظیمات ذخیره شد.</p></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$api_url = get_option('ifnex_api_url', 'http://localhost:8000/api/v1');
|
||||||
|
$api_key = get_option('ifnex_api_key', '');
|
||||||
|
?>
|
||||||
|
<div class="wrap">
|
||||||
|
<h1>تنظیمات IFNEX Logistics Bridge</h1>
|
||||||
|
<form method="post">
|
||||||
|
<?php wp_nonce_field('ifnex_settings_save'); ?>
|
||||||
|
<table class="form-table">
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><label for="ifnex_api_url">API URL</label></th>
|
||||||
|
<td><input type="text" id="ifnex_api_url" name="ifnex_api_url" value="<?php echo esc_attr($api_url); ?>" class="regular-text" placeholder="http://localhost:8000/api/v1"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><label for="ifnex_api_key">API Key</label></th>
|
||||||
|
<td><input type="text" id="ifnex_api_key" name="ifnex_api_key" value="<?php echo esc_attr($api_key); ?>" class="regular-text"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<?php submit_button('ذخیره تنظیمات'); ?>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* IFNEX API Client
|
||||||
|
* اتصال به API لاراول برای استعلام ترکینگ
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
class IFNEX_API_Client {
|
||||||
|
private $api_url;
|
||||||
|
private $api_key;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->api_url = rtrim(get_option('ifnex_api_url', 'http://localhost:8000/api/v1'), '/');
|
||||||
|
$this->api_key = get_option('ifnex_api_key', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function track_shipment($awb_no) {
|
||||||
|
if (empty($this->api_key)) {
|
||||||
|
return new WP_Error('no_api_key', 'API Key تنظیم نشده است.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = $this->api_url . '/track/' . urlencode($awb_no);
|
||||||
|
|
||||||
|
$args = array(
|
||||||
|
'headers' => array(
|
||||||
|
'Authorization' => 'Bearer ' . $this->api_key,
|
||||||
|
'Accept' => 'application/json',
|
||||||
|
),
|
||||||
|
'timeout' => 30,
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = wp_remote_get($url, $args);
|
||||||
|
|
||||||
|
if (is_wp_error($response)) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = wp_remote_retrieve_body($response);
|
||||||
|
$data = json_decode($body, true);
|
||||||
|
|
||||||
|
if ($response['response']['code'] === 404) {
|
||||||
|
return new WP_Error('not_found', 'مرسولهای با این کد پیدا نشد.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($response['response']['code'] !== 200) {
|
||||||
|
return new WP_Error('api_error', 'خطا در ارتباط با API: ' . ($data['message'] ?? 'Unknown error'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* IFNEX Shortcodes
|
||||||
|
* شورتکدهای پلاگین IFNEX Bridge
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// شورتکد فرم ترکینگ
|
||||||
|
add_shortcode('ifnex_tracking_form', 'ifnex_tracking_form_shortcode');
|
||||||
|
|
||||||
|
function ifnex_tracking_form_shortcode($atts) {
|
||||||
|
$atts = shortcode_atts(array(
|
||||||
|
'title' => 'رهگیری مرسوله',
|
||||||
|
'placeholder' => 'شماره بارنامه را وارد کنید',
|
||||||
|
'button_text' => 'رهگیری',
|
||||||
|
), $atts);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
<div class="ifnex-tracking-container">
|
||||||
|
<h2><?php echo esc_html($atts['title']); ?></h2>
|
||||||
|
<form id="ifnex-tracking-form" class="ifnex-tracking-form">
|
||||||
|
<div class="ifnex-form-group">
|
||||||
|
<input type="text" id="ifnex-awb-input" placeholder="<?php echo esc_attr($atts['placeholder']); ?>" required>
|
||||||
|
<button type="submit" id="ifnex-track-btn"><?php echo esc_html($atts['button_text']); ?></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div id="ifnex-tracking-result" class="ifnex-tracking-result" style="display: none;"></div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
// شورتکد نمایش وضعیت مستقیم
|
||||||
|
add_shortcode('ifnex_tracking_status', 'ifnex_tracking_status_shortcode');
|
||||||
|
|
||||||
|
function ifnex_tracking_status_shortcode($atts) {
|
||||||
|
$atts = shortcode_atts(array(
|
||||||
|
'awb' => '',
|
||||||
|
), $atts);
|
||||||
|
|
||||||
|
if (empty($atts['awb'])) {
|
||||||
|
return '<p>شماره بارنامه وارد نشده است.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$client = new IFNEX_API_Client();
|
||||||
|
$result = $client->track_shipment($atts['awb']);
|
||||||
|
|
||||||
|
if (is_wp_error($result)) {
|
||||||
|
return '<p class="ifnex-error">' . esc_html($result->get_error_message()) . '</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
<p><strong>فرستنده:</strong> <?php echo esc_html($result['sender']['name'] ?? ''); ?></p>
|
||||||
|
<p><strong>گیرنده:</strong> <?php echo esc_html($result['receiver']['name'] ?? ''); ?></p>
|
||||||
|
</div>
|
||||||
|
<?php if (!empty($result['timeline']) && is_array($result['timeline'])): ?>
|
||||||
|
<div class="ifnex-timeline">
|
||||||
|
<h4>تاریخچه رهگیری</h4>
|
||||||
|
<ul>
|
||||||
|
<?php foreach ($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
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
@ -0,0 +1,206 @@
|
|||||||
|
<?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));
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user