Skip to content

Commit 9200a16

Browse files
author
Valeriy Nayda
committed
Merge remote-tracking branch 'origin/2.3-develop' into 55-56-account-mutations
2 parents cc8d328 + da5a9ed commit 9200a16

File tree

57 files changed

+2020
-146
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2020
-146
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminCreateApiDynamicBundleProductActionGroup">
12+
<arguments>
13+
<argument name="productName" defaultValue="Api Dynamic Bundle Product" type="string"/>
14+
</arguments>
15+
<!--Create 4 simple products-->
16+
<createData entity="SimpleProduct2" stepKey="simpleProduct1">
17+
<field key="price">4.99</field>
18+
</createData>
19+
<createData entity="SimpleProduct2" stepKey="simpleProduct2">
20+
<field key="price">2.89</field>
21+
</createData>
22+
<createData entity="SimpleProduct2" stepKey="simpleProduct3">
23+
<field key="price">7.33</field>
24+
</createData>
25+
<createData entity="SimpleProduct2" stepKey="simpleProduct4">
26+
<field key="price">18.25</field>
27+
</createData>
28+
<!-- Create the bundle product based -->
29+
<createData entity="ApiBundleProduct" stepKey="createBundleProduct">
30+
<field key="name">{{productName}}</field>
31+
</createData>
32+
<createData entity="MultipleSelectOption" stepKey="createBundleOption1_1">
33+
<requiredEntity createDataKey="createBundleProduct"/>
34+
<field key="required">false</field>
35+
</createData>
36+
<createData entity="CheckboxOption" stepKey="createBundleOption1_2">
37+
<requiredEntity createDataKey="createBundleProduct"/>
38+
</createData>
39+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct">
40+
<requiredEntity createDataKey="createBundleProduct"/>
41+
<requiredEntity createDataKey="createBundleOption1_1"/>
42+
<requiredEntity createDataKey="simpleProduct1"/>
43+
</createData>
44+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct2">
45+
<requiredEntity createDataKey="createBundleProduct"/>
46+
<requiredEntity createDataKey="createBundleOption1_1"/>
47+
<requiredEntity createDataKey="simpleProduct2"/>
48+
</createData>
49+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct3">
50+
<requiredEntity createDataKey="createBundleProduct"/>
51+
<requiredEntity createDataKey="createBundleOption1_2"/>
52+
<requiredEntity createDataKey="simpleProduct3"/>
53+
</createData>
54+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct4">
55+
<requiredEntity createDataKey="createBundleProduct"/>
56+
<requiredEntity createDataKey="createBundleOption1_2"/>
57+
<requiredEntity createDataKey="simpleProduct4"/>
58+
</createData>
59+
</actionGroup>
60+
<actionGroup name="AdminCreateApiFixedBundleProductActionGroup">
61+
<arguments>
62+
<argument name="productName" defaultValue="Api Fixed Bundle Product" type="string"/>
63+
</arguments>
64+
<!--Create 4 simple products-->
65+
<createData entity="SimpleProduct2" stepKey="simpleProduct1">
66+
<field key="price">4.99</field>
67+
</createData>
68+
<createData entity="SimpleProduct2" stepKey="simpleProduct2">
69+
<field key="price">2.89</field>
70+
</createData>
71+
<createData entity="SimpleProduct2" stepKey="simpleProduct3">
72+
<field key="price">7.33</field>
73+
</createData>
74+
<createData entity="SimpleProduct2" stepKey="simpleProduct4">
75+
<field key="price">18.25</field>
76+
</createData>
77+
<!-- Create the bundle product based -->
78+
<createData entity="ApiFixedBundleProduct" stepKey="createBundleProduct">
79+
<field key="name">{{productName}}</field>
80+
</createData>
81+
<createData entity="MultipleSelectOption" stepKey="createBundleOption1_1">
82+
<requiredEntity createDataKey="createBundleProduct"/>
83+
<field key="required">false</field>
84+
</createData>
85+
<createData entity="CheckboxOption" stepKey="createBundleOption1_2">
86+
<requiredEntity createDataKey="createBundleProduct"/>
87+
</createData>
88+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct">
89+
<requiredEntity createDataKey="createBundleProduct"/>
90+
<requiredEntity createDataKey="createBundleOption1_1"/>
91+
<requiredEntity createDataKey="simpleProduct1"/>
92+
</createData>
93+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct2">
94+
<requiredEntity createDataKey="createBundleProduct"/>
95+
<requiredEntity createDataKey="createBundleOption1_1"/>
96+
<requiredEntity createDataKey="simpleProduct2"/>
97+
</createData>
98+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct3">
99+
<requiredEntity createDataKey="createBundleProduct"/>
100+
<requiredEntity createDataKey="createBundleOption1_2"/>
101+
<requiredEntity createDataKey="simpleProduct3"/>
102+
</createData>
103+
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct4">
104+
<requiredEntity createDataKey="createBundleProduct"/>
105+
<requiredEntity createDataKey="createBundleOption1_2"/>
106+
<requiredEntity createDataKey="simpleProduct4"/>
107+
</createData>
108+
</actionGroup>
109+
</actionGroups>

app/code/Magento/Bundle/Test/Mftf/Data/ProductData.xml

+15
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,19 @@
6060
<requiredEntity type="custom_attribute">CustomAttributeDynamicPrice</requiredEntity>
6161
<requiredEntity type="custom_attribute">CustomAttributePriceViewRange</requiredEntity>
6262
</entity>
63+
<entity name="ApiFixedBundleProduct" type="product2">
64+
<data key="name" unique="suffix">Api Fixed Bundle Product</data>
65+
<data key="sku" unique="suffix">api-fixed-bundle-product</data>
66+
<data key="type_id">bundle</data>
67+
<data key="attribute_set_id">4</data>
68+
<data key="price">1.23</data>
69+
<data key="visibility">4</data>
70+
<data key="status">1</data>
71+
<data key="urlKey" unique="suffix">api-fixed-bundle-product</data>
72+
<requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity>
73+
<requiredEntity type="custom_attribute">ApiProductDescription</requiredEntity>
74+
<requiredEntity type="custom_attribute">ApiProductShortDescription</requiredEntity>
75+
<requiredEntity type="custom_attribute">CustomAttributeFixPrice</requiredEntity>
76+
<requiredEntity type="custom_attribute">CustomAttributePriceView</requiredEntity>
77+
</entity>
6378
</entities>

app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMessagesSection.xml

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1111
<section name="StorefrontMessagesSection">
1212
<element name="success" type="text" selector="div.message-success.success.message"/>
13+
<element name="error" type="text" selector="div.message-error.error.message"/>
1314
</section>
1415
</sections>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Product\Option;
9+
10+
use Magento\Catalog\Model\Product\Option\Type\Date as ProductDateOptionType;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\Stdlib\DateTime;
13+
14+
/**
15+
* @inheritdoc
16+
*/
17+
class DateType extends ProductDateOptionType
18+
{
19+
/**
20+
* Make valid string as a value of date option type for GraphQl queries
21+
*
22+
* @param array $values All product option values, i.e. array (option_id => mixed, option_id => mixed...)
23+
* @return ProductDateOptionType
24+
*/
25+
public function validateUserValue($values)
26+
{
27+
if ($this->_dateExists() || $this->_timeExists()) {
28+
return parent::validateUserValue($this->formatValues($values));
29+
}
30+
31+
return $this;
32+
}
33+
34+
/**
35+
* Format date value from string to date array
36+
*
37+
* @param [] $values
38+
* @return []
39+
* @throws LocalizedException
40+
*/
41+
private function formatValues($values)
42+
{
43+
if (isset($values[$this->getOption()->getId()])) {
44+
$value = $values[$this->getOption()->getId()];
45+
$dateTime = \DateTime::createFromFormat(DateTime::DATETIME_PHP_FORMAT, $value);
46+
$values[$this->getOption()->getId()] = [
47+
'date' => $value,
48+
'year' => $dateTime->format('Y'),
49+
'month' => $dateTime->format('m'),
50+
'day' => $dateTime->format('d'),
51+
'hour' => $dateTime->format('H'),
52+
'minute' => $dateTime->format('i'),
53+
'day_part' => $dateTime->format('a'),
54+
];
55+
}
56+
57+
return $values;
58+
}
59+
60+
/**
61+
* @inheritdoc
62+
*/
63+
public function useCalendar()
64+
{
65+
return false;
66+
}
67+
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function __construct(
7979
}
8080

8181
/**
82-
* {@inheritdoc}
82+
* @inheritdoc
8383
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
8484
*/
8585
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
@@ -114,6 +114,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
114114
$categories[$item->getId()] = $this->customAttributesFlattener
115115
->flatten($categories[$item->getId()]);
116116
$categories[$item->getId()]['product_count'] = $item->getProductCount();
117+
$categories[$item->getId()]['model'] = $item;
117118
}
118119
}
119120

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver\Category;
9+
10+
use Magento\Catalog\Model\Category;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Query\ResolverInterface;
14+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
15+
use Magento\Catalog\Helper\Output as OutputHelper;
16+
17+
/**
18+
* Resolve rendered content for category attributes where HTML content is allowed
19+
*/
20+
class CategoryHtmlAttribute implements ResolverInterface
21+
{
22+
/**
23+
* @var OutputHelper
24+
*/
25+
private $outputHelper;
26+
27+
/**
28+
* @param OutputHelper $outputHelper
29+
*/
30+
public function __construct(
31+
OutputHelper $outputHelper
32+
) {
33+
$this->outputHelper = $outputHelper;
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function resolve(
40+
Field $field,
41+
$context,
42+
ResolveInfo $info,
43+
array $value = null,
44+
array $args = null
45+
) {
46+
if (!isset($value['model'])) {
47+
throw new LocalizedException(__('"model" value should be specified'));
48+
}
49+
50+
/* @var $category Category */
51+
$category = $value['model'];
52+
$fieldName = $field->getName();
53+
$renderedValue = $this->outputHelper->categoryAttribute($category, $category->getData($fieldName), $fieldName);
54+
55+
return $renderedValue;
56+
}
57+
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Image.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use Magento\Catalog\Model\Product;
1111
use Magento\Catalog\Model\Product\ImageFactory;
12+
use Magento\Framework\Exception\LocalizedException;
1213
use Magento\Framework\GraphQl\Config\Element\Field;
1314
use Magento\Framework\GraphQl\Query\ResolverInterface;
1415
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
@@ -45,7 +46,7 @@ public function resolve(
4546
array $args = null
4647
): array {
4748
if (!isset($value['model'])) {
48-
throw new \LogicException(__('"model" value should be specified'));
49+
throw new LocalizedException(__('"model" value should be specified'));
4950
}
5051
/** @var Product $product */
5152
$product = $value['model'];

app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\CatalogGraphQl\Model\Resolver;
99

10+
use Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters;
1011
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1112
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter;
1213
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Search;
@@ -51,13 +52,15 @@ class Products implements ResolverInterface
5152
* @param Builder $searchCriteriaBuilder
5253
* @param Search $searchQuery
5354
* @param Filter $filterQuery
55+
* @param SearchFilter $searchFilter
56+
* @param Filters $filtersDataProvider
5457
*/
5558
public function __construct(
5659
Builder $searchCriteriaBuilder,
5760
Search $searchQuery,
5861
Filter $filterQuery,
5962
SearchFilter $searchFilter,
60-
\Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider
63+
Filters $filtersDataProvider
6164
) {
6265
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
6366
$this->searchQuery = $searchQuery;
@@ -100,10 +103,10 @@ public function resolve(
100103

101104
$currentPage = $searchCriteria->getCurrentPage();
102105
if ($searchCriteria->getCurrentPage() > $maxPages && $searchResult->getTotalCount() > 0) {
103-
$currentPage = new GraphQlInputException(
106+
throw new GraphQlInputException(
104107
__(
105-
'currentPage value %1 specified is greater than the number of pages available.',
106-
[$maxPages]
108+
'currentPage value %1 specified is greater than the %2 page(s) available.',
109+
[$currentPage, $maxPages]
107110
)
108111
);
109112
}
@@ -113,7 +116,8 @@ public function resolve(
113116
'items' => $searchResult->getProductsSearchResult(),
114117
'page_info' => [
115118
'page_size' => $searchCriteria->getPageSize(),
116-
'current_page' => $currentPage
119+
'current_page' => $currentPage,
120+
'total_pages' => $maxPages
117121
],
118122
'filters' => $this->filtersDataProvider->getData($layerType)
119123
];

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php

+7
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public function __construct(
8383
}
8484

8585
/**
86+
* Returns categories tree starting from parent $rootCategoryId
87+
*
8688
* @param ResolveInfo $resolveInfo
8789
* @param int $rootCategoryId
8890
* @return array
@@ -107,6 +109,8 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId) : array
107109
}
108110

109111
/**
112+
* Iterates through category tree
113+
*
110114
* @param \Iterator $iterator
111115
* @return array
112116
*/
@@ -119,6 +123,7 @@ private function processTree(\Iterator $iterator) : array
119123
$iterator->next();
120124
$nextCategory = $iterator->current();
121125
$tree[$category->getId()] = $this->hydrator->hydrateCategory($category);
126+
$tree[$category->getId()]['model'] = $category;
122127
if ($nextCategory && (int) $nextCategory->getLevel() !== (int) $category->getLevel()) {
123128
$tree[$category->getId()]['children'] = $this->processTree($iterator);
124129
}
@@ -128,6 +133,8 @@ private function processTree(\Iterator $iterator) : array
128133
}
129134

130135
/**
136+
* Joins EAV attributes recursively
137+
*
131138
* @param Collection $collection
132139
* @param FieldNode $fieldNode
133140
* @return void

app/code/Magento/CatalogGraphQl/etc/graphql/di.xml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<preference for="Magento\Catalog\Model\Product\Option\Type\Date" type="Magento\CatalogGraphQl\Model\Product\Option\DateType" />
910
<type name="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite">
1011
<arguments>
1112
<argument name="productTypeNameResolvers" xsi:type="array">

app/code/Magento/CatalogGraphQl/etc/schema.graphqls

+1-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGra
369369

370370
interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\CategoryInterfaceTypeResolver") @doc(description: "CategoryInterface contains the full set of attributes that can be returned in a category search") {
371371
id: Int @doc(description: "An ID that uniquely identifies the category")
372-
description: String @doc(description: "An optional description of the category")
372+
description: String @doc(description: "An optional description of the category") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryHtmlAttribute")
373373
name: String @doc(description: "The display name of the category")
374374
path: String @doc(description: "Category Path")
375375
path_in_store: String @doc(description: "Category path in store")

0 commit comments

Comments
 (0)