Skip to content
This repository has been archived by the owner on May 20, 2019. It is now read-only.

Commit

Permalink
Merge pull request #3183 from magento-engcom/graphql-develop-prs
Browse files Browse the repository at this point in the history
[EngCom] Public Pull Requests - GraphQL
  • Loading branch information
Valeriy Naida authored Sep 18, 2018
2 parents 5f643ef + a633590 commit 43dca41
Show file tree
Hide file tree
Showing 13 changed files with 340 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogGraphQl\Model\Resolver\Product;

use Magento\Catalog\Model\Product;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Catalog\Helper\Output as OutputHelper;

/**
* Resolve rendered content for attributes where HTML content is allowed
*/
class ProductHtmlAttribute 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 GraphQlInputException(__('"model" value should be specified'));
}

/* @var $product Product */
$product = $value['model'];
$fieldName = $field->getName();
$renderedValue = $this->outputHelper->productAttribute($product, $product->getData($fieldName), $fieldName);
return $renderedValue;
}
}
6 changes: 3 additions & 3 deletions app/code/Magento/CatalogGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\
id: Int @doc(description: "The ID number assigned to the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\EntityIdToId")
name: String @doc(description: "The product name. Customers use this name to identify the product.")
sku: String @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer")
description: String @doc(description: "Detailed information about the product. The value can include simple HTML tags.")
short_description: String @doc(description: "A short description of the product. Its use depends on the theme.")
description: String @doc(description: "Detailed information about the product. The value can include simple HTML tags.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductHtmlAttribute")
short_description: String @doc(description: "A short description of the product. Its use depends on the theme.") @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductHtmlAttribute")
special_price: Float @doc(description: "The discounted price of the product")
special_from_date: String @doc(description: "The beginning date that a product has a special price")
special_to_date: String @doc(description: "The end date that a product has a special price")
Expand Down Expand Up @@ -548,6 +548,6 @@ type SortField {
}

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")
default: String @doc(description: "Default value of sort fields")
options: [SortField] @doc(description: "Available sort fields")
}
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\CustomerGraphQl\Model\Resolver\Customer\Account;

use Magento\Framework\Exception\AuthenticationException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Integration\Api\CustomerTokenServiceInterface;

/**
* Customers Token resolver, used for GraphQL request processing.
*/
class GenerateCustomerToken implements ResolverInterface
{
/**
* @var CustomerTokenServiceInterface
*/
private $customerTokenService;

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

/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
try {
if (!isset($args['email'])) {
throw new GraphQlInputException(__('"email" value should be specified'));
}
if (!isset($args['password'])) {
throw new GraphQlInputException(__('"password" value should be specified'));
}
$token = $this->customerTokenService->createCustomerAccessToken($args['email'], $args['password']);
return ['token' => $token];
} catch (AuthenticationException $e) {
throw new GraphQlAuthorizationException(
__($e->getMessage())
);
}
}
}
1 change: 1 addition & 0 deletions app/code/Magento/CustomerGraphQl/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"php": "~7.1.3||~7.2.0",
"magento/module-customer": "*",
"magento/module-authorization": "*",
"magento/module-integration": "*",
"magento/framework": "*"
},
"suggest": {
Expand Down
8 changes: 8 additions & 0 deletions app/code/Magento/CustomerGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ type Query {
customer: Customer @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\Customer") @doc(description: "The customer query returns information about a customer account")
}

type Mutation {
generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\Customer\\Account\\GenerateCustomerToken") @doc(description:"Retrieve Customer token")
}

type CustomerToken {
token: String @doc(description: "The customer token")
}

type Customer @doc(description: "Customer defines the customer name and address and other details") {
created_at: String @doc(description: "Timestamp indicating when the account was created")
group_id: Int @doc(description: "The group assigned to the user. Default values are 0 (Not logged in), 1 (General), 2 (Wholesale), and 3 (Retailer)")
Expand Down
3 changes: 3 additions & 0 deletions app/code/Magento/Quote/Model/MaskedQuoteIdToQuoteId.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\ResourceModel\Quote\QuoteIdMask as QuoteIdMaskResource;

/**
* MaskedQuoteId to QuoteId resolver
*/
class MaskedQuoteIdToQuoteId implements MaskedQuoteIdToQuoteIdInterface
{
/**
Expand Down
20 changes: 16 additions & 4 deletions app/code/Magento/Quote/Model/QuoteIdToMaskedQuoteId.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,40 @@
namespace Magento\Quote\Model;

use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\ResourceModel\Quote\QuoteIdMask as QuoteIdMaskResource;

/**
* QuoteId to MaskedQuoteId resolver
*/
class QuoteIdToMaskedQuoteId implements QuoteIdToMaskedQuoteIdInterface
{
/**
* @var QuoteIdMaskFactory
*/
private $quoteIdMaskFactory;

/**
* @var CartRepositoryInterface
*/
private $cartRepository;

/**
* @var QuoteIdMaskResource
*/
private $quoteIdMaskResource;

/**
* @param QuoteIdMaskFactory $quoteIdMaskFactory
* @param CartRepositoryInterface $cartRepository
* @param QuoteIdMaskResource $quoteIdMaskResource
*/
public function __construct(
QuoteIdMaskFactory $quoteIdMaskFactory,
CartRepositoryInterface $cartRepository
CartRepositoryInterface $cartRepository,
QuoteIdMaskResource $quoteIdMaskResource
) {
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
$this->cartRepository = $cartRepository;
$this->quoteIdMaskResource = $quoteIdMaskResource;
}

/**
Expand All @@ -42,8 +53,9 @@ public function execute(int $quoteId): string
$this->cartRepository->get($quoteId);

$quoteIdMask = $this->quoteIdMaskFactory->create();
$quoteIdMask->setQuoteId($quoteId)->save();
$this->quoteIdMaskResource->load($quoteIdMask, $quoteId, 'quote_id');
$maskedId = $quoteIdMask->getMaskedId() ?? '';

return $quoteIdMask->getMaskedId();
return $maskedId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Magento\Quote\Api\CartManagementInterface;
use Magento\Quote\Api\GuestCartManagementInterface;
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;
use Magento\Quote\Model\QuoteIdMaskFactory;

/**
* @inheritdoc
Expand All @@ -24,7 +25,6 @@ class CreateEmptyCart implements ResolverInterface
* @var CartManagementInterface
*/
private $cartManagement;

/**
* @var GuestCartManagementInterface
*/
Expand All @@ -40,22 +40,30 @@ class CreateEmptyCart implements ResolverInterface
*/
private $userContext;

/**
* @var QuoteIdMaskFactory
*/
private $quoteIdMaskFactory;

/**
* @param CartManagementInterface $cartManagement
* @param GuestCartManagementInterface $guestCartManagement
* @param UserContextInterface $userContext
* @param QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedId
* @param QuoteIdMaskFactory $quoteIdMaskFactory
*/
public function __construct(
CartManagementInterface $cartManagement,
GuestCartManagementInterface $guestCartManagement,
UserContextInterface $userContext,
QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedId
QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedId,
QuoteIdMaskFactory $quoteIdMaskFactory
) {
$this->cartManagement = $cartManagement;
$this->guestCartManagement = $guestCartManagement;
$this->userContext = $userContext;
$this->quoteIdToMaskedId = $quoteIdToMaskedId;
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
}

/**
Expand All @@ -67,7 +75,13 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value

if (0 !== $customerId && null !== $customerId) {
$quoteId = $this->cartManagement->createEmptyCartForCustomer($customerId);
$maskedQuoteId = $this->quoteIdToMaskedId->execute($quoteId);
$maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$quoteId);

if (empty($maskedQuoteId)) {
$quoteIdMask = $this->quoteIdMaskFactory->create();
$quoteIdMask->setQuoteId($quoteId)->save();
$maskedQuoteId = $quoteIdMask->getMaskedId();
}
} else {
$maskedQuoteId = $this->guestCartManagement->createEmptyCart();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function resolve(
if ($urlRewrite) {
$result = [
'id' => $urlRewrite->getEntityId(),
'canonical_url' => $urlRewrite->getTargetPath(),
'relative_url' => $urlRewrite->getTargetPath(),
'type' => $this->sanitizeType($urlRewrite->getEntityType())
];
}
Expand Down
6 changes: 3 additions & 3 deletions app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Copyright © Magento, Inc. All rights reserved.
# See COPYING.txt for license details.

type EntityUrl @doc(description: "EntityUrl is an output object containing the `id`, `canonical_url`, and `type` attributes") {
type EntityUrl @doc(description: "EntityUrl is an output object containing the `id`, `relative_url`, and `type` attributes") {
id: Int @doc(description: "The ID assigned to the object associated with the specified url. This could be a product ID, category ID, or page ID.")
canonical_url: String @doc(description: "The internal relative URL. If the specified url is a redirect, the query returns the redirected URL, not the original.")
relative_url: String @doc(description: "The internal relative URL. If the specified url is a redirect, the query returns the redirected URL, not the original.")
type: UrlRewriteEntityTypeEnum @doc(description: "One of PRODUCT, CATEGORY, or CMS_PAGE.")
}

type Query {
urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") @doc(description: "The urlResolver query returns the canonical URL for a specified product, category or CMS page")
urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") @doc(description: "The urlResolver query returns the relative URL for a specified product, category or CMS page")
}

enum UrlRewriteEntityTypeEnum {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\Catalog;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\TestFramework\ObjectManager;
use Magento\TestFramework\TestCase\GraphQlAbstract;

/**
* Test for checking that product fields with directives allowed are rendered correctly
*/
class ProductWithDescriptionDirectivesTest extends GraphQlAbstract
{
/**
* @var \Magento\TestFramework\ObjectManager
*/
private $objectManager;

protected function setUp()
{
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
}

/**
* @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
* @magentoApiDataFixture Magento/Cms/_files/block.php
*/
public function testHtmlDirectivesRendered()
{
$productSku = 'simple';
$cmsBlockId = 'fixture_block';
$assertionCmsBlockText = 'Fixture Block Title';

/** @var ProductRepositoryInterface $productRepository */
$productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
/** @var ProductInterface $product */
$product = $productRepository->get($productSku, false, null, true);
$product->setDescription('Test: {{block id="' . $cmsBlockId . '"}}');
$product->setShortDescription('Test: {{block id="' . $cmsBlockId . '"}}');
$productRepository->save($product);

$query = <<<QUERY
{
products(filter: {sku: {eq: "{$productSku}"}}) {
items {
description
short_description
}
}
}
QUERY;
$response = $this->graphQlQuery($query);

self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['description']);
self::assertNotContains('{{block id', $response['products']['items'][0]['description']);
self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['short_description']);
self::assertNotContains('{{block id', $response['products']['items'][0]['short_description']);
}
}
Loading

0 comments on commit 43dca41

Please sign in to comment.