Invision Community 4: SEO, prepare for v5 and dormant account notifications By Matt Monday at 02:04 PM
IPCommerceFan Posted March 13, 2019 Posted March 13, 2019 Hi, Is it just me, or does the POST functionality for /downloads/files not seem to work entirely? Looking at the source code of applications/downloads/api, there doesn't seem to be any reference to the object parameters of 'name', 'url', or 'size', which seem to not be functional at all. They are, however, listed in the API reference: Here's an example of what I'm trying to execute: //<?php //Purchase Data $member = $purchase->member->member_id; //REST API Community URL and KEY $communityUrl = 'xxx'; $apiKey = 'xxx'; //Create File in Downloads $endpoint = '/downloads/files'; $curl = curl_init( $communityUrl . 'api' . $endpoint ); $message = '<p>Testing</p>'; $file_url = '/home/useracct/public_html/test.txt'; $filename = 'test.txt'; $curl_post_data = array(); $curl_post_data['category'] = 1; $curl_post_data['author'] = $member; $curl_post_data['title'] = 'Test'; $curl_post_data['description'] = $message; $curl_post_data['hidden'] = -1; $curl_post_data['files'][$filename] = array(); $curl_post_data['files'][$filename]['name'] = $filename; $curl_post_data['files'][$filename]['url'] = $file_url; $curl_post_data['files'][$filename]['size'] = filesize($file_url); $curl_post_data = urldecode(http_build_query($curl_post_data)); curl_setopt_array( $curl, array( CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => "{$apiKey}:", CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $curl_post_data ) ); category, author, title, description, hidden, and 'files' => $filename work, however none of the items "below" that work. The result is a download page with a file that has the correct name (since it picked it up from $filename) available to download that is only 1 byte in size. Is the method of pulling in a file via url broken, or am I missing something in the syntax? Any help would be appreciated!
Daniel F Posted March 13, 2019 Posted March 13, 2019 Hello, that's the documentation for the response! Your POST file parameter should only be an array with the name and the file content Quote * @reqapiparam object files Files. Keys should be filename (e.g. 'file.txt') and values should be file content Untested but this should work: $curl_post_data['files'][$filename] = file_get_contents($file_url);
IPCommerceFan Posted March 13, 2019 Author Posted March 13, 2019 Ah! I should've looked more closely. Unfortunately I've tried the proposed method, but the file that is uploaded is still "empty" ... $curl_post_data['description'] = $message; $curl_post_data['hidden'] = -1; $curl_post_data['files'][$filename] = file_get_contents($file_url); ... (actual size is > 3MB) If I print_r($curl_post_data), I can see that the file's contents are in fact being retrieved though. They're just not being posted to the download file.
bfarber Posted March 14, 2019 Posted March 14, 2019 You might want to grab the file that was stored in Downloads (i.e. download it), change the extension to .txt and open it in a text editor to see what those 45 bytes are - my hunch is some sort of error message that will clue you in as to the issue. If you don't have allow_url_fopen for instance, this might be failing: file_get_contents($file_url);
IPCommerceFan Posted March 14, 2019 Author Posted March 14, 2019 Interesting idea! So, first of all: $curl_post_data['files'][$filename] = file_get_contents($file_url); ^ This IS the correct syntax, after all. I checked out the contents of the test file, then tried a few different file types, and found an interesting trend. It stops parsing the file any time it runs into an ampersand! Looking at these files in a hex editor, I found this: Uploaded file 1: Original file: Uploaded file 2: Original file: So, I suppose that means its imported as text instead of as binary, and the ampersand kills it? In any case, it seems this is the source of my problems. Should I open a ticket for this?
bfarber Posted March 15, 2019 Posted March 15, 2019 I think the problem is that you need to send the multipart/form-data header. Check this out for instructions: https://ec.haxx.se/http-multipart.html
IPCommerceFan Posted March 15, 2019 Author Posted March 15, 2019 Hmm, it would seem it is already being sent as multipart/form-data: ... $curl_post_data = array(); $curl_post_data['category'] = 1; $curl_post_data['author'] = $member; $curl_post_data['title'] = 'Test'; $curl_post_data['description'] = $message; $curl_post_data['hidden'] = -1; $curl_post_data['files'][$filename] = array(); $curl_post_data['files'][$filename] = file_get_contents($file_url); $curl_post_data = urldecode(http_build_query($curl_post_data)); ... curl_setopt_array( $curl, array( CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => "{$apiKey}:", CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $curl_post_data ) ); https://secure.php.net/curl_setopt
IPCommerceFan Posted April 15, 2019 Author Posted April 15, 2019 This works now! The missing link was that we needed to replace this: file_get_contents($file_url) with this: urlencode(file_get_contents($file_url)) As I understand it, urlencode makes it so that the ampersands are transmitted as '%26', and also converts any other characters that might've broken the URL. Here is the complete code for uploading a file from the local file system in conjunction with the Rules app: //<?php //Purchase Data $member = $purchase->member->member_id; //REST API URL and KEY $communityUrl = '...'; $apiKey = '...'; //Upload File from filesystem // REST Endpoint $endpoint = '/downloads/files'; $curl = curl_init( $communityUrl . 'api' . $endpoint ); // File Description $file_desc = '<p>File Description</p>'; // File name $filename = 'test.txt'; // Path to file $file_url = '/home/acct/public_html/' . $filename; // Download Page Settings $curl_post_data = array( 'category' => 1, 'author' => $member, 'title' => 'REST Downloads POST', 'description' => $file_desc, 'files' => array( $filename => urlencode(file_get_contents($file_url)) ), 'hidden' => 1, ); // Prepare data for cURL POST $curl_post_data = urldecode(http_build_query($curl_post_data)); // POST Data curl_setopt_array( $curl, array( CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => "{$apiKey}:", CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $curl_post_data ) ); // Get Response $response = curl_exec( $curl ); // Get file info array $download_file = json_decode($response); return "action complete";
Recommended Posts
Archived
This topic is now archived and is closed to further replies.