Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Re: Remove all images for a product. GraphQL

Remove all images for a product. GraphQL

mattayres
Shopify Partner
11 0 8

Hi guys .. I cannot see a way to do this but is it possible to run a GraphQL mutation to delete ALL images for a product?

I need to regularly do a refresh for a product.

The way it stands, it seems I will have to do a request to get the existing product image ID's then perform a mutation to delete the image ID's that have been acquired.

Is there a better way?

Replies 4 (4)

Matthias7
Excursionist
30 3 3

Hey Mattayres, 

 

great question, did you find an answer to it? 🙂 

 

Cheers,

 

Matthias

shopYFY_guy
Shopify Partner
1 0 1

I found this process super cumbersome too, they should add a delete all media mutation. Here is my laravel class that has all 3 graphQL queries (query for IDs/delete/re-add) for your reference:

https://gist.github.com/wasalwayshere/903def4d3b711f916ad5e49beaa67685

farid-movsumov
Shopify Partner
109 6 34
farid-movsumov
Shopify Partner
109 6 34

I actually realized the productDeleteImages method is deprecated, and I should use productDeleteMedia instead.

 

This is what my new code looks like

 

public function deleteAllImages(User $shop, string $productId)
{
$mediaIds = $this->getMediaIds($shop, $productId);

if (empty($mediaIds)) {
return [];
}

// Split the mediaIds array into chunks of 200 items each
$mediaIdsChunks = array_chunk($mediaIds, 200);

foreach ($mediaIdsChunks as $mediaIdsChunk) {
$mutation = <<<GQL
mutation productDeleteMedia(\$productId: ID!, \$mediaIds: [ID!]!) {
productDeleteMedia(productId: \$productId, mediaIds: \$mediaIds) {
deletedProductImageIds
}
}
GQL;

$variables = [
'productId' => $productId,
'mediaIds' => $mediaIdsChunk,
];

try {
$result = $shop->api()->graph($mutation, $variables);
} catch (\Throwable $throwable) {
//Try again
Log::error('Error deleting images. Reason:' . $throwable->getMessage());
report($throwable);
$result = $shop->api()->graph($mutation, $variables);
}

if (!empty($result['errors'])) {
$errorMessage = 'Error deleting images. Reason:' . json_encode($result['errors']);
Log::error($errorMessage);
$exception = new \Exception($errorMessage);
report($exception);
throw $exception;
}

$this->graphqlRateLimitHandler->handleRateLimit($result);
}

return [];
}

public function getMediaIds(User $shop, string $productId)
{
$imageIds = [];
$cursor = 'null';
$hasNextPage = false;

do {
$query = <<<GQL
{
product(id: "{$productId}") {
media(first: 250, after: {$cursor}) {
pageInfo {
hasNextPage
}
edges {
cursor
node {
... on MediaImage {
id
}
}
}
}
}
}
GQL;

$result = $shop->api()->graph($query);

if (!empty($result['errors'])) {
$errorMessage = 'Error getting media ids. Reason:' . json_encode($result['errors']);
Log::error($errorMessage);
$exception = new \Exception($errorMessage);
report($exception);
throw $exception;
}

$this->graphqlRateLimitHandler->handleRateLimit($result);

if ($result['status'] === 429) {
continue;
}

$edges = $result['body']['data']['product']['media']['edges'];

$edges = $edges->toArray();

$imageIds = array_merge($imageIds, array_map(function ($edge) {
if (empty($edge['node']['id'])) {
return null;
}
return $edge['node']['id'];
}, $edges));

if (!empty($edges)) {
$lastEdge = end($edges);
if (isset($lastEdge['cursor'])) {
$cursor = '"' . $lastEdge['cursor'] . '"';
}
}

$hasNextPage = $result['body']['data']['product']['media']['pageInfo']['hasNextPage'];

} while ($hasNextPage);

if (empty($imageIds)) {
return [];
}

$imageIds = array_filter($imageIds);
$imageIds = array_values($imageIds);

return $imageIds;
}