Franz
Franz

Reputation: 675

Is this the correct way to create and post a mutipart form data in CakePhp3?

I am trying to post a mutipart form data in CakePhp3. The form should contain a few information about the user (text fields) and an image.

I'm doing something like this:

$request = [
  'fistname'=>$user->firstname,
  'lastname'=>'$user->lastname',
  '_session'=>'$session'
];

$form = new FormData();
foreach ($request as $key => $value) {
  $form->add($key,$request);
}
$file = $form->addFile('upload',fopen(WWW_ROOT.'img/picture.png','r'));
$file->contentId('mypicture'); // <-- not sure what this is
$file->disposition('attachment');

$response = $http->post(
  $url,
  (string)$form,
  ['headers' => ['Content-Type' => $form->contentType()]]
);

Is this the correct way to create and post a mutipart form data in CakePhp3?

Thanks for your help.

EDIT

If I post to my own server it seems to be working (thanks @Mary), but I get firstname and lastname replicated (this might be the problem):

object(Cake\Http\ServerRequest) {
trustProxy => false
...
[protected] data => [
    'fistname' => [
        'fistname' => 'Test',
        'lastname' => 'Test'
    ],
    'lastname' => [
        'fistname' => 'Test',
        'lastname' => 'Test'
    ],
    'upload' => [
        'tmp_name' => '/private/var/folders/g5/jjd1vc557bs21hq805lcxjk80000gn/T/phpAVXNqK',
        'error' => (int) 0,
        'name' => 'SELL5BAE2B6348272_gallery_1.png',
        'type' => 'image/png',
        'size' => (int) 200231
    ]
]
...

If I post to the API server it doesn't work. I did the same with CURL and it works:

$filename = WWW_ROOT.'ufiles/medium/'.$img['image_1'];
$cFile = curl_file_create($filename);
$request = [
  '_operation'=>'uploadFile',
  'id'=>$ticket_id,
  '_session'=>$session,
  'file' => $cFile
];

try{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  curl_setopt($ch, CURLOPT_URL,$this->crm['endpoint']);
  curl_setopt($ch, CURLOPT_POST,1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
  $response=curl_exec($ch);
  curl_close ($ch);
}catch(\Exception $e){
  $response = null;
}

Upvotes: 0

Views: 440

Answers (1)

Marijan
Marijan

Reputation: 1865

Counterquestion: Does it work?

As you can see here, $file->contentId() sets the Content ID or part in a multipart form data request body:
https://github.com/cakephp/cakephp/blob/master/src/Http/Client/FormDataPart.php#L114

I’m not sure about this, but I don’t think you have to set it as it doesn’t seem to be required for multipart/form-data:
https://www.w3.org/TR/2006/REC-xforms-20060314/slice11.html#serialize-form-data


Edit
I did some testing and: It. works. Here is what I tried:

use Cake\Http\Client;
use Cake\Http\Client\FormData;

public function test() {

    $request = [
        'fistname'=>'Test',
        'lastname'=>'Test'
    ];

    $form = new FormData();
    $http = new Client();

    foreach ($request as $key => $value) {
        $form->add($key,$request);
    }
    $file = $form->addFile('upload',fopen(WWW_ROOT.'img/awards.png','r'));
    $file->contentId('mypicture'); // <-- not sure what this is
    $file->disposition('attachment');

    $response = $http->post(
      'http://www.testurl.dev/test',
      (string)$form,
      ['headers' => ['Content-Type' => $form->contentType()]]
    );
    var_dump($response);
    exit;
}

Output of var_dump($response):

object(Cake\Http\Client\Response)#150 (12) {
  ["code":protected]=>int(200)
  …
  ["headers":protected]=>array(12) {
    ["Date"]=>array(1) {
      [0]=>string(29) "Fri, 28 Sep 2018 12:44:31 GMT"
    }
    …
  }
}

Server access log output:

[28/Sep/2018:14:44:31 +0200] "POST /test HTTP/1.1" 200 6852 "-" "CakePHP"

Upvotes: 1

Related Questions