Прикрепить файл к задачи в OpenProject API v3

Нужно прикрепить файл к задаче проекта в OpenProject Api v3. Использую Laravel и Guzzle последней версии.

$openProjectIssue = json_decode($this->client->post('projects/' . $projectData[0] . '/work_packages', $data)->getBody()->getContents());

        foreach ($request->allFiles()['files'] as $file) {
            $data = [
                'headers' => [
                    'Content-Type' => 'multipart/form-data',
                    'Accept' => 'multipart/form-data',
                ],
                'body' => json_encode([
                    '_type' => 'Attachment',
                    'contentType' => $file->getMimeType(),
                    'fileName' => $file->getRealPath(),
                    'description' => [
                        'format' => 'plain',
                        'html' => '<p>' . $file->getClientOriginalName() . '</p>',
                        'raw' => $file->getClientOriginalName(),
                    ],
                    'filesize' => $file->getSize(),
                ])
            ];

            try {
                $openProjectIssue = json_decode($this->client->post('work_packages/' . $openProjectIssue->id . '/attachments', $data)->getBody()->getContents());
                dd($openProjectIssue);
            } catch (\Exception $exception) {
                dd(json_decode($exception->getResponse()->getBody()->getContents(), true));
            }
        }

Ссылка на документацию: https://www.openproject.org/docs/api/endpoints/attachments/

Хотя я пробовал и через collections как в примере по теме: https://stackoverflow.com/questions/51251894/how-to-get-an-attachments-data-with-the-openproject-api


Ответы (2 шт):

Автор решения: Sanya H

попробуйте взять функцию формирования мультипарт отсюда и использовать в Вашем коде. Если я не ошибся, то должно быть так:

<?php
$contentType = '';
foreach ($request->allFiles()['files'] as $file) {
  $body['metadata'] = json_encode([
                    '_type' => 'Attachment',
                    'contentType' => $file->getMimeType(),
                    'fileName' => $file->getClientOriginalName(),
                    'description' => [
                        'format' => 'plain',
                        'html' => '<p>' . $file->getClientOriginalName() . '</p>',
                        'raw' => $file->getClientOriginalName(),
                    ],
                    'filesize' => $file->getSize(),
                ]);
  $files['file'] = $file->getRealPath();
  $data['body'] = buildMultipartFormData($body, $files, $contentType);
  $data['headers'] => [
                'Content-Type' => $contentType,
            ];
  
  try {
    $openProjectIssue = json_decode($this->client->post('work_packages/' . $openProjectIssue->id . '/attachments', $data)->getBody()->getContents());
    dd($openProjectIssue);
  } catch (\Exception $exception) {
    dd(json_decode($exception->getResponse()->getBody()->getContents(), true));
  }
}

→ Ссылка
Автор решения: Sanya H

<?php

foreach ($request->allFiles()['files'] as $file) {  
  $data = [
    'multipart' => [
        [
            'name'     => 'metadata',
            'contents' => json_encode([
                '_type' => 'Attachment',
                'contentType' => $file->getMimeType(),
                'fileName' => $file->getClientOriginalName(),
                'description' => [
                    'format' => 'plain',
                    'html' => '<p>' . $file->getClientOriginalName() . '</p>',
                    'raw' => $file->getClientOriginalName(),
                ],
                'filesize' => $file->getSize(),
            ]);
        ],
        [
            'name'     => 'file',
            'contents' => \GuzzleHttp\Psr7\Utils::tryFopen($file->getRealPath(), 'r'),
            'filename' => $file->getClientOriginalName()
        ],
    ]
  ];
  
  try {
    $openProjectIssue = json_decode($this->client->post('work_packages/' . $openProjectIssue->id . '/attachments', $data)->getBody()->getContents());
    dd($openProjectIssue);
  } catch (\Exception $exception) {
    dd(json_decode($exception->getResponse()->getBody()->getContents(), true));
  }
}

→ Ссылка