New Files API can't write files?

lekhang25122
Visitor
2 0 0

I use Graphql API: stagedUploadsCreate, then I send request to Url: https://shopify.s3.amazonaws.com.
But response Location url: Access Denied
I then send a request to the Graphql API: fileCreate and the image is not uploaded successfully.
When I submit a public image url from google I don't get the returned image url in: files -> preview -> image -> originalSrc.

Here is my PHP code:

 

 

 

use PHPShopify\ShopifySDK;
        $file = $_FILES['upload'];
        $filename = $file['name'];
        $mimeType = $file['type'];
        $filesize = (string) $file['size'];
        $query = '
        mutation stagedUploadsCreate($input: [StagedUploadInput!]!) {
            stagedUploadsCreate(input: $input) {
                stagedTargets {
                    url
                    resourceUrl
                    parameters {
                        name
                        value
                    }
                }
                userErrors {
                    field
                    message
                }
            }
        }
        ';
        $variables = [
            'input' => [
                'fileSize' => $filesize,
                'filename' => $filename,
                'httpMethod' => 'POST',
                'mimeType' => $mimeType,
                'resource' => 'FILE'
                ]
        ];

        $config = [
            'ShopUrl' => 'onepiece-test.myshopify.com',
            'AccessToken' => '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',
        ];
        $shopify = ShopifySDK::config($config);

        $response = $shopify->GraphQL->post($query, null, null, $variables);

        $client = new \GuzzleHttp\Client();
        $url = $response['data']['stagedUploadsCreate']['stagedTargets'][0]['url'];
        $resourceUrl = $response['data']['stagedUploadsCreate']['stagedTargets'][0]['resourceUrl'];
        $parameters = $response['data']['stagedUploadsCreate']['stagedTargets'][0]['parameters'];

        $formData = [];
        foreach ($parameters as $parameter) {
            $formData[] = [
                'name' => $parameter['name'],
                'contents' => $parameter['value']
            ];
        }

        $formData[] = [
            'name' => 'file',
            'contents' => $file['tmp_name']
        ];

        try {
            $response = $client->request('POST', $url, [
                'headers' => [
                    'Accept'     => 'application/json',
                ],
                'multipart' => $formData
            ]);

            $xml = simplexml_load_string($response->getBody()->getContents());
            $convertJson = json_encode($xml);
            $convertArray = json_decode($convertJson, true);
            $imageUrl = urldecode($convertArray['Location']);
            // $imageUrl = $url . '/' . $imageKey['value'];
            // $imageUrl = 'https://www.industrialempathy.com/img/remote/ZiClJf-1920w.jpg';
            // dd($imageUrl);
            $query = '
            mutation fileCreate($files: [FileCreateInput!]!) {
                fileCreate(files: $files) {
                    files {
                        alt
                        createdAt
                        fileErrors {
                            code
                            details
                            message
                        }
                        fileStatus
                        preview {
                            image {
                                altText
                                height
                                id
                                originalSrc
                                transformedSrc
                                width
                            }
                            status
                        }
                    }
                    userErrors {
                        code
                        field
                        message
                    }
                }
            }
            ';
            $variables = [
                'files' => [
                    [
                        'originalSource' => $resourceUrl,
                    ]
                ]
            ];
            $response = $shopify->GraphQL->post($query, null, null, $variables);
            dd($response);


        } catch (RequestException $e) {
            throw $e;
        }
          

 

Copy

 

  Can you help me. Thanks

Replies 2 (2)

awwdam
Shopify Staff
249 42 36

Hey @lekhang25122,

I took a closer look here at your questions, code and worked through a bit of testing.

While I am not a PHP developer, this does seem to be the correct approach. Have you tried logging out the GuzzleHttp request data to confirm that this multipart/form data is formatted properly, and that all the 'parameters' returned from the stagedUploadCreate mutation are being passed? For file uploads, I did a quick example cURL request that was worked as expected. From there I used this to staged upload process with a .json file  and utilized the corresponding "resourceURL" when completing the fileCreate mutation. Here is that request:

curl -v -X "POST" \
  -F "key= {VALUE}" \
  -F "content-type=text/json" \
  -F "success_action_status=201" \
  -F "acl=private" \
  -F "policy={VALUE}" \
  -F "x-amz-credential={VALUE}" \
  -F "x-amz-algorithm={VALUE}" \
  -F "x-amz-date={VALUE}" \
  -F "x-amz-signature={VALUE}" \
  -F "file=~{FILE}" \
"https://shopify.s3.amazonaws.com/"


Does your logging match this request structure?

- Cheers 

awwdam | API Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

anitaernszt
Visitor
2 0 0

S3 expects the content type in the header. Try adding the following:

"Content-Type" => $mimeType 

 

"POST" should also be replaced with HTTP method "PUT"

You can find some examples for other languages here on the AWS docs:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html