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

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);
    }
}
}
1 Like

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" => "

This is an example product for gitfcard

",
                "variants" => $variants,
            ],
            "media" => [
                "mediaContentType": "IMAGE",
                "originalSource": "

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"
1 Like