Skip to content

Commit

Permalink
Refactored Account Mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
nuzil committed Sep 13, 2018
1 parent 8963811 commit d0dd90f
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\Webapi\ServiceOutputProcessor;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Newsletter\Model\SubscriberFactory;
use Magento\Customer\Model\CustomerRegistry;
use Magento\Framework\Encryption\EncryptorInterface as Encryptor;
use Magento\Store\Api\StoreResolverInterface;
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;

/**
* Customer field data provider, used for GraphQL request processing.
Expand All @@ -34,16 +31,6 @@ class CustomerDataProvider
*/
private $serviceOutputProcessor;

/**
* @var StoreResolverInterface
*/
private $storeResolver;

/**
* @var \Magento\Newsletter\Model\SubscriberFactory
*/
protected $subscriberFactory;

/**
* @var CustomerRegistry
*/
Expand All @@ -68,31 +55,14 @@ public function __construct(
CustomerRepositoryInterface $customerRepository,
ServiceOutputProcessor $serviceOutputProcessor,
SerializerInterface $jsonSerializer,
SubscriberFactory $subscriberFactory,
CustomerRegistry $customerRegistry,
Encryptor $encryptor,
StoreResolverInterface $storeResolver
Encryptor $encryptor
) {
$this->customerRepository = $customerRepository;
$this->serviceOutputProcessor = $serviceOutputProcessor;
$this->jsonSerializer = $jsonSerializer;
$this->subscriberFactory = $subscriberFactory;
$this->customerRegistry = $customerRegistry;
$this->encryptor = $encryptor;
$this->storeResolver = $storeResolver;
}

/**
* Load customer object
*
* @param int $customerId
* @return CustomerInterface
* @throws LocalizedException
* @throws NoSuchEntityException
*/
public function loadCustomerById(int $customerId): CustomerInterface
{
return $this->customerRepository->getById($customerId);
}

/**
Expand Down Expand Up @@ -158,82 +128,14 @@ private function processCustomer(CustomerInterface $customerObject): array
}

/**
* Check if customer is subscribed to Newsletter
*
* @param int $customerId
* @return bool
*/
public function isSubscribed(int $customerId): bool
{
$checkSubscriber = $this->subscriberFactory->create()->loadByCustomerId($customerId);
return $checkSubscriber->isSubscribed();
}

/**
* Manage customer subscription. Subscribe OR unsubscribe if required
*
* @param string $password
* @param int $customerId
* @param $newSubscriptionStatus
* @return bool
*/
public function manageSubscription(int $customerId, bool $newSubscriptionStatus): bool
{
$checkSubscriber = $this->subscriberFactory->create()->loadByCustomerId($customerId);
$isSubscribed = $this->isSubscribed($customerId);

if ($newSubscriptionStatus === true && !$isSubscribed) {
$this->subscriberFactory->create()->subscribeCustomerById($customerId);
} elseif ($newSubscriptionStatus === false && $checkSubscriber->isSubscribed()) {
$this->subscriberFactory->create()->unsubscribeCustomerById($customerId);
}
return true;
}

/**
* @param int $customerId
* @param array $customerData
* @return CustomerInterface
* @throws LocalizedException
* @throws NoSuchEntityException
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\State\InputMismatchException
*/
public function updateAccountInformation(int $customerId, array $customerData): CustomerInterface
public function isPasswordCorrect(string $password, int $customerId)
{

$customer = $this->loadCustomerById($customerId);

if (isset($customerData['email'])
&& $customer->getEmail() !== $customerData['email']
&& isset($customerData['password'])) {
if ($this->isPasswordCorrect($customerData['password'], $customerId)) {
$customer->setEmail($customerData['email']);
} else {
throw new GraphQlAuthorizationException(__('Invalid current user password.'));
}
}

if (isset($customerData['firstname'])) {
$customer->setFirstname($customerData['firstname']);
}
if (isset($customerData['lastname'])) {
$customer->setLastname($customerData['lastname']);
}

$customer->setStoreId($this->storeResolver->getCurrentStoreId());
$this->customerRepository->save($customer);

return $customer;
}

private function isPasswordCorrect(string $password, int $customerId)
{

$customerSecure = $this->customerRegistry->retrieveSecureData($customerId);
$hash = $customerSecure->getPasswordHash();
if (!$this->encryptor->validateHash($password, $hash)) {
return false;
}
return true;
$hash = $this->customerRegistry->retrieveSecureData($customerId)->getPasswordHash();
return $this->encryptor->validateHash($password, $hash);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CustomerGraphQl\Model\Resolver\Customer;

use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Store\Api\StoreResolverInterface;
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
use Magento\Newsletter\Model\SubscriberFactory;

/**
* Customer field data provider, used for GraphQL request processing.
*/
class CustomerDataUpdater
{
/**
* @var CustomerRepositoryInterface
*/
private $customerRepository;

/**
* @var \Magento\Newsletter\Model\SubscriberFactory
*/
private $subscriberFactory;

/**
* @var StoreResolverInterface
*/
private $storeResolver;

/**
* @var CustomerDataProvider
*/
private $customerDataProvider;

/**
* CustomerDataUpdater constructor.
* @param CustomerRepositoryInterface $customerRepository
* @param StoreResolverInterface $storeResolver
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
StoreResolverInterface $storeResolver,
CustomerDataProvider $customerDataProvider,
SubscriberFactory $subscriberFactory
) {
$this->customerRepository = $customerRepository;
$this->storeResolver = $storeResolver;
$this->customerDataProvider = $customerDataProvider;
$this->subscriberFactory = $subscriberFactory;
}

/**
* Manage customer subscription. Subscribe OR unsubscribe if required. Return new subscription status
*
* @param int $customerId
* @param $newSubscriptionStatus
* @return bool
*/
public function manageSubscription(int $customerId, bool $newSubscriptionStatus): bool
{
$subscriber = $this->subscriberFactory->create()->loadByCustomerId($customerId);
if ($newSubscriptionStatus === true && !$subscriber->isSubscribed()) {
$this->subscriberFactory->create()->subscribeCustomerById($customerId);
} elseif ($newSubscriptionStatus === false && $subscriber->isSubscribed()) {
$this->subscriberFactory->create()->unsubscribeCustomerById($customerId);
}
/** Load subscribed again to get his new status after update subscription */
$subscriber = $this->subscriberFactory->create()->loadByCustomerId($customerId);
return $subscriber->isSubscribed();
}

/**
* @param int $customerId
* @param array $customerData
* @return CustomerInterface
* @throws GraphQlAuthorizationException
* @throws LocalizedException
* @throws NoSuchEntityException
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\State\InputMismatchException
*/
public function updateAccountInformation(int $customerId, array $customerData): CustomerInterface
{
$customer = $this->customerRepository->getById($customerId);

if (isset($customerData['email'])
&& $customer->getEmail() !== $customerData['email']
&& isset($customerData['password'])) {
if ($this->customerDataProvider->isPasswordCorrect($customerData['password'], $customerId)) {
$customer->setEmail($customerData['email']);
} else {
throw new GraphQlAuthorizationException(__('Invalid current user password.'));
}
}

if (isset($customerData['firstname'])) {
$customer->setFirstname($customerData['firstname']);
}
if (isset($customerData['lastname'])) {
$customer->setLastname($customerData['lastname']);
}

$customer->setStoreId($this->storeResolver->getCurrentStoreId());
$this->customerRepository->save($customer);

return $customer;
}
}
15 changes: 12 additions & 3 deletions app/code/Magento/CustomerGraphQl/Model/Resolver/CustomerUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Magento\Authorization\Model\UserContextInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\CustomerGraphQl\Model\Resolver\Customer\CustomerDataProvider;
use Magento\CustomerGraphQl\Model\Resolver\Customer\CustomerDataUpdater;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
Expand All @@ -27,6 +28,11 @@ class CustomerUpdate implements ResolverInterface
*/
private $customerResolver;

/**
* @var CustomerDataUpdater
*/
private $customerUpdater;

/**
* @var ValueFactory
*/
Expand All @@ -48,12 +54,14 @@ class CustomerUpdate implements ResolverInterface
*/
public function __construct(
CustomerDataProvider $customerResolver,
CustomerDataUpdater $customerUpdater,
ValueFactory $valueFactory,
\Magento\Newsletter\Model\SubscriberFactory $subscriberFactory
) {
$this->customerResolver = $customerResolver;
$this->valueFactory = $valueFactory;
$this->subscriberFactory = $subscriberFactory;
$this->customerUpdater = $customerUpdater;
}

/**
Expand All @@ -77,13 +85,14 @@ public function resolve(
);
}

$this->customerResolver->updateAccountInformation($context->getUserId(), $args);
$customerId = $context->getUserId();
$this->customerUpdater->updateAccountInformation($customerId, $args);
$data = $this->customerResolver->getCustomerById($customerId);

if (isset($args['is_subscribed'])) {
$this->customerResolver->manageSubscription($context->getUserId(), $args['is_subscribed']);
$data['is_subscribed'] = $this->customerUpdater->manageSubscription($customerId, $args['is_subscribed']);
}

$data = $args;
$result = function () use ($data) {
return !empty($data) ? $data : [];
};
Expand Down
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/newsletter": "*",
"magento/framework": "*"
},
"suggest": {
Expand Down
Loading

0 comments on commit d0dd90f

Please sign in to comment.