Produkt-Bilder über API hochladen?

Hallo,

ich konnte über die API (CURL+JSON) ein einfaches Produkt anlegen. 

Nun möchte ich gerne Produkte mit Bildern anlegen. Wie muss ich die Bilder im JSON angeben? Gibt es dazu eine Doku? Habe leider nix gefunden.

Wenn ich mir ein Produkt ausgeben lassen (z.B. über http://develop.shopware6.de/api/v1/product?filter[product.productNumber]=X123) finde ich zwar die Bilder über den relationships > media link, aber ich weiß trotzdem nicht, wie ich neue Bilder hochladen und verknüpfen kann.

Vielen Dank im Voraus

 

Ich wäre auch sehr an ein paar “real-world” Beispielen interessiert, gerade was Produkt- und Kategoriedaten angeht.
In der alten API Doku gab es so viele Beispiele - das wäre (gerade für den Start!) von Shopware 6 extrem sinnvoll.

Du kannst Dir über die Entwickler-Konsole im Browser die API-Befehle anzeigen lassen. Das hat mir bei der Produkt-Kategorie-Verknüpfung weitergeholfen:

https://forum.shopware.com/discussion/61998/api-produkt-mit-kategorie-verknuepfen

Beim Bilder hochladen bin ich gerade noch am Frickeln. Das geht wohl über http://develop.shopware6.de/api/v1/_action/media/0ab9f58488854…/upload?extension=jpg&fileName=demo

Bekomme im Moment beim Upload den Fehler “CONTENT__MEDIA_NOT_FOUND”. Ich vermute, dass meine Bild-Daten im falschen Format vorliegen. Habs schon mit base64 versucht, aber das funktioniert auch nicht.

Grüße

Hallo,

da ich auch gerade am Bilder-Upload hänge, möchte ich das Thema noch mal aufwärmen. Nach dem Studium der Entwickler-Konsole bin ich zu der Erkenntnis gekommen, das man für den Bild-Upload ZWEI POSTs benötigt.

Den ersten POST schicke ich unter Angabe der gewünschten mediaFolderId an media?_response=true

array(‚mediaFolderId‘ => ‚cef84bd4991c4055a7b02388dc49ca70‘);

Als Rückgabewert erhalte ich die ID des neuen Bildes. Im Backend ist jetzt ein „weißes bzw. leeres Bild“ als Platzhalter zu sehen:

 

Den zweiten POST sende ich nun unter Angabe der neuen ID an media/ID/upload?extension=jpg&fileName=bildname. Der Inhalt des POST ist der Pfad zum Bild:

array(‚url‘ => 'Pfad zum Bild - Webadresse**’);**

Theoretisch sollte das funktionieren, jedoch erhalte ich in der Praxis leider eine Fehlermeldung:

Resource at path „media.upload“ is not an existing relation. ;-(

 

Eine Sache verstehe ich nicht:

In der Netzwerkkonsole wird beim ERSTEN POST zusätzlich zur mediaFolderID auch die ID des Bildes übertragen - welches ja noch gar nicht existiert:

{„mediaFolderId“:„cef84bd4991c4055a7b02388dc49ca70“,„id“:„23def9d0efcf4c91a94b062dec4f1e12“}

Wie kann das sein? Bzw. wie kann man so eine ID (per PHP) generieren? Evtl. ist das der Grund meiner Fehlermeldung?

Über ein Feedback würde ich mich sehr freuen!

 

 

Problem gelöst - der Pfad meines zweiten POSTs war falsch!!!

Falls jemand über diesen Thread stolpert, nochmals kurz die Erklärung, wie es mit dem Bildupload funktioniert:

POST an media?_response=true
Request Payload: die mediaFolderId, in der ich das Bild speichern möchte:

{„mediaFolderId“:„cef84bd4991c4055a7b02388dc49ca70“ }

Als Response erhält man dann die neu erzeugte media-ID

 

Unter Angabe der neuen media-ID ein zweiter POST an _ action/media/media-ID/upload?extension=jpg&fileName=bildname
Request Payload: die URL des Bildes:

{„url“:„Webpfad zum Bild/bildname.jpg“}

FERTIG!

 

4 Likes

Moin,

das Bild hochladen bekomme ich hin - nur will sich das Bild nicht dem Produkt unterordnen :D. Habt ihr hier eine Starthilfe für mich?

 Produkt Patchen und Attribut `media` bearbeiten. foreach ($product['images'] as $imageKey =\> $image) { $swMediaId = addMedia($image); $data['media'][] = ['mediaId' =\> $swMediaId, 'position' =\> $imageKey]; }

Um das Cover Bild zu ändern ähnliches Verfahren, hier Attribut coverId bearbeiten

 // Add Cover [PATCH] $sProductMedia = swApiCall('product/' . $swProductId . '/media'); if (isset($sProductMedia['data'][0]['id'])) { swApiCall('product/' . $swProductId, 'PATCH', ['coverId' =\> $sProductMedia['data'][0]['id'] ]); }

 

1 Like

Danke, dass Du mir antwortest :slight_smile:

Mein JSON sieht bspw. wie folgt aus:

{
    "coverId": "91786f1990b54701ae85adbe6bb83d1d",
    "media":[
        {
            "mediaId":"91786f1990b54701ae85adbe6bb83d1d",
            "position":0
        }
    ]
}

Das schieße ich mit folgendem Request ab (gerade über Postman):

PATCH shop/api/v1/product/1c3edd69508c4f74992fb6a3a7f95755

Interessanterweise bekomme ich bei Postman einfach einen Statuscode 200 zurück und als Body das gesamte Produkt. Nutze ich meine Schnittstelle, ist es ein 204er Code und eine “leere” Response - so wie ich es erwarte. Aber weder über Postman noch “meine” Schnittstelle wird das Bild geupdated :-/. Bin ich blind und übersehe etwas?

ja, ich vermute mal, dass die coverId != mediaId ist, dort kommt die id aus der Relationstabelle “Produkt->Media” rein. Deshalb musst du nach dem Zuweisen der Medien auch nochmal product/{id}/media abrufen :wink:

1 Like

Danke! Manchmal sieht man den Baum vor lauter Wald nicht :).

@Moorleiche‍ Das würde ja bedeuten das ich (angenommen mein Produkt hat 1 Bild), mindestens 4 Requests brauche:

  1. POST auf  /media um das Bild anzulegen

  2. POST auf /product mit der erzeugten mediaId um das Produkt mit der Bildzuweisung anzulegen

  3. GET auf /product/{id}/media 

  4. PATCH auf /product mit der abgefragten “mediaId”

Hi Sebastian,

du kannst auch sofort beim Anlegen des Produktes anstatt nur die MediaId auch die Id der Product-Media-Relation angeben. So machen wir das zum Beispiel auch bei der Migration. So ähnlich sollte das dann beim Erstellen des Produktes aussehen:

{
   "id": "e2a534a99d0c4cd28a7338a6a5b58fa2",

   ......
   ......
   ......

   "media":[
      {
         "id":"4200faf9949f4adaad6afd76a5164c0f",
         "productId":"e2a534a99d0c4cd28a7338a6a5b58fa2",
         "position":1,
         "mediaId": "a6fcfcb093bc41aea3de334aa6273c24"
      }
   ],

   "cover":{
      "id":"4200faf9949f4adaad6afd76a5164c0f",
      "productId":"e2a534a99d0c4cd28a7338a6a5b58fa2",
      "position":1,
      "media": "a6fcfcb093bc41aea3de334aa6273c24"
   }
}

 

2 Likes

Hallo, interessanter Post… 

Eine Frage habe ich dazu: 

Woher bekomme ich die mediaFolderId ?

Das finde ich nirgends. 

Beste Grüße

Holger 

Die kannst du dir via API holen , müsste GET /api/v1/media-folder 

1 Like

@VaniKa schrieb:

Mir fällt auf, dass bei den Beispielen (auch woanders) häufig bereits beim Erstellen eines Objekts (z.B. Produkt) eine ID angegeben wird. Dabei entsteht die doch eigentlich erst beim Anlegen. Oder kann man einfach eine angeben und die wird dann übernommen? Kann das dann nicht zu Konflikten führen, falls eine ID bereits existiert?

Hallo, ich habe auch bei einigen api importen von Daten eine eigene uuid erzeugt.

 Str::uuid()-\>getHex()

Was passiert wenn es diese schon gibt weiß ich nicht, denke dann wird eine Exception kommen. (Str Illuminate)

 

@VaniKa schrieb:

Mir fällt auf, dass bei den Beispielen (auch woanders) häufig bereits beim Erstellen eines Objekts (z.B. Produkt) eine ID angegeben wird. Dabei entsteht die doch eigentlich erst beim Anlegen. Oder kann man einfach eine angeben und die wird dann übernommen? Kann das dann nicht zu Konflikten führen, falls eine ID bereits existiert?

Das ist rein Optional, die IDs müssten nur 32 Stellig und Hexadezimal sein und es dürfen keine Duplikate sein. Rein theorietisch könnte man einfach immer einen MD5 Hash aus einer Numerischen ID oder einer beliebigen ID (z.B. Artikel Nr) erzeugen.

Wenn man keine IDs vorgibt sollte man sich die von Shopware erzeugten IDs zumindest zwischenspeichern und ein Mapping erzeugen, also eine Merkliste von Quell ID und Shopware ID.

 

 

Hallo,

ich arbeite momentan an einer lokalen Artikelverwaltung, von wo aus die fertigen Daten in den Online-Shop hochgeladen werden. Es gestaltet sich ziemlich schwierig ohne die ganzen Hintergrundinfos. Über die Entwicklerkonsole des Browsers kann man zwar einige Infos einholen, aber das ist ja auch nur ein “Behelf”. Schön wäre es, wenn es irgendwo eine genaue Beschreibung der Datenbank geben würde. Mittlerweile ist der Upload von Produkten und Bildern möglich. Jetzt möchte ich sowohl Produkt- als auch Bilddaten wieder runterladen, um dann die UUID’s in meiner Datenbank einzutragen. Letzten Endes will ich die Bilder dann den Produkten zuordnen und diese Zuordnung in den Shop übertragen. Beim Runterladen der Bilddaten hänge ich im Moment. Die Folder-ID ist mir bekannt.

Ich wollte jetzt auch einen Bildupload via API machen. Habe aber das Problem, dass mir die API schon beim 1. Schritt, den Media-Entrag zu erzeugen einen Fehler zurückgibt.

Client error: `POST .../api/v1/media?_response=true` resulted in a `415 Unsupported Media Type` response:
{"errors":[{"code":"0","status":"415","title":"Unsupported Media Type","detail":"All provided media types are unsupporte (truncated...)

Kann in Shopware\Core\Content\Media\MediaType\MediaType und Shopware\Core\Content\Media\MediaType\ImageType und nicht wirklich erkennen, wie es richtig sein soll.

Die API will braucht zwingend einen MediaType. Hatte mir via API mal den MediaType eines bestehenden Bilder geholt aber das nimmt die API auch nicht.

...
            "userId": "243c6fba9e174a9e8a0e9c256e6a2149",
            "mediaFolderId": "e0eb5b025c7e473496c849955b784cae",
            "mimeType": "image/jpeg",
            "fileExtension": "jpg",
            "uploadedAt": "2020-04-23T10:47:46+00:00",
            "fileName": "Test-Bild6",
            "fileSize": 77224,
            "metaData": {
                "type": 2,
                "width": 1500,
                "height": 1500
            },
            "mediaType": {
                "name": "IMAGE",
                "flags": [],
                "extensions": []
            },
            "alt": null,
            "title": null,
...

Ich habe als MediaType verschiedene Varianten probiert aber nichts wird angenommen.

 'mediaType' =\> 'IMAGE',

 'mediaType' =\> ['name' =\> 'IMAGE', 'flags' =\> [], 'extensions' =\> [] ],

Die Doku sagt dazu natürlich wie immer nichts und scheinbar hat sich die API über die Monate noch etwas verändert.

Habs rausgefunden indem ich mir die Requests im Adminbereich genau angeschaut habe. Diese nutzen etwas andere API Calls. Allerdings erzeuge ich die UUID von mir aus und nicht vom SW.

Hallo,

ich hätte eine Frage ob jemand das Problem kennt bzw. weiss was ich falsch mache.

Soweit habe ich alles - und würde dann anhand der mediaId einen Post absetzen um das Bild hochzuladen.

Als Body gebe ich die url mit:

 https://www.matamoto.de/api/v1/\_action/media/30bc6bc7630043daab5bdc3f90dfd489/upload?extension=jpg&fileName=149289

 [0] =\> Array ( [url] =\> https://pfad-zum-bild.de/bild/149289.jpg )

Bekomme aber immer diese Fehlermeldung

 {"errors":[{"status":"500","code":"CONTENT\_\_MEDIA\_UPLOAD","title":"Internal Server Error","detail":"You must provide a valid url.","meta":{"parameters":{"message":"You must provide a valid url."}}}]}

Die Bildurl ist aber richtig…

Kann mir jemand einen Tipp geben?

Danke