Skip to content

Commit

Permalink
ENGCOM-5606: magento#271 [My Account] Add support of Customer attribu…
Browse files Browse the repository at this point in the history
…tes magento#489

 - Merge Pull Request magento/graphql-ce#489 from magento/graphql-ce:feature/271-Customer-Attributes-Validation
 - Merged commits:
   1. dba9800
   2. 7f6718d
   3. 3735e91
   4. 342675a
   5. e177801
   6. 9b5b0a1
   7. 9f1ba1a
   8. 670116c
   9. 40e2363
   10. d071027
   11. b4db736
   12. 4b7acdc
   13. 48f1891
   14. 3641627
   15. ef078b6
   16. 1c65121
   17. cc69055
   18. 7ee6a1a
   19. f358267
   20. eb48f44
   21. 2eb7c15
   22. 7ca7acc
   23. 1c30336
   24. 4382c3a
   25. da8d6ac
   26. 0b4c496
   27. 5ae0633
  • Loading branch information
magento-engcom-team committed Aug 12, 2019
2 parents c6427d1 + 5ae0633 commit 2c39ba3
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Magento\Framework\Api\DataObjectHelper;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\Reflection\DataObjectProcessor;
use Magento\Store\Api\Data\StoreInterface;

/**
Expand Down Expand Up @@ -41,21 +42,39 @@ class CreateCustomerAccount
private $changeSubscriptionStatus;

/**
* @var ValidateCustomerData
*/
private $validateCustomerData;

/**
* @var DataObjectProcessor
*/
private $dataObjectProcessor;

/**
* CreateCustomerAccount constructor.
*
* @param DataObjectHelper $dataObjectHelper
* @param CustomerInterfaceFactory $customerFactory
* @param AccountManagementInterface $accountManagement
* @param ChangeSubscriptionStatus $changeSubscriptionStatus
* @param DataObjectProcessor $dataObjectProcessor
* @param ValidateCustomerData $validateCustomerData
*/
public function __construct(
DataObjectHelper $dataObjectHelper,
CustomerInterfaceFactory $customerFactory,
AccountManagementInterface $accountManagement,
ChangeSubscriptionStatus $changeSubscriptionStatus
ChangeSubscriptionStatus $changeSubscriptionStatus,
DataObjectProcessor $dataObjectProcessor,
ValidateCustomerData $validateCustomerData
) {
$this->dataObjectHelper = $dataObjectHelper;
$this->customerFactory = $customerFactory;
$this->accountManagement = $accountManagement;
$this->changeSubscriptionStatus = $changeSubscriptionStatus;
$this->validateCustomerData = $validateCustomerData;
$this->dataObjectProcessor = $dataObjectProcessor;
}

/**
Expand Down Expand Up @@ -91,6 +110,15 @@ public function execute(array $data, StoreInterface $store): CustomerInterface
private function createAccount(array $data, StoreInterface $store): CustomerInterface
{
$customerDataObject = $this->customerFactory->create();
/**
* Add required attributes for customer entity
*/
$requiredDataAttributes = $this->dataObjectProcessor->buildOutputDataArray(
$customerDataObject,
CustomerInterface::class
);
$data = array_merge($requiredDataAttributes, $data);
$this->validateCustomerData->execute($data);
$this->dataObjectHelper->populateWithArray(
$customerDataObject,
$data,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CustomerGraphQl\Model\Customer;

use Magento\Customer\Api\CustomerMetadataManagementInterface;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Api\Data\CustomerInterfaceFactory;
use Magento\Eav\Model\AttributeRepository;
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Exception\InputException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\Reflection\DataObjectProcessor;

/**
* Get allowed address attributes
*/
class GetAllowedCustomerAttributes
{
/**
* @var AttributeRepository
*/
private $attributeRepository;

/**
* @var CustomerInterfaceFactory\
*/
private $customerDataFactory;

/**
* @var DataObjectProcessor
*/
private $dataObjectProcessor;

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

/**
* GetAllowedCustomerAttributes constructor.
*
* @param AttributeRepository $attributeRepository
* @param CustomerInterfaceFactory $customerDataFactory
* @param DataObjectProcessor $dataObjectProcessor
* @param SearchCriteriaBuilder $searchCriteriaBuilder
*/
public function __construct(
AttributeRepository $attributeRepository,
CustomerInterfaceFactory $customerDataFactory,
DataObjectProcessor $dataObjectProcessor,
SearchCriteriaBuilder $searchCriteriaBuilder
) {
$this->attributeRepository = $attributeRepository;
$this->customerDataFactory = $customerDataFactory;
$this->dataObjectProcessor = $dataObjectProcessor;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
}

/**
* Get allowed customer attributes
*
* @param array $attributeKeys
*
* @throws GraphQlInputException
*
* @return AbstractAttribute[]
*/
public function execute($attributeKeys): array
{
$this->searchCriteriaBuilder->addFilter('attribute_code', $attributeKeys, 'in');
$searchCriteria = $this->searchCriteriaBuilder->create();
try {
$attributesSearchResult = $this->attributeRepository->getList(
CustomerMetadataManagementInterface::ENTITY_TYPE_CUSTOMER,
$searchCriteria
);
} catch (InputException $exception) {
throw new GraphQlInputException(__($exception->getMessage()));
}

/** @var AbstractAttribute[] $attributes */
$attributes = $attributesSearchResult->getItems();

foreach ($attributes as $index => $attribute) {
if (false === $attribute->getIsVisibleOnFront()) {
unset($attributes[$index]);
}
}

return $attributes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

namespace Magento\CustomerGraphQl\Model\Customer;

use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\GraphQl\Exception\GraphQlAlreadyExistsException;
use Magento\Framework\GraphQl\Exception\GraphQlAuthenticationException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\Api\DataObjectHelper;
use Magento\Store\Api\Data\StoreInterface;

Expand Down Expand Up @@ -41,6 +43,11 @@ class UpdateCustomerAccount
*/
private $changeSubscriptionStatus;

/**
* @var ValidateCustomerData
*/
private $validateCustomerData;

/**
* @var array
*/
Expand All @@ -51,24 +58,27 @@ class UpdateCustomerAccount
* @param CheckCustomerPassword $checkCustomerPassword
* @param DataObjectHelper $dataObjectHelper
* @param ChangeSubscriptionStatus $changeSubscriptionStatus
* @param ValidateCustomerData $validateCustomerData
* @param array $restrictedKeys
*/
public function __construct(
SaveCustomer $saveCustomer,
CheckCustomerPassword $checkCustomerPassword,
DataObjectHelper $dataObjectHelper,
ChangeSubscriptionStatus $changeSubscriptionStatus,
ValidateCustomerData $validateCustomerData,
array $restrictedKeys = []
) {
$this->saveCustomer = $saveCustomer;
$this->checkCustomerPassword = $checkCustomerPassword;
$this->dataObjectHelper = $dataObjectHelper;
$this->restrictedKeys = $restrictedKeys;
$this->changeSubscriptionStatus = $changeSubscriptionStatus;
$this->validateCustomerData = $validateCustomerData;
}

/**
* Update customer account data
* Update customer account
*
* @param CustomerInterface $customer
* @param array $data
Expand All @@ -77,7 +87,7 @@ public function __construct(
* @throws GraphQlAlreadyExistsException
* @throws GraphQlAuthenticationException
* @throws GraphQlInputException
* @throws \Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException
* @throws GraphQlNoSuchEntityException
*/
public function execute(CustomerInterface $customer, array $data, StoreInterface $store): void
{
Expand All @@ -89,11 +99,15 @@ public function execute(CustomerInterface $customer, array $data, StoreInterface
$this->checkCustomerPassword->execute($data['password'], (int)$customer->getId());
$customer->setEmail($data['email']);
}

$this->validateCustomerData->execute($data);
$filteredData = array_diff_key($data, array_flip($this->restrictedKeys));
$this->dataObjectHelper->populateWithArray($customer, $filteredData, CustomerInterface::class);

$customer->setStoreId($store->getId());
try {
$customer->setStoreId($store->getId());
} catch (NoSuchEntityException $exception) {
throw new GraphQlNoSuchEntityException(__($exception->getMessage()), $exception);
}

$this->saveCustomer->execute($customer);

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

namespace Magento\CustomerGraphQl\Model\Customer;

use Magento\Framework\GraphQl\Exception\GraphQlInputException;

/**
* Class ValidateCustomerData
*/
class ValidateCustomerData
{
/**
* Get allowed/required customer attributes
*
* @var GetAllowedCustomerAttributes
*/
private $getAllowedCustomerAttributes;

/**
* ValidateCustomerData constructor.
*
* @param GetAllowedCustomerAttributes $getAllowedCustomerAttributes
*/
public function __construct(GetAllowedCustomerAttributes $getAllowedCustomerAttributes)
{
$this->getAllowedCustomerAttributes = $getAllowedCustomerAttributes;
}

/**
* Validate customer data
*
* @param array $customerData
*
* @return void
*
* @throws GraphQlInputException
*/
public function execute(array $customerData): void
{
$attributes = $this->getAllowedCustomerAttributes->execute(array_keys($customerData));
$errorInput = [];

foreach ($attributes as $attributeInfo) {
if ($attributeInfo->getIsRequired()
&& (!isset($customerData[$attributeInfo->getAttributeCode()])
|| $customerData[$attributeInfo->getAttributeCode()] == '')
) {
$errorInput[] = $attributeInfo->getDefaultFrontendLabel();
}
}

if ($errorInput) {
throw new GraphQlInputException(
__('Required parameters are missing: %1', [implode(', ', $errorInput)])
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public function testCreateCustomerIfInputDataIsEmpty()

/**
* @expectedException \Exception
* @expectedExceptionMessage The customer email is missing. Enter and try again.
* @expectedExceptionMessage Required parameters are missing: Email
*/
public function testCreateCustomerIfEmailMissed()
{
Expand Down Expand Up @@ -241,6 +241,41 @@ public function testCreateCustomerIfPassedAttributeDosNotExistsInCustomerInput()
$this->graphQlMutation($query);
}

/**
* @expectedException \Exception
* @expectedExceptionMessage Required parameters are missing: First Name
*/
public function testCreateCustomerIfNameEmpty()
{
$newEmail = 'customer_created' . rand(1, 2000000) . '@example.com';
$newFirstname = '';
$newLastname = 'Rowe';
$currentPassword = 'test123#';

$query = <<<QUERY
mutation {
createCustomer(
input: {
email: "{$newEmail}"
firstname: "{$newFirstname}"
lastname: "{$newLastname}"
password: "{$currentPassword}"
is_subscribed: true
}
) {
customer {
id
firstname
lastname
email
is_subscribed
}
}
}
QUERY;
$this->graphQlMutation($query);
}

public function tearDown()
{
$newEmail = 'new_customer@example.com';
Expand Down
Loading

0 comments on commit 2c39ba3

Please sign in to comment.