Skip to content
This repository was archived by the owner on Dec 19, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model\Resolver\Category;

use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;

/**
* Retrieves the sort field default value
*/
class SortFieldDefault implements ResolverInterface
{
/**
* @var ValueFactory
*/
private $valueFactory;

/**
* @var \Magento\Catalog\Model\Config
*/
private $catalogConfig;

/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;

/**
* @param ValueFactory $valueFactory
* @param \Magento\Catalog\Model\Config $catalogConfig
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
*/
public function __construct(
ValueFactory $valueFactory,
\Magento\Catalog\Model\Config $catalogConfig,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->valueFactory = $valueFactory;
$this->catalogConfig = $catalogConfig;
$this->storeManager = $storeManager;
}

/**
* {@inheritDoc}
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value
{
$sortFieldDefault = $this->catalogConfig->getProductListDefaultSortBy($this->storeManager->getStore()->getId());

$result = function () use ($sortFieldDefault) {
return $sortFieldDefault;
};

return $this->valueFactory->create($result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model\Resolver\Category;

use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;

/**
* Retrieves the sort fields options information object
*/
class SortFieldsOptions implements ResolverInterface
{
/**
* @var ValueFactory
*/
private $valueFactory;

/**
* @var \Magento\Catalog\Model\Config
*/
private $catalogConfig;

/**
* @param ValueFactory $valueFactory
* @param \Magento\Catalog\Model\Config $catalogConfig
*/
public function __construct(
ValueFactory $valueFactory,
\Magento\Catalog\Model\Config $catalogConfig
) {
$this->valueFactory = $valueFactory;
$this->catalogConfig = $catalogConfig;
}

/**
* {@inheritDoc}
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) : Value
{
$sortFieldsOptions = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use \Magento\Catalog\Model\Category\Attribute\Source\Sortby::getAllOptions. It has two benefits:

  • includes position, so no need to hardcode it here again
  • result is already properly formatted, no need to do foreach (assuming that key is renamed to value as suggested in another comment)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason i didn't use this function was the translation function called for labels in \Magento\Catalog\Model\Category\Attribute\Source\Sortby::getAllOptions casuses Internal server error and every value for label is equal null. I'm not sure exactly, but it looks like a bug.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this one \Magento\Catalog\Model\Config::getAttributeUsedForSortByArray?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same, this function also contains translation function for Position option
$options = ['position' => __('Position')];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that underlying GraphQL library (webonyx) expects exact match between declared type (string) and the actual value type (Magento\Framework\Phrase), and it does not try to perform type casting.

I was able to make it work by manually casting Phrase to string before returning the result:

        $sortFieldsOptions = $this->sortBy->getAllOptions();
        array_walk(
            $sortFieldsOptions,
            function (&$option) {
                $option['label'] = (string)$option['label'];
            }
        );

['key' => 'position', 'label' => 'Position']
];
foreach ($this->catalogConfig->getAttributesUsedForSortBy() as $attribute) {
$sortFieldsOptions[] = ['key' => $attribute->getAttributeCode(), 'label' => $attribute->getStoreLabel()];
}

$result = function () use ($sortFieldsOptions) {
return $sortFieldsOptions;
};

return $this->valueFactory->create($result);
}
}
5 changes: 3 additions & 2 deletions app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ public function resolve(
'items' => $searchResult->getProductsSearchResult(),
'page_info' => [
'page_size' => $searchCriteria->getPageSize(),
'current_page' => $currentPage
'current_page' => $currentPage,
'sort_fields' => [],
],
'filters' => $this->filtersDataProvider->getData($layerType)
'filters' => $this->filtersDataProvider->getData($layerType),
];

$result = function () use ($data) {
Expand Down
11 changes: 11 additions & 0 deletions app/code/Magento/GraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,20 @@ input FilterTypeInput @doc(description: "FilterTypeInput specifies which action
type SearchResultPageInfo @doc(description: "SearchResultPageInfo provides navigation for the query response") {
page_size: Int @doc(description: "Specifies the maximum number of items to return")
current_page: Int @doc(description: "Specifies which page of results to return")
sort_fields: SortFields @doc(description: "An object that includes the default sort field and all available sort fields")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a single new resolver, just for sort_fields.

}

enum SortEnum @doc(description: "This enumeration indicates whether to return results in ascending or descending order") {
ASC
DESC
}

type SortField {
key: String @doc(description: "Attribute code of sort field")
label: String @doc(description: "Label of sort field")
}

type SortFields @doc(description: "SortFields contains a default value for sort fields and all available sort fields") {
default: String @doc(description: "Default value of sort fields") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\SortFieldDefault")
options: [SortField] @doc(description: "Available sort fields") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\SortFieldsOptions")
}
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,15 @@ public function testQueryProductsInCurrentPageSortedByPriceASC()
{
page_size
current_page
sort_fields
{
default
options
{
key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename key to value for consistency with naming in other places in Magento, for example \Magento\Catalog\Model\Category\Attribute\Source\Sortby::getAllOptions

label
}
}
}
}
}
Expand All @@ -530,6 +539,10 @@ public function testQueryProductsInCurrentPageSortedByPriceASC()
$this->assertProductItems($filteredChildProducts, $response);
$this->assertEquals(4, $response['products']['page_info']['page_size']);
$this->assertEquals(1, $response['products']['page_info']['current_page']);
$this->assertArrayHasKey('sort_fields', $response['products']['page_info']);
$this->assertArrayHasKey('options', $response['products']['page_info']['sort_fields']);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add assertion for options values, it is not validated at the moment.

$this->assertArrayHasKey('default', $response['products']['page_info']['sort_fields']);
$this->assertEquals('position', $response['products']['page_info']['sort_fields']['default']);
}

/**
Expand Down