// βœ… NEW: Upload file to Asana and attach it to a task as a comment function afb_upload_file_to_asana($file, $task_gid, $project_id) { $url = "https://app.asana.com/api/1.0/attachments"; // Get API headers $headers = afb_get_asana_headers(); // Prepare the file for uploading (FormData) $file_data = new CURLFile($file['tmp_name'], $file['type'], $file['name']); // Prepare the POST data $post_data = [ 'file' => $file_data, 'task' => $task_gid, // Attach to the specific task 'project' => $project_id // Attach to the project (optional) ]; // Initialize cURL $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); // Execute the cURL request $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // Handle errors if the request failed if ($http_code !== 200 || !$response) { return false; } // Parse the response to get the attachment ID (for use in a comment) $data = json_decode($response, true); if (isset($data['data']['gid'])) { return $data['data']['gid']; // Return the attachment's ID } return false; } // βœ… NEW: Add a comment to the Asana task with the uploaded file function afb_add_file_comment_to_task($task_gid, $attachment_gid) { $url = "https://app.asana.com/api/1.0/tasks/{$task_gid}/stories"; $headers = afb_get_asana_headers(); // Prepare the comment text $comment_text = "πŸ“Ž Attached: " . $attachment_gid; // You can customize the comment message here // Prepare the POST data $post_data = [ 'text' => $comment_text ]; // Initialize cURL for adding the comment $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data)); // Execute the cURL request $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // Check for success if ($http_code !== 201 || !$response) { return false; } return true; } // βœ… Get API headers with auth token function afb_get_asana_headers() { $token = get_option('afb_asana_token'); return [ 'Authorization: Bearer ' . $token, 'Content-Type: application/json' ]; } // 🌐 Generic fetch wrapper function afb_fetch_asana($endpoint) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://app.asana.com/api/1.0/' . $endpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, afb_get_asana_headers()); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($http_code !== 200 || !$response) { return false; } $data = json_decode($response, true); return $data['data'] ?? null; } // βœ… Get all projects available to the authenticated user function afb_get_all_projects() { return afb_fetch_asana('projects'); } // πŸ” Fetch custom fields for a project function afb_get_project_fields($project_id) { return afb_fetch_asana("projects/{$project_id}/custom_field_settings"); } // πŸ” Fetch sections of a project function afb_get_project_sections($project_id) { return afb_fetch_asana("projects/{$project_id}/sections"); } // πŸ” Fetch available users (assignees) function afb_get_asana_users() { return afb_fetch_asana("users"); } // πŸ” Fetch a project’s details function afb_get_project($project_id) { return afb_fetch_asana("projects/{$project_id}"); } // βœ… Check if the Asana token is valid and return user + project info function afb_check_asana_connection() { $token = get_option('afb_asana_token'); $project_id = get_option('afb_default_project_id'); // Step 1: Get current user info $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://app.asana.com/api/1.0/users/me'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, afb_get_asana_headers()); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($http_code !== 200 || !$response) { return [ 'success' => false, 'message' => '❌ Unable to connect to Asana. Please check your API token.' ]; } $user_data = json_decode($response, true); $user = $user_data['data'] ?? null; // Step 2: Get default project name (if available) $project_info = null; if ($project_id) { $project_info = afb_get_project($project_id); } $project_name = $project_info['name'] ?? null; // Step 3: Build message $message = 'βœ… Connected to Asana as ' . esc_html($user['name']) . ' (' . esc_html($user['email']) . ')'; if ($project_name) { $message .= '
πŸ“ Default Project: ' . esc_html($project_name) . ''; } elseif ($project_id) { $message .= '
⚠️ Could not fetch project details for ID: ' . esc_html($project_id) . ''; } return [ 'success' => true, 'message' => $message, 'user' => $user, 'project' => $project_info ]; } XML-RPC server accepts POST requests only.