1

In Dreamfactory (v2.4.2), I'm posting (via multipart/form-data) to a service/_table/{tablename} to create a record in a table. Using PHP, I then use the ID of that record returned as a folder name for file storage. I'd like to have the service/_table/{tablename}.post_process script post using the platform.api.post method and pass it the binary data from the original request, but am having a difficult time determining how to pass that data without base64_encoding it.

How do you pass the multipart/form-data request from the original event request into an internal API call of another service? Thanks in advance for your help!

ShaunOle
  • 21
  • 4

1 Answers1

0

I have since found a solution. Please provide any tips or advice to improve, I'm fairly new, but have spent the last 2 days researching and troubleshooting this. I have the following set up:


ON THE CLIENT:

Post URL: /tableService/_table/tableName

Post Data: Form method: multipart/form-data -You have to provide each of your table fields as a form key:value pair -You have to provide the upload file with a key of "files" -You also need your authentication headers (X-DreamFactory-Session-Token & X-Dreamfactory-API-Key)


ON THE SERVER:

You'll need to set up a pre and post process script for the table.

...pre_process

tableService._table.tableName.post.pre_process

if(!isset($_FILES['files']) || !is_array($_FILES['files'])){
        // Stop execution and return a specific status code
        $event['response']['errorCode'] = 400;
        $event['response']['errorMessage'] = "File is missing. Check that the a file was provided and the field name is: [files], to continue.";
        return false;
    } else {
        $event['payload'] = $_POST;
        // use this next variable if your table has a field, "fileName" to store the file name. This should be changed to your needs
        $event['payload']['fileName'] = $_FILES['files']['name'];
        $event['payload'] = array("resource"=>array($event['payload']));
        $event['request']['payload'] = $event['payload'];
        $event['request']['content'] = json_encode($event['payload']);
        $event['request']['content_type'] = 'json';
    }

From here, the table should add the record, we'll handle uploading the file in the post_process script for the table.

...post_process

tableService._table.tableName.post.post_process

// we need to get the ID of the created record. Be sure to use the variable you want to use as your ID.
$recordId = $r['primaryKeyId'];

// For path, you can prepend an already existing directory if you need to like this.
$path = '/Documents/'.$recordId;

// The filename should be in the returned resource, assuming you store it. Otherwise, you can pull this from the $_FILES array, if you haven't changed it from the POST'd value. We should only have one file, so we'll use resource 0.
$filename = $event['payload']['resource'][0]['fileName'];

/**
 * Prepping file for upload via API Endpoint
 */

// This is the URL for your internal files API Endpoint
$url = 'fileService/'.$path;

// let's create the directory, we need to make sure there is a trailing slash
$post($url.'/');

// we need to read the file data into a string, so we'll use file_get_contents on the tmp file.
$fileData = file_get_contents($_FILES['files']['tmp_name']);

$post($url.'/'.$filename, $fileData);
ShaunOle
  • 21
  • 4