thomasaull/RestApi

multipart/form-data request not supported?

Closed this issue · 5 comments

I can't seem to upload files using a POST. Is this supported in the module?

Yes. I upload files via API. POST Content-Type: multipart/form-data; boundary=X-INSOMNIA-BOUNDARY
But if you need to download large files then you need to set AllowAjax variable

    $ul = wire(new WireUpload($formName));
    $ul->setValidExtensions(['mp4', 'avi', '3gp']);
    $ul->setMaxFiles(1);
    $ul->setMaxFileSize(100 * 1000000); // 100 MB
    $ul->setOverwrite(true);
    $ul->setDestinationPath($p_path);
    $ul->setLowercase(true);
    $ul->setAllowAjax(true);
    $files = $ul->execute();

@andy-scboy Thanks for stepping in, very much appreciated! :)
@spoetnik Generally speaking the module does not limit what you can do, basically it's just a router to your own functions, so anything you can do in PHP or in ProcessWire should be possible with this module aswell.

Thanks for the help @andy-scboy but can you please help me a bit further?

Looking at some examples, the use the $data variable to access the POST data.

public static function login($data) {

My 'files'-field is not in the $data-array my function receives.

You mention in your code-example above '$formName', that's not part of the $data-array.

Can you please give me a code example of the function receiving the POST data?

Thanks in advance!!

As example add line in Routes.php

['POST', 'sp/{id:\d+}', Example::class, 'setPage', ["auth" => false]],

It give you POST request by address: Your_Domain/sp/page_id (as ex. localhost/sp/1821)

Next step edit Example.php and add function.
We will send different data:
id from routing (int);
field_digit (int);
field_name (string);
field_double (float);
photo (file).

  public static function setPage($data) {
// Sanitize your fields to use
// but we don’t have a file here. we will take it the other way.
    $data = RestApiHelper::checkAndSanitizeRequiredParameters($data, ['id|int'],['field_digit|int'],['field_name|string'],['field_double|float']);

// give a response
    $response = new \StdClass();
// get page by id
    $page = wire('pages')->get($data->id);
    if(!isset($page->id)) throw new \Exception('page not set');
// change fields in page
    $page->title = $data->field_name;
    $page->number = $data->field_digit;
    $page->temperature = $data->field_double;
    $p->save();

Now let's talk about the file

// Use a global variable
	if($_FILES){
// PHP load errors with code
        $f_error = $_FILES["up_photo"]["error"]; 
// request header
        $fheader = getallheaders();
        $f_size = $fheader["Content-Length"];
// name label by reguest
        $formlabel = 'up_photo';
// name of file by request
	$formName = array_key_first($_FILES);
	$TempDir = $_FILES[$formName]['tmp_name'];
// path where this file is usually located in PW
	$p_path = wire('config')->paths->assets . "files/". $page->id . "/";

// next file manipulating

	    $ul = wire(new WireUpload($formName));
	    $ul->setValidExtensions(['jpg', 'jpeg', 'png']);
	    $ul->setMaxFiles(1);
	    $ul->setMaxFileSize(100 * 1000000); // 100MB
	    $ul->setOverwrite(true);
	    $ul->setDestinationPath($p_path);
	    $ul->setExtractArchives(false);
	    $ul->setLowercase(true);
	    $ul->setAllowAjax(true);
	    $files = $ul->execute();
	    $err_array = $ul->getErrors();

// WireUpload errors
	    if($ul->getErrors()) throw new \Exception("ErrUp:".$err_array[0]);

	    if(count($files)) {
// take the first file
	        $file = $p_path . reset($files);
		    // do something with your file
		    $resp = $page->photo->add($file);
		    if($page->photo->$resp->filesize == 0 ) throw new \Exception('Photo not correctly upload');
	    	$page->save();

	     $response = $files[0];
            }

Sorry if I wrote with errors. I just wanted to state the principles.

Thanks a lot @andy-scboy !!! This helps me a lot! I would have never figured this out myself. Thanks, thanks, thanks!!!