0

Good afternoon all,

I am currently working with a custom frontend for Magento 2 that uses Graphql to grab product data:

Currently for the product image section we are getting back the following data attributes:

media_gallery {
   url
   position
   label
}

Is there a way that I can request any image roles that are associated with the images in the product gallery? The query would then be something like the following:

media_gallery {
   url
   position
   label
   role
}

I know this will require M2 backend module and any guidance on how to do this would be very welcome.

1 Answer 1

0

Here's a simplified outline of how you might go about this.

Step 1. Create a Custom Module You'll first need to create a custom module. In the app/code directory, create a new directory for your module, say VendorName/ModuleName. In this new directory, create the following files:

registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'VendorName_ModuleName',
    __DIR__
);

etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="VendorName_ModuleName" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

Step 2. Define a Schema Extension for GraphQL In your module directory, create a file etc/schema.graphqls:

type ProductImage {
    role: [String] @doc(description: "Role of the image") @resolver(class: "\\VendorName\\ModuleName\\Model\\Resolver\\MediaGalleryRole")
}

Step 3. Create a Resolver to Get the Media Roles for Image Under VendorName\ModuleName\Model\Resolver, create a new PHP class MediaGalleryRole.php:

<?php

declare(strict_types=1);

namespace VendorName\ModuleName\Model\Resolver;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

class MediaGalleryRole implements ResolverInterface
{
    public const IMAGE_ROLES = ['image', 'small_image', 'thumbnail'];

    private ProductRepositoryInterface $productRepository;

    public function __construct(ProductRepositoryInterface $productRepository)
    {
        $this->productRepository = $productRepository;
    }

    /**
     * @param Field $field
     * @param $context
     * @param ResolveInfo $info
     * @param array|null $value
     * @param array|null $args
     * @return array
     * @throws GraphQlNoSuchEntityException
     */
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        if (!isset($value['model']) || !isset($value['file'])) {
            return [];
        }
        $sku = $value['model']->getData('sku');

        return $this->getImageRoles($sku, $value['file']);
    }

    /**
     * @param string $sku
     * @param string $fileName
     * @return array
     * @throws GraphQlNoSuchEntityException
     */
    private function getImageRoles(string $sku, string $fileName): array
    {
        try {
            $product = $this->productRepository->get($sku);
        } catch (NoSuchEntityException) {
            throw new GraphQlNoSuchEntityException(__('No such product with sku %1', $sku));
        }

        $imageRoles = [];
        foreach (self::IMAGE_ROLES as $imageRole) {
            if ($product->getCustomAttribute($imageRole)?->getValue() === $fileName) {
                $imageRoles[] = $imageRole;
            }
        }

        return $imageRoles;
    }
}

rebuild (bin/magento setup:di:compile)

Example query:

query {
    products(search: "") {
        items {
            sku
            media_gallery {
                url
                label
                ... on ProductImage {
                    position
                    role
                }
            }
        }
    }
}

Result: enter image description here

2
  • In the MediaGalleryRole.php resolver file, change the IMAGE_ROLES constant if other image file roles are provided
    – byalexes
    Jul 28 at 5:52
  • This looks brilliant, plenty for me to work with. I will look at applying and will come back with an update
    – Baber
    Jul 28 at 12:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.