Skip to content

Commit

Permalink
Merge branch '2.3-develop-mainline' into PULL-12965-FORWARDPORT
Browse files Browse the repository at this point in the history
  • Loading branch information
p-bystritsky committed Jan 4, 2018
2 parents 9e1610e + d7f2541 commit 8e3bbd0
Show file tree
Hide file tree
Showing 85 changed files with 2,753 additions and 385 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* See COPYING.txt for license details.
*/
-->
<a class="product-item-link"
<a if="isAllowed()"
class="product-item-link"
attr="href: $row().url"
text="label"/>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* See COPYING.txt for license details.
*/

namespace Magento\GraphQlCatalog\Model\Resolver\Products\Query;
namespace Magento\Framework\GraphQl\Query;

/**
* Processor or processors to re-format and add additional data outside of the scope of the query's fetch.
Expand All @@ -14,8 +14,8 @@ interface PostFetchProcessorInterface
/**
* Process data by formatting and add any necessary additional attributes.
*
* @param array $productData
* @param array $resultData
* @return array
*/
public function process(array $productData);
public function process(array $resultData);
}
46 changes: 26 additions & 20 deletions app/code/Magento/GraphQl/Controller/GraphQl.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
use Magento\Framework\App\Request\Http;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\Webapi\Response;
use Magento\GraphQl\Model\SchemaGeneratorInterface;
use Magento\Framework\GraphQl\RequestProcessor;
use Magento\Framework\GraphQl\QueryProcessor;
use Magento\Framework\GraphQl\ExceptionFormatter;
use Magento\GraphQl\Model\ResolverContext;
use Magento\Framework\GraphQl\HttpRequestProcessor;

/**
* Front controller for web API GraphQL area.
Expand All @@ -39,38 +39,50 @@ class GraphQl implements FrontControllerInterface
private $jsonSerializer;

/**
* @var RequestProcessor
* @var QueryProcessor
*/
private $requestProcessor;
private $queryProcessor;

/** @var ExceptionFormatter */
/**
* @var ExceptionFormatter
*/
private $graphQlError;

/** @var ResolverContext */
/**
* @var ResolverContext
*/
private $context;

/**
* @var HttpRequestProcessor
*/
private $requestProcessor;

/**
* @param Response $response
* @param SchemaGeneratorInterface $schemaGenerator
* @param SerializerInterface $jsonSerializer
* @param RequestProcessor $requestProcessor
* @param QueryProcessor $queryProcessor
* @param ExceptionFormatter $graphQlError
* @param ResolverContext $context
* @param HttpRequestProcessor $requestProcessor
*/
public function __construct(
Response $response,
SchemaGeneratorInterface $schemaGenerator,
SerializerInterface $jsonSerializer,
RequestProcessor $requestProcessor,
QueryProcessor $queryProcessor,
ExceptionFormatter $graphQlError,
ResolverContext $context
ResolverContext $context,
HttpRequestProcessor $requestProcessor
) {
$this->response = $response;
$this->schemaGenerator = $schemaGenerator;
$this->jsonSerializer = $jsonSerializer;
$this->requestProcessor = $requestProcessor;
$this->queryProcessor = $queryProcessor;
$this->graphQlError = $graphQlError;
$this->context = $context;
$this->requestProcessor = $requestProcessor;
}

/**
Expand All @@ -82,17 +94,11 @@ public function __construct(
public function dispatch(RequestInterface $request)
{
try {
/** @var $request Http */
if ($request->getHeader('Content-Type')
&& strpos($request->getHeader('Content-Type'), 'application/json') !== false
) {
$content = $request->getContent();
$data = $this->jsonSerializer->unserialize($content);
} else {
throw new LocalizedException(__('Request content type must be application/json'));
}
/** @var Http $request */
$this->requestProcessor->processHeaders($request);
$data = $this->jsonSerializer->unserialize($request->getContent());
$schema = $this->schemaGenerator->generate();
$result = $this->requestProcessor->process(
$result = $this->queryProcessor->process(
$schema,
isset($data['query']) ? $data['query'] : '',
null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\GraphQl\Controller\HttpHeaderProcessor;

use Magento\Framework\GraphQl\HttpHeaderProcessorInterface;
use Magento\Framework\Exception\LocalizedException;

/**
* Processes the "Content-Type" header entry
*/
class ContentTypeProcessor implements HttpHeaderProcessorInterface
{
/**
* Handle the mandatory application/json header
*
* {@inheritDoc}
* @throws LocalizedException
*/
public function processHeaderValue($headerValue)
{
if (!$headerValue || strpos($headerValue, 'application/json') === false) {
throw new LocalizedException(
new \Magento\Framework\Phrase('Request content type must be application/json')
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\GraphQl\Controller\HttpHeaderProcessor;

use Magento\Framework\GraphQl\HttpHeaderProcessorInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;

/**
* Process the "Store" header entry
*/
class StoreProcessor implements HttpHeaderProcessorInterface
{
/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* StoreProcessor constructor.
* @param StoreManagerInterface $storeManager
*/
public function __construct(StoreManagerInterface $storeManager)
{
$this->storeManager = $storeManager;
}

/**
* Handle the value of the store and set the scope
*
* {@inheritDoc}
* @throws NoSuchEntityException
*/
public function processHeaderValue($headerValue)
{
if ($headerValue) {
$storeCode = ltrim(rtrim($headerValue));
$stores = $this->storeManager->getStores(false, true);
if (isset($stores[$storeCode])) {
$this->storeManager->setCurrentStore($storeCode);
} elseif (strtolower($storeCode) !== 'default') {
throw new GraphQlInputException(
new \Magento\Framework\Phrase('Store code %1 does not exist', [$storeCode])
);
}
}
}
}
98 changes: 81 additions & 17 deletions app/code/Magento/GraphQl/Model/EntityAttributeList.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,106 @@
namespace Magento\GraphQl\Model;

use Magento\Eav\Api\AttributeManagementInterface;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Api\AttributeSetRepositoryInterface;
use Magento\Eav\Api\Data\AttributeInterface;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\MetadataServiceInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;

/**
* Iterate through all attribute sets to retrieve attributes for any given entity type
*/
class EntityAttributeList
{
/**
* @var AttributeManagementInterface
*/
private $management;
private $attributeManagement;

/**
* @var EavSetupFactory
* @var AttributeSetRepositoryInterface
*/
private $eavSetupFactory;
private $attributeSetRepository;

/**
* @var EavSetup
* @var SearchCriteriaBuilder
*/
private $eavSetup;
private $searchCriteriaBuilder;

/**
* @param AttributeManagementInterface $management
* @param EavSetupFactory $eavSetupFactory
* @var FilterBuilder
*/
private $filterBuilder;

/**
* @param AttributeManagementInterface $attributeManagement
* @param AttributeSetRepositoryInterface $attributeSetRepository
* @param SearchCriteriaBuilder $searchCriteriaBuilder
* @param FilterBuilder $filterBuilder
*/
public function __construct(
AttributeManagementInterface $management,
EavSetupFactory $eavSetupFactory
AttributeManagementInterface $attributeManagement,
AttributeSetRepositoryInterface $attributeSetRepository,
SearchCriteriaBuilder $searchCriteriaBuilder,
FilterBuilder $filterBuilder
) {
$this->management = $management;
$this->eavSetupFactory = $eavSetupFactory;
$this->eavSetup = $this->eavSetupFactory->create();
$this->attributeManagement = $attributeManagement;
$this->attributeSetRepository = $attributeSetRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->filterBuilder = $filterBuilder;
}

public function getDefaultEntityAttributes(string $entityCode)
/**
* Retrieve all EAV and custom attribute codes from all attribute sets for given entity code.
*
* Returned in the format [$attributeCode => $isSortable] with $isSortable being a boolean value where an attribute
* can be sorted with in a search criteria expression. The metadata service parameter is only required if type has
* custom attributes.
*
* @param string $entityCode
* @param MetadataServiceInterface $metadataService
* @return boolean[]
* @throws GraphQlInputException
*/
public function getDefaultEntityAttributes(string $entityCode, MetadataServiceInterface $metadataService = null)
{
$defaultAttributeSetId = $this->eavSetup->getDefaultAttributeSetId($entityCode);
return $this->management->getAttributes($entityCode, $defaultAttributeSetId);
$this->searchCriteriaBuilder->addFilters(
[
$this->filterBuilder
->setField('entity_type_code')
->setValue($entityCode)
->setConditionType('eq')
->create(),
]
);
$attributeSetList = $this->attributeSetRepository->getList($this->searchCriteriaBuilder->create())->getItems();
$attributes = [];
foreach ($attributeSetList as $attributeSet) {
try {
$attributes = array_merge(
$attributes,
$this->attributeManagement->getAttributes($entityCode, $attributeSet->getAttributeSetId())
);
} catch (NoSuchEntityException $exception) {
throw new GraphQlInputException(__('Entity code %1 does not exist.', [$entityCode]));
}
}
$attributeCodes = [];
$metadata = $metadataService ? $metadataService->getCustomAttributesMetadata() : [];
foreach ($metadata as $customAttribute) {
if (!array_key_exists($customAttribute->getAttributeCode(), $attributeCodes)) {
$attributeCodes[$customAttribute->getAttributeCode()] = false;
}
}
/** @var AttributeInterface $attribute */
foreach ($attributes as $attribute) {
if (!array_key_exists($attribute->getAttributeCode(), $attributeCodes)) {
$attributeCodes[$attribute->getAttributeCode()]
= ((! $attribute->getIsUserDefined()) && !is_array($attribute));
}
}
return $attributeCodes;
}
}
13 changes: 0 additions & 13 deletions app/code/Magento/GraphQl/Model/SchemaGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,6 @@ public function generate()
'fields' => $schemaConfig['fields'],
'resolveField' => function ($value, $args, $context, ResolveInfo $info) {
$fieldName = $info->fieldName;
$fieldNodes = $info->fieldNodes;
$selections = [];
// foreach ($fieldNodes as $fieldNode) {
// foreach ($fieldNode->selectionSet->selections as $field) {
// $name = $field->name;
// if (isset($field->selectionSet)) {
// $selections[$name] = $this->getFields;
// }
// foreach ($field->selectionSet->selections as $selection) {
// $selections[$name] = $selection->name;
// }
// }
// }
$resolver = $this->resolverFactory->create($fieldName);

$fieldArguments = [];
Expand Down
10 changes: 10 additions & 0 deletions app/code/Magento/GraphQl/Model/Type/Handler/Pool/Complex.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ class Complex
*/
private $typeHandlerFactory;

/**
* @param HandlerConfig $typeConfig
* @param HandlerFactory $typeHandlerFactory
*/
public function __construct(HandlerConfig $typeConfig, HandlerFactory $typeHandlerFactory)
{
$this->typeConfig = $typeConfig;
$this->typeHandlerFactory = $typeHandlerFactory;
}

/**
* Retrieve type's configuration based off name
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

/**
* Translate web API service contract layer from array-style schema to GraphQL types
*
* @api
*/
class TypeGenerator
{
Expand Down
1 change: 1 addition & 0 deletions app/code/Magento/GraphQl/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"require": {
"php": "7.0.2|7.0.4|~7.0.6|~7.1.0",
"magento/module-authorization": "100.3.*",
"magento/module-store": "100.3.*",
"magento/module-webapi": "100.3.*",
"magento/module-eav": "100.3.*",
"magento/framework": "100.3.*"
Expand Down
Loading

0 comments on commit 8e3bbd0

Please sign in to comment.