Introduce a complete workflow for managing shipment-related documents
and mandatory commitment forms between the Laravel backend and
WordPress frontend.
- Laravel:
- Add `ShipmentCommitmentForm` model and migration to track signed
forms per shipment.
- Implement `CommitmentFormController` to handle fetching available
forms and uploading signed documents.
- Add PDF download endpoints for AWB, labels, and invoices via
`ShipmentPdfController`.
- Extend `User` model with notification management methods.
- Add `FinanceOverviewWidget` for Filament dashboard.
- WordPress:
- Implement AJAX handlers in `user-bridge.php` for PDF downloads and
commitment form management.
- Update `shortcodes.php` to display document download grid and
dynamic commitment form upload interface in order details.
- Add styling for document buttons and form status indicators in
`ifnex-orders.css`.
841 lines
31 KiB
PHP
841 lines
31 KiB
PHP
<?php
|
|
if (function_exists('opcache_reset')) { @opcache_reset(); }
|
|
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
|
header('Pragma: no-cache');
|
|
/**
|
|
* IFNEX User Bridge
|
|
* مدیریت ارتباط کاربران وردپرس با لاراول
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class IFNEX_User_Bridge {
|
|
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', '');
|
|
}
|
|
|
|
/**
|
|
* دریافت توکن Sanctum از لاراول برای کاربر وردپرس
|
|
*/
|
|
public function get_user_token($user_id) {
|
|
$token = get_user_meta($user_id, 'ifnex_laravel_token', true);
|
|
$token_expiry = get_user_meta($user_id, 'ifnex_laravel_token_expiry', true);
|
|
|
|
// اگر توکن معتبر وجود دارد، از آن استفاده کن
|
|
if ($token && $token_expiry && strtotime($token_expiry) > time()) {
|
|
return $token;
|
|
}
|
|
|
|
// دریافت اطلاعات کاربر وردپرس
|
|
$wp_user = get_userdata($user_id);
|
|
if (!$wp_user) {
|
|
return false;
|
|
}
|
|
|
|
// درخواست توکن از Bridge endpoint (جدید)
|
|
$token = $this->request_bridge_token(
|
|
$user_id,
|
|
$wp_user->user_email,
|
|
$wp_user->display_name
|
|
);
|
|
|
|
if ($token) {
|
|
update_user_meta($user_id, 'ifnex_laravel_token', $token);
|
|
update_user_meta($user_id, 'ifnex_laravel_token_expiry', date('Y-m-d H:i:s', strtotime('+30 days')));
|
|
}
|
|
|
|
return $token;
|
|
}
|
|
|
|
/**
|
|
* درخواست توکن از Bridge endpoint جدید
|
|
* این روش نیازی به رمز عبور ندارد و از API Key مشترک استفاده میکند
|
|
*/
|
|
private function request_bridge_token($wp_user_id, $email, $name) {
|
|
$url = $this->api_url . '/bridge/login';
|
|
$bridge_key = get_option('ifnex_bridge_api_key', '');
|
|
|
|
if (empty($bridge_key)) {
|
|
error_log('IFNEX: Bridge API Key is not configured in WordPress settings');
|
|
return false;
|
|
}
|
|
|
|
$args = array(
|
|
'headers' => array(
|
|
'Content-Type' => 'application/json',
|
|
'Accept' => 'application/json',
|
|
),
|
|
'body' => json_encode(array(
|
|
'bridge_api_key' => $bridge_key,
|
|
'wp_user_id' => $wp_user_id,
|
|
'wp_user_email' => $email,
|
|
'wp_user_name' => $name,
|
|
'token_name' => 'wordpress-bridge-' . get_current_blog_id(),
|
|
)),
|
|
'timeout' => 30,
|
|
);
|
|
|
|
$response = wp_remote_post($url, $args);
|
|
|
|
if (is_wp_error($response)) {
|
|
error_log('IFNEX Bridge Error: ' . $response->get_error_message());
|
|
return false;
|
|
}
|
|
|
|
$body = wp_remote_retrieve_body($response);
|
|
$data = json_decode($body, true);
|
|
|
|
if (isset($data['token'])) {
|
|
return $data['token'];
|
|
}
|
|
|
|
error_log('IFNEX Bridge Token Error: ' . ($data['message'] ?? 'Unknown error'));
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* ارسال درخواست احراز هویتشده به API لاراول
|
|
*/
|
|
public function authenticated_request($user_id, $endpoint, $method = 'GET', $data = array()) {
|
|
$token = $this->get_user_token($user_id);
|
|
|
|
if (!$token) {
|
|
return new WP_Error('no_token', 'توکن احراز هویت یافت نشد.');
|
|
}
|
|
|
|
$url = $this->api_url . $endpoint;
|
|
$method = strtoupper($method);
|
|
|
|
$args = array(
|
|
'headers' => array(
|
|
'Authorization' => 'Bearer ' . $token,
|
|
'Accept' => 'application/json',
|
|
'Content-Type' => 'application/json',
|
|
),
|
|
'timeout' => 30,
|
|
'method' => $method, // ✅ همیشه متد درخواستی استفاده شود
|
|
);
|
|
|
|
// ✅ اصلاح: بر اساس متد، data را اضافه کن
|
|
if (in_array($method, ['POST', 'PUT', 'PATCH'])) {
|
|
// حتی اگر data خالی باشد، body را خالی بفرست
|
|
$args['body'] = json_encode($data ?: new \stdClass());
|
|
} elseif ($method === 'GET' && !empty($data)) {
|
|
// برای GET، data را به URL اضافه کن
|
|
$url = add_query_arg($data, $url);
|
|
}
|
|
|
|
$response = wp_remote_request($url, $args);
|
|
|
|
if (is_wp_error($response)) {
|
|
return $response;
|
|
}
|
|
|
|
$body = wp_remote_retrieve_body($response);
|
|
$code = wp_remote_retrieve_response_code($response);
|
|
$data = json_decode($body, true);
|
|
|
|
// لاگ برای دیباگ
|
|
error_log("IFNEX API [{$method}] {$endpoint} => Status: {$code}");
|
|
|
|
if ($code === 401) {
|
|
$this->invalidate_token(get_current_user_id());
|
|
return new WP_Error('token_expired', 'توکن منقضی شده است. لطفاً دوباره وارد شوید.');
|
|
}
|
|
|
|
// اگر پاسخ JSON نیست
|
|
if (!is_array($data)) {
|
|
return new WP_Error('invalid_response', 'پاسخ نامعتبر از سرور: ' . substr($body, 0, 200));
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* باطل کردن توکن
|
|
*/
|
|
public function invalidate_token($user_id) {
|
|
delete_user_meta($user_id, 'ifnex_laravel_token');
|
|
delete_user_meta($user_id, 'ifnex_laravel_token_expiry');
|
|
}
|
|
|
|
/**
|
|
* دریافت موجودی کیف پول کاربر
|
|
*/
|
|
public function get_wallet_balance($user_id) {
|
|
$result = $this->authenticated_request($user_id, '/wallet/balance');
|
|
|
|
if (is_wp_error($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return array(
|
|
'balance' => $result['balance'] ?? 0,
|
|
'total_deposited' => $result['total_deposited'] ?? 0,
|
|
'total_withdrawn' => $result['total_withdrawn'] ?? 0,
|
|
'is_frozen' => $result['is_frozen'] ?? false,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* دریافت تراکنشهای کاربر
|
|
*/
|
|
public function get_transactions($user_id, $per_page = 15) {
|
|
$result = $this->authenticated_request($user_id, '/wallet/transactions', 'GET', array(
|
|
'per_page' => $per_page,
|
|
));
|
|
|
|
if (is_wp_error($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* رهگیری مرسوله
|
|
*/
|
|
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;
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// Customer Orders API (جدید)
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* دریافت پروفایل و آمار کاربر
|
|
*/
|
|
public function get_customer_profile($user_id) {
|
|
$result = $this->authenticated_request($user_id, '/customer/profile');
|
|
|
|
if (is_wp_error($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* دریافت لیست کشورها
|
|
*/
|
|
public function get_countries($user_id) {
|
|
$api_url = rtrim(get_option('ifnex_api_url', 'http://localhost:8000/api/v1'), '/');
|
|
$response = wp_remote_get($api_url . '/countries', array(
|
|
'headers' => array('Accept' => 'application/json'),
|
|
'timeout' => 15,
|
|
));
|
|
|
|
if (is_wp_error($response)) {
|
|
return $response;
|
|
}
|
|
|
|
$body = json_decode(wp_remote_retrieve_body($response), true);
|
|
$code = wp_remote_retrieve_response_code($response);
|
|
|
|
if ($code !== 200 || empty($body['data'])) {
|
|
return new WP_Error('countries_error', 'خطا در دریافت لیست کشورها');
|
|
}
|
|
|
|
return $body['data'];
|
|
}
|
|
|
|
/**
|
|
* دریافت لیست سفارشات کاربر
|
|
*/
|
|
public function get_customer_orders($user_id, $per_page = 15, $status = null) {
|
|
$params = ['per_page' => $per_page];
|
|
|
|
if ($status) {
|
|
$params['status'] = $status;
|
|
}
|
|
|
|
$result = $this->authenticated_request($user_id, '/customer/orders', 'GET', $params);
|
|
|
|
if (is_wp_error($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* دریافت جزئیات یک سفارش
|
|
*/
|
|
public function get_customer_order($user_id, $shipment_id) {
|
|
$result = $this->authenticated_request($user_id, "/customer/orders/{$shipment_id}");
|
|
|
|
if (is_wp_error($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* ثبت سفارش جدید
|
|
*/
|
|
public function create_customer_order($user_id, $order_data) {
|
|
$result = $this->authenticated_request($user_id, '/customer/orders', 'POST', $order_data);
|
|
|
|
if (is_wp_error($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* لغو سفارش
|
|
*/
|
|
public function cancel_customer_order($user_id, $shipment_id) {
|
|
$result = $this->authenticated_request($user_id, "/customer/orders/{$shipment_id}/cancel", 'POST');
|
|
|
|
if (is_wp_error($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* دریافت نوتیفیکیشنهای کاربر
|
|
*/
|
|
public function get_notifications($user_id, $per_page = 20) {
|
|
$result = $this->authenticated_request($user_id, '/customer/notifications', 'GET', array(
|
|
'per_page' => $per_page,
|
|
));
|
|
|
|
if (is_wp_error($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* علامتگذاری نوتیفیکیشن به عنوان خواندهشده
|
|
*/
|
|
public function mark_notification_read($user_id, $notification_id) {
|
|
$result = $this->authenticated_request($user_id, "/customer/notifications/{$notification_id}/read", 'POST');
|
|
return $result;
|
|
}
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// AJAX Handler برای لغو سفارش
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
add_action('wp_ajax_ifnex_cancel_order', 'ifnex_cancel_order_ajax');
|
|
|
|
function ifnex_cancel_order_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error('باید وارد شوید.');
|
|
}
|
|
|
|
$order_id = intval($_POST['order_id'] ?? 0);
|
|
if (!$order_id) {
|
|
wp_send_json_error('شناسه سفارش نامعتبر است.');
|
|
}
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$result = $bridge->cancel_customer_order(get_current_user_id(), $order_id);
|
|
|
|
if (is_wp_error($result)) {
|
|
wp_send_json_error($result->get_error_message());
|
|
}
|
|
|
|
wp_send_json_success('سفارش لغو شد.');
|
|
}
|
|
|
|
// Enqueue AJAX script
|
|
add_action('wp_enqueue_scripts', 'ifnex_enqueue_ajax_script');
|
|
|
|
function ifnex_enqueue_ajax_script() {
|
|
global $post;
|
|
|
|
if (is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'ifnex_orders_list')) {
|
|
wp_enqueue_script('jquery');
|
|
wp_localize_script('jquery', 'ifnex_ajax', array(
|
|
'ajax_url' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
|
));
|
|
}
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// AJAX Handlers برای فرم سفارش
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
add_action('wp_ajax_ifnex_get_countries', 'ifnex_get_countries_ajax');
|
|
function ifnex_get_countries_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) wp_send_json_error('باید وارد شوید.');
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$result = $bridge->get_countries(get_current_user_id());
|
|
|
|
if (is_wp_error($result)) wp_send_json_error($result->get_error_message());
|
|
wp_send_json_success($result);
|
|
}
|
|
|
|
add_action('wp_ajax_ifnex_calculate_price', 'ifnex_calculate_price_ajax');
|
|
function ifnex_calculate_price_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) wp_send_json_error('باید وارد شوید.');
|
|
|
|
$data = $_POST['data'] ?? [];
|
|
if (empty($data)) wp_send_json_error('دادهای ارسال نشده.');
|
|
|
|
// تبدیل direction برای PriceCalculator
|
|
$payload = array(
|
|
'direction' => ($data['direction'] === 'export') ? 'Outbound' : 'Inbound',
|
|
'type' => $data['type'],
|
|
'country_iso' => $data['country_iso'],
|
|
'weight' => floatval($data['weight']),
|
|
'volumetric_weight' => floatval($data['volumetric_weight'] ?? 0),
|
|
);
|
|
if (!empty($data['discount_code'])) $payload['discount_code'] = $data['discount_code'];
|
|
|
|
$api_url = rtrim(get_option('ifnex_api_url', 'http://localhost:8000/api/v1'), '/');
|
|
$response = wp_remote_post($api_url . '/calculate', array(
|
|
'headers' => array('Content-Type' => 'application/json', 'Accept' => 'application/json'),
|
|
'body' => json_encode($payload),
|
|
'timeout' => 30,
|
|
));
|
|
|
|
if (is_wp_error($response)) wp_send_json_error($response->get_error_message());
|
|
|
|
$body = json_decode(wp_remote_retrieve_body($response), true);
|
|
if ($response['response']['code'] !== 200) {
|
|
wp_send_json_error($body['message'] ?? 'خطا در محاسبه قیمت');
|
|
}
|
|
wp_send_json_success($body);
|
|
}
|
|
|
|
add_action('wp_ajax_ifnex_submit_order', 'ifnex_submit_order_ajax');
|
|
function ifnex_submit_order_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) wp_send_json_error('باید وارد شوید.');
|
|
|
|
$data = $_POST['data'] ?? [];
|
|
if (empty($data)) wp_send_json_error('دادهای ارسال نشده.');
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$result = $bridge->create_customer_order(get_current_user_id(), $data);
|
|
|
|
if (is_wp_error($result)) wp_send_json_error($result->get_error_message());
|
|
if (isset($result['success']) && !$result['success']) {
|
|
wp_send_json_error($result['message'] ?? 'خطا در ثبت سفارش');
|
|
}
|
|
wp_send_json_success($result);
|
|
}
|
|
|
|
// Enqueue scripts & styles برای شورتکدهای جدید
|
|
add_action('wp_enqueue_scripts', 'ifnex_enqueue_order_assets');
|
|
function ifnex_enqueue_order_assets() {
|
|
global $post;
|
|
if (!is_a($post, 'WP_Post')) return;
|
|
|
|
$plugin_url = trailingslashit(plugins_url('', dirname(__FILE__)));
|
|
|
|
// لود CSS — وابسته به CSS قالب
|
|
wp_enqueue_style(
|
|
'ifnex-orders-css',
|
|
$plugin_url . 'assets/css/ifnex-orders.css',
|
|
array('ifnex-main'),
|
|
'2.0.0-' . time()
|
|
);
|
|
|
|
// لود jQuery & JS
|
|
wp_enqueue_script('jquery');
|
|
wp_enqueue_script(
|
|
'ifnex-order-form-js',
|
|
$plugin_url . 'assets/js/ifnex-order-form.js',
|
|
array('jquery'),
|
|
'2.0.0-' . time(),
|
|
true
|
|
);
|
|
|
|
// Pass data to JS
|
|
wp_localize_script('ifnex-order-form-js', 'ifnex_ajax', array(
|
|
'ajax_url' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
|
'orders_url' => home_url('/my-account/?tab=orders'),
|
|
));
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// AJAX Handler برای شارژ کیف پول
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
add_action('wp_ajax_ifnex_wallet_charge', 'ifnex_wallet_charge_ajax');
|
|
|
|
function ifnex_wallet_charge_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error('باید وارد شوید.');
|
|
}
|
|
|
|
$amount = intval($_POST['amount'] ?? 0);
|
|
if ($amount < 10000) {
|
|
wp_send_json_error('مبلغ نامعتبر است.');
|
|
}
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$callback_url = home_url('/wallet/?status=callback');
|
|
|
|
$result = $bridge->authenticated_request(
|
|
get_current_user_id(),
|
|
'/payment/redirect',
|
|
'POST',
|
|
[
|
|
'amount' => $amount,
|
|
'description' => 'شارژ کیف پول IFNEX',
|
|
'frontend_callback' => home_url('/wallet/'),
|
|
]
|
|
);
|
|
|
|
if (is_wp_error($result)) {
|
|
wp_send_json_error($result->get_error_message());
|
|
}
|
|
|
|
if (isset($result['success']) && !$result['success']) {
|
|
wp_send_json_error($result['message'] ?? 'خطا در اتصال به درگاه');
|
|
}
|
|
|
|
wp_send_json_success($result);
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// AJAX Handler برای پرداخت سفارش از کیف پول
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
add_action('wp_ajax_ifnex_pay_order_wallet', 'ifnex_pay_order_wallet_ajax');
|
|
|
|
function ifnex_pay_order_wallet_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error('باید وارد شوید.');
|
|
}
|
|
|
|
$order_id = intval($_POST['order_id'] ?? 0);
|
|
if (!$order_id) {
|
|
wp_send_json_error('شناسه سفارش نامعتبر است.');
|
|
}
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$result = $bridge->authenticated_request(
|
|
get_current_user_id(),
|
|
"/customer/orders/{$order_id}/pay-wallet",
|
|
'POST'
|
|
);
|
|
|
|
if (is_wp_error($result)) {
|
|
wp_send_json_error($result->get_error_message());
|
|
}
|
|
|
|
if (isset($result['success']) && !$result['success']) {
|
|
wp_send_json_error($result['message'] ?? 'خطا در پرداخت از کیف پول');
|
|
}
|
|
|
|
wp_send_json_success($result);
|
|
}
|
|
|
|
add_action('wp_ajax_ifnex_pay_order_gateway', 'ifnex_pay_order_gateway_ajax');
|
|
function ifnex_pay_order_gateway_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) wp_send_json_error('باید وارد شوید.');
|
|
|
|
$order_id = intval($_POST['order_id'] ?? 0);
|
|
$callback_url = sanitize_url($_POST['callback_url'] ?? '');
|
|
|
|
if (!$order_id) wp_send_json_error('شناسه سفارش نامعتبر است.');
|
|
if (!$callback_url) wp_send_json_error('آدرس بازگشت نامعتبر است.');
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$result = $bridge->authenticated_request(
|
|
get_current_user_id(),
|
|
"/customer/orders/{$order_id}/pay-gateway",
|
|
'POST',
|
|
['frontend_callback' => $callback_url]
|
|
);
|
|
|
|
if (is_wp_error($result)) wp_send_json_error($result->get_error_message());
|
|
if (isset($result['success']) && !$result['success']) {
|
|
wp_send_json_error($result['message'] ?? 'خطا در اتصال به درگاه');
|
|
}
|
|
|
|
wp_send_json_success($result);
|
|
}
|
|
|
|
// Enqueue برای صفحه پرداخت
|
|
add_action('wp_enqueue_scripts', 'ifnex_enqueue_payment_assets');
|
|
function ifnex_enqueue_payment_assets() {
|
|
global $post;
|
|
if (!is_a($post, 'WP_Post')) return;
|
|
|
|
if (has_shortcode($post->post_content, 'ifnex_order_payment')) {
|
|
$plugin_url = trailingslashit(plugins_url('', dirname(__FILE__)));
|
|
wp_enqueue_style(
|
|
'ifnex-orders-css',
|
|
$plugin_url . 'assets/css/ifnex-orders.css',
|
|
array('ifnex-main'),
|
|
'2.0.0-' . time()
|
|
);
|
|
wp_enqueue_script('jquery');
|
|
wp_add_inline_script('jquery', 'var ifnex_ajax = ' . wp_json_encode(array(
|
|
'ajax_url' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
|
'orders_url' => home_url('/my-account/?tab=orders'),
|
|
)) . ';', 'before');
|
|
}
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// لود سراسری CSS و متغیرهای AJAX برای همه صفحات IFNEX
|
|
// این تابع همیشه اجرا میشود تا هیچ شورتکدی بدون استایل نماند
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
add_action('wp_enqueue_scripts', 'ifnex_enqueue_global_assets', 20);
|
|
|
|
function ifnex_enqueue_global_assets() {
|
|
$plugin_url = trailingslashit(plugins_url('', dirname(__FILE__)));
|
|
|
|
// لود CSS اصلی — وابسته به CSS قالب تا بعد از آن لود شود
|
|
wp_enqueue_style(
|
|
'ifnex-orders-css',
|
|
$plugin_url . 'assets/css/ifnex-orders.css',
|
|
array('ifnex-main'),
|
|
'2.0.0-' . time()
|
|
);
|
|
|
|
// لود jQuery
|
|
wp_enqueue_script('jquery');
|
|
|
|
// متغیرهای AJAX برای همه صفحات
|
|
wp_add_inline_script('jquery', 'var ifnex_ajax = ' . wp_json_encode(array(
|
|
'ajax_url' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('ifnex_ajax_nonce'),
|
|
'orders_url' => home_url('/my-account/?tab=orders'),
|
|
'home_url' => home_url('/'),
|
|
)) . ';', 'before');
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// AJAX Handler برای دانلود مدارک PDF سفارش
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
add_action('wp_ajax_ifnex_download_order_pdf', 'ifnex_download_order_pdf_ajax');
|
|
|
|
function ifnex_download_order_pdf_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error('باید وارد شوید.');
|
|
}
|
|
|
|
$order_id = intval($_POST['order_id'] ?? 0);
|
|
$download_type = sanitize_text_field($_POST['download_type'] ?? '');
|
|
|
|
if (!$order_id) wp_send_json_error('شناسه سفارش نامعتبر است.');
|
|
if (!in_array($download_type, ['awb', 'invoice', 'label', 'import-invoice'])) wp_send_json_error('نوع فایل نامعتبر است.');
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$user_id = get_current_user_id();
|
|
|
|
// بررسی مالکیت سفارش
|
|
$order = $bridge->get_customer_order($user_id, $order_id);
|
|
if (is_wp_error($order)) wp_send_json_error($order->get_error_message());
|
|
|
|
// ساخت URL دانلود از API لاراول
|
|
$api_url = get_option('ifnex_api_url', 'http://localhost:8000/api/v1');
|
|
$download_url = rtrim($api_url, '/') . "/customer/orders/{$order_id}/pdf/{$download_type}";
|
|
|
|
// ارسال درخواست به لاراول با توکن احراز هویت
|
|
$token = get_user_meta($user_id, 'ifnex_api_token', true);
|
|
if (!$token) wp_send_json_error('توکن احراز هویت یافت نشد.');
|
|
|
|
$response = wp_remote_get($download_url, array(
|
|
'headers' => array(
|
|
'Authorization' => 'Bearer ' . $token,
|
|
'Accept' => 'application/pdf',
|
|
),
|
|
'timeout' => 30,
|
|
));
|
|
|
|
if (is_wp_error($response)) wp_send_json_error('خطا در ارتباط با سرور.');
|
|
|
|
$status_code = wp_remote_retrieve_response_code($response);
|
|
if ($status_code !== 200) wp_send_json_error('خطا در دانلود فایل.');
|
|
|
|
$file_content = wp_remote_retrieve_body($response);
|
|
$filename = strtoupper($download_type) . '-' . $order['data']['awb_no'] . '.pdf';
|
|
|
|
// ارسال فایل به مرورگر
|
|
nocache_headers();
|
|
header('Content-Type: application/pdf');
|
|
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
|
header('Content-Length: ' . strlen($file_content));
|
|
echo $file_content;
|
|
exit;
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// AJAX Handler برای دریافت لیست تعهدنامههای سفارش
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
add_action('wp_ajax_ifnex_get_commitment_forms', 'ifnex_get_commitment_forms_ajax');
|
|
|
|
function ifnex_get_commitment_forms_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error('باید وارد شوید.');
|
|
}
|
|
|
|
$order_id = intval($_POST['order_id'] ?? 0);
|
|
if (!$order_id) wp_send_json_error('شناسه سفارش نامعتبر است.');
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$user_id = get_current_user_id();
|
|
|
|
$order = $bridge->get_customer_order($user_id, $order_id);
|
|
if (is_wp_error($order)) wp_send_json_error($order->get_error_message());
|
|
|
|
$direction = strtolower($order['data']['direction'] ?? 'export');
|
|
$api_url = get_option('ifnex_api_url', 'http://localhost:8000/api/v1');
|
|
$url = rtrim($api_url, '/') . "/customer/orders/{$order_id}/commitment-forms";
|
|
|
|
$token = get_user_meta($user_id, 'ifnex_api_token', true);
|
|
if (!$token) wp_send_json_error('توکن احراز هویت یافت نشد.');
|
|
|
|
$response = wp_remote_get($url, array(
|
|
'headers' => array(
|
|
'Authorization' => 'Bearer ' . $token,
|
|
),
|
|
'timeout' => 30,
|
|
));
|
|
|
|
if (is_wp_error($response)) wp_send_json_error('خطا در ارتباط با سرور.');
|
|
|
|
$body = json_decode(wp_remote_retrieve_body($response), true);
|
|
if (!$body || !isset($body['success'])) wp_send_json_error('خطا در دریافت اطلاعات.');
|
|
|
|
wp_send_json_success($body['data']);
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════════
|
|
// AJAX Handler برای آپلود فرم تعهدنامه امضاشده
|
|
// ══════════════════════════════════════════════════════════════
|
|
|
|
add_action('wp_ajax_ifnex_upload_commitment_form', 'ifnex_upload_commitment_form_ajax');
|
|
|
|
function ifnex_upload_commitment_form_ajax() {
|
|
check_ajax_referer('ifnex_ajax_nonce', 'nonce');
|
|
if (!is_user_logged_in()) {
|
|
wp_send_json_error('باید وارد شوید.');
|
|
}
|
|
|
|
$order_id = intval($_POST['order_id'] ?? 0);
|
|
$form_id = intval($_POST['form_id'] ?? 0);
|
|
|
|
if (!$order_id) wp_send_json_error('شناسه سفارش نامعتبر است.');
|
|
if (!$form_id) wp_send_json_error('شناسه فرم نامعتبر است.');
|
|
if (!isset($_FILES['file'])) wp_send_json_error('فایل ارسال نشده است.');
|
|
|
|
$bridge = new IFNEX_User_Bridge();
|
|
$user_id = get_current_user_id();
|
|
|
|
$order = $bridge->get_customer_order($user_id, $order_id);
|
|
if (is_wp_error($order)) wp_send_json_error($order->get_error_message());
|
|
|
|
$file = $_FILES['file'];
|
|
$allowed_types = array('application/pdf', 'image/jpeg', 'image/jpg', 'image/png');
|
|
$max_size = 5 * 1024 * 1024; // 5MB
|
|
|
|
if (!in_array($file['type'], $allowed_types)) wp_send_json_error('فرمت فایل مجاز نیست. فقط PDF, JPG, PNG.');
|
|
if ($file['size'] > $max_size) wp_send_json_error('حجم فایل نباید بیشتر از 5MB باشد.');
|
|
|
|
// آپلود فایل به وردپرس
|
|
require_once(ABSPATH . 'wp-admin/includes/file.php');
|
|
require_once(ABSPATH . 'wp-admin/includes/media.php');
|
|
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
|
|
|
$upload = wp_handle_upload($file, array('test_form' => false));
|
|
if (isset($upload['error'])) wp_send_json_error('خطا در آپلود: ' . $upload['error']);
|
|
|
|
$file_path = str_replace(wp_get_upload_dir()['basedir'] . '/', '', $upload['file']);
|
|
$file_url = $upload['url'];
|
|
|
|
// ارسال به API لاراول
|
|
$api_url = get_option('ifnex_api_url', 'http://localhost:8000/api/v1');
|
|
$url = rtrim($api_url, '/') . "/customer/orders/{$order_id}/commitment-forms/{$form_id}/upload";
|
|
|
|
$token = get_user_meta($user_id, 'ifnex_api_token', true);
|
|
if (!$token) wp_send_json_error('توکن احراز هویت یافت نشد.');
|
|
|
|
$multipart = new CURLFile($upload['file'], $file['type'], $file['name']);
|
|
$post_fields = array(
|
|
'file' => $multipart,
|
|
'notes' => sanitize_textarea_field($_POST['notes'] ?? ''),
|
|
);
|
|
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
curl_setopt($ch, CURLOPT_POST, 1);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
|
'Authorization: Bearer ' . $token,
|
|
));
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
|
$response = curl_exec($ch);
|
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($http_code !== 200 && $http_code !== 201) wp_send_json_error('خطا در ارسال فایل به سرور.');
|
|
|
|
$result = json_decode($response, true);
|
|
if (!$result || !isset($result['success'])) wp_send_json_error('خطا در پردازش پاسخ سرور.');
|
|
|
|
wp_send_json_success($result['data']);
|
|
} |