diff --git a/README.md b/README.md index e4494199..6b132fac 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ composer require spryker/customer ## Documentation -[Module Documentation](http://academy.spryker.com/developing_with_spryker/module_guide/customer_management/customer/customer.html) +[Module Documentation](https://academy.spryker.com/developing_with_spryker/module_guide/customer_management/customer/customer.html) diff --git a/composer.json b/composer.json index 1132e9ba..0a398d81 100644 --- a/composer.json +++ b/composer.json @@ -8,12 +8,14 @@ "spryker/kernel": "^3.0.0", "spryker/locale": "^3.0.0", "spryker/mail": "^4.0.0", - "spryker/propel-orm": "^1.0.0", + "spryker/propel-orm": "^1.5.0", "spryker/sequence-number": "^3.0.0", "spryker/session": "^3.0.0", "spryker/symfony": "^3.0.0", "spryker/util-date-time": "^1.0.0", + "spryker/util-sanitize": "^2.0.0", "spryker/util-text": "^1.1.0", + "spryker/util-validate": "^1.0.0", "spryker/zed-request": "^3.0.0" }, "require-dev": { @@ -36,7 +38,7 @@ "autoload": { "psr-4": { "Spryker\\": "src/Spryker/", - "SprykerTest\\Shared\\Customer\\": "tests/SprykerTest/Shared/Customer/_support/Helper/" + "SprykerTest\\Shared\\Customer\\Helper\\": "tests/SprykerTest/Shared/Customer/_support/Helper/" } }, "autoload-dev": { diff --git a/src/Spryker/Client/Customer/CustomerClient.php b/src/Spryker/Client/Customer/CustomerClient.php index 3d24671b..30e2ea2a 100644 --- a/src/Spryker/Client/Customer/CustomerClient.php +++ b/src/Spryker/Client/Customer/CustomerClient.php @@ -17,27 +17,8 @@ class CustomerClient extends AbstractClient implements CustomerClientInterface { /** - * @api - * - * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer + * {@inheritdoc} * - * @return bool - */ - public function hasCustomerWithEmailAndPassword(CustomerTransfer $customerTransfer) - { - $customerResponseTransfer = $this->getFactory() - ->createZedCustomerStub() - ->hasCustomerWithEmailAndPassword($customerTransfer); - - $hasCustomer = $customerResponseTransfer->getHasCustomer(); - if ($hasCustomer === true) { - $this->setCustomer($customerResponseTransfer->getCustomerTransfer()); - } - - return $hasCustomer; - } - - /** * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -54,6 +35,8 @@ public function findCustomerWithEmailAndPassword(CustomerTransfer $customerTrans } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -68,6 +51,8 @@ public function registerCustomer(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -82,6 +67,8 @@ public function confirmRegistration(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -96,6 +83,8 @@ public function sendPasswordRestoreMail(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -110,6 +99,8 @@ public function restorePassword(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -126,6 +117,8 @@ public function setCustomer(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @return \Generated\Shared\Transfer\CustomerTransfer @@ -140,6 +133,8 @@ public function getCustomer() } /** + * {@inheritdoc} + * * @api * * @param int $idCustomer @@ -179,6 +174,8 @@ public function findCustomerById(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -195,6 +192,8 @@ public function getCustomerByEmail(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -209,6 +208,8 @@ public function updateCustomer(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -223,6 +224,8 @@ public function updateCustomerPassword(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -237,6 +240,8 @@ public function deleteCustomer(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -257,6 +262,8 @@ public function login(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @return void @@ -269,6 +276,8 @@ public function logout() } /** + * {@inheritdoc} + * * @api * * @return bool @@ -281,6 +290,8 @@ public function isLoggedIn() } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -295,6 +306,8 @@ public function getAddresses(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -309,6 +322,8 @@ public function getAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -323,6 +338,8 @@ public function updateAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -337,6 +354,8 @@ public function updateAddressAndCustomerDefaultAddresses(AddressTransfer $addres } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -351,6 +370,8 @@ public function createAddressAndUpdateCustomerDefaultAddresses(AddressTransfer $ } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -365,6 +386,8 @@ public function createAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -379,6 +402,8 @@ public function deleteAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -393,6 +418,8 @@ public function setDefaultShippingAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -407,6 +434,8 @@ public function setDefaultBillingAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer diff --git a/src/Spryker/Client/Customer/CustomerClientInterface.php b/src/Spryker/Client/Customer/CustomerClientInterface.php index 7037d6a9..714af97b 100644 --- a/src/Spryker/Client/Customer/CustomerClientInterface.php +++ b/src/Spryker/Client/Customer/CustomerClientInterface.php @@ -13,15 +13,9 @@ interface CustomerClientInterface { /** - * @api - * - * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer + * Specification: + * - Checks if customer exists in persistent storage by provided email and plain text password. * - * @return bool - */ - public function hasCustomerWithEmailAndPassword(CustomerTransfer $customerTransfer); - - /** * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -31,6 +25,15 @@ public function hasCustomerWithEmailAndPassword(CustomerTransfer $customerTransf public function findCustomerWithEmailAndPassword(CustomerTransfer $customerTransfer); /** + * Specification: + * - Validates provided customer email information. + * - Encrypts provided plain text password. + * - Assigns current locale to customer if it is not set already. + * - Generates customer reference for customer. + * - Stores customer data. + * - Sends specific registration confirmation link via email using a freshly generated registration key. + * - Sends password restoration email if SendPasswordToken property is set in the provided transfer object. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -40,6 +43,10 @@ public function findCustomerWithEmailAndPassword(CustomerTransfer $customerTrans public function registerCustomer(CustomerTransfer $customerTransfer); /** + * Specification: + * - Finds customer registration confirmation by provided registration key. + * - Sets customer as registered and removes the registration key from persistent storage. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -49,6 +56,9 @@ public function registerCustomer(CustomerTransfer $customerTransfer); public function confirmRegistration(CustomerTransfer $customerTransfer); /** + * Specification: + * - Sends password restoration link via email using a freshly generated password restoration key. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -58,6 +68,13 @@ public function confirmRegistration(CustomerTransfer $customerTransfer); public function sendPasswordRestoreMail(CustomerTransfer $customerTransfer); /** + * Specification: + * - Identifies customer by either customer ID, customer email, or password restoration key. + * - Encrypts provided plain text password. + * - Stores new password for customer in persistent storage. + * - Removes password restoration key from customer. + * - Sends password restoration confirmation email. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -67,6 +84,10 @@ public function sendPasswordRestoreMail(CustomerTransfer $customerTransfer); public function restorePassword(CustomerTransfer $customerTransfer); /** + * Specification: + * - Deletes a customer entity by either customer ID, customer email, or password restoration key. + * - Does not handle related connected entities. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -77,7 +98,7 @@ public function deleteCustomer(CustomerTransfer $customerTransfer); /** * Specification: - * - Returns Customer data from session + * - Returns customer information from session. * * @api * @@ -86,6 +107,9 @@ public function deleteCustomer(CustomerTransfer $customerTransfer); public function getCustomer(); /** + * Specification: + * - Stores provided customer information in session. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -95,6 +119,10 @@ public function getCustomer(); public function setCustomer(CustomerTransfer $customerTransfer); /** + * Specification: + * - Checks if customer exists in persistent storage by provided email and plain text password. + * - Stores found customer information in session. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -104,6 +132,9 @@ public function setCustomer(CustomerTransfer $customerTransfer); public function login(CustomerTransfer $customerTransfer); /** + * Specification: + * - Removes customer information from session. + * * @api * * @return void @@ -111,6 +142,9 @@ public function login(CustomerTransfer $customerTransfer); public function logout(); /** + * Specification: + * - Checks if customer information is present in session. + * * @api * * @return bool @@ -118,6 +152,9 @@ public function logout(); public function isLoggedIn(); /** + * Specification: + * - Retrieves provided customer related addresses from persistent storage. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -128,7 +165,7 @@ public function getAddresses(CustomerTransfer $customerTransfer); /** * Specification: - * - Returns fresh Customer data from database by ID + * - Retrieves customer information with customer addresses by customer ID from persistent storage. * * @api * @@ -140,7 +177,8 @@ public function getCustomerById($idCustomer); /** * Specification: - * - Returns fresh Customer transfer or NULL, if it does not exist + * - Retrieves customer information using provided customer ID. + * - Returns null if customer was not found. * * @api * @@ -151,6 +189,9 @@ public function getCustomerById($idCustomer); public function findCustomerById(CustomerTransfer $customerTransfer); /** + * Specification: + * - Retrieves customer information by either customer ID, customer email, or password restoration key. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -160,6 +201,15 @@ public function findCustomerById(CustomerTransfer $customerTransfer); public function getCustomerByEmail(CustomerTransfer $customerTransfer); /** + * Specification: + * - Updates password if NewPassword property is set in provided transfer object: + * - Validates provided current plain text password using persistent storage. + * - Encrypts provided plain text password before update. + * - Identifies customer by either customer ID, customer email, or password restoration key. + * - Validates customer email information. + * - Updates customer data which is set in provided transfer object. + * - Sends password restoration email if SendPasswordToken property is set in the provided transfer object. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -169,6 +219,11 @@ public function getCustomerByEmail(CustomerTransfer $customerTransfer); public function updateCustomer(CustomerTransfer $customerTransfer); /** + * Specification: + * - Identifies customer by either customer ID, customer email, or password restoration key. + * - Validates provided current plain text password using persistent storage. + * - Encrypts provided plain text password and stores it in persistent storage. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -178,6 +233,10 @@ public function updateCustomer(CustomerTransfer $customerTransfer); public function updateCustomerPassword(CustomerTransfer $customerTransfer); /** + * Specification: + * - Retrieves an address by customer ID and address ID. + * - Populates address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -187,6 +246,9 @@ public function updateCustomerPassword(CustomerTransfer $customerTransfer); public function getAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Updates customer address using provided transfer object. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -196,6 +258,10 @@ public function getAddress(AddressTransfer $addressTransfer); public function updateAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Updates customer address using provided transfer object. + * - Sets address as default address based on provided default address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -205,6 +271,10 @@ public function updateAddress(AddressTransfer $addressTransfer); public function updateAddressAndCustomerDefaultAddresses(AddressTransfer $addressTransfer); /** + * Specification: + * - Creates customer address using provided transfer object. + * - Sets address as default address based on provided default address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -214,6 +284,10 @@ public function updateAddressAndCustomerDefaultAddresses(AddressTransfer $addres public function createAddressAndUpdateCustomerDefaultAddresses(AddressTransfer $addressTransfer); /** + * Specification: + * - Creates customer address using provided transfer object. + * - Sets address as default address based on provided default address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -223,6 +297,10 @@ public function createAddressAndUpdateCustomerDefaultAddresses(AddressTransfer $ public function createAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Deletes address. + * - Removes references between customer-address entities. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -232,6 +310,9 @@ public function createAddress(AddressTransfer $addressTransfer); public function deleteAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Sets provided address as default shipping address for the related customer. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -241,6 +322,9 @@ public function deleteAddress(AddressTransfer $addressTransfer); public function setDefaultShippingAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Sets provided address as default billing address for the related customer. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -250,6 +334,13 @@ public function setDefaultShippingAddress(AddressTransfer $addressTransfer); public function setDefaultBillingAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Identifies customer by either customer ID, customer email, or password restoration key. + * - Applies configured CustomerAnonymizerPluginInterface plugins on customer data. + * - Anonymizes customer addresses. + * - Anonymizes customer data. + * - Updates persistent storage with anonymized data. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer diff --git a/src/Spryker/Shared/Customer/Code/Messages.php b/src/Spryker/Shared/Customer/Code/Messages.php index ea15b87f..729b7582 100644 --- a/src/Spryker/Shared/Customer/Code/Messages.php +++ b/src/Spryker/Shared/Customer/Code/Messages.php @@ -26,6 +26,7 @@ interface Messages const CUSTOMER_AUTHORIZATION_FAILED = 'customer.authorization.failed'; const CUSTOMER_PASSWORD_INVALID = 'customer.password.invalid'; const CUSTOMER_EMAIL_ALREADY_USED = 'customer.email.already.used'; + const CUSTOMER_EMAIL_FORMAT_INVALID = 'customer.email.format.invalid'; const CUSTOMER_EMAIL_INVALID = 'customer.email.invalid'; const CUSTOMER_TOKEN_INVALID = 'customer.token.invalid'; const CUSTOMER_ANONYMIZATION_SUCCESS = 'customer.anonymization.success'; diff --git a/src/Spryker/Shared/Customer/CustomerConstants.php b/src/Spryker/Shared/Customer/CustomerConstants.php index ad1f029c..28892faf 100644 --- a/src/Spryker/Shared/Customer/CustomerConstants.php +++ b/src/Spryker/Shared/Customer/CustomerConstants.php @@ -12,11 +12,9 @@ interface CustomerConstants const CUSTOMER_ANONYMOUS_PATTERN = 'CUSTOMER_ANONYMOUS_PATTERN'; const CUSTOMER_SECURED_PATTERN = 'CUSTOMER_SECURED_PATTERN'; - /** @deprecated Use CustomerConstants::BASE_URL_YVES instead */ - const HOST_YVES = 'HOST_YVES'; - /** - * Base URL for Yves including scheme and port (e.g. http://www.de.demoshop.local:8080) + * Specification: + * - Base URL for Yves including scheme and port (e.g. http://www.de.demoshop.local:8080) * * @api */ diff --git a/src/Spryker/Zed/Customer/Business/Exception/CountryNotFoundException.php b/src/Spryker/Yves/Customer/CustomerConfig.php similarity index 59% rename from src/Spryker/Zed/Customer/Business/Exception/CountryNotFoundException.php rename to src/Spryker/Yves/Customer/CustomerConfig.php index 6627b469..d179c423 100644 --- a/src/Spryker/Zed/Customer/Business/Exception/CountryNotFoundException.php +++ b/src/Spryker/Yves/Customer/CustomerConfig.php @@ -5,10 +5,10 @@ * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. */ -namespace Spryker\Zed\Customer\Business\Exception; +namespace Spryker\Yves\Customer; -use Exception; +use Spryker\Yves\Kernel\AbstractBundleConfig; -class CountryNotFoundException extends Exception +class CustomerConfig extends AbstractBundleConfig { } diff --git a/src/Spryker/Zed/Customer/Business/Anonymizer/CustomerAnonymizer.php b/src/Spryker/Zed/Customer/Business/Anonymizer/CustomerAnonymizer.php index c35511cf..dd1d0fce 100644 --- a/src/Spryker/Zed/Customer/Business/Anonymizer/CustomerAnonymizer.php +++ b/src/Spryker/Zed/Customer/Business/Anonymizer/CustomerAnonymizer.php @@ -47,8 +47,7 @@ class CustomerAnonymizer implements CustomerAnonymizerInterface * @param array $customerAnonymizerPlugins */ public function __construct( - CustomerQueryContainerInterface - $customerQueryContainer, + CustomerQueryContainerInterface $customerQueryContainer, CustomerInterface $customerModel, AddressInterface $addressModel, array $customerAnonymizerPlugins @@ -130,7 +129,12 @@ protected function anonymizeCustomer(CustomerTransfer $customerTransfer) protected function generateRandomEmail() { do { - $randomEmail = md5(mt_rand()); + $randomEmail = sprintf( + '%s@%s.%s', + strtolower(md5(mt_rand())), + strtolower(md5(mt_rand())), + strtolower(md5(mt_rand())) + ); } while ($this->queryContainer->queryCustomerByEmail($randomEmail)->exists()); return $randomEmail; diff --git a/src/Spryker/Zed/Customer/Business/Customer/Address.php b/src/Spryker/Zed/Customer/Business/Customer/Address.php index 2126fb27..de1905d7 100644 --- a/src/Spryker/Zed/Customer/Business/Customer/Address.php +++ b/src/Spryker/Zed/Customer/Business/Customer/Address.php @@ -15,7 +15,6 @@ use Orm\Zed\Customer\Persistence\SpyCustomerAddress; use Propel\Runtime\Collection\ObjectCollection; use Spryker\Zed\Customer\Business\Exception\AddressNotFoundException; -use Spryker\Zed\Customer\Business\Exception\CountryNotFoundException; use Spryker\Zed\Customer\Business\Exception\CustomerNotFoundException; use Spryker\Zed\Customer\Dependency\Facade\CustomerToCountryInterface; use Spryker\Zed\Customer\Dependency\Facade\CustomerToLocaleInterface; @@ -352,22 +351,13 @@ protected function getCustomerFromCustomerTransfer(CustomerTransfer $customerTra } /** - * @throws \Spryker\Zed\Customer\Business\Exception\CountryNotFoundException - * * @return int */ protected function getCustomerCountryId() { - $idCountry = $this->countryFacade->getIdCountryByIso2Code($this->getIsoCode()); - - if ($idCountry === null) { - throw new CountryNotFoundException(sprintf( - 'Country not found for ISO code `%s`.', - $this->getIsoCode() - )); - } + $countryTransfer = $this->countryFacade->getCountryByIso2Code($this->getIsoCode()); - return $idCountry; + return $countryTransfer->getIdCountry(); } /** @@ -465,7 +455,8 @@ protected function retrieveFkCountry(AddressTransfer $addressTransfer) if (empty($fkCountry)) { $iso2Code = $addressTransfer->getIso2Code(); if (empty($iso2Code) === false) { - $fkCountry = $this->countryFacade->getIdCountryByIso2Code($iso2Code); + $countryTransfer = $this->countryFacade->getCountryByIso2Code($iso2Code); + $fkCountry = $countryTransfer->getIdCountry(); } else { $fkCountry = $this->getCustomerCountryId(); } diff --git a/src/Spryker/Zed/Customer/Business/Customer/Customer.php b/src/Spryker/Zed/Customer/Business/Customer/Customer.php index 7bc4b675..fb6313f4 100644 --- a/src/Spryker/Zed/Customer/Business/Customer/Customer.php +++ b/src/Spryker/Zed/Customer/Business/Customer/Customer.php @@ -52,6 +52,11 @@ class Customer implements CustomerInterface */ protected $customerConfig; + /** + * @var \Spryker\Zed\Customer\Business\Customer\EmailValidatorInterface + */ + protected $emailValidator; + /** * @var \Spryker\Zed\Customer\Dependency\Facade\CustomerToMailInterface */ @@ -71,6 +76,7 @@ class Customer implements CustomerInterface * @param \Spryker\Zed\Customer\Persistence\CustomerQueryContainerInterface $queryContainer * @param \Spryker\Zed\Customer\Business\ReferenceGenerator\CustomerReferenceGeneratorInterface $customerReferenceGenerator * @param \Spryker\Zed\Customer\CustomerConfig $customerConfig + * @param \Spryker\Zed\Customer\Business\Customer\EmailValidatorInterface $emailValidator * @param \Spryker\Zed\Customer\Dependency\Facade\CustomerToMailInterface $mailFacade * @param \Spryker\Zed\Locale\Persistence\LocaleQueryContainerInterface $localeQueryContainer * @param \Spryker\Shared\Kernel\Store $store @@ -79,6 +85,7 @@ public function __construct( CustomerQueryContainerInterface $queryContainer, CustomerReferenceGeneratorInterface $customerReferenceGenerator, CustomerConfig $customerConfig, + EmailValidatorInterface $emailValidator, CustomerToMailInterface $mailFacade, LocaleQueryContainerInterface $localeQueryContainer, Store $store @@ -86,6 +93,7 @@ public function __construct( $this->queryContainer = $queryContainer; $this->customerReferenceGenerator = $customerReferenceGenerator; $this->customerConfig = $customerConfig; + $this->emailValidator = $emailValidator; $this->mailFacade = $mailFacade; $this->localeQueryContainer = $localeQueryContainer; $this->store = $store; @@ -153,14 +161,12 @@ public function add($customerTransfer) $this->addLocale($customerEntity); - if (!$this->isEmailAvailableForCustomer($customerEntity)) { - $customerResponseTransfer = $this->createCustomerEmailAlreadyUsedResponse(); - + $customerResponseTransfer = $this->createCustomerResponseTransfer(); + $customerResponseTransfer = $this->validateCustomerEmail($customerResponseTransfer, $customerEntity); + if ($customerResponseTransfer->getIsSuccess() !== true) { return $customerResponseTransfer; } - $customerResponseTransfer = $this->createCustomerResponseTransfer(); - $customerEntity->setCustomerReference($this->customerReferenceGenerator->generateCustomerReference($customerTransfer)); $customerEntity->setRegistrationKey($this->generateKey()); @@ -403,15 +409,15 @@ public function update(CustomerTransfer $customerTransfer) } } + $customerResponseTransfer = $this->createCustomerResponseTransfer(); $customerEntity = $this->getCustomer($customerTransfer); $customerEntity->fromArray($customerTransfer->modifiedToArray()); - if (!$this->isEmailAvailableForCustomer($customerEntity)) { - return $this->createCustomerEmailAlreadyUsedResponse(); + $customerResponseTransfer = $this->validateCustomerEmail($customerResponseTransfer, $customerEntity); + if ($customerResponseTransfer->getIsSuccess() !== true) { + return $customerResponseTransfer; } - $customerResponseTransfer = $this->createCustomerResponseTransfer(); - $changedRows = $customerEntity->save(); $customerResponseTransfer @@ -439,31 +445,41 @@ protected function createCustomerResponseTransfer($isSuccess = true) } /** + * @param \Generated\Shared\Transfer\CustomerResponseTransfer $customerResponseTransfer + * @param \Orm\Zed\Customer\Persistence\SpyCustomer $customerEntity + * * @return \Generated\Shared\Transfer\CustomerResponseTransfer */ - protected function createCustomerEmailAlreadyUsedResponse() + protected function validateCustomerEmail(CustomerResponseTransfer $customerResponseTransfer, SpyCustomer $customerEntity) { - $customerErrorTransfer = new CustomerErrorTransfer(); - $customerErrorTransfer->setMessage(Messages::CUSTOMER_EMAIL_ALREADY_USED); + if (!$this->emailValidator->isFormatValid($customerEntity->getEmail())) { + $customerResponseTransfer->setIsSuccess(false); + $customerResponseTransfer->addError( + $this->createErrorCustomerResponseTransfer(Messages::CUSTOMER_EMAIL_FORMAT_INVALID) + ); + } - $customerResponseTransfer = $this->createCustomerResponseTransfer(false); - $customerResponseTransfer->addError($customerErrorTransfer); + if (!$this->emailValidator->isEmailAvailableForCustomer($customerEntity->getEmail(), $customerEntity->getIdCustomer())) { + $customerResponseTransfer->setIsSuccess(false); + $customerResponseTransfer->addError( + $this->createErrorCustomerResponseTransfer(Messages::CUSTOMER_EMAIL_ALREADY_USED) + ); + } return $customerResponseTransfer; } /** - * @param \Orm\Zed\Customer\Persistence\SpyCustomer $customerEntity + * @param string $message * - * @return bool + * @return \Generated\Shared\Transfer\CustomerErrorTransfer */ - protected function isEmailAvailableForCustomer(SpyCustomer $customerEntity) + protected function createErrorCustomerResponseTransfer($message) { - $count = $this->queryContainer - ->queryCustomerByEmailApartFromIdCustomer($customerEntity->getEmail(), $customerEntity->getIdCustomer()) - ->count(); + $customerErrorTransfer = new CustomerErrorTransfer(); + $customerErrorTransfer->setMessage($message); - return ($count === 0); + return $customerErrorTransfer; } /** diff --git a/src/Spryker/Zed/Customer/Business/Customer/EmailValidator.php b/src/Spryker/Zed/Customer/Business/Customer/EmailValidator.php new file mode 100644 index 00000000..a9d5cd7a --- /dev/null +++ b/src/Spryker/Zed/Customer/Business/Customer/EmailValidator.php @@ -0,0 +1,59 @@ +queryContainer = $queryContainer; + $this->utilValidateService = $utilValidateService; + } + + /** + * @param string $email + * + * @return bool + */ + public function isFormatValid($email) + { + return $this->utilValidateService->isEmailFormatValid($email); + } + + /** + * @param string $email + * @param int $idCustomer + * + * @return bool + */ + public function isEmailAvailableForCustomer($email, $idCustomer) + { + $customerEntity = $this->queryContainer + ->queryCustomerByEmailApartFromIdCustomer($email, $idCustomer) + ->findOne(); + + return ($customerEntity === null); + } +} diff --git a/src/Spryker/Zed/Customer/Business/Customer/EmailValidatorInterface.php b/src/Spryker/Zed/Customer/Business/Customer/EmailValidatorInterface.php new file mode 100644 index 00000000..cc9de45f --- /dev/null +++ b/src/Spryker/Zed/Customer/Business/Customer/EmailValidatorInterface.php @@ -0,0 +1,26 @@ +getQueryContainer(), $this->createCustomerReferenceGenerator(), $config, + $this->createEmailValidator(), $this->getMailFacade(), $this->getLocaleQueryContainer(), $this->getStore() @@ -106,7 +108,7 @@ public function createCustomerOrderSaver() */ public function createPreConditionChecker() { - return new PreConditionChecker($this->createCustomer()); + return new PreConditionChecker($this->createCustomer(), $this->getUtilValidateService()); } /** @@ -155,4 +157,23 @@ public function createCustomerOrderHydrator() $this->createCustomer() ); } + + /** + * @return \Spryker\Zed\Customer\Business\Customer\EmailValidatorInterface + */ + protected function createEmailValidator() + { + return new EmailValidator( + $this->getQueryContainer(), + $this->getUtilValidateService() + ); + } + + /** + * @return \Spryker\Zed\Customer\Dependency\Service\CustomerToUtilValidateServiceInterface + */ + protected function getUtilValidateService() + { + return $this->getProvidedDependency(CustomerDependencyProvider::SERVICE_UTIL_VALIDATE); + } } diff --git a/src/Spryker/Zed/Customer/Business/CustomerFacade.php b/src/Spryker/Zed/Customer/Business/CustomerFacade.php index c786b862..42a0c4fe 100644 --- a/src/Spryker/Zed/Customer/Business/CustomerFacade.php +++ b/src/Spryker/Zed/Customer/Business/CustomerFacade.php @@ -20,6 +20,8 @@ class CustomerFacade extends AbstractFacade implements CustomerFacadeInterface { /** + * {@inheritdoc} + * * @api * * @param string $email @@ -34,6 +36,8 @@ public function hasEmail($email) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -64,6 +68,8 @@ public function registerCustomer(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -78,20 +84,8 @@ public function confirmRegistration(CustomerTransfer $customerTransfer) } /** - * @api - * - * @deprecated Use CustomerFacade::sendPasswordRestoreMail() instead - * - * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer + * {@inheritdoc} * - * @return \Generated\Shared\Transfer\CustomerResponseTransfer - */ - public function forgotPassword(CustomerTransfer $customerTransfer) - { - return $this->sendPasswordRestoreMail($customerTransfer); - } - - /** * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -106,6 +100,8 @@ public function sendPasswordRestoreMail(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -120,6 +116,8 @@ public function restorePassword(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -134,6 +132,8 @@ public function deleteCustomer(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -148,6 +148,8 @@ public function findCustomerById(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -162,6 +164,8 @@ public function getCustomer(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -176,6 +180,8 @@ public function updateCustomer(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -190,6 +196,8 @@ public function updateCustomerPassword(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -204,6 +212,8 @@ public function getAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -218,6 +228,8 @@ public function getAddresses(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -232,6 +244,8 @@ public function updateAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -246,6 +260,8 @@ public function updateAddressAndCustomerDefaultAddresses(AddressTransfer $addres } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -260,6 +276,8 @@ public function createAddressAndUpdateCustomerDefaultAddresses(AddressTransfer $ } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -274,6 +292,8 @@ public function createAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -288,6 +308,8 @@ public function setDefaultBillingAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -302,6 +324,8 @@ public function setDefaultShippingAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -316,6 +340,8 @@ public function renderAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -330,6 +356,8 @@ public function getDefaultShippingAddress(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -344,6 +372,8 @@ public function getDefaultBillingAddress(CustomerTransfer $customerTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -358,6 +388,8 @@ public function deleteAddress(AddressTransfer $addressTransfer) } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -372,6 +404,8 @@ public function tryAuthorizeCustomerByEmailAndPassword(CustomerTransfer $custome } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer @@ -381,12 +415,14 @@ public function tryAuthorizeCustomerByEmailAndPassword(CustomerTransfer $custome */ public function saveCustomerForOrder( QuoteTransfer $quoteTransfer, - CheckoutResponseTransfer $checkoutResponseTransfer + CheckoutResponseTransfer $checkoutResponseTransfer ) { $this->getFactory()->createCustomerOrderSaver()->saveOrder($quoteTransfer, $checkoutResponseTransfer); } /** + * {@inheritdoc} + * * @api * * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer @@ -396,7 +432,7 @@ public function saveCustomerForOrder( */ public function checkOrderPreSaveConditions( QuoteTransfer $quoteTransfer, - CheckoutResponseTransfer $checkoutResponseTransfer + CheckoutResponseTransfer $checkoutResponseTransfer ) { $this->getFactory() ->createPreConditionChecker() @@ -420,10 +456,10 @@ public function anonymizeCustomer(CustomerTransfer $customerTransfer) } /** - * @api - * * {@inheritdoc} * + * @api + * * @param string $customerReference * * @return \Generated\Shared\Transfer\CustomerTransfer|null diff --git a/src/Spryker/Zed/Customer/Business/CustomerFacadeInterface.php b/src/Spryker/Zed/Customer/Business/CustomerFacadeInterface.php index 157b89ec..cea9b2c5 100644 --- a/src/Spryker/Zed/Customer/Business/CustomerFacadeInterface.php +++ b/src/Spryker/Zed/Customer/Business/CustomerFacadeInterface.php @@ -16,6 +16,9 @@ interface CustomerFacadeInterface { /** + * Specification: + * - Checks if provided email address exists in persistent storage. + * * @api * * @param string $email @@ -26,9 +29,11 @@ public function hasEmail($email); /** * Specification: - * - Hashes password if provided - * - Saves customer - * - Returns CustomerResponseTransfer with success flag + * - Validates provided customer email information. + * - Encrypts provided plain text password. + * - Assigns current locale to customer if it is not set already. + * - Generates customer reference for customer. + * - Stores customer data. * * @api * @@ -40,10 +45,13 @@ public function addCustomer(CustomerTransfer $customerTransfer); /** * Specification: - * - Hashes password if provided - * - Saves customer - * - Sends registration email (on successful registration) - * - Returns CustomerResponseTransfer with success flag + * - Validates provided customer email information. + * - Encrypts provided plain text password. + * - Assigns current locale to customer if it is not set already. + * - Generates customer reference for customer. + * - Stores customer data. + * - Sends registration confirmation link via email using a freshly generated registration key. + * - Sends password restoration email if SendPasswordToken property is set in the provided transfer object. * * @api * @@ -54,6 +62,10 @@ public function addCustomer(CustomerTransfer $customerTransfer); public function registerCustomer(CustomerTransfer $customerTransfer); /** + * Specification: + * - Finds customer registration confirmation by provided registration key. + * - Sets customer as registered and removes the registration key from persistent storage. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -63,17 +75,9 @@ public function registerCustomer(CustomerTransfer $customerTransfer); public function confirmRegistration(CustomerTransfer $customerTransfer); /** - * @api - * - * @deprecated Use sendPasswordRestoreMail() instead - * - * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer + * Specification: + * - Sends password restoration link via email using a freshly generated password restoration key. * - * @return \Generated\Shared\Transfer\CustomerResponseTransfer - */ - public function forgotPassword(CustomerTransfer $customerTransfer); - - /** * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -83,6 +87,13 @@ public function forgotPassword(CustomerTransfer $customerTransfer); public function sendPasswordRestoreMail(CustomerTransfer $customerTransfer); /** + * Specification: + * - Identifies customer by either customer ID, customer email, or password restoration key. + * - Encrypts provided plain text password. + * - Stores new password for customer in persistent storage. + * - Removes password restoration key from customer. + * - Sends password restoration confirmation email. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -92,6 +103,9 @@ public function sendPasswordRestoreMail(CustomerTransfer $customerTransfer); public function restorePassword(CustomerTransfer $customerTransfer); /** + * Specification: + * - Deletes a customer by either customer ID, customer email, or password restoration key. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -101,6 +115,9 @@ public function restorePassword(CustomerTransfer $customerTransfer); public function deleteCustomer(CustomerTransfer $customerTransfer); /** + * Specification: + * - Retrieves customer information with customer addresses by customer ID from persistent storage. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -110,6 +127,9 @@ public function deleteCustomer(CustomerTransfer $customerTransfer); public function getCustomer(CustomerTransfer $customerTransfer); /** + * Specification: + * - Retrieves customer information with customer addresses and locale information by customer ID. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -120,10 +140,13 @@ public function findCustomerById(CustomerTransfer $customerTransfer); /** * Specification: - * - Hashes password if provided - * - Saves customer - * - Sends password restore email if applicable - * - Returns CustomerResponseTransfer with success flag + * - Updates password if NewPassword property is set in provided transfer object: + * - Validates provided current plain text password using persistent storage. + * - Encrypts provided plain text password before update. + * - Identifies customer by either customer ID, customer email, or password restoration key. + * - Validates customer email information. + * - Updates customer data which is set in provided transfer object. + * - Sends password restoration email if SendPasswordToken property is set in the provided transfer object. * * @api * @@ -134,6 +157,11 @@ public function findCustomerById(CustomerTransfer $customerTransfer); public function updateCustomer(CustomerTransfer $customerTransfer); /** + * Specification: + * - Identifies customer by either customer ID, customer email, or password restoration key. + * - Validates provided current plain text password using persistent storage. + * - Encrypts provided plain text password and stores it in persistent storage. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -143,6 +171,10 @@ public function updateCustomer(CustomerTransfer $customerTransfer); public function updateCustomerPassword(CustomerTransfer $customerTransfer); /** + * Specification: + * - Retrieves an address by customer ID and address ID. + * - Populates address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -152,6 +184,9 @@ public function updateCustomerPassword(CustomerTransfer $customerTransfer); public function getAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Retrieves provided customer related addresses from persistent storage. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -161,6 +196,10 @@ public function getAddress(AddressTransfer $addressTransfer); public function getAddresses(CustomerTransfer $customerTransfer); /** + * Specification: + * - Retrieves an address by customer ID and address ID. + * - Populates address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -170,6 +209,10 @@ public function getAddresses(CustomerTransfer $customerTransfer); public function updateAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Updates customer address using provided transfer object. + * - Sets address as default address based on provided default address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -179,6 +222,10 @@ public function updateAddress(AddressTransfer $addressTransfer); public function updateAddressAndCustomerDefaultAddresses(AddressTransfer $addressTransfer); /** + * Specification: + * - Creates customer address using provided transfer object. + * - Sets address as default address based on provided default address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -188,6 +235,10 @@ public function updateAddressAndCustomerDefaultAddresses(AddressTransfer $addres public function createAddressAndUpdateCustomerDefaultAddresses(AddressTransfer $addressTransfer); /** + * Specification: + * - Creates customer address using provided transfer object. + * - Sets address as default address based on provided default address flags. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -197,6 +248,9 @@ public function createAddressAndUpdateCustomerDefaultAddresses(AddressTransfer $ public function createAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Sets provided address as default billing address for the related customer. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -206,6 +260,9 @@ public function createAddress(AddressTransfer $addressTransfer); public function setDefaultBillingAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Sets provided address as default shipping address for the related customer. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -215,6 +272,9 @@ public function setDefaultBillingAddress(AddressTransfer $addressTransfer); public function setDefaultShippingAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Retrieves address as a formatted string for rendering. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -224,6 +284,9 @@ public function setDefaultShippingAddress(AddressTransfer $addressTransfer); public function renderAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Retrieves default shipping address for customer. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -233,6 +296,9 @@ public function renderAddress(AddressTransfer $addressTransfer); public function getDefaultShippingAddress(CustomerTransfer $customerTransfer); /** + * Specification: + * - Retrieves default billing address for customer. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -242,6 +308,10 @@ public function getDefaultShippingAddress(CustomerTransfer $customerTransfer); public function getDefaultBillingAddress(CustomerTransfer $customerTransfer); /** + * Specification: + * - Deletes address. + * - Removes references between customer-address entities. + * * @api * * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer @@ -251,6 +321,9 @@ public function getDefaultBillingAddress(CustomerTransfer $customerTransfer); public function deleteAddress(AddressTransfer $addressTransfer); /** + * Specification: + * - Checks if customer exists in persistent storage by provided email and plain text password. + * * @api * * @param \Generated\Shared\Transfer\CustomerTransfer $customerTransfer @@ -260,6 +333,15 @@ public function deleteAddress(AddressTransfer $addressTransfer); public function tryAuthorizeCustomerByEmailAndPassword(CustomerTransfer $customerTransfer); /** + * Specification: + * - Does nothing if customer is guest. + * - Registers customer if it does not exist in persistent storage. + * - Updates customer if it exists in persistent storage. + * - Updates customer addresses. + * + * @see CustomerFacadeInterface::registerCustomer() + * @see CustomerFacadeInterface::updateCustomer() + * * @api * * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer @@ -269,10 +351,14 @@ public function tryAuthorizeCustomerByEmailAndPassword(CustomerTransfer $custome */ public function saveCustomerForOrder( QuoteTransfer $quoteTransfer, - CheckoutResponseTransfer $checkoutResponseTransfer + CheckoutResponseTransfer $checkoutResponseTransfer ); /** + * Specification: + * - Checks if a new customer has a not yet registered email. + * - Checks if a new customer or a guest user has a valid email address. + * * @api * * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer @@ -282,14 +368,16 @@ public function saveCustomerForOrder( */ public function checkOrderPreSaveConditions( QuoteTransfer $quoteTransfer, - CheckoutResponseTransfer $checkoutResponseTransfer + CheckoutResponseTransfer $checkoutResponseTransfer ); /** * Specification: - * - Executes anonymization plugins - * - Executes customer addresses anonymization - * - Executes customer anonymization + * - Identifies customer by either customer ID, customer email, or password restoration key. + * - Applies configured CustomerAnonymizerPluginInterface plugins on customer data. + * - Anonymizes customer addresses. + * - Anonymizes customer data. + * - Updates persistent storage with anonymized data. * * @api * @@ -300,6 +388,9 @@ public function checkOrderPreSaveConditions( public function anonymizeCustomer(CustomerTransfer $customerTransfer); /** + * Specification: + * - Retrieves customer information with customer addresses and locale information by customer reference. + * * @api * * Specification: @@ -313,6 +404,11 @@ public function anonymizeCustomer(CustomerTransfer $customerTransfer); public function findByReference($customerReference); /** + * Specification: + * - Hydrates Customer transfer object into provided Order transfer object. + * - Uses Order::customerReference transfer object property to identify customer. + * - Does nothing if Customer transfer object is already set. + * * @api * * Specification diff --git a/src/Spryker/Zed/Customer/Business/Model/PreConditionChecker.php b/src/Spryker/Zed/Customer/Business/Model/PreConditionChecker.php index c7abb066..9209d973 100644 --- a/src/Spryker/Zed/Customer/Business/Model/PreConditionChecker.php +++ b/src/Spryker/Zed/Customer/Business/Model/PreConditionChecker.php @@ -10,22 +10,33 @@ use Generated\Shared\Transfer\CheckoutErrorTransfer; use Generated\Shared\Transfer\CheckoutResponseTransfer; use Generated\Shared\Transfer\QuoteTransfer; -use Spryker\Zed\Customer\Business\Customer\Customer; +use Spryker\Zed\Customer\Business\Customer\CustomerInterface; use Spryker\Zed\Customer\CustomerConfig; +use Spryker\Zed\Customer\Dependency\Service\CustomerToUtilValidateServiceInterface; class PreConditionChecker implements PreConditionCheckerInterface { + const ERROR_EMAIL_INVALID = 'customer.email.invalid'; + const ERROR_EMAIL_UNIQUE = 'customer.email.already.used'; + /** - * @var \Spryker\Zed\Customer\Business\Customer\Customer + * @var \Spryker\Zed\Customer\Business\Customer\CustomerInterface */ protected $customer; /** - * @param \Spryker\Zed\Customer\Business\Customer\Customer $customer + * @var \Spryker\Zed\Customer\Dependency\Service\CustomerToUtilValidateServiceInterface + */ + protected $utilValidateService; + + /** + * @param \Spryker\Zed\Customer\Business\Customer\CustomerInterface $customer + * @param \Spryker\Zed\Customer\Dependency\Service\CustomerToUtilValidateServiceInterface $utilValidateService */ - public function __construct(Customer $customer) + public function __construct(CustomerInterface $customer, CustomerToUtilValidateServiceInterface $utilValidateService) { $this->customer = $customer; + $this->utilValidateService = $utilValidateService; } /** @@ -36,26 +47,59 @@ public function __construct(Customer $customer) */ public function checkPreConditions(QuoteTransfer $quoteTransfer, CheckoutResponseTransfer $checkoutResponseTransfer) { - if ($quoteTransfer->getCustomer() !== null && $quoteTransfer->getCustomer()->getIdCustomer() !== null) { + if ($this->hasIdCustomer($quoteTransfer)) { return; } + if (!$this->utilValidateService->isEmailFormatValid($quoteTransfer->getCustomer()->getEmail())) { + $this->addViolation( + $checkoutResponseTransfer, + CustomerConfig::ERROR_CODE_CUSTOMER_INVALID_EMAIL, + static::ERROR_EMAIL_INVALID + ); + } + if ($quoteTransfer->getCustomer()->getIsGuest() === true) { return; } if ($this->customer->hasEmail($quoteTransfer->getCustomer()->getEmail())) { - $checkoutErrorTransfer = $this->createCheckoutErrorTransfer(); - $checkoutErrorTransfer - ->setErrorCode(CustomerConfig::ERROR_CODE_CUSTOMER_ALREADY_REGISTERED) - ->setMessage('Email already taken'); - - $checkoutResponseTransfer - ->setIsSuccess(false) - ->addError($checkoutErrorTransfer); + $this->addViolation( + $checkoutResponseTransfer, + CustomerConfig::ERROR_CODE_CUSTOMER_ALREADY_REGISTERED, + static::ERROR_EMAIL_UNIQUE + ); } } + /** + * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer + * + * @return bool + */ + protected function hasIdCustomer(QuoteTransfer $quoteTransfer) + { + return $quoteTransfer->getCustomer() !== null && $quoteTransfer->getCustomer()->getIdCustomer() !== null; + } + + /** + * @param \Generated\Shared\Transfer\CheckoutResponseTransfer $checkoutResponseTransfer + * @param int $errorCode + * @param string $errorMessage + * + * @return void + */ + protected function addViolation(CheckoutResponseTransfer $checkoutResponseTransfer, $errorCode, $errorMessage) + { + $checkoutResponseTransfer + ->setIsSuccess(false) + ->addError( + $this->createCheckoutErrorTransfer() + ->setErrorCode($errorCode) + ->setMessage($errorMessage) + ); + } + /** * @return \Generated\Shared\Transfer\CheckoutErrorTransfer */ diff --git a/src/Spryker/Zed/Customer/Communication/Controller/AddController.php b/src/Spryker/Zed/Customer/Communication/Controller/AddController.php index d2294d26..a28e9a78 100644 --- a/src/Spryker/Zed/Customer/Communication/Controller/AddController.php +++ b/src/Spryker/Zed/Customer/Communication/Controller/AddController.php @@ -12,7 +12,7 @@ use Symfony\Component\HttpFoundation\Request; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class AddController extends AbstractController @@ -55,12 +55,4 @@ public function indexAction(Request $request) 'form' => $form->createView(), ]); } - - /** - * @return \Generated\Shared\Transfer\CustomerTransfer - */ - protected function createCustomerTransfer() - { - return new CustomerTransfer(); - } } diff --git a/src/Spryker/Zed/Customer/Communication/Controller/AddressController.php b/src/Spryker/Zed/Customer/Communication/Controller/AddressController.php index fc0d3119..2a61d3ea 100644 --- a/src/Spryker/Zed/Customer/Communication/Controller/AddressController.php +++ b/src/Spryker/Zed/Customer/Communication/Controller/AddressController.php @@ -13,89 +13,11 @@ use Symfony\Component\HttpFoundation\Request; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class AddressController extends AbstractController { - /** - * @deprecated moved to Customer view page ViewController->indexAction() - * - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return array - */ - public function indexAction(Request $request) - { - $idCustomerRaw = $request->get(CustomerConstants::PARAM_ID_CUSTOMER); - - if (empty($idCustomerRaw)) { - return $this->redirectResponse('/customer'); - } - - $idCustomer = $this->castId($idCustomerRaw); - - $table = $this->getFactory() - ->createCustomerAddressTable($idCustomer); - - return $this->viewResponse([ - 'addressTable' => $table->render(), - 'idCustomer' => $idCustomer, - ]); - } - - /** - * @deprecated moved to Customer view page ViewController->indexAction() - * - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return \Symfony\Component\HttpFoundation\JsonResponse - */ - public function tableAction(Request $request) - { - $idCustomer = $this->castId($request->get(CustomerConstants::PARAM_ID_CUSTOMER)); - - $table = $this->getFactory() - ->createCustomerAddressTable($idCustomer); - - return $this->jsonResponse($table->fetchData()); - } - - /** - * @deprecated Address has no detail page anymore - * - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return array - */ - public function viewAction(Request $request) - { - $idCustomer = false; - $idCustomerAddress = $this->castId($request->get(CustomerConstants::PARAM_ID_CUSTOMER_ADDRESS)); - - $customerAddress = $this->createCustomerAddressTransfer(); - $customerAddress->setIdCustomerAddress($idCustomerAddress); - - $addressDetails = $this->getFacade() - ->getAddress($customerAddress); - - if (empty($addressDetails) === false) { - $idCustomer = $addressDetails->getFkCustomer(); - } - - $customerAddressTransfer = $this->createCustomerAddressTransfer(); - $customerAddressTransfer->setIdCustomerAddress($idCustomerAddress); - - $address = $this->getFacade() - ->getAddress($customerAddressTransfer); - - return $this->viewResponse([ - 'address' => $address->toArray(), - 'idCustomer' => $idCustomer, - 'idCustomerAddress' => $idCustomerAddress, - ]); - } - /** * @param \Symfony\Component\HttpFoundation\Request $request * diff --git a/src/Spryker/Zed/Customer/Communication/Controller/DeleteController.php b/src/Spryker/Zed/Customer/Communication/Controller/DeleteController.php index d1d56455..45f0ce2e 100644 --- a/src/Spryker/Zed/Customer/Communication/Controller/DeleteController.php +++ b/src/Spryker/Zed/Customer/Communication/Controller/DeleteController.php @@ -14,7 +14,7 @@ use Symfony\Component\HttpFoundation\Request; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class DeleteController extends AbstractController diff --git a/src/Spryker/Zed/Customer/Communication/Controller/EditController.php b/src/Spryker/Zed/Customer/Communication/Controller/EditController.php index 177fce99..d2381a35 100644 --- a/src/Spryker/Zed/Customer/Communication/Controller/EditController.php +++ b/src/Spryker/Zed/Customer/Communication/Controller/EditController.php @@ -14,7 +14,7 @@ use Symfony\Component\HttpFoundation\Request; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class EditController extends AbstractController diff --git a/src/Spryker/Zed/Customer/Communication/Controller/GatewayController.php b/src/Spryker/Zed/Customer/Communication/Controller/GatewayController.php index 48fbc035..4f588f55 100644 --- a/src/Spryker/Zed/Customer/Communication/Controller/GatewayController.php +++ b/src/Spryker/Zed/Customer/Communication/Controller/GatewayController.php @@ -15,7 +15,7 @@ use Spryker\Zed\Kernel\Communication\Controller\AbstractGatewayController; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class GatewayController extends AbstractGatewayController diff --git a/src/Spryker/Zed/Customer/Communication/Controller/IndexController.php b/src/Spryker/Zed/Customer/Communication/Controller/IndexController.php index 68729b02..9d4450d0 100644 --- a/src/Spryker/Zed/Customer/Communication/Controller/IndexController.php +++ b/src/Spryker/Zed/Customer/Communication/Controller/IndexController.php @@ -10,7 +10,7 @@ use Spryker\Zed\Kernel\Communication\Controller\AbstractController; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class IndexController extends AbstractController diff --git a/src/Spryker/Zed/Customer/Communication/Controller/ProfileController.php b/src/Spryker/Zed/Customer/Communication/Controller/ProfileController.php deleted file mode 100644 index 54898241..00000000 --- a/src/Spryker/Zed/Customer/Communication/Controller/ProfileController.php +++ /dev/null @@ -1,181 +0,0 @@ -castId($request->query->get('id')); - - $form = $this->getFactory() - ->createCustomerForm($idCustomer); - - $customerTransfer = new CustomerTransfer(); - $customerTransfer->setIdCustomer($idCustomer); - $customerTransfer = $this->getFacade() - ->getCustomer($customerTransfer); - - try { - $idShippingAddress = $this->getFacade() - ->getDefaultShippingAddress($customerTransfer) - ->getIdCustomerAddress(); - } catch (AddressNotFoundException $e) { - $idShippingAddress = null; - } - - try { - $idBillingAddress = $this->getFacade() - ->getDefaultBillingAddress($customerTransfer) - ->getIdCustomerAddress(); - } catch (AddressNotFoundException $e) { - $idBillingAddress = null; - } - - $addresses = []; - $addressesItems = $customerTransfer->getAddresses() - ->getAddresses(); - foreach ($addressesItems as $address) { - $addresses[] = [ - 'id' => $address->getIdCustomerAddress(), - 'first_name' => $address->getFirstName(), - 'last_name' => $address->getLastName(), - 'address1' => $address->getAddress1(), - 'address2' => $address->getAddress2(), - 'address3' => $address->getAddress3(), - 'company' => $address->getCompany(), - 'zipCode' => $address->getZipCode(), - 'city' => $address->getCity(), - 'isDefaultBilling' => ($address->getIdCustomerAddress() === $idBillingAddress), - 'isDefaultShipping' => ($address->getIdCustomerAddress() === $idShippingAddress), - ]; - } - - return [ - 'idCustomer' => $customerTransfer->getIdCustomer(), - 'customerJson' => json_encode($form->toArray()), - 'registered' => $customerTransfer->getRegistered(), - 'addresses' => $addresses, - 'form' => $form->renderDataForTwig()[self::OUTPUT_PAYLOAD]['fields'], - ]; - } - - /** - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse - */ - public function sendPasswordRestoreTokenAction(Request $request) - { - $customerTransfer = new CustomerTransfer(); - $customerTransfer->setIdCustomer($this->castId($request->query->get('id'))); - $this->getFacade() - ->sendPasswordRestoreMail($customerTransfer); - - return $this->redirectResponse('/customer/profile?id=' . $this->castId($request->query->get('id'))); - } - - /** - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return \Symfony\Component\HttpFoundation\JsonResponse - */ - public function editAction(Request $request) - { - $form = $this->getFactory() - ->createCustomerForm($request); - - if ($form->isValid() === true) { - $customerTransfer = new CustomerTransfer(); - $customerTransfer->fromArray($form->getRequestData()); - $this->getFacade() - ->updateCustomer($customerTransfer); - } - - return $this->jsonResponse($form->renderData()); - } - - /** - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return \Symfony\Component\HttpFoundation\JsonResponse - */ - public function addressAction(Request $request) - { - $form = $this->getFactory() - ->createAddressForm($request); - - if ($form->isValid() === true) { - $addressTransfer = new AddressTransfer(); - $addressTransfer->fromArray($form->getRequestData()); - if ($addressTransfer->getIdCustomerAddress()) { - $this->getFacade() - ->updateAddress($addressTransfer); - - return $this->jsonResponse($form->renderData()); - } - - $this->getFacade() - ->createAddress($addressTransfer); - } - - return $this->jsonResponse($form->renderData()); - } - - /** - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse - */ - public function setDefaultShippingAddressAction(Request $request) - { - $addressTransfer = new AddressTransfer(); - $addressTransfer->setIdCustomerAddress($this->castId($request->query->get('address_id'))); - $addressTransfer->setFkCustomer($this->castId($request->query->get('customer_id'))); - $this->getFacade() - ->setDefaultShippingAddress($addressTransfer); - - return $this->redirectResponse('/customer/profile?id=' . $this->castId($request->query->get('customer_id'))); - } - - /** - * @param \Symfony\Component\HttpFoundation\Request $request - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse - */ - public function setDefaultBillingAddressAction(Request $request) - { - $addressTransfer = new AddressTransfer(); - $addressTransfer->setIdCustomerAddress($this->castId($request->query->get('address_id'))); - $addressTransfer->setFkCustomer($this->castId($request->query->get('customer_id'))); - $this->getFacade() - ->setDefaultBillingAddress($addressTransfer); - - return $this->redirectResponse('/customer/profile?id=' . $this->castId($request->query->get('customer_id'))); - } -} diff --git a/src/Spryker/Zed/Customer/Communication/Controller/ViewController.php b/src/Spryker/Zed/Customer/Communication/Controller/ViewController.php index 7f4f0ef6..c0078859 100644 --- a/src/Spryker/Zed/Customer/Communication/Controller/ViewController.php +++ b/src/Spryker/Zed/Customer/Communication/Controller/ViewController.php @@ -13,7 +13,7 @@ use Symfony\Component\HttpFoundation\Request; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class ViewController extends AbstractController diff --git a/src/Spryker/Zed/Customer/Communication/CustomerCommunicationFactory.php b/src/Spryker/Zed/Customer/Communication/CustomerCommunicationFactory.php index 2b5eca54..df3a7bd2 100644 --- a/src/Spryker/Zed/Customer/Communication/CustomerCommunicationFactory.php +++ b/src/Spryker/Zed/Customer/Communication/CustomerCommunicationFactory.php @@ -19,7 +19,7 @@ use Spryker\Zed\Kernel\Communication\AbstractCommunicationFactory; /** - * @method \Spryker\Zed\Customer\Persistence\CustomerQueryContainer getQueryContainer() + * @method \Spryker\Zed\Customer\Persistence\CustomerQueryContainerInterface getQueryContainer() * @method \Spryker\Zed\Customer\CustomerConfig getConfig() */ class CustomerCommunicationFactory extends AbstractCommunicationFactory @@ -42,7 +42,7 @@ public function createCustomerTable() */ public function createCustomerAddressTable($idCustomer) { - return new AddressTable($this->getQueryContainer(), $idCustomer); + return new AddressTable($this->getQueryContainer(), $idCustomer, $this->getUtilSanitizeService()); } /** @@ -127,4 +127,12 @@ public function getCustomerTransferExpanderPlugins() { return $this->getProvidedDependency(CustomerDependencyProvider::PLUGINS_CUSTOMER_TRANSFER_EXPANDER); } + + /** + * @return \Spryker\Zed\Customer\Dependency\Service\CustomerToUtilSanitizeServiceInterface + */ + protected function getUtilSanitizeService() + { + return $this->getProvidedDependency(CustomerDependencyProvider::SERVICE_UTIL_SANITIZE); + } } diff --git a/src/Spryker/Zed/Customer/Communication/Form/AddressForm.php b/src/Spryker/Zed/Customer/Communication/Form/AddressForm.php index 84f7e8bc..29b17d4f 100644 --- a/src/Spryker/Zed/Customer/Communication/Form/AddressForm.php +++ b/src/Spryker/Zed/Customer/Communication/Form/AddressForm.php @@ -10,7 +10,6 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Required; @@ -53,18 +52,6 @@ public function configureOptions(OptionsResolver $resolver) ]); } - /** - * @deprecated Use `configureOptions()` instead. - * - * @param \Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver - * - * @return void - */ - public function setDefaultOptions(OptionsResolverInterface $resolver) - { - $this->configureOptions($resolver); - } - /** * @param \Symfony\Component\Form\FormBuilderInterface $builder * @param array $options diff --git a/src/Spryker/Zed/Customer/Communication/Form/CustomerForm.php b/src/Spryker/Zed/Customer/Communication/Form/CustomerForm.php index 9fc617d0..d069b98e 100644 --- a/src/Spryker/Zed/Customer/Communication/Form/CustomerForm.php +++ b/src/Spryker/Zed/Customer/Communication/Form/CustomerForm.php @@ -11,7 +11,6 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\Length; @@ -64,18 +63,6 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setRequired(self::OPTION_GENDER_CHOICES); } - /** - * @deprecated Use `configureOptions()` instead. - * - * @param \Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver - * - * @return void - */ - public function setDefaultOptions(OptionsResolverInterface $resolver) - { - $this->configureOptions($resolver); - } - /** * @param \Symfony\Component\Form\FormBuilderInterface $builder * @param array $options diff --git a/src/Spryker/Zed/Customer/Communication/Form/CustomerUpdateForm.php b/src/Spryker/Zed/Customer/Communication/Form/CustomerUpdateForm.php index 6d2d26ab..27866a77 100644 --- a/src/Spryker/Zed/Customer/Communication/Form/CustomerUpdateForm.php +++ b/src/Spryker/Zed/Customer/Communication/Form/CustomerUpdateForm.php @@ -9,7 +9,6 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\OptionsResolver\OptionsResolverInterface; class CustomerUpdateForm extends CustomerForm { @@ -30,18 +29,6 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setRequired(self::OPTION_ADDRESS_CHOICES); } - /** - * @deprecated Use `configureOptions()` instead. - * - * @param \Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver - * - * @return void - */ - public function setDefaultOptions(OptionsResolverInterface $resolver) - { - $this->configureOptions($resolver); - } - /** * @param \Symfony\Component\Form\FormBuilderInterface $builder * @param array $options diff --git a/src/Spryker/Zed/Customer/Communication/Plugin/CustomerPreConditionCheckerPlugin.php b/src/Spryker/Zed/Customer/Communication/Plugin/CustomerPreConditionCheckerPlugin.php index 9a4e8969..8084f225 100644 --- a/src/Spryker/Zed/Customer/Communication/Plugin/CustomerPreConditionCheckerPlugin.php +++ b/src/Spryker/Zed/Customer/Communication/Plugin/CustomerPreConditionCheckerPlugin.php @@ -13,7 +13,7 @@ use Spryker\Zed\Kernel\Communication\AbstractPlugin; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class CustomerPreConditionCheckerPlugin extends AbstractPlugin implements CheckoutPreConditionInterface diff --git a/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRegistrationMailTypePlugin.php b/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRegistrationMailTypePlugin.php index 1ee359d4..51190da2 100644 --- a/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRegistrationMailTypePlugin.php +++ b/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRegistrationMailTypePlugin.php @@ -12,7 +12,7 @@ use Spryker\Zed\Mail\Dependency\Plugin\MailTypePluginInterface; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class CustomerRegistrationMailTypePlugin extends AbstractPlugin implements MailTypePluginInterface diff --git a/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRestorePasswordMailTypePlugin.php b/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRestorePasswordMailTypePlugin.php index 797ac6d4..bbc293f0 100644 --- a/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRestorePasswordMailTypePlugin.php +++ b/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRestorePasswordMailTypePlugin.php @@ -12,7 +12,7 @@ use Spryker\Zed\Mail\Dependency\Plugin\MailTypePluginInterface; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class CustomerRestorePasswordMailTypePlugin extends AbstractPlugin implements MailTypePluginInterface diff --git a/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRestoredPasswordConfirmationMailTypePlugin.php b/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRestoredPasswordConfirmationMailTypePlugin.php index ef02934c..c5393401 100644 --- a/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRestoredPasswordConfirmationMailTypePlugin.php +++ b/src/Spryker/Zed/Customer/Communication/Plugin/Mail/CustomerRestoredPasswordConfirmationMailTypePlugin.php @@ -12,7 +12,7 @@ use Spryker\Zed\Mail\Dependency\Plugin\MailTypePluginInterface; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class CustomerRestoredPasswordConfirmationMailTypePlugin extends AbstractPlugin implements MailTypePluginInterface diff --git a/src/Spryker/Zed/Customer/Communication/Plugin/OrderCustomerSavePlugin.php b/src/Spryker/Zed/Customer/Communication/Plugin/OrderCustomerSavePlugin.php index 756dd732..1f261ac9 100644 --- a/src/Spryker/Zed/Customer/Communication/Plugin/OrderCustomerSavePlugin.php +++ b/src/Spryker/Zed/Customer/Communication/Plugin/OrderCustomerSavePlugin.php @@ -13,7 +13,7 @@ use Spryker\Zed\Kernel\Communication\AbstractPlugin; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class OrderCustomerSavePlugin extends AbstractPlugin implements CheckoutSaveOrderInterface diff --git a/src/Spryker/Zed/Customer/Communication/Plugin/Sales/CustomerOrderHydratePlugin.php b/src/Spryker/Zed/Customer/Communication/Plugin/Sales/CustomerOrderHydratePlugin.php index d920cc2a..8aac0581 100644 --- a/src/Spryker/Zed/Customer/Communication/Plugin/Sales/CustomerOrderHydratePlugin.php +++ b/src/Spryker/Zed/Customer/Communication/Plugin/Sales/CustomerOrderHydratePlugin.php @@ -12,7 +12,7 @@ use Spryker\Zed\Sales\Dependency\Plugin\HydrateOrderPluginInterface; /** - * @method \Spryker\Zed\Customer\Business\CustomerFacade getFacade() + * @method \Spryker\Zed\Customer\Business\CustomerFacadeInterface getFacade() * @method \Spryker\Zed\Customer\Communication\CustomerCommunicationFactory getFactory() */ class CustomerOrderHydratePlugin extends AbstractPlugin implements HydrateOrderPluginInterface diff --git a/src/Spryker/Zed/Customer/Communication/Table/AddressTable.php b/src/Spryker/Zed/Customer/Communication/Table/AddressTable.php index 303cf4db..f0e73536 100644 --- a/src/Spryker/Zed/Customer/Communication/Table/AddressTable.php +++ b/src/Spryker/Zed/Customer/Communication/Table/AddressTable.php @@ -9,6 +9,7 @@ use Orm\Zed\Customer\Persistence\Map\SpyCustomerAddressTableMap; use Spryker\Shared\Customer\CustomerConstants; +use Spryker\Zed\Customer\Dependency\Service\CustomerToUtilSanitizeServiceInterface; use Spryker\Zed\Customer\Persistence\CustomerQueryContainerInterface; use Spryker\Zed\Gui\Communication\Table\AbstractTable; use Spryker\Zed\Gui\Communication\Table\TableConfiguration; @@ -32,14 +33,24 @@ class AddressTable extends AbstractTable */ protected $idCustomer; + /** + * @var \Spryker\Zed\Customer\Dependency\Service\CustomerToUtilSanitizeServiceInterface + */ + protected $utilSanitize; + /** * @param \Spryker\Zed\Customer\Persistence\CustomerQueryContainerInterface $customerQueryContainer * @param int $idCustomer + * @param \Spryker\Zed\Customer\Dependency\Service\CustomerToUtilSanitizeServiceInterface $utilSanitize */ - public function __construct(CustomerQueryContainerInterface $customerQueryContainer, $idCustomer) - { + public function __construct( + CustomerQueryContainerInterface $customerQueryContainer, + $idCustomer, + CustomerToUtilSanitizeServiceInterface $utilSanitize + ) { $this->customerQueryContainer = $customerQueryContainer; $this->idCustomer = $idCustomer; + $this->utilSanitize = $utilSanitize; } /** @@ -125,7 +136,8 @@ protected function prepareData(TableConfiguration $config) $tags[] = 'SHIPPING'; } - $lines[$key][SpyCustomerAddressTableMap::COL_ADDRESS1] = (!empty($tags) ? implode(' ', $tags) . ' ' : '') . $lines[$key][SpyCustomerAddressTableMap::COL_ADDRESS1]; + $address = $this->utilSanitize->escapeHtml($lines[$key][SpyCustomerAddressTableMap::COL_ADDRESS1]); + $lines[$key][SpyCustomerAddressTableMap::COL_ADDRESS1] = (!empty($tags) ? implode(' ', $tags) . ' ' : '') . $address; $lines[$key][self::ACTIONS] = $this->buildLinks($value); } diff --git a/src/Spryker/Zed/Customer/CustomerConfig.php b/src/Spryker/Zed/Customer/CustomerConfig.php index 2072bfbd..d38fb1b7 100644 --- a/src/Spryker/Zed/Customer/CustomerConfig.php +++ b/src/Spryker/Zed/Customer/CustomerConfig.php @@ -16,16 +16,14 @@ class CustomerConfig extends AbstractBundleConfig { const ERROR_CODE_CUSTOMER_ALREADY_REGISTERED = 4001; + const ERROR_CODE_CUSTOMER_INVALID_EMAIL = 4002; /** * @return string */ public function getHostYves() { - return $this->getConfig()->hasKey(CustomerConstants::BASE_URL_YVES) - ? $this->get(CustomerConstants::BASE_URL_YVES) - // @deprecated this is just for backward compatibility - : $this->get(CustomerConstants::HOST_YVES); + return $this->get(CustomerConstants::BASE_URL_YVES); } /** diff --git a/src/Spryker/Zed/Customer/CustomerDependencyProvider.php b/src/Spryker/Zed/Customer/CustomerDependencyProvider.php index 775404d9..53b92500 100644 --- a/src/Spryker/Zed/Customer/CustomerDependencyProvider.php +++ b/src/Spryker/Zed/Customer/CustomerDependencyProvider.php @@ -12,18 +12,25 @@ use Spryker\Zed\Customer\Dependency\Facade\CustomerToLocaleBridge; use Spryker\Zed\Customer\Dependency\Facade\CustomerToMailBridge; use Spryker\Zed\Customer\Dependency\Facade\CustomerToSequenceNumberBridge; +use Spryker\Zed\Customer\Dependency\Service\CustomerToUtilSanitizeServiceBridge; +use Spryker\Zed\Customer\Dependency\Service\CustomerToUtilValidateServiceBridge; use Spryker\Zed\Kernel\AbstractBundleDependencyProvider; use Spryker\Zed\Kernel\Container; class CustomerDependencyProvider extends AbstractBundleDependencyProvider { - const FACADE_SEQUENCE_NUMBER = 'sequence number facade'; - const FACADE_COUNTRY = 'country facade'; - const FACADE_LOCALE = 'locale facade'; - const FACADE_MAIL = 'mail facade'; - const SERVICE_DATE_FORMATTER = 'date formatter service'; - const QUERY_CONTAINER_LOCALE = 'locale query container'; - const STORE = 'store'; + const FACADE_SEQUENCE_NUMBER = 'FACADE_SEQUENCE_NUMBER'; + const FACADE_COUNTRY = 'FACADE_COUNTRY'; + const FACADE_LOCALE = 'FACADE_LOCALE'; + const FACADE_MAIL = 'FACADE_MAIL'; + + const SERVICE_DATE_FORMATTER = 'SERVICE_DATE_FORMATTER'; + const SERVICE_UTIL_VALIDATE = 'SERVICE_UTIL_VALIDATE'; + const SERVICE_UTIL_SANITIZE = 'SERVICE_UTIL_SANITIZE'; + + const QUERY_CONTAINER_LOCALE = 'QUERY_CONTAINER_LOCALE'; + + const STORE = 'STORE'; const PLUGINS_CUSTOMER_ANONYMIZER = 'PLUGINS_CUSTOMER_ANONYMIZER'; const PLUGINS_CUSTOMER_TRANSFER_EXPANDER = 'PLUGINS_CUSTOMER_TRANSFER_EXPANDER'; @@ -57,6 +64,7 @@ public function provideBusinessLayerDependencies(Container $container) $container = $this->addStore($container); $container = $this->addCustomerAnonymizerPlugins($container); + $container = $this->addUtilValidateService($container); return $container; } @@ -77,6 +85,7 @@ public function provideCommunicationLayerDependencies(Container $container) $container = $this->addStore($container); $container = $this->addCustomerTransferExpanderPlugins($container); + $container = $this->addUtilSanitizeService($container); return $container; } @@ -117,6 +126,20 @@ protected function addStore(Container $container) return $container; } + /** + * @param \Spryker\Zed\Kernel\Container $container + * + * @return \Spryker\Zed\Kernel\Container + */ + protected function addUtilValidateService(Container $container) + { + $container[static::SERVICE_UTIL_VALIDATE] = function (Container $container) { + return new CustomerToUtilValidateServiceBridge($container->getLocator()->utilValidate()->service()); + }; + + return $container; + } + /** * @param \Spryker\Zed\Kernel\Container $container * @@ -138,4 +161,18 @@ protected function getCustomerTransferExpanderPlugins() { return []; } + + /** + * @param \Spryker\Zed\Kernel\Container $container + * + * @return \Spryker\Zed\Kernel\Container + */ + protected function addUtilSanitizeService(Container $container) + { + $container[static::SERVICE_UTIL_SANITIZE] = function (Container $container) { + return new CustomerToUtilSanitizeServiceBridge($container->getLocator()->utilSanitize()->service()); + }; + + return $container; + } } diff --git a/src/Spryker/Zed/Customer/Dependency/Facade/CustomerToCountryBridge.php b/src/Spryker/Zed/Customer/Dependency/Facade/CustomerToCountryBridge.php index 5277c150..a680fdc4 100644 --- a/src/Spryker/Zed/Customer/Dependency/Facade/CustomerToCountryBridge.php +++ b/src/Spryker/Zed/Customer/Dependency/Facade/CustomerToCountryBridge.php @@ -40,18 +40,6 @@ public function getAvailableCountries() return $this->countryFacade->getAvailableCountries(); } - /** - * @deprecated Use getCountryByIso2Code() instead. - * - * @param string $iso2Code - * - * @return int - */ - public function getIdCountryByIso2Code($iso2Code) - { - return $this->countryFacade->getIdCountryByIso2Code($iso2Code); - } - /** * @param string $iso2Code * diff --git a/src/Spryker/Zed/Customer/Dependency/Facade/CustomerToCountryInterface.php b/src/Spryker/Zed/Customer/Dependency/Facade/CustomerToCountryInterface.php index f3f39a6e..a7d2a7ee 100644 --- a/src/Spryker/Zed/Customer/Dependency/Facade/CustomerToCountryInterface.php +++ b/src/Spryker/Zed/Customer/Dependency/Facade/CustomerToCountryInterface.php @@ -9,15 +9,6 @@ interface CustomerToCountryInterface { - /** - * @deprecated Use getCountryByIso2Code() instead. - * - * @param string $iso2Code - * - * @return int - */ - public function getIdCountryByIso2Code($iso2Code); - /** * @param string $countryName * diff --git a/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilSanitizeServiceBridge.php b/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilSanitizeServiceBridge.php new file mode 100644 index 00000000..1ebc3b24 --- /dev/null +++ b/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilSanitizeServiceBridge.php @@ -0,0 +1,36 @@ +utilSanitizeService = $utilSanitizeService; + } + + /** + * @param string $text + * @param bool $double + * @param string|null $charset + * + * @return string + */ + public function escapeHtml($text, $double = true, $charset = null) + { + return $this->utilSanitizeService->escapeHtml($text, $double, $charset); + } +} diff --git a/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilSanitizeServiceInterface.php b/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilSanitizeServiceInterface.php new file mode 100644 index 00000000..09efe321 --- /dev/null +++ b/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilSanitizeServiceInterface.php @@ -0,0 +1,20 @@ +utilValidateService = $utilValidateService; + } + + /** + * @param string $email + * + * @return string + */ + public function isEmailFormatValid($email) + { + return $this->utilValidateService->isEmailFormatValid($email); + } +} diff --git a/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilValidateServiceInterface.php b/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilValidateServiceInterface.php new file mode 100644 index 00000000..9c0bea9f --- /dev/null +++ b/src/Spryker/Zed/Customer/Dependency/Service/CustomerToUtilValidateServiceInterface.php @@ -0,0 +1,18 @@ + - - + + diff --git a/src/Spryker/Zed/Customer/Presentation/Add/index.twig b/src/Spryker/Zed/Customer/Presentation/Add/index.twig index 8f5722b9..f977b435 100644 --- a/src/Spryker/Zed/Customer/Presentation/Add/index.twig +++ b/src/Spryker/Zed/Customer/Presentation/Add/index.twig @@ -18,7 +18,7 @@ {{ form_start(form) }} {{ form_widget(form) }} - + {{ form_end(form) }} {% endblock %} diff --git a/src/Spryker/Zed/Customer/Presentation/Delete/index.twig b/src/Spryker/Zed/Customer/Presentation/Delete/index.twig index db0eba65..0b17eb5b 100644 --- a/src/Spryker/Zed/Customer/Presentation/Delete/index.twig +++ b/src/Spryker/Zed/Customer/Presentation/Delete/index.twig @@ -16,7 +16,7 @@ {% block widget_content %} {{ 'Back' | trans}} - {{ 'Delete account' | trans}} + {{ 'Delete account' | trans}} {% endblock %} diff --git a/src/Spryker/Zed/Customer/Presentation/Edit/index.twig b/src/Spryker/Zed/Customer/Presentation/Edit/index.twig index de895d19..907dabd8 100644 --- a/src/Spryker/Zed/Customer/Presentation/Edit/index.twig +++ b/src/Spryker/Zed/Customer/Presentation/Edit/index.twig @@ -20,7 +20,7 @@ {{ form_start(form) }} {{ form_widget(form) }} - + {{ form_end(form) }} {% endblock %} diff --git a/tests/SprykerTest/Zed/Customer/Business/CustomerFacadeTest.php b/tests/SprykerTest/Zed/Customer/Business/CustomerFacadeTest.php index 8093c987..9809dfd2 100644 --- a/tests/SprykerTest/Zed/Customer/Business/CustomerFacadeTest.php +++ b/tests/SprykerTest/Zed/Customer/Business/CustomerFacadeTest.php @@ -9,14 +9,19 @@ use Codeception\Test\Unit; use Generated\Shared\Transfer\AddressTransfer; +use Generated\Shared\Transfer\CheckoutResponseTransfer; use Generated\Shared\Transfer\CustomerTransfer; +use Generated\Shared\Transfer\QuoteTransfer; use Spryker\Shared\Kernel\Transfer\TransferInterface; use Spryker\Zed\Customer\Business\Customer\Address; use Spryker\Zed\Customer\Business\Customer\Customer; use Spryker\Zed\Customer\Business\CustomerBusinessFactory; use Spryker\Zed\Customer\Business\CustomerFacade; +use Spryker\Zed\Customer\Business\Exception\CustomerNotFoundException; +use Spryker\Zed\Customer\Business\Model\PreConditionChecker; use Spryker\Zed\Customer\CustomerDependencyProvider; use Spryker\Zed\Customer\Dependency\Facade\CustomerToMailInterface; +use Spryker\Zed\Customer\Dependency\Service\CustomerToUtilValidateServiceInterface; use Spryker\Zed\Kernel\Container; /** @@ -32,18 +37,30 @@ class CustomerFacadeTest extends Unit { const TESTER_EMAIL = 'tester@spryker.com'; + const TESTER_INVALID_EMAIL = 'tester<>@spryker.com'; const TESTER_NON_EXISTING_EMAIL = 'nonexisting@spryker.com'; + const TESTER_UPDATE_EMAIL = 'update.tester@spryker.com'; const TESTER_PASSWORD = 'tester'; const TESTER_NAME = 'Tester'; const TESTER_CITY = 'Testcity'; const TESTER_ADDRESS1 = 'Testerstreet 23'; const TESTER_ZIP_CODE = '42'; + /** + * @var \SprykerTest\Zed\Customer\CustomerBusinessTester + */ + protected $tester; + /** * @var \Spryker\Zed\Customer\Business\CustomerFacadeInterface */ protected $customerFacade; + /** + * @var \Spryker\Zed\Kernel\Container + */ + protected $businessLayerDependencies; + /** * @return void */ @@ -71,13 +88,13 @@ protected function getBusinessFactory() protected function getContainer() { $dependencyProvider = new CustomerDependencyProvider(); - $container = new Container(); + $this->businessLayerDependencies = new Container(); - $dependencyProvider->provideBusinessLayerDependencies($container); + $dependencyProvider->provideBusinessLayerDependencies($this->businessLayerDependencies); - $container[CustomerDependencyProvider::FACADE_MAIL] = $this->getMockBuilder(CustomerToMailInterface::class)->getMock(); + $this->businessLayerDependencies[CustomerDependencyProvider::FACADE_MAIL] = $this->getMockBuilder(CustomerToMailInterface::class)->getMock(); - return $container; + return $this->businessLayerDependencies; } /** @@ -201,6 +218,59 @@ public function testRegisterCustomerWithAlreadyExistingEmail() $this->assertFalse($customerResponseTransfer->getIsSuccess()); } + /** + * @return void + */ + public function testRegisterCustomerFailsWhenInvalidEmailFormatIsProvided() + { + // Assign + $this->mockUtilValidateService(false); + $customerTransfer = $this->createTestCustomerTransfer(); + + // Act + $customerResponseTransfer = $this->customerFacade->registerCustomer($customerTransfer); + + // Assert + $this->assertFalse($customerResponseTransfer->getIsSuccess()); + } + + /** + * @uses UtilValidateServiceInterface::isEmailFormatValid() + * + * @param bool $isEmailFormatValid + * + * @return void + */ + protected function mockUtilValidateService($isEmailFormatValid) + { + $serviceMock = $this->getMockBuilder(CustomerToUtilValidateServiceInterface::class) + ->setMethods(['isEmailFormatValid']) + ->getMock(); + + $serviceMock + ->expects($this->any()) + ->method('isEmailFormatValid') + ->willReturn($isEmailFormatValid); + + $this->businessLayerDependencies[CustomerDependencyProvider::SERVICE_UTIL_VALIDATE] = $serviceMock; + } + + /** + * @return void + */ + public function testRegisterCustomerRegistersCustomerWithValidEmail() + { + // Assign + $customerTransfer = $this->createTestCustomerTransfer(); + $this->mockUtilValidateService(true); + + // Act + $customerResponseTransfer = $this->customerFacade->registerCustomer($customerTransfer); + + // Assert + $this->assertTrue($customerResponseTransfer->getIsSuccess()); + } + /** * @return void */ @@ -265,6 +335,39 @@ public function testUpdateCustomer() $this->assertEquals(self::TESTER_NAME, $customerTransfer->getLastName()); } + /** + * @return void + */ + public function testUpdateCustomerFailsWhenInvalidEmailFormatIsProvided() + { + // Assign + $customerTransfer = $this->createTestCustomer(); + $this->mockUtilValidateService(false); + + // Act + $customerResponse = $this->customerFacade->updateCustomer($customerTransfer); + + // Assert + $this->assertFalse($customerResponse->getIsSuccess()); + } + + /** + * @return void + */ + public function testUpdateCustomerUpdatesValidEmail() + { + // Assign + $customerTransfer = $this->createTestCustomer(); + $customerTransfer->setPassword("other password"); + $this->mockUtilValidateService(true); + + // Act + $customerResponse = $this->customerFacade->updateCustomer($customerTransfer); + + // Assert + $this->assertTrue($customerResponse->getIsSuccess()); + } + /** * @return void */ @@ -479,6 +582,183 @@ public function testDeleteCustomerWithDefaultAddresses() $this->customerFacade->getAddress($addressTransfer); } + /** + * @return void + */ + public function testCheckOrderPreSaveConditionsDoesNotValidateEmailForRegisteredCustomer() + { + // Assign + $dummyIdCustomer = 11111; + $quoteTransfer = (new QuoteTransfer()) + ->setCustomer( + (new CustomerTransfer()) + ->setIdCustomer($dummyIdCustomer) + ->setEmail(static::TESTER_INVALID_EMAIL) + ); + $checkoutResponseTransfer = new CheckoutResponseTransfer(); + + // Act + $this->customerFacade->checkOrderPreSaveConditions($quoteTransfer, $checkoutResponseTransfer); + + // Assert + $this->assertFalse($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_INVALID)); + } + + /** + * @return void + */ + public function testCheckOrderPreSaveConditionsDoesNotCheckUniqueEmailForRegisteredCustomer() + { + // Assign + $dummyCustomerId = 11111; + $email = 'occupied@spryker.com'; + $this->tester->haveCustomer(['email' => $email]); + + $quoteTransfer = (new QuoteTransfer()) + ->setCustomer( + (new CustomerTransfer()) + ->setIdCustomer($dummyCustomerId) + ->setEmail($email) + ); + $checkoutResponseTransfer = new CheckoutResponseTransfer(); + + // Act + $this->customerFacade->checkOrderPreSaveConditions($quoteTransfer, $checkoutResponseTransfer); + + // Assert + $this->assertFalse($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_UNIQUE)); + } + + /** + * @return void + */ + public function testCheckOrderPreSaveConditionsReturnsErrorIfEmailIsInvalidForGuest() + { + // Assign + $quoteTransfer = (new QuoteTransfer()) + ->setCustomer( + (new CustomerTransfer()) + ->setIsGuest(true) + ->setEmail(static::TESTER_INVALID_EMAIL) + ); + $checkoutResponseTransfer = new CheckoutResponseTransfer(); + + // Act + $this->customerFacade->checkOrderPreSaveConditions($quoteTransfer, $checkoutResponseTransfer); + + // Assert + $this->assertTrue($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_INVALID)); + } + + /** + * @return void + */ + public function testCheckOrderPreSaveConditionsReturnsNoErrorIfEmailIsValidForGuest() + { + // Assign + $quoteTransfer = (new QuoteTransfer()) + ->setCustomer( + (new CustomerTransfer()) + ->setIsGuest(true) + ->setEmail(static::TESTER_EMAIL) + ); + $checkoutResponseTransfer = new CheckoutResponseTransfer(); + + // Act + $this->customerFacade->checkOrderPreSaveConditions($quoteTransfer, $checkoutResponseTransfer); + + // Assert + $this->assertFalse($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_INVALID)); + } + + /** + * @return void + */ + public function testCheckOrderPreSaveConditionsDoesNotCheckUniqueEmailForGuest() + { + // Assign + $email = 'occupied@spryker.com'; + $this->tester->haveCustomer(['email' => $email]); + + $quoteTransfer = (new QuoteTransfer()) + ->setCustomer( + (new CustomerTransfer()) + ->setIsGuest(true) + ->setEmail($email) + ); + $checkoutResponseTransfer = new CheckoutResponseTransfer(); + + // Act + $this->customerFacade->checkOrderPreSaveConditions($quoteTransfer, $checkoutResponseTransfer); + + // Assert + $this->assertFalse($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_UNIQUE)); + } + + /** + * @return void + */ + public function testCheckOrderPreSaveConditionsReturnsErrorIfEmailIsInvalidForNewCustomer() + { + // Assign + $quoteTransfer = (new QuoteTransfer()) + ->setCustomer( + (new CustomerTransfer()) + ->setEmail(static::TESTER_INVALID_EMAIL) + ); + $checkoutResponseTransfer = new CheckoutResponseTransfer(); + + // Act + $this->customerFacade->checkOrderPreSaveConditions($quoteTransfer, $checkoutResponseTransfer); + + // Assert + $this->assertTrue($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_INVALID)); + } + + /** + * @return void + */ + public function testCheckOrderPreSaveConditionsReturnsErrorIfEmailIsNotUniqueForNewCustomer() + { + // Assign + $email = 'occupied@spryker.com'; + $this->tester->haveCustomer(['email' => $email]); + + $quoteTransfer = (new QuoteTransfer()) + ->setCustomer( + (new CustomerTransfer()) + ->setEmail($email) + ); + $checkoutResponseTransfer = new CheckoutResponseTransfer(); + + // Act + $this->customerFacade->checkOrderPreSaveConditions($quoteTransfer, $checkoutResponseTransfer); + + // Assert + $this->assertTrue($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_UNIQUE)); + } + + /** + * @return void + */ + public function testCheckOrderPreSaveConditionsReturnsNoErrorIfEmailIsValidAndUniqueForNewCustomer() + { + // Assign + $quoteTransfer = (new QuoteTransfer()) + ->setCustomer( + (new CustomerTransfer()) + ->setEmail(static::TESTER_EMAIL) + ); + $checkoutResponseTransfer = new CheckoutResponseTransfer(); + + // Act + $this->customerFacade->checkOrderPreSaveConditions($quoteTransfer, $checkoutResponseTransfer); + + // Assert + $this->assertFalse($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_UNIQUE)); + $this->assertFalse($this->hasCheckoutErrorMessage($checkoutResponseTransfer, PreConditionChecker::ERROR_EMAIL_INVALID)); + } + /** * @param \Spryker\Shared\Kernel\Transfer\TransferInterface|null $transfer * @param bool $hasEmail @@ -636,4 +916,37 @@ public function testUpdateCustomerPassword() $this->assertSame($customerTransfer, $facade->updateCustomerPassword($customerTransfer)); } + + /** + * @return void + */ + public function testAnonymizeCustomer() + { + // Assign + $customerTransfer = $this->createTestCustomer(); + + // Act + $this->customerFacade->anonymizeCustomer($customerTransfer); + + // Assert + $this->expectException(CustomerNotFoundException::class); + $this->customerFacade->getCustomer($customerTransfer); + } + + /** + * @param \Generated\Shared\Transfer\CheckoutResponseTransfer $checkoutResponseTransfer + * @param string $errorMessage + * + * @return bool + */ + protected function hasCheckoutErrorMessage(CheckoutResponseTransfer $checkoutResponseTransfer, $errorMessage) + { + foreach ($checkoutResponseTransfer->getErrors() as $errorTransfer) { + if ($errorTransfer->getMessage() === $errorMessage) { + return true; + } + } + + return false; + } } diff --git a/tests/SprykerTest/Zed/Customer/codeception.yml b/tests/SprykerTest/Zed/Customer/codeception.yml index e4611710..0ad65614 100644 --- a/tests/SprykerTest/Zed/Customer/codeception.yml +++ b/tests/SprykerTest/Zed/Customer/codeception.yml @@ -23,6 +23,7 @@ suites: - \SprykerTest\Shared\Testify\Helper\LocatorHelper - \SprykerTest\Shared\Testify\Helper\DependencyHelper - \SprykerTest\Shared\Propel\Helper\TransactionHelper + - \SprykerTest\Shared\Customer\Helper\CustomerDataHelper Communication: path: Communication @@ -41,4 +42,13 @@ suites: depends: \SprykerTest\Shared\Testify\Helper\ZedBootstrap - \SprykerTest\Shared\Testify\Helper\ZedBootstrap: depends: \SprykerTest\Shared\Testify\Helper\BundleConfig + serviceProvider: + - Spryker\Shared\Application\ServiceProvider\FormFactoryServiceProvider + - Spryker\Zed\Application\Communication\Plugin\ServiceProvider\MvcRoutingServiceProvider + - Spryker\Zed\Application\Communication\Plugin\ServiceProvider\RoutingServiceProvider + - Spryker\Zed\Application\Communication\Plugin\ServiceProvider\RequestServiceProvider + - Spryker\Zed\Application\Communication\Plugin\ServiceProvider\TranslationServiceProvider + - Spryker\Zed\Gui\Communication\Plugin\ServiceProvider\GuiTwigExtensionServiceProvider + - Spryker\Zed\Twig\Communication\Plugin\ServiceProvider\TwigServiceProvider + - Spryker\Zed\ZedNavigation\Communication\Plugin\ServiceProvider\ZedNavigationServiceProvider - \SprykerTest\Shared\Customer\Helper\CustomerDataHelper