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

Commit

Permalink
#741: Add extension point to set custom parameters to Query Context o…
Browse files Browse the repository at this point in the history
…bject
  • Loading branch information
naydav committed Jun 13, 2019
1 parent dffe94d commit 3096057
Show file tree
Hide file tree
Showing 14 changed files with 563 additions and 185 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CustomerGraphQl\Model\Context;

use Magento\Authorization\Model\UserContextInterface;
use Magento\GraphQl\Model\Query\ContextParametersInterface;
use Magento\GraphQl\Model\Query\ContextParametersProcessorInterface;

/**
* @inheritdoc
*/
class AddUserInfoToContext implements ContextParametersProcessorInterface
{
/**
* @var UserContextInterface
*/
private $userContext;

/**
* @var GetCustomer
*/
private $getCustomer;

/**
* @param UserContextInterface $userContext
* @param GetCustomer $getCustomer
*/
public function __construct(
UserContextInterface $userContext,
GetCustomer $getCustomer
) {
$this->userContext = $userContext;
$this->getCustomer = $getCustomer;
}

/**
* @inheritdoc
*/
public function execute(ContextParametersInterface $contextParameters): ContextParametersInterface
{
$currentUserId = $this->userContext->getUserId();
if (null !== $currentUserId) {
$currentUserId = (int)$currentUserId;
}

$currentUserType = $this->userContext->getUserType();
if (null !== $currentUserType) {
$currentUserType = (int)$currentUserType;
}

if (false === $this->isUserGuest($currentUserId, $currentUserType)) {
$customer = $this->getCustomer->execute($currentUserId);
$contextParameters->addExtensionAttribute('customer', $customer);
}

$contextParameters->setUserId($currentUserId);
$contextParameters->setUserType($currentUserType);
return $contextParameters;
}

/**
* Checking if current customer is guest
*
* @param int|null $customerId
* @param int|null $customerType
* @return bool
*/
private function isUserGuest(?int $customerId, ?int $customerType): bool
{
if (null === $customerId || null === $customerType) {
return true;
}
return 0 === (int)$customerId || (int)$customerType === UserContextInterface::USER_TYPE_GUEST;
}
}
94 changes: 94 additions & 0 deletions app/code/Magento/CustomerGraphQl/Model/Context/GetCustomer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CustomerGraphQl\Model\Context;

use Magento\Customer\Api\AccountManagementInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Model\AuthenticationInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Exception\GraphQlAuthenticationException;
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;

/**
* Get customer
*/
class GetCustomer
{
/**
* @var AuthenticationInterface
*/
private $authentication;

/**
* @var CustomerRepositoryInterface
*/
private $customerRepository;

/**
* @var AccountManagementInterface
*/
private $accountManagement;

/**
* @param AuthenticationInterface $authentication
* @param CustomerRepositoryInterface $customerRepository
* @param AccountManagementInterface $accountManagement
*/
public function __construct(
AuthenticationInterface $authentication,
CustomerRepositoryInterface $customerRepository,
AccountManagementInterface $accountManagement
) {
$this->authentication = $authentication;
$this->customerRepository = $customerRepository;
$this->accountManagement = $accountManagement;
}

/**
* Get customer
*
* @param int $customerId
* @return void
* @throws GraphQlAuthenticationException
* @throws GraphQlAuthorizationException
* @throws GraphQlInputException
* @throws GraphQlNoSuchEntityException
*/
public function execute(int $customerId): CustomerInterface
{
try {
$customer = $this->customerRepository->getById($customerId);
} catch (NoSuchEntityException $e) {
throw new GraphQlNoSuchEntityException(
__('Customer with id "%customer_id" does not exist.', ['customer_id' => $customerId]),
$e
);
} catch (LocalizedException $e) {
throw new GraphQlInputException(__($e->getMessage()));
}

if (true === $this->authentication->isLocked($customerId)) {
throw new GraphQlAuthenticationException(__('The account is locked.'));
}

try {
$confirmationStatus = $this->accountManagement->getConfirmationStatus($customerId);
} catch (LocalizedException $e) {
throw new GraphQlInputException(__($e->getMessage()));
}

if ($confirmationStatus === AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED) {
throw new GraphQlAuthenticationException(__("This account isn't confirmed. Verify and try again."));
}
return $customer;
}
}
7 changes: 7 additions & 0 deletions app/code/Magento/CustomerGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@
</argument>
</arguments>
</type>
<type name="Magento\GraphQl\Model\Query\ContextFactory">
<arguments>
<argument name="contextParametersProcessors" xsi:type="array">
<item name="add_customer_to_context" xsi:type="object">Magento\CustomerGraphQl\Model\Context\AddUserInfoToContext</item>
</argument>
</arguments>
</type>
</config>
14 changes: 7 additions & 7 deletions app/code/Magento/GraphQl/Controller/GraphQl.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\GraphQl\Exception\ExceptionFormatter;
use Magento\Framework\GraphQl\Query\QueryProcessor;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
use Magento\Framework\GraphQl\Schema\SchemaGeneratorInterface;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\Webapi\Response;
use Magento\Framework\App\Response\Http as HttpResponse;
use Magento\Framework\GraphQl\Query\Fields as QueryFields;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\App\ObjectManager;
use Magento\GraphQl\Model\Query\ContextFactoryInterface;

/**
* Front controller for web API GraphQL area.
Expand Down Expand Up @@ -57,9 +57,9 @@ class GraphQl implements FrontControllerInterface
private $graphQlError;

/**
* @var ContextInterface
* @var ContextFactoryInterface
*/
private $resolverContext;
private $contextFactory;

/**
* @var HttpRequestProcessor
Expand Down Expand Up @@ -87,7 +87,7 @@ class GraphQl implements FrontControllerInterface
* @param SerializerInterface $jsonSerializer
* @param QueryProcessor $queryProcessor
* @param ExceptionFormatter $graphQlError
* @param ContextInterface $resolverContext
* @param ContextFactoryInterface $contextFactory
* @param HttpRequestProcessor $requestProcessor
* @param QueryFields $queryFields
* @param JsonFactory|null $jsonFactory
Expand All @@ -100,7 +100,7 @@ public function __construct(
SerializerInterface $jsonSerializer,
QueryProcessor $queryProcessor,
ExceptionFormatter $graphQlError,
ContextInterface $resolverContext,
ContextFactoryInterface $contextFactory,
HttpRequestProcessor $requestProcessor,
QueryFields $queryFields,
JsonFactory $jsonFactory = null,
Expand All @@ -111,7 +111,7 @@ public function __construct(
$this->jsonSerializer = $jsonSerializer;
$this->queryProcessor = $queryProcessor;
$this->graphQlError = $graphQlError;
$this->resolverContext = $resolverContext;
$this->contextFactory = $contextFactory;
$this->requestProcessor = $requestProcessor;
$this->queryFields = $queryFields;
$this->jsonFactory = $jsonFactory ?: ObjectManager::getInstance()->get(JsonFactory::class);
Expand Down Expand Up @@ -144,7 +144,7 @@ public function dispatch(RequestInterface $request) : ResponseInterface
$result = $this->queryProcessor->process(
$schema,
$query,
$this->resolverContext,
$this->contextFactory->create(),
$data['variables'] ?? []
);
} catch (\Exception $error) {
Expand Down
72 changes: 72 additions & 0 deletions app/code/Magento/GraphQl/Model/Query/Context.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\Model\Query;

/**
* Concrete implementation for @see ContextInterface
*
* The purpose for this that GraphQL specification wants to make use of such object where multiple modules can
* participate with data through extension attributes.
*/
class Context implements ContextInterface
{
/**
* @var int|null
*/
private $userType;

/**
* @var int|null
*/
private $userId;

/**
* @var ContextExtensionInterface
*/
private $extensionAttributes;

/**
* @param int|null $userType
* @param int|null $userId
* @param ContextExtensionInterface $extensionAttributes
*/
public function __construct(
?int $userType,
?int $userId,
ContextExtensionInterface $extensionAttributes
) {
$this->userType = $userType;
$this->userId = $userId;
$this->extensionAttributes = $extensionAttributes;
}


/**
* @inheritdoc
*/
public function getUserType(): ?int
{
return $this->userType;
}

/**
* @inheritdoc
*/
public function getUserId(): ?int
{
return $this->userId;
}

/**
* @inheritdoc
*/
public function getExtensionAttributes(): ContextExtensionInterface
{
return $this->extensionAttributes;
}
}
Loading

0 comments on commit 3096057

Please sign in to comment.