0

In my schema.graphqls file I've created this Query

type Query {
    getLinkedProductsByGroups(groups: [String]): [LinkedProductsByGroup] @resolver(class: "Vendor\\ProductDisplay\\Model\\Resolver\\LinkedProductsByGroups")
}

type LinkedProductsByGroup {
    group: String
    products: [ProductInterface]
}

I've created my resolver

<?php
/*
 * Copyright (c) 2023. Vendor TECHNOLOGIES
 */

namespace Vendor\ProductDisplay\Model\Resolver;

use Vendor\ProductDisplay\Service\LinkedProductsLocator;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector;
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Deferred\Product as ProductDataProvider;
use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ProductSearch;
use Magento\Framework\Api\SearchCriteriaBuilderFactory;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\BatchResolverInterface;
use Magento\Framework\GraphQl\Query\Resolver\BatchResponse;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

class LinkedProductsByGroups implements ResolverInterface
{
    protected LinkedProductsLocator $linkedProductsLocator;
    protected ProductRepositoryInterface $productRepository;
    protected SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory;

    public function __construct(
        SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory,
        ProductRepositoryInterface   $productRepository,
        LinkedProductsLocator        $linkedProductsLocator
    )
    {
        $this->linkedProductsLocator = $linkedProductsLocator;
        $this->searchCriteriaBuilderFactory = $searchCriteriaBuilderFactory;
        $this->productRepository = $productRepository;
    }

    public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
    {

        $result = [];
        $groups = $args['groups'];
        foreach ($groups as $group) {
            $resultItem = [];
            $resultItem['group'] = $group;
            $resultItem['products'] = [];

            //fetch related products
            $linkedProductIds = $this->linkedProductsLocator->getLinkedProductIdsByGroup($group);
            $scb = $this->searchCriteriaBuilderFactory->create();
            $scb->addFilter('entity_id', $linkedProductIds, 'in');
            $searchResults = $this->productRepository->getList($scb->create());
            if ($searchResults->getTotalCount() > 0) {
                foreach ($searchResults->getItems() as $item) {
                    $data = $item->toArray();
                    $data['model'] = 'product';
                    $resultItem['products'][] = $data;
                }
            }

            $result[] = $resultItem;
        }

        return $result;
    }
}

This pretty much works but I have a problem fetching composite fields like price or small_image.

When I run my query without them everything is fine.

But with them I get this error

query {
  getLinkedProductsByGroups(groups: ["001021", "001107"]) {
    group
    products {    
      name
      sku
      small_image {
          url
      }    
    }
  }
}

This error comes up

{
    "errors": [
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                0,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                1,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                2,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                3,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                4,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                5,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                6,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                7,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                8,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                9,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                10,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                0,
                "products",
                11,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                1,
                "products",
                0,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                1,
                "products",
                1,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                1,
                "products",
                2,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                1,
                "products",
                3,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                1,
                "products",
                4,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                1,
                "products",
                5,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                1,
                "products",
                6,
                "small_image",
                "url"
            ]
        },
        {
            "debugMessage": "Call to a member function getData() on string",
            "message": "Internal server error",
            "extensions": {
                "category": "internal"
            },
            "locations": [
                {
                    "line": 8,
                    "column": 11
                }
            ],
            "path": [
                "getLinkedProductsByGroups",
                1,
                "products",
                7,
                "small_image",
                "url"
            ]
        }
    ],
    "data": {
        "getLinkedProductsByGroups": [
            {
                "group": "001021",
                "products": [
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-PKIB",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-PKYW",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-PKDBL",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "BIDI BADU Bella Tech Neck Women's T-shirt-XS",
                        "sku": "001021-PKDBL-XS",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-BKDBL",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-DBPK",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-CON",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-GRCO",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-PKGR",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Tech Neck Women's T-shirt-XS",
                        "sku": "001021-PKGR-XS",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-RDPK",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Bella Women's Tech Neck T-shirt",
                        "sku": "001021-ANDB",
                        "small_image": {
                            "url": null
                        }
                    }
                ]
            },
            {
                "group": "001107",
                "products": [
                    {
                        "name": "Bidi Badu Magu Crew Tech Sport Socks x 3",
                        "sku": "001107-WH",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Magu Crew Tech Socks - set of 3-39-42",
                        "sku": "001107-WH-39-42",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Magu Crew Tech Socks - set of 3-43-46",
                        "sku": "001107-WH-43-46",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Magu Crew Tech Socks - set of 3-46-50",
                        "sku": "001107-WH-46-50",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Magu Crew Tech Sport Socks x 3",
                        "sku": "001107-BK",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Magu Crew Tech Socks - set of 3-39-42",
                        "sku": "001107-BK-39-42",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Magu Crew Tech Socks - set of 3-43-46",
                        "sku": "001107-BK-43-46",
                        "small_image": {
                            "url": null
                        }
                    },
                    {
                        "name": "Bidi Badu Magu Crew Tech Socks - set of 3-46-50",
                        "sku": "001107-BK-46-50",
                        "small_image": {
                            "url": null
                        }
                    }
                ]
            }
        ]
    }
}

Of course I can't use the price / image fields directly because the ProductInterface type must have a sub-selection for them. But the toArray() and the getData() functions don't give the result as expected. So how do I make it convert the fields properly from the ProductInterface defined in the PHP classes, to the ProductInterface defined in GraphQl so that the result is correct?

1 Answer 1

0

To answer my own question there is a ProductDataProvider service for requesting the product information by ID.

\Magento\CatalogGraphQl\Model\ProductDataProvider

Using this function

\Magento\CatalogGraphQl\Model\ProductDataProvider::getProductDataById

Makes everything resolve correctly in the GraphQl resolver

Moreover I can modify my code to

            if ($searchResults->getTotalCount() > 0) {
                foreach ($searchResults->getItems() as $item) {
                    $data = $item->toArray();
                    $data['model'] = $item;
                    $resultItem['products'][] = $data;
                }
            }

so that it works as well. The difference is that in the model key, the whole product object needs to be passed.

Your Answer

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

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