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
  • Loading branch information
lenaorobei authored Aug 15, 2019
2 parents dc47068 + 2c39ba3 commit 2d48fbc
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 = '[email protected]';
Expand Down
Loading

0 comments on commit 2d48fbc

Please sign in to comment.