Search code examples
shopwareshopware6shopware6-api

How to get a persistent link to document in Shopware 6?


Is it possible to get a persistent static link to a document media object? If we update a document with new details and do "update and replace" via the admin interface the document still gets a new ID, therefore breaking any external links pointing to a Shopware document.

None of the SHOPWARE_CDN_STRATEGY_DEFAULT options help with this either as all links seem to have the ID (or some other unique value) prepending the filename.

Original document: example.com/12345/filename.pdf
Updated document: example.com/67890/filename.pdf


Solution

  • You're in fact not updating the file but creating a new document, also with it's own unique document number, which is the intended behavior.

    This is in the interest of most merchants and their customers, as it would be a serious risk if a customer would find that a previous invoice, that they had received previously, was altered afterwards. That's why the merchant is encouraged to create a new version of the document instead, so both parties still have access to previous versions.

    Just for the sake of completion: There is a way to replace the file of an existing document using the admin-api.

    There's an endpoint which allows you to upload a file to a document:

    POST /api/_action/document/{documentId}/upload?fileName=name_of_the_file&extension=pdf
    Content-Type: application/json
    {
      "url": "http://url.to/some_file.pdf"
    }
    

    You can alternatively also upload a file directly using an http client:

    const formData = new FormData();
    const file = new File([binaryData], 'test.pdf');
    formData.append('file', file, 'test.pdf');
    
    client.request({
        headers: {
            Authorization: `Bearer ${token}`,
            'Content-Type': 'multipart/form-data',
        },
        method: 'POST',
        url: `${baseUrl}/api/_action/document/${documentId}/upload?fileName=test&extension=pdf`,
        formData,
    });
    

    Here's the catch though. The endpoint will not allow you to upload a file for a document, if the document already has been assigned a file. In that case an exception DocumentGenerationException('Document already exists') will be thrown, for the reasons mentioned earlier. You can however circumvent that exception.

    Before you upload a new file, you'll have to request the endpoint to patch the document's database entry and unassign the previously assigned file:

    PATCH /api/document/{documentId}
    Content-Type: application/json
    {
      "documentMediaFileId": null
    }
    

    Afterwards you should be able to upload a new file to an existing document, keeping the deep link code and id the same.