I want to sort the products graphql with backorder and is_in_stock attribute. Please let me know if anyone has any solution for it. I tried with quantity_and_stock_status it is applied only on qty.
2 Answers
You don't need any special query methods to retrieve custom attributes. We can just pass the custom attribute code to the query. And also for filtering you can simply pass the attribute name, please follow this documentation:
CHeck this -> GraphQL Custom Filters
Here’s how you can achieve adding custom sorting for backorder
and is_in_stock
attributes in Magento 2.3.6 with the correct naming:
Step 1: Create a Custom Module
Create the module directory structure:
app/code/Vendor/CustomGraphQlSort/
Create the
registration.php
file:<?php use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register( ComponentRegistrar::MODULE, 'Vendor_CustomGraphQlSort', __DIR__ );
Create the
module.xml
file: Inapp/code/Vendor/CustomGraphQlSort/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="Vendor_CustomGraphQlSort" setup_version="1.0.0"/> </config>
Step 2: Extend the GraphQL Resolver
Create the
schema.graphqls
file:This file defines the schema that extends the GraphQL capabilities. Place it in
app/code/Vendor/CustomGraphQlSort/etc/schema.graphqls
.type Query { products( search: String, sort: ProductSortInput ): Products } input ProductSortInput { backorder: SortEnum is_in_stock: SortEnum } enum SortEnum { ASC DESC }
Create a Custom Resolver to Sort Products by
backorder
andis_in_stock
:In
app/code/Vendor/CustomGraphQlSort/Model/Resolver/ProductSort.php
:<?php namespace Vendor\CustomGraphQlSort\Model\Resolver; use Magento\CatalogGraphQl\Model\Resolver\Products as MagentoProductsResolver; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SortOrder; use Magento\Framework\Api\FilterBuilder; use Magento\CatalogInventory\Model\StockRegistry; class ProductSort implements ResolverInterface { protected $productRepository; protected $searchCriteriaBuilder; protected $filterBuilder; protected $sortOrder; protected $stockRegistry; public function __construct( ProductRepositoryInterface $productRepository, SearchCriteriaBuilder $searchCriteriaBuilder, FilterBuilder $filterBuilder, SortOrder $sortOrder, StockRegistry $stockRegistry ) { $this->productRepository = $productRepository; $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->filterBuilder = $filterBuilder; $this->sortOrder = $sortOrder; $this->stockRegistry = $stockRegistry; } public function resolve( Field $field, $context, ResolveInfo $info, array $value = null, array $args = null ) { $sortField = $args['sort'] ?? []; // Build search criteria $searchCriteria = $this->searchCriteriaBuilder->create(); // Add custom sorting logic for backorder and is_in_stock attributes if (isset($sortField['backorder'])) { $this->applyCustomSortOrder($searchCriteria, 'backorders', $sortField['backorder']); } if (isset($sortField['is_in_stock'])) { $this->applyCustomSortOrder($searchCriteria, 'is_in_stock', $sortField['is_in_stock']); } // Get products $products = $this->productRepository->getList($searchCriteria); // Process products and return the response return [ 'total_count' => $products->getTotalCount(), 'items' => $products->getItems() ]; } /** * Apply custom sort order to the search criteria. * * @param \Magento\Framework\Api\SearchCriteria $searchCriteria * @param string $field * @param string $direction */ protected function applyCustomSortOrder($searchCriteria, $field, $direction) { $sortOrder = $this->sortOrder->setField($field)->setDirection($direction); $searchCriteria->addSortOrder($sortOrder); } }
Step 3: Update the di.xml
File
You need to update the di.xml
to register the new sorting functionality. This will extend Magento’s default product resolver.
In app/code/Vendor/CustomGraphQlSort/etc/di.xml
:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework/ObjectManager/etc/config.xsd">
<type name="Magento\CatalogGraphQl\Model\Resolver\Products">
<plugin name="custom_product_sort_plugin" type="Vendor\CustomGraphQlSort\Model\Resolver\ProductSort" />
</type>
</config>
Step 4: Add Custom Attributes
You need to ensure that the backorder
and is_in_stock
attributes are correctly indexed and available for sorting:
is_in_stock
: This attribute is managed by Magento’s native inventory system.backorder
: If you have a custom attribute for backorders, make sure it's properly indexed and part of the product attributes.
Step 5: Clear Cache and Recompile
Once you’ve completed the code changes, run the following commands:
Clear Cache:
php bin/magento cache:flush
Run Dependency Injection Compilation:
php bin/magento setup:di:compile
Reindex (Optional, but recommended):
php bin/magento indexer:reindex
Deploy Static Content (if in production mode):
php bin/magento setup:static-content:deploy -f
Step 6: Test the GraphQL Query
Once your module is set up, test your GraphQL query to ensure that sorting by backorder
and is_in_stock
is working as expected. Use a query like this:
{
products(
search: "shirt",
sort: {
backorder: ASC,
is_in_stock: DESC
}
) {
items {
name
sku
is_in_stock
backorder
}
}
}
Summary:
- We created a custom GraphQL module to add sorting functionality for
backorder
andis_in_stock
attributes. - We extended the product resolver to handle these custom attributes and sort them.
- We defined a custom
schema.graphqls
to add new sorting options. - Finally, we applied the custom sort in the product list.
This solution should work in Magento 2.3.6 and allow you to sort products in GraphQL based on stock and backorder attributes.