_formKeyValidator = $formKeyValidator; $this->_customerSession = $customerSession; $this->wishlistProvider = $wishlistProvider; $this->_wishlistConfig = $wishlistConfig; $this->_transportBuilder = $transportBuilder; $this->inlineTranslation = $inlineTranslation; $this->_customerHelperView = $customerHelperView; $this->wishlistSession = $wishlistSession; $this->scopeConfig = $scopeConfig; $this->storeManager = $storeManager; $this->captchaHelper = $captchaHelper ?: ObjectManager::getInstance()->get(CaptchaHelper::class); $this->captchaStringResolver = $captchaStringResolver ? : ObjectManager::getInstance()->get(CaptchaStringResolver::class); parent::__construct($context); } /** * Share wishlist * * @return \Magento\Framework\Controller\Result\Redirect * @throws NotFoundException * @throws \Zend_Validate_Exception * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function execute() { /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); $captchaForName = 'share_wishlist_form'; /** @var CaptchaModel $captchaModel */ $captchaModel = $this->captchaHelper->getCaptcha($captchaForName); if (!$this->_formKeyValidator->validate($this->getRequest())) { $resultRedirect->setPath('*/*/'); return $resultRedirect; } $isCorrectCaptcha = $this->validateCaptcha($captchaModel, $captchaForName); $this->logCaptchaAttempt($captchaModel); if (!$isCorrectCaptcha) { $this->messageManager->addErrorMessage(__('Incorrect CAPTCHA')); $resultRedirect->setPath('*/*/share'); return $resultRedirect; } $wishlist = $this->wishlistProvider->getWishlist(); if (!$wishlist) { throw new NotFoundException(__('Page not found.')); } $sharingLimit = $this->_wishlistConfig->getSharingEmailLimit(); $textLimit = $this->_wishlistConfig->getSharingTextLimit(); $emailsLeft = $sharingLimit - $wishlist->getShared(); $emails = $this->getRequest()->getPost('emails'); $emails = empty($emails) ? $emails : explode(',', $emails); $error = false; $message = (string)$this->getRequest()->getPost('message'); if (strlen($message) > $textLimit) { $error = __('Message length must not exceed %1 symbols', $textLimit); } else { $message = nl2br(htmlspecialchars($message)); if (empty($emails)) { $error = __('Please enter an email address.'); } else { if (count($emails) > $emailsLeft) { $error = __('This wish list can be shared %1 more times.', $emailsLeft); } else { foreach ($emails as $index => $email) { $email = trim($email); if (!\Zend_Validate::is($email, \Magento\Framework\Validator\EmailAddress::class)) { $error = __('Please enter a valid email address.'); break; } $emails[$index] = $email; } } } } if ($error) { $this->messageManager->addError($error); $this->wishlistSession->setSharingForm($this->getRequest()->getPostValue()); $resultRedirect->setPath('*/*/share'); return $resultRedirect; } /** @var \Magento\Framework\View\Result\Layout $resultLayout */ $resultLayout = $this->resultFactory->create(ResultFactory::TYPE_LAYOUT); $this->addLayoutHandles($resultLayout); $this->inlineTranslation->suspend(); $sent = 0; try { $customer = $this->_customerSession->getCustomerDataObject(); $customerName = $this->_customerHelperView->getCustomerName($customer); $message .= $this->getRssLink($wishlist->getId(), $resultLayout); $emails = array_unique($emails); $sharingCode = $wishlist->getSharingCode(); try { foreach ($emails as $email) { $transport = $this->_transportBuilder->setTemplateIdentifier( $this->scopeConfig->getValue( 'wishlist/email/email_template', \Magento\Store\Model\ScopeInterface::SCOPE_STORE ) )->setTemplateOptions( [ 'area' => \Magento\Framework\App\Area::AREA_FRONTEND, 'store' => $this->storeManager->getStore()->getStoreId(), ] )->setTemplateVars( [ 'customer' => $customer, 'customerName' => $customerName, 'salable' => $wishlist->isSalable() ? 'yes' : '', 'items' => $this->getWishlistItems($resultLayout), 'viewOnSiteLink' => $this->_url->getUrl('*/shared/index', ['code' => $sharingCode]), 'message' => $message, 'store' => $this->storeManager->getStore(), ] )->setFrom( $this->scopeConfig->getValue( 'wishlist/email/email_identity', \Magento\Store\Model\ScopeInterface::SCOPE_STORE ) )->addTo( $email )->getTransport(); $transport->sendMessage(); $sent++; } } catch (\Exception $e) { $wishlist->setShared($wishlist->getShared() + $sent); $wishlist->save(); throw $e; } $wishlist->setShared($wishlist->getShared() + $sent); $wishlist->save(); $this->inlineTranslation->resume(); $this->_eventManager->dispatch('wishlist_share', ['wishlist' => $wishlist]); $this->messageManager->addSuccess(__('Your wish list has been shared.')); $resultRedirect->setPath('*/*', ['wishlist_id' => $wishlist->getId()]); return $resultRedirect; } catch (\Exception $e) { $this->inlineTranslation->resume(); $this->messageManager->addError($e->getMessage()); $this->wishlistSession->setSharingForm($this->getRequest()->getPostValue()); $resultRedirect->setPath('*/*/share'); return $resultRedirect; } } /** * Prepare to load additional email blocks * * Add 'wishlist_email_rss' layout handle. * Add 'wishlist_email_items' layout handle. * * @param \Magento\Framework\View\Result\Layout $resultLayout * @return void */ protected function addLayoutHandles(ResultLayout $resultLayout) { if ($this->getRequest()->getParam('rss_url')) { $resultLayout->addHandle('wishlist_email_rss'); } $resultLayout->addHandle('wishlist_email_items'); } /** * Retrieve RSS link content (html) * * @param int $wishlistId * @param \Magento\Framework\View\Result\Layout $resultLayout * @return mixed */ protected function getRssLink($wishlistId, ResultLayout $resultLayout) { if ($this->getRequest()->getParam('rss_url')) { return $resultLayout->getLayout() ->getBlock('wishlist.email.rss') ->setWishlistId($wishlistId) ->toHtml(); } } /** * Retrieve wishlist items content (html) * * @param \Magento\Framework\View\Result\Layout $resultLayout * @return string */ protected function getWishlistItems(ResultLayout $resultLayout) { return $resultLayout->getLayout() ->getBlock('wishlist.email.items') ->toHtml(); } /** * Log customer action attempts * * @param CaptchaModel $captchaModel * @return void */ private function logCaptchaAttempt(CaptchaModel $captchaModel): void { /** @var Customer $customer */ $customer = $this->_customerSession->getCustomer(); $email = ''; if ($customer->getId()) { $email = $customer->getEmail(); } $captchaModel->logAttempt($email); } /** * Captcha validate logic * * @param CaptchaModel $captchaModel * @param string $captchaFormName * @return bool */ private function validateCaptcha(CaptchaModel $captchaModel, string $captchaFormName) : bool { if ($captchaModel->isRequired()) { $word = $this->captchaStringResolver->resolve( $this->getRequest(), $captchaFormName ); if (!$captchaModel->isCorrect($word)) { return false; } } return true; } }