From 607773051b9a7c409d69be3578909de114295749 Mon Sep 17 00:00:00 2001 From: Roman Leshchenko Date: Wed, 11 Jul 2018 14:34:50 +0300 Subject: [PATCH 001/526] MAGETWO-90468: Added posibility to use captcha on share wishlist page --- .../Wishlist/Controller/Index/Send.php | 41 ++++++++++++++++++- app/code/Magento/Wishlist/etc/config.xml | 22 ++++++++++ .../frontend/layout/wishlist_index_share.xml | 17 +++++++- .../view/frontend/templates/sharing.phtml | 1 + 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Wishlist/Controller/Index/Send.php b/app/code/Magento/Wishlist/Controller/Index/Send.php index c2389af6a2282..780f4d94f04d9 100644 --- a/app/code/Magento/Wishlist/Controller/Index/Send.php +++ b/app/code/Magento/Wishlist/Controller/Index/Send.php @@ -8,11 +8,15 @@ use Magento\Framework\App\Action; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ResponseInterface; use Magento\Framework\Exception\NotFoundException; use Magento\Framework\Session\Generic as WishlistSession; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Controller\ResultFactory; use Magento\Framework\View\Result\Layout as ResultLayout; +use Magento\Captcha\Helper\Data as CaptchaHelper; +use Magento\Captcha\Observer\CaptchaStringResolver; +use Magento\Framework\App\ObjectManager; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -69,6 +73,16 @@ class Send extends \Magento\Wishlist\Controller\AbstractIndex */ protected $storeManager; + /** + * @var CaptchaHelper|null + */ + protected $captchaHelper; + + /** + * @var CaptchaStringResolver|null + */ + protected $captchaStringResolver; + /** * @param Action\Context $context * @param \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator @@ -81,6 +95,8 @@ class Send extends \Magento\Wishlist\Controller\AbstractIndex * @param WishlistSession $wishlistSession * @param ScopeConfigInterface $scopeConfig * @param StoreManagerInterface $storeManager + * @param CaptchaHelper $captchaHelper|null + * @param CaptchaStringResolver $captchaStringResolver|null * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -94,7 +110,9 @@ public function __construct( \Magento\Customer\Helper\View $customerHelperView, WishlistSession $wishlistSession, ScopeConfigInterface $scopeConfig, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + CaptchaHelper $captchaHelper = null, + CaptchaStringResolver $captchaStringResolver = null ) { $this->_formKeyValidator = $formKeyValidator; $this->_customerSession = $customerSession; @@ -106,6 +124,9 @@ public function __construct( $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); } @@ -117,16 +138,34 @@ public function __construct( * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @throws \Zend_Validate_Exception */ public function execute() { /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); + $captchaFormName = 'share_wishlist_form'; + /** @var \Magento\Captcha\Model\DefaultModel $captchaModel */ + $captchaModel = $this->captchaHelper->getCaptcha($captchaFormName); + if (!$this->_formKeyValidator->validate($this->getRequest())) { $resultRedirect->setPath('*/*/'); return $resultRedirect; } + if ($captchaModel->isRequired()) { + $word = $this->captchaStringResolver->resolve( + $this->getRequest(), + $captchaFormName + ); + + if (!$captchaModel->isCorrect($word)) { + $this->messageManager->addErrorMessage(__('Incorrect CAPTCHA')); + $resultRedirect->setPath('*/*/share'); + return $resultRedirect; + } + } + $wishlist = $this->wishlistProvider->getWishlist(); if (!$wishlist) { throw new NotFoundException(__('Page not found.')); diff --git a/app/code/Magento/Wishlist/etc/config.xml b/app/code/Magento/Wishlist/etc/config.xml index 1fec2d1baf9d4..d0e7354df41ac 100644 --- a/app/code/Magento/Wishlist/etc/config.xml +++ b/app/code/Magento/Wishlist/etc/config.xml @@ -17,6 +17,28 @@ 10 255 + + + 1 + + + + + + + + + + + + + + + + 1 + + + diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_share.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_share.xml index 09d8675f6b37e..08e1da699e2cb 100644 --- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_share.xml +++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_share.xml @@ -9,7 +9,22 @@ - + + + + share_wishlist_form + + 230 + + + 50 + + + + + + + diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml index 430ebd384c82b..ff01cb4532cc7 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml @@ -40,6 +40,7 @@ + getChildHtml('captcha'); ?>
- \ No newline at end of file + From 66f06398a11841df014464f77cca94fe01678e4e Mon Sep 17 00:00:00 2001 From: Roman Leshchenko Date: Thu, 26 Jul 2018 14:11:30 +0300 Subject: [PATCH 022/526] MAGETWO-90516: Wrong custom option behavior --- .../Product/View/Options/View/Checkable.php | 2 +- .../fieldset/options/view/checkable.phtml | 98 +++++++++---------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/View/Checkable.php b/app/code/Magento/Catalog/Block/Product/View/Options/View/Checkable.php index 45d7531a83623..6adaf56296439 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/View/Checkable.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/View/Checkable.php @@ -57,4 +57,4 @@ public function getCurrencyByStore(ProductCustomOptionValuesInterface $value) : false ); } -} \ No newline at end of file +} diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/view/checkable.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/view/checkable.phtml index 827843c8a58bc..99f7018846d0a 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/view/checkable.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/view/checkable.phtml @@ -4,39 +4,38 @@ */ $option = $this->getOption(); -if ($option): ?> - getProduct()->getPreconfiguredValues()->getData('options/' . $option->getId()); - $optionType = $option->getType(); - $arraySign = $optionType === 'checkbox' ? '[]' : ''; - $count = 1; - ?> - -
+if ($option) : ?> +getProduct()->getPreconfiguredValues()->getData('options/' . $option->getId()); +$optionType = $option->getType(); +$arraySign = $optionType === 'checkbox' ? '[]' : ''; +$count = 1; +?> - -
- - +
getValues() as $value) : ?> From 3b3edd930f4bf5a05c500dcb4722d1389f309f45 Mon Sep 17 00:00:00 2001 From: Roman Leshchenko Date: Wed, 29 Aug 2018 22:55:18 +0300 Subject: [PATCH 043/526] MAGETWO-90516: Wrong custom option behavior --- .../Catalog/Block/Product/View/Options/Select/Multiple.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/Select/Multiple.php b/app/code/Magento/Catalog/Block/Product/View/Options/Select/Multiple.php index 6395a493f7b44..56702919da5d5 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/Select/Multiple.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/Select/Multiple.php @@ -12,7 +12,7 @@ use Magento\Framework\View\Element\Html\Select; /** - * CLass represents necessary logic for dropdown and multiselect option types + * Class represents necessary logic for dropdown and multiselect option types */ class Multiple extends AbstractOptions { From c5cbfc0da9786b67a6908f9df377a2a020f54272 Mon Sep 17 00:00:00 2001 From: Roman Leshchenko Date: Fri, 31 Aug 2018 16:45:53 +0300 Subject: [PATCH 044/526] MAGETWO-92728: Fixed wrong admin notifications behavior --- .../Block/Grid/Renderer/Actions.php | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php b/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php index 6f0e42bdcbef1..3c4549ba8017c 100644 --- a/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php +++ b/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php @@ -37,28 +37,35 @@ public function __construct( */ public function render(\Magento\Framework\DataObject $row) { - $readDetailsHtml = $row->getUrl() ? '' . + $readDetailsHtml = $row->getUrl() ? '' . __('Read Details') . '' : ''; - $markAsReadHtml = !$row->getIsRead() ? '' . __( - 'Mark as Read' - ) . '' : ''; + $markAsReadHtml = !$row->getIsRead() ? '' . __( + 'Mark as Read' + ) . '' : ''; $encodedUrl = $this->_urlHelper->getEncodedUrl(); return sprintf( '%s%s%s', $readDetailsHtml, $markAsReadHtml, - $this->getUrl( - '*/*/remove/', - [ - '_current' => true, - 'id' => $row->getId(), - \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl - ] + $this->escapeHtml( + $this->getUrl( + '*/*/remove/', + [ + '_current' => true, + 'id' => $row->getId(), + \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl + ] + ) ), __('Are you sure?'), __('Remove') From c155cf4bfddb75c0f302c73fb38ae4ea77851e07 Mon Sep 17 00:00:00 2001 From: roman Date: Thu, 6 Sep 2018 12:34:38 +0300 Subject: [PATCH 045/526] MAGETWO-92728: Fixed wrong admin notifications behavior --- .../AdminNotification/Block/Grid/Renderer/Actions.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php b/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php index 3c4549ba8017c..bc25f56faaf53 100644 --- a/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php +++ b/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php @@ -38,16 +38,14 @@ public function __construct( public function render(\Magento\Framework\DataObject $row) { $readDetailsHtml = $row->getUrl() ? '' . __('Read Details') . '' : ''; $markAsReadHtml = !$row->getIsRead() ? '' . __( 'Mark as Read' ) . '' : ''; @@ -57,7 +55,6 @@ public function render(\Magento\Framework\DataObject $row) '%s%s%s', $readDetailsHtml, $markAsReadHtml, - $this->escapeHtml( $this->getUrl( '*/*/remove/', [ @@ -65,8 +62,7 @@ public function render(\Magento\Framework\DataObject $row) 'id' => $row->getId(), \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl ] - ) - ), + ), __('Are you sure?'), __('Remove') ); From f854982410be60c809549d1aa052a3fce14dc041 Mon Sep 17 00:00:00 2001 From: roman Date: Thu, 6 Sep 2018 12:36:40 +0300 Subject: [PATCH 046/526] MAGETWO-92728: Fixed wrong admin notifications behavior --- .../Block/Grid/Renderer/Actions.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php b/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php index bc25f56faaf53..e3ebd8c16fe3a 100644 --- a/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php +++ b/app/code/Magento/AdminNotification/Block/Grid/Renderer/Actions.php @@ -44,8 +44,8 @@ public function render(\Magento\Framework\DataObject $row) $markAsReadHtml = !$row->getIsRead() ? '' . __( 'Mark as Read' ) . '' : ''; @@ -55,14 +55,14 @@ public function render(\Magento\Framework\DataObject $row) '%s%s%s', $readDetailsHtml, $markAsReadHtml, - $this->getUrl( - '*/*/remove/', - [ - '_current' => true, - 'id' => $row->getId(), - \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl - ] - ), + $this->getUrl( + '*/*/remove/', + [ + '_current' => true, + 'id' => $row->getId(), + \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl + ] + ), __('Are you sure?'), __('Remove') ); From f6fe81eda4d7be7aa0c87694026fa378f7e6aeef Mon Sep 17 00:00:00 2001 From: roman Date: Mon, 24 Sep 2018 13:34:45 +0300 Subject: [PATCH 047/526] MAGETWO-90516: Wrong custom option behavior --- .../Product/View/Options/Type/Select.php | 4 +- .../Options/{ => Type}/Select/Checkable.php | 5 +- .../Options/{ => Type}/Select/Multiple.php | 2 +- .../fieldset/options/view/checkable.phtml | 113 ++++++++++-------- 4 files changed, 67 insertions(+), 57 deletions(-) rename app/code/Magento/Catalog/Block/Product/View/Options/{ => Type}/Select/Checkable.php (87%) rename app/code/Magento/Catalog/Block/Product/View/Options/{ => Type}/Select/Multiple.php (98%) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php index ff8f1ea311305..959a6e76dc1ab 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php @@ -7,8 +7,8 @@ namespace Magento\Catalog\Block\Product\View\Options\Type; use Magento\Catalog\Api\Data\ProductCustomOptionInterface; -use Magento\Catalog\Block\Product\View\Options\Select\CheckableFactory; -use Magento\Catalog\Block\Product\View\Options\Select\MultipleFactory; +use Magento\Catalog\Block\Product\View\Options\Type\Select\CheckableFactory; +use Magento\Catalog\Block\Product\View\Options\Type\Select\MultipleFactory; use Magento\Framework\App\ObjectManager; use Magento\Framework\View\Element\Template\Context; use Magento\Framework\Pricing\Helper\Data; diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/Select/Checkable.php b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select/Checkable.php similarity index 87% rename from app/code/Magento/Catalog/Block/Product/View/Options/Select/Checkable.php rename to app/code/Magento/Catalog/Block/Product/View/Options/Type/Select/Checkable.php index eac733adab5da..2b000b1e5105d 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/Select/Checkable.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select/Checkable.php @@ -4,13 +4,10 @@ * See COPYING.txt for license details. */ -namespace Magento\Catalog\Block\Product\View\Options\Select; +namespace Magento\Catalog\Block\Product\View\Options\Type\Select; use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface; use Magento\Catalog\Block\Product\View\Options\AbstractOptions; -use Magento\Framework\View\Element\Template\Context; -use Magento\Framework\Pricing\Helper\Data; -use Magento\Catalog\Helper\Data as CatalogHelper; /** * Represent necessary logic for checkbox and radio button option type diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/Select/Multiple.php b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select/Multiple.php similarity index 98% rename from app/code/Magento/Catalog/Block/Product/View/Options/Select/Multiple.php rename to app/code/Magento/Catalog/Block/Product/View/Options/Type/Select/Multiple.php index 56702919da5d5..20164b0622a6d 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/Select/Multiple.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select/Multiple.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Catalog\Block\Product\View\Options\Select; +namespace Magento\Catalog\Block\Product\View\Options\Type\Select; use Magento\Catalog\Block\Product\View\Options\AbstractOptions; use Magento\Catalog\Api\Data\ProductCustomOptionInterface; diff --git a/app/code/Magento/Catalog/view/base/templates/product/composite/fieldset/options/view/checkable.phtml b/app/code/Magento/Catalog/view/base/templates/product/composite/fieldset/options/view/checkable.phtml index ad8e87414d418..0e2635f27c4b9 100644 --- a/app/code/Magento/Catalog/view/base/templates/product/composite/fieldset/options/view/checkable.phtml +++ b/app/code/Magento/Catalog/view/base/templates/product/composite/fieldset/options/view/checkable.phtml @@ -4,84 +4,97 @@ * See COPYING.txt for license details. */ -use Magento\Catalog\Api\Data\ProductCustomOptionInterface; +// @codingStandardsIgnoreFile +use Magento\Catalog\Model\Product\Option; /** - * @var \Magento\Catalog\Block\Product\View\Options\Select\Checkable $block + * @var \Magento\Catalog\Block\Product\View\Options\Type\Select\Checkable $block */ $option = $block->getOption(); - if ($option) : ?> -getPreconfiguredValue($option); -$optionType = $option->getType(); -$arraySign = $optionType === ProductCustomOptionInterface::OPTION_TYPE_CHECKBOX ? '[]' : ''; -$count = 1; -?> + getPreconfiguredValue($option); + $optionType = $option->getType(); + $arraySign = $optionType === Option::OPTION_TYPE_CHECKBOX ? '[]' : ''; + $count = 1; + ?> -
- - -
- - -
- +
+ getIsRequire()): ?> +
+ + +
+ getValues() as $value) : ?> getOptionTypeId(), $configValue) ? 'checked' : ''; } else { $checked = $configValue == $value->getOptionTypeId() ? 'checked' : ''; } - $dataSelector = 'options[' . $option->getId() . ']'; if ($arraySign) { $dataSelector .= '[' . $value->getOptionTypeId() . ']'; } ?> -
- getIsRequire() ? 'required': '' ?>"> + - data-selector="" - price="getCurrencyByStore($value) ?>" + getSkipJsReloadPrice() ? '' : 'opConfig.reloadPrice()' ?>" + name="options[getId() ?>]" + id="options_getId() . '_' . $count ?>" + value="getOptionTypeId() ?>" + + data-selector="" + price="getCurrencyByStore($value) ?>" />
-
- - +
+ \ No newline at end of file From 1e3d575aa4a1d6b6c449ab248da7bd50de31b7bb Mon Sep 17 00:00:00 2001 From: roman Date: Tue, 16 Oct 2018 11:46:43 +0300 Subject: [PATCH 048/526] MAGETWO-88650: Wrong swatches behavior --- .../templates/cart/item/default.phtml | 2 +- .../web/template/minicart/item/default.html | 2 +- .../web/template/summary/item/details.html | 2 +- .../components/dynamic-rows-configurable.js | 11 +- .../view/frontend/web/js/swatch-renderer.js | 155 ++++++++++-------- 5 files changed, 99 insertions(+), 73 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml index 0567c61f0db60..a423d8c8a0896 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml @@ -49,7 +49,7 @@ $canApplyMsrp = $helper->isShowBeforeOrderConfirm($product) && $helper->isMinima - + escapeHtml($_formatedOptionValue['value']) ?> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html b/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html index 357b0e550af0f..41d442a76d510 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html @@ -45,7 +45,7 @@ - + diff --git a/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details.html b/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details.html index dd59bd78416c6..730ceadbd914c 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details.html @@ -35,7 +35,7 @@
-
+
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js index 01abce7696014..df800c9a64a39 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/dynamic-rows-configurable.js @@ -6,8 +6,9 @@ define([ 'underscore', 'uiRegistry', - 'Magento_Ui/js/dynamic-rows/dynamic-rows' -], function (_, registry, dynamicRows) { + 'Magento_Ui/js/dynamic-rows/dynamic-rows', + 'jquery' +], function (_, registry, dynamicRows, $) { 'use strict'; return dynamicRows.extend({ @@ -217,6 +218,8 @@ define([ _.each(tmpData, function (row, index) { path = this.dataScope + '.' + this.index + '.' + (this.startIndex + index); + row.attributes = $('').text(row.attributes).html(); + row.sku = $('').text(row.sku).html(); this.source.set(path, row); }, this); @@ -376,8 +379,8 @@ define([ product = { 'id': row.productId, 'product_link': row.productUrl, - 'name': row.name, - 'sku': row.sku, + 'name': $('').text(row.name).html(), + 'sku': $('').text(row.sku).html(), 'status': row.status, 'price': row.price, 'price_currency': row.priceCurrency, diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 1aabab8b1d5d6..e2598e3247fc5 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -396,45 +396,50 @@ define([ select = $widget._RenderSwatchSelect(item, chooseText), input = $widget._RenderFormInput(item), listLabel = '', - label = ''; + firstSpan = '', + div = '', + subDiv = '', + secondSpan = ''; // Show only swatch controls if ($widget.options.onlySwatches && !$widget.options.jsonSwatchConfig.hasOwnProperty(item.id)) { return; } - if ($widget.options.enableControlLabel) { - label += - '' + - item.label + - '' + - ''; - } - if ($widget.inProductList) { $widget.productForm.append(input); input = ''; - listLabel = 'aria-label="' + item.label + '"'; + listLabel = document.createAttribute('aria-label'); + listLabel.value = item.label; } else { - listLabel = 'aria-labelledby="' + controlLabelId + '"'; + listLabel = document.createAttribute('aria-labelledby'); + listLabel.value = controlLabelId; + } + + div = document.createElement('div'); + subDiv = document.createElement('div'); + div.setAttribute('class', classes.attributeClass + ' ' + item.code); + div.setAttribute('attribute-code', item.code); + div.setAttribute('attribute-id', item.id); + div.innerHTML = input; + subDiv.setAttribute('aria-activedescendant', ''); + subDiv.setAttribute('tabindex', 0); + subDiv.setAttribute('aria-invalid', false); + subDiv.setAttribute('aria-required', true); + subDiv.setAttribute('role', 'listbox'); + subDiv.setAttributeNode(listLabel); + subDiv.setAttribute('class', classes.attributeOptionsWrapper + ' clearfix'); + subDiv.innerHTML = options + select; + + if ($widget.options.enableControlLabel) { + div.appendChild(firstSpan); + div.appendChild(secondSpan); } + div.appendChild(subDiv); + // Create new control - container.append( - '
' + - label + - '
' + - options + select + - '
' + input + - '
' - ); + container.append(div.outerHTML); $widget.optionsMap[item.id] = {}; @@ -501,7 +506,8 @@ define([ label, width, height, - attr; + link, + div; if (!optionConfig.hasOwnProperty(this.id)) { return ''; @@ -509,7 +515,12 @@ define([ // Add more button if (moreLimit === countAttributes++) { - html += '' + moreText + ''; + link = document.createElement('a'); + link.setAttribute('class', moreClass); + link.setAttribute('href', '#'); + link.textContent = moreText; + + html += link.outerHTML; } id = this.id; @@ -519,48 +530,54 @@ define([ width = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.width : 110; height = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.height : 90; label = this.label ? this.label : ''; - attr = - ' id="' + controlId + '-item-' + id + '"' + - ' aria-checked="false"' + - ' aria-describedby="' + controlId + '"' + - ' tabindex="0"' + - ' option-type="' + type + '"' + - ' option-id="' + id + '"' + - ' option-label="' + label + '"' + - ' aria-label="' + label + '"' + - ' option-tooltip-thumb="' + thumb + '"' + - ' option-tooltip-value="' + value + '"' + - ' role="option"' + - ' thumb-width="' + width + '"' + - ' thumb-height="' + height + '"'; + + div = document.createElement('div'); + + div.setAttribute('id', controlId + '-item-' + id); + div.setAttribute('aria-checked', false); + div.setAttribute('aria-describedby', controlId); + div.setAttribute('tabindex', 0); + div.setAttribute('option-type', type); + div.setAttribute('option-id', id); + div.setAttribute('option-label', label); + div.setAttribute('aria-label', label); + div.setAttribute('option-tooltip-thumb', thumb); + div.setAttribute('option-tooltip-value', value); + div.setAttribute('role', 'option'); + div.setAttribute('thumb-width', width); + div.setAttribute('thumb-height', height); if (!this.hasOwnProperty('products') || this.products.length <= 0) { - attr += ' option-empty="true"'; + div.setAttribute('option-empty', true); } if (type === 0) { // Text - html += '
' + (value ? value : label) + - '
'; + div.setAttribute('class', optionClass + ' text'); + div.textContent = value ? value : label; } else if (type === 1) { // Color - html += '
' + '' + - '
'; + div.setAttribute('class', optionClass + ' color'); + div.setAttribute('style', 'background: ' + value + ' no-repeat center; background-size: initial;'); + } else if (type === 2) { // Image - html += '
' + '' + - '
'; + div.setAttribute('class', optionClass + ' image'); + div.setAttribute('style', + 'background: url(' + value + + ') no-repeat center;' + + ' background-size: initial;' + + ' width:' + sizeConfig.swatchImage.width + 'px;' + + ' height:' + sizeConfig.swatchImage.height + 'px;'); } else if (type === 3) { // Clear - html += '
'; + div.setAttribute('class', optionClass); } else { // Default - html += '
' + label + '
'; + div.setAttribute('class', optionClass); + div.textContent = label; } + html += div.outerHTML; }); return html; @@ -575,30 +592,36 @@ define([ * @private */ _RenderSwatchSelect: function (config, chooseText) { - var html; + var select, + firstOption, + otherOption; if (this.options.jsonSwatchConfig.hasOwnProperty(config.id)) { return ''; } - html = - ''; - - return html; + return select.outerHTML; }, /** From ef5de2ecddce79e8e7c9d33e673f10cc8c15422b Mon Sep 17 00:00:00 2001 From: roman Date: Tue, 16 Oct 2018 19:54:23 +0300 Subject: [PATCH 049/526] MAGETWO-88650: Wrong swatches behavior --- .../Swatches/view/frontend/web/js/swatch-renderer.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index e2598e3247fc5..5371e3d85e70b 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -406,6 +406,15 @@ define([ return; } + if ($widget.options.enableControlLabel) { + firstSpan = document.createElement('span'); + secondSpan = document.createElement('span'); + firstSpan.setAttribute('id', controlLabelId); + firstSpan.setAttribute('class', classes.attributeLabelClass); + firstSpan.textContent = item.label; + secondSpan.setAttribute('class', classes.attributeSelectedOptionLabelClass); + } + if ($widget.inProductList) { $widget.productForm.append(input); input = ''; From 12f92431d7a36eafb13c54d86b98c9fe65a4dda0 Mon Sep 17 00:00:00 2001 From: roman Date: Wed, 17 Oct 2018 12:42:37 +0300 Subject: [PATCH 050/526] MAGETWO-88650: Wrong swatches behavior --- .../Checkout/view/frontend/templates/cart/item/default.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml index a423d8c8a0896..10a64fe755187 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/default.phtml @@ -49,7 +49,7 @@ $canApplyMsrp = $helper->isShowBeforeOrderConfirm($product) && $helper->isMinima - escapeHtml($_formatedOptionValue['value']) ?> + escapeHtml($_formatedOptionValue['value'], ['span']) ?> From 81fc5aa1135e094fb6a3c8f762e8123918c635e6 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi Date: Thu, 18 Oct 2018 15:04:53 -0500 Subject: [PATCH 051/526] Fix docblock --- .../Magento/Backend/Block/System/Store/Grid/Render/Group.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php index 04d173cd3c179..8656518260eb6 100644 --- a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php +++ b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php @@ -9,7 +9,7 @@ * Store render group * * @author Magento Core Team - * @deprecated + * @deprecated since Store Grid is refactored with UI Components */ class Group extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer { From c4fbe49677aac50c3fabffc7d8e67e060bccf581 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi Date: Thu, 18 Oct 2018 15:05:35 -0500 Subject: [PATCH 052/526] Fix docblock --- .../Magento/Backend/Block/System/Store/Grid/Render/Store.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Store.php b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Store.php index 8ce048bde537e..9be630277d4e5 100644 --- a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Store.php +++ b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Store.php @@ -9,12 +9,12 @@ * Store render store * * @author Magento Core Team - * @deprecated + * @deprecated since Store Grid is refactored with UI Components */ class Store extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer { /** - * {@inheritdoc} + * @inheritdoc */ public function render(\Magento\Framework\DataObject $row) { From 8910b68ccf8b33863ff23da35ef941d9eeb153fd Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi Date: Thu, 18 Oct 2018 15:06:00 -0500 Subject: [PATCH 053/526] Fix docblock --- .../Magento/Backend/Block/System/Store/Grid/Render/Group.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php index 8656518260eb6..37f11754529e5 100644 --- a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php +++ b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php @@ -14,7 +14,7 @@ class Group extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer { /** - * {@inheritdoc} + * @inheritdoc */ public function render(\Magento\Framework\DataObject $row) { From 7bc52b96586af3edc74174a477fe0689ee366ab1 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi Date: Thu, 18 Oct 2018 15:06:19 -0500 Subject: [PATCH 054/526] Fix docblock --- .../Backend/Block/System/Store/Grid/Render/Website.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Website.php b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Website.php index f97dffc9fa069..d4bb213dce14e 100644 --- a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Website.php +++ b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Website.php @@ -9,12 +9,12 @@ * Store render website * * @author Magento Core Team - * @deprecated + * @deprecated since Store Grid is refactored with UI Components */ class Website extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer { /** - * {@inheritdoc} + * @inheritdoc */ public function render(\Magento\Framework\DataObject $row) { From c0e78e0645382bee9e7739966ccb4c5dfd05f67b Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi Date: Thu, 18 Oct 2018 15:06:51 -0500 Subject: [PATCH 055/526] Fix docblock --- app/code/Magento/Backend/Block/System/Store/Store.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/System/Store/Store.php b/app/code/Magento/Backend/Block/System/Store/Store.php index 451794c0e2a95..2145dc524259e 100644 --- a/app/code/Magento/Backend/Block/System/Store/Store.php +++ b/app/code/Magento/Backend/Block/System/Store/Store.php @@ -12,7 +12,7 @@ * @author Magento Core Team * @api * @since 100.0.2 - * @deprecated + * @deprecated since Store Grid is refactored with UI Components */ class Store extends \Magento\Backend\Block\Widget\Grid\Container { From 9fa1d41d2d295ab1b8ad7c03963a3a0953d4e69e Mon Sep 17 00:00:00 2001 From: roman Date: Wed, 31 Oct 2018 15:18:34 +0200 Subject: [PATCH 056/526] MAGETWO-95402: Incorrect send-friend feature flow --- app/code/Magento/SendFriend/Block/Send.php | 21 + .../Magento/SendFriend/Model/SendFriend.php | 86 +- .../Unit/Controller/Product/SendmailTest.php | 906 ------------------ app/code/Magento/SendFriend/composer.json | 3 +- app/code/Magento/SendFriend/etc/config.xml | 16 + app/code/Magento/SendFriend/etc/module.xml | 1 + .../view/frontend/templates/send.phtml | 1 + .../etc/install-config-mysql.php.dist | 4 +- .../Product/CustomerSendmailTest.php | 168 ++++ 9 files changed, 295 insertions(+), 911 deletions(-) delete mode 100644 app/code/Magento/SendFriend/Test/Unit/Controller/Product/SendmailTest.php create mode 100644 dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php diff --git a/app/code/Magento/SendFriend/Block/Send.php b/app/code/Magento/SendFriend/Block/Send.php index 43e95ebe43d48..967393e81e4c4 100644 --- a/app/code/Magento/SendFriend/Block/Send.php +++ b/app/code/Magento/SendFriend/Block/Send.php @@ -5,6 +5,7 @@ */ namespace Magento\SendFriend\Block; +use Magento\Captcha\Block\Captcha; use Magento\Customer\Model\Context; /** @@ -222,4 +223,24 @@ public function canSend() { return !$this->sendfriend->isExceedLimit(); } + + /** + * @inheritdoc + */ + protected function _prepareLayout() + { + if (!$this->getChildBlock('captcha')) { + $this->addChild( + 'captcha', + Captcha::class, + [ + 'cacheable' => false, + 'after' => '-', + 'form_id' => 'product_sendtofriend_form', + 'image_width' => 230, + 'image_height' => 230 + ] + ); + } + } } diff --git a/app/code/Magento/SendFriend/Model/SendFriend.php b/app/code/Magento/SendFriend/Model/SendFriend.php index c69d6342b4892..4cfc8d29e4278 100644 --- a/app/code/Magento/SendFriend/Model/SendFriend.php +++ b/app/code/Magento/SendFriend/Model/SendFriend.php @@ -5,7 +5,15 @@ */ namespace Magento\SendFriend\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException as CoreException; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\App\RequestInterface; +use Magento\Captcha\Model\DefaultModel as CaptchaModel; +use Magento\Captcha\Helper\Data as CaptchaHelper; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Captcha\Observer\CaptchaStringResolver; +use Magento\Customer\Model\Customer; /** * SendFriend Log @@ -109,6 +117,26 @@ class SendFriend extends \Magento\Framework\Model\AbstractModel */ protected $remoteAddress; + /** + * @var RequestInterface + */ + private $request; + + /** + * @var CaptchaHelper + */ + private $captchaHelper; + + /** + * @var CaptchaStringResolver + */ + private $captchaStringResolver; + + /** + * @var CustomerSession + */ + private $customerSession; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -123,7 +151,10 @@ class SendFriend extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data - * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @param CaptchaHelper|null $captchaHelper + * @param CaptchaStringResolver|null $captchaStringResolver + * @param CustomerSession|null $customerSession + * @param RequestInterface|null $request */ public function __construct( \Magento\Framework\Model\Context $context, @@ -138,7 +169,11 @@ public function __construct( \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, - array $data = [] + array $data = [], + CaptchaHelper $captchaHelper = null, + CaptchaStringResolver $captchaStringResolver = null, + CustomerSession $customerSession = null, + RequestInterface $request = null ) { $this->_storeManager = $storeManager; $this->_transportBuilder = $transportBuilder; @@ -148,6 +183,12 @@ public function __construct( $this->remoteAddress = $remoteAddress; $this->cookieManager = $cookieManager; $this->inlineTranslation = $inlineTranslation; + $this->captchaHelper = $captchaHelper ?: ObjectManager::getInstance()->create(CaptchaHelper::class); + $this->captchaStringResolver = $captchaStringResolver ?: + ObjectManager::getInstance()->create(CaptchaStringResolver::class); + $this->customerSession = $customerSession ?: ObjectManager::getInstance()->create(CustomerSession::class); + $this->request = $request ?: ObjectManager::getInstance()->get(RequestInterface::class); + parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -420,12 +461,53 @@ public function canEmailToFriend() * Check if user is exceed limit * * @return boolean + * @throws LocalizedException */ public function isExceedLimit() { + $captchaTargetFormName = 'product_sendtofriend_form'; + /** @var CaptchaModel $captchaModel */ + $captchaModel = $this->captchaHelper->getCaptcha($captchaTargetFormName); + + if ($captchaModel->isRequired()) { + $word = $this->captchaStringResolver->resolve( + $this->request, + $captchaTargetFormName + ); + + if (!$word) { + $this->logCaptchaAttempt($captchaModel); + throw new LocalizedException(__('No CAPTCHA word provided')); + } + $isCorrectCaptcha = $captchaModel->isCorrect($word); + $this->logCaptchaAttempt($captchaModel); + + if (!$isCorrectCaptcha) { + throw new LocalizedException(__('Incorrect CAPTCHA')); + } + } + return $this->getSentCount() >= $this->getMaxSendsToFriend(); } + /** + * Logs a try to pass captcha validation + * + * @param CaptchaModel $captchaModel + */ + private function logCaptchaAttempt(CaptchaModel $captchaModel) + { + /** @var Customer $customer */ + $customer = $this->customerSession->getCustomer(); + $email = ''; + + if ($customer->getId()) { + $email = $customer->getEmail(); + } + + $captchaModel->logAttempt($email); + } + /** * Return count of sent in last period * diff --git a/app/code/Magento/SendFriend/Test/Unit/Controller/Product/SendmailTest.php b/app/code/Magento/SendFriend/Test/Unit/Controller/Product/SendmailTest.php deleted file mode 100644 index c7881f366f520..0000000000000 --- a/app/code/Magento/SendFriend/Test/Unit/Controller/Product/SendmailTest.php +++ /dev/null @@ -1,906 +0,0 @@ -requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class) - ->setMethods(['getPost', 'getPostValue', 'getParam']) - ->getMockForAbstractClass(); - $this->registryMock = $this->getMockBuilder(\Magento\Framework\Registry::class) - ->disableOriginalConstructor() - ->getMock(); - $this->validatorMock = $this->getMockBuilder(\Magento\Framework\Data\Form\FormKey\Validator::class) - ->disableOriginalConstructor() - ->getMock(); - $this->sendFriendMock = $this->getMockBuilder(\Magento\SendFriend\Model\SendFriend::class) - ->disableOriginalConstructor() - ->getMock(); - $this->productRepositoryMock = $this->getMockBuilder(\Magento\Catalog\Api\ProductRepositoryInterface::class) - ->getMockForAbstractClass(); - $this->categoryRepositoryMock = $this->getMockBuilder(\Magento\Catalog\Api\CategoryRepositoryInterface::class) - ->getMockForAbstractClass(); - $this->catalogSessionMock = $this->getMockBuilder(\Magento\Catalog\Model\Session::class) - ->setMethods(['getSendfriendFormData', 'setSendfriendFormData']) - ->disableOriginalConstructor() - ->getMock(); - $this->messageManagerMock = $this->getMockBuilder(\Magento\Framework\Message\ManagerInterface::class) - ->getMock(); - $this->resultFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\ResultFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) - ->getMock(); - $this->redirectMock = $this->getMockBuilder(\Magento\Framework\App\Response\RedirectInterface::class) - ->getMock(); - $this->urlBuilderMock = $this->getMockBuilder(\Magento\Framework\UrlInterface::class) - ->getMock(); - - $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->model = $this->objectManagerHelper->getObject( - \Magento\SendFriend\Controller\Product\Sendmail::class, - [ - 'request' => $this->requestMock, - 'coreRegistry' => $this->registryMock, - 'formKeyValidator' => $this->validatorMock, - 'sendFriend' => $this->sendFriendMock, - 'productRepository' => $this->productRepositoryMock, - 'categoryRepository' => $this->categoryRepositoryMock, - 'catalogSession' => $this->catalogSessionMock, - 'messageManager' => $this->messageManagerMock, - 'resultFactory' => $this->resultFactoryMock, - 'eventManager' => $this->eventManagerMock, - 'redirect' => $this->redirectMock, - 'url' => $this->urlBuilderMock, - ] - ); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testExecute() - { - $productId = 11; - $categoryId = 5; - $sender = 'sender'; - $recipients = 'recipients'; - $formData = [ - 'sender' => $sender, - 'recipients' => $recipients, - ]; - $productUrl = 'product_url'; - - /** @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock->expects($this->once()) - ->method('create') - ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT, []) - ->willReturn($redirectMock); - - $this->validatorMock->expects($this->once()) - ->method('validate') - ->with($this->requestMock) - ->willReturn(true); - - $this->requestMock->expects($this->exactly(2)) - ->method('getParam') - ->willReturnMap( - [ - ['id', null, $productId], - ['cat_id', null, $categoryId], - ] - ); - - /** @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject $productMock */ - $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) - ->setMethods(['isVisibleInCatalog', 'setCategory', 'getProductUrl']) - ->getMockForAbstractClass(); - - $this->productRepositoryMock->expects($this->once()) - ->method('getById') - ->with($productId, false, null, false) - ->willReturn($productMock); - - $productMock->expects($this->once()) - ->method('isVisibleInCatalog') - ->willReturn(true); - - /** @var \Magento\Catalog\Api\Data\CategoryInterface|\PHPUnit_Framework_MockObject_MockObject $categoryMock */ - $categoryMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\CategoryInterface::class) - ->getMockForAbstractClass(); - - $this->categoryRepositoryMock->expects($this->once()) - ->method('get') - ->with($categoryId, null) - ->willReturn($categoryMock); - - $productMock->expects($this->once()) - ->method('setCategory') - ->with($categoryMock); - - $this->registryMock->expects($this->exactly(2)) - ->method('register') - ->willReturnMap( - [ - ['product', $productMock, false, null], - ['current_category', $categoryMock, false, null], - ] - ); - - $this->requestMock->expects($this->once()) - ->method('getPostValue') - ->willReturn($formData); - - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['sender', $sender], - ['recipients', $recipients], - ] - ); - - $this->sendFriendMock->expects($this->once()) - ->method('setSender') - ->with($sender) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setRecipients') - ->with($recipients) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setProduct') - ->with($productMock) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('validate') - ->willReturn(true); - $this->sendFriendMock->expects($this->once()) - ->method('send') - ->willReturnSelf(); - - $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') - ->with(__('The link to a friend was sent.')) - ->willReturnSelf(); - - $productMock->expects($this->once()) - ->method('getProductUrl') - ->willReturn($productUrl); - - $this->redirectMock->expects($this->once()) - ->method('success') - ->with($productUrl) - ->willReturnArgument(0); - - $redirectMock->expects($this->once()) - ->method('setUrl') - ->with($productUrl) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testExecuteWithoutValidationAndCategory() - { - $productId = 11; - $categoryId = 5; - $sender = 'sender'; - $recipients = 'recipients'; - $formData = [ - 'sender' => $sender, - 'recipients' => $recipients, - ]; - $redirectUrl = 'redirect_url'; - - /** @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock->expects($this->once()) - ->method('create') - ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT, []) - ->willReturn($redirectMock); - - $this->validatorMock->expects($this->once()) - ->method('validate') - ->with($this->requestMock) - ->willReturn(true); - - $this->requestMock->expects($this->exactly(2)) - ->method('getParam') - ->willReturnMap( - [ - ['id', null, $productId], - ['cat_id', null, $categoryId], - ] - ); - - /** @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject $productMock */ - $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) - ->setMethods(['isVisibleInCatalog', 'setCategory', 'getProductUrl']) - ->getMockForAbstractClass(); - - $this->productRepositoryMock->expects($this->once()) - ->method('getById') - ->with($productId, false, null, false) - ->willReturn($productMock); - - $productMock->expects($this->once()) - ->method('isVisibleInCatalog') - ->willReturn(true); - - $this->categoryRepositoryMock->expects($this->once()) - ->method('get') - ->with($categoryId, null) - ->willThrowException(new \Magento\Framework\Exception\NoSuchEntityException(__('No Category Exception.'))); - - $productMock->expects($this->never()) - ->method('setCategory'); - - $this->registryMock->expects($this->once()) - ->method('register') - ->willReturnMap( - [ - ['product', $productMock, false, null], - ] - ); - - $this->requestMock->expects($this->once()) - ->method('getPostValue') - ->willReturn($formData); - - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['sender', $sender], - ['recipients', $recipients], - ] - ); - - $this->sendFriendMock->expects($this->once()) - ->method('setSender') - ->with($sender) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setRecipients') - ->with($recipients) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setProduct') - ->with($productMock) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('validate') - ->willReturn(['Some error']); - $this->sendFriendMock->expects($this->never()) - ->method('send'); - - $this->messageManagerMock->expects($this->once()) - ->method('addError') - ->with(__('Some error')) - ->willReturnSelf(); - - $this->catalogSessionMock->expects($this->once()) - ->method('setSendfriendFormData') - ->with($formData); - - $this->urlBuilderMock->expects($this->once()) - ->method('getUrl') - ->with('sendfriend/product/send', ['_current' => true]) - ->willReturn($redirectUrl); - - $this->redirectMock->expects($this->once()) - ->method('error') - ->with($redirectUrl) - ->willReturnArgument(0); - - $redirectMock->expects($this->once()) - ->method('setUrl') - ->with($redirectUrl) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testExecuteWithoutValidationAndCategoryWithProblems() - { - $productId = 11; - $categoryId = 5; - $sender = 'sender'; - $recipients = 'recipients'; - $formData = [ - 'sender' => $sender, - 'recipients' => $recipients, - ]; - $redirectUrl = 'redirect_url'; - - /** @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock->expects($this->once()) - ->method('create') - ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT, []) - ->willReturn($redirectMock); - - $this->validatorMock->expects($this->once()) - ->method('validate') - ->with($this->requestMock) - ->willReturn(true); - - $this->requestMock->expects($this->exactly(2)) - ->method('getParam') - ->willReturnMap( - [ - ['id', null, $productId], - ['cat_id', null, $categoryId], - ] - ); - - /** @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject $productMock */ - $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) - ->setMethods(['isVisibleInCatalog', 'setCategory', 'getProductUrl']) - ->getMockForAbstractClass(); - - $this->productRepositoryMock->expects($this->once()) - ->method('getById') - ->with($productId, false, null, false) - ->willReturn($productMock); - - $productMock->expects($this->once()) - ->method('isVisibleInCatalog') - ->willReturn(true); - - $this->categoryRepositoryMock->expects($this->once()) - ->method('get') - ->with($categoryId, null) - ->willThrowException(new \Magento\Framework\Exception\NoSuchEntityException(__('No Category Exception.'))); - - $productMock->expects($this->never()) - ->method('setCategory'); - - $this->registryMock->expects($this->once()) - ->method('register') - ->willReturnMap( - [ - ['product', $productMock, false, null], - ] - ); - - $this->requestMock->expects($this->once()) - ->method('getPostValue') - ->willReturn($formData); - - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['sender', $sender], - ['recipients', $recipients], - ] - ); - - $this->sendFriendMock->expects($this->once()) - ->method('setSender') - ->with($sender) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setRecipients') - ->with($recipients) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setProduct') - ->with($productMock) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('validate') - ->willReturn('Some error'); - $this->sendFriendMock->expects($this->never()) - ->method('send'); - - $this->messageManagerMock->expects($this->once()) - ->method('addError') - ->with(__('We found some problems with the data.')) - ->willReturnSelf(); - - $this->catalogSessionMock->expects($this->once()) - ->method('setSendfriendFormData') - ->with($formData); - - $this->urlBuilderMock->expects($this->once()) - ->method('getUrl') - ->with('sendfriend/product/send', ['_current' => true]) - ->willReturn($redirectUrl); - - $this->redirectMock->expects($this->once()) - ->method('error') - ->with($redirectUrl) - ->willReturnArgument(0); - - $redirectMock->expects($this->once()) - ->method('setUrl') - ->with($redirectUrl) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testExecuteWithLocalizedException() - { - $productId = 11; - $categoryId = 5; - $sender = 'sender'; - $recipients = 'recipients'; - $formData = [ - 'sender' => $sender, - 'recipients' => $recipients, - ]; - $redirectUrl = 'redirect_url'; - - /** @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock->expects($this->once()) - ->method('create') - ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT, []) - ->willReturn($redirectMock); - - $this->validatorMock->expects($this->once()) - ->method('validate') - ->with($this->requestMock) - ->willReturn(true); - - $this->requestMock->expects($this->exactly(2)) - ->method('getParam') - ->willReturnMap( - [ - ['id', null, $productId], - ['cat_id', null, $categoryId], - ] - ); - - /** @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject $productMock */ - $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) - ->setMethods(['isVisibleInCatalog', 'setCategory', 'getProductUrl']) - ->getMockForAbstractClass(); - - $this->productRepositoryMock->expects($this->once()) - ->method('getById') - ->with($productId, false, null, false) - ->willReturn($productMock); - - $productMock->expects($this->once()) - ->method('isVisibleInCatalog') - ->willReturn(true); - - $this->categoryRepositoryMock->expects($this->once()) - ->method('get') - ->with($categoryId, null) - ->willThrowException(new \Magento\Framework\Exception\NoSuchEntityException(__('No Category Exception.'))); - - $productMock->expects($this->never()) - ->method('setCategory'); - - $this->registryMock->expects($this->once()) - ->method('register') - ->willReturnMap( - [ - ['product', $productMock, false, null], - ] - ); - - $this->requestMock->expects($this->once()) - ->method('getPostValue') - ->willReturn($formData); - - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['sender', $sender], - ['recipients', $recipients], - ] - ); - - $this->sendFriendMock->expects($this->once()) - ->method('setSender') - ->with($sender) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setRecipients') - ->with($recipients) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setProduct') - ->with($productMock) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('validate') - ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__('Localized Exception.'))); - $this->sendFriendMock->expects($this->never()) - ->method('send'); - - $this->messageManagerMock->expects($this->once()) - ->method('addError') - ->with(__('Localized Exception.')) - ->willReturnSelf(); - - $this->catalogSessionMock->expects($this->once()) - ->method('setSendfriendFormData') - ->with($formData); - - $this->urlBuilderMock->expects($this->once()) - ->method('getUrl') - ->with('sendfriend/product/send', ['_current' => true]) - ->willReturn($redirectUrl); - - $this->redirectMock->expects($this->once()) - ->method('error') - ->with($redirectUrl) - ->willReturnArgument(0); - - $redirectMock->expects($this->once()) - ->method('setUrl') - ->with($redirectUrl) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testExecuteWithException() - { - $productId = 11; - $categoryId = 5; - $sender = 'sender'; - $recipients = 'recipients'; - $formData = [ - 'sender' => $sender, - 'recipients' => $recipients, - ]; - $redirectUrl = 'redirect_url'; - - /** @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock->expects($this->once()) - ->method('create') - ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT, []) - ->willReturn($redirectMock); - - $this->validatorMock->expects($this->once()) - ->method('validate') - ->with($this->requestMock) - ->willReturn(true); - - $this->requestMock->expects($this->exactly(2)) - ->method('getParam') - ->willReturnMap( - [ - ['id', null, $productId], - ['cat_id', null, $categoryId], - ] - ); - - /** @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject $productMock */ - $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) - ->setMethods(['isVisibleInCatalog', 'setCategory', 'getProductUrl']) - ->getMockForAbstractClass(); - - $this->productRepositoryMock->expects($this->once()) - ->method('getById') - ->with($productId, false, null, false) - ->willReturn($productMock); - - $productMock->expects($this->once()) - ->method('isVisibleInCatalog') - ->willReturn(true); - - $this->categoryRepositoryMock->expects($this->once()) - ->method('get') - ->with($categoryId, null) - ->willThrowException(new \Magento\Framework\Exception\NoSuchEntityException(__('No Category Exception.'))); - - $productMock->expects($this->never()) - ->method('setCategory'); - - $this->registryMock->expects($this->once()) - ->method('register') - ->willReturnMap( - [ - ['product', $productMock, false, null], - ] - ); - - $this->requestMock->expects($this->once()) - ->method('getPostValue') - ->willReturn($formData); - - $this->requestMock->expects($this->exactly(2)) - ->method('getPost') - ->willReturnMap( - [ - ['sender', $sender], - ['recipients', $recipients], - ] - ); - - $this->sendFriendMock->expects($this->once()) - ->method('setSender') - ->with($sender) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setRecipients') - ->with($recipients) - ->willReturnSelf(); - $this->sendFriendMock->expects($this->once()) - ->method('setProduct') - ->with($productMock) - ->willReturnSelf(); - $exception = new \Exception(__('Exception.')); - $this->sendFriendMock->expects($this->once()) - ->method('validate') - ->willThrowException($exception); - $this->sendFriendMock->expects($this->never()) - ->method('send'); - - $this->messageManagerMock->expects($this->once()) - ->method('addException') - ->with($exception, __('Some emails were not sent.')) - ->willReturnSelf(); - - $this->catalogSessionMock->expects($this->once()) - ->method('setSendfriendFormData') - ->with($formData); - - $this->urlBuilderMock->expects($this->once()) - ->method('getUrl') - ->with('sendfriend/product/send', ['_current' => true]) - ->willReturn($redirectUrl); - - $this->redirectMock->expects($this->once()) - ->method('error') - ->with($redirectUrl) - ->willReturnArgument(0); - - $redirectMock->expects($this->once()) - ->method('setUrl') - ->with($redirectUrl) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testExecuteWithoutProduct() - { - $sender = 'sender'; - $recipients = 'recipients'; - $formData = [ - 'sender' => $sender, - 'recipients' => $recipients, - ]; - - /** @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - /** @var \Magento\Framework\Controller\Result\Forward|\PHPUnit_Framework_MockObject_MockObject $forwardMock */ - $forwardMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Forward::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock->expects($this->exactly(2)) - ->method('create') - ->willReturnMap( - [ - [\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT, [], $redirectMock], - [\Magento\Framework\Controller\ResultFactory::TYPE_FORWARD, [], $forwardMock], - ] - ); - - $this->validatorMock->expects($this->once()) - ->method('validate') - ->with($this->requestMock) - ->willReturn(true); - - $this->requestMock->expects($this->once()) - ->method('getParam') - ->willReturnMap( - [ - ['id', null, null], - ] - ); - - $this->requestMock->expects($this->once()) - ->method('getPostValue') - ->willReturn($formData); - - $forwardMock->expects($this->once()) - ->method('forward') - ->with('noroute') - ->willReturnSelf(); - - $this->assertEquals($forwardMock, $this->model->execute()); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testExecuteWithoutData() - { - $productId = 11; - $formData = ''; - - /** @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - /** @var \Magento\Framework\Controller\Result\Forward|\PHPUnit_Framework_MockObject_MockObject $forwardMock */ - $forwardMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Forward::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock->expects($this->exactly(2)) - ->method('create') - ->willReturnMap( - [ - [\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT, [], $redirectMock], - [\Magento\Framework\Controller\ResultFactory::TYPE_FORWARD, [], $forwardMock], - ] - ); - - $this->validatorMock->expects($this->once()) - ->method('validate') - ->with($this->requestMock) - ->willReturn(true); - - $this->requestMock->expects($this->once()) - ->method('getParam') - ->willReturnMap( - [ - ['id', null, $productId], - ] - ); - - /** @var \Magento\Catalog\Api\Data\ProductInterface|\PHPUnit_Framework_MockObject_MockObject $productMock */ - $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) - ->setMethods(['isVisibleInCatalog', 'setCategory', 'getProductUrl']) - ->getMockForAbstractClass(); - - $this->productRepositoryMock->expects($this->once()) - ->method('getById') - ->with($productId, false, null, false) - ->willReturn($productMock); - - $productMock->expects($this->once()) - ->method('isVisibleInCatalog') - ->willReturn(true); - - $this->registryMock->expects($this->once()) - ->method('register') - ->willReturnMap( - [ - ['product', $productMock, false, null], - ] - ); - - $this->requestMock->expects($this->once()) - ->method('getPostValue') - ->willReturn($formData); - - $forwardMock->expects($this->once()) - ->method('forward') - ->with('noroute') - ->willReturnSelf(); - - $this->assertEquals($forwardMock, $this->model->execute()); - } - - public function testExecuteWithoutFormKey() - { - /** @var \Magento\Framework\Controller\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ - $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->resultFactoryMock->expects($this->once()) - ->method('create') - ->willReturnMap( - [ - [\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT, [], $redirectMock], - ] - ); - - $this->validatorMock->expects($this->once()) - ->method('validate') - ->with($this->requestMock) - ->willReturn(false); - - $redirectMock->expects($this->once()) - ->method('setPath') - ->with('sendfriend/product/send', ['_current' => true]) - ->willReturnSelf(); - - $this->assertEquals($redirectMock, $this->model->execute()); - } -} diff --git a/app/code/Magento/SendFriend/composer.json b/app/code/Magento/SendFriend/composer.json index 324465885f82f..806f02b23cc22 100644 --- a/app/code/Magento/SendFriend/composer.json +++ b/app/code/Magento/SendFriend/composer.json @@ -6,7 +6,8 @@ "magento/module-store": "100.2.*", "magento/module-catalog": "102.0.*", "magento/module-customer": "101.0.*", - "magento/framework": "101.0.*" + "magento/framework": "101.0.*", + "magento/module-captcha": "100.2.*" }, "type": "magento2-module", "version": "100.2.2", diff --git a/app/code/Magento/SendFriend/etc/config.xml b/app/code/Magento/SendFriend/etc/config.xml index 9fa005dcd2fd4..d65e5a4a073dd 100644 --- a/app/code/Magento/SendFriend/etc/config.xml +++ b/app/code/Magento/SendFriend/etc/config.xml @@ -17,5 +17,21 @@ 0 + + + + + + + + + + + + + 1 + + + diff --git a/app/code/Magento/SendFriend/etc/module.xml b/app/code/Magento/SendFriend/etc/module.xml index fae2b90f710a3..c874c54cbc672 100644 --- a/app/code/Magento/SendFriend/etc/module.xml +++ b/app/code/Magento/SendFriend/etc/module.xml @@ -10,6 +10,7 @@ + diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index 2b25e0efab84a..52b1a4061db22 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -108,6 +108,7 @@
getChildHtml('form_additional_info') ?> + getChildHtml('captcha'); ?>