Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/2.3-develop' into product-url-re…
Browse files Browse the repository at this point in the history
…writes
  • Loading branch information
Valeriy Nayda committed Oct 3, 2018
2 parents 7b8799d + da5a9ed commit 6d8e43d
Show file tree
Hide file tree
Showing 57 changed files with 2,020 additions and 146 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="AdminCreateApiDynamicBundleProductActionGroup">
<arguments>
<argument name="productName" defaultValue="Api Dynamic Bundle Product" type="string"/>
</arguments>
<!--Create 4 simple products-->
<createData entity="SimpleProduct2" stepKey="simpleProduct1">
<field key="price">4.99</field>
</createData>
<createData entity="SimpleProduct2" stepKey="simpleProduct2">
<field key="price">2.89</field>
</createData>
<createData entity="SimpleProduct2" stepKey="simpleProduct3">
<field key="price">7.33</field>
</createData>
<createData entity="SimpleProduct2" stepKey="simpleProduct4">
<field key="price">18.25</field>
</createData>
<!-- Create the bundle product based -->
<createData entity="ApiBundleProduct" stepKey="createBundleProduct">
<field key="name">{{productName}}</field>
</createData>
<createData entity="MultipleSelectOption" stepKey="createBundleOption1_1">
<requiredEntity createDataKey="createBundleProduct"/>
<field key="required">false</field>
</createData>
<createData entity="CheckboxOption" stepKey="createBundleOption1_2">
<requiredEntity createDataKey="createBundleProduct"/>
</createData>
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct">
<requiredEntity createDataKey="createBundleProduct"/>
<requiredEntity createDataKey="createBundleOption1_1"/>
<requiredEntity createDataKey="simpleProduct1"/>
</createData>
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct2">
<requiredEntity createDataKey="createBundleProduct"/>
<requiredEntity createDataKey="createBundleOption1_1"/>
<requiredEntity createDataKey="simpleProduct2"/>
</createData>
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct3">
<requiredEntity createDataKey="createBundleProduct"/>
<requiredEntity createDataKey="createBundleOption1_2"/>
<requiredEntity createDataKey="simpleProduct3"/>
</createData>
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct4">
<requiredEntity createDataKey="createBundleProduct"/>
<requiredEntity createDataKey="createBundleOption1_2"/>
<requiredEntity createDataKey="simpleProduct4"/>
</createData>
</actionGroup>
<actionGroup name="AdminCreateApiFixedBundleProductActionGroup">
<arguments>
<argument name="productName" defaultValue="Api Fixed Bundle Product" type="string"/>
</arguments>
<!--Create 4 simple products-->
<createData entity="SimpleProduct2" stepKey="simpleProduct1">
<field key="price">4.99</field>
</createData>
<createData entity="SimpleProduct2" stepKey="simpleProduct2">
<field key="price">2.89</field>
</createData>
<createData entity="SimpleProduct2" stepKey="simpleProduct3">
<field key="price">7.33</field>
</createData>
<createData entity="SimpleProduct2" stepKey="simpleProduct4">
<field key="price">18.25</field>
</createData>
<!-- Create the bundle product based -->
<createData entity="ApiFixedBundleProduct" stepKey="createBundleProduct">
<field key="name">{{productName}}</field>
</createData>
<createData entity="MultipleSelectOption" stepKey="createBundleOption1_1">
<requiredEntity createDataKey="createBundleProduct"/>
<field key="required">false</field>
</createData>
<createData entity="CheckboxOption" stepKey="createBundleOption1_2">
<requiredEntity createDataKey="createBundleProduct"/>
</createData>
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct">
<requiredEntity createDataKey="createBundleProduct"/>
<requiredEntity createDataKey="createBundleOption1_1"/>
<requiredEntity createDataKey="simpleProduct1"/>
</createData>
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct2">
<requiredEntity createDataKey="createBundleProduct"/>
<requiredEntity createDataKey="createBundleOption1_1"/>
<requiredEntity createDataKey="simpleProduct2"/>
</createData>
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct3">
<requiredEntity createDataKey="createBundleProduct"/>
<requiredEntity createDataKey="createBundleOption1_2"/>
<requiredEntity createDataKey="simpleProduct3"/>
</createData>
<createData entity="ApiBundleLink" stepKey="linkOptionToProduct4">
<requiredEntity createDataKey="createBundleProduct"/>
<requiredEntity createDataKey="createBundleOption1_2"/>
<requiredEntity createDataKey="simpleProduct4"/>
</createData>
</actionGroup>
</actionGroups>
15 changes: 15 additions & 0 deletions app/code/Magento/Bundle/Test/Mftf/Data/ProductData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,19 @@
<requiredEntity type="custom_attribute">CustomAttributeDynamicPrice</requiredEntity>
<requiredEntity type="custom_attribute">CustomAttributePriceViewRange</requiredEntity>
</entity>
<entity name="ApiFixedBundleProduct" type="product2">
<data key="name" unique="suffix">Api Fixed Bundle Product</data>
<data key="sku" unique="suffix">api-fixed-bundle-product</data>
<data key="type_id">bundle</data>
<data key="attribute_set_id">4</data>
<data key="price">1.23</data>
<data key="visibility">4</data>
<data key="status">1</data>
<data key="urlKey" unique="suffix">api-fixed-bundle-product</data>
<requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity>
<requiredEntity type="custom_attribute">ApiProductDescription</requiredEntity>
<requiredEntity type="custom_attribute">ApiProductShortDescription</requiredEntity>
<requiredEntity type="custom_attribute">CustomAttributeFixPrice</requiredEntity>
<requiredEntity type="custom_attribute">CustomAttributePriceView</requiredEntity>
</entity>
</entities>
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
<section name="StorefrontMessagesSection">
<element name="success" type="text" selector="div.message-success.success.message"/>
<element name="error" type="text" selector="div.message-error.error.message"/>
</section>
</sections>
67 changes: 67 additions & 0 deletions app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model\Product\Option;

use Magento\Catalog\Model\Product\Option\Type\Date as ProductDateOptionType;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Stdlib\DateTime;

/**
* @inheritdoc
*/
class DateType extends ProductDateOptionType
{
/**
* Make valid string as a value of date option type for GraphQl queries
*
* @param array $values All product option values, i.e. array (option_id => mixed, option_id => mixed...)
* @return ProductDateOptionType
*/
public function validateUserValue($values)
{
if ($this->_dateExists() || $this->_timeExists()) {
return parent::validateUserValue($this->formatValues($values));
}

return $this;
}

/**
* Format date value from string to date array
*
* @param [] $values
* @return []
* @throws LocalizedException
*/
private function formatValues($values)
{
if (isset($values[$this->getOption()->getId()])) {
$value = $values[$this->getOption()->getId()];
$dateTime = \DateTime::createFromFormat(DateTime::DATETIME_PHP_FORMAT, $value);
$values[$this->getOption()->getId()] = [
'date' => $value,
'year' => $dateTime->format('Y'),
'month' => $dateTime->format('m'),
'day' => $dateTime->format('d'),
'hour' => $dateTime->format('H'),
'minute' => $dateTime->format('i'),
'day_part' => $dateTime->format('a'),
];
}

return $values;
}

/**
* @inheritdoc
*/
public function useCalendar()
{
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public function __construct(
}

/**
* {@inheritdoc}
* @inheritdoc
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
Expand Down Expand Up @@ -114,6 +114,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
$categories[$item->getId()] = $this->customAttributesFlattener
->flatten($categories[$item->getId()]);
$categories[$item->getId()]['product_count'] = $item->getProductCount();
$categories[$item->getId()]['model'] = $item;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?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\Catalog\Model\Category;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Catalog\Helper\Output as OutputHelper;

/**
* Resolve rendered content for category attributes where HTML content is allowed
*/
class CategoryHtmlAttribute implements ResolverInterface
{
/**
* @var OutputHelper
*/
private $outputHelper;

/**
* @param OutputHelper $outputHelper
*/
public function __construct(
OutputHelper $outputHelper
) {
$this->outputHelper = $outputHelper;
}

/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
if (!isset($value['model'])) {
throw new LocalizedException(__('"model" value should be specified'));
}

/* @var $category Category */
$category = $value['model'];
$fieldName = $field->getName();
$renderedValue = $this->outputHelper->categoryAttribute($category, $category->getData($fieldName), $fieldName);

return $renderedValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\ImageFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
Expand Down Expand Up @@ -45,7 +46,7 @@ public function resolve(
array $args = null
): array {
if (!isset($value['model'])) {
throw new \LogicException(__('"model" value should be specified'));
throw new LocalizedException(__('"model" value should be specified'));
}
/** @var Product $product */
$product = $value['model'];
Expand Down
14 changes: 9 additions & 5 deletions app/code/Magento/CatalogGraphQl/Model/Resolver/Products.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Magento\CatalogGraphQl\Model\Resolver;

use Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Filter;
use Magento\CatalogGraphQl\Model\Resolver\Products\Query\Search;
Expand Down Expand Up @@ -51,13 +52,15 @@ class Products implements ResolverInterface
* @param Builder $searchCriteriaBuilder
* @param Search $searchQuery
* @param Filter $filterQuery
* @param SearchFilter $searchFilter
* @param Filters $filtersDataProvider
*/
public function __construct(
Builder $searchCriteriaBuilder,
Search $searchQuery,
Filter $filterQuery,
SearchFilter $searchFilter,
\Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider
Filters $filtersDataProvider
) {
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->searchQuery = $searchQuery;
Expand Down Expand Up @@ -100,10 +103,10 @@ public function resolve(

$currentPage = $searchCriteria->getCurrentPage();
if ($searchCriteria->getCurrentPage() > $maxPages && $searchResult->getTotalCount() > 0) {
$currentPage = new GraphQlInputException(
throw new GraphQlInputException(
__(
'currentPage value %1 specified is greater than the number of pages available.',
[$maxPages]
'currentPage value %1 specified is greater than the %2 page(s) available.',
[$currentPage, $maxPages]
)
);
}
Expand All @@ -113,7 +116,8 @@ public function resolve(
'items' => $searchResult->getProductsSearchResult(),
'page_info' => [
'page_size' => $searchCriteria->getPageSize(),
'current_page' => $currentPage
'current_page' => $currentPage,
'total_pages' => $maxPages
],
'filters' => $this->filtersDataProvider->getData($layerType)
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ public function __construct(
}

/**
* Returns categories tree starting from parent $rootCategoryId
*
* @param ResolveInfo $resolveInfo
* @param int $rootCategoryId
* @return array
Expand All @@ -107,6 +109,8 @@ public function getTree(ResolveInfo $resolveInfo, int $rootCategoryId) : array
}

/**
* Iterates through category tree
*
* @param \Iterator $iterator
* @return array
*/
Expand All @@ -119,6 +123,7 @@ private function processTree(\Iterator $iterator) : array
$iterator->next();
$nextCategory = $iterator->current();
$tree[$category->getId()] = $this->hydrator->hydrateCategory($category);
$tree[$category->getId()]['model'] = $category;
if ($nextCategory && (int) $nextCategory->getLevel() !== (int) $category->getLevel()) {
$tree[$category->getId()]['children'] = $this->processTree($iterator);
}
Expand All @@ -128,6 +133,8 @@ private function processTree(\Iterator $iterator) : array
}

/**
* Joins EAV attributes recursively
*
* @param Collection $collection
* @param FieldNode $fieldNode
* @return void
Expand Down
1 change: 1 addition & 0 deletions app/code/Magento/CatalogGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Model\Product\Option\Type\Date" type="Magento\CatalogGraphQl\Model\Product\Option\DateType" />
<type name="Magento\CatalogGraphQl\Model\ProductInterfaceTypeResolverComposite">
<arguments>
<argument name="productTypeNameResolvers" xsi:type="array">
Expand Down
2 changes: 1 addition & 1 deletion app/code/Magento/CatalogGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ interface CustomizableProductInterface @typeResolver(class: "Magento\\CatalogGra

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") {
id: Int @doc(description: "An ID that uniquely identifies the category")
description: String @doc(description: "An optional description of the category")
description: String @doc(description: "An optional description of the category") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryHtmlAttribute")
name: String @doc(description: "The display name of the category")
path: String @doc(description: "Category Path")
path_in_store: String @doc(description: "Category path in store")
Expand Down
Loading

0 comments on commit 6d8e43d

Please sign in to comment.