PDF Media Upload über API

Hallo zusammen,

ich möchte ein PDF hochladen, erzeuge dazu erst eine mediaId. Die PDF-Daten habe ich in einem base64Encoded String. Ich schaffe es aber nicht, die Daten hochzuladen.

Ich erhalte immer das folgende Result:
{„errors“:[{„status“:„404“,„code“:„CONTENT__MEDIA_NOT_FOUND“,„title“:„Not Found“,„detail“:„Media for id 1e23680b921641a9bc3804dd12e07889 not found.“,„meta“:{„parameters“:{„mediaId“:„1e23680b921641a9bc3804dd12e07889“}}}]}

Call zu Shopware wäre der hier:
/api/_action/media/[myMediaID]/upload?extension=pdf&fileName=12345

Im Body soll dann sicher der base64Encoded String mitgegeben werden.

Fragen dazu:
Welche Header muss ich mitgeben ? Muss ich explizit einen Content-Type mitgeben und wenn ja, welchen ? Wie muss der Body mitgegeben werden ?

Hat jemand das schon mal gemacht und vielleicht ein Beispiel dazu für mich ?

Besten Dank und Grüße
Holger

Fast :slight_smile:

  1. Die Daten müssten NICHT als base64 sondern als octet-stream gesendet werden. Hängt dann vom Client wie man das macht.
curl ... --data-binary @/var/www/temp/zxy.pdf

(die Magie kommt hier von dem @-Zeichen !)

Andere Client machen das anders.

  1. Ich bin mir gerade nicht 100% sicher ob man PDF Dateien auch als media-file ablegen kann. Ich denke schon. Aber jeden Fall werden die Dateien kann nicht angezeigt. Ist aber alles ein anderes Problem.

kleiner Ausschnitt aus einem PHP Script was den den Upload macht:

$url  = $this->shopUrl . '/api/_action/media/' . $mediaId . '/upload?';
$url .= 'extension=' . $pi['extension'];
$url .= '&fileName=' . urlencode($pi['filename']);

$content_type = $storage->mimeType($asset->getRealFullPath()); 

// $tmpfname = tempnam("/tmp", "pic." . $pi['extension']);
$asset->getData();

$headers = array(
    "Content-Type: $content_type", // or whatever you want
    "Authorization: " . $this->getAuthHeader()
);

$filesize = $storage->fileSize($asset->getRealFullPath());
$stream = $asset->getStream();

$curl_opts = array(
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_PUT => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_INFILE => $stream,
    CURLOPT_VERBOSE => 0,
    CURLOPT_INFILESIZE => $filesize,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1
);

(Achtung das ist nicht komplett, da fehlt das finale CURL-exec und die Daten kommen hier aus einem PIM; $asset object, lässt sicher aber sicher auch in PHP abbilden.)

LG
Carsten

Hallo chamaw,

die Doku sagt dazu das hier, was ich aber nicht wirklich verstehe

curl --request POST \
  --url 'http://localhost/api/_action/media/0fa91ce3e96a4bc2be4bd9ce752c3425/upload?extension=jpg' \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "// binary file body": null
}'

Was übergebe ich denn als binary file body, einen Stream kann ich ja nicht schicken… und du sagtest NICHT als base64… ich bin ratlos, weil es bei mir mit allen möglichen Varianten und Clients nicht funktioniert. Letzter Versuch war mit Indy und TIdMultiPartFormDataStream… da gefällt dem Server die content-lenght nicht… PHP hilft mir nicht viel weiter.

Grüße
Holger

auf der CMD line dann einfach

curl ... --data-binary @/pfad/auf/dem/server/asdf.pdf

vorne das @ nicht vergessen, dann packt curl den Inhalt der Datei in den Body.
content-type ist dann „application/pdf“ und der Bearer Token müsste auch gesetzt werden …

Ich muss gestehen, ich habe keine Ahnung, was Du meinst.
CMD Line ? Ich habe eine Delphi Anwendung, mit der ich versuche, ein PDF hochzuladen.
Es kann doch nicht sein, dass ich der erste bin, der damit Probleme hat. Ich finde hier im Forum leider nichts dazu.

Tatsächlich gehört Delphi nicht zu meinem Portfolio. Hier aber ein CodeStück aus C#, vielleicht hilft das:

HttpClient httpClient = new HttpClient();

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/vnd.api+json"));

httpClient.DefaultRequestHeaders.Add("Authorization", this.AuthHeader);

byte[] rawBytes = File.ReadAllBytes(filepath);
if (rawBytes.Length == 0)
{
    throw new Exception("File is empty " + filepath);
}
ByteArrayContent byteArrayContent = new ByteArrayContent(rawBytes);
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("image/" + mediaUpload.Extension.ToLower());
byteArrayContent.Headers.ContentLength = rawBytes.LongLength;

string finalSendDataUrl = this._config.server.TrimEnd('/') + path;
HttpResponseMessage result = httpClient.PostAsync(finalSendDataUrl, byteArrayContent).Result;

Wichtig ist halt, dass das Image am Ende einfach „raw binary“ im Body landet.

Vielleicht hilft dir das:

Ich würd einfach das SDK benutzen.