Solved

How can I add an image when creating a product in my app?

iuzairaziz
Shopify Partner
7 0 2

Hi!
I am creating a shopify app and in my controller I have created a function to create product and it's working fine but I wanna send an image aswell when the product is created, I have tried multiple things but nothing is working. 
I am attaching my code below of where the product is being created kindly guide me on how I can attach image

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Routing\Controller as BaseController;
use Shopify\Clients\Graphql;
use App\Models\AppData;

/**
 * Controller to create Product and save product ID in database
 */
class ProductController extends BaseController
{
    private const CREATE_PRODUCTS_MUTATION = <<<'QUERY'
    mutation populateProduct($input: ProductInput!) {
        productCreate(input: $input) {
            product {
                id
            }
        }
    }
    QUERY;

    // 
     /**
     * Create Product when one click integration button is clicked 
     * @param Request $request
     */
    public function createProduct(Request $request)
    {
        
        $client = new Graphql($request->shop, $request->accessToken);

    $productTitle = "GiftCard";
    $variants = [
    [
        'price' => '0.00',
    ]
    ];
    
    $response = $client->query([
        "query" => self::CREATE_PRODUCTS_MUTATION,
        "variables" => [
            "input" => [
                "title" => $productTitle,
                "descriptionHtml" => "<p>This is an example product for gitfcard</p>",
                "variants" => $variants,
            ],
        ],
    ]);
    $responseContent = $response->getBody();
    $responseJson = json_decode($responseContent, true);

    if ($response->getStatusCode() == 200) {
        $productData = $responseJson['data']['productCreate']['product'];
        $productIdWithPrefix = $productData['id'];

        // Extract only the numeric part of the product ID
        $productId = substr($productIdWithPrefix, strrpos($productIdWithPrefix, '/') + 1);

        $saveResponse = $this->saveProductId($request, $productId);
        return response()->json(['success' => true, 'productId' => $productId], 200);
        // return response()->json(['success' => true], 200);
    } else {
        // The GraphQL query encountered errors
    
        $errors = $response->getErrors();
        // Handle the errors or log them
    
        // Return an error response
        return response()->json(['error' => 'Failed to create product', 'errors' => $response], 400);
    }
}

 // 
     /**
     * Save ProductID in our table against shop name when product is created
     * @param Request $request
     * @param $productId
     */
public function saveProductId(Request $request, $productId)
{
    $singleRow = AppData::where('store_url', $request->shop)->first();     //retireve the row which matches your shop url and apikey

    if ($singleRow) {
    // $singleRow->product_id = $request->product_id;
    $singleRow->product_id = $productId;
        $saved = $singleRow->save();
    return response()->json(['message' => 'Product Id saved successfully', 'value' => $singleRow], 201);
    } else {
    return response()->json(['message' => 'Failed to save Product ID'], 500);
    }
}
}
Accepted Solution (1)

Ole_
Shopify Partner
41 8 17

This is an accepted solution.

This is how your query has to look like:

 

    private const CREATE_PRODUCTS_MUTATION = <<<'QUERY'
    mutation populateProduct($input: ProductInput!, $media: [CreateMediaInput!]) {
        productCreate(input: $input, media: $media) {
            product {
                id
            }
        }
    }

 

 

And I am no php expert, but the query call should look something like this:

 

    $response = $client->query([
        "query" => self::CREATE_PRODUCTS_MUTATION,
        "variables" => [
            "input" => [
                "title" => $productTitle,
                "descriptionHtml" => "<p>This is an example product for gitfcard</p>",
                "variants" => $variants,
            ],
            "media" => [
                "mediaContentType": "IMAGE",
                "originalSource": "<YOUR_IMAGE_URL_HERE"
            ],
        ],
    ]);

 

Notice that "media" is on the same level as "input". In previous API versions you had "images" inside of "input". This changed with API version 2023-07.

mediaContentType and originalSource are required. Since you want to set an image, always set mediaContentType to "IMAGE"

If you find my suggestions helpful, kindly express your feedback by liking or marking them as a solution.

visionz.de

View solution in original post

Reply 1 (1)

Ole_
Shopify Partner
41 8 17

This is an accepted solution.

This is how your query has to look like:

 

    private const CREATE_PRODUCTS_MUTATION = <<<'QUERY'
    mutation populateProduct($input: ProductInput!, $media: [CreateMediaInput!]) {
        productCreate(input: $input, media: $media) {
            product {
                id
            }
        }
    }

 

 

And I am no php expert, but the query call should look something like this:

 

    $response = $client->query([
        "query" => self::CREATE_PRODUCTS_MUTATION,
        "variables" => [
            "input" => [
                "title" => $productTitle,
                "descriptionHtml" => "<p>This is an example product for gitfcard</p>",
                "variants" => $variants,
            ],
            "media" => [
                "mediaContentType": "IMAGE",
                "originalSource": "<YOUR_IMAGE_URL_HERE"
            ],
        ],
    ]);

 

Notice that "media" is on the same level as "input". In previous API versions you had "images" inside of "input". This changed with API version 2023-07.

mediaContentType and originalSource are required. Since you want to set an image, always set mediaContentType to "IMAGE"

If you find my suggestions helpful, kindly express your feedback by liking or marking them as a solution.

visionz.de