diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/CreateCustomerAccount.php b/app/code/Magento/CustomerGraphQl/Model/Customer/CreateCustomerAccount.php index eada473b61e1..969c205329f2 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/CreateCustomerAccount.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/CreateCustomerAccount.php @@ -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; /** @@ -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; } /** @@ -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, diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/GetAllowedCustomerAttributes.php b/app/code/Magento/CustomerGraphQl/Model/Customer/GetAllowedCustomerAttributes.php new file mode 100644 index 000000000000..aada79aa016b --- /dev/null +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/GetAllowedCustomerAttributes.php @@ -0,0 +1,98 @@ +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; + } +} diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateCustomerAccount.php b/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateCustomerAccount.php index 51d47eaf0d04..f7bf26513dc2 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateCustomerAccount.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/UpdateCustomerAccount.php @@ -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; @@ -41,6 +43,11 @@ class UpdateCustomerAccount */ private $changeSubscriptionStatus; + /** + * @var ValidateCustomerData + */ + private $validateCustomerData; + /** * @var array */ @@ -51,6 +58,7 @@ class UpdateCustomerAccount * @param CheckCustomerPassword $checkCustomerPassword * @param DataObjectHelper $dataObjectHelper * @param ChangeSubscriptionStatus $changeSubscriptionStatus + * @param ValidateCustomerData $validateCustomerData * @param array $restrictedKeys */ public function __construct( @@ -58,6 +66,7 @@ public function __construct( CheckCustomerPassword $checkCustomerPassword, DataObjectHelper $dataObjectHelper, ChangeSubscriptionStatus $changeSubscriptionStatus, + ValidateCustomerData $validateCustomerData, array $restrictedKeys = [] ) { $this->saveCustomer = $saveCustomer; @@ -65,10 +74,11 @@ public function __construct( $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 @@ -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 { @@ -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); diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/ValidateCustomerData.php b/app/code/Magento/CustomerGraphQl/Model/Customer/ValidateCustomerData.php new file mode 100644 index 000000000000..794cb0048592 --- /dev/null +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/ValidateCustomerData.php @@ -0,0 +1,63 @@ +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)]) + ); + } + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php index fc51f57a83a7..67c21a3798a5 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php @@ -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() { @@ -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 = <<graphQlMutation($query); + } + public function tearDown() { $newEmail = 'new_customer@example.com'; diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php index 7b1f3a67a119..178d10b3c35a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php @@ -253,6 +253,8 @@ public function testUpdateEmailIfEmailAlreadyExists() $currentEmail = 'customer@example.com'; $currentPassword = 'password'; $existedEmail = 'customer_two@example.com'; + $firstname = 'Richard'; + $lastname = 'Rowe'; $query = <<graphQlMutation($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @expectedException \Exception + * @expectedExceptionMessage Required parameters are missing: First Name + */ + public function testEmptyCustomerName() + { + $currentEmail = 'customer@example.com'; + $currentPassword = 'password'; + + $query = <<graphQlMutation($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); + } + /** * @param string $email * @param string $password