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($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 resubmit_customer_order($user_id, $shipment_id, $order_data) { $result = $this->authenticated_request( $user_id, "/customer/orders/{$shipment_id}/resubmit", '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('سفارش لغو شد.'); } // AJAX Handler برای دریافت سفارش جهت اصلاح و ارسال مجدد add_action( 'wp_ajax_ifnex_get_resubmit_order', 'ifnex_get_resubmit_order_ajax' ); function ifnex_get_resubmit_order_ajax() { check_ajax_referer('ifnex_ajax_nonce', 'nonce'); if (!is_user_logged_in()) { wp_send_json_error('برای اصلاح سفارش باید وارد حساب خود شوید.'); } $order_id = absint($_POST['order_id'] ?? 0); if (!$order_id) { wp_send_json_error('شناسه سفارش نامعتبر است.'); } $user_id = get_current_user_id(); $bridge = new IFNEX_User_Bridge(); /* * سفارش از طریق endpoint احراز‌شده مشتری دریافت می‌شود. * بنابراین مالکیت سفارش نیز در Laravel بررسی می‌شود. */ $result = $bridge->get_customer_order( $user_id, $order_id ); if (is_wp_error($result)) { wp_send_json_error($result->get_error_message()); } if (empty($result['data']) || !is_array($result['data'])) { wp_send_json_error('اطلاعات سفارش یافت نشد.'); } $order = $result['data']; $review = $order['review'] ?? []; /* * فقط سفارشی که آخرین تصمیم آن changes_requested است * قابلیت اصلاح و ارسال مجدد دارد. */ if (($review['state'] ?? '') !== 'changes_requested') { wp_send_json_error( 'این سفارش در حال حاضر قابل اصلاح و ارسال مجدد نیست.' ); } if (empty($review['can_resubmit'])) { wp_send_json_error( 'امکان ارسال مجدد این سفارش فعال نیست.' ); } $order_id = $order['id'] ?? $order_id; wp_send_json_success([ 'id' => $order_id, 'direction' => $order['direction'] ?? '', 'type' => $order['type'] ?? '', 'from_country' => $order['from_country'] ?? null, 'to_country' => $order['to_country'] ?? null, 'sender' => $order['sender'] ?? null, 'receiver' => $order['receiver'] ?? null, 'packages' => $order['packages'] ?? [], 'items' => $order['items'] ?? [], 'review' => $review, ]); } // AJAX Handler برای ارسال مجدد سفارش add_action('wp_ajax_ifnex_resubmit_order', 'ifnex_resubmit_order_ajax'); function ifnex_resubmit_order_ajax() { check_ajax_referer('ifnex_ajax_nonce', 'nonce'); if (!is_user_logged_in()) { wp_send_json_error('برای ارسال مجدد سفارش باید وارد حساب خود شوید.'); } $order_id = absint($_POST['order_id'] ?? 0); if (!$order_id) { wp_send_json_error('شناسه سفارش نامعتبر است.'); } $data = $_POST['data'] ?? []; /* * بسته به نحوه ارسال jQuery ممکن است data * به صورت array یا JSON string دریافت شود. */ if (is_string($data)) { $decoded = json_decode(wp_unslash($data), true); if (json_last_error() !== JSON_ERROR_NONE) { wp_send_json_error('داده‌های سفارش نامعتبر هستند.'); } $data = $decoded; } if (!is_array($data) || empty($data)) { wp_send_json_error('داده‌های سفارش ارسال نشده است.'); } $bridge = new IFNEX_User_Bridge(); $result = $bridge->resubmit_customer_order( get_current_user_id(), $order_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 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']); }