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; } $user = get_userdata($user_id); if (!$user) { return false; } $token = $this->request_token($user->user_email, $this->generate_temp_password($user_id)); 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; } /** * درخواست توکن از لاراول */ private function request_token($email, $password) { //$url = $this->api_url . '/sanctum/token'; $url = $this->api_url . '/auth/login'; $args = array( 'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', ), 'body' => json_encode(array( 'email' => $email, 'password' => $password, 'token_name' => 'wordpress-bridge-' . get_current_blog_id(), )), 'timeout' => 30, ); $response = wp_remote_post($url, $args); if (is_wp_error($response)) { return false; } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (isset($data['token'])) { return $data['token']; } return false; } /** * تولید رمز عبور موقت برای کاربر وردپرس */ private function generate_temp_password($user_id) { $temp_pass = get_user_meta($user_id, 'ifnex_temp_password', true); if (!$temp_pass) { $temp_pass = wp_generate_password(32, true, true); update_user_meta($user_id, 'ifnex_temp_password', $temp_pass); } return $temp_pass; } /** * ارسال درخواست احراز هویت به 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; $args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $token, 'Accept' => 'application/json', 'Content-Type' => 'application/json', ), 'timeout' => 30, ); if ($method === 'POST' && !empty($data)) { $args['body'] = json_encode($data); $args['method'] = 'POST'; } else { $args['method'] = 'GET'; if (!empty($data)) { $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); $data = json_decode($body, true); if ($response['response']['code'] === 401) { $this->invalidate_token(get_current_user_id()); return new WP_Error('token_expired', 'توکن منقضی شده است. لطفاً دوباره وارد شوید.'); } 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) { $result = $this->authenticated_request($user_id, '/customer/countries'); if (is_wp_error($result)) { return $result; } return $result['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; } } // ══════════════════════════════════════════════════════════════ // 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; $has_order_shortcodes = has_shortcode($post->post_content, 'ifnex_orders_list') || has_shortcode($post->post_content, 'ifnex_order_form') || has_shortcode($post->post_content, 'ifnex_user_profile'); if ($has_order_shortcodes) { // ✅ اصلاح: dirname(__FILE__) یک سطح بالاتر می‌رود $plugin_url = plugin_dir_url(dirname(__FILE__)); // Load CSS wp_enqueue_style( 'ifnex-orders-css', $plugin_url . 'assets/css/ifnex-orders.css', array(), '1.2.0' //版本号 changed برای شکستن cache ); // Load jQuery & JS wp_enqueue_script('jquery'); wp_enqueue_script( 'ifnex-order-form-js', $plugin_url . 'assets/js/ifnex-order-form.js', array('jquery'), '1.2.0', //版本号 changed 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-orders/'), )); } }