From 5fdc9efa6267079ceb3d84c34a2d89a9534796d1 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 16 Apr 2019 18:43:30 -0500 Subject: [PATCH 001/372] MC-15901: Recursion in filter widget --- .../Magento/Catalog/Ui/Component/ColumnFactory.php | 1 + .../Ui/view/base/web/js/grid/filters/filters.js | 1 + lib/web/mage/utils/template.js | 12 +++++++++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php index f7554219c6c31..1495d6a41d91b 100644 --- a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php +++ b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php @@ -73,6 +73,7 @@ public function create($attribute, $context, array $config = []) 'filter' => ($attribute->getIsFilterableInGrid() || array_key_exists($columnName, $filterModifiers)) ? $this->getFilterType($attribute->getFrontendInput()) : null, + '__disableTmpl' => true, ], $config); if ($attribute->usesSource()) { diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index 98c3eb1c6f882..e6ac0b2b80f42 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -272,6 +272,7 @@ define([ } filter = utils.extend({}, filters.base, filter); + filter.__disableTmpl = {label : true}; return utils.template(filter, { filters: this, diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 7aa695023cb56..861c352ee2026 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -37,7 +37,7 @@ define([ * * @param {String} tmpl * @param {Object} target - * @returns {Boolean} + * @returns {Boolean|Object} */ function isTmplIgnored(tmpl, target) { var parsedTmpl; @@ -53,7 +53,7 @@ define([ if (typeof target !== 'undefined') { if (typeof target === 'object' && target.hasOwnProperty('__disableTmpl')) { - return true; + return target.__disableTmpl; } } @@ -201,6 +201,8 @@ define([ * Template iterator function. */ _.each(tmpl, function iterate(value, key, list) { + var disabled; + if (key === '$data') { return; } @@ -213,7 +215,11 @@ define([ } if (isTemplate(value)) { - list[key] = render(value, tmpl, castString, list); + disabled = isTmplIgnored(value, list); + + if (!((typeof disabled) == 'object' && disabled.hasOwnProperty(key) && disabled[key])) { + list[key] = render(value, tmpl, castString, list); + } } else if ($.isPlainObject(value) || Array.isArray(value)) { _.each(value, iterate); } From 29a98deda1da6b2b2a596668028049b8a32bd857 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 18 Apr 2019 10:52:54 -0500 Subject: [PATCH 002/372] MC-15901: Recursion in filter widget --- .../Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php | 1 + app/code/Magento/Catalog/Ui/Component/ColumnFactory.php | 2 +- app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js | 4 +++- lib/web/mage/utils/template.js | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php index 774edcfeb6b64..45d911f7e94e5 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php @@ -111,6 +111,7 @@ public function testCreateWithNotFilterableInGridAttribute(array $filterModifier 'visible' => null, 'filter' => $filter, 'component' => 'Magento_Ui/js/grid/columns/column', + '__disableTmpl' => ['label' => true] ], ], 'context' => $this->context, diff --git a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php index 1495d6a41d91b..491d945e4644f 100644 --- a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php +++ b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php @@ -73,7 +73,7 @@ public function create($attribute, $context, array $config = []) 'filter' => ($attribute->getIsFilterableInGrid() || array_key_exists($columnName, $filterModifiers)) ? $this->getFilterType($attribute->getFrontendInput()) : null, - '__disableTmpl' => true, + '__disableTmpl' => ['label' => true], ], $config); if ($attribute->usesSource()) { diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index e6ac0b2b80f42..26d21eac0c28b 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -272,7 +272,9 @@ define([ } filter = utils.extend({}, filters.base, filter); - filter.__disableTmpl = {label : true}; + filter.__disableTmpl = { + label: true + }; return utils.template(filter, { filters: this, diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 861c352ee2026..a459d73ff360e 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -217,7 +217,7 @@ define([ if (isTemplate(value)) { disabled = isTmplIgnored(value, list); - if (!((typeof disabled) == 'object' && disabled.hasOwnProperty(key) && disabled[key])) { + if (typeof disabled !== 'object' || !disabled.hasOwnProperty(key) || !disabled[key]) { list[key] = render(value, tmpl, castString, list); } } else if ($.isPlainObject(value) || Array.isArray(value)) { From e51a4e2fa7b3930c964982f897981c72d7cc387e Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 18 Apr 2019 19:03:02 -0500 Subject: [PATCH 003/372] MC-15901: Recursion in filter widget --- .../view/base/web/js/grid/filters/filters.js | 11 ++++- lib/web/mage/utils/template.js | 43 +++++++++++++------ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index 26d21eac0c28b..c608400a6f174 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -272,14 +272,21 @@ define([ } filter = utils.extend({}, filters.base, filter); + //Accepting labels as is. filter.__disableTmpl = { - label: true + label: 1 }; - return utils.template(filter, { + filter = utils.template(filter, { filters: this, column: column }, true, true); + + filter.__disableTmpl = { + label: true + }; + + return filter; }, /** diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index a459d73ff360e..cd3e66ef58cf1 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -33,7 +33,11 @@ define([ })(); /** - * Validates template + * Objects can specify how to use templating for their properties - getting that configuration. + * + * To disable rendering for all properties of your object add __disableTmpl: true. + * To disable for specific property add __disableTmpl: {propertyName: true}. + * To limit recursion for a specific property add __disableTmpl: {propertyName: numberOfCycles}. * * @param {String} tmpl * @param {Object} target @@ -69,14 +73,10 @@ define([ * * @param {String} tmpl - Template string. * @param {Object} $ - Data object used in a template. - * @param {Object} target * @returns {String} Compiled template. */ - template = function (tmpl, $, target) { - - if (!isTmplIgnored(tmpl, target)) { - return eval('`' + tmpl + '`'); - } + template = function (tmpl, $) { + return eval('`' + tmpl + '`'); return tmpl; }; @@ -130,19 +130,22 @@ define([ * @param {Boolean} [castString=false] - Flag that indicates whether template * should be casted after evaluation to a value of another type or * that it should be leaved as a string. + * @param {Number|undefined} maxCycles Maximum number of rendering cycles, can be 0. * @returns {*} Compiled template. */ - function render(tmpl, data, castString, target) { - var last = tmpl; + function render(tmpl, data, castString, maxCycles) { + var last = tmpl, + cycles = 0; - while (~tmpl.indexOf(opener)) { - tmpl = template(tmpl, data, target); + while (~tmpl.indexOf(opener) && (typeof maxCycles === 'undefined' || cycles < maxCycles)) { + tmpl = template(tmpl, data); if (tmpl === last) { break; } last = tmpl; + cycles++; } return castString ? @@ -201,7 +204,8 @@ define([ * Template iterator function. */ _.each(tmpl, function iterate(value, key, list) { - var disabled; + var disabled, + maxCycles; if (key === '$data') { return; @@ -215,11 +219,22 @@ define([ } if (isTemplate(value)) { + //Getting template disabling settings, can be true for all disabled and separate settings + //for each property. disabled = isTmplIgnored(value, list); - if (typeof disabled !== 'object' || !disabled.hasOwnProperty(key) || !disabled[key]) { - list[key] = render(value, tmpl, castString, list); + if (typeof disabled === 'object' && disabled.hasOwnProperty(key) && disabled[key] !== false) { + //Checking if specific settings for a property provided. + maxCycles = disabled[key]; + if (maxCycles === true) { + maxCycles = 0; + } + } else if (disabled === true) { + //Rendering for all properties is disabled. + maxCycles = 0; } + + list[key] = render(value, tmpl, castString, maxCycles); } else if ($.isPlainObject(value) || Array.isArray(value)) { _.each(value, iterate); } From 76c9f8353ff0f9437d970a4d73a1852149396202 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 19 Apr 2019 17:34:04 -0500 Subject: [PATCH 004/372] MC-15901: Recursion in filter widget --- lib/web/mage/utils/template.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index cd3e66ef58cf1..192e6bddcf7ac 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -77,8 +77,6 @@ define([ */ template = function (tmpl, $) { return eval('`' + tmpl + '`'); - - return tmpl; }; /*eslint-enable no-unused-vars, no-eval*/ @@ -130,7 +128,7 @@ define([ * @param {Boolean} [castString=false] - Flag that indicates whether template * should be casted after evaluation to a value of another type or * that it should be leaved as a string. - * @param {Number|undefined} maxCycles Maximum number of rendering cycles, can be 0. + * @param {Number|undefined} maxCycles - Maximum number of rendering cycles, can be 0. * @returns {*} Compiled template. */ function render(tmpl, data, castString, maxCycles) { @@ -226,10 +224,7 @@ define([ if (typeof disabled === 'object' && disabled.hasOwnProperty(key) && disabled[key] !== false) { //Checking if specific settings for a property provided. maxCycles = disabled[key]; - if (maxCycles === true) { - maxCycles = 0; - } - } else if (disabled === true) { + } else if (disabled === true || maxCycles === true) { //Rendering for all properties is disabled. maxCycles = 0; } From ac7fe775ef062af5ebe5bbfbb5cc85df1d212d86 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 19 Apr 2019 17:40:26 -0500 Subject: [PATCH 005/372] MC-15901: Recursion in filter widget --- lib/web/mage/utils/template.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 192e6bddcf7ac..4032c9387904d 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -224,7 +224,9 @@ define([ if (typeof disabled === 'object' && disabled.hasOwnProperty(key) && disabled[key] !== false) { //Checking if specific settings for a property provided. maxCycles = disabled[key]; - } else if (disabled === true || maxCycles === true) { + } + + if (disabled === true || maxCycles === true) { //Rendering for all properties is disabled. maxCycles = 0; } From 9051331d7782641ae855421340c0dbb27c8daaf1 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Mon, 22 Apr 2019 15:19:27 -0500 Subject: [PATCH 006/372] MC-15576: CMS block cache --- app/code/Magento/Cms/Block/Block.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Cms/Block/Block.php b/app/code/Magento/Cms/Block/Block.php index d0d75ea691195..99c18c4913948 100644 --- a/app/code/Magento/Cms/Block/Block.php +++ b/app/code/Magento/Cms/Block/Block.php @@ -18,6 +18,11 @@ class Block extends AbstractBlock implements \Magento\Framework\DataObject\Ident */ protected $_filterProvider; + /** + * Prefix for cache key of CMS block + */ + const CACHE_KEY_PREFIX = 'CMS_BLOCK_'; + /** * Store manager * From 406024bc7abcc1d588211f00f01bd7606ae57c47 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Tue, 23 Apr 2019 15:03:55 -0500 Subject: [PATCH 007/372] MC-15132: Update XML Design --- .../Argument/Interpreter/ConfigurableObject.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index c40d26ab2f500..35a5fffd45269 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -13,6 +13,13 @@ */ class ConfigurableObject implements InterpreterInterface { + /** + * @var array + */ + private $classBlacklist = [ + \Zend\Code\Reflection\FileReflection::class + ]; + /** * @var ObjectManagerInterface */ @@ -53,6 +60,14 @@ public function evaluate(array $data) if (!isset($arguments['class'])) { throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); } + + if (in_array(ltrim($arguments['class'], '\\'), $this->classBlacklist)) { + throw new \InvalidArgumentException(sprintf( + 'Class argument is invalid: %s', + $arguments['class'] + )); + } + $className = $arguments['class']; unset($arguments['class']); } From 966764b097664efdc34e6651703edb7ea27d01ab Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Wed, 24 Apr 2019 09:58:27 -0500 Subject: [PATCH 008/372] MC-15576: CMS block cache --- app/code/Magento/Cms/Block/Block.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cms/Block/Block.php b/app/code/Magento/Cms/Block/Block.php index 99c18c4913948..2ff740c9303b3 100644 --- a/app/code/Magento/Cms/Block/Block.php +++ b/app/code/Magento/Cms/Block/Block.php @@ -14,14 +14,14 @@ class Block extends AbstractBlock implements \Magento\Framework\DataObject\IdentityInterface { /** - * @var \Magento\Cms\Model\Template\FilterProvider + * Prefix for cache key of CMS block */ - protected $_filterProvider; + const CACHE_KEY_PREFIX = 'CMS_BLOCK_'; /** - * Prefix for cache key of CMS block + * @var \Magento\Cms\Model\Template\FilterProvider */ - const CACHE_KEY_PREFIX = 'CMS_BLOCK_'; + protected $_filterProvider; /** * Store manager From fe7fbce272c0c0fdd06b7eaadede0bd18cfe8212 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Wed, 24 Apr 2019 23:01:24 -0500 Subject: [PATCH 009/372] MC-15811: Incorrect Url Added Store Switcher Added Controller Added Unit test. --- .../Magento/Backend/etc/adminhtml/system.xml | 5 - .../Store/Controller/Store/SwitchRequest.php | 131 +++++++++++ .../Model/StoreSwitcher/HashGenerator.php | 88 ++++++++ .../Store/Setup/Patch/Data/DisableSid.php | 80 +++++++ .../Controller/Store/SwitchRequestTest.php | 128 +++++++++++ app/code/Magento/Store/etc/config.xml | 2 +- app/code/Magento/Store/etc/di.xml | 1 + .../Magento/Store/etc/frontend/sections.xml | 1 + .../Framework/Session/SidResolverTest.php | 210 ------------------ .../Magento/Framework/Session/SidResolver.php | 1 + 10 files changed, 431 insertions(+), 216 deletions(-) create mode 100644 app/code/Magento/Store/Controller/Store/SwitchRequest.php create mode 100644 app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php create mode 100644 app/code/Magento/Store/Setup/Patch/Data/DisableSid.php create mode 100644 app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php delete mode 100644 dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 98b8e702b1c53..e58335d95dc66 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -583,11 +583,6 @@ Magento\Config\Model\Config\Source\Yesno - - - Allows customers to stay logged in when switching between different stores. - Magento\Config\Model\Config\Source\Yesno - diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php new file mode 100644 index 0000000000000..af2d20b5fba85 --- /dev/null +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -0,0 +1,131 @@ +storeRepository = $storeRepository; + $this->customerSession = $session; + $this->deploymentConfig = $deploymentConfig; + $this->customerRepository=$customerRepository; + } + + /** + * Execute action + * + * @return void + */ + public function execute() + { + $fromStoreCode = (string)$this->_request->getParam('___from_store'); + $customerId = (int)$this->_request->getParam('customer_id'); + $timeStamp = (string)$this->_request->getParam('time_stamp'); + $targetStoreCode = $this->_request->getParam('___to_store'); + $signature = (string)$this->_request->getParam('signature'); + $error = null; + + try { + /** @var \Magento\Store\Model\Store $fromStore */ + $fromStore = $this->storeRepository->get($fromStoreCode); + } catch (NoSuchEntityException $e) { + $error = __('Requested store is not found.'); + } + + if ($this->validateHash($customerId, $timeStamp, $signature, $fromStoreCode)) { + try { + $customer = $this->customerRepository->getById($customerId); + if (!$this->customerSession->isLoggedIn()) { + $this->customerSession->setCustomerDataAsLoggedIn($customer); + } + } catch (NoSuchEntityException $e) { + $error = __('The requested customer does not exist.'); + } catch (LocalizedException $e) { + $error = __('There was an error retrieving the customer record.'); + } + } else { + $error = __('Invalid request. Store switching action cannot be performed at this time.'); + } + + if ($error !== null) { + $this->messageManager->addErrorMessage($error); + $this->getResponse()->setRedirect('/'); + } else { + $this->getResponse()->setRedirect("/$targetStoreCode"); + } + } + + /** + * Validates one time token + * + * @param int $customerId + * @param string $timeStamp + * @param string $signature + * @param string $fromStoreCode + * @return bool + */ + private function validateHash(int $customerId, string $timeStamp, string $signature, string $fromStoreCode): bool + { + + if ($customerId && $timeStamp && $signature) { + $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); + $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + if (time() - $timeStamp <= 5 && hash_equals($signature, hash_hmac('sha256', $data, $key))) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php new file mode 100644 index 0000000000000..4a8549f299ed0 --- /dev/null +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -0,0 +1,88 @@ +customerSession = $customerSession; + $this->deploymentConfig = $deploymentConfig; + $this->urlHelper=$urlHelper; + } + + /** + * Builds redirect url with token + * + * @param StoreInterface $fromStore store where we came from + * @param StoreInterface $targetStore store where to go to + * @param string $redirectUrl original url requested for redirect after switching + * @return string redirect url + */ + public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string + { + $targetUrl = $redirectUrl; + $customerId = $this->customerSession->getId(); + + if ($customerId) { + $urlParts = parse_url($targetUrl); + $host = $urlParts['host']; + $scheme = $urlParts['scheme']; + $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + $timeStamp = time(); + $fromStoreCode = $fromStore->getCode(); + $targetStoreCode=$targetStore->getCode(); + $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); + $signature = hash_hmac('sha256', $data, $key); + $targetUrl = $scheme . "://" . $host.'/stores/store/switchrequest'; + $targetUrl = $this->urlHelper->addRequestParam( + $targetUrl, + ['customer_id' => $this->customerSession->getId()] + ); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => time()]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['signature' => $signature]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___from_store' => $fromStoreCode]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___to_store' => $targetStoreCode]); + } + return $targetUrl; + } +} diff --git a/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php b/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php new file mode 100644 index 0000000000000..129f5538f5cdc --- /dev/null +++ b/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php @@ -0,0 +1,80 @@ +mutableScopeConfig=$mutableScopeConfig; + $this->_scopeType=$scopeType; + } + + /** + * {@inheritdoc} + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function apply() + { + $this->mutableScopeConfig->setValue(self::XML_PATH_USE_FRONTEND_SID, 0, $this->_scopeType); + } + + /** + * {@inheritdoc} + */ + public static function getDependencies() + { + return []; + } + + /** + * {@inheritdoc} + */ + public static function getVersion() + { + return '2.0.0'; + } + + /** + * {@inheritdoc} + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php new file mode 100644 index 0000000000000..a8d4472145deb --- /dev/null +++ b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php @@ -0,0 +1,128 @@ +customerSessionMock = $this->getMockBuilder(CustomerSession::class) + ->disableOriginalConstructor()->getMock(); + $this->customerRepositoryMock = + $this->getMockBuilder(CustomerRepositoryInterface::class)->getMock(); + $this->storeRepositoryMock = + $this->getMockBuilder(\Magento\Store\Api\StoreRepositoryInterface::class) + ->disableOriginalConstructor()->setMethods(['get'])->getMockForAbstractClass(); + + $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)->getMock(); + $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) + ->disableOriginalConstructor() + ->setMethods(['setRedirect']) + ->getMockForAbstractClass(); + $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) + ->disableOriginalConstructor()->getMock(); + $this->storeMock = $this->getMockBuilder(StoreInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getBaseUrl']) + ->getMockForAbstractClass(); + + $this->model = (new ObjectManager($this))->getObject( + \Magento\Store\Controller\Store\SwitchRequest::class, + [ + 'customerSession' => $this->customerRepositoryMock, + 'deploymentConfig' => $this->deploymentConfigMock, + 'storeRepository' => $this->storeRepositoryMock, + 'customerRepository' => $this->customerRepositoryMock, + '_request' => $this->requestMock, + '_response' => $this->responseMock, + ] + ); + } + + /** + * @return void + */ + public function testExecute() + { + $fromStoreCode = 'sv2'; + $targetStoreCode = 'default'; + $expectedRedirectUrl='/'; + $customerId=5; + $timestamp='1556131830'; + + $this->requestMock->method('getParam') + ->willReturnMap([ + ['___from_store', null, $fromStoreCode], + ['customer_id', null, $customerId], + ['time_stamp', null, $timestamp], + ['___to_store', null, $targetStoreCode], + ['signature', null, 'cbc099b3cc4a9a8f3a78a97e7a579ceff19a2b26a6c88b08f0f58442ea5bd968'] + ]); + + $this->storeRepositoryMock + ->expects($this->once()) + ->method('get') + ->with($fromStoreCode) + ->willReturn($this->storeMock); + + $this->responseMock->expects($this->once())->method('setRedirect')->with($expectedRedirectUrl); + $this->model->execute(); + } +} \ No newline at end of file diff --git a/app/code/Magento/Store/etc/config.xml b/app/code/Magento/Store/etc/config.xml index b9e7ac1c6aca0..23182c8d76470 100644 --- a/app/code/Magento/Store/etc/config.xml +++ b/app/code/Magento/Store/etc/config.xml @@ -83,7 +83,7 @@ 0 0 0 - 1 + 0 1 diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml index defe0694d018d..62f6f41424025 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -436,6 +436,7 @@ Magento\Store\Model\StoreSwitcher\CleanTargetUrl Magento\Store\Model\StoreSwitcher\ManageStoreCookie Magento\Store\Model\StoreSwitcher\ManagePrivateContent + Magento\Store\Model\StoreSwitcher\HashGenerator diff --git a/app/code/Magento/Store/etc/frontend/sections.xml b/app/code/Magento/Store/etc/frontend/sections.xml index b1a9fc3cb1d71..b7dbfe405263b 100644 --- a/app/code/Magento/Store/etc/frontend/sections.xml +++ b/app/code/Magento/Store/etc/frontend/sections.xml @@ -8,4 +8,5 @@ + diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php deleted file mode 100644 index 5e70eb491b50c..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php +++ /dev/null @@ -1,210 +0,0 @@ -session = $objectManager->get(\Magento\Framework\Session\Generic::class); - - $this->scopeConfig = $this->getMockBuilder( - \Magento\Framework\App\Config\ScopeConfigInterface::class - )->setMethods( - ['getValue'] - )->disableOriginalConstructor()->getMockForAbstractClass(); - - $this->urlBuilder = $this->getMockBuilder( - \Magento\Framework\Url::class - )->setMethods( - ['isOwnOriginUrl'] - )->disableOriginalConstructor()->getMockForAbstractClass(); - - $this->request = $objectManager->get(\Magento\Framework\App\RequestInterface::class); - - $this->appState = $this->getMockBuilder(State::class) - ->setMethods(['getAreaCode']) - ->disableOriginalConstructor() - ->getMock(); - - $this->model = $objectManager->create( - \Magento\Framework\Session\SidResolver::class, - [ - 'scopeConfig' => $this->scopeConfig, - 'urlBuilder' => $this->urlBuilder, - 'sidNameMap' => [$this->customSessionName => $this->customSessionQueryParam], - 'request' => $this->request, - 'appState' => $this->appState, - ] - ); - } - - public function tearDown() - { - $this->request->setQuery(new Parameters()); - } - - /** - * @param mixed $sid - * @param bool $useFrontedSid - * @param bool $isOwnOriginUrl - * @param mixed $testSid - * @dataProvider dataProviderTestGetSid - */ - public function testGetSid($sid, $useFrontedSid, $isOwnOriginUrl, $testSid) - { - $this->appState->expects($this->atLeastOnce()) - ->method('getAreaCode') - ->willReturn(\Magento\Framework\App\Area::AREA_FRONTEND); - - $this->scopeConfig->expects( - $this->any() - )->method( - 'isSetFlag' - )->with( - \Magento\Framework\Session\SidResolver::XML_PATH_USE_FRONTEND_SID, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - )->will( - $this->returnValue($useFrontedSid) - ); - - $this->urlBuilder->expects($this->any())->method('isOwnOriginUrl')->will($this->returnValue($isOwnOriginUrl)); - - if ($testSid) { - $this->request->getQuery()->set($this->model->getSessionIdQueryParam($this->session), $testSid); - } - $this->assertEquals($sid, $this->model->getSid($this->session)); - $this->assertEquals($useFrontedSid, $this->model->getUseSessionInUrl()); - } - - /** - * @return array - */ - public function dataProviderTestGetSid() - { - return [ - [null, false, false, 'test-sid'], - [null, false, true, 'test-sid'], - [null, false, false, 'test-sid'], - [null, true, false, 'test-sid'], - [null, false, true, 'test-sid'], - ['test-sid', true, true, 'test-sid'], - [null, true, true, null] - ]; - } - - public function testGetSessionIdQueryParam() - { - $this->assertEquals(SidResolver::SESSION_ID_QUERY_PARAM, $this->model->getSessionIdQueryParam($this->session)); - } - - public function testGetSessionIdQueryParamCustom() - { - $this->session->destroy(); - $oldSessionName = $this->session->getName(); - $this->session->setName($this->customSessionName); - $this->assertEquals($this->customSessionQueryParam, $this->model->getSessionIdQueryParam($this->session)); - $this->session->setName($oldSessionName); - $this->session->start(); - } - - public function testSetGetUseSessionVar() - { - $this->assertFalse($this->model->getUseSessionVar()); - $this->model->setUseSessionVar(true); - $this->assertTrue($this->model->getUseSessionVar()); - } - - /** - * Variations of Use SID on frontend value. - * - * @return array - */ - public function dataProviderSessionInUrl() - { - return [ - [true], - [false], - ]; - } - - /** - * Testing "Use SID in URLs" flag. - * Checking that the method returns config value if not explicitly - * overridden. - * - * @param bool $configValue Use SID on frontend config value. - * @dataProvider dataProviderSessionInUrl - */ - public function testSetGetUseSessionInUrl($configValue) - { - $this->scopeConfig->expects( - $this->any() - )->method( - 'isSetFlag' - )->with( - \Magento\Framework\Session\SidResolver::XML_PATH_USE_FRONTEND_SID, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - )->will( - $this->returnValue($configValue) - ); - - $this->assertEquals($configValue, $this->model->getUseSessionInUrl()); - $this->model->setUseSessionInUrl(!$configValue); - $this->assertEquals(!$configValue, $this->model->getUseSessionInUrl()); - } -} diff --git a/lib/internal/Magento/Framework/Session/SidResolver.php b/lib/internal/Magento/Framework/Session/SidResolver.php index 1208aeb31eaee..117c46f3443a7 100644 --- a/lib/internal/Magento/Framework/Session/SidResolver.php +++ b/lib/internal/Magento/Framework/Session/SidResolver.php @@ -11,6 +11,7 @@ /** * Class SidResolver + * @deprecated 2.3.2 */ class SidResolver implements SidResolverInterface { From 25e7ae6d50d6fe4acbb7637361cda7842c9af820 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 25 Apr 2019 12:43:29 -0500 Subject: [PATCH 010/372] MC-15901: Recursion in filter widget --- .../Catalog/Model/Category/Attribute/Source/Sortby.php | 1 + .../Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php | 2 ++ .../Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php | 1 + .../Product/Form/Modifier/Data/AssociatedProducts.php | 5 +++++ 4 files changed, 9 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php index 97bc00bc7dd64..f279cc5150d7b 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php @@ -50,6 +50,7 @@ public function getAllOptions() $this->_options[] = [ 'label' => __($attribute['frontend_label']), 'value' => $attribute['attribute_code'], + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index 209fd235bcd6e..bc15c269df1c9 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -671,6 +671,7 @@ public function setupAttributeMeta(ProductAttributeInterface $attribute, $groupC 'scopeLabel' => $this->getScopeLabel($attribute), 'globalScope' => $this->isScopeGlobal($attribute), 'sortOrder' => $sortOrder * self::SORT_ORDER_MULTIPLIER, + '__disableTmpl' => ['label' => true, 'code' => true] ]); // TODO: Refactor to $attribute->getOptions() when MAGETWO-48289 is done @@ -816,6 +817,7 @@ public function setupAttributeContainerMeta(ProductAttributeInterface $attribute 'breakLine' => false, 'label' => $attribute->getDefaultFrontendLabel(), 'required' => $attribute->getIsRequired(), + '__disableTmpl' => ['label' => true] ] ); diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php index 4874dc8ea03ae..a7bdaaab64cb4 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php @@ -411,6 +411,7 @@ private function prepareAttributes( 'id' => $attribute->getAttributeId(), 'position' => $configurableAttributes[$attribute->getAttributeId()]['position'], 'chosen' => [], + '__disableTmpl' => true ]; foreach ($attribute->getOptions() as $option) { if (!empty($option->getValue())) { diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php index c474acbec5094..45a48a37e5ceb 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php @@ -213,6 +213,7 @@ public function getConfigurableAttributesData() 'code' => $attribute['code'], 'label' => $attribute['label'], 'position' => $attribute['position'], + '__disableTmpl' => true ]; foreach ($attribute['chosen'] as $chosenOption) { @@ -261,6 +262,7 @@ protected function prepareVariations() 'id' => $attribute->getAttributeId(), 'position' => $configurableAttributes[$attribute->getAttributeId()]['position'], 'chosen' => [], + '__disableTmpl' => true ]; foreach ($attribute->getOptions() as $option) { if (!empty($option->getValue())) { @@ -270,6 +272,7 @@ protected function prepareVariations() 'id' => $option->getValue(), 'label' => $option->getLabel(), 'value' => $option->getValue(), + '__disableTmpl' => true ]; } } @@ -281,6 +284,7 @@ protected function prepareVariations() 'id' => $optionId, 'label' => $variation[$attribute->getId()]['label'], 'value' => $optionId, + '__disableTmpl' => true ]; $variationOptions[] = $variationOption; $attributes[$attribute->getAttributeId()]['chosen'][$optionId] = $variationOption; @@ -306,6 +310,7 @@ protected function prepareVariations() 'newProduct' => 0, 'attributes' => $this->getTextAttributes($variationOptions), 'thumbnail_image' => $this->imageHelper->init($product, 'product_thumbnail_image')->getUrl(), + '__disableTmpl' => true ]; $productIds[] = $product->getId(); } From 2d3bb5074882cff729697338c0d6030f495f06f2 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 25 Apr 2019 13:30:29 -0500 Subject: [PATCH 011/372] MC-15811: Incorrect Url Fix static errors. Modify unit test. Fix store patch. --- .../Store/Controller/Store/SwitchRequest.php | 12 ++++++--- .../Model/StoreSwitcher/HashGenerator.php | 26 ++++++++++++++----- .../Store/Setup/Patch/Data/DisableSid.php | 26 ++++++++----------- .../Controller/Store/SwitchRequestTest.php | 23 +++++++++++----- app/code/Magento/Store/composer.json | 3 ++- 5 files changed, 58 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index af2d20b5fba85..d962e6be64de9 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -8,7 +8,7 @@ namespace Magento\Store\Controller\Store; use Magento\Framework\App\Action\Context; -use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Api\StoreRepositoryInterface; use Magento\Customer\Model\Session as CustomerSession; @@ -16,11 +16,12 @@ use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Customer\Api\CustomerRepositoryInterface; use \Magento\Framework\Exception\LocalizedException; +use Magento\Store\Model\StoreIsInactiveException; /** * Builds correct url to target store and performs redirect. */ -class SwitchRequest extends \Magento\Framework\App\Action\Action +class SwitchRequest extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface { /** * @var StoreRepositoryInterface @@ -78,10 +79,12 @@ public function execute() $error = null; try { - /** @var \Magento\Store\Model\Store $fromStore */ $fromStore = $this->storeRepository->get($fromStoreCode); + $this->storeRepository->getActiveStoreByCode($targetStoreCode); } catch (NoSuchEntityException $e) { $error = __('Requested store is not found.'); + } catch (StoreIsInactiveException $e) { + $error = __('Requested store is inactive.'); } if ($this->validateHash($customerId, $timeStamp, $signature, $fromStoreCode)) { @@ -101,7 +104,8 @@ public function execute() if ($error !== null) { $this->messageManager->addErrorMessage($error); - $this->getResponse()->setRedirect('/'); + //redirect to previous store + $this->getResponse()->setRedirect($fromStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK)); } else { $this->getResponse()->setRedirect("/$targetStoreCode"); } diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 4a8549f299ed0..56a865f8e2fd3 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -13,6 +13,7 @@ use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Url\Helper\Data as UrlHelper; use Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Authorization\Model\UserContextInterface; /** * Generate one time token and build redirect url @@ -35,19 +36,27 @@ class HashGenerator implements StoreSwitcherInterface */ private $urlHelper; + /** + * @var UserContextInterface + */ + private $currentUser; + /** * @param CustomerSession $customerSession * @param DeploymentConfig $deploymentConfig * @param UrlHelper $urlHelper + * @param UserContextInterface $currentUser */ public function __construct( CustomerSession $customerSession, DeploymentConfig $deploymentConfig, - UrlHelper $urlHelper + UrlHelper $urlHelper, + UserContextInterface $currentUser ) { $this->customerSession = $customerSession; $this->deploymentConfig = $deploymentConfig; - $this->urlHelper=$urlHelper; + $this->urlHelper = $urlHelper; + $this->currentUser = $currentUser; } /** @@ -61,22 +70,27 @@ public function __construct( public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string { $targetUrl = $redirectUrl; - $customerId = $this->customerSession->getId(); + $customerId = null; + + if ($this->currentUser->getUserType() == UserContextInterface::USER_TYPE_CUSTOMER) { + $customerId = $this->currentUser->getUserId(); + } if ($customerId) { + // phpcs:ignore $urlParts = parse_url($targetUrl); $host = $urlParts['host']; $scheme = $urlParts['scheme']; $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); $timeStamp = time(); $fromStoreCode = $fromStore->getCode(); - $targetStoreCode=$targetStore->getCode(); + $targetStoreCode = $targetStore->getCode(); $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); $signature = hash_hmac('sha256', $data, $key); - $targetUrl = $scheme . "://" . $host.'/stores/store/switchrequest'; + $targetUrl = $scheme . "://" . $host . '/stores/store/switchrequest'; $targetUrl = $this->urlHelper->addRequestParam( $targetUrl, - ['customer_id' => $this->customerSession->getId()] + ['customer_id' => $customerId] ); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => time()]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['signature' => $signature]); diff --git a/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php b/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php index 129f5538f5cdc..95df83043f15f 100644 --- a/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php +++ b/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php @@ -11,8 +11,7 @@ use \Magento\Framework\App\Config\MutableScopeConfigInterface; /** - * Class CreateDefaultPages - * @package Magento\Cms\Setup\Patch + * Disable default frontend SID */ class DisableSid implements DataPatchInterface, PatchVersionInterface { @@ -28,34 +27,31 @@ class DisableSid implements DataPatchInterface, PatchVersionInterface private $mutableScopeConfig; /** - * @var string + * scope type */ - protected $_scopeType; + const SCOPE_STORE = 'store'; /** * Disable Sid constructor. + * * @param MutableScopeConfigInterface $mutableScopeConfig - * @param string $scopeType */ public function __construct( - MutableScopeConfigInterface $mutableScopeConfig, - $scopeType + MutableScopeConfigInterface $mutableScopeConfig ) { - $this->mutableScopeConfig=$mutableScopeConfig; - $this->_scopeType=$scopeType; + $this->mutableScopeConfig = $mutableScopeConfig; } /** - * {@inheritdoc} - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @inheritdoc */ public function apply() { - $this->mutableScopeConfig->setValue(self::XML_PATH_USE_FRONTEND_SID, 0, $this->_scopeType); + $this->mutableScopeConfig->setValue(self::XML_PATH_USE_FRONTEND_SID, 0, self::SCOPE_STORE); } /** - * {@inheritdoc} + * @inheritdoc */ public static function getDependencies() { @@ -63,7 +59,7 @@ public static function getDependencies() } /** - * {@inheritdoc} + * @inheritdoc */ public static function getVersion() { @@ -71,7 +67,7 @@ public static function getVersion() } /** - * {@inheritdoc} + * @inheritdoc */ public function getAliases() { diff --git a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php index a8d4472145deb..ebd85d89c23a9 100644 --- a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php +++ b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php @@ -13,7 +13,7 @@ use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; /** - * Test class for \Magento\Store\Controller\Store\SwitchAction + * Test class for \Magento\Store\Controller\Store\SwitchRequest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class SwitchRequestTest extends \PHPUnit\Framework\TestCase @@ -51,7 +51,7 @@ class SwitchRequestTest extends \PHPUnit\Framework\TestCase /** * @var DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject */ - private $storeMock; + private $fromStoreMock; /** * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject @@ -69,7 +69,7 @@ protected function setUp() $this->getMockBuilder(CustomerRepositoryInterface::class)->getMock(); $this->storeRepositoryMock = $this->getMockBuilder(\Magento\Store\Api\StoreRepositoryInterface::class) - ->disableOriginalConstructor()->setMethods(['get'])->getMockForAbstractClass(); + ->disableOriginalConstructor()->setMethods(['get', 'getActiveStoreByCode'])->getMockForAbstractClass(); $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)->getMock(); $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) @@ -78,7 +78,7 @@ protected function setUp() ->getMockForAbstractClass(); $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) ->disableOriginalConstructor()->getMock(); - $this->storeMock = $this->getMockBuilder(StoreInterface::class) + $this->fromStoreMock = $this->getMockBuilder(StoreInterface::class) ->disableOriginalConstructor() ->setMethods(['getBaseUrl']) ->getMockForAbstractClass(); @@ -120,9 +120,20 @@ public function testExecute() ->expects($this->once()) ->method('get') ->with($fromStoreCode) - ->willReturn($this->storeMock); + ->willReturn($this->fromStoreMock); + + $this->storeRepositoryMock + ->expects($this->once()) + ->method('getActiveStoreByCode') + ->with($targetStoreCode); + + $this->fromStoreMock + ->expects($this->once()) + ->method('getBaseUrl') + ->with(\Magento\Framework\UrlInterface::URL_TYPE_LINK) + ->willReturn($expectedRedirectUrl); $this->responseMock->expects($this->once())->method('setRedirect')->with($expectedRedirectUrl); $this->model->execute(); } -} \ No newline at end of file +} diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index da408f105ccb6..390c6214d59a1 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -12,7 +12,8 @@ "magento/module-config": "*", "magento/module-directory": "*", "magento/module-media-storage": "*", - "magento/module-ui": "*" + "magento/module-ui": "*", + "magento/module-customer":"*" }, "suggest": { "magento/module-deploy": "*" From 25a8d8c0312a6347a47b292cea65c36e0903e849 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 25 Apr 2019 15:39:42 -0500 Subject: [PATCH 012/372] MC-15811: Incorrect Url Add composer dependency. Fix Unit test. Fix static failure in controller. --- .../Magento/Store/Controller/Store/SwitchRequest.php | 2 +- .../Store/Model/StoreSwitcher/HashGenerator.php | 10 ---------- app/code/Magento/Store/composer.json | 3 ++- .../testsuite/Magento/Framework/UrlTest.php | 7 ------- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index d962e6be64de9..e243cc912134f 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -132,4 +132,4 @@ private function validateHash(int $customerId, string $timeStamp, string $signat } return false; } -} \ No newline at end of file +} diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 56a865f8e2fd3..be110f965f74c 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -9,7 +9,6 @@ use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\StoreSwitcherInterface; -use Magento\Customer\Model\Session as CustomerSession; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Url\Helper\Data as UrlHelper; use Magento\Framework\Config\ConfigOptionsListConstants; @@ -20,12 +19,6 @@ */ class HashGenerator implements StoreSwitcherInterface { - - /** - * @var \Magento\Customer\Model\Session - */ - private $customerSession; - /** * @var \Magento\Framework\App\DeploymentConfig */ @@ -42,18 +35,15 @@ class HashGenerator implements StoreSwitcherInterface private $currentUser; /** - * @param CustomerSession $customerSession * @param DeploymentConfig $deploymentConfig * @param UrlHelper $urlHelper * @param UserContextInterface $currentUser */ public function __construct( - CustomerSession $customerSession, DeploymentConfig $deploymentConfig, UrlHelper $urlHelper, UserContextInterface $currentUser ) { - $this->customerSession = $customerSession; $this->deploymentConfig = $deploymentConfig; $this->urlHelper = $urlHelper; $this->currentUser = $currentUser; diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index 390c6214d59a1..8af8db8d935a0 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -13,7 +13,8 @@ "magento/module-directory": "*", "magento/module-media-storage": "*", "magento/module-ui": "*", - "magento/module-customer":"*" + "magento/module-customer": "*", + "magento/module-authorization": "*" }, "suggest": { "magento/module-deploy": "*" diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index 9d1d8761a16a7..47e814c96d505 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -20,13 +20,6 @@ protected function setUp() $this->model = Bootstrap::getObjectManager()->create(\Magento\Framework\Url::class); } - public function testSetGetUseSession() - { - $this->assertTrue((bool)$this->model->getUseSession()); - $this->model->setUseSession(false); - $this->assertFalse($this->model->getUseSession()); - } - public function testSetRouteFrontName() { $value = 'route'; From be6ade8dcd4a9a156cd8e18d7377baba7e538801 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 25 Apr 2019 16:01:35 -0500 Subject: [PATCH 013/372] MC-15901: Recursion in filter widget --- .../Catalog/Model/Category/Attribute/Source/Sortby.php | 3 +-- app/code/Magento/Catalog/Model/Category/DataProvider.php | 3 +++ .../Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php | 6 ++++++ .../Product/Form/Modifier/Data/AssociatedProducts.php | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php index f279cc5150d7b..2e152a5696192 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php @@ -49,8 +49,7 @@ public function getAllOptions() foreach ($this->_getCatalogConfig()->getAttributesUsedForSortBy() as $attribute) { $this->_options[] = [ 'label' => __($attribute['frontend_label']), - 'value' => $attribute['attribute_code'], - '__disableTmpl' => true + 'value' => $attribute['attribute_code'] ]; } } diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index a4127c9a97ffd..d3c4bfb8494bd 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -340,6 +340,9 @@ public function getAttributesMeta(Type $entityType) } if ($attribute->usesSource()) { $meta[$code]['options'] = $attribute->getSource()->getAllOptions(); + foreach ($meta[$code]['options'] as &$option) { + $option['__disableTmpl'] = true; + } } } diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index 91a09c907de65..ddaa520d7f75f 100755 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -563,6 +563,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], ], 'default_null_prod_not_new_locked_and_required' => [ @@ -582,6 +583,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], 'locked' => true, ], @@ -602,6 +604,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], ], 'default_null_prod_new_and_not_required' => [ @@ -621,6 +624,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], ], 'default_null_prod_new_locked_and_not_required' => [ @@ -640,6 +644,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], 'locked' => true, ], @@ -660,6 +665,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], ] ]; diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php index 45a48a37e5ceb..e98da6b6e4258 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php @@ -21,6 +21,8 @@ use Magento\Framework\Escaper; /** + * Loads data for product configurations. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class AssociatedProducts @@ -232,6 +234,7 @@ public function getConfigurableAttributesData() * * @return void * @throws \Zend_Currency_Exception + * phpcs:disable Generic.Metrics.NestingLevel.TooHigh */ protected function prepareVariations() { @@ -321,6 +324,7 @@ protected function prepareVariations() $this->productIds = $productIds; $this->productAttributes = array_values($attributes); } + //phpcs: enable /** * Get JSON string that contains attribute code and value From 2d924eff1fff9fdc3e16511a99d8806595fd1340 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 25 Apr 2019 17:53:08 -0500 Subject: [PATCH 014/372] MC-15901: Recursion in filter widget --- .../Catalog/Model/Category/Attribute/Source/Sortby.php | 2 +- app/code/Magento/Catalog/Model/Category/DataProvider.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php index 2e152a5696192..4dda2fe5786e3 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php @@ -40,7 +40,7 @@ protected function _getCatalogConfig() } /** - * {@inheritdoc} + * @inheritdoc */ public function getAllOptions() { diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index d3c4bfb8494bd..8db6ab8c228ca 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -210,6 +210,8 @@ public function getMeta() } /** + * Add 'use default checkbox' to attributes that can have it. + * * @param Category $category * @param array $meta * @return array @@ -501,6 +503,7 @@ private function convertValues($category, $categoryData) $stat = $fileInfo->getStat($fileName); $mime = $fileInfo->getMimeType($fileName); + // phpcs:ignore Magento2.Functions.DiscouragedFunction $categoryData[$attributeCode][0]['name'] = basename($fileName); if ($fileInfo->isBeginsWithMediaDirectoryPath($fileName)) { @@ -536,6 +539,8 @@ public function getDefaultMetaData($result) } /** + * List form field sets and fields. + * * @return array * @since 101.0.0 */ From 045f5520373222ea49e21a0bc7ef9d52124a18d1 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 25 Apr 2019 18:43:49 -0500 Subject: [PATCH 015/372] MC-15811: Incorrect Url Add class annotation. --- dev/tests/integration/testsuite/Magento/Framework/UrlTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index 47e814c96d505..21f0ebd5b77fc 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -8,6 +8,9 @@ use Zend\Stdlib\Parameters; use Magento\TestFramework\Helper\Bootstrap; +/** + * Test class for \Magento\Framework\Url + */ class UrlTest extends \PHPUnit\Framework\TestCase { /** From 38f2f3ad7451fb73b2ffc5e6be179840d8e9445f Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 26 Apr 2019 11:48:28 -0500 Subject: [PATCH 016/372] MC-15901: Recursion in filter widget --- .../DataProvider/Product/Form/Modifier/EavTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index ddaa520d7f75f..599d10c24027c 100755 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -563,7 +563,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_not_new_locked_and_required' => [ @@ -583,7 +583,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], 'locked' => true, ], @@ -604,7 +604,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_new_and_not_required' => [ @@ -624,7 +624,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_new_locked_and_not_required' => [ @@ -644,7 +644,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], 'locked' => true, ], @@ -665,7 +665,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], ] ]; From 2e9c607c12f2c065a74c4390cdaf23e9c5ff2485 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 29 Apr 2019 12:20:23 -0500 Subject: [PATCH 017/372] MC-15901: Recursion in filter widget --- .../app/Magento/Catalog/Test/Handler/Category/Curl.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php index 5c54b366b7ab4..fb9d6e9772c74 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php @@ -251,8 +251,13 @@ protected function getBlockId($landingName) $curl->write($url, [], CurlInterface::GET); $response = $curl->read(); $curl->close(); - preg_match('~\{"value":"(\d+)","label":"' . preg_quote($landingName) . '"\}~', $response, $matches); - $id = isset($matches[1]) ? (int)$matches[1] : null; + $id = null; + //Finding block option in 'Add block' options UI data. + preg_match('~\{[^\{\}]*?"label":"' . preg_quote($landingName) . '"[^\{\}]*?\}~', $response, $matches); + if (!empty($matches)) { + $blockOption = json_decode($matches[0], true); + $id = (int)$blockOption['value']; + } return $id; } From b5cb8f12faf14a013477bb4c164a336324a962c5 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Mon, 29 Apr 2019 15:47:46 -0500 Subject: [PATCH 018/372] MC-16045: Update symfony/http-foundation --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 06ab71ee75970..96c36a8b7cf34 100644 --- a/composer.lock +++ b/composer.lock @@ -8983,16 +8983,16 @@ }, { "name": "symfony/http-foundation", - "version": "v4.2.4", + "version": "v4.2.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "850a667d6254ccf6c61d853407b16f21c4579c77" + "reference": "6ebbe61f48069033225c9d3fa7eb5ed116d766d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/850a667d6254ccf6c61d853407b16f21c4579c77", - "reference": "850a667d6254ccf6c61d853407b16f21c4579c77", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6ebbe61f48069033225c9d3fa7eb5ed116d766d6", + "reference": "6ebbe61f48069033225c9d3fa7eb5ed116d766d6", "shasum": "" }, "require": { @@ -9033,7 +9033,7 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-02-26T08:03:39+00:00" + "time": "2019-04-17T14:56:00+00:00" }, { "name": "symfony/options-resolver", From 9672ace6359e41fd39825d732d747e3d9c149db0 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Wed, 1 May 2019 09:55:22 -0500 Subject: [PATCH 019/372] MC-15811: Incorrect Url Add integration test for token validator. Refactor validation logic from controller. --- .../Store/Controller/Store/SwitchRequest.php | 43 ++---- .../Model/StoreSwitcher/HashGenerator.php | 25 +++- .../Magento/Store/Model/HashGeneratorTest.php | 137 ++++++++++++++++++ 3 files changed, 176 insertions(+), 29 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index e243cc912134f..6d97487df67b8 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -13,7 +13,7 @@ use Magento\Store\Api\StoreRepositoryInterface; use Magento\Customer\Model\Session as CustomerSession; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; -use Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Store\Model\StoreSwitcher\HashGenerator; use Magento\Customer\Api\CustomerRepositoryInterface; use \Magento\Framework\Exception\LocalizedException; use Magento\Store\Model\StoreIsInactiveException; @@ -43,25 +43,33 @@ class SwitchRequest extends \Magento\Framework\App\Action\Action implements Http */ private $customerRepository; + /** + * @var HashGenerator + */ + private $hashGenerator; + /** * @param Context $context * @param StoreRepositoryInterface $storeRepository * @param CustomerSession $session * @param DeploymentConfig $deploymentConfig * @param CustomerRepositoryInterface $customerRepository + * @param HashGenerator $hashGenerator */ public function __construct( Context $context, StoreRepositoryInterface $storeRepository, CustomerSession $session, DeploymentConfig $deploymentConfig, - CustomerRepositoryInterface $customerRepository + CustomerRepositoryInterface $customerRepository, + HashGenerator $hashGenerator ) { parent::__construct($context); $this->storeRepository = $storeRepository; $this->customerSession = $session; $this->deploymentConfig = $deploymentConfig; - $this->customerRepository=$customerRepository; + $this->customerRepository = $customerRepository; + $this->hashGenerator = $hashGenerator; } /** @@ -80,14 +88,15 @@ public function execute() try { $fromStore = $this->storeRepository->get($fromStoreCode); - $this->storeRepository->getActiveStoreByCode($targetStoreCode); + $targetStore=$this->storeRepository->getActiveStoreByCode($targetStoreCode); + $targetUrl=$targetStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK); } catch (NoSuchEntityException $e) { $error = __('Requested store is not found.'); } catch (StoreIsInactiveException $e) { $error = __('Requested store is inactive.'); } - if ($this->validateHash($customerId, $timeStamp, $signature, $fromStoreCode)) { + if ($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])) { try { $customer = $this->customerRepository->getById($customerId); if (!$this->customerSession->isLoggedIn()) { @@ -107,29 +116,7 @@ public function execute() //redirect to previous store $this->getResponse()->setRedirect($fromStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK)); } else { - $this->getResponse()->setRedirect("/$targetStoreCode"); - } - } - - /** - * Validates one time token - * - * @param int $customerId - * @param string $timeStamp - * @param string $signature - * @param string $fromStoreCode - * @return bool - */ - private function validateHash(int $customerId, string $timeStamp, string $signature, string $fromStoreCode): bool - { - - if ($customerId && $timeStamp && $signature) { - $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); - $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); - if (time() - $timeStamp <= 5 && hash_equals($signature, hash_hmac('sha256', $data, $key))) { - return true; - } + $this->getResponse()->setRedirect($targetUrl); } - return false; } } diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index be110f965f74c..0e0e77b04f94f 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -71,6 +71,7 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s $urlParts = parse_url($targetUrl); $host = $urlParts['host']; $scheme = $urlParts['scheme']; + $path=$urlParts['path']; $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); $timeStamp = time(); $fromStoreCode = $fromStore->getCode(); @@ -82,11 +83,33 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s $targetUrl, ['customer_id' => $customerId] ); - $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => time()]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => $timeStamp]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['signature' => $signature]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___from_store' => $fromStoreCode]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___to_store' => $targetStoreCode]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['path' => $path]); } return $targetUrl; } + + /** + * Validates one time token + * + * @param string $signature + * @param array $data + * @return bool + */ + public function validateHash(string $signature, array $data): bool + { + if (!empty($signature) && !empty($data)) { + $timeStamp = $data[1] ?? 0; + $value = implode(",", $data); + $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + + if (time() - $timeStamp <= 5 && hash_equals($signature, hash_hmac('sha256', $value, $key))) { + return true; + } + } + return false; + } } diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php new file mode 100644 index 0000000000000..7b5bb357b9345 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -0,0 +1,137 @@ +objectManager = Bootstrap::getObjectManager(); + $session = $this->objectManager->create( + Session::class + ); + $this->accountManagement = $this->objectManager->create(AccountManagementInterface::class); + $customer = $this->accountManagement->authenticate('customer@example.com', 'password'); + $session->setCustomerDataAsLoggedIn($customer); + $this->customerSessionUserContext = $this->objectManager->create( + \Magento\Customer\Model\Authorization\CustomerSessionUserContext::class, + ['customerSession' => $session] + ); + $this->hashGenerator = $this->objectManager->create( + StoreSwitcher\HashGenerator::class, + ['currentUser' => $this->customerSessionUserContext] + ); + $this->customerId = $customer->getId(); + $this->deploymentConfig = $this->objectManager->get(DeploymentConfig::class); + $this->key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + } + + /** + * @magentoDataFixture Magento/Store/_files/store.php + * @magentoDataFixture Magento/Store/_files/second_store.php + * @magentoDataFixture Magento/Customer/_files/customer.php + * @return void + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function testSwitch(): void + { + $redirectUrl = "http://domain.com/"; + $fromStoreCode = 'test'; + $toStoreCode = 'fixture_second_store'; + /** @var \Magento\Store\Api\StoreRepositoryInterface $storeRepository */ + $storeRepository = $this->objectManager->create(\Magento\Store\Api\StoreRepositoryInterface::class); + $fromStore = $storeRepository->get($fromStoreCode); + $toStore = $storeRepository->get($toStoreCode); + $timeStamp = time(); + $data = implode(',', [$this->customerId, $timeStamp, $fromStoreCode]); + $signature = hash_hmac('sha256', $data, $this->key); + $customerId = $this->customerId; + + $expectedUrl = "http://domain.com/stores/store/switchrequest?customer_id=$customerId"; + $expectedUrl .= "&time_stamp=$timeStamp&signature=$signature"; + $expectedUrl .= "&___from_store=$fromStoreCode&___to_store=$toStoreCode"; + $this->assertEquals($expectedUrl, $this->hashGenerator->switch($fromStore, $toStore, $redirectUrl)); + } + + /** + * @return void + */ + public function testValidateHashWithCorrectData(): void + { + $timeStamp = time(); + $customerId = $this->customerId; + $fromStoreCode = 'test'; + $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); + $signature = hash_hmac('sha256', $data, $this->key); + $this->assertTrue($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])); + } + + /** + * @return void + */ + public function testValidateHashWithInCorrectData(): void + { + $timeStamp = 0; + $customerId = 8; + $fromStoreCode = 'test'; + $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); + $signature = hash_hmac('sha256', $data, $this->key); + $this->assertFalse($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])); + } +} From b4562e0a0d738c65818f4a8bb5a194fa275ee3a0 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Wed, 1 May 2019 15:51:31 -0500 Subject: [PATCH 020/372] MC-15975: Fixed incorrect behavior of template variables --- lib/internal/Magento/Framework/Filter/Template.php | 3 ++- .../Magento/Framework/Filter/Test/Unit/TemplateTest.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 6a04e8e8c6953..38198bb9a717b 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -81,7 +81,8 @@ class Template implements \Zend_Filter_Interface 'settemplateprocessor', 'gettemplateprocessor', 'vardirective', - 'delete' + 'delete', + 'getdatausingmethod' ]; /** diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php index 0ee3a06ce5420..b7f76cb35953a 100644 --- a/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php +++ b/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php @@ -445,7 +445,8 @@ public function disallowedMethods() ['setTemplateProcessor'], ['getTemplateProcessor'], ['varDirective'], - ['delete'] + ['delete'], + ['getDataUsingMethod'] ]; } } From 02babd14eaf25752c8bef5949773c09a0f3ebcc0 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Thu, 2 May 2019 11:19:47 +0300 Subject: [PATCH 021/372] MC-13886: Downloadable Product controller|API save changes --- .../Helper/Plugin/Downloadable.php | 81 +++++++++++++++- .../Downloadable/Model/Link/Builder.php | 13 ++- .../Model/Link/ContentValidator.php | 80 +++++++++++----- .../Downloadable/Model/LinkRepository.php | 96 ++++++++++++++----- .../Model/Sample/ContentValidator.php | 55 ++++++++--- .../Downloadable/Model/SampleRepository.php | 38 ++++---- .../Helper/Plugin/DownloadableTest.php | 19 +++- .../Unit/Model/Link/ContentValidatorTest.php | 25 ++++- .../Model/Sample/ContentValidatorTest.php | 25 ++++- .../Product/Form/Modifier/Data/Links.php | 20 +++- .../Product/Form/Modifier/Data/Samples.php | 18 +++- .../Downloadable/Api/LinkRepositoryTest.php | 69 +++++++++++++ .../Api/ProductRepositoryTest.php | 5 +- .../Downloadable/Api/SampleRepositoryTest.php | 31 ++++++ 14 files changed, 484 insertions(+), 91 deletions(-) diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php index a283891afc406..f310b376633d3 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php @@ -5,11 +5,14 @@ */ namespace Magento\Downloadable\Controller\Adminhtml\Product\Initialization\Helper\Plugin; -use Magento\Framework\App\RequestInterface; +use Magento\Downloadable\Api\Data\LinkInterfaceFactory; +use Magento\Downloadable\Api\Data\SampleInterfaceFactory; +use Magento\Downloadable\Helper\Download; use Magento\Downloadable\Model\Link\Builder as LinkBuilder; +use Magento\Downloadable\Model\Product\Type; +use Magento\Downloadable\Model\ResourceModel\Sample\Collection; use Magento\Downloadable\Model\Sample\Builder as SampleBuilder; -use Magento\Downloadable\Api\Data\SampleInterfaceFactory; -use Magento\Downloadable\Api\Data\LinkInterfaceFactory; +use Magento\Framework\App\RequestInterface; /** * Class for initialization downloadable info from request. @@ -42,8 +45,6 @@ class Downloadable private $linkBuilder; /** - * Constructor - * * @param RequestInterface $request * @param LinkBuilder $linkBuilder * @param SampleBuilder $sampleBuilder @@ -79,14 +80,18 @@ public function afterInitialize( \Magento\Catalog\Model\Product $product ) { if ($downloadable = $this->request->getPost('downloadable')) { + $product->setTypeId(Type::TYPE_DOWNLOADABLE); $product->setDownloadableData($downloadable); $extension = $product->getExtensionAttributes(); + $productLinks = $product->getTypeInstance()->getLinks($product); + $productSamples = $product->getTypeInstance()->getSamples($product); if (isset($downloadable['link']) && is_array($downloadable['link'])) { $links = []; foreach ($downloadable['link'] as $linkData) { if (!$linkData || (isset($linkData['is_delete']) && $linkData['is_delete'])) { continue; } else { + $linkData = $this->processLink($linkData, $productLinks); $links[] = $this->linkBuilder->setData( $linkData )->build( @@ -104,6 +109,7 @@ public function afterInitialize( if (!$sampleData || (isset($sampleData['is_delete']) && (bool)$sampleData['is_delete'])) { continue; } else { + $sampleData = $this->processSample($sampleData, $productSamples); $samples[] = $this->sampleBuilder->setData( $sampleData )->build( @@ -124,4 +130,69 @@ public function afterInitialize( } return $product; } + + /** + * Check Links type and status. + * + * @param array $linkData + * @param array $productLinks + * @return array + */ + private function processLink(array $linkData, array $productLinks): array + { + $linkId = $linkData['link_id'] ?? null; + if ($linkId && isset($productLinks[$linkId])) { + $linkData = $this->processFileStatus($linkData, $productLinks[$linkId]->getLinkFile()); + $linkData['sample'] = $this->processFileStatus( + $linkData['sample'] ?? [], + $productLinks[$linkId]->getSampleFile() + ); + } else { + $linkData = $this->processFileStatus($linkData, null); + $linkData['sample'] = $this->processFileStatus($linkData['sample'] ?? [], null); + } + + return $linkData; + } + + /** + * Check Sample type and status. + * + * @param array $sampleData + * @param Collection $productSamples + * @return array + */ + private function processSample(array $sampleData, Collection $productSamples): array + { + $sampleId = $sampleData['sample_id'] ?? null; + /** @var \Magento\Downloadable\Model\Sample $productSample */ + $productSample = $sampleId ? $productSamples->getItemById($sampleId) : null; + if ($sampleId && $productSample) { + $sampleData = $this->processFileStatus($sampleData, $productSample->getSampleFile()); + } else { + $sampleData = $this->processFileStatus($sampleData, null); + } + + return $sampleData; + } + + /** + * Compare file path from request with DB and set status. + * + * @param array $data + * @param string|null $file + * @return array + */ + private function processFileStatus(array $data, ?string $file): array + { + if (isset($data['type']) && $data['type'] === Download::LINK_TYPE_FILE && isset($data['file']['0']['file'])) { + if ($data['file'][0]['file'] !== $file) { + $data['file'][0]['status'] = 'new'; + } else { + $data['file'][0]['status'] = 'old'; + } + } + + return $data; + } } diff --git a/app/code/Magento/Downloadable/Model/Link/Builder.php b/app/code/Magento/Downloadable/Model/Link/Builder.php index 83d01f76fe9cd..ff76f7eeda440 100644 --- a/app/code/Magento/Downloadable/Model/Link/Builder.php +++ b/app/code/Magento/Downloadable/Model/Link/Builder.php @@ -69,6 +69,8 @@ public function __construct( } /** + * Set Data. + * * @param array $data * @return $this * @since 100.1.0 @@ -80,6 +82,8 @@ public function setData(array $data) } /** + * Build correct data structure. + * * @param \Magento\Downloadable\Api\Data\LinkInterface $link * @return \Magento\Downloadable\Api\Data\LinkInterface * @throws \Magento\Framework\Exception\LocalizedException @@ -134,6 +138,8 @@ public function build(\Magento\Downloadable\Api\Data\LinkInterface $link) } /** + * Reset data. + * * @return void */ private function resetData() @@ -142,6 +148,8 @@ private function resetData() } /** + * Get existing component or create new. + * * @return Link */ private function getComponent() @@ -153,6 +161,8 @@ private function getComponent() } /** + * Build correct sample structure. + * * @param \Magento\Downloadable\Api\Data\LinkInterface $link * @param array $sample * @return \Magento\Downloadable\Api\Data\LinkInterface @@ -174,7 +184,8 @@ private function buildSample(\Magento\Downloadable\Api\Data\LinkInterface $link, ), \Magento\Downloadable\Api\Data\LinkInterface::class ); - if ($link->getSampleType() === \Magento\Downloadable\Helper\Download::LINK_TYPE_FILE) { + if ($link->getSampleType() === \Magento\Downloadable\Helper\Download::LINK_TYPE_FILE + && isset($sample['file'])) { $linkSampleFileName = $this->downloadableFile->moveFileFromTmp( $this->getComponent()->getBaseSampleTmpPath(), $this->getComponent()->getBaseSamplePath(), diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php index 088356caefad0..8497bf7de6592 100644 --- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php @@ -6,10 +6,16 @@ namespace Magento\Downloadable\Model\Link; use Magento\Downloadable\Api\Data\LinkInterface; +use Magento\Downloadable\Helper\File; use Magento\Downloadable\Model\File\ContentValidator as FileContentValidator; use Magento\Framework\Exception\InputException; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Url\Validator as UrlValidator; +/** + * Class to validate Link Content. + */ class ContentValidator { /** @@ -22,20 +28,28 @@ class ContentValidator */ protected $urlValidator; + /** + * @var File + */ + private $fileHelper; + /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator + * @param File|null $fileHelper */ public function __construct( FileContentValidator $fileContentValidator, - UrlValidator $urlValidator + UrlValidator $urlValidator, + File $fileHelper = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; + $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); } /** - * Check if link content is valid + * Check if link content is valid. * * @param LinkInterface $link * @param bool $validateLinkContent @@ -63,50 +77,66 @@ public function isValid(LinkInterface $link, $validateLinkContent = true, $valid if ($validateSampleContent) { $this->validateSampleResource($link); } + return true; } /** - * Validate link resource (file or URL) + * Validate link resource (file or URL). * * @param LinkInterface $link - * @throws InputException * @return void + * @throws InputException */ protected function validateLinkResource(LinkInterface $link) { - if ($link->getLinkType() == 'url' - && !$this->urlValidator->isValid($link->getLinkUrl()) - ) { - throw new InputException(__('Link URL must have valid format.')); - } - if ($link->getLinkType() == 'file' - && (!$link->getLinkFileContent() - || !$this->fileContentValidator->isValid($link->getLinkFileContent())) - ) { - throw new InputException(__('Provided file content must be valid base64 encoded data.')); + if ($link->getLinkType() === 'url') { + if (!$this->urlValidator->isValid($link->getLinkUrl())) { + throw new InputException(__('Link URL must have valid format.')); + } + } elseif ($link->getLinkFileContent()) { + if (!$this->fileContentValidator->isValid($link->getLinkFileContent())) { + throw new InputException(__('Provided file content must be valid base64 encoded data.')); + } + } elseif (!$this->isFileValid($link->getBasePath() . $link->getLinkFile())) { + throw new InputException(__('Link file not found. Please try again.')); } } /** - * Validate sample resource (file or URL) + * Validate sample resource (file or URL). * * @param LinkInterface $link - * @throws InputException * @return void + * @throws InputException */ protected function validateSampleResource(LinkInterface $link) { - if ($link->getSampleType() == 'url' - && !$this->urlValidator->isValid($link->getSampleUrl()) - ) { - throw new InputException(__('Sample URL must have valid format.')); + if ($link->getSampleType() === 'url') { + if (!$this->urlValidator->isValid($link->getSampleUrl())) { + throw new InputException(__('Sample URL must have valid format.')); + } + } elseif ($link->getSampleFileContent()) { + if (!$this->fileContentValidator->isValid($link->getSampleFileContent())) { + throw new InputException(__('Provided file content must be valid base64 encoded data.')); + } + } elseif (!$this->isFileValid($link->getBaseSamplePath() . $link->getSampleFile())) { + throw new InputException(__('Link sample file not found. Please try again.')); } - if ($link->getSampleType() == 'file' - && (!$link->getSampleFileContent() - || !$this->fileContentValidator->isValid($link->getSampleFileContent())) - ) { - throw new InputException(__('Provided file content must be valid base64 encoded data.')); + } + + /** + * Check that Links File or Sample is valid. + * + * @param string $file + * @return bool + */ + private function isFileValid(string $file): bool + { + try { + return $this->fileHelper->ensureFileInFilesystem($file); + } catch (ValidatorException $e) { + return false; } } } diff --git a/app/code/Magento/Downloadable/Model/LinkRepository.php b/app/code/Magento/Downloadable/Model/LinkRepository.php index 0898f1924e538..57e0fee5c1181 100644 --- a/app/code/Magento/Downloadable/Model/LinkRepository.php +++ b/app/code/Magento/Downloadable/Model/LinkRepository.php @@ -97,7 +97,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getList($sku) { @@ -107,6 +107,8 @@ public function getList($sku) } /** + * @inheritdoc + * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @return array */ @@ -166,9 +168,11 @@ protected function setBasicFields($resourceData, $dataObject) } /** - * {@inheritdoc} + * @inheritdoc + * * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) + * @throws InputException */ public function save($sku, LinkInterface $link, $isGlobalScopeContent = true) { @@ -181,24 +185,23 @@ public function save($sku, LinkInterface $link, $isGlobalScopeContent = true) __('The product needs to be the downloadable type. Verify the product and try again.') ); } - $validateLinkContent = !($link->getLinkType() === 'file' && $link->getLinkFile()); - $validateSampleContent = !($link->getSampleType() === 'file' && $link->getSampleFile()); - if (!$this->contentValidator->isValid($link, $validateLinkContent, $validateSampleContent)) { + $this->validateLinkType($link); + $validateSampleContent = $this->isValidateSample($link); + if (!$this->contentValidator->isValid($link, true, $validateSampleContent)) { throw new InputException(__('The link information is invalid. Verify the link and try again.')); } - - if (!in_array($link->getLinkType(), ['url', 'file'], true)) { - throw new InputException(__('The link type is invalid. Verify and try again.')); - } $title = $link->getTitle(); if (empty($title)) { throw new InputException(__('The link title is empty. Enter the link title and try again.')); } + return $this->saveLink($product, $link, $isGlobalScopeContent); } } /** + * Construct Data structure and Save it. + * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param LinkInterface $link * @param bool $isGlobalScopeContent @@ -220,7 +223,7 @@ protected function saveLink( 'is_shareable' => $link->getIsShareable(), ]; - if ($link->getLinkType() == 'file' && $link->getLinkFile() === null) { + if ($link->getLinkType() == 'file' && $link->getLinkFileContent() !== null) { $linkData['file'] = $this->jsonEncoder->encode( [ $this->fileContentUploader->upload($link->getLinkFileContent(), 'link_file'), @@ -242,7 +245,7 @@ protected function saveLink( if ($link->getSampleType() == 'file') { $linkData['sample']['type'] = 'file'; - if ($link->getSampleFile() === null) { + if ($link->getSampleFileContent() !== null) { $fileData = [ $this->fileContentUploader->upload($link->getSampleFileContent(), 'link_sample_file'), ]; @@ -269,6 +272,8 @@ protected function saveLink( } /** + * Update existing Link. + * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param LinkInterface $link * @param bool $isGlobalScopeContent @@ -298,9 +303,9 @@ protected function updateLink( __("The downloadable link isn't related to the product. Verify the link and try again.") ); } - $validateLinkContent = !($link->getLinkFileContent() === null); - $validateSampleContent = !($link->getSampleFileContent() === null); - if (!$this->contentValidator->isValid($link, $validateLinkContent, $validateSampleContent)) { + $this->validateLinkType($link); + $validateSampleContent = $this->isValidateSample($link); + if (!$this->contentValidator->isValid($link, true, $validateSampleContent)) { throw new InputException(__('The link information is invalid. Verify the link and try again.')); } if ($isGlobalScopeContent) { @@ -312,20 +317,16 @@ protected function updateLink( throw new InputException(__('The link title is empty. Enter the link title and try again.')); } } - - if ($link->getLinkType() == 'file' && $link->getLinkFileContent() === null && !$link->getLinkFile()) { - $link->setLinkFile($existingLink->getLinkFile()); - } - if ($link->getSampleType() == 'file' && $link->getSampleFileContent() === null && !$link->getSampleFile()) { - $link->setSampleFile($existingLink->getSampleFile()); + if (!$validateSampleContent) { + $this->resetLinkSampleContent($link, $existingLink); } - $this->saveLink($product, $link, $isGlobalScopeContent); + return $existingLink->getId(); } /** - * {@inheritdoc} + * @inheritdoc */ public function delete($id) { @@ -344,6 +345,57 @@ public function delete($id) return true; } + /** + * Check that Link type exist. + * + * @param LinkInterface $link + * @throws \Magento\Framework\Exception\InputException + */ + private function validateLinkType(LinkInterface $link): void + { + if (!in_array($link->getLinkType(), ['url', 'file'], true)) { + throw new InputException(__('The link type is invalid. Verify and try again.')); + } + } + + /** + * Check that Link sample type exist. + * + * @param \Magento\Downloadable\Api\Data\LinkInterface $link + * @return bool + * @throws \Magento\Framework\Exception\InputException + */ + private function isValidateSample(LinkInterface $link): bool + { + if ($link->hasSampleType()) { + if (in_array($link->getSampleType(), ['url', 'file'], true)) { + return true; + } else { + throw new InputException(__('The link sample type is invalid. Verify and try again.')); + } + } + + return false; + } + + /** + * Reset Sample type and file. + * + * @param LinkInterface $link + * @param LinkInterface $existingLink + * @return void + */ + private function resetLinkSampleContent(LinkInterface $link, LinkInterface $existingLink): void + { + $existingType = $existingLink->getSampleType(); + $link->setSampleType($existingType); + if ($existingType === 'file') { + $link->setSampleFile($existingLink->getSampleFile()); + } else { + $link->setSampleUrl($existingLink->getSampleUrl()); + } + } + /** * Get MetadataPool instance * diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php index 6a273bfe5d34e..7348b04793a8f 100644 --- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php @@ -6,10 +6,16 @@ namespace Magento\Downloadable\Model\Sample; use Magento\Downloadable\Api\Data\SampleInterface; +use Magento\Downloadable\Helper\File; use Magento\Downloadable\Model\File\ContentValidator as FileContentValidator; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Url\Validator as UrlValidator; +/** + * Class to validate Sample Content. + */ class ContentValidator { /** @@ -22,20 +28,28 @@ class ContentValidator */ protected $fileContentValidator; + /** + * @var File + */ + private $fileHelper; + /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator + * @param File|null $fileHelper */ public function __construct( FileContentValidator $fileContentValidator, - UrlValidator $urlValidator + UrlValidator $urlValidator, + File $fileHelper = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; + $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); } /** - * Check if sample content is valid + * Check if sample content is valid. * * @param SampleInterface $sample * @param bool $validateSampleContent @@ -51,29 +65,44 @@ public function isValid(SampleInterface $sample, $validateSampleContent = true) if ($validateSampleContent) { $this->validateSampleResource($sample); } + return true; } /** - * Validate sample resource (file or URL) + * Validate sample resource (file or URL). * * @param SampleInterface $sample - * @throws InputException * @return void + * @throws InputException */ protected function validateSampleResource(SampleInterface $sample) { - $sampleFile = $sample->getSampleFileContent(); - if ($sample->getSampleType() == 'file' - && (!$sampleFile || !$this->fileContentValidator->isValid($sampleFile)) - ) { - throw new InputException(__('Provided file content must be valid base64 encoded data.')); + if ($sample->getSampleType() === 'url') { + if (!$this->urlValidator->isValid($sample->getSampleUrl())) { + throw new InputException(__('Sample URL must have valid format.')); + } + } elseif ($sample->getSampleFileContent()) { + if (!$this->fileContentValidator->isValid($sample->getSampleFileContent())) { + throw new InputException(__('Provided file content must be valid base64 encoded data.')); + } + } elseif (!$this->isFileValid($sample->getBasePath() . $sample->getSampleFile())) { + throw new InputException(__('Sample file not found. Please try again.')); } + } - if ($sample->getSampleType() == 'url' - && !$this->urlValidator->isValid($sample->getSampleUrl()) - ) { - throw new InputException(__('Sample URL must have valid format.')); + /** + * Check that Samples file is valid. + * + * @param string $file + * @return bool + */ + private function isFileValid(string $file): bool + { + try { + return $this->fileHelper->ensureFileInFilesystem($file); + } catch (ValidatorException $e) { + return false; } } } diff --git a/app/code/Magento/Downloadable/Model/SampleRepository.php b/app/code/Magento/Downloadable/Model/SampleRepository.php index 07c7631fade13..37f376e666243 100644 --- a/app/code/Magento/Downloadable/Model/SampleRepository.php +++ b/app/code/Magento/Downloadable/Model/SampleRepository.php @@ -189,17 +189,12 @@ public function save( __('The product needs to be the downloadable type. Verify the product and try again.') ); } - $validateSampleContent = !($sample->getSampleType() === 'file' && $sample->getSampleFile()); - if (!$this->contentValidator->isValid($sample, $validateSampleContent)) { + $this->validateSampleType($sample); + if (!$this->contentValidator->isValid($sample, true)) { throw new InputException( __('The sample information is invalid. Verify the information and try again.') ); } - - if (!in_array($sample->getSampleType(), ['url', 'file'], true)) { - throw new InputException(__('The sample type is invalid. Verify the sample type and try again.')); - } - $title = $sample->getTitle(); if (empty($title)) { throw new InputException(__('The sample title is empty. Enter the title and try again.')); @@ -230,7 +225,7 @@ protected function saveSample( 'title' => $sample->getTitle(), ]; - if ($sample->getSampleType() === 'file' && $sample->getSampleFile() === null) { + if ($sample->getSampleType() === 'file' && $sample->getSampleFileContent() !== null) { $sampleData['file'] = $this->jsonEncoder->encode( [ $this->fileContentUploader->upload($sample->getSampleFileContent(), 'sample'), @@ -293,9 +288,8 @@ protected function updateSample( __("The downloadable sample isn't related to the product. Verify the link and try again.") ); } - - $validateFileContent = $sample->getSampleFileContent() === null ? false : true; - if (!$this->contentValidator->isValid($sample, $validateFileContent)) { + $this->validateSampleType($sample); + if (!$this->contentValidator->isValid($sample, true)) { throw new InputException(__('The sample information is invalid. Verify the information and try again.')); } if ($isGlobalScopeContent) { @@ -312,14 +306,8 @@ protected function updateSample( } else { $existingSample->setTitle($sample->getTitle()); } - - if ($sample->getSampleType() === 'file' - && $sample->getSampleFileContent() === null - && $sample->getSampleFile() !== null - ) { - $existingSample->setSampleFile($sample->getSampleFile()); - } $this->saveSample($product, $sample, $isGlobalScopeContent); + return $existingSample->getId(); } @@ -343,6 +331,20 @@ public function delete($id) return true; } + /** + * Check that Sample type exist. + * + * @param SampleInterface $sample + * @throws InputException + * @return void + */ + private function validateSampleType(SampleInterface $sample): void + { + if (!in_array($sample->getSampleType(), ['url', 'file'], true)) { + throw new InputException(__('The sample type is invalid. Verify the sample type and try again.')); + } + } + /** * Get MetadataPool instance * diff --git a/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php b/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php index 25a5d86b0385c..508ef930f5d04 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php @@ -7,6 +7,9 @@ use Magento\Catalog\Api\Data\ProductExtensionInterface; +/** + * Unit tests for \Magento\Downloadable\Controller\Adminhtml\Product\Initialization\Helper\Plugin\Downloadable. + */ class DownloadableTest extends \PHPUnit\Framework\TestCase { /** @@ -34,12 +37,17 @@ class DownloadableTest extends \PHPUnit\Framework\TestCase */ private $extensionAttributesMock; + /** + * @var \Magento\Downloadable\Model\Product\Type|\Magento\Catalog\Api\Data\ProductExtensionInterface + */ + private $downloadableProductTypeMock; + protected function setUp() { $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); $this->productMock = $this->createPartialMock( \Magento\Catalog\Model\Product::class, - ['setDownloadableData', 'getExtensionAttributes', '__wakeup'] + ['setDownloadableData', 'getExtensionAttributes', '__wakeup', 'getTypeInstance'] ); $this->subjectMock = $this->createMock( \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper::class @@ -62,6 +70,10 @@ protected function setUp() $sampleBuilderMock = $this->getMockBuilder(\Magento\Downloadable\Model\Sample\Builder::class) ->disableOriginalConstructor() ->getMock(); + $this->downloadableProductTypeMock = $this->createPartialMock( + \Magento\Downloadable\Model\Product\Type::class, + ['getLinks', 'getSamples'] + ); $this->downloadablePlugin = new \Magento\Downloadable\Controller\Adminhtml\Product\Initialization\Helper\Plugin\Downloadable( $this->requestMock, @@ -86,6 +98,11 @@ public function testAfterInitializeWithNoDataToSave($downloadable) $this->productMock->expects($this->once()) ->method('getExtensionAttributes') ->willReturn($this->extensionAttributesMock); + $this->productMock->expects($this->exactly(2)) + ->method('getTypeInstance') + ->willReturn($this->downloadableProductTypeMock); + $this->downloadableProductTypeMock->expects($this->once())->method('getLinks')->willReturn([]); + $this->downloadableProductTypeMock->expects($this->once())->method('getSamples')->willReturn([]); $this->extensionAttributesMock->expects($this->once()) ->method('setDownloadableProductLinks') ->with([]); diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php index 2639c22ff2ca2..5484e39bd57fc 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php @@ -5,8 +5,12 @@ */ namespace Magento\Downloadable\Test\Unit\Model\Link; +use Magento\Downloadable\Helper\File; use Magento\Downloadable\Model\Link\ContentValidator; +/** + * Unit tests for Magento\Downloadable\Model\Link\ContentValidator. + */ class ContentValidatorTest extends \PHPUnit\Framework\TestCase { /** @@ -34,13 +38,32 @@ class ContentValidatorTest extends \PHPUnit\Framework\TestCase */ protected $sampleFileMock; + /** + * @var File|\PHPUnit_Framework_MockObject_MockObject + */ + private $fileMock; + + /** + * @inheritdoc + */ protected function setUp() { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->fileValidatorMock = $this->createMock(\Magento\Downloadable\Model\File\ContentValidator::class); $this->urlValidatorMock = $this->createMock(\Magento\Framework\Url\Validator::class); $this->linkFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); $this->sampleFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); - $this->validator = new ContentValidator($this->fileValidatorMock, $this->urlValidatorMock); + $this->fileMock = $this->createMock(File::class); + + $this->validator = $objectManager->getObject( + ContentValidator::class, + [ + 'fileContentValidator' => $this->fileValidatorMock, + 'urlValidator' => $this->urlValidatorMock, + 'fileHelper' => $this->fileMock, + ] + ); } public function testIsValid() diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php index c863fb7ad62ff..90bcfa2e39bef 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php @@ -6,7 +6,11 @@ namespace Magento\Downloadable\Test\Unit\Model\Sample; use Magento\Downloadable\Model\Sample\ContentValidator; +use Magento\Downloadable\Helper\File; +/** + * Unit tests for Magento\Downloadable\Model\Sample\ContentValidator. + */ class ContentValidatorTest extends \PHPUnit\Framework\TestCase { /** @@ -34,12 +38,31 @@ class ContentValidatorTest extends \PHPUnit\Framework\TestCase */ protected $sampleFileMock; + /** + * @var File|\PHPUnit_Framework_MockObject_MockObject + */ + private $fileMock; + + /** + * @inheritdoc + */ protected function setUp() { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->fileValidatorMock = $this->createMock(\Magento\Downloadable\Model\File\ContentValidator::class); $this->urlValidatorMock = $this->createMock(\Magento\Framework\Url\Validator::class); $this->sampleFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); - $this->validator = new ContentValidator($this->fileValidatorMock, $this->urlValidatorMock); + $this->fileMock = $this->createMock(File::class); + + $this->validator = $objectManager->getObject( + ContentValidator::class, + [ + 'fileContentValidator' => $this->fileValidatorMock, + 'urlValidator' => $this->urlValidatorMock, + 'fileHelper' => $this->fileMock, + ] + ); } public function testIsValid() diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php index f29708cc9a2c6..7a8d201d09c4f 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php @@ -13,6 +13,7 @@ use Magento\Framework\UrlInterface; use Magento\Downloadable\Model\Link as LinkModel; use Magento\Downloadable\Api\Data\LinkInterface; +use Magento\Framework\Exception\ValidatorException; /** * Class Links @@ -155,7 +156,7 @@ protected function addSampleFile(array $linkData, LinkInterface $link) $sampleFile = $link->getSampleFile(); if ($sampleFile) { $file = $this->downloadableFile->getFilePath($this->linkModel->getBaseSamplePath(), $sampleFile); - if ($this->downloadableFile->ensureFileInFilesystem($file)) { + if ($this->checkLinksFile($file)) { $linkData['sample']['file'][0] = [ 'file' => $sampleFile, 'name' => $this->downloadableFile->getFileFromPathFile($sampleFile), @@ -184,7 +185,7 @@ protected function addLinkFile(array $linkData, LinkInterface $link) $linkFile = $link->getLinkFile(); if ($linkFile) { $file = $this->downloadableFile->getFilePath($this->linkModel->getBasePath(), $linkFile); - if ($this->downloadableFile->ensureFileInFilesystem($file)) { + if ($this->checkLinksFile($file)) { $linkData['file'][0] = [ 'file' => $linkFile, 'name' => $this->downloadableFile->getFileFromPathFile($linkFile), @@ -201,6 +202,21 @@ protected function addLinkFile(array $linkData, LinkInterface $link) return $linkData; } + /** + * Check that Links File or Sample is valid. + * + * @param string $file + * @return bool + */ + private function checkLinksFile(string $file): bool + { + try { + return $this->downloadableFile->ensureFileInFilesystem($file); + } catch (ValidatorException $e) { + return false; + } + } + /** * Return formatted price with two digits after decimal point * diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php index b000de487b775..ac8f3eb962957 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php @@ -11,6 +11,7 @@ use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Downloadable\Helper\File as DownloadableFile; +use Magento\Framework\Exception\ValidatorException; use Magento\Framework\UrlInterface; use Magento\Downloadable\Api\Data\SampleInterface; @@ -136,7 +137,7 @@ protected function addSampleFile(array $sampleData, SampleInterface $sample) $sampleFile = $sample->getSampleFile(); if ($sampleFile) { $file = $this->downloadableFile->getFilePath($this->sampleModel->getBasePath(), $sampleFile); - if ($this->downloadableFile->ensureFileInFilesystem($file)) { + if ($this->checkSamplesFile($file)) { $sampleData['file'][0] = [ 'file' => $sampleFile, 'name' => $this->downloadableFile->getFileFromPathFile($sampleFile), @@ -152,4 +153,19 @@ protected function addSampleFile(array $sampleData, SampleInterface $sample) return $sampleData; } + + /** + * Check that Sample file is valid. + * + * @param string $file + * @return bool + */ + private function checkSamplesFile(string $file): bool + { + try { + return $this->downloadableFile->ensureFileInFilesystem($file); + } catch (ValidatorException $e) { + return false; + } + } } diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index c881969a3b679..3fa60f93fc683 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -12,6 +12,9 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; +/** + * API tests for Magento\Downloadable\Model\LinkRepository. + */ class LinkRepositoryTest extends WebapiAbstract { /** @@ -135,10 +138,12 @@ public function testCreateUploadsProvidedFileContent() 'number_of_downloads' => 100, 'link_type' => 'file', 'link_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'image.jpg', ], 'sample_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'image.jpg', ], @@ -292,6 +297,64 @@ public function testCreateThrowsExceptionIfLinkFileContentIsNotAValidBase64Encod $this->_webApiCall($this->createServiceInfo, $requestData); } + /** + * Check that error appears when link file not existing in filesystem. + * + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Link file not found. Please try again. + * @return void + */ + public function testCreateThrowsExceptionIfLinkFileNotFoundInSystem(): void + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'link' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'price' => 10, + 'is_shareable' => 1, + 'number_of_downloads' => 100, + 'link_type' => 'file', + 'link_file' => '/n/o/nexistfile.png', + 'sample_type' => 'url', + 'sample_file' => 'http://google.com', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + + /** + * Check that error appears when link sample file not existing in filesystem. + * + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Link sample file not found. Please try again. + * @return void + */ + public function testCreateThrowsExceptionIfLinkSampleFileNotFoundInSystem(): void + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'link' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'price' => 10, + 'is_shareable' => 1, + 'number_of_downloads' => 100, + 'link_type' => 'url', + 'link_url' => 'http://www.example.com/', + 'sample_type' => 'file', + 'sample_file' => '/n/o/nexistfile.png', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception @@ -339,6 +402,7 @@ public function testCreateThrowsExceptionIfLinkFileNameContainsForbiddenCharacte 'number_of_downloads' => 100, 'link_type' => 'file', 'link_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'name/with|forbidden{characters', ], @@ -370,6 +434,7 @@ public function testCreateThrowsExceptionIfSampleFileNameContainsForbiddenCharac 'link_url' => 'http://www.example.com/', 'sample_type' => 'file', 'sample_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'name/with|forbidden{characters', ], @@ -610,7 +675,9 @@ public function testUpdate() 'is_shareable' => 0, 'number_of_downloads' => 50, 'link_type' => 'url', + 'link_url' => 'http://google.com', 'sample_type' => 'url', + 'sample_url' => 'http://google.com', ], ]; $this->assertEquals($linkId, $this->_webApiCall($this->updateServiceInfo, $requestData)); @@ -643,7 +710,9 @@ public function testUpdateSavesDataInGlobalScopeAndDoesNotAffectValuesStoredInSt 'is_shareable' => 0, 'number_of_downloads' => 50, 'link_type' => 'url', + 'link_url' => 'http://google.com', 'sample_type' => 'url', + 'sample_url' => 'http://google.com', ], ]; diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php index 769abadf20585..782c15a99b4d4 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php @@ -227,7 +227,9 @@ public function testUpdateDownloadableProductLinks() 'price' => 5.0, 'number_of_downloads' => 999, 'link_type' => 'file', - 'sample_type' => 'file' + 'link_file' => $linkFile, + 'sample_type' => 'file', + 'sample_file' => $sampleFile, ]; $linkData = $this->getLinkData(); @@ -273,6 +275,7 @@ public function testUpdateDownloadableProductLinks() 'number_of_downloads' => 999, 'link_type' => 'file', 'sample_type' => 'file', + 'sample_file' => '/s/a/sample2.jpg', ]; $expectedLinkData = array_merge($expectedLinkData, $this->getExpectedLinkData()); $this->assertEquals($expectedLinkData, $resultLinks); diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php index b537947d5e4db..b339e97d8d69d 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php @@ -11,6 +11,9 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; +/** + * API tests for Magento\Downloadable\Model\SampleRepository. + */ class SampleRepositoryTest extends WebapiAbstract { /** @@ -131,6 +134,7 @@ public function testCreateUploadsProvidedFileContent() 'title' => 'Title', 'sort_order' => 1, 'sample_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'image.jpg', ], @@ -223,6 +227,30 @@ public function testCreateThrowsExceptionIfSampleTypeIsInvalid() $this->_webApiCall($this->createServiceInfo, $requestData); } + /** + * Check that error appears when sample file not existing in filesystem. + * + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Sample file not found. Please try again. + * @return void + */ + public function testCreateThrowsExceptionIfSampleFileNotFoundInSystem(): void + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'sample' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'sample_type' => 'file', + 'sample_file' => '/n/o/nexistfile.png', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception @@ -262,6 +290,7 @@ public function testCreateThrowsExceptionIfSampleFileNameContainsForbiddenCharac 'sort_order' => 15, 'sample_type' => 'file', 'sample_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'name/with|forbidden{characters', ], @@ -380,6 +409,7 @@ public function testUpdate() 'title' => 'Updated Title', 'sort_order' => 2, 'sample_type' => 'url', + 'sample_url' => 'http://google.com', ], ]; @@ -408,6 +438,7 @@ public function testUpdateSavesDataInGlobalScopeAndDoesNotAffectValuesStoredInSt 'title' => 'Updated Title', 'sort_order' => 2, 'sample_type' => 'url', + 'sample_url' => 'http://google.com', ], ]; From 01a7ea0f8f3977b700a05ccf650108476582c390 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Thu, 2 May 2019 11:59:44 +0300 Subject: [PATCH 022/372] MC-13886: Downloadable Product controller|API save changes --- .../Downloadable/Test/Unit/Model/LinkRepositoryTest.php | 5 ++++- .../Downloadable/Test/Unit/Model/SampleRepositoryTest.php | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php index 821f251929f8b..4494877b70f6c 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php @@ -162,7 +162,8 @@ protected function getLinkMock(array $linkData) 'getNumberOfDownloads', 'getIsShareable', 'getLinkUrl', - 'getLinkFile' + 'getLinkFile', + 'hasSampleType', ] ) ->getMockForAbstractClass(); @@ -436,6 +437,8 @@ public function testUpdateThrowsExceptionIfTitleIsEmptyAndScopeIsGlobal() 'price' => 10.1, 'number_of_downloads' => 100, 'is_shareable' => true, + 'link_type' => 'url', + 'link_url' => 'https://google.com', ]; $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) ->will($this->returnValue($this->productMock)); diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php index 8e13bd83b039e..f1ca30bd7dd36 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php @@ -353,6 +353,8 @@ public function testUpdateThrowsExceptionIfTitleIsEmptyAndScopeIsGlobal() 'id' => $sampleId, 'title' => '', 'sort_order' => 1, + 'sample_type' => 'url', + 'sample_url' => 'https://google.com', ]; $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) ->will($this->returnValue($this->productMock)); From 56edf648db291846e72cd50137b085c52797da03 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Thu, 2 May 2019 12:37:01 +0300 Subject: [PATCH 023/372] MC-13886: Downloadable Product controller|API save changes --- .../testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php index 782c15a99b4d4..cf99b34207124 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php @@ -275,7 +275,6 @@ public function testUpdateDownloadableProductLinks() 'number_of_downloads' => 999, 'link_type' => 'file', 'sample_type' => 'file', - 'sample_file' => '/s/a/sample2.jpg', ]; $expectedLinkData = array_merge($expectedLinkData, $this->getExpectedLinkData()); $this->assertEquals($expectedLinkData, $resultLinks); From a7b52c225775fab2591732986c2ca582ff6f3710 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 2 May 2019 10:28:12 -0500 Subject: [PATCH 024/372] MC-16044: Update symfony/dependency-injection --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 5d9f7fbdf695c..cbeaac07eaa08 100644 --- a/composer.lock +++ b/composer.lock @@ -8853,16 +8853,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.2.4", + "version": "v4.2.7", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "cdadb3765df7c89ac93628743913b92bb91f1704" + "reference": "2748643dd378626c4d348a31ad12394e2d6f7ea8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/cdadb3765df7c89ac93628743913b92bb91f1704", - "reference": "cdadb3765df7c89ac93628743913b92bb91f1704", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2748643dd378626c4d348a31ad12394e2d6f7ea8", + "reference": "2748643dd378626c4d348a31ad12394e2d6f7ea8", "shasum": "" }, "require": { @@ -8922,7 +8922,7 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-02-23T15:17:42+00:00" + "time": "2019-04-16T11:19:53+00:00" }, { "name": "symfony/dom-crawler", From eb3249e41e3a9b052b492407bcccbc24f56ae935 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Thu, 2 May 2019 17:50:35 +0300 Subject: [PATCH 025/372] MC-13886: Downloadable Product controller|API save changes --- .../Downloadable/Model/LinkRepository.php | 30 ++++++++----------- .../Helper/Plugin/DownloadableTest.php | 3 ++ .../Product/Form/Modifier/Data/Links.php | 6 ++-- .../Product/Form/Modifier/Data/Samples.php | 4 +-- .../Downloadable/Api/LinkRepositoryTest.php | 4 +-- .../Downloadable/Api/SampleRepositoryTest.php | 2 +- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/LinkRepository.php b/app/code/Magento/Downloadable/Model/LinkRepository.php index 57e0fee5c1181..68fbba2a7d385 100644 --- a/app/code/Magento/Downloadable/Model/LinkRepository.php +++ b/app/code/Magento/Downloadable/Model/LinkRepository.php @@ -180,14 +180,14 @@ public function save($sku, LinkInterface $link, $isGlobalScopeContent = true) if ($link->getId() !== null) { return $this->updateLink($product, $link, $isGlobalScopeContent); } else { - if ($product->getTypeId() !== \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) { + if ($product->getTypeId() !== Type::TYPE_DOWNLOADABLE) { throw new InputException( __('The product needs to be the downloadable type. Verify the product and try again.') ); } $this->validateLinkType($link); - $validateSampleContent = $this->isValidateSample($link); - if (!$this->contentValidator->isValid($link, true, $validateSampleContent)) { + $this->validateSampleType($link); + if (!$this->contentValidator->isValid($link, true, $link->hasSampleType())) { throw new InputException(__('The link information is invalid. Verify the link and try again.')); } $title = $link->getTitle(); @@ -304,7 +304,8 @@ protected function updateLink( ); } $this->validateLinkType($link); - $validateSampleContent = $this->isValidateSample($link); + $this->validateSampleType($link); + $validateSampleContent = $link->hasSampleType(); if (!$this->contentValidator->isValid($link, true, $validateSampleContent)) { throw new InputException(__('The link information is invalid. Verify the link and try again.')); } @@ -349,7 +350,8 @@ public function delete($id) * Check that Link type exist. * * @param LinkInterface $link - * @throws \Magento\Framework\Exception\InputException + * @return void + * @throws InputException */ private function validateLinkType(LinkInterface $link): void { @@ -361,21 +363,15 @@ private function validateLinkType(LinkInterface $link): void /** * Check that Link sample type exist. * - * @param \Magento\Downloadable\Api\Data\LinkInterface $link - * @return bool - * @throws \Magento\Framework\Exception\InputException + * @param LinkInterface $link + * @return void + * @throws InputException */ - private function isValidateSample(LinkInterface $link): bool + private function validateSampleType(LinkInterface $link): void { - if ($link->hasSampleType()) { - if (in_array($link->getSampleType(), ['url', 'file'], true)) { - return true; - } else { - throw new InputException(__('The link sample type is invalid. Verify and try again.')); - } + if ($link->hasSampleType() && !in_array($link->getSampleType(), ['url', 'file'], true)) { + throw new InputException(__('The link sample type is invalid. Verify and try again.')); } - - return false; } /** diff --git a/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php b/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php index 508ef930f5d04..55353c16b4727 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php @@ -42,6 +42,9 @@ class DownloadableTest extends \PHPUnit\Framework\TestCase */ private $downloadableProductTypeMock; + /** + * @inheritdoc + */ protected function setUp() { $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php index 7a8d201d09c4f..0a3ea2fc6ba19 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php @@ -156,7 +156,7 @@ protected function addSampleFile(array $linkData, LinkInterface $link) $sampleFile = $link->getSampleFile(); if ($sampleFile) { $file = $this->downloadableFile->getFilePath($this->linkModel->getBaseSamplePath(), $sampleFile); - if ($this->checkLinksFile($file)) { + if ($this->isLinkFileValid($file)) { $linkData['sample']['file'][0] = [ 'file' => $sampleFile, 'name' => $this->downloadableFile->getFileFromPathFile($sampleFile), @@ -185,7 +185,7 @@ protected function addLinkFile(array $linkData, LinkInterface $link) $linkFile = $link->getLinkFile(); if ($linkFile) { $file = $this->downloadableFile->getFilePath($this->linkModel->getBasePath(), $linkFile); - if ($this->checkLinksFile($file)) { + if ($this->isLinkFileValid($file)) { $linkData['file'][0] = [ 'file' => $linkFile, 'name' => $this->downloadableFile->getFileFromPathFile($linkFile), @@ -208,7 +208,7 @@ protected function addLinkFile(array $linkData, LinkInterface $link) * @param string $file * @return bool */ - private function checkLinksFile(string $file): bool + private function isLinkFileValid(string $file): bool { try { return $this->downloadableFile->ensureFileInFilesystem($file); diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php index ac8f3eb962957..988f429de1d87 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php @@ -137,7 +137,7 @@ protected function addSampleFile(array $sampleData, SampleInterface $sample) $sampleFile = $sample->getSampleFile(); if ($sampleFile) { $file = $this->downloadableFile->getFilePath($this->sampleModel->getBasePath(), $sampleFile); - if ($this->checkSamplesFile($file)) { + if ($this->isSampleFileValid($file)) { $sampleData['file'][0] = [ 'file' => $sampleFile, 'name' => $this->downloadableFile->getFileFromPathFile($sampleFile), @@ -160,7 +160,7 @@ protected function addSampleFile(array $sampleData, SampleInterface $sample) * @param string $file * @return bool */ - private function checkSamplesFile(string $file): bool + private function isSampleFileValid(string $file): bool { try { return $this->downloadableFile->ensureFileInFilesystem($file); diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index 3fa60f93fc683..1c239fba244ac 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -305,7 +305,7 @@ public function testCreateThrowsExceptionIfLinkFileContentIsNotAValidBase64Encod * @expectedExceptionMessage Link file not found. Please try again. * @return void */ - public function testCreateThrowsExceptionIfLinkFileNotFoundInSystem(): void + public function testCreateLinkWithMissingFileThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, @@ -334,7 +334,7 @@ public function testCreateThrowsExceptionIfLinkFileNotFoundInSystem(): void * @expectedExceptionMessage Link sample file not found. Please try again. * @return void */ - public function testCreateThrowsExceptionIfLinkSampleFileNotFoundInSystem(): void + public function testCreateLinkWithMissingSampleThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php index b339e97d8d69d..a97e4c5d9e119 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php @@ -235,7 +235,7 @@ public function testCreateThrowsExceptionIfSampleTypeIsInvalid() * @expectedExceptionMessage Sample file not found. Please try again. * @return void */ - public function testCreateThrowsExceptionIfSampleFileNotFoundInSystem(): void + public function testCreateSampleWithMissingFileThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, From 32be5b967d5c8f2e680e8cc39b64ddc1851567be Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 2 May 2019 14:48:00 -0500 Subject: [PATCH 026/372] MC-15811: Incorrect Url Refactor controller validation logic. Fix integration test. --- .../Store/Controller/Store/SwitchRequest.php | 53 ++++++------------- .../Model/StoreSwitcher/HashGenerator.php | 10 ++-- .../Magento/Store/Model/HashGeneratorTest.php | 28 ++++++++-- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index 6d97487df67b8..e220941017c34 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -10,34 +10,24 @@ use Magento\Framework\App\Action\Context; use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Store\Api\StoreRepositoryInterface; use Magento\Customer\Model\Session as CustomerSession; -use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Store\Model\StoreSwitcher\HashGenerator; use Magento\Customer\Api\CustomerRepositoryInterface; use \Magento\Framework\Exception\LocalizedException; -use Magento\Store\Model\StoreIsInactiveException; +use Magento\Framework\Url\DecoderInterface; +use \Magento\Framework\App\ActionInterface; /** * Builds correct url to target store and performs redirect. */ class SwitchRequest extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface { - /** - * @var StoreRepositoryInterface - */ - private $storeRepository; /** * @var customerSession */ private $customerSession; - /** - * @var \Magento\Framework\App\DeploymentConfig - */ - private $deploymentConfig; - /** * @var CustomerRepositoryInterface */ @@ -48,28 +38,30 @@ class SwitchRequest extends \Magento\Framework\App\Action\Action implements Http */ private $hashGenerator; + /** + * @var DecoderInterface + */ + private $urlDecoder; + /** * @param Context $context - * @param StoreRepositoryInterface $storeRepository * @param CustomerSession $session - * @param DeploymentConfig $deploymentConfig * @param CustomerRepositoryInterface $customerRepository * @param HashGenerator $hashGenerator + * @param DecoderInterface $urlDecoder */ public function __construct( Context $context, - StoreRepositoryInterface $storeRepository, CustomerSession $session, - DeploymentConfig $deploymentConfig, CustomerRepositoryInterface $customerRepository, - HashGenerator $hashGenerator + HashGenerator $hashGenerator, + DecoderInterface $urlDecoder ) { parent::__construct($context); - $this->storeRepository = $storeRepository; $this->customerSession = $session; - $this->deploymentConfig = $deploymentConfig; $this->customerRepository = $customerRepository; $this->hashGenerator = $hashGenerator; + $this->urlDecoder = $urlDecoder; } /** @@ -82,41 +74,30 @@ public function execute() $fromStoreCode = (string)$this->_request->getParam('___from_store'); $customerId = (int)$this->_request->getParam('customer_id'); $timeStamp = (string)$this->_request->getParam('time_stamp'); - $targetStoreCode = $this->_request->getParam('___to_store'); $signature = (string)$this->_request->getParam('signature'); $error = null; + $encodedUrl = (string)$this->_request->getParam(ActionInterface::PARAM_NAME_URL_ENCODED); + $targetUrl = $this->urlDecoder->decode($encodedUrl); + $data=[$customerId, $timeStamp, $fromStoreCode]; - try { - $fromStore = $this->storeRepository->get($fromStoreCode); - $targetStore=$this->storeRepository->getActiveStoreByCode($targetStoreCode); - $targetUrl=$targetStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK); - } catch (NoSuchEntityException $e) { - $error = __('Requested store is not found.'); - } catch (StoreIsInactiveException $e) { - $error = __('Requested store is inactive.'); - } - - if ($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])) { + if ($targetUrl && $this->hashGenerator->validateHash($signature, $data)) { try { $customer = $this->customerRepository->getById($customerId); if (!$this->customerSession->isLoggedIn()) { $this->customerSession->setCustomerDataAsLoggedIn($customer); } + $this->getResponse()->setRedirect($targetUrl); } catch (NoSuchEntityException $e) { $error = __('The requested customer does not exist.'); } catch (LocalizedException $e) { $error = __('There was an error retrieving the customer record.'); } } else { - $error = __('Invalid request. Store switching action cannot be performed at this time.'); + $error = __('The requested store cannot be found. Please check the request and try again.'); } if ($error !== null) { $this->messageManager->addErrorMessage($error); - //redirect to previous store - $this->getResponse()->setRedirect($fromStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK)); - } else { - $this->getResponse()->setRedirect($targetUrl); } } } diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 0e0e77b04f94f..945b5f36a0a8c 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -13,6 +13,7 @@ use Magento\Framework\Url\Helper\Data as UrlHelper; use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Authorization\Model\UserContextInterface; +use \Magento\Framework\App\ActionInterface; /** * Generate one time token and build redirect url @@ -61,6 +62,7 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s { $targetUrl = $redirectUrl; $customerId = null; + $encodedUrl = $this->urlHelper->getEncodedUrl($redirectUrl); if ($this->currentUser->getUserType() == UserContextInterface::USER_TYPE_CUSTOMER) { $customerId = $this->currentUser->getUserId(); @@ -71,11 +73,9 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s $urlParts = parse_url($targetUrl); $host = $urlParts['host']; $scheme = $urlParts['scheme']; - $path=$urlParts['path']; $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); $timeStamp = time(); $fromStoreCode = $fromStore->getCode(); - $targetStoreCode = $targetStore->getCode(); $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); $signature = hash_hmac('sha256', $data, $key); $targetUrl = $scheme . "://" . $host . '/stores/store/switchrequest'; @@ -86,8 +86,10 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => $timeStamp]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['signature' => $signature]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___from_store' => $fromStoreCode]); - $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___to_store' => $targetStoreCode]); - $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['path' => $path]); + $targetUrl = $this->urlHelper->addRequestParam( + $targetUrl, + [ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl] + ); } return $targetUrl; } diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 7b5bb357b9345..8b0cec3dfa20e 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -14,6 +14,8 @@ use Magento\Customer\Model\Session; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Config\ConfigOptionsListConstants; +use \Magento\Framework\App\ActionInterface; +use Magento\Framework\Url\Helper\Data as UrlHelper; /** * Test class for \Magento\Store\Model\StoreSwitcher\HashGenerator @@ -33,7 +35,7 @@ class HashGeneratorTest extends \PHPUnit\Framework\TestCase private $objectManager; /** - * + * @var int */ private $customerId; @@ -51,10 +53,15 @@ class HashGeneratorTest extends \PHPUnit\Framework\TestCase private $deploymentConfig; /** - * + * @var string */ private $key; + /** + * @var UrlHelper + */ + private $urlHelper; + /** * Class dependencies initialization * @return void @@ -80,6 +87,7 @@ protected function setUp() $this->customerId = $customer->getId(); $this->deploymentConfig = $this->objectManager->get(DeploymentConfig::class); $this->key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + $this->urlHelper=$this->objectManager->create(UrlHelper::class); } /** @@ -94,6 +102,7 @@ public function testSwitch(): void $redirectUrl = "http://domain.com/"; $fromStoreCode = 'test'; $toStoreCode = 'fixture_second_store'; + $encodedUrl=$this->urlHelper->getEncodedUrl($redirectUrl); /** @var \Magento\Store\Api\StoreRepositoryInterface $storeRepository */ $storeRepository = $this->objectManager->create(\Magento\Store\Api\StoreRepositoryInterface::class); $fromStore = $storeRepository->get($fromStoreCode); @@ -103,9 +112,18 @@ public function testSwitch(): void $signature = hash_hmac('sha256', $data, $this->key); $customerId = $this->customerId; - $expectedUrl = "http://domain.com/stores/store/switchrequest?customer_id=$customerId"; - $expectedUrl .= "&time_stamp=$timeStamp&signature=$signature"; - $expectedUrl .= "&___from_store=$fromStoreCode&___to_store=$toStoreCode"; + $expectedUrl = "http://domain.com/stores/store/switchrequest"; + $expectedUrl = $this->urlHelper->addRequestParam( + $expectedUrl, + ['customer_id' => $customerId] + ); + $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['time_stamp' => $timeStamp]); + $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['signature' => $signature]); + $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['___from_store' => $fromStoreCode]); + $expectedUrl = $this->urlHelper->addRequestParam( + $expectedUrl, + [ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl] + ); $this->assertEquals($expectedUrl, $this->hashGenerator->switch($fromStore, $toStore, $redirectUrl)); } From 5bffe14b6ec4eab02a1e87b01c0bd62bfa2f7775 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 2 May 2019 15:04:46 -0500 Subject: [PATCH 027/372] MC-15811: Incorrect Url Remove redundant unit test. --- .../Controller/Store/SwitchRequestTest.php | 139 ------------------ 1 file changed, 139 deletions(-) delete mode 100644 app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php diff --git a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php deleted file mode 100644 index ebd85d89c23a9..0000000000000 --- a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php +++ /dev/null @@ -1,139 +0,0 @@ -customerSessionMock = $this->getMockBuilder(CustomerSession::class) - ->disableOriginalConstructor()->getMock(); - $this->customerRepositoryMock = - $this->getMockBuilder(CustomerRepositoryInterface::class)->getMock(); - $this->storeRepositoryMock = - $this->getMockBuilder(\Magento\Store\Api\StoreRepositoryInterface::class) - ->disableOriginalConstructor()->setMethods(['get', 'getActiveStoreByCode'])->getMockForAbstractClass(); - - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)->getMock(); - $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) - ->disableOriginalConstructor() - ->setMethods(['setRedirect']) - ->getMockForAbstractClass(); - $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) - ->disableOriginalConstructor()->getMock(); - $this->fromStoreMock = $this->getMockBuilder(StoreInterface::class) - ->disableOriginalConstructor() - ->setMethods(['getBaseUrl']) - ->getMockForAbstractClass(); - - $this->model = (new ObjectManager($this))->getObject( - \Magento\Store\Controller\Store\SwitchRequest::class, - [ - 'customerSession' => $this->customerRepositoryMock, - 'deploymentConfig' => $this->deploymentConfigMock, - 'storeRepository' => $this->storeRepositoryMock, - 'customerRepository' => $this->customerRepositoryMock, - '_request' => $this->requestMock, - '_response' => $this->responseMock, - ] - ); - } - - /** - * @return void - */ - public function testExecute() - { - $fromStoreCode = 'sv2'; - $targetStoreCode = 'default'; - $expectedRedirectUrl='/'; - $customerId=5; - $timestamp='1556131830'; - - $this->requestMock->method('getParam') - ->willReturnMap([ - ['___from_store', null, $fromStoreCode], - ['customer_id', null, $customerId], - ['time_stamp', null, $timestamp], - ['___to_store', null, $targetStoreCode], - ['signature', null, 'cbc099b3cc4a9a8f3a78a97e7a579ceff19a2b26a6c88b08f0f58442ea5bd968'] - ]); - - $this->storeRepositoryMock - ->expects($this->once()) - ->method('get') - ->with($fromStoreCode) - ->willReturn($this->fromStoreMock); - - $this->storeRepositoryMock - ->expects($this->once()) - ->method('getActiveStoreByCode') - ->with($targetStoreCode); - - $this->fromStoreMock - ->expects($this->once()) - ->method('getBaseUrl') - ->with(\Magento\Framework\UrlInterface::URL_TYPE_LINK) - ->willReturn($expectedRedirectUrl); - - $this->responseMock->expects($this->once())->method('setRedirect')->with($expectedRedirectUrl); - $this->model->execute(); - } -} From 6195986fe755284ce68aa0bb24a3c51548108f07 Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Mon, 15 Apr 2019 14:35:56 -0500 Subject: [PATCH 028/372] MC-13900: Email to a Friend updates - default config option --- app/code/Magento/SendFriend/etc/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriend/etc/config.xml b/app/code/Magento/SendFriend/etc/config.xml index d65e5a4a073dd..6239a4da591e2 100644 --- a/app/code/Magento/SendFriend/etc/config.xml +++ b/app/code/Magento/SendFriend/etc/config.xml @@ -9,7 +9,7 @@ - 1 + 0 0 5 From 4c7c050f2e7cb15055b5429e4bbd15eb6f858552 Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Thu, 18 Apr 2019 13:42:07 -0500 Subject: [PATCH 029/372] MC-13900: Email to a Friend updates - update integration tests with compatible config --- .../SendFriend/Controller/Product/CustomerSendmailTest.php | 4 +++- .../testsuite/Magento/SendFriend/Controller/SendmailTest.php | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php index 8794dfdff8fd7..686af841c7ff1 100644 --- a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php +++ b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php @@ -58,6 +58,7 @@ protected function setUp() } /** + * @magentoConfigFixture default_store sendfriend/email/enabled 1 * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/product_simple.php */ @@ -95,6 +96,7 @@ public function testExecute() * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/product_simple.php * @magentoConfigFixture default_store customer/captcha/forms product_sendtofriend_form + * @magentoConfigFixture default_store sendfriend/email/enabled 1 */ public function testWithCaptchaFailed() { @@ -133,7 +135,7 @@ public function testWithCaptchaFailed() * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/product_simple.php * @magentoConfigFixture default_store customer/captcha/forms product_sendtofriend_form - * + * @magentoConfigFixture default_store sendfriend/email/enabled 1 */ public function testWithCaptchaSuccess() { diff --git a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php index a075398e9cdb7..5c2ddf86d6f96 100644 --- a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php +++ b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php @@ -26,6 +26,7 @@ class SendmailTest extends AbstractController * * @magentoDbIsolation enabled * @magentoAppIsolation enabled + * @magentoConfigFixture default_store sendfriend/email/enabled 1 * @magentoDataFixture Magento/SendFriend/_files/disable_allow_guest_config.php * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/products.php From b19cd09cca57b6daae9e1ed4078cbdcef2e2d3c4 Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Tue, 23 Apr 2019 12:49:09 -0500 Subject: [PATCH 030/372] MC-13900: Email to a Friend updates - add doc comment --- .../SendFriend/Controller/Product/CustomerSendmailTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php index 686af841c7ff1..a94a96c5cbefb 100644 --- a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php +++ b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php @@ -17,6 +17,9 @@ use Magento\Framework\Message\MessageInterface; use Magento\Captcha\Helper\Data as CaptchaHelper; +/** + * Class CustomerSendmailTest + */ class CustomerSendmailTest extends AbstractController { /** From 18907a694d6e99d2a00ce4ca905b9505f44839cb Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Mon, 29 Apr 2019 10:51:52 -0500 Subject: [PATCH 031/372] MC-13900: Email to a Friend updates - add translation --- app/code/Magento/SendFriend/etc/adminhtml/system.xml | 5 ++++- app/code/Magento/SendFriend/i18n/en_US.csv | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriend/etc/adminhtml/system.xml b/app/code/Magento/SendFriend/etc/adminhtml/system.xml index 785b7a8bb40c8..564f7bd306f8b 100644 --- a/app/code/Magento/SendFriend/etc/adminhtml/system.xml +++ b/app/code/Magento/SendFriend/etc/adminhtml/system.xml @@ -13,8 +13,11 @@ Magento_Config::sendfriend - + + + CAPTCHA solution alongside enabling "Email to a Friend" to ensure abuse of this feature does not occur.]]> + Magento\Config\Model\Config\Source\Yesno diff --git a/app/code/Magento/SendFriend/i18n/en_US.csv b/app/code/Magento/SendFriend/i18n/en_US.csv index eee540c89a7b0..24fdea50be536 100644 --- a/app/code/Magento/SendFriend/i18n/en_US.csv +++ b/app/code/Magento/SendFriend/i18n/en_US.csv @@ -45,3 +45,5 @@ Enabled,Enabled "Max Recipients","Max Recipients" "Max Products Sent in 1 Hour","Max Products Sent in 1 Hour" "Limit Sending By","Limit Sending By" +"We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur.","We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur." + From 07fa87ae48a09e2f0eff5ec38617eeaae01b2c8f Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Mon, 29 Apr 2019 11:40:20 -0500 Subject: [PATCH 032/372] MC-13900: Email to a Friend updates - add translation --- app/code/Magento/SendFriend/etc/adminhtml/system.xml | 2 +- app/code/Magento/SendFriend/i18n/en_US.csv | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SendFriend/etc/adminhtml/system.xml b/app/code/Magento/SendFriend/etc/adminhtml/system.xml index 564f7bd306f8b..5cace4bcf92db 100644 --- a/app/code/Magento/SendFriend/etc/adminhtml/system.xml +++ b/app/code/Magento/SendFriend/etc/adminhtml/system.xml @@ -16,7 +16,7 @@ - CAPTCHA solution alongside enabling "Email to a Friend" to ensure abuse of this feature does not occur.]]> + CAPTCHA solution alongside enabling "Email to a Friend" to ensure abuse of this feature does not occur.]]> Magento\Config\Model\Config\Source\Yesno diff --git a/app/code/Magento/SendFriend/i18n/en_US.csv b/app/code/Magento/SendFriend/i18n/en_US.csv index 24fdea50be536..8d5b596fe1ca6 100644 --- a/app/code/Magento/SendFriend/i18n/en_US.csv +++ b/app/code/Magento/SendFriend/i18n/en_US.csv @@ -45,5 +45,4 @@ Enabled,Enabled "Max Recipients","Max Recipients" "Max Products Sent in 1 Hour","Max Products Sent in 1 Hour" "Limit Sending By","Limit Sending By" -"We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur.","We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur." - +"We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur.","We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur." From 54c07ca9a7559a433f0ea932715b6f2b4d0f2ada Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Fri, 3 May 2019 11:45:29 +0300 Subject: [PATCH 033/372] MC-13886: Downloadable Product controller|API save changes --- .../testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index 1c239fba244ac..0eb3da755c5f0 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -305,7 +305,7 @@ public function testCreateThrowsExceptionIfLinkFileContentIsNotAValidBase64Encod * @expectedExceptionMessage Link file not found. Please try again. * @return void */ - public function testCreateLinkWithMissingFileThrowsException(): void + public function testCreateLinkWithMissingLinkFileThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, @@ -334,7 +334,7 @@ public function testCreateLinkWithMissingFileThrowsException(): void * @expectedExceptionMessage Link sample file not found. Please try again. * @return void */ - public function testCreateLinkWithMissingSampleThrowsException(): void + public function testCreateLinkWithMissingSampleFileThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, From 686e79a0b3d9356012e9f1396efe351f54146a45 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Fri, 3 May 2019 09:45:50 -0500 Subject: [PATCH 034/372] MC-15811: Incorrect Url Fix static errors. --- .../Magento/Store/Model/StoreSwitcher/HashGenerator.php | 1 + .../integration/testsuite/Magento/Framework/UrlTest.php | 7 ------- .../testsuite/Magento/Store/Model/HashGeneratorTest.php | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 945b5f36a0a8c..ac195c699a96a 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -57,6 +57,7 @@ public function __construct( * @param StoreInterface $targetStore store where to go to * @param string $redirectUrl original url requested for redirect after switching * @return string redirect url + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string { diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index 21f0ebd5b77fc..9d07c07e824d4 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -485,13 +485,6 @@ public function testSessionUrlVar() $this->assertEquals('www.example.com', $sessionUrl); } - public function testUseSessionIdForUrl() - { - $_SERVER['HTTP_HOST'] = 'localhost'; - $this->assertFalse($this->model->useSessionIdForUrl(true)); - $this->assertFalse($this->model->useSessionIdForUrl(false)); - } - /** * Note: isolation flushes the URL memory cache * @magentoAppIsolation enabled diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 8b0cec3dfa20e..c56f2bf347a7b 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -21,7 +21,6 @@ * Test class for \Magento\Store\Model\StoreSwitcher\HashGenerator * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ - class HashGeneratorTest extends \PHPUnit\Framework\TestCase { /** From 315ee90a45065b5bd35e4e8a6a4a401e05c5768b Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Fri, 3 May 2019 12:17:00 -0500 Subject: [PATCH 035/372] MC-15977: Email template preview --- .../Block/Adminhtml/Template/Preview.php | 16 +- .../Block/Adminhtml/Template/PreviewTest.php | 163 +++++++++++++----- 2 files changed, 131 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index acc367de742dd..5b2705a1989e8 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -55,19 +55,27 @@ public function __construct( * Prepare html output * * @return string + * @throws \Exception */ protected function _toHtml() { + /** @var $request \Magento\Framework\App\Request\Http */ + $request = $this->getRequest(); + + if(!$request->isSafeMethod()) { + throw new \Exception('Wrong request.'); + } + $storeId = $this->getAnyStoreView()->getId(); /** @var $template \Magento\Email\Model\Template */ $template = $this->_emailFactory->create(); - if ($id = (int)$this->getRequest()->getParam('id')) { + if ($id = (int)$request->getParam('id')) { $template->load($id); } else { - $template->setTemplateType($this->getRequest()->getParam('type')); - $template->setTemplateText($this->getRequest()->getParam('text')); - $template->setTemplateStyles($this->getRequest()->getParam('styles')); + $template->setTemplateType($request->getParam('type')); + $template->setTemplateText($request->getParam('text')); + $template->setTemplateStyles($request->getParam('styles')); } \Magento\Framework\Profiler::start($this->profilerName); diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index b91d94edb589e..4363bf223157e 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -18,26 +18,42 @@ class PreviewTest extends \PHPUnit\Framework\TestCase const MALICIOUS_TEXT = 'test malicious'; + /** + * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject + */ + protected $request; + + /** + * @var \Magento\Email\Block\Adminhtml\Template\Preview + */ + protected $preview; + + /** + * @var \Magento\Framework\Filter\Input\MaliciousCode|\PHPUnit_Framework_MockObject_MockObject + */ + protected $maliciousCode; + + /** + * @var \Magento\Email\Model\Template|\PHPUnit_Framework_MockObject_MockObject + */ + protected $template; + + /** + * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $storeManager; + /** * Init data */ protected function setUp() { $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - } - /** - * Check of processing email templates - * - * @param array $requestParamMap - * - * @dataProvider toHtmlDataProvider - * @param $requestParamMap - */ - public function testToHtml($requestParamMap) - { $storeId = 1; - $template = $this->getMockBuilder(\Magento\Email\Model\Template::class) + $designConfigData = []; + + $this->template = $this->getMockBuilder(\Magento\Email\Model\Template::class) ->setMethods([ 'setDesignConfig', 'getDesignConfig', @@ -48,36 +64,46 @@ public function testToHtml($requestParamMap) ]) ->disableOriginalConstructor() ->getMock(); - $template->expects($this->once()) + + $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->request = $this->createMock(\Magento\Framework\App\Request\Http::class); + + $this->maliciousCode = $this->createPartialMock( + \Magento\Framework\Filter\Input\MaliciousCode::class, ['filter'] + ); + + $this->template->expects($this->once()) ->method('getProcessedTemplate') ->with($this->equalTo([])) ->willReturn(self::MALICIOUS_TEXT); - $designConfigData = []; - $template->expects($this->atLeastOnce()) - ->method('getDesignConfig') + + $this->template->method('getDesignConfig') ->willReturn(new \Magento\Framework\DataObject( $designConfigData )); + $emailFactory = $this->createPartialMock(\Magento\Email\Model\TemplateFactory::class, ['create']); $emailFactory->expects($this->any()) ->method('create') - ->willReturn($template); + ->willReturn($this->template); - $request = $this->createMock(\Magento\Framework\App\RequestInterface::class); - $request->expects($this->any())->method('getParam')->willReturnMap($requestParamMap); $eventManage = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); $scopeConfig = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); $design = $this->createMock(\Magento\Framework\View\DesignInterface::class); $store = $this->createPartialMock(\Magento\Store\Model\Store::class, ['getId', '__wakeup']); - $store->expects($this->any())->method('getId')->willReturn($storeId); - $storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $storeManager->expects($this->atLeastOnce()) - ->method('getDefaultStoreView') + + $store->expects($this->any()) + ->method('getId') + ->willReturn($storeId); + + $this->storeManager->method('getDefaultStoreView') ->willReturn($store); - $storeManager->expects($this->any())->method('getDefaultStoreView')->willReturn(null); - $storeManager->expects($this->any())->method('getStores')->willReturn([$store]); + + $this->storeManager->expects($this->any())->method('getDefaultStoreView')->willReturn(null); + $this->storeManager->expects($this->any())->method('getStores')->willReturn([$store]); $appState = $this->getMockBuilder(\Magento\Framework\App\State::class) ->setConstructorArgs([ $scopeConfig @@ -87,36 +113,85 @@ public function testToHtml($requestParamMap) ->getMock(); $appState->expects($this->any()) ->method('emulateAreaCode') - ->with(\Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, [$template, 'getProcessedTemplate']) - ->willReturn($template->getProcessedTemplate()); + ->with(\Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, [$this->template, 'getProcessedTemplate']) + ->willReturn($this->template->getProcessedTemplate()); $context = $this->createPartialMock( \Magento\Backend\Block\Template\Context::class, ['getRequest', 'getEventManager', 'getScopeConfig', 'getDesignPackage', 'getStoreManager', 'getAppState'] ); - $context->expects($this->any())->method('getRequest')->willReturn($request); - $context->expects($this->any())->method('getEventManager')->willReturn($eventManage); - $context->expects($this->any())->method('getScopeConfig')->willReturn($scopeConfig); - $context->expects($this->any())->method('getDesignPackage')->willReturn($design); - $context->expects($this->any())->method('getStoreManager')->willReturn($storeManager); - $context->expects($this->once())->method('getAppState')->willReturn($appState); - - $maliciousCode = $this->createPartialMock(\Magento\Framework\Filter\Input\MaliciousCode::class, ['filter']); - $maliciousCode->expects($this->once()) - ->method('filter') - ->with($this->equalTo($requestParamMap[1][2])) - ->willReturn(self::MALICIOUS_TEXT); + $context->expects($this->any()) + ->method('getRequest') + ->willReturn($this->request); + $context->expects($this->any()) + ->method('getEventManager') + ->willReturn($eventManage); + $context->expects($this->any()) + ->method('getScopeConfig') + ->willReturn($scopeConfig); + $context->expects($this->any()) + ->method('getDesignPackage') + ->willReturn($design); + $context->expects($this->any()) + ->method('getStoreManager') + ->willReturn($this->storeManager); + $context->expects($this->once()) + ->method('getAppState') + ->willReturn($appState); /** @var \Magento\Email\Block\Adminhtml\Template\Preview $preview */ - $preview = $this->objectManagerHelper->getObject( + $this->preview = $this->objectManagerHelper->getObject( \Magento\Email\Block\Adminhtml\Template\Preview::class, [ 'context' => $context, - 'maliciousCode' => $maliciousCode, + 'maliciousCode' => $this->maliciousCode, 'emailFactory' => $emailFactory ] ); - $this->assertEquals(self::MALICIOUS_TEXT, $preview->toHtml()); + } + + /** + * Check of processing email templates + * + * @param array $requestParamMap + * + * @dataProvider toHtmlDataProvider + * @param $requestParamMap + */ + public function testToHtml($requestParamMap) + { + $this->request->expects($this->atLeastOnce()) + ->method('isSafeMethod') + ->willReturn(true); + $this->request->expects($this->any()) + ->method('getParam') + ->willReturnMap($requestParamMap); + $this->template + ->expects($this->atLeastOnce()) + ->method('getDesignConfig'); + $this->storeManager->expects($this->atLeastOnce()) + ->method('getDefaultStoreView'); + $this->maliciousCode->expects($this->once()) + ->method('filter') + ->with($this->equalTo($requestParamMap[1][2])) + ->willReturn(self::MALICIOUS_TEXT); + + $this->assertEquals(self::MALICIOUS_TEXT, $this->preview->toHtml()); + } + + /** + * @expectedException \Exception + */ + public function testToHtmlWithException() + { + $this->request->expects($this->atLeastOnce()) + ->method('isSafeMethod') + ->willReturn(false); + $this->template + ->expects($this->never()) + ->method('getDesignConfig'); + $this->expectException(\Exception::class); + $this->preview->toHtml(); } /** From 1e1b69be141d00ad3cbacdccb42b08593c5fe1fd Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Tue, 7 May 2019 13:21:24 -0500 Subject: [PATCH 036/372] MC-15977: Email template preview --- .../Block/Adminhtml/Template/Preview.php | 6 +-- .../Block/Adminhtml/Template/PreviewTest.php | 39 ++++++++----------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index 5b2705a1989e8..d9cd5ef7f0c84 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -55,15 +55,15 @@ public function __construct( * Prepare html output * * @return string - * @throws \Exception + * @throws \Magento\Framework\Exception\LocalizedException */ protected function _toHtml() { /** @var $request \Magento\Framework\App\Request\Http */ $request = $this->getRequest(); - if(!$request->isSafeMethod()) { - throw new \Exception('Wrong request.'); + if (!$request->isSafeMethod()) { + throw new \Magento\Framework\Exception\LocalizedException(__('Wrong request.')); } $storeId = $this->getAnyStoreView()->getId(); diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 4363bf223157e..55757476ea825 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -72,7 +72,8 @@ protected function setUp() $this->request = $this->createMock(\Magento\Framework\App\Request\Http::class); $this->maliciousCode = $this->createPartialMock( - \Magento\Framework\Filter\Input\MaliciousCode::class, ['filter'] + \Magento\Framework\Filter\Input\MaliciousCode::class, + ['filter'] ); $this->template->expects($this->once()) @@ -113,31 +114,22 @@ protected function setUp() ->getMock(); $appState->expects($this->any()) ->method('emulateAreaCode') - ->with(\Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, [$this->template, 'getProcessedTemplate']) + ->with( + \Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, + [$this->template, 'getProcessedTemplate'] + ) ->willReturn($this->template->getProcessedTemplate()); $context = $this->createPartialMock( \Magento\Backend\Block\Template\Context::class, ['getRequest', 'getEventManager', 'getScopeConfig', 'getDesignPackage', 'getStoreManager', 'getAppState'] ); - $context->expects($this->any()) - ->method('getRequest') - ->willReturn($this->request); - $context->expects($this->any()) - ->method('getEventManager') - ->willReturn($eventManage); - $context->expects($this->any()) - ->method('getScopeConfig') - ->willReturn($scopeConfig); - $context->expects($this->any()) - ->method('getDesignPackage') - ->willReturn($design); - $context->expects($this->any()) - ->method('getStoreManager') - ->willReturn($this->storeManager); - $context->expects($this->once()) - ->method('getAppState') - ->willReturn($appState); + $context->expects($this->any())->method('getRequest')->willReturn($this->request); + $context->expects($this->any())->method('getEventManager')->willReturn($eventManage); + $context->expects($this->any())->method('getScopeConfig')->willReturn($scopeConfig); + $context->expects($this->any())->method('getDesignPackage')->willReturn($design); + $context->expects($this->any())->method('getStoreManager')->willReturn($this->storeManager); + $context->expects($this->once())->method('getAppState')->willReturn($appState); /** @var \Magento\Email\Block\Adminhtml\Template\Preview $preview */ $this->preview = $this->objectManagerHelper->getObject( @@ -180,7 +172,7 @@ public function testToHtml($requestParamMap) } /** - * @expectedException \Exception + * @expectedException \Magento\Framework\Exception\LocalizedException */ public function testToHtmlWithException() { @@ -190,7 +182,10 @@ public function testToHtmlWithException() $this->template ->expects($this->never()) ->method('getDesignConfig'); - $this->expectException(\Exception::class); + $this->expectException(\Magento\Framework\Exception\LocalizedException::class); + $this->expectExceptionMessage( + (string)__('Wrong request.') + ); $this->preview->toHtml(); } From 42c73b6d279f99b13d3166bc63da95cf8d289c64 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 7 May 2019 15:05:04 -0500 Subject: [PATCH 037/372] MC-6293: Fixed incorrect import behavior --- .../Model/Import/Uploader.php | 29 +++++++++--- .../Block/Adminhtml/Import/Edit/Form.php | 7 ++- .../Controller/Adminhtml/Import/Start.php | 44 +++++++++++++++++-- .../Magento/ImportExport/Model/Import.php | 29 +++++++++++- app/code/Magento/ImportExport/etc/config.xml | 1 + .../Model/Import/UploaderTest.php | 21 +++++++++ .../Magento/ImportExport/Model/ImportTest.php | 33 ++++++++++++-- 7 files changed, 147 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index 4ce1c0e39d6de..b5d7364dedc47 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -7,6 +7,8 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\ValidatorException; +use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\DriverPool; /** @@ -111,13 +113,18 @@ class Uploader extends \Magento\MediaStorage\Model\File\Uploader */ private $random; + /** + * @var Filesystem + */ + private $fileSystem; + /** * @param \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDb * @param \Magento\MediaStorage\Helper\File\Storage $coreFileStorage * @param \Magento\Framework\Image\AdapterFactory $imageFactory * @param \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $validator - * @param \Magento\Framework\Filesystem $filesystem - * @param \Magento\Framework\Filesystem\File\ReadFactory $readFactory + * @param Filesystem $filesystem + * @param Filesystem\File\ReadFactory $readFactory * @param string|null $filePath * @param \Magento\Framework\Math\Random|null $random * @throws \Magento\Framework\Exception\FileSystemException @@ -128,8 +135,8 @@ public function __construct( \Magento\MediaStorage\Helper\File\Storage $coreFileStorage, \Magento\Framework\Image\AdapterFactory $imageFactory, \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $validator, - \Magento\Framework\Filesystem $filesystem, - \Magento\Framework\Filesystem\File\ReadFactory $readFactory, + Filesystem $filesystem, + Filesystem\File\ReadFactory $readFactory, $filePath = null, \Magento\Framework\Math\Random $random = null ) { @@ -137,6 +144,7 @@ public function __construct( $this->_coreFileStorageDb = $coreFileStorageDb; $this->_coreFileStorage = $coreFileStorage; $this->_validator = $validator; + $this->fileSystem = $filesystem; $this->_directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); $this->_readFactory = $readFactory; if ($filePath !== null) { @@ -236,7 +244,18 @@ private function downloadFileFromUrl($url, $driver) */ protected function _setUploadFile($filePath) { - if (!$this->_directory->isReadable($filePath)) { + try { + $fullPath = $this->_directory->getAbsolutePath($filePath); + if ($this->getTmpDir()) { + $tmpDir = $this->fileSystem->getDirectoryReadByPath($this->_directory->getAbsolutePath($this->getTmpDir())); + } else { + $tmpDir = $this->_directory; + } + $readable = $tmpDir->isReadable($fullPath); + } catch (ValidatorException $exception) { + $readable = false; + } + if (!$readable) { throw new \Magento\Framework\Exception\LocalizedException( __('File \'%1\' was not found or has read restriction.', $filePath) ); diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php index d6b96a28afcc9..c53ef36c8a2cc 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php @@ -231,8 +231,11 @@ protected function _prepareForm() 'required' => false, 'class' => 'input-text', 'note' => __( - 'For Type "Local Server" use relative path to Magento installation, - e.g. var/export, var/import, var/export/some/dir' + $this->escapeHtml( + 'For Type "Local Server" use relative path to /' + .$this->_scopeConfig->getValue('general/file/import_images_base_dir') + .', e.g. product_images, import_images/batch1' + ) ), ] ); diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index e850f6af86cf9..721ccabad9925 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -6,9 +6,14 @@ namespace Magento\ImportExport\Controller\Adminhtml\Import; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\App\ObjectManager; use Magento\ImportExport\Controller\Adminhtml\ImportResult as ImportResultController; use Magento\Framework\Controller\ResultFactory; use Magento\ImportExport\Model\Import; +use Magento\ImportExport\Model\ImportFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Filesystem; +use Magento\Framework\App\Filesystem\DirectoryList; /** * Controller responsible for initiating the import process @@ -25,25 +30,50 @@ class Start extends ImportResultController implements HttpPostActionInterface */ private $exceptionMessageFactory; + /** + * @var ScopeConfigInterface + */ + private $config; + + /** + * @var ImportFactory + */ + private $importFactory; + + /** + * @var Filesystem + */ + private $fileSystem; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\ImportExport\Model\Report\ReportProcessorInterface $reportProcessor * @param \Magento\ImportExport\Model\History $historyModel * @param \Magento\ImportExport\Helper\Report $reportHelper - * @param \Magento\ImportExport\Model\Import $importModel + * @param Import $importModel * @param \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory + * @param ScopeConfigInterface|null $config + * @param ImportFactory|null $importFactory + * @param Filesystem|null $fileSystem + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\ImportExport\Model\Report\ReportProcessorInterface $reportProcessor, \Magento\ImportExport\Model\History $historyModel, \Magento\ImportExport\Helper\Report $reportHelper, - \Magento\ImportExport\Model\Import $importModel, - \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory + Import $importModel, + \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory, + ?ScopeConfigInterface $config = null, + ?ImportFactory $importFactory = null, + ?Filesystem $fileSystem = null ) { parent::__construct($context, $reportProcessor, $historyModel, $reportHelper); - $this->importModel = $importModel; + $this->exceptionMessageFactory = $exceptionMessageFactory; + $this->config = $config ?? ObjectManager::getInstance()->get(ScopeConfigInterface::class); + $this->importFactory = $importFactory ?? ObjectManager::getInstance()->get(ImportFactory::class); + $this->fileSystem = $fileSystem ?? ObjectManager::getInstance()->get(Filesystem::class); } /** @@ -53,6 +83,12 @@ public function __construct( */ public function execute() { + $imagesDirectoryPath = $this->config->getValue('general/file/import_images_base_dir'); + $imagesDirectory = $this->fileSystem->getDirectoryReadByPath( + $this->fileSystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath($imagesDirectoryPath) + ); + $this->importModel = $this->importFactory->create(['imagesTempDirectoryBase' => $imagesDirectory]); + $data = $this->getRequest()->getPostValue(); if ($data) { /** @var \Magento\Framework\View\Result\Layout $resultLayout */ diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index 04f4111d3a0a8..1113165d4159f 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -13,6 +13,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Filesystem; use Magento\Framework\HTTP\Adapter\FileTransferFactory; use Magento\Framework\Indexer\IndexerRegistry; @@ -198,6 +199,11 @@ class Import extends AbstractModel */ private $random; + /** + * @var Filesystem\Directory\Read|null + */ + private $imagesTempDirectoryBase; + /** * @param LoggerInterface $logger * @param Filesystem $filesystem @@ -216,6 +222,7 @@ class Import extends AbstractModel * @param array $data * @param ManagerInterface|null $messageManager * @param Random|null $random + * @param Filesystem\Directory\Read|null $imagesTempDirectoryBase * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -235,7 +242,8 @@ public function __construct( DateTime $localeDate, array $data = [], ManagerInterface $messageManager = null, - Random $random = null + Random $random = null, + ?Filesystem\Directory\Read $imagesTempDirectoryBase = null ) { $this->_importExportData = $importExportData; $this->_coreConfig = $coreConfig; @@ -254,6 +262,7 @@ public function __construct( ->get(ManagerInterface::class); $this->random = $random ?: ObjectManager::getInstance() ->get(Random::class); + $this->imagesTempDirectoryBase = $imagesTempDirectoryBase; parent::__construct($logger, $filesystem, $data); } @@ -464,8 +473,24 @@ public function importSource() { $this->setData('entity', $this->getDataSourceModel()->getEntityTypeCode()); $this->setData('behavior', $this->getDataSourceModel()->getBehavior()); - $this->importHistoryModel->updateReport($this); + //Validating images temporary directory path if the constraint has been provided + if ($this->imagesTempDirectoryBase) { + if (!$this->imagesTempDirectoryBase->isReadable()) { + $rootWrite = $this->_filesystem->getDirectoryWrite(DirectoryList::ROOT); + $rootWrite->create($this->imagesTempDirectoryBase->getAbsolutePath()); + } + try { + $this->setData( + self::FIELD_NAME_IMG_FILE_DIR, + $this->imagesTempDirectoryBase->getAbsolutePath($this->getData(self::FIELD_NAME_IMG_FILE_DIR)) + ); + $this->_getEntityAdapter()->setParameters($this->getData()); + } catch (ValidatorException $exception) { + throw new LocalizedException(__('Images file directory is outside required directory'), $exception); + } + } + $this->importHistoryModel->updateReport($this); $this->addLogComment(__('Begin import of "%1" with "%2" behavior', $this->getEntity(), $this->getBehavior())); $result = $this->processImport(); diff --git a/app/code/Magento/ImportExport/etc/config.xml b/app/code/Magento/ImportExport/etc/config.xml index 7aee9bdd2fd6d..b8ce1c70ee16d 100644 --- a/app/code/Magento/ImportExport/etc/config.xml +++ b/app/code/Magento/ImportExport/etc/config.xml @@ -18,6 +18,7 @@ 100 + var/import/images diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php index f61aa7578d4a3..a8672abd52c89 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php @@ -73,6 +73,27 @@ public function testMoveWithValidFile(): void $this->assertTrue($this->directory->isExist($this->uploader->getTmpDir() . '/' . $fileName)); } + /** + * Check validation against temporary directory. + * + * @magentoAppIsolation enabled + * @return void + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testMoveWithFileOutsideTemp(): void + { + $tmpDir = $this->uploader->getTmpDir(); + if (!$this->directory->create($newTmpDir = $tmpDir .'/test1')) { + throw new \RuntimeException('Failed to create temp dir'); + } + $this->uploader->setTmpDir($newTmpDir); + $fileName = 'magento_additional_image_one.jpg'; + $filePath = $this->directory->getAbsolutePath($tmpDir . '/' . $fileName); + copy(__DIR__ . '/_files/' . $fileName, $filePath); + $this->uploader->move('../' .$fileName); + $this->assertTrue($this->directory->isExist($tmpDir . '/' . $fileName)); + } + /** * @magentoAppIsolation enabled * @return void diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php index 0c1f2d2fcc8d7..0fa37f6a753b3 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php @@ -5,8 +5,11 @@ */ namespace Magento\ImportExport\Model; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem; use Magento\Framework\Phrase; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; +use Magento\TestFramework\Helper\Bootstrap; /** * @magentoDataFixture Magento/ImportExport/_files/import_data.php @@ -65,13 +68,35 @@ class ImportTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->_importConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + $this->_importConfig = Bootstrap::getObjectManager()->create( \Magento\ImportExport\Model\Import\Config::class ); - $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + /** @var Filesystem $fileSystem */ + $fileSystem = Bootstrap::getObjectManager()->get(Filesystem::class); + $this->_model = Bootstrap::getObjectManager()->create( Import::class, - ['importConfig' => $this->_importConfig] + [ + 'importConfig' => $this->_importConfig, + 'imagesTempDirectoryBase' => $fileSystem->getDirectoryRead(DirectoryList::VAR_DIR) + ] + ); + } + + /** + * Test validation of images directory against provided base directory. + * + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Images file directory is outside required directory + * @return void + */ + public function testImagesDirBase(): void + { + $this->_model->setData( + Import::FIELD_NAME_VALIDATION_STRATEGY, + ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_SKIP_ERRORS ); + $this->_model->setData(Import::FIELD_NAME_IMG_FILE_DIR, '../_files'); + $this->_model->importSource(); } /** @@ -80,7 +105,7 @@ protected function setUp() public function testImportSource() { /** @var $customersCollection \Magento\Customer\Model\ResourceModel\Customer\Collection */ - $customersCollection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + $customersCollection = Bootstrap::getObjectManager()->create( \Magento\Customer\Model\ResourceModel\Customer\Collection::class ); From 567e512064353792db50597028382fef256ef507 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 7 May 2019 18:33:26 -0500 Subject: [PATCH 038/372] MC-6293: Fixed incorrect import behavior --- .../Magento/CatalogImportExport/Model/Import/Uploader.php | 4 +++- .../ImportExport/Controller/Adminhtml/Import/Start.php | 2 ++ .../Magento/CatalogImportExport/Model/Import/UploaderTest.php | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index b5d7364dedc47..09c3cc4daf1d9 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -247,7 +247,9 @@ protected function _setUploadFile($filePath) try { $fullPath = $this->_directory->getAbsolutePath($filePath); if ($this->getTmpDir()) { - $tmpDir = $this->fileSystem->getDirectoryReadByPath($this->_directory->getAbsolutePath($this->getTmpDir())); + $tmpDir = $this->fileSystem->getDirectoryReadByPath( + $this->_directory->getAbsolutePath($this->getTmpDir()) + ); } else { $tmpDir = $this->_directory; } diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 721ccabad9925..b18490505fee5 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -17,6 +17,8 @@ /** * Controller responsible for initiating the import process + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Start extends ImportResultController implements HttpPostActionInterface { diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php index a8672abd52c89..3961a77927314 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php @@ -68,6 +68,7 @@ public function testMoveWithValidFile(): void { $fileName = 'magento_additional_image_one.jpg'; $filePath = $this->directory->getAbsolutePath($this->uploader->getTmpDir() . '/' . $fileName); + //phpcs:ignore copy(__DIR__ . '/_files/' . $fileName, $filePath); $this->uploader->move($fileName); $this->assertTrue($this->directory->isExist($this->uploader->getTmpDir() . '/' . $fileName)); @@ -89,6 +90,7 @@ public function testMoveWithFileOutsideTemp(): void $this->uploader->setTmpDir($newTmpDir); $fileName = 'magento_additional_image_one.jpg'; $filePath = $this->directory->getAbsolutePath($tmpDir . '/' . $fileName); + //phpcs:ignore copy(__DIR__ . '/_files/' . $fileName, $filePath); $this->uploader->move('../' .$fileName); $this->assertTrue($this->directory->isExist($tmpDir . '/' . $fileName)); @@ -104,6 +106,7 @@ public function testMoveWithInvalidFile(): void { $fileName = 'media_import_image.php'; $filePath = $this->directory->getAbsolutePath($this->uploader->getTmpDir() . '/' . $fileName); + //phpcs:ignore copy(__DIR__ . '/_files/' . $fileName, $filePath); $this->uploader->move($fileName); $this->assertFalse($this->directory->isExist($this->uploader->getTmpDir() . '/' . $fileName)); From 293667e01dd4c76f59a66e34f320f0056f513998 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Thu, 9 May 2019 10:27:39 -0500 Subject: [PATCH 039/372] MC-15977: Email template preview --- app/code/Magento/Email/Block/Adminhtml/Template/Preview.php | 2 +- .../Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index d9cd5ef7f0c84..5b7979c3d8607 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -62,7 +62,7 @@ protected function _toHtml() /** @var $request \Magento\Framework\App\Request\Http */ $request = $this->getRequest(); - if (!$request->isSafeMethod()) { + if (!$request instanceof \Magento\Framework\App\RequestSafetyInterface || !$request->isSafeMethod()) { throw new \Magento\Framework\Exception\LocalizedException(__('Wrong request.')); } diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 55757476ea825..8143995f3b2af 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -146,9 +146,7 @@ protected function setUp() * Check of processing email templates * * @param array $requestParamMap - * * @dataProvider toHtmlDataProvider - * @param $requestParamMap */ public function testToHtml($requestParamMap) { From 703f00d90ad97aaefb26a41dfd971a7885deeb60 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Thu, 9 May 2019 11:02:46 -0500 Subject: [PATCH 040/372] MC-15977: Email template preview --- app/code/Magento/Email/Block/Adminhtml/Template/Preview.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index 5b7979c3d8607..4f0479a9573f4 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -59,7 +59,6 @@ public function __construct( */ protected function _toHtml() { - /** @var $request \Magento\Framework\App\Request\Http */ $request = $this->getRequest(); if (!$request instanceof \Magento\Framework\App\RequestSafetyInterface || !$request->isSafeMethod()) { From 24ee35853e53ba77b1954eb43829cbbdc982c2ed Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 9 May 2019 15:42:12 -0500 Subject: [PATCH 041/372] MC-15132: Update XML Design --- .../UiComponent/Argument/Interpreter/ConfigurableObject.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 35a5fffd45269..5135ad4d7f86d 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -61,7 +61,10 @@ public function evaluate(array $data) throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); } - if (in_array(ltrim($arguments['class'], '\\'), $this->classBlacklist)) { + if (in_array( + ltrim(strtolower($arguments['class']), '\\'), + array_map('strtolower', $this->classBlacklist) + )) { throw new \InvalidArgumentException(sprintf( 'Class argument is invalid: %s', $arguments['class'] From 6528d9abf3613433bebe8ec0b8e11327469483da Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 10 May 2019 11:45:24 -0500 Subject: [PATCH 042/372] MC-6293: Fixed incorrect import behavior --- .../Block/Adminhtml/Import/Edit/Form.php | 14 +++- .../Controller/Adminhtml/Import/Start.php | 41 +++--------- .../Magento/ImportExport/Model/Import.php | 27 ++++---- .../Import/ImageDirectoryBaseProvider.php | 64 +++++++++++++++++++ .../Magento/ImportExport/Model/ImportTest.php | 15 ++--- 5 files changed, 106 insertions(+), 55 deletions(-) create mode 100644 app/code/Magento/ImportExport/Model/Import/ImageDirectoryBaseProvider.php diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php index c53ef36c8a2cc..af5377a6227ca 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php @@ -5,6 +5,7 @@ */ namespace Magento\ImportExport\Block\Adminhtml\Import\Edit; +use Magento\Framework\App\ObjectManager; use Magento\ImportExport\Model\Import; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; @@ -32,6 +33,11 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic */ protected $_behaviorFactory; + /** + * @var Import\ImageDirectoryBaseProvider + */ + private $imagesDirectoryProvider; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Registry $registry @@ -40,6 +46,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic * @param \Magento\ImportExport\Model\Source\Import\EntityFactory $entityFactory * @param \Magento\ImportExport\Model\Source\Import\Behavior\Factory $behaviorFactory * @param array $data + * @param Import\ImageDirectoryBaseProvider|null $imageDirProvider */ public function __construct( \Magento\Backend\Block\Template\Context $context, @@ -48,12 +55,15 @@ public function __construct( \Magento\ImportExport\Model\Import $importModel, \Magento\ImportExport\Model\Source\Import\EntityFactory $entityFactory, \Magento\ImportExport\Model\Source\Import\Behavior\Factory $behaviorFactory, - array $data = [] + array $data = [], + ?Import\ImageDirectoryBaseProvider $imageDirProvider = null ) { $this->_entityFactory = $entityFactory; $this->_behaviorFactory = $behaviorFactory; parent::__construct($context, $registry, $formFactory, $data); $this->_importModel = $importModel; + $this->imagesDirectoryProvider = $imageDirProvider + ?? ObjectManager::getInstance()->get(Import\ImageDirectoryBaseProvider::class); } /** @@ -233,7 +243,7 @@ protected function _prepareForm() 'note' => __( $this->escapeHtml( 'For Type "Local Server" use relative path to /' - .$this->_scopeConfig->getValue('general/file/import_images_base_dir') + .$this->imagesDirectoryProvider->getDirectoryRelativePath() .', e.g. product_images, import_images/batch1' ) ), diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index b18490505fee5..0cc1fd40bf7e4 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -10,15 +10,10 @@ use Magento\ImportExport\Controller\Adminhtml\ImportResult as ImportResultController; use Magento\Framework\Controller\ResultFactory; use Magento\ImportExport\Model\Import; -use Magento\ImportExport\Model\ImportFactory; -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Filesystem; -use Magento\Framework\App\Filesystem\DirectoryList; /** * Controller responsible for initiating the import process * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Start extends ImportResultController implements HttpPostActionInterface { @@ -33,19 +28,9 @@ class Start extends ImportResultController implements HttpPostActionInterface private $exceptionMessageFactory; /** - * @var ScopeConfigInterface + * @var Import\ImageDirectoryBaseProvider */ - private $config; - - /** - * @var ImportFactory - */ - private $importFactory; - - /** - * @var Filesystem - */ - private $fileSystem; + private $imagesDirProvider; /** * @param \Magento\Backend\App\Action\Context $context @@ -54,9 +39,7 @@ class Start extends ImportResultController implements HttpPostActionInterface * @param \Magento\ImportExport\Helper\Report $reportHelper * @param Import $importModel * @param \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory - * @param ScopeConfigInterface|null $config - * @param ImportFactory|null $importFactory - * @param Filesystem|null $fileSystem + * @param Import\ImageDirectoryBaseProvider|null $imageDirectoryBaseProvider * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( @@ -66,16 +49,14 @@ public function __construct( \Magento\ImportExport\Helper\Report $reportHelper, Import $importModel, \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory, - ?ScopeConfigInterface $config = null, - ?ImportFactory $importFactory = null, - ?Filesystem $fileSystem = null + ?Import\ImageDirectoryBaseProvider $imageDirectoryBaseProvider = null ) { parent::__construct($context, $reportProcessor, $historyModel, $reportHelper); + $this->importModel = $importModel; $this->exceptionMessageFactory = $exceptionMessageFactory; - $this->config = $config ?? ObjectManager::getInstance()->get(ScopeConfigInterface::class); - $this->importFactory = $importFactory ?? ObjectManager::getInstance()->get(ImportFactory::class); - $this->fileSystem = $fileSystem ?? ObjectManager::getInstance()->get(Filesystem::class); + $this->imagesDirProvider = $imageDirectoryBaseProvider + ?? ObjectManager::getInstance()->get(Import\ImageDirectoryBaseProvider::class); } /** @@ -85,12 +66,6 @@ public function __construct( */ public function execute() { - $imagesDirectoryPath = $this->config->getValue('general/file/import_images_base_dir'); - $imagesDirectory = $this->fileSystem->getDirectoryReadByPath( - $this->fileSystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath($imagesDirectoryPath) - ); - $this->importModel = $this->importFactory->create(['imagesTempDirectoryBase' => $imagesDirectory]); - $data = $this->getRequest()->getPostValue(); if ($data) { /** @var \Magento\Framework\View\Result\Layout $resultLayout */ @@ -104,6 +79,8 @@ public function execute() ->addAction('hide', ['edit_form', 'upload_button', 'messages']); $this->importModel->setData($data); + //Images can be read only from given directory. + $this->importModel->setData(Import::IMAGES_BASE_DIR, $this->imagesDirProvider->getDirectory()); $errorAggregator = $this->importModel->getErrorAggregator(); $errorAggregator->initValidationStrategy( $this->importModel->getData(Import::FIELD_NAME_VALIDATION_STRATEGY), diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index 1113165d4159f..8d3bef38e3cbe 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -72,6 +72,11 @@ class Import extends AbstractModel */ const FIELD_NAME_IMG_FILE_DIR = 'import_images_file_dir'; + /** + * ReadInterface of the directory constraint for images. + */ + const IMAGES_BASE_DIR = 'images_base_directory'; + /** * Allowed errors count field name */ @@ -199,11 +204,6 @@ class Import extends AbstractModel */ private $random; - /** - * @var Filesystem\Directory\Read|null - */ - private $imagesTempDirectoryBase; - /** * @param LoggerInterface $logger * @param Filesystem $filesystem @@ -222,7 +222,6 @@ class Import extends AbstractModel * @param array $data * @param ManagerInterface|null $messageManager * @param Random|null $random - * @param Filesystem\Directory\Read|null $imagesTempDirectoryBase * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -242,8 +241,7 @@ public function __construct( DateTime $localeDate, array $data = [], ManagerInterface $messageManager = null, - Random $random = null, - ?Filesystem\Directory\Read $imagesTempDirectoryBase = null + Random $random = null ) { $this->_importExportData = $importExportData; $this->_coreConfig = $coreConfig; @@ -262,7 +260,6 @@ public function __construct( ->get(ManagerInterface::class); $this->random = $random ?: ObjectManager::getInstance() ->get(Random::class); - $this->imagesTempDirectoryBase = $imagesTempDirectoryBase; parent::__construct($logger, $filesystem, $data); } @@ -474,15 +471,19 @@ public function importSource() $this->setData('entity', $this->getDataSourceModel()->getEntityTypeCode()); $this->setData('behavior', $this->getDataSourceModel()->getBehavior()); //Validating images temporary directory path if the constraint has been provided - if ($this->imagesTempDirectoryBase) { - if (!$this->imagesTempDirectoryBase->isReadable()) { + if ($this->hasData(self::IMAGES_BASE_DIR) + && $this->getData(self::IMAGES_BASE_DIR) instanceof Filesystem\Directory\ReadInterface + ) { + /** @var Filesystem\Directory\ReadInterface $imagesDirectory */ + $imagesDirectory = $this->getData(self::IMAGES_BASE_DIR); + if (!$imagesDirectory->isReadable()) { $rootWrite = $this->_filesystem->getDirectoryWrite(DirectoryList::ROOT); - $rootWrite->create($this->imagesTempDirectoryBase->getAbsolutePath()); + $rootWrite->create($imagesDirectory->getAbsolutePath()); } try { $this->setData( self::FIELD_NAME_IMG_FILE_DIR, - $this->imagesTempDirectoryBase->getAbsolutePath($this->getData(self::FIELD_NAME_IMG_FILE_DIR)) + $imagesDirectory->getAbsolutePath($this->getData(self::FIELD_NAME_IMG_FILE_DIR)) ); $this->_getEntityAdapter()->setParameters($this->getData()); } catch (ValidatorException $exception) { diff --git a/app/code/Magento/ImportExport/Model/Import/ImageDirectoryBaseProvider.php b/app/code/Magento/ImportExport/Model/Import/ImageDirectoryBaseProvider.php new file mode 100644 index 0000000000000..9c90b57c30ea8 --- /dev/null +++ b/app/code/Magento/ImportExport/Model/Import/ImageDirectoryBaseProvider.php @@ -0,0 +1,64 @@ +config = $config; + $this->filesystem = $filesystem; + } + + /** + * Directory that users are allowed to place images for importing. + * + * @return ReadInterface + */ + public function getDirectory(): ReadInterface + { + $path = $this->getDirectoryRelativePath(); + + return $this->filesystem->getDirectoryReadByPath( + $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath($path) + ); + } + + /** + * The directory's path relative to Magento root. + * + * @return string + */ + public function getDirectoryRelativePath(): string + { + return $this->config->getValue('general/file/import_images_base_dir'); + } +} diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php index 0fa37f6a753b3..c6abf51c08580 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php @@ -5,10 +5,9 @@ */ namespace Magento\ImportExport\Model; -use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\Filesystem; use Magento\Framework\Phrase; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; +use Magento\ImportExport\Model\Import\ImageDirectoryBaseProvider; use Magento\TestFramework\Helper\Bootstrap; /** @@ -24,7 +23,7 @@ class ImportTest extends \PHPUnit\Framework\TestCase protected $_model; /** - * @var \Magento\ImportExport\Model\Import\Config + * @var Import\Config */ protected $_importConfig; @@ -69,17 +68,17 @@ class ImportTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->_importConfig = Bootstrap::getObjectManager()->create( - \Magento\ImportExport\Model\Import\Config::class + Import\Config::class ); - /** @var Filesystem $fileSystem */ - $fileSystem = Bootstrap::getObjectManager()->get(Filesystem::class); + /** @var ImageDirectoryBaseProvider $provider */ + $provider = Bootstrap::getObjectManager()->get(ImageDirectoryBaseProvider::class); $this->_model = Bootstrap::getObjectManager()->create( Import::class, [ - 'importConfig' => $this->_importConfig, - 'imagesTempDirectoryBase' => $fileSystem->getDirectoryRead(DirectoryList::VAR_DIR) + 'importConfig' => $this->_importConfig ] ); + $this->_model->setData(Import::IMAGES_BASE_DIR, $provider->getDirectory()); } /** From d188d7f2dee04ef3a7b2e76c159e6e9ea25dc69f Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 10 May 2019 14:17:38 -0500 Subject: [PATCH 043/372] MC-6293: Fixed incorrect import behavior --- .../ImportExport/Controller/Adminhtml/Import/Start.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 0cc1fd40bf7e4..70e6f66329b70 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -12,8 +12,9 @@ use Magento\ImportExport\Model\Import; /** - * Controller responsible for initiating the import process + * Controller responsible for initiating the import process. * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Start extends ImportResultController implements HttpPostActionInterface { @@ -40,7 +41,6 @@ class Start extends ImportResultController implements HttpPostActionInterface * @param Import $importModel * @param \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory * @param Import\ImageDirectoryBaseProvider|null $imageDirectoryBaseProvider - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( \Magento\Backend\App\Action\Context $context, From 5456745f8726eec4df2303d1e054a1ceed3cb74e Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 13 May 2019 09:57:08 -0500 Subject: [PATCH 044/372] MC-15811: Incorrect Url Use data object for token generation. Modify unit and integration tests. Fix static error. --- .../Store/Controller/Store/SwitchRequest.php | 8 +- .../Model/StoreSwitcher/HashGenerator.php | 13 ++- .../StoreSwitcher/HashGenerator/HashData.php | 44 +++++++++ .../testsuite/Magento/Framework/UrlTest.php | 14 +++ .../Magento/Store/Model/HashGeneratorTest.php | 97 ++++++++++++------- 5 files changed, 135 insertions(+), 41 deletions(-) create mode 100644 app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index e220941017c34..24e07137497b1 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -16,6 +16,7 @@ use \Magento\Framework\Exception\LocalizedException; use Magento\Framework\Url\DecoderInterface; use \Magento\Framework\App\ActionInterface; +use Magento\Store\Model\StoreSwitcher\HashGenerator\HashData; /** * Builds correct url to target store and performs redirect. @@ -78,7 +79,12 @@ public function execute() $error = null; $encodedUrl = (string)$this->_request->getParam(ActionInterface::PARAM_NAME_URL_ENCODED); $targetUrl = $this->urlDecoder->decode($encodedUrl); - $data=[$customerId, $timeStamp, $fromStoreCode]; + + $data = new HashData([ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ]); if ($targetUrl && $this->hashGenerator->validateHash($signature, $data)) { try { diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index ac195c699a96a..0fe47412537c8 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -14,6 +14,7 @@ use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Authorization\Model\UserContextInterface; use \Magento\Framework\App\ActionInterface; +use Magento\Framework\DataObject; /** * Generate one time token and build redirect url @@ -99,14 +100,16 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s * Validates one time token * * @param string $signature - * @param array $data + * @param DataObject $hashData * @return bool */ - public function validateHash(string $signature, array $data): bool + public function validateHash(string $signature, DataObject $hashData): bool { - if (!empty($signature) && !empty($data)) { - $timeStamp = $data[1] ?? 0; - $value = implode(",", $data); + if (!empty($signature) && !empty($hashData)) { + $timeStamp = $hashData->getTimestamp(); + $fromStoreCode = $hashData->getFromStoreCode(); + $customerId = $hashData->getCustomerId(); + $value = implode(",", [$customerId, $timeStamp, $fromStoreCode]); $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); if (time() - $timeStamp <= 5 && hash_equals($signature, hash_hmac('sha256', $value, $key))) { diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php new file mode 100644 index 0000000000000..19ca8fe7ddadc --- /dev/null +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php @@ -0,0 +1,44 @@ +getData('customer_id'); + } + + /** + * Get Timestamp + * + * @return int + */ + public function getTimestamp() + { + return $this->getData('time_stamp'); + } + + /** + * Get Fromstore + * + * @return string + */ + public function getFromStoreCode() + { + return $this->getData('___from_store'); + } +} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index 9d07c07e824d4..ae91d5042d418 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -23,6 +23,13 @@ protected function setUp() $this->model = Bootstrap::getObjectManager()->create(\Magento\Framework\Url::class); } + public function testSetGetUseSession() + { + $this->assertFalse((bool)$this->model->getUseSession()); + $this->model->setUseSession(false); + $this->assertFalse($this->model->getUseSession()); + } + public function testSetRouteFrontName() { $value = 'route'; @@ -485,6 +492,13 @@ public function testSessionUrlVar() $this->assertEquals('www.example.com', $sessionUrl); } + public function testUseSessionIdForUrl() + { + $_SERVER['HTTP_HOST'] = 'localhost'; + $this->assertFalse($this->model->useSessionIdForUrl(true)); + $this->assertFalse($this->model->useSessionIdForUrl(false)); + } + /** * Note: isolation flushes the URL memory cache * @magentoAppIsolation enabled diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index c56f2bf347a7b..0eda33645b6bc 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -11,11 +11,11 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\Store\Model\StoreSwitcher\HashGenerator; use Magento\Customer\Api\AccountManagementInterface; -use Magento\Customer\Model\Session; +use Magento\Customer\Model\Session as CustomerSession; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Config\ConfigOptionsListConstants; -use \Magento\Framework\App\ActionInterface; use Magento\Framework\Url\Helper\Data as UrlHelper; +use Magento\Store\Model\StoreSwitcher\HashGenerator\HashData; /** * Test class for \Magento\Store\Model\StoreSwitcher\HashGenerator @@ -61,6 +61,16 @@ class HashGeneratorTest extends \PHPUnit\Framework\TestCase */ private $urlHelper; + /** + * @var HashData + */ + private $hashData; + + /** + * @var CustomerSession + */ + private $customerSession; + /** * Class dependencies initialization * @return void @@ -69,15 +79,15 @@ class HashGeneratorTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $session = $this->objectManager->create( - Session::class + $this->customerSession = $this->objectManager->create( + CustomerSession::class ); $this->accountManagement = $this->objectManager->create(AccountManagementInterface::class); $customer = $this->accountManagement->authenticate('customer@example.com', 'password'); - $session->setCustomerDataAsLoggedIn($customer); + $this->customerSession->setCustomerDataAsLoggedIn($customer); $this->customerSessionUserContext = $this->objectManager->create( \Magento\Customer\Model\Authorization\CustomerSessionUserContext::class, - ['customerSession' => $session] + ['customerSession' => $this->customerSession] ); $this->hashGenerator = $this->objectManager->create( StoreSwitcher\HashGenerator::class, @@ -87,46 +97,53 @@ protected function setUp() $this->deploymentConfig = $this->objectManager->get(DeploymentConfig::class); $this->key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); $this->urlHelper=$this->objectManager->create(UrlHelper::class); + $this->hashData=$this->objectManager->create(HashData::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->customerSession->logout(); + parent:tearDown(); } /** + * @magentoAppIsolation enabled * @magentoDataFixture Magento/Store/_files/store.php * @magentoDataFixture Magento/Store/_files/second_store.php * @magentoDataFixture Magento/Customer/_files/customer.php * @return void - * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function testSwitch(): void { $redirectUrl = "http://domain.com/"; $fromStoreCode = 'test'; - $toStoreCode = 'fixture_second_store'; - $encodedUrl=$this->urlHelper->getEncodedUrl($redirectUrl); - /** @var \Magento\Store\Api\StoreRepositoryInterface $storeRepository */ - $storeRepository = $this->objectManager->create(\Magento\Store\Api\StoreRepositoryInterface::class); - $fromStore = $storeRepository->get($fromStoreCode); - $toStore = $storeRepository->get($toStoreCode); + $fromStore = $this->createPartialMock(Store::class, ['getCode']); + $toStore = $this->createPartialMock(Store::class, ['getCode']); + $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); $timeStamp = time(); - $data = implode(',', [$this->customerId, $timeStamp, $fromStoreCode]); - $signature = hash_hmac('sha256', $data, $this->key); - $customerId = $this->customerId; + $targetUrl=$this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); + // phpcs:ignore + $urlParts=parse_url($targetUrl, PHP_URL_QUERY); + $signature=''; + // phpcs:ignore + parse_str($urlParts, $params); - $expectedUrl = "http://domain.com/stores/store/switchrequest"; - $expectedUrl = $this->urlHelper->addRequestParam( - $expectedUrl, - ['customer_id' => $customerId] - ); - $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['time_stamp' => $timeStamp]); - $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['signature' => $signature]); - $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['___from_store' => $fromStoreCode]); - $expectedUrl = $this->urlHelper->addRequestParam( - $expectedUrl, - [ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl] - ); - $this->assertEquals($expectedUrl, $this->hashGenerator->switch($fromStore, $toStore, $redirectUrl)); + if (isset($params['signature'])) { + $signature=$params['signature']; + } + $this->assertTrue($this->hashGenerator->validateHash($signature, new HashData([ + "customer_id" => $this->customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ]))); } /** + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/Customer/_files/customer.php * @return void */ public function testValidateHashWithCorrectData(): void @@ -134,12 +151,18 @@ public function testValidateHashWithCorrectData(): void $timeStamp = time(); $customerId = $this->customerId; $fromStoreCode = 'test'; - $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); - $signature = hash_hmac('sha256', $data, $this->key); - $this->assertTrue($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])); + $data = new HashData([ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ]); + $signature = hash_hmac('sha256', implode(',', [$this->customerId, $timeStamp, $fromStoreCode]), $this->key); + $this->assertTrue($this->hashGenerator->validateHash($signature, $data)); } /** + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/Customer/_files/customer.php * @return void */ public function testValidateHashWithInCorrectData(): void @@ -147,8 +170,12 @@ public function testValidateHashWithInCorrectData(): void $timeStamp = 0; $customerId = 8; $fromStoreCode = 'test'; - $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); - $signature = hash_hmac('sha256', $data, $this->key); - $this->assertFalse($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])); + $data = new HashData([ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ]); + $signature = hash_hmac('sha256', implode(',', [$this->customerId, $timeStamp, $fromStoreCode]), $this->key); + $this->assertFalse($this->hashGenerator->validateHash($signature, $data)); } } From 27af1c05e295f842b9efdb57174b257cb27b6afb Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 13 May 2019 11:29:07 -0500 Subject: [PATCH 045/372] MC-6293: Fixed incorrect import behavior --- .../ImportExport/Controller/Adminhtml/Import/Start.php | 2 +- app/code/Magento/ImportExport/Model/Import.php | 6 +++--- .../testsuite/Magento/ImportExport/Model/ImportTest.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 70e6f66329b70..5f036e51f66c4 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -80,7 +80,7 @@ public function execute() $this->importModel->setData($data); //Images can be read only from given directory. - $this->importModel->setData(Import::IMAGES_BASE_DIR, $this->imagesDirProvider->getDirectory()); + $this->importModel->setData('images_base_directory', $this->imagesDirProvider->getDirectory()); $errorAggregator = $this->importModel->getErrorAggregator(); $errorAggregator->initValidationStrategy( $this->importModel->getData(Import::FIELD_NAME_VALIDATION_STRATEGY), diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index 8d3bef38e3cbe..cbc5cf8ceeb88 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -471,11 +471,11 @@ public function importSource() $this->setData('entity', $this->getDataSourceModel()->getEntityTypeCode()); $this->setData('behavior', $this->getDataSourceModel()->getBehavior()); //Validating images temporary directory path if the constraint has been provided - if ($this->hasData(self::IMAGES_BASE_DIR) - && $this->getData(self::IMAGES_BASE_DIR) instanceof Filesystem\Directory\ReadInterface + if ($this->hasData('images_base_directory') + && $this->getData('images_base_directory') instanceof Filesystem\Directory\ReadInterface ) { /** @var Filesystem\Directory\ReadInterface $imagesDirectory */ - $imagesDirectory = $this->getData(self::IMAGES_BASE_DIR); + $imagesDirectory = $this->getData('images_base_directory'); if (!$imagesDirectory->isReadable()) { $rootWrite = $this->_filesystem->getDirectoryWrite(DirectoryList::ROOT); $rootWrite->create($imagesDirectory->getAbsolutePath()); diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php index c6abf51c08580..0f92da2230f7c 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php @@ -78,7 +78,7 @@ protected function setUp() 'importConfig' => $this->_importConfig ] ); - $this->_model->setData(Import::IMAGES_BASE_DIR, $provider->getDirectory()); + $this->_model->setData('images_base_directory', $provider->getDirectory()); } /** From 7faf67bb2f1f77782edb45e64bcbda5c3d6d449a Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 13 May 2019 11:35:40 -0500 Subject: [PATCH 046/372] MC-15811: Incorrect Url Fix typo in function call. --- .../testsuite/Magento/Store/Model/HashGeneratorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 0eda33645b6bc..3f8a1768a1faf 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -106,7 +106,7 @@ protected function setUp() protected function tearDown() { $this->customerSession->logout(); - parent:tearDown(); + parent::tearDown(); } /** From 98239dd88a95456412403a8f588975caabfc6367 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 13 May 2019 14:28:45 -0500 Subject: [PATCH 047/372] MC-15811: Incorrect Url Fix phpcs static errors. Fix integration test. --- .../Store/Model/StoreSwitcher/HashGenerator/HashData.php | 2 +- dev/tests/integration/testsuite/Magento/Framework/UrlTest.php | 1 + .../testsuite/Magento/Store/Model/HashGeneratorTest.php | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php index 19ca8fe7ddadc..988b889b2d9ba 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php @@ -41,4 +41,4 @@ public function getFromStoreCode() { return $this->getData('___from_store'); } -} \ No newline at end of file +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index ae91d5042d418..db830d228201c 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -494,6 +494,7 @@ public function testSessionUrlVar() public function testUseSessionIdForUrl() { + // phpcs:ignore $_SERVER['HTTP_HOST'] = 'localhost'; $this->assertFalse($this->model->useSessionIdForUrl(true)); $this->assertFalse($this->model->useSessionIdForUrl(false)); diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 3f8a1768a1faf..aa3d8d36de29f 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -120,8 +120,8 @@ public function testSwitch(): void { $redirectUrl = "http://domain.com/"; $fromStoreCode = 'test'; - $fromStore = $this->createPartialMock(Store::class, ['getCode']); - $toStore = $this->createPartialMock(Store::class, ['getCode']); + $fromStore = $this->createMock(Store::class); + $toStore = $this->createMock(Store::class); $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); $timeStamp = time(); $targetUrl=$this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); From 337b7625740633ac10245a4b13894e4faa92c80c Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 13 May 2019 15:12:28 -0500 Subject: [PATCH 048/372] MC-6293: Fixed incorrect import behavior --- app/code/Magento/ImportExport/Model/Import.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index cbc5cf8ceeb88..c8a5921b41b12 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -72,11 +72,6 @@ class Import extends AbstractModel */ const FIELD_NAME_IMG_FILE_DIR = 'import_images_file_dir'; - /** - * ReadInterface of the directory constraint for images. - */ - const IMAGES_BASE_DIR = 'images_base_directory'; - /** * Allowed errors count field name */ From cdd3fe01612f6a32fb4d5dd7a617f02a233fc987 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 13 May 2019 16:05:14 -0500 Subject: [PATCH 049/372] MC-15811: Incorrect Url Remove unused fixture. --- .../testsuite/Magento/Store/Model/HashGeneratorTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index aa3d8d36de29f..0ff9f40e4c9cb 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -111,8 +111,6 @@ protected function tearDown() /** * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Store/_files/store.php - * @magentoDataFixture Magento/Store/_files/second_store.php * @magentoDataFixture Magento/Customer/_files/customer.php * @return void */ @@ -120,8 +118,8 @@ public function testSwitch(): void { $redirectUrl = "http://domain.com/"; $fromStoreCode = 'test'; - $fromStore = $this->createMock(Store::class); - $toStore = $this->createMock(Store::class); + $fromStore = $this->createPartialMock(Store::class, ['getCode']); + $toStore = $this->createPartialMock(Store::class, ['getCode']); $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); $timeStamp = time(); $targetUrl=$this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); From eda0fcd0bf6a030e502a981dde7f2848f8534b10 Mon Sep 17 00:00:00 2001 From: David Haecker Date: Tue, 14 May 2019 12:33:16 -0500 Subject: [PATCH 050/372] MC-16261: Failing MFTF Test in 2.3.3-develop: MAGETWO-96164: Checking Catalog grid page number after Save and Close action - Fixing product grid reset in AdminGridPageNumberAfterSaveAndCloseActionTest --- .../Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml index b24ed7f9c9a81..aff5e89166328 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml @@ -24,9 +24,7 @@ - - + From fef28787f80873a508acdc404401c48f81bd2db4 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 15 May 2019 10:33:36 -0500 Subject: [PATCH 051/372] MC-15132: Update XML Design --- .../UiComponent/Argument/Interpreter/ConfigurableObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 5135ad4d7f86d..2810db6569421 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -43,7 +43,7 @@ public function __construct(ObjectManagerInterface $objectManager, InterpreterIn } /** - * {@inheritdoc} + * @inheritdoc */ public function evaluate(array $data) { From f5bf195926f907ac9f6fe1b4e56cbe730c1dfbaf Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Wed, 15 May 2019 12:46:47 -0500 Subject: [PATCH 052/372] MC-15811: Incorrect Url Fix method signature. Add type hint. Fix integration test. --- .../Model/StoreSwitcher/HashGenerator.php | 6 +-- .../StoreSwitcher/HashGenerator/HashData.php | 14 ++++--- .../Magento/Store/Model/HashGeneratorTest.php | 42 +++++++++---------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 0fe47412537c8..456941bd41c25 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -8,13 +8,13 @@ namespace Magento\Store\Model\StoreSwitcher; use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreSwitcher\HashGenerator\HashData; use Magento\Store\Model\StoreSwitcherInterface; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Url\Helper\Data as UrlHelper; use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Authorization\Model\UserContextInterface; use \Magento\Framework\App\ActionInterface; -use Magento\Framework\DataObject; /** * Generate one time token and build redirect url @@ -100,10 +100,10 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s * Validates one time token * * @param string $signature - * @param DataObject $hashData + * @param HashData $hashData * @return bool */ - public function validateHash(string $signature, DataObject $hashData): bool + public function validateHash(string $signature, HashData $hashData): bool { if (!empty($signature) && !empty($hashData)) { $timeStamp = $hashData->getTimestamp(); diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php index 988b889b2d9ba..2d0068efbdd92 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Store\Model\StoreSwitcher\HashGenerator; use Magento\Framework\DataObject; @@ -17,9 +19,9 @@ class HashData extends DataObject * * @return int */ - public function getCustomerId() + public function getCustomerId(): int { - return $this->getData('customer_id'); + return (int)$this->getData('customer_id'); } /** @@ -27,9 +29,9 @@ public function getCustomerId() * * @return int */ - public function getTimestamp() + public function getTimestamp(): int { - return $this->getData('time_stamp'); + return (int)$this->getData('time_stamp'); } /** @@ -37,8 +39,8 @@ public function getTimestamp() * * @return string */ - public function getFromStoreCode() + public function getFromStoreCode(): string { - return $this->getData('___from_store'); + return (string)$this->getData('___from_store'); } } diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 0ff9f40e4c9cb..226cacd71195e 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -121,7 +121,6 @@ public function testSwitch(): void $fromStore = $this->createPartialMock(Store::class, ['getCode']); $toStore = $this->createPartialMock(Store::class, ['getCode']); $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); - $timeStamp = time(); $targetUrl=$this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); // phpcs:ignore $urlParts=parse_url($targetUrl, PHP_URL_QUERY); @@ -132,32 +131,16 @@ public function testSwitch(): void if (isset($params['signature'])) { $signature=$params['signature']; } + $this->assertEquals($params['customer_id'], $this->customerId); + $this->assertEquals($params['___from_store'], $fromStoreCode); + $this->assertTrue($this->hashGenerator->validateHash($signature, new HashData([ "customer_id" => $this->customerId, - "time_stamp" => $timeStamp, + "time_stamp" => $params['time_stamp'], "___from_store" => $fromStoreCode ]))); } - /** - * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Customer/_files/customer.php - * @return void - */ - public function testValidateHashWithCorrectData(): void - { - $timeStamp = time(); - $customerId = $this->customerId; - $fromStoreCode = 'test'; - $data = new HashData([ - "customer_id" => $customerId, - "time_stamp" => $timeStamp, - "___from_store" => $fromStoreCode - ]); - $signature = hash_hmac('sha256', implode(',', [$this->customerId, $timeStamp, $fromStoreCode]), $this->key); - $this->assertTrue($this->hashGenerator->validateHash($signature, $data)); - } - /** * @magentoAppIsolation enabled * @magentoDataFixture Magento/Customer/_files/customer.php @@ -167,13 +150,26 @@ public function testValidateHashWithInCorrectData(): void { $timeStamp = 0; $customerId = 8; - $fromStoreCode = 'test'; + $fromStoreCode = 'store1'; $data = new HashData([ "customer_id" => $customerId, "time_stamp" => $timeStamp, "___from_store" => $fromStoreCode ]); - $signature = hash_hmac('sha256', implode(',', [$this->customerId, $timeStamp, $fromStoreCode]), $this->key); + $redirectUrl = "http://domain.com/"; + $fromStore = $this->createPartialMock(Store::class, ['getCode']); + $toStore = $this->createPartialMock(Store::class, ['getCode']); + $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); + $targetUrl = $this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); + // phpcs:ignore + $urlParts = parse_url($targetUrl,PHP_URL_QUERY); + $signature = ''; + // phpcs:ignore + parse_str($urlParts, $params); + + if (isset($params['signature'])) { + $signature = $params['signature']; + } $this->assertFalse($this->hashGenerator->validateHash($signature, $data)); } } From d4c0c0d755119e87e7208f2949d8ac9dca8ba81d Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 16 May 2019 15:27:23 -0500 Subject: [PATCH 053/372] MC-15811: Incorrect Url Fix annotation. --- lib/internal/Magento/Framework/Session/SidResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Session/SidResolver.php b/lib/internal/Magento/Framework/Session/SidResolver.php index 117c46f3443a7..041995d20fcd2 100644 --- a/lib/internal/Magento/Framework/Session/SidResolver.php +++ b/lib/internal/Magento/Framework/Session/SidResolver.php @@ -11,7 +11,7 @@ /** * Class SidResolver - * @deprecated 2.3.2 + * @deprecated 2.3.3 SIDs in URLs are no longer used */ class SidResolver implements SidResolverInterface { From 40e805e8535eefcfcb7a3364fb0ff6e16a66a313 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Thu, 23 May 2019 15:59:52 -0500 Subject: [PATCH 054/372] MC-16865: Outdated js libraries - Updated js library --- lib/web/knockoutjs/knockout.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/web/knockoutjs/knockout.js b/lib/web/knockoutjs/knockout.js index cd11f4d0c0d14..93ccdc5415111 100644 --- a/lib/web/knockoutjs/knockout.js +++ b/lib/web/knockoutjs/knockout.js @@ -502,16 +502,6 @@ ko.utils = (function () { setElementName: function(element, name) { element.name = name; - - // Workaround IE 6/7 issue - // - https://github.com/SteveSanderson/knockout/issues/197 - // - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/ - if (ieVersion <= 7) { - try { - element.mergeAttributes(document.createElement(""), false); - } - catch(e) {} // For IE9 with doc mode "IE9 Standards" and browser mode "IE9 Compatibility View" - } }, forceRefresh: function(node) { From ec7f7b8708e1014e5e742bc1715ca3bf77cf1637 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Fri, 17 May 2019 13:20:51 -0500 Subject: [PATCH 055/372] MC-15733: firefox method update - Updated method for firefox consumption - Updated test for the change --- lib/internal/Magento/Framework/Escaper.php | 2 +- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index b12548f27bc8b..b7daadb04daba 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -135,7 +135,7 @@ private function removeNotAllowedTags(\DOMDocument $domDocument, array $allowedT . '\']' ); foreach ($nodes as $node) { - if ($node->nodeName != '#text' && $node->nodeName != '#comment') { + if ($node->nodeName != '#text') { $node->parentNode->replaceChild($domDocument->createTextNode($node->textContent), $node); } } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 7b45765fdefe8..a1d03f023a20c 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -224,7 +224,7 @@ public function escapeHtmlDataProvider() ], 'text with html comment' => [ 'data' => 'Only 2 in stock ', - 'expected' => 'Only 2 in stock ', + 'expected' => 'Only 2 in stock HTML COMMENT ', 'allowedTags' => ['span', 'b'], ], 'text with non ascii characters' => [ From 4b0823380c32a29aa3f1fec12aa2dabd4a608b97 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Fri, 17 May 2019 14:32:22 -0500 Subject: [PATCH 056/372] MC-15733: firefox method update - Resolved static failures --- lib/internal/Magento/Framework/Escaper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index b7daadb04daba..29e285114fa05 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -6,6 +6,8 @@ namespace Magento\Framework; +use Magento\Framework\Exception\LocalizedException; + /** * Magento escape methods * @@ -74,7 +76,7 @@ public function escapeHtml($data, $allowedTags = null) $domDocument = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( function ($errorNumber, $errorString) { - throw new \Exception($errorString, $errorNumber); + throw new LocalizedException($errorString, $errorNumber); } ); $data = $this->prepareUnescapedCharacters($data); From ebc9622a6d09f505275ee8992233c83ceaed1184 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Fri, 17 May 2019 15:31:09 -0500 Subject: [PATCH 057/372] MC-15733: firefox method update - Resolved static failures --- lib/internal/Magento/Framework/Escaper.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 29e285114fa05..fac4d9445c052 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -6,8 +6,6 @@ namespace Magento\Framework; -use Magento\Framework\Exception\LocalizedException; - /** * Magento escape methods * @@ -76,7 +74,7 @@ public function escapeHtml($data, $allowedTags = null) $domDocument = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( function ($errorNumber, $errorString) { - throw new LocalizedException($errorString, $errorNumber); + throw new \InvalidArgumentException($errorString, $errorNumber); } ); $data = $this->prepareUnescapedCharacters($data); From 73381b2f4bddf5949d798fef4b98017e7fe22c36 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Mon, 20 May 2019 11:29:33 -0500 Subject: [PATCH 058/372] MC-15733: firefox method update - Added method for firefox consumption - Updated test for the change --- lib/internal/Magento/Framework/Escaper.php | 16 ++++++++++++++++ .../Magento/Framework/Test/Unit/EscaperTest.php | 7 ++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index fac4d9445c052..9eec5aec530a7 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -89,6 +89,7 @@ function ($errorNumber, $errorString) { } restore_error_handler(); + $this->removeComments($domDocument); $this->removeNotAllowedTags($domDocument, $allowedTags); $this->removeNotAllowedAttributes($domDocument); $this->escapeText($domDocument); @@ -158,6 +159,21 @@ private function removeNotAllowedAttributes(\DOMDocument $domDocument) } } + /** + * Remove comments + * + * @param \DOMDocument $domDocument + * @return void + */ + private function removeComments(\DOMDocument $domDocument) + { + $xpath = new \DOMXPath($domDocument); + $nodes = $xpath->query('//comment()'); + foreach ($nodes as $node) { + $node->parentNode->removeChild($node); + } + } + /** * Escape text * diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index a1d03f023a20c..77ad480a53bd0 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -224,7 +224,12 @@ public function escapeHtmlDataProvider() ], 'text with html comment' => [ 'data' => 'Only 2 in stock ', - 'expected' => 'Only 2 in stock HTML COMMENT ', + 'expected' => 'Only 2 in stock ', + 'allowedTags' => ['span', 'b'], + ], + 'text with multi-line html comment' => [ + 'data' => 'Only 2 in stock ', + 'expected' => 'Only 2 in stock ', 'allowedTags' => ['span', 'b'], ], 'text with non ascii characters' => [ From 191b33243a8bd2005d29e37155d29951bb2f3b90 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Tue, 21 May 2019 10:35:08 -0500 Subject: [PATCH 059/372] MC-15733: firefox method update - Resolved incorrect test quotes --- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 77ad480a53bd0..bc12b0bd1227c 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -228,7 +228,7 @@ public function escapeHtmlDataProvider() 'allowedTags' => ['span', 'b'], ], 'text with multi-line html comment' => [ - 'data' => 'Only 2 in stock ', + 'data' => "Only 2 in stock ", 'expected' => 'Only 2 in stock ', 'allowedTags' => ['span', 'b'], ], From 7dc3ef8ecef02e9e036cff69f27987605e473e57 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Fri, 24 May 2019 11:22:34 -0500 Subject: [PATCH 060/372] MC-15811: Incorrect Url Fix multi line function static error. Refactor data object in integration test. --- .../Store/Controller/Store/SwitchRequest.php | 12 +++++---- .../Magento/Store/Model/HashGeneratorTest.php | 25 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index 24e07137497b1..9ce151bdab094 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -80,11 +80,13 @@ public function execute() $encodedUrl = (string)$this->_request->getParam(ActionInterface::PARAM_NAME_URL_ENCODED); $targetUrl = $this->urlDecoder->decode($encodedUrl); - $data = new HashData([ - "customer_id" => $customerId, - "time_stamp" => $timeStamp, - "___from_store" => $fromStoreCode - ]); + $data = new HashData( + [ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ] + ); if ($targetUrl && $this->hashGenerator->validateHash($signature, $data)) { try { diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 226cacd71195e..1bacd79b74f49 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -134,11 +134,14 @@ public function testSwitch(): void $this->assertEquals($params['customer_id'], $this->customerId); $this->assertEquals($params['___from_store'], $fromStoreCode); - $this->assertTrue($this->hashGenerator->validateHash($signature, new HashData([ - "customer_id" => $this->customerId, - "time_stamp" => $params['time_stamp'], - "___from_store" => $fromStoreCode - ]))); + $data = new HashData( + [ + "customer_id" => $this->customerId, + "time_stamp" => $params['time_stamp'], + "___from_store" => $fromStoreCode + ] + ); + $this->assertTrue($this->hashGenerator->validateHash($signature, $data)); } /** @@ -151,11 +154,13 @@ public function testValidateHashWithInCorrectData(): void $timeStamp = 0; $customerId = 8; $fromStoreCode = 'store1'; - $data = new HashData([ - "customer_id" => $customerId, - "time_stamp" => $timeStamp, - "___from_store" => $fromStoreCode - ]); + $data = new HashData( + [ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ] + ); $redirectUrl = "http://domain.com/"; $fromStore = $this->createPartialMock(Store::class, ['getCode']); $toStore = $this->createPartialMock(Store::class, ['getCode']); From a22b9234a9f05512c5a47a9e64b0070b996c453b Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Fri, 24 May 2019 16:05:16 -0500 Subject: [PATCH 061/372] MC-16977: Broken MFTF Test: MC-14208: Clear all products from the 'Compare Products' list --- app/code/Magento/Catalog/Controller/Product/Compare/Add.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index f5c3171a3fe90..ae6a55bdd112f 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -6,6 +6,7 @@ */ namespace Magento\Catalog\Controller\Product\Compare; +use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\Exception\NoSuchEntityException; @@ -18,6 +19,7 @@ class Add extends \Magento\Catalog\Controller\Product\Compare implements HttpPos * Add item to compare list. * * @return \Magento\Framework\Controller\ResultInterface + * @throws NoSuchEntityException */ public function execute() { @@ -36,7 +38,7 @@ public function execute() $product = null; } - if ($product && $product->isSalable()) { + if ($product && $product->getStatus() === Status::STATUS_ENABLED) { $this->_catalogProductCompareList->addProduct($product); $productName = $this->_objectManager->get( \Magento\Framework\Escaper::class From cd67eab797cac72813a688cd7115d620164145a1 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Fri, 24 May 2019 16:56:58 -0500 Subject: [PATCH 062/372] MC-16977: Broken MFTF Test: MC-14208: Clear all products from the 'Compare Products' list --- app/code/Magento/Catalog/Controller/Product/Compare/Add.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index ae6a55bdd112f..3793a3858406e 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -38,7 +38,7 @@ public function execute() $product = null; } - if ($product && $product->getStatus() === Status::STATUS_ENABLED) { + if ($product && $product->getStatus() !== Status::STATUS_DISABLED) { $this->_catalogProductCompareList->addProduct($product); $productName = $this->_objectManager->get( \Magento\Framework\Escaper::class From 70d8f5dead89f801be7b1af2d5f6782b93308803 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 28 May 2019 07:51:22 -0500 Subject: [PATCH 063/372] MC-16977: Broken MFTF Test: MC-14208: Clear all products from the 'Compare Products' list --- app/code/Magento/Catalog/Controller/Product/Compare/Add.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index 3793a3858406e..ac162652cf897 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -19,7 +19,6 @@ class Add extends \Magento\Catalog\Controller\Product\Compare implements HttpPos * Add item to compare list. * * @return \Magento\Framework\Controller\ResultInterface - * @throws NoSuchEntityException */ public function execute() { From 26513db3d98d65fa3471f7ee1706affcb4fc1878 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 28 May 2019 09:26:03 -0500 Subject: [PATCH 064/372] MC-16977: Broken MFTF Test: MC-14208: Clear all products from the 'Compare Products' list --- app/code/Magento/Catalog/Controller/Product/Compare/Add.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index ac162652cf897..2b989dde9809f 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -37,7 +37,7 @@ public function execute() $product = null; } - if ($product && $product->getStatus() !== Status::STATUS_DISABLED) { + if ($product && (int)$product->getStatus() !== Status::STATUS_DISABLED) { $this->_catalogProductCompareList->addProduct($product); $productName = $this->_objectManager->get( \Magento\Framework\Escaper::class From 7447cc947e0a551ac45ab1fdb62dcfbe7d8f12aa Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Tue, 28 May 2019 15:35:16 -0500 Subject: [PATCH 065/372] MC-15977: Email template preview --- .../Block/Adminhtml/Template/PreviewTest.php | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 8143995f3b2af..83eda7e39a810 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -54,14 +54,16 @@ protected function setUp() $designConfigData = []; $this->template = $this->getMockBuilder(\Magento\Email\Model\Template::class) - ->setMethods([ - 'setDesignConfig', - 'getDesignConfig', - '__wakeup', - 'getProcessedTemplate', - 'getAppState', - 'revertDesign' - ]) + ->setMethods( + [ + 'setDesignConfig', + 'getDesignConfig', + '__wakeup', + 'getProcessedTemplate', + 'getAppState', + 'revertDesign' + ] + ) ->disableOriginalConstructor() ->getMock(); @@ -82,9 +84,7 @@ protected function setUp() ->willReturn(self::MALICIOUS_TEXT); $this->template->method('getDesignConfig') - ->willReturn(new \Magento\Framework\DataObject( - $designConfigData - )); + ->willReturn(new \Magento\Framework\DataObject($designConfigData)); $emailFactory = $this->createPartialMock(\Magento\Email\Model\TemplateFactory::class, ['create']); $emailFactory->expects($this->any()) @@ -106,9 +106,11 @@ protected function setUp() $this->storeManager->expects($this->any())->method('getDefaultStoreView')->willReturn(null); $this->storeManager->expects($this->any())->method('getStores')->willReturn([$store]); $appState = $this->getMockBuilder(\Magento\Framework\App\State::class) - ->setConstructorArgs([ - $scopeConfig - ]) + ->setConstructorArgs( + [ + $scopeConfig + ] + ) ->setMethods(['emulateAreaCode']) ->disableOriginalConstructor() ->getMock(); From 9b50d1eae804b70e85fd4fa65be82613823aac01 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Wed, 29 May 2019 12:03:18 -0500 Subject: [PATCH 066/372] MC-15573: Prevent invalid UPS configurations --- .../Ups/Model/Config/Backend/UpsUrl.php | 32 ++++++++ .../Unit/Model/Config/Backend/UpsUrlTest.php | 78 +++++++++++++++++++ app/code/Magento/Ups/etc/adminhtml/system.xml | 3 + app/code/Magento/Ups/i18n/en_US.csv | 1 + 4 files changed, 114 insertions(+) create mode 100644 app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php create mode 100644 app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php diff --git a/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php b/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php new file mode 100644 index 0000000000000..155ab7c87be34 --- /dev/null +++ b/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php @@ -0,0 +1,32 @@ +getValue(), \PHP_URL_HOST); + + if (!empty($host) && !preg_match('/(?:.+\.|^)ups\.com$/i', $host)) { + throw new ValidatorException(__('UPS API endpoint URL\'s must use ups.com')); + } + + return parent::beforeSave(); + } +} diff --git a/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php b/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php new file mode 100644 index 0000000000000..8a480983b1bdc --- /dev/null +++ b/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php @@ -0,0 +1,78 @@ +config = $objectManager->getObject(UpsUrl::class); + } + + /** + * @dataProvider validDataProvider + * @param string $data The valid data + */ + public function testBeforeSave($data=null) + { + $this->config->setValue($data); + $this->config->beforeSave(); + } + + /** + * @dataProvider invalidDataProvider + * @param string $data The invalid data + * @expectedException \Magento\Framework\Exception\ValidatorException + * @expectedExceptionMessage UPS API endpoint URL's must use ups.com + */ + public function testBeforeSaveErrors($data) + { + $this->config->setValue($data); + $this->config->beforeSave(); + } + + public function validDataProvider() + { + return [ + [], + [null], + [''], + ['http://ups.com'], + ['https://foo.ups.com'], + ['http://foo.ups.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } + + public function invalidDataProvider() + { + return [ + ['http://upsfoo.com'], + ['https://fooups.com'], + ['https://ups.com.fake.com'], + ['https://ups.info'], + ['http://ups.com.foo.com/foo/bar?baz=bash&fizz=buzz'], + ['http://fooups.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } +} diff --git a/app/code/Magento/Ups/etc/adminhtml/system.xml b/app/code/Magento/Ups/etc/adminhtml/system.xml index 8b9dc30a0188b..91eed08f31db7 100644 --- a/app/code/Magento/Ups/etc/adminhtml/system.xml +++ b/app/code/Magento/Ups/etc/adminhtml/system.xml @@ -56,9 +56,11 @@ + Magento\Ups\Model\Config\Backend\UpsUrl + Magento\Ups\Model\Config\Backend\UpsUrl @@ -103,6 +105,7 @@ + Magento\Ups\Model\Config\Backend\UpsUrl diff --git a/app/code/Magento/Ups/i18n/en_US.csv b/app/code/Magento/Ups/i18n/en_US.csv index baf8ecc855440..68dd34a313bd9 100644 --- a/app/code/Magento/Ups/i18n/en_US.csv +++ b/app/code/Magento/Ups/i18n/en_US.csv @@ -114,3 +114,4 @@ Title,Title Mode,Mode "This enables or disables SSL verification of the Magento server by UPS.","This enables or disables SSL verification of the Magento server by UPS." Debug,Debug +"UPS API endpoint URL's must use ups.com","UPS API endpoint URL's must use ups.com" From 5215bbad2c99f1c0d96a62c4276b08107c2e9b2d Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Wed, 29 May 2019 13:11:06 -0500 Subject: [PATCH 067/372] MC-15573: Prevent invalid UPS configurations --- .../Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php b/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php index 8a480983b1bdc..149f9378889f8 100644 --- a/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php +++ b/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php @@ -34,7 +34,7 @@ protected function setUp() * @dataProvider validDataProvider * @param string $data The valid data */ - public function testBeforeSave($data=null) + public function testBeforeSave($data = null) { $this->config->setValue($data); $this->config->beforeSave(); From 1b80e1b84d22b1fdf341c2f3654b8b833dde9a2b Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 29 May 2019 14:17:32 -0500 Subject: [PATCH 068/372] MC-16114: Update Email Template Filter --- .../Magento/Framework/Filter/Template.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 38198bb9a717b..c32df1b175d8f 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -85,6 +85,16 @@ class Template implements \Zend_Filter_Interface 'getdatausingmethod' ]; + /** + * @var array[] + */ + private $restrictedMethodsByInstanceType = [ + \Magento\Framework\DB\Adapter\AdapterInterface::class => [ + 'rawquery', + 'rawfetchrow' + ] + ]; + /** * @param \Magento\Framework\Stdlib\StringUtils $string * @param array $variables @@ -405,6 +415,12 @@ private function validateVariableMethodCall($object, string $method): void if (in_array(mb_strtolower($method), $this->restrictedMethods)) { throw new \InvalidArgumentException("Method $method cannot be called from template."); } + } else { + foreach ($this->restrictedMethodsByInstanceType as $instanceType => $restrictedMethods) { + if ($object instanceof $instanceType && in_array(mb_strtolower($method), $restrictedMethods)) { + throw new \InvalidArgumentException("Method $method cannot be called from template."); + } + } } } From 95601282c252cde1ce14a6e26871cc6393071e6c Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Wed, 29 May 2019 14:20:52 -0500 Subject: [PATCH 069/372] MC-15573: Prevent invalid UPS configuration --- app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php b/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php index 155ab7c87be34..9db35b6a42dcc 100644 --- a/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php +++ b/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php @@ -21,6 +21,7 @@ class UpsUrl extends Value */ public function beforeSave() { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $host = parse_url((string)$this->getValue(), \PHP_URL_HOST); if (!empty($host) && !preg_match('/(?:.+\.|^)ups\.com$/i', $host)) { From b320ba646413422b8f379b16908d065ebfb40b03 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra Date: Thu, 30 May 2019 10:57:28 +0300 Subject: [PATCH 070/372] MC-13886: Downloadable Product controller|API save changes --- .../Unit/Model/Link/ContentValidatorTest.php | 51 +++++++------------ .../Test/Unit/Model/LinkRepositoryTest.php | 38 +++++++++----- .../Model/Sample/ContentValidatorTest.php | 33 ++++++------ .../Test/Unit/Model/SampleRepositoryTest.php | 36 +++++++------ 4 files changed, 79 insertions(+), 79 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php index 5484e39bd57fc..771fbc37e5e13 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php @@ -246,45 +246,29 @@ protected function getLinkMock(array $linkData) 'isShareable', 'getNumberOfDownloads', 'getLinkType', - 'getLinkFile' + 'getLinkFile', ] ) ->getMockForAbstractClass(); - $linkMock->expects($this->any())->method('getTitle')->will($this->returnValue( - $linkData['title'] - )); - $linkMock->expects($this->any())->method('getPrice')->will($this->returnValue( - $linkData['price'] - )); - $linkMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( - $linkData['sort_order'] - )); - $linkMock->expects($this->any())->method('isShareable')->will($this->returnValue( - $linkData['shareable'] - )); - $linkMock->expects($this->any())->method('getNumberOfDownloads')->will($this->returnValue( - $linkData['number_of_downloads'] - )); - $linkMock->expects($this->any())->method('getLinkType')->will($this->returnValue( - $linkData['link_type'] - )); - $linkMock->expects($this->any())->method('getLinkFile')->will($this->returnValue( - $this->linkFileMock - )); + $linkMock->expects($this->any())->method('getTitle')->will($this->returnValue($linkData['title'])); + $linkMock->expects($this->any())->method('getPrice')->will($this->returnValue($linkData['price'])); + $linkMock->expects($this->any())->method('getSortOrder')->will($this->returnValue($linkData['sort_order'])); + $linkMock->expects($this->any())->method('isShareable')->will($this->returnValue($linkData['shareable'])); + $linkMock->expects($this->any())->method('getNumberOfDownloads')->will( + $this->returnValue($linkData['number_of_downloads']) + ); + $linkMock->expects($this->any())->method('getLinkType')->will($this->returnValue($linkData['link_type'])); + $linkMock->expects($this->any())->method('getLinkFile')->will($this->returnValue($this->linkFileMock)); if (isset($linkData['link_url'])) { - $linkMock->expects($this->any())->method('getLinkUrl')->will($this->returnValue( - $linkData['link_url'] - )); + $linkMock->expects($this->any())->method('getLinkUrl')->will($this->returnValue($linkData['link_url'])); } if (isset($linkData['sample_url'])) { - $linkMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( - $linkData['sample_url'] - )); + $linkMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue($linkData['sample_url'])); } if (isset($linkData['sample_type'])) { - $linkMock->expects($this->any())->method('getSampleType')->will($this->returnValue( - $linkData['sample_type'] - )); + $linkMock->expects($this->any())->method('getSampleType')->will( + $this->returnValue($linkData['sample_type']) + ); } if (isset($linkData['link_file_content'])) { $linkMock->expects($this->any())->method('getLinkFileContent')->willReturn($linkData['link_file_content']); @@ -293,9 +277,8 @@ protected function getLinkMock(array $linkData) $linkMock->expects($this->any())->method('getSampleFileContent') ->willReturn($linkData['sample_file_content']); } - $linkMock->expects($this->any())->method('getSampleFile')->will($this->returnValue( - $this->sampleFileMock - )); + $linkMock->expects($this->any())->method('getSampleFile')->will($this->returnValue($this->sampleFileMock)); + return $linkMock; } } diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php index 4494877b70f6c..25f720f27150c 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php @@ -98,7 +98,9 @@ protected function setUp() \Magento\Framework\Json\EncoderInterface::class ); $this->linkFactoryMock = $this->createPartialMock(\Magento\Downloadable\Model\LinkFactory::class, ['create']); - $this->productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, [ + $this->productMock = $this->createPartialMock( + \Magento\Catalog\Model\Product::class, + [ '__wakeup', 'getTypeId', 'setDownloadableData', @@ -107,8 +109,9 @@ protected function setUp() 'getStoreId', 'getStore', 'getWebsiteIds', - 'getData' - ]); + 'getData', + ] + ); $this->service = new \Magento\Downloadable\Model\LinkRepository( $this->repositoryMock, $this->productTypeMock, @@ -310,12 +313,15 @@ public function testUpdate() $storeMock = $this->createMock(\Magento\Store\Model\Store::class); $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId)); $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock)); - $existingLinkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [ + $existingLinkMock = $this->createPartialMock( + \Magento\Downloadable\Model\Link::class, + [ '__wakeup', 'getId', 'load', - 'getProductId' - ]); + 'getProductId', + ] + ); $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock)); $linkMock = $this->getLinkMock($linkData); $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock) @@ -372,12 +378,15 @@ public function testUpdateWithExistingFile() $storeMock = $this->createMock(\Magento\Store\Model\Store::class); $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId)); $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock)); - $existingLinkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [ + $existingLinkMock = $this->createPartialMock( + \Magento\Downloadable\Model\Link::class, + [ '__wakeup', 'getId', 'load', - 'getProductId' - ]); + 'getProductId', + ] + ); $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock)); $linkMock = $this->getLinkMock($linkData); $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock) @@ -504,10 +513,12 @@ public function testGetList() 'sample_file' => '/r/o/rock.melody.ogg', 'link_type' => 'url', 'link_url' => 'http://link.url', - 'link_file' => null + 'link_file' => null, ]; - $linkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [ + $linkMock = $this->createPartialMock( + \Magento\Downloadable\Model\Link::class, + [ 'getId', 'getStoreTitle', 'getTitle', @@ -522,8 +533,9 @@ public function testGetList() 'getSampleUrl', 'getLinkType', 'getLinkFile', - 'getLinkUrl' - ]); + 'getLinkUrl', + ] + ); $linkInterfaceMock = $this->createMock(\Magento\Downloadable\Api\Data\LinkInterface::class); diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php index 90bcfa2e39bef..4a32a45859cec 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php @@ -117,28 +117,29 @@ public function getInvalidSortOrder() protected function getSampleContentMock(array $sampleContentData) { $contentMock = $this->createMock(\Magento\Downloadable\Api\Data\SampleInterface::class); - $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue( - $sampleContentData['title'] - )); - - $contentMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( - $sampleContentData['sort_order'] - )); - $contentMock->expects($this->any())->method('getSampleType')->will($this->returnValue( - $sampleContentData['sample_type'] - )); + $contentMock->expects($this->any())->method('getTitle')->will( + $this->returnValue($sampleContentData['title']) + ); + + $contentMock->expects($this->any())->method('getSortOrder')->will( + $this->returnValue($sampleContentData['sort_order']) + ); + $contentMock->expects($this->any())->method('getSampleType')->will( + $this->returnValue($sampleContentData['sample_type']) + ); if (isset($sampleContentData['sample_url'])) { - $contentMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( - $sampleContentData['sample_url'] - )); + $contentMock->expects($this->any())->method('getSampleUrl')->will( + $this->returnValue($sampleContentData['sample_url']) + ); } if (isset($sampleContentData['sample_file_content'])) { $contentMock->expects($this->any())->method('getSampleFileContent') ->willReturn($sampleContentData['sample_file_content']); } - $contentMock->expects($this->any())->method('getSampleFile')->will($this->returnValue( - $this->sampleFileMock - )); + $contentMock->expects($this->any())->method('getSampleFile')->will( + $this->returnValue($this->sampleFileMock) + ); + return $contentMock; } } diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php index f1ca30bd7dd36..f1674c6838a2d 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php @@ -149,25 +149,26 @@ protected function getSampleMock(array $sampleData) $sampleMock->expects($this->any())->method('getId')->willReturn($sampleData['id']); } $sampleMock->expects($this->any())->method('getTitle')->will($this->returnValue($sampleData['title'])); - $sampleMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( - $sampleData['sort_order'] - )); + $sampleMock->expects($this->any())->method('getSortOrder')->will( + $this->returnValue($sampleData['sort_order']) + ); if (isset($sampleData['sample_type'])) { - $sampleMock->expects($this->any())->method('getSampleType')->will($this->returnValue( - $sampleData['sample_type'] - )); + $sampleMock->expects($this->any())->method('getSampleType')->will( + $this->returnValue($sampleData['sample_type']) + ); } if (isset($sampleData['sample_url'])) { - $sampleMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( - $sampleData['sample_url'] - )); + $sampleMock->expects($this->any())->method('getSampleUrl')->will( + $this->returnValue($sampleData['sample_url']) + ); } if (isset($sampleData['sample_file'])) { - $sampleMock->expects($this->any())->method('getSampleFile')->will($this->returnValue( - $sampleData['sample_file'] - )); + $sampleMock->expects($this->any())->method('getSampleFile')->will( + $this->returnValue($sampleData['sample_file']) + ); } + return $sampleMock; } @@ -416,10 +417,12 @@ public function testGetList() 'sort_order' => 21, 'sample_type' => 'file', 'sample_url' => null, - 'sample_file' => '/r/o/rock.melody.ogg' + 'sample_file' => '/r/o/rock.melody.ogg', ]; - $sampleMock = $this->createPartialMock(\Magento\Downloadable\Model\Sample::class, [ + $sampleMock = $this->createPartialMock( + \Magento\Downloadable\Model\Sample::class, + [ 'getId', 'getStoreTitle', 'getTitle', @@ -428,8 +431,9 @@ public function testGetList() 'getSampleUrl', 'getSortOrder', 'getData', - '__wakeup' - ]); + '__wakeup', + ] + ); $sampleInterfaceMock = $this->createMock(\Magento\Downloadable\Api\Data\SampleInterface::class); From f7f8ceb43f2348257ae38498197d2dc3d1641266 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Thu, 30 May 2019 11:14:49 -0500 Subject: [PATCH 071/372] MC-17067: Update config table schema - Updated config table schema --- app/code/Magento/Config/etc/db_schema.xml | 2 ++ app/code/Magento/Config/etc/db_schema_whitelist.json | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Config/etc/db_schema.xml b/app/code/Magento/Config/etc/db_schema.xml index 8aeac802fbd91..1b2f7a0519411 100644 --- a/app/code/Magento/Config/etc/db_schema.xml +++ b/app/code/Magento/Config/etc/db_schema.xml @@ -15,6 +15,8 @@ default="0" comment="Config Scope Id"/> + diff --git a/app/code/Magento/Config/etc/db_schema_whitelist.json b/app/code/Magento/Config/etc/db_schema_whitelist.json index 850e160bc732f..51ca41d8e6af8 100644 --- a/app/code/Magento/Config/etc/db_schema_whitelist.json +++ b/app/code/Magento/Config/etc/db_schema_whitelist.json @@ -5,11 +5,12 @@ "scope": true, "scope_id": true, "path": true, - "value": true + "value": true, + "updated_at": true }, "constraint": { "PRIMARY": true, "CORE_CONFIG_DATA_SCOPE_SCOPE_ID_PATH": true } } -} \ No newline at end of file +} From c7676c54342926a3d40878ceb6042899f0ec49fe Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Thu, 30 May 2019 15:36:53 -0500 Subject: [PATCH 072/372] MC-16940: Prevent errors from incorrect configurations --- .../Interpreter/ConfigurableObject.php | 70 +++++++++++++++---- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 2810db6569421..654359ec30be7 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -3,10 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; +use Magento\Framework\Code\Reader\ClassReader; +use Magento\Framework\Data\OptionSourceInterface; +use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Data\Argument\InterpreterInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; /** * Class ConfigurableObject @@ -16,8 +22,9 @@ class ConfigurableObject implements InterpreterInterface /** * @var array */ - private $classBlacklist = [ - \Zend\Code\Reflection\FileReflection::class + private $classWhitelist = [ + DataProviderInterface::class, + OptionSourceInterface::class ]; /** @@ -29,17 +36,33 @@ class ConfigurableObject implements InterpreterInterface * @var InterpreterInterface */ protected $argumentInterpreter; + /** + * @var ClassReader|null + */ + private $classReader; + /** + * @var ConfigInterface + */ + private $objectManagerConfig; /** * Constructor * * @param ObjectManagerInterface $objectManager * @param InterpreterInterface $argumentInterpreter + * @param ClassReader|null $classReader + * @param ConfigInterface $objectManagerConfig */ - public function __construct(ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter) - { + public function __construct( + ObjectManagerInterface $objectManager, + InterpreterInterface $argumentInterpreter, + ClassReader $classReader = null, + ConfigInterface $objectManagerConfig = null + ) { $this->objectManager = $objectManager; $this->argumentInterpreter = $argumentInterpreter; + $this->classReader = $classReader ?? $objectManager->get(ClassReader::class); + $this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class); } /** @@ -61,14 +84,18 @@ public function evaluate(array $data) throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); } - if (in_array( - ltrim(strtolower($arguments['class']), '\\'), - array_map('strtolower', $this->classBlacklist) - )) { - throw new \InvalidArgumentException(sprintf( - 'Class argument is invalid: %s', - $arguments['class'] - )); + $type = $this->objectManagerConfig->getInstanceType( + $this->objectManagerConfig->getPreference($arguments['class']) + ); + + $classParents = $this->getParents($type); + + $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); + + if (empty($whitelistIntersection)) { + throw new \InvalidArgumentException( + sprintf('Class argument is invalid: %s', $arguments['class']) + ); } $className = $arguments['class']; @@ -77,4 +104,23 @@ public function evaluate(array $data) return $this->objectManager->create($className, $arguments); } + + /** + * Retrieves all the parent classes and interfaces for a class including the ones implemented by the class itself + * + * @param string $type + * @return string[] + */ + private function getParents(string $type) + { + $classParents = $this->classReader->getParents($type); + foreach ($classParents as $parent) { + if (empty($parent)) { + continue; + } + $classParents = array_merge($classParents, $this->getParents($parent)); + } + + return $classParents; + } } From 84bf99b4d098b4dde120546c7b727e153bdc94ae Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Fri, 31 May 2019 12:13:06 -0500 Subject: [PATCH 073/372] MC-16074: Sitemap generator update - Updated magento store config file --- app/code/Magento/Store/etc/config.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Store/etc/config.xml b/app/code/Magento/Store/etc/config.xml index 23182c8d76470..07e4c8b0b6529 100644 --- a/app/code/Magento/Store/etc/config.xml +++ b/app/code/Magento/Store/etc/config.xml @@ -135,14 +135,14 @@ - /app/*/* - /bin/*/* - /dev/*/* - /generated/*/* - /lib/*/* - /setup/*/* - /update/*/* - /vendor/*/* + */app/*/* + */bin/*/* + */dev/*/* + */generated/*/* + */lib/*/* + */setup/*/* + */update/*/* + */vendor/*/* From e6e7665d54074c55fcd821d6682554c77f1b9f7b Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Fri, 31 May 2019 12:21:26 -0500 Subject: [PATCH 074/372] MC-16940: Prevent errors from incorrect configurations --- app/etc/di.xml | 8 ++++ .../Interpreter/ConfigurableObject.php | 47 +++++++------------ 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/app/etc/di.xml b/app/etc/di.xml index 200a56201239d..cccae25b467eb 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -662,6 +662,14 @@ layoutArgumentGeneratorInterpreter + + + + Magento\Framework\Data\OptionSourceInterface + Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface + + + Magento\Indexer\Model\Mview\View\State diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 654359ec30be7..4e7caaf4c5655 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -8,11 +8,9 @@ namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; use Magento\Framework\Code\Reader\ClassReader; -use Magento\Framework\Data\OptionSourceInterface; use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Data\Argument\InterpreterInterface; -use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; /** * Class ConfigurableObject @@ -22,10 +20,7 @@ class ConfigurableObject implements InterpreterInterface /** * @var array */ - private $classWhitelist = [ - DataProviderInterface::class, - OptionSourceInterface::class - ]; + private $classWhitelist = []; /** * @var ObjectManagerInterface @@ -36,10 +31,12 @@ class ConfigurableObject implements InterpreterInterface * @var InterpreterInterface */ protected $argumentInterpreter; + /** - * @var ClassReader|null + * @var ClassReader */ private $classReader; + /** * @var ConfigInterface */ @@ -50,17 +47,20 @@ class ConfigurableObject implements InterpreterInterface * * @param ObjectManagerInterface $objectManager * @param InterpreterInterface $argumentInterpreter + * @param array $classWhitelist * @param ClassReader|null $classReader - * @param ConfigInterface $objectManagerConfig + * @param ConfigInterface|null $objectManagerConfig */ public function __construct( ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter, + array $classWhitelist = [], ClassReader $classReader = null, ConfigInterface $objectManagerConfig = null ) { $this->objectManager = $objectManager; $this->argumentInterpreter = $argumentInterpreter; + $this->classWhitelist = $classWhitelist; $this->classReader = $classReader ?? $objectManager->get(ClassReader::class); $this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class); } @@ -88,11 +88,15 @@ public function evaluate(array $data) $this->objectManagerConfig->getPreference($arguments['class']) ); - $classParents = $this->getParents($type); - - $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); + $classIsAllowed = false; + foreach ($this->classWhitelist as $allowedClass) { + if (is_subclass_of($type, $allowedClass, true)) { + $classIsAllowed = true; + break; + } + } - if (empty($whitelistIntersection)) { + if (!$classIsAllowed) { throw new \InvalidArgumentException( sprintf('Class argument is invalid: %s', $arguments['class']) ); @@ -104,23 +108,4 @@ public function evaluate(array $data) return $this->objectManager->create($className, $arguments); } - - /** - * Retrieves all the parent classes and interfaces for a class including the ones implemented by the class itself - * - * @param string $type - * @return string[] - */ - private function getParents(string $type) - { - $classParents = $this->classReader->getParents($type); - foreach ($classParents as $parent) { - if (empty($parent)) { - continue; - } - $classParents = array_merge($classParents, $this->getParents($parent)); - } - - return $classParents; - } } From e06b4e596da2147f487413325528623da32eaac6 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Fri, 31 May 2019 12:26:13 -0500 Subject: [PATCH 075/372] MC-16940: Prevent errors from incorrect configurations --- .../Argument/Interpreter/ConfigurableObject.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 4e7caaf4c5655..3098504ebfc53 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -7,7 +7,6 @@ namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; -use Magento\Framework\Code\Reader\ClassReader; use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Data\Argument\InterpreterInterface; @@ -32,11 +31,6 @@ class ConfigurableObject implements InterpreterInterface */ protected $argumentInterpreter; - /** - * @var ClassReader - */ - private $classReader; - /** * @var ConfigInterface */ @@ -48,20 +42,17 @@ class ConfigurableObject implements InterpreterInterface * @param ObjectManagerInterface $objectManager * @param InterpreterInterface $argumentInterpreter * @param array $classWhitelist - * @param ClassReader|null $classReader * @param ConfigInterface|null $objectManagerConfig */ public function __construct( ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter, array $classWhitelist = [], - ClassReader $classReader = null, ConfigInterface $objectManagerConfig = null ) { $this->objectManager = $objectManager; $this->argumentInterpreter = $argumentInterpreter; $this->classWhitelist = $classWhitelist; - $this->classReader = $classReader ?? $objectManager->get(ClassReader::class); $this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class); } From edb45bd6b45a5de87a35498f0340238fcb80ad6a Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Fri, 31 May 2019 16:02:24 -0500 Subject: [PATCH 076/372] MC-16940: Prevent errors from incorrect configurations --- .../Interpreter/ConfigurableObject.php | 60 ++-- .../Interpreter/ConfigurableObjectTest.php | 286 ++++++++++++++++++ 2 files changed, 329 insertions(+), 17 deletions(-) create mode 100644 lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 3098504ebfc53..2ea2856cc0f13 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -7,9 +7,12 @@ namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; +use Magento\Framework\Code\Reader\ClassReader; +use Magento\Framework\Data\OptionSourceInterface; use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Data\Argument\InterpreterInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; /** * Class ConfigurableObject @@ -31,6 +34,11 @@ class ConfigurableObject implements InterpreterInterface */ protected $argumentInterpreter; + /** + * @var ClassReader|null + */ + private $classReader; + /** * @var ConfigInterface */ @@ -42,17 +50,20 @@ class ConfigurableObject implements InterpreterInterface * @param ObjectManagerInterface $objectManager * @param InterpreterInterface $argumentInterpreter * @param array $classWhitelist + * @param ClassReader|null $classReader * @param ConfigInterface|null $objectManagerConfig */ public function __construct( ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter, array $classWhitelist = [], + ClassReader $classReader = null, ConfigInterface $objectManagerConfig = null ) { $this->objectManager = $objectManager; $this->argumentInterpreter = $argumentInterpreter; $this->classWhitelist = $classWhitelist; + $this->classReader = $classReader ?? $objectManager->get(ClassReader::class); $this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class); } @@ -75,28 +86,43 @@ public function evaluate(array $data) throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); } - $type = $this->objectManagerConfig->getInstanceType( - $this->objectManagerConfig->getPreference($arguments['class']) - ); + $className = $arguments['class']; + unset($arguments['class']); + } - $classIsAllowed = false; - foreach ($this->classWhitelist as $allowedClass) { - if (is_subclass_of($type, $allowedClass, true)) { - $classIsAllowed = true; - break; - } - } + $type = $this->objectManagerConfig->getInstanceType( + $this->objectManagerConfig->getPreference($className) + ); - if (!$classIsAllowed) { - throw new \InvalidArgumentException( - sprintf('Class argument is invalid: %s', $arguments['class']) - ); - } + $classParents = $this->getParents($type); - $className = $arguments['class']; - unset($arguments['class']); + $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); + + if (empty($whitelistIntersection)) { + throw new \InvalidArgumentException( + sprintf('Class argument is invalid: %s', $className) + ); } return $this->objectManager->create($className, $arguments); } + + /** + * Retrieves all the parent classes and interfaces for a class including the ones implemented by the class itself + * + * @param string $type + * @return string[] + */ + private function getParents(string $type) + { + $classParents = $this->classReader->getParents($type); + foreach ($classParents as $parent) { + if (empty($parent)) { + continue; + } + $classParents = array_merge($classParents, $this->getParents($parent)); + } + + return $classParents; + } } diff --git a/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php b/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php new file mode 100644 index 0000000000000..8b4f2a35c0802 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php @@ -0,0 +1,286 @@ +objectManager = $this->createMock(ObjectManagerInterface::class); + $this->interpreter = $this->createMock(InterpreterInterface::class); + $this->classReader = $this->createMock(ClassReader::class); + $this->objectManagerConfig = $this->createMock(ConfigInterface::class); + $this->configurableObject = $objectManager->getObject( + ConfigurableObject::class, + [ + 'objectManager' => $this->objectManager, + 'argumentInterpreter' => $this->interpreter, + 'classWhitelist' => [ + \Foo\Bar\ClassA::class, + \Foo\Bar\InterfaceA::class, + ], + 'classReader' => $this->classReader, + 'objectManagerConfig' => $this->objectManagerConfig, + ] + ); + } + + /** + * @dataProvider validDataProvider + */ + public function testValidCombinations( + $data, + $expectedClass, + $classParentsValueMap, + $expectedArguments + ) { + $this->objectManagerConfig + ->method('getPreference') + ->with($expectedClass) + ->WillReturn('bar'); + $this->objectManagerConfig + ->method('getInstanceType') + ->with('bar') + ->willReturn($expectedClass); + + $this->classReader + ->method('getParents') + ->willReturnMap($classParentsValueMap); + + $this->objectManager + ->expects($this->once()) + ->method('create') + ->with($expectedClass, $expectedArguments) + ->willReturn('an object yay!'); + + $this->interpreter + ->method('evaluate') + ->will( + $this->returnCallback( + function (array $arg) { + return $arg['value']; + } + ) + ); + + $actualResult = $this->configurableObject->evaluate($data); + self::assertSame('an object yay!', $actualResult); + } + + /** + * @dataProvider invalidDataProvider + */ + public function testInvalidCombinations( + $data, + $expectedClass, + $classParentsValueMap, + $expectedException, + $expectedExceptionMessage + ) { + + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + + $this->objectManagerConfig + ->method('getPreference') + ->with($expectedClass) + ->WillReturn('bar'); + $this->objectManagerConfig + ->method('getInstanceType') + ->with('bar') + ->willReturn($expectedClass); + + $this->classReader + ->method('getParents') + ->willReturnMap($classParentsValueMap); + + $this->objectManager + ->expects($this->never()) + ->method('create'); + + $this->interpreter + ->method('evaluate') + ->will( + $this->returnCallback( + function (array $arg) { + return $arg['value']; + } + ) + ); + + $actualResult = $this->configurableObject->evaluate($data); + self::assertSame('an object yay!', $actualResult); + } + + public function validDataProvider() + { + return [ + // Test most basic syntax + [ + [ + 'value' => 'MyFooClass', + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', []], + [\Foo\Bar\ClassA::class, []] + ], + [] + ], + // Test alternative data syntax + [ + [ + 'argument' => [ + 'class' => ['value' => 'MyFooClass'] + ] + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', []], + [\Foo\Bar\ClassA::class, []] + ], + [] + ], + // Test arguments + [ + [ + 'argument' => [ + 'class' => ['value' => 'MyFooClass'], + 'myarg' => ['value' => 'bar'], + ] + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', []], + [\Foo\Bar\ClassA::class, []] + ], + ['myarg' => 'bar'] + ], + // Test multiple matching whitelisted classes + [ + [ + 'argument' => [ + 'class' => ['value' => 'MyFooClass'], + 'myarg' => ['value' => 'bar'], + ] + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', [\Foo\Bar\InterfaceA::class]], + [\Foo\Bar\ClassA::class, []], + [\Foo\Bar\InterfaceA::class, []] + ], + ['myarg' => 'bar'] + ], + ]; + } + + public function invalidDataProvider() + { + return [ + [ + [ + 'notvalid' => 'sup' + ], + '', + [], + \InvalidArgumentException::class, + 'Node "argument" required for this type.' + ], + [ + [ + 'argument' => [ + 'notclass' => ['value' => 'doesntmatter'] + ] + ], + '', + [], + \InvalidArgumentException::class, + 'Node "argument" with name "class" is required for this type.' + ], + [ + [ + 'argument' => [ + 'class' => ['value' => 'MyFooClass'], + 'myarg' => ['value' => 'bar'], + ] + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', ['unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', []], + ], + \InvalidArgumentException::class, + 'Class argument is invalid: MyFooClass' + ], + ]; + } +} From 839095db2229adb41e0b226b6b8737fb67f00096 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 3 Jun 2019 08:21:59 -0500 Subject: [PATCH 077/372] MC-16940: Prevent errors from incorrect configurations --- .../Interpreter/ConfigurableObject.php | 20 +++++++++---------- .../Interpreter/ConfigurableObjectTest.php | 16 ++++----------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 2ea2856cc0f13..2691bc21357b0 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -88,20 +88,20 @@ public function evaluate(array $data) $className = $arguments['class']; unset($arguments['class']); - } - $type = $this->objectManagerConfig->getInstanceType( - $this->objectManagerConfig->getPreference($className) - ); + $type = $this->objectManagerConfig->getInstanceType( + $this->objectManagerConfig->getPreference($className) + ); - $classParents = $this->getParents($type); + $classParents = $this->getParents($type); - $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); + $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); - if (empty($whitelistIntersection)) { - throw new \InvalidArgumentException( - sprintf('Class argument is invalid: %s', $className) - ); + if (empty($whitelistIntersection)) { + throw new \InvalidArgumentException( + sprintf('Class argument is invalid: %s', $className) + ); + } } return $this->objectManager->create($className, $arguments); diff --git a/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php b/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php index 8b4f2a35c0802..0d4be68a4c1bb 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php @@ -159,21 +159,13 @@ function (array $arg) { public function validDataProvider() { return [ - // Test most basic syntax + // Test most basic syntax with no arguments [ [ - 'value' => 'MyFooClass', - ], - 'MyFooClass', - [ - ['MyFooClass', ['Something', 'skipme']], - ['Something', ['dontcare', 'SomethingElse']], - ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], - ['skipme', []], - ['dontcare', []], - ['unrelated', []], - [\Foo\Bar\ClassA::class, []] + 'value' => 'MyObject', ], + 'MyObject', + [], [] ], // Test alternative data syntax From 1c0879c90dda4050fecb02e743d676e9b7036072 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Mon, 3 Jun 2019 12:11:42 -0500 Subject: [PATCH 078/372] MC-15134: Currency rate config update - Updated currency matrix template --- .../view/adminhtml/templates/system/currency/rate/matrix.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml b/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml index 8a16eb71e0853..9701fc928e861 100644 --- a/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml +++ b/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml @@ -28,7 +28,7 @@ $_rates = ($_newRates) ? $_newRates : $_oldRates;   getAllowedCurrencies() as $_currencyCode): ?> - + escapeHtml($_currencyCode) ?> From ceb5524a85fa6cbfe5d63ff4d7912cf26cf6b926 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Tue, 4 Jun 2019 13:31:10 -0500 Subject: [PATCH 079/372] MC-16114: Update Email Template Filter --- lib/internal/Magento/Framework/Filter/Template.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index c32df1b175d8f..1bb063fb279a6 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -90,8 +90,7 @@ class Template implements \Zend_Filter_Interface */ private $restrictedMethodsByInstanceType = [ \Magento\Framework\DB\Adapter\AdapterInterface::class => [ - 'rawquery', - 'rawfetchrow' + '*' ] ]; @@ -417,7 +416,9 @@ private function validateVariableMethodCall($object, string $method): void } } else { foreach ($this->restrictedMethodsByInstanceType as $instanceType => $restrictedMethods) { - if ($object instanceof $instanceType && in_array(mb_strtolower($method), $restrictedMethods)) { + if ($object instanceof $instanceType && + ($restrictedMethods === '*' || in_array(mb_strtolower($method), $restrictedMethods)) + ) { throw new \InvalidArgumentException("Method $method cannot be called from template."); } } From 9a9b6e4733ec3dab4c0bf133bf9d4211e9789749 Mon Sep 17 00:00:00 2001 From: Roman Hanin Date: Tue, 4 Jun 2019 14:58:11 -0500 Subject: [PATCH 080/372] MC-16056: Template engine optimizations --- .../Magento/Framework/Filter/Template.php | 108 ++++++++---------- 1 file changed, 48 insertions(+), 60 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 6a04e8e8c6953..6654135b7f6c6 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -9,9 +9,6 @@ */ namespace Magento\Framework\Filter; -use Magento\Framework\Model\AbstractExtensibleModel; -use Magento\Framework\Model\AbstractModel; - /** * Template filter * @@ -400,7 +397,7 @@ protected function getParameters($value) */ private function validateVariableMethodCall($object, string $method): void { - if ($object === $this) { + if ($object instanceof self || $object instanceof \Magento\Framework\DataObject) { if (in_array(mb_strtolower($method), $this->restrictedMethods)) { throw new \InvalidArgumentException("Method $method cannot be called from template."); } @@ -408,28 +405,7 @@ private function validateVariableMethodCall($object, string $method): void } /** - * Check allowed methods for data objects. - * - * Deny calls for methods that may disrupt template processing. - * - * @param object $object - * @param string $method - * @return bool - * @throws \InvalidArgumentException - */ - private function isAllowedDataObjectMethod($object, string $method): bool - { - if ($object instanceof AbstractExtensibleModel || $object instanceof AbstractModel) { - if (in_array(mb_strtolower($method), $this->restrictedMethods)) { - throw new \InvalidArgumentException("Method $method cannot be called from template."); - } - } - - return true; - } - - /** - * Return variable value for var construction + * Return variable value for var construction. * * @param string $value raw parameters * @param string $default default value @@ -448,45 +424,18 @@ protected function getVariable($value, $default = '{no_value_defined}') if ($i == 0 && isset($this->templateVars[$stackVars[$i]['name']])) { // Getting of template value $stackVars[$i]['variable'] = & $this->templateVars[$stackVars[$i]['name']]; - } elseif (isset($stackVars[$i - 1]['variable']) - && $stackVars[$i - 1]['variable'] instanceof \Magento\Framework\DataObject - ) { - // If data object calling methods or getting properties + } elseif (isset($stackVars[$i - 1]['variable']) && is_object($stackVars[$i - 1]['variable'])) { if ($stackVars[$i]['type'] == 'property') { - $caller = 'get' . $this->string->upperCaseWords($stackVars[$i]['name'], '_', ''); - $stackVars[$i]['variable'] = method_exists( + $stackVars[$i]['variable'] = $this->evaluateObjectPropertyAccess( $stackVars[$i - 1]['variable'], - $caller - ) ? $stackVars[$i - 1]['variable']->{$caller}() : $stackVars[$i - 1]['variable']->getData( $stackVars[$i]['name'] ); } elseif ($stackVars[$i]['type'] == 'method') { - // Calling of data object method - if (method_exists($stackVars[$i - 1]['variable'], $stackVars[$i]['name']) - || substr($stackVars[$i]['name'], 0, 3) == 'get' - ) { - $stackVars[$i]['args'] = $this->getStackArgs($stackVars[$i]['args']); - - if ($this->isAllowedDataObjectMethod($stackVars[$i - 1]['variable'], $stackVars[$i]['name'])) { - $stackVars[$i]['variable'] = call_user_func_array( - [$stackVars[$i - 1]['variable'], $stackVars[$i]['name']], - $stackVars[$i]['args'] - ); - } - } - } - $last = $i; - } elseif (isset($stackVars[$i - 1]['variable']) - && is_object($stackVars[$i - 1]['variable']) - && $stackVars[$i]['type'] == 'method' - ) { - // Calling object methods - $object = $stackVars[$i - 1]['variable']; - $method = $stackVars[$i]['name']; - if (method_exists($object, $method)) { - $args = $this->getStackArgs($stackVars[$i]['args']); - $this->validateVariableMethodCall($object, $method); - $stackVars[$i]['variable'] = call_user_func_array([$object, $method], $args); + $stackVars[$i]['variable'] = $this->evaluateObjectMethodCall( + $stackVars[$i - 1]['variable'], + $stackVars[$i]['name'], + $stackVars[$i]['args'] + ); } $last = $i; } @@ -500,6 +449,45 @@ protected function getVariable($value, $default = '{no_value_defined}') return $result; } + /** + * Evaluate object property access. + * + * @param object $object + * @param string $property + * @return null + */ + private function evaluateObjectPropertyAccess($object, $property) + { + $method = 'get' . $this->string->upperCaseWords($property, '_', ''); + $this->validateVariableMethodCall($object, $method); + return method_exists($object, $method) + ? $object->{$method}() + : (($object instanceof \Magento\Framework\DataObject) ? $object->getData($property) : null); + } + + /** + * Evaluate object method call. + * + * @param object $object + * @param string $method + * @param array $arguments + * @return mixed|null + */ + private function evaluateObjectMethodCall($object, $method, $arguments) + { + if (method_exists($object, $method) + || ($object instanceof \Magento\Framework\DataObject && substr($method, 0, 3) == 'get') + ) { + $arguments = $this->getStackArgs($arguments); + $this->validateVariableMethodCall($object, $method); + return call_user_func_array( + [$object, $method], + $arguments + ); + } + return null; + } + /** * Loops over a set of stack args to process variables into array argument values * From 142e5fd71839d3f28a99fedf6a3ce11ad9cfdff1 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Wed, 5 Jun 2019 12:57:50 -0500 Subject: [PATCH 081/372] MC-15919: Customer attribute label update - Updated meta data resolver object --- app/code/Magento/Customer/Model/AttributeMetadataResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php index 979730eb1c9c2..84162bb8dae09 100644 --- a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php +++ b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php @@ -144,7 +144,7 @@ public function getAttributesMeta( $attribute, $meta['arguments']['data']['config'] ); - + $meta['arguments']['data']['config']['__disableTmpl'] = true; return $meta; } From 52dbfdf1905825b947265bc1fc44b159973e3790 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Wed, 5 Jun 2019 08:47:44 -0500 Subject: [PATCH 082/372] MC-16963: Admin panel Design Configuration changes logs are missing --- .../Model/Design/BackendModelFactory.php | 22 ++++++++++++++----- .../Model/Design/Config/ValueChecker.php | 6 ++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Theme/Model/Design/BackendModelFactory.php b/app/code/Magento/Theme/Model/Design/BackendModelFactory.php index 155afa89c4173..2896e9f101298 100644 --- a/app/code/Magento/Theme/Model/Design/BackendModelFactory.php +++ b/app/code/Magento/Theme/Model/Design/BackendModelFactory.php @@ -11,6 +11,9 @@ use Magento\Theme\Model\Design\Config\MetadataProvider; use Magento\Theme\Model\ResourceModel\Design\Config\CollectionFactory; +/** + * Class BackendModelFactory + */ class BackendModelFactory extends ValueFactory { /** @@ -58,13 +61,15 @@ public function __construct( */ public function create(array $data = []) { + $storedData = $this->getStoredData($data['scope'], $data['scopeId'], $data['config']['path']); + $backendModelData = array_replace_recursive( - $this->getStoredData($data['scope'], $data['scopeId'], $data['config']['path']), + $storedData, [ 'path' => $data['config']['path'], 'scope' => $data['scope'], 'scope_id' => $data['scopeId'], - 'field_config' => $data['config'], + 'field_config' => $data['config'] ] ); @@ -76,6 +81,10 @@ public function create(array $data = []) $backendModel = $this->getNewBackendModel($backendType, $backendModelData); $backendModel->setValue($data['value']); + foreach ($storedData as $key => $value) { + $backendModel->setOrigData($key, $value); + } + return $backendModel; } @@ -166,9 +175,12 @@ protected function getMetadata() { if (!$this->metadata) { $this->metadata = $this->metadataProvider->get(); - array_walk($this->metadata, function (&$value) { - $value = $value['path']; - }); + array_walk( + $this->metadata, + function (&$value) { + $value = $value['path']; + } + ); } return $this->metadata; } diff --git a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php index 42801f57c8822..00f30e9d7976c 100644 --- a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php +++ b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php @@ -8,6 +8,9 @@ use Magento\Framework\App\Config as AppConfig; use Magento\Framework\App\ScopeFallbackResolverInterface; +/** + * Class ValueChecker + */ class ValueChecker { /** @@ -61,7 +64,7 @@ public function isDifferentFromDefault($value, $scope, $scopeId, array $fieldCon $fieldConfig ), $this->valueProcessor->process( - $this->appConfig->getValue($fieldConfig['path'], $scope, $scopeId), + ($this->appConfig->getValue($fieldConfig['path'], $scope, $scopeId) ?? ""), $scope, $scopeId, $fieldConfig @@ -80,6 +83,7 @@ public function isDifferentFromDefault($value, $scope, $scopeId, array $fieldCon */ protected function isEqual($value, $defaultValue) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction switch (gettype($value)) { case 'array': return $this->isEqualArrays($value, $defaultValue); From 5dad282326cc4c7aff794ad1db1df283be28540c Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" Date: Wed, 5 Jun 2019 14:38:26 +0300 Subject: [PATCH 083/372] MAGETWO-99862: wishlist_item_option table contains unrelated data --- .../Wishlist/Controller/Index/Plugin.php | 8 ++- .../Test/Unit/Controller/Index/PluginTest.php | 37 ++++++---- .../Wishlist/Controller/Index/PluginTest.php | 71 +++++++++++++++++++ 3 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php diff --git a/app/code/Magento/Wishlist/Controller/Index/Plugin.php b/app/code/Magento/Wishlist/Controller/Index/Plugin.php index 60d6859613d5e..150e4de72b40d 100644 --- a/app/code/Magento/Wishlist/Controller/Index/Plugin.php +++ b/app/code/Magento/Wishlist/Controller/Index/Plugin.php @@ -1,6 +1,5 @@ customerSession->getBeforeWishlistUrl()) { $this->customerSession->setBeforeWishlistUrl($this->redirector->getRefererUrl()); } - $this->customerSession->setBeforeWishlistRequest($request->getParams()); + $data = $request->getParams(); + unset($data['login']); + $this->customerSession->setBeforeWishlistRequest($data); $this->customerSession->setBeforeRequestParams($this->customerSession->getBeforeWishlistRequest()); $this->customerSession->setBeforeModuleName('wishlist'); $this->customerSession->setBeforeControllerName('index'); diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/PluginTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/PluginTest.php index 399b48073b339..2b583f9101516 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/PluginTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/PluginTest.php @@ -6,6 +6,9 @@ namespace Magento\Wishlist\Test\Unit\Controller\Index; +/** + * Test for wishlist plugin before dispatch + */ class PluginTest extends \PHPUnit\Framework\TestCase { /** @@ -38,22 +41,26 @@ class PluginTest extends \PHPUnit\Framework\TestCase */ protected $request; + /** + * @inheritdoc + */ protected function setUp() { $this->customerSession = $this->getMockBuilder(\Magento\Customer\Model\Session::class) ->disableOriginalConstructor() - ->setMethods([ - 'authenticate', - 'getBeforeWishlistUrl', - 'setBeforeWishlistUrl', - 'setBeforeWishlistRequest', - 'getBeforeWishlistRequest', - 'setBeforeRequestParams', - 'setBeforeModuleName', - 'setBeforeControllerName', - 'setBeforeAction', - ]) - ->getMock(); + ->setMethods( + [ + 'authenticate', + 'getBeforeWishlistUrl', + 'setBeforeWishlistUrl', + 'setBeforeWishlistRequest', + 'getBeforeWishlistRequest', + 'setBeforeRequestParams', + 'setBeforeModuleName', + 'setBeforeControllerName', + 'setBeforeAction', + ] + )->getMock(); $this->authenticationState = $this->createMock(\Magento\Wishlist\Model\AuthenticationState::class); $this->config = $this->createMock(\Magento\Framework\App\Config::class); @@ -62,6 +69,9 @@ protected function setUp() $this->request = $this->createMock(\Magento\Framework\App\Request\Http::class); } + /** + * @inheritdoc + */ protected function tearDown() { unset( @@ -96,6 +106,7 @@ public function testBeforeDispatch() $refererUrl = 'http://referer-url.com'; $params = [ 'product' => 1, + 'login' => [], ]; $actionFlag = $this->createMock(\Magento\Framework\App\ActionFlag::class); @@ -139,7 +150,7 @@ public function testBeforeDispatch() ->willReturnSelf(); $this->customerSession->expects($this->once()) ->method('setBeforeWishlistRequest') - ->with($params) + ->with(['product' => 1]) ->willReturnSelf(); $this->customerSession->expects($this->once()) ->method('getBeforeWishlistRequest') diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php new file mode 100644 index 0000000000000..4c8937e1c6e9a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php @@ -0,0 +1,71 @@ +customerSession = $this->_objectManager->get(CustomerSession::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->customerSession->logout(); + $this->customerSession = null; + parent::tearDown(); + } + + /** + * Test for adding product to wishlist with invalidate credentials + * + * @return void + * @magentoDataFixture Magento/Catalog/_files/product_simple_xss.php + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoAppArea frontend + */ + public function testAddActionProductWithInvalidCredentials(): void + { + $this->getRequest()->setPostValue( + [ + 'login' => [ + 'username' => 'invalidCustomer@example.com', + 'password' => 'invalidPassword', + ], + ] + ); + + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->_objectManager->get(ProductRepositoryInterface::class); + + $product = $productRepository->get('product-with-xss'); + + $this->dispatch('wishlist/index/add/product/' . $product->getId() . '?nocookie=1'); + + $this->assertArrayNotHasKey('login', $this->customerSession->getBeforeWishlistRequest()); + } +} From cc3ce3d72904007b5d6b251f526f587cf0d4e83a Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 6 Jun 2019 10:40:36 -0500 Subject: [PATCH 084/372] MC-16114: Update Email Template Filter --- lib/internal/Magento/Framework/Filter/Template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 1bb063fb279a6..0515b60cc3165 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -417,7 +417,7 @@ private function validateVariableMethodCall($object, string $method): void } else { foreach ($this->restrictedMethodsByInstanceType as $instanceType => $restrictedMethods) { if ($object instanceof $instanceType && - ($restrictedMethods === '*' || in_array(mb_strtolower($method), $restrictedMethods)) + (in_array('*', $restrictedMethods) || in_array(mb_strtolower($method), $restrictedMethods)) ) { throw new \InvalidArgumentException("Method $method cannot be called from template."); } From 8b623dbea0ffeeca7ce698e5b5e7d76b95f0916f Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Thu, 6 Jun 2019 11:28:55 -0500 Subject: [PATCH 085/372] MC-15919: Customer attribute label update - Updated meta data resolver object --- .../Magento/Customer/Model/AttributeMetadataResolver.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php index 84162bb8dae09..a41d52cdc45a4 100644 --- a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php +++ b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php @@ -113,7 +113,12 @@ public function getAttributesMeta( // use getDataUsingMethod, since some getters are defined and apply additional processing of returning value foreach (self::$metaProperties as $metaName => $origName) { $value = $attribute->getDataUsingMethod($origName); - $meta['arguments']['data']['config'][$metaName] = ($metaName === 'label') ? __($value) : $value; + if ($metaName === 'label') { + $meta['arguments']['data']['config'][$metaName] = __($value); + $meta['arguments']['data']['config']['__disableTmpl'] = [$metaName => true]; + } else { + $meta['arguments']['data']['config'][$metaName] = $value; + } if ('frontend_input' === $origName) { $meta['arguments']['data']['config']['formElement'] = self::$formElement[$value] ?? $value; } @@ -144,7 +149,6 @@ public function getAttributesMeta( $attribute, $meta['arguments']['data']['config'] ); - $meta['arguments']['data']['config']['__disableTmpl'] = true; return $meta; } From 3d19d0f53aa7ed2903ae9170bac92046ec061348 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Thu, 6 Jun 2019 15:41:17 -0500 Subject: [PATCH 086/372] MC-16963: Admin panel Design Configuration changes logs are missing --- .../Magento/Theme/Model/Design/BackendModelFactory.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Theme/Model/Design/BackendModelFactory.php b/app/code/Magento/Theme/Model/Design/BackendModelFactory.php index 2896e9f101298..df4ad381ca0d8 100644 --- a/app/code/Magento/Theme/Model/Design/BackendModelFactory.php +++ b/app/code/Magento/Theme/Model/Design/BackendModelFactory.php @@ -3,6 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +declare(strict_types=1); + namespace Magento\Theme\Model\Design; use Magento\Framework\App\Config\Value; @@ -81,8 +84,11 @@ public function create(array $data = []) $backendModel = $this->getNewBackendModel($backendType, $backendModelData); $backendModel->setValue($data['value']); - foreach ($storedData as $key => $value) { - $backendModel->setOrigData($key, $value); + if ($storedData) { + foreach ($storedData as $key => $value) { + $backendModel->setOrigData($key, $value); + } + $backendModel->setOrigData('field_config', $data['config']); } return $backendModel; From bd051c49790daa6756c1d9645d5d58f93811b714 Mon Sep 17 00:00:00 2001 From: Joan He Date: Fri, 7 Jun 2019 14:41:46 -0500 Subject: [PATCH 087/372] MC-15973: Incorrect ImportExport file handling --- app/code/Magento/ImportExport/Model/Import.php | 8 +++++++- .../Controller/Adminhtml/Import/ValidateTest.php | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index c8a5921b41b12..d29bf29dd50af 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -568,9 +568,15 @@ public function uploadSource() $entity = $this->getEntity(); /** @var $uploader Uploader */ $uploader = $this->_uploaderFactory->create(['fileId' => self::FIELD_NAME_SOURCE_FILE]); + $uploader->setAllowedExtensions(['csv', 'zip']); $uploader->skipDbProcessing(true); $fileName = $this->random->getRandomString(32) . '.' . $uploader->getFileExtension(); - $result = $uploader->save($this->getWorkingDir(), $fileName); + try { + $result = $uploader->save($this->getWorkingDir(), $fileName); + } catch (\Exception $e) { + throw new LocalizedException(__('The file cannot be uploaded.')); + } + // phpcs:disable Magento2.Functions.DiscouragedFunction.Discouraged $extension = pathinfo($result['file'], PATHINFO_EXTENSION); diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php index a3cf42b48489f..d9a758b549667 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php @@ -93,7 +93,7 @@ public function validationDataProvider(): array [ 'file_name' => 'test.txt', 'mime-type' => 'text/csv', - 'message' => '\'txt\' file extension is not supported', + 'message' => 'The file cannot be uploaded.', 'delimiter' => ',', ], [ From 57645ff1df01e3ddb467d30750d3c6957b26fc7f Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 10 Jun 2019 11:15:29 -0500 Subject: [PATCH 088/372] MC-17305: Product Form Update. --- .../Catalog/view/frontend/templates/product/view/form.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml index 8d298aec9f1cb..e201877b47cce 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml @@ -22,7 +22,7 @@ - + getBlockHtml('formkey') ?> getChildHtml('form_top') ?> hasOptions()) :?> From 58836f072898c63edb8fa4afa9670570aca3beb8 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Tue, 11 Jun 2019 10:03:33 -0500 Subject: [PATCH 089/372] MC-15972: File uploads --- .../Model/Product/Gallery/Processor.php | 18 +++--- .../Model/ResourceModel/File/Storage/File.php | 39 +++++++++--- .../ResourceModel/File/Storage/FileTest.php | 34 +++++++++- .../Framework/File/Test/Unit/UploaderTest.php | 63 +++++++++++++++++++ .../Magento/Framework/File/Uploader.php | 56 ++++++++++------- 5 files changed, 169 insertions(+), 41 deletions(-) create mode 100644 lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index e1b788bc3941b..f1d27c38e9456 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -167,10 +167,10 @@ public function addImage( } $fileName = \Magento\MediaStorage\Model\File\Uploader::getCorrectFileName($pathinfo['basename']); - $dispretionPath = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName); - $fileName = $dispretionPath . '/' . $fileName; + $dispersionPath = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName); + $fileName = $dispersionPath . '/' . $fileName; - $fileName = $this->getNotDuplicatedFilename($fileName, $dispretionPath); + $fileName = $this->getNotDuplicatedFilename($fileName, $dispersionPath); $destinationFile = $this->mediaConfig->getTmpMediaPath($fileName); @@ -465,27 +465,27 @@ protected function getUniqueFileName($file, $forTmp = false) * Get filename which is not duplicated with other files in media temporary and media directories * * @param string $fileName - * @param string $dispretionPath + * @param string $dispersionPath * @return string * @since 101.0.0 */ - protected function getNotDuplicatedFilename($fileName, $dispretionPath) + protected function getNotDuplicatedFilename($fileName, $dispersionPath) { - $fileMediaName = $dispretionPath . '/' + $fileMediaName = $dispersionPath . '/' . \Magento\MediaStorage\Model\File\Uploader::getNewFileName($this->mediaConfig->getMediaPath($fileName)); - $fileTmpMediaName = $dispretionPath . '/' + $fileTmpMediaName = $dispersionPath . '/' . \Magento\MediaStorage\Model\File\Uploader::getNewFileName($this->mediaConfig->getTmpMediaPath($fileName)); if ($fileMediaName != $fileTmpMediaName) { if ($fileMediaName != $fileName) { return $this->getNotDuplicatedFilename( $fileMediaName, - $dispretionPath + $dispersionPath ); } elseif ($fileTmpMediaName != $fileName) { return $this->getNotDuplicatedFilename( $fileTmpMediaName, - $dispretionPath + $dispersionPath ); } } diff --git a/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php b/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php index 8dfce40419b4a..b847b4c13adfc 100644 --- a/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php +++ b/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php @@ -6,12 +6,20 @@ namespace Magento\MediaStorage\Model\ResourceModel\File\Storage; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Filesystem\Io\File as FileIo; +use Magento\Framework\App\ObjectManager; /** * Class File */ class File { + /** + * @var FileIo + */ + private $fileIo; + /** * @var \Magento\Framework\Filesystem */ @@ -25,11 +33,16 @@ class File /** * @param \Magento\Framework\Filesystem $filesystem * @param \Psr\Log\LoggerInterface $log + * @param FileIo $fileIo */ - public function __construct(\Magento\Framework\Filesystem $filesystem, \Psr\Log\LoggerInterface $log) - { + public function __construct( + \Magento\Framework\Filesystem $filesystem, + \Psr\Log\LoggerInterface $log, + FileIo $fileIo = null + ) { $this->_logger = $log; $this->_filesystem = $filesystem; + $this->fileIo = $fileIo ?? ObjectManager::getInstance()->get(FileIo::class); } /** @@ -45,14 +58,15 @@ public function getStorageData($dir = '/') $directoryInstance = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); if ($directoryInstance->isDirectory($dir)) { foreach ($directoryInstance->readRecursively($dir) as $path) { - $itemName = basename($path); + $pathInfo = $this->fileIo->getPathInfo($path); + $itemName = $pathInfo['basename']; if ($itemName == '.svn' || $itemName == '.htaccess') { continue; } if ($directoryInstance->isDirectory($path)) { $directories[] = [ 'name' => $itemName, - 'path' => dirname($path) == '.' ? '/' : dirname($path), + 'path' => $pathInfo['dirname'] === '.' ? '/' : $pathInfo['dirname'], ]; } else { $files[] = $path; @@ -64,7 +78,7 @@ public function getStorageData($dir = '/') } /** - * Clear files and directories in storage + * Clear all files in storage $dir * * @param string $dir * @return $this @@ -73,8 +87,17 @@ public function clear($dir = '') { $directoryInstance = $this->_filesystem->getDirectoryWrite(DirectoryList::MEDIA); if ($directoryInstance->isDirectory($dir)) { - foreach ($directoryInstance->read($dir) as $path) { - $directoryInstance->delete($path); + $paths = $directoryInstance->readRecursively($dir); + foreach ($paths as $path) { + if ($directoryInstance->isDirectory()) { + continue; + } + + $pathInfo = $this->fileIo->getPathInfo($path); + + if ($pathInfo['basename'] !== '.htaccess') { + $directoryInstance->delete($path); + } } } @@ -127,7 +150,7 @@ public function saveFile($filePath, $content, $overwrite = false) } } catch (\Magento\Framework\Exception\FileSystemException $e) { $this->_logger->info($e->getMessage()); - throw new \Magento\Framework\Exception\LocalizedException(__('Unable to save file: %1', $filePath)); + throw new LocalizedException(__('Unable to save file: %1', $filePath)); } return false; diff --git a/app/code/Magento/MediaStorage/Test/Unit/Model/ResourceModel/File/Storage/FileTest.php b/app/code/Magento/MediaStorage/Test/Unit/Model/ResourceModel/File/Storage/FileTest.php index 97dffbe0e39a9..adc045cd0bed5 100644 --- a/app/code/Magento/MediaStorage/Test/Unit/Model/ResourceModel/File/Storage/FileTest.php +++ b/app/code/Magento/MediaStorage/Test/Unit/Model/ResourceModel/File/Storage/FileTest.php @@ -6,12 +6,18 @@ namespace Magento\MediaStorage\Test\Unit\Model\ResourceModel\File\Storage; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; /** * Class FileTest */ class FileTest extends \PHPUnit\Framework\TestCase { + /** + * @var \Magento\Framework\Filesystem\Io\File + */ + private $fileIoMock; + /** * @var \Magento\MediaStorage\Model\ResourceModel\File\Storage\File */ @@ -44,9 +50,17 @@ protected function setUp() ['isDirectory', 'readRecursively'] ); - $this->storageFile = new \Magento\MediaStorage\Model\ResourceModel\File\Storage\File( - $this->filesystemMock, - $this->loggerMock + $this->fileIoMock = $this->createPartialMock(\Magento\Framework\Filesystem\Io\File::class, ['getPathInfo']); + + $objectManager = new ObjectManager($this); + + $this->storageFile = $objectManager->getObject( + \Magento\MediaStorage\Model\ResourceModel\File\Storage\File::class, + [ + 'filesystem' => $this->filesystemMock, + 'log' => $this->loggerMock, + 'fileIo' => $this->fileIoMock + ] ); } @@ -98,6 +112,20 @@ public function testGetStorageData() 'folder_one/folder_two/.htaccess', 'folder_one/folder_two/file_two.txt', ]; + + $pathInfos = array_map( + function ($path) { + return [$path, pathinfo($path)]; + }, + $paths + ); + + $this->fileIoMock->expects( + $this->any() + )->method( + 'getPathInfo' + )->will($this->returnValueMap($pathInfos)); + sort($paths); $this->directoryReadMock->expects( $this->once() diff --git a/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php b/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php new file mode 100644 index 0000000000000..ac19f4dc36ed9 --- /dev/null +++ b/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php @@ -0,0 +1,63 @@ +expectException(\InvalidArgumentException::class); + } + + $this->assertEquals( + $expectedCorrectedFileName, + \Magento\Framework\File\Uploader::getCorrectFileName($fileName) + ); + } + + /** + * @return array + */ + public function getCorrectFileNameProvider() + { + return [ + [ + '^&*&^&*^$$$$()', + 'file.' + ], + [ + '^&*&^&*^$$$$().png', + 'file.png' + ], + [ + '_', + 'file.' + ], + [ + '_.jpg', + 'file.jpg' + ], + [ + 'a.' . str_repeat('b', 100), + true + ] + ]; + } +} diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index 328a748cfd5df..5396862195f88 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\File; +use Magento\Framework\Exception\FileSystemException; +use Magento\Framework\Validation\ValidationException; + /** * File upload class * @@ -75,7 +78,7 @@ class Uploader protected $_allowRenameFiles = false; /** - * If this variable is set to TRUE, files dispertion will be supported. + * If this variable is set to TRUE, files dispersion will be supported. * * @var bool * @access protected @@ -162,7 +165,7 @@ class Uploader * * @param string|array $fileId * @param \Magento\Framework\File\Mime|null $fileMime - * @throws \Exception + * @throws \DomainException */ public function __construct( $fileId, @@ -171,7 +174,7 @@ public function __construct( $this->_setUploadFileId($fileId); if (!file_exists($this->_file['tmp_name'])) { $code = empty($this->_file['tmp_name']) ? self::TMP_NAME_EMPTY : 0; - throw new \Exception('The file was not uploaded.', $code); + throw new \DomainException('The file was not uploaded.', $code); } else { $this->_fileExists = true; } @@ -256,7 +259,7 @@ public function save($destinationFolder, $newFileName = null) * * @param string $destinationFolder * @return void - * @throws \Exception + * @throws FileSystemException */ private function validateDestination($destinationFolder) { @@ -265,7 +268,7 @@ private function validateDestination($destinationFolder) } if (!is_writable($destinationFolder)) { - throw new \Exception('Destination folder is not writable or does not exists.'); + throw new FileSystemException(__('Destination folder is not writable or does not exists.')); } } @@ -302,7 +305,7 @@ protected function _moveFile($tmpPath, $destPath) * Validate file before save * * @return void - * @throws \Exception + * @throws ValidationException */ protected function _validateFile() { @@ -312,7 +315,7 @@ protected function _validateFile() //is file extension allowed if (!$this->checkAllowedExtension($this->getFileExtension())) { - throw new \Exception('Disallowed file type.'); + throw new ValidationException(__('Disallowed file type.')); } //run validate callbacks foreach ($this->_validateCallbacks as $params) { @@ -366,19 +369,27 @@ public function removeValidateCallback($callbackName) } /** - * Correct filename with special chars and spaces + * Correct filename with special chars and spaces; also trim excessively long filenames * * @param string $fileName * @return string + * @throws \InvalidArgumentException */ public static function getCorrectFileName($fileName) { $fileName = preg_replace('/[^a-z0-9_\\-\\.]+/i', '_', $fileName); $fileInfo = pathinfo($fileName); + $fileInfo['extension'] = $fileInfo['extension'] ?? ''; + + // account for excessively long filenames that cannot be stored completely in database + if (strlen($fileInfo['basename']) > 100) { + throw new \InvalidArgumentException('Filename is too long; must be 100 characters or less'); + } if (preg_match('/^_+$/', $fileInfo['filename'])) { $fileName = 'file.' . $fileInfo['extension']; } + return $fileName; } @@ -533,7 +544,8 @@ private function _getMimeType() * * @param string|array $fileId * @return void - * @throws \Exception + * @throws \DomainException + * @throws \InvalidArgumentException * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ private function _setUploadFileId($fileId) @@ -543,7 +555,7 @@ private function _setUploadFileId($fileId) $this->_file = $fileId; } else { if (empty($_FILES)) { - throw new \Exception('$_FILES array is empty'); + throw new \DomainException('$_FILES array is empty'); } preg_match("/^(.*?)\[(.*?)\]$/", $fileId, $file); @@ -565,7 +577,9 @@ private function _setUploadFileId($fileId) $this->_uploadType = self::SINGLE_STYLE; $this->_file = $_FILES[$fileId]; } elseif ($fileId == '') { - throw new \Exception('Invalid parameter given. A valid $_FILES[] identifier is expected.'); + throw new \InvalidArgumentException( + 'Invalid parameter given. A valid $_FILES[] identifier is expected.' + ); } } } @@ -575,7 +589,7 @@ private function _setUploadFileId($fileId) * * @param string $destinationFolder * @return \Magento\Framework\File\Uploader - * @throws \Exception + * @throws FileSystemException */ private function _createDestinationFolder($destinationFolder) { @@ -590,7 +604,7 @@ private function _createDestinationFolder($destinationFolder) if (!(@is_dir($destinationFolder) || @mkdir($destinationFolder, 0777, true) )) { - throw new \Exception("Unable to create directory '{$destinationFolder}'."); + throw new FileSystemException(__('Unable to create directory %1.', $destinationFolder)); } return $this; } @@ -620,7 +634,7 @@ public static function getNewFileName($destinationFile) } /** - * Get dispertion path + * Get dispersion path * * @param string $fileName * @return string @@ -632,7 +646,7 @@ public static function getDispretionPath($fileName) } /** - * Get dispertion path + * Get dispersion path * * @param string $fileName * @return string @@ -640,17 +654,17 @@ public static function getDispretionPath($fileName) public static function getDispersionPath($fileName) { $char = 0; - $dispertionPath = ''; + $dispersionPath = ''; while ($char < 2 && $char < strlen($fileName)) { - if (empty($dispertionPath)) { - $dispertionPath = '/' . ('.' == $fileName[$char] ? '_' : $fileName[$char]); + if (empty($dispersionPath)) { + $dispersionPath = '/' . ('.' == $fileName[$char] ? '_' : $fileName[$char]); } else { - $dispertionPath = self::_addDirSeparator( - $dispertionPath + $dispersionPath = self::_addDirSeparator( + $dispersionPath ) . ('.' == $fileName[$char] ? '_' : $fileName[$char]); } $char++; } - return $dispertionPath; + return $dispersionPath; } } From 1322bd3c5c2be9f2ed06b7fbeebd167735cf6016 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Tue, 11 Jun 2019 11:16:54 -0500 Subject: [PATCH 090/372] MC-16963: Admin panel Design Configuration changes logs are missing --- .../Magento/Theme/Model/Design/Config/ValueChecker.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php index 00f30e9d7976c..11d45616e387d 100644 --- a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php +++ b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php @@ -83,13 +83,11 @@ public function isDifferentFromDefault($value, $scope, $scopeId, array $fieldCon */ protected function isEqual($value, $defaultValue) { - // phpcs:ignore Magento2.Functions.DiscouragedFunction - switch (gettype($value)) { - case 'array': - return $this->isEqualArrays($value, $defaultValue); - default: - return $value === $defaultValue; + if (is_array($value)) { + return $this->isEqualArrays($value, $defaultValue); } + + return $value === $defaultValue; } /** From dc8786a27f9f2a789f926ce0757c663f6633bf53 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Tue, 11 Jun 2019 11:22:48 -0500 Subject: [PATCH 091/372] MC-17305: Product Form Update. Add int typecast. --- .../Catalog/view/frontend/templates/product/view/form.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml index e201877b47cce..7d59e9831e947 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml @@ -22,7 +22,7 @@ - + getBlockHtml('formkey') ?> getChildHtml('form_top') ?> hasOptions()) :?> From 0a0f3943777aa64c48a76ac37a64aa1657c3e88b Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Tue, 11 Jun 2019 13:20:07 -0500 Subject: [PATCH 092/372] MC-17065: Email error message - Resolved error message issue for inline editing customer --- .../Customer/Controller/Adminhtml/Index/InlineEdit.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 7220de0356817..599415bc7bb7c 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -70,8 +70,14 @@ class InlineEdit extends \Magento\Backend\App\Action implements HttpPostActionIn */ private $addressRegistry; + /** + * @var \Magento\Framework\Escaper + */ + private $escaper; + /** * @param Action\Context $context + * @param \Magento\Framework\Escaper $escaper * @param CustomerRepositoryInterface $customerRepository * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Customer\Model\Customer\Mapper $customerMapper @@ -86,6 +92,7 @@ public function __construct( \Magento\Customer\Model\Customer\Mapper $customerMapper, \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, \Psr\Log\LoggerInterface $logger, + \Magento\Framework\Escaper $escaper, AddressRegistry $addressRegistry = null ) { $this->customerRepository = $customerRepository; @@ -93,6 +100,7 @@ public function __construct( $this->customerMapper = $customerMapper; $this->dataObjectHelper = $dataObjectHelper; $this->logger = $logger; + $this->escaper = $escaper; $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class); parent::__construct($context); } @@ -315,7 +323,7 @@ protected function getCustomer() */ protected function getErrorWithCustomerId($errorText) { - return '[Customer ID: ' . $this->getCustomer()->getId() . '] ' . __($errorText); + return '[Customer ID: ' . $this->getCustomer()->getId() . '] ' . $this->escaper->escapeHtml(__($errorText)); } /** From 61c3ea0eda1e2b7cc4aa80a7f844c399b3a705cf Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Tue, 11 Jun 2019 15:40:42 -0500 Subject: [PATCH 093/372] MC-17065: Email error message - Resolved unit test failures --- .../Unit/Controller/Adminhtml/Index/InlineEditTest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index 45e64f6557d51..7d2db1cc16b01 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Model\EmailNotificationInterface; use Magento\Framework\DataObject; use Magento\Framework\Message\MessageInterface; +use Magento\Framework\Escaper; /** * Unit tests for Inline customer edit @@ -78,6 +79,9 @@ class InlineEditTest extends \PHPUnit\Framework\TestCase /** @var array */ private $items; + /** @var \Magento\Framework\Escaper */ + private $escaper; + /** * Sets up mocks * @@ -86,7 +90,7 @@ class InlineEditTest extends \PHPUnit\Framework\TestCase protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - + $this->escaper = new Escaper(); $this->request = $this->getMockForAbstractClass( \Magento\Framework\App\RequestInterface::class, [], @@ -172,7 +176,8 @@ protected function setUp() 'addressDataFactory' => $this->addressDataFactory, 'addressRepository' => $this->addressRepository, 'logger' => $this->logger, - 'addressRegistry' => $this->addressRegistry + 'escaper' => $this->escaper, + 'addressRegistry' => $this->addressRegistry, ] ); $reflection = new \ReflectionClass(get_class($this->controller)); @@ -365,6 +370,7 @@ public function testExecuteLocalizedException() ->method('save') ->with($this->customerData) ->willThrowException($exception); + $this->messageManager->expects($this->once()) ->method('addError') ->with('[Customer ID: 12] Exception message'); From 75180b57877fe3efdbce95722444c8c16a59f317 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Tue, 11 Jun 2019 15:42:38 -0500 Subject: [PATCH 094/372] MC-17065: Email error message - Updated implementation --- .../Customer/Controller/Adminhtml/Index/InlineEdit.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 599415bc7bb7c..7405269f8451d 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -242,10 +242,10 @@ protected function saveCustomer(CustomerInterface $customer) $this->disableAddressValidation($customer); $this->customerRepository->save($customer); } catch (\Magento\Framework\Exception\InputException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($e->getMessage())); + $this->getMessageManager()->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); $this->logger->critical($e); } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($e->getMessage())); + $this->getMessageManager()->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); $this->logger->critical($e); } catch (\Exception $e) { $this->getMessageManager()->addError($this->getErrorWithCustomerId('We can\'t save the customer.')); @@ -323,7 +323,7 @@ protected function getCustomer() */ protected function getErrorWithCustomerId($errorText) { - return '[Customer ID: ' . $this->getCustomer()->getId() . '] ' . $this->escaper->escapeHtml(__($errorText)); + return '[Customer ID: ' . $this->getCustomer()->getId() . '] ' . __($errorText); } /** From e3c99770eab38dc7da5041760b4156871ef4f92b Mon Sep 17 00:00:00 2001 From: Mark Berube Date: Wed, 12 Jun 2019 00:29:44 -0500 Subject: [PATCH 095/372] MC-15974: Fixing payment title. --- .../view/frontend/web/js/action/select-payment-method.js | 4 ++++ .../Ui/Component/Listing/Column/Method/Options.php | 9 +++++++++ .../Magento/Ui/view/base/web/js/grid/filters/filters.js | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js index 702df47526715..6bda10fceb7b9 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js @@ -12,6 +12,10 @@ define([ 'use strict'; return function (paymentMethod) { + paymentMethod.__disableTmpl = { + title: true + }; + quote.paymentMethod(paymentMethod); }; }); diff --git a/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php b/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php index fbf80de519f9f..71e0384c72f79 100644 --- a/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php +++ b/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Payment\Ui\Component\Listing\Column\Method; /** @@ -41,6 +42,14 @@ public function toOptionArray() if ($this->options === null) { $this->options = $this->paymentHelper->getPaymentMethodList(true, true); } + + array_walk( + $this->options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); + return $this->options; } } diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index c608400a6f174..78016ee489a11 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -274,7 +274,8 @@ define([ filter = utils.extend({}, filters.base, filter); //Accepting labels as is. filter.__disableTmpl = { - label: 1 + label: 1, + options: 1 }; filter = utils.template(filter, { From 3c9064feec8d18cc17503a0f1f3726afb8ac45b9 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 12 Jun 2019 10:16:33 -0500 Subject: [PATCH 096/372] MC-15972: File uploads --- .../MediaStorage/Model/ResourceModel/File/Storage/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php b/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php index b847b4c13adfc..8c9fe7b848fad 100644 --- a/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php +++ b/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php @@ -89,7 +89,7 @@ public function clear($dir = '') if ($directoryInstance->isDirectory($dir)) { $paths = $directoryInstance->readRecursively($dir); foreach ($paths as $path) { - if ($directoryInstance->isDirectory()) { + if ($directoryInstance->isDirectory($path)) { continue; } From fcc01ed7486aba33bc6380d3a3664cc30504682d Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Wed, 12 Jun 2019 10:44:43 -0500 Subject: [PATCH 097/372] MC-17065: Email error message - Resolved static test failures --- .../Controller/Adminhtml/Index/InlineEdit.php | 33 ++++++++++++------- .../Adminhtml/Index/InlineEditTest.php | 24 +++++++++----- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 7405269f8451d..77c9cbad07a1c 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -77,12 +77,12 @@ class InlineEdit extends \Magento\Backend\App\Action implements HttpPostActionIn /** * @param Action\Context $context - * @param \Magento\Framework\Escaper $escaper * @param CustomerRepositoryInterface $customerRepository * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Customer\Model\Customer\Mapper $customerMapper * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper * @param \Psr\Log\LoggerInterface $logger + * @param \Magento\Framework\Escaper $escaper * @param AddressRegistry|null $addressRegistry */ public function __construct( @@ -136,10 +136,14 @@ public function execute() $postItems = $this->getRequest()->getParam('items', []); if (!($this->getRequest()->getParam('isAjax') && count($postItems))) { - return $resultJson->setData([ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ]); + return $resultJson->setData( + [ + 'messages' => [ + __('Please correct the data sent.') + ], + 'error' => true, + ] + ); } foreach (array_keys($postItems) as $customerId) { @@ -155,10 +159,12 @@ public function execute() $this->getEmailNotification()->credentialsChanged($this->getCustomer(), $currentCustomer->getEmail()); } - return $resultJson->setData([ - 'messages' => $this->getErrorMessages(), - 'error' => $this->isErrorExists() - ]); + return $resultJson->setData( + [ + 'messages' => $this->getErrorMessages(), + 'error' => $this->isErrorExists() + ] + ); } /** @@ -242,13 +248,16 @@ protected function saveCustomer(CustomerInterface $customer) $this->disableAddressValidation($customer); $this->customerRepository->save($customer); } catch (\Magento\Framework\Exception\InputException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); + $this->getMessageManager() + ->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); $this->logger->critical($e); } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); + $this->getMessageManager() + ->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); $this->logger->critical($e); } catch (\Exception $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId('We can\'t save the customer.')); + $this->getMessageManager() + ->addError($this->getErrorWithCustomerId('We can\'t save the customer.')); $this->logger->critical($e); } } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index 7d2db1cc16b01..7fca556fc2cda 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -296,10 +296,14 @@ protected function prepareMocksForErrorMessagesProcessing() ->willReturn('Error text'); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => ['Error text'], - 'error' => true, - ]) + ->with( + [ + 'messages' => [ + 'Error text', + ], + 'error' => true, + ] + ) ->willReturnSelf(); } @@ -345,10 +349,14 @@ public function testExecuteWithoutItems() $this->resultJson ->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ]) + ->with( + [ + 'messages' => [ + __('Please correct the data sent.'), + ], + 'error' => true, + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); } From bfaab3775c93767d8b58dca6c27481d89c0822a8 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Wed, 12 Jun 2019 11:17:27 -0500 Subject: [PATCH 098/372] MC-17447: Update wishlist controller - Updated wishlist controller - Updated integration test for wishlist controller --- app/code/Magento/Wishlist/Controller/Index/Add.php | 5 ++++- .../Magento/Wishlist/Controller/Index/PluginTest.php | 1 + .../testsuite/Magento/Wishlist/Controller/IndexTest.php | 9 ++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Wishlist/Controller/Index/Add.php b/app/code/Magento/Wishlist/Controller/Index/Add.php index 5cb60905aea48..ad7ff670a9c5b 100644 --- a/app/code/Magento/Wishlist/Controller/Index/Add.php +++ b/app/code/Magento/Wishlist/Controller/Index/Add.php @@ -7,15 +7,18 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\App\Action; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Data\Form\FormKey\Validator; use Magento\Framework\Exception\NotFoundException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Controller\ResultFactory; /** + * Wish list Add controller + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Add extends \Magento\Wishlist\Controller\AbstractIndex +class Add extends \Magento\Wishlist\Controller\AbstractIndex implements HttpPostActionInterface { /** * @var \Magento\Wishlist\Controller\WishlistProviderInterface diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php index 4c8937e1c6e9a..5303c9f352b87 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php @@ -50,6 +50,7 @@ protected function tearDown() */ public function testAddActionProductWithInvalidCredentials(): void { + $this->getRequest()->setMethod('POST'); $this->getRequest()->setPostValue( [ 'login' => [ diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php index e020d31838f06..f43133c92fc3d 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php @@ -98,9 +98,12 @@ public function testAddActionProductNameXss() { /** @var \Magento\Framework\Data\Form\FormKey $formKey */ $formKey = $this->_objectManager->get(\Magento\Framework\Data\Form\FormKey::class); - $this->getRequest()->setPostValue([ - 'form_key' => $formKey->getFormKey(), - ]); + $this->getRequest()->setMethod('POST'); + $this->getRequest()->setPostValue( + [ + 'form_key' => $formKey->getFormKey(), + ] + ); /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() From f290df20014d522fcc395cc78e707743cb944d6a Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Wed, 12 Jun 2019 12:43:10 -0500 Subject: [PATCH 099/372] MC-17447: Update wishlist controller - Resolved static test failure --- app/code/Magento/Wishlist/Controller/Index/Add.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Wishlist/Controller/Index/Add.php b/app/code/Magento/Wishlist/Controller/Index/Add.php index ad7ff670a9c5b..3ed152cb84125 100644 --- a/app/code/Magento/Wishlist/Controller/Index/Add.php +++ b/app/code/Magento/Wishlist/Controller/Index/Add.php @@ -141,6 +141,7 @@ public function execute() 'referer' => $referer ] ); + // phpcs:disable Magento2.Exceptions.ThrowCatch } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addErrorMessage( __('We can\'t add the item to Wish List right now: %1.', $e->getMessage()) From b573a7a447287403cab785c6656345f95302a8f0 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Wed, 12 Jun 2019 14:21:34 -0500 Subject: [PATCH 100/372] MC-17065: Email error message - Resolved backward incompatibility issue --- .../Customer/Controller/Adminhtml/Index/InlineEdit.php | 8 ++++---- .../Unit/Controller/Adminhtml/Index/InlineEditTest.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 77c9cbad07a1c..eff812a65a3bb 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -82,8 +82,8 @@ class InlineEdit extends \Magento\Backend\App\Action implements HttpPostActionIn * @param \Magento\Customer\Model\Customer\Mapper $customerMapper * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper * @param \Psr\Log\LoggerInterface $logger - * @param \Magento\Framework\Escaper $escaper * @param AddressRegistry|null $addressRegistry + * @param \Magento\Framework\Escaper $escaper */ public function __construct( Action\Context $context, @@ -92,16 +92,16 @@ public function __construct( \Magento\Customer\Model\Customer\Mapper $customerMapper, \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, \Psr\Log\LoggerInterface $logger, - \Magento\Framework\Escaper $escaper, - AddressRegistry $addressRegistry = null + AddressRegistry $addressRegistry = null, + \Magento\Framework\Escaper $escaper = null ) { $this->customerRepository = $customerRepository; $this->resultJsonFactory = $resultJsonFactory; $this->customerMapper = $customerMapper; $this->dataObjectHelper = $dataObjectHelper; $this->logger = $logger; - $this->escaper = $escaper; $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class); + $this->escaper = $escaper ?: ObjectManager::getInstance()->get(\Magento\Framework\Escaper::class); parent::__construct($context); } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index 7fca556fc2cda..8267624f7b006 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -176,8 +176,8 @@ protected function setUp() 'addressDataFactory' => $this->addressDataFactory, 'addressRepository' => $this->addressRepository, 'logger' => $this->logger, - 'escaper' => $this->escaper, 'addressRegistry' => $this->addressRegistry, + 'escaper' => $this->escaper, ] ); $reflection = new \ReflectionClass(get_class($this->controller)); From 592d49b5de426c89a819818fedf0b7f6f5f1e13f Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Wed, 12 Jun 2019 16:26:16 -0500 Subject: [PATCH 101/372] MC-16284: Visible message alert --- .../view/base/web/js/form/element/file-uploader.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js index f28569caa0053..f4b267758cf1d 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js @@ -427,7 +427,8 @@ define([ _.each(this.aggregatedErrors, function (error) { notification().add({ error: true, - message: '%s' + error.message, // %s to be used as placeholder for html injection + // %s to be used as placeholders for html injection + message: '%s' + error.filename + '%s ' + $t('was not uploaded.') + '%s' + error.message, /** * Adds constructed error notification to aggregatedErrorMessages @@ -435,12 +436,11 @@ define([ * @param {String} constructedMessage */ insertMethod: function (constructedMessage) { - var errorMsgBodyHtml = '%s %s.
' - .replace('%s', error.filename) - .replace('%s', $t('was not uploaded')); - // html is escaped in message body for notification widget; prepend unescaped html here - constructedMessage = constructedMessage.replace('%s', errorMsgBodyHtml); + constructedMessage = constructedMessage + .replace('%s', '') + .replace('%s', '') + .replace('%s', '
'); aggregatedErrorMessages.push(constructedMessage); } From 61b0be7ba66cfff980022246039767782f033b19 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 13 Jun 2019 15:07:31 -0500 Subject: [PATCH 102/372] MC-15972: File uploads --- .../Magento/Framework/File/Test/Unit/UploaderTest.php | 6 +++++- lib/internal/Magento/Framework/File/Uploader.php | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php b/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php index ac19f4dc36ed9..d0aa658184457 100644 --- a/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php +++ b/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php @@ -55,7 +55,11 @@ public function getCorrectFileNameProvider() 'file.jpg' ], [ - 'a.' . str_repeat('b', 100), + 'a.' . str_repeat('b', 88), + 'a.' . str_repeat('b', 88) + ], + [ + 'a.' . str_repeat('b', 89), true ] ]; diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index 5396862195f88..af19c619ae68f 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -382,8 +382,8 @@ public static function getCorrectFileName($fileName) $fileInfo['extension'] = $fileInfo['extension'] ?? ''; // account for excessively long filenames that cannot be stored completely in database - if (strlen($fileInfo['basename']) > 100) { - throw new \InvalidArgumentException('Filename is too long; must be 100 characters or less'); + if (strlen($fileInfo['basename']) > 90) { + throw new \InvalidArgumentException('Filename is too long; must be 90 characters or less'); } if (preg_match('/^_+$/', $fileInfo['filename'])) { From 6786439ab125a564c2a8ba50b0f8387c26f7c486 Mon Sep 17 00:00:00 2001 From: DianaRusin Date: Fri, 14 Jun 2019 09:45:11 +0300 Subject: [PATCH 103/372] MC-16042: Zip archive validation --- lib/internal/Magento/Framework/Archive/Zip.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index c41f8b28ce348..925adda48504c 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -54,6 +54,7 @@ public function unpack($source, $destination) $zip = new \ZipArchive(); if ($zip->open($source) === true) { $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); + $filename = $this->filterExcludedFiles($filename); if ($filename) { $zip->extractTo(dirname($destination), $filename); rename(dirname($destination).'/'.$filename, $destination); @@ -82,4 +83,19 @@ private function filterRelativePaths(string $path): string return $path; } + + /** + * Filter excluded files. + * + * @param string $file + * @return string + */ + private function filterExcludedFiles(string $file): string + { + if ($file && preg_match('/^\.htaccess$/', $file)) { + $file = ''; + } + + return $file; + } } From 6c7c45103cc2aeb4f6c51cb5b266c85cb024d80c Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Fri, 14 Jun 2019 15:56:52 +0300 Subject: [PATCH 104/372] MC-17303: Customer login fix --- app/code/Magento/Customer/Controller/Account/LoginPost.php | 2 +- app/code/Magento/Customer/Controller/Ajax/Login.php | 2 +- app/code/Magento/Customer/Model/Plugin/CustomerNotification.php | 2 +- app/code/Magento/Customer/Model/Session.php | 2 +- app/code/Magento/Rss/Controller/Feed.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 04051fbbf366b..9afaab4121644 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -182,8 +182,8 @@ public function execute() if (!empty($login['username']) && !empty($login['password'])) { try { $customer = $this->customerAccountManagement->authenticate($login['username'], $login['password']); - $this->session->setCustomerDataAsLoggedIn($customer); $this->session->regenerateId(); + $this->session->setCustomerDataAsLoggedIn($customer); if ($this->getCookieManager()->getCookie('mage-cache-sessid')) { $metadata = $this->getCookieMetadataFactory()->createCookieMetadata(); $metadata->setPath('/'); diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php index 5049c83e60f35..d5425bfc27332 100644 --- a/app/code/Magento/Customer/Controller/Ajax/Login.php +++ b/app/code/Magento/Customer/Controller/Ajax/Login.php @@ -190,8 +190,8 @@ public function execute() $credentials['username'], $credentials['password'] ); - $this->customerSession->setCustomerDataAsLoggedIn($customer); $this->customerSession->regenerateId(); + $this->customerSession->setCustomerDataAsLoggedIn($customer); $redirectRoute = $this->getAccountRedirect()->getRedirectCookie(); if ($this->cookieManager->getCookie('mage-cache-sessid')) { $metadata = $this->cookieMetadataFactory->createCookieMetadata(); diff --git a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php index 517aef5690ee6..9b655fc843529 100644 --- a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php +++ b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php @@ -82,10 +82,10 @@ public function beforeDispatch(AbstractAction $subject, RequestInterface $reques ) ) { try { + $this->session->regenerateId(); $customer = $this->customerRepository->getById($customerId); $this->session->setCustomerData($customer); $this->session->setCustomerGroupId($customer->getGroupId()); - $this->session->regenerateId(); $this->notificationStorage->remove(NotificationStorage::UPDATE_CUSTOMER_SESSION, $customer->getId()); } catch (NoSuchEntityException $e) { $this->logger->error($e); diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php index 5900fed218edf..c37a28d04fc52 100644 --- a/app/code/Magento/Customer/Model/Session.php +++ b/app/code/Magento/Customer/Model/Session.php @@ -412,10 +412,10 @@ public function checkCustomerId($customerId) */ public function setCustomerAsLoggedIn($customer) { + $this->regenerateId(); $this->setCustomer($customer); $this->_eventManager->dispatch('customer_login', ['customer' => $customer]); $this->_eventManager->dispatch('customer_data_object_login', ['customer' => $this->getCustomerDataObject()]); - $this->regenerateId(); return $this; } diff --git a/app/code/Magento/Rss/Controller/Feed.php b/app/code/Magento/Rss/Controller/Feed.php index 8fbe7addb560d..634540dde5d96 100644 --- a/app/code/Magento/Rss/Controller/Feed.php +++ b/app/code/Magento/Rss/Controller/Feed.php @@ -84,8 +84,8 @@ protected function auth() list($login, $password) = $this->httpAuthentication->getCredentials(); try { $customer = $this->customerAccountManagement->authenticate($login, $password); - $this->customerSession->setCustomerDataAsLoggedIn($customer); $this->customerSession->regenerateId(); + $this->customerSession->setCustomerDataAsLoggedIn($customer); } catch (\Exception $e) { $this->logger->critical($e); } From 5e4f83b39c41d32416886a7a794a8c2315a5810c Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Fri, 7 Jun 2019 13:18:57 -0500 Subject: [PATCH 105/372] MC-16724: Prevent errors from incorrect import data --- .../Model/Import/Product.php | 3 + .../Import/Product/Validator/LayoutUpdate.php | 85 +++++++++++++++ .../Validator/LayoutUpdatePermissions.php | 81 ++++++++++++++ .../Validator/LayoutUpdatePermissionsTest.php | 101 ++++++++++++++++++ .../Product/Validator/LayoutUpdateTest.php | 97 +++++++++++++++++ .../Magento/CatalogImportExport/composer.json | 3 +- .../Magento/CatalogImportExport/etc/di.xml | 7 ++ .../LayoutUpdate/PermissionsValidatorTest.php | 101 ++++++++++++++++++ app/etc/di.xml | 10 ++ .../Model/Import/ProductTest.php | 21 ++++ .../Unit/ValidationState/ConfigurableTest.php | 30 ++++++ .../Config/ValidationState/Configurable.php | 38 +++++++ 12 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdate.php create mode 100644 app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php create mode 100644 app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php create mode 100644 app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdateTest.php create mode 100644 app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php create mode 100644 lib/internal/Magento/Framework/Config/Test/Unit/ValidationState/ConfigurableTest.php create mode 100644 lib/internal/Magento/Framework/Config/ValidationState/Configurable.php diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 0b7fbaf86826b..036bd5de0fb27 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -301,6 +301,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually', ValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES => 'Value for multiselect attribute %s contains duplicated values', 'invalidNewToDateValue' => 'Make sure new_to_date is later than or the same as new_from_date', + 'invalidLayoutUpdate' => 'Invalid layout update', + 'insufficientPermissions' => 'You do not have permissions to update "%s"', ]; //@codingStandardsIgnoreEnd @@ -1508,6 +1510,7 @@ public function getImagesFromRow(array $rowData) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @SuppressWarnings(PHPMD.UnusedLocalVariable) * @throws LocalizedException + * phpcs:disable Generic.Metrics.NestingLevel.TooHigh */ protected function _saveProducts() { diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdate.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdate.php new file mode 100644 index 0000000000000..99919628518c6 --- /dev/null +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdate.php @@ -0,0 +1,85 @@ +layoutValidatorFactory = $layoutValidatorFactory; + $this->validationState = $validationState; + } + + /** + * @inheritdoc + */ + public function isValid($value): bool + { + if (!empty($value['custom_layout_update']) && !$this->validateXml($value['custom_layout_update'])) { + $this->_addMessages( + [ + $this->context->retrieveMessageTemplate(self::ERROR_INVALID_LAYOUT_UPDATE) + ] + ); + return false; + } + + return true; + } + + /** + * Validate XML layout update + * + * @param string $xml + * @return bool + */ + private function validateXml(string $xml): bool + { + /** @var $layoutXmlValidator \Magento\Framework\View\Model\Layout\Update\Validator */ + $layoutXmlValidator = $this->layoutValidatorFactory->create( + [ + 'validationState' => $this->validationState, + ] + ); + + try { + if (!$layoutXmlValidator->isValid($xml)) { + return false; + } + } catch (\Exception $e) { + return false; + } + + return true; + } +} diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php new file mode 100644 index 0000000000000..d1df04b8e95c8 --- /dev/null +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php @@ -0,0 +1,81 @@ +userContext = $userContext; + $this->authorization = $authorization; + } + + /** + * Validate that the current user is allowed to make design updates + * + * @param array $data + * @return boolean + */ + public function isValid($data): bool + { + if (empty($data['custom_layout_update'])) { + return true; + } + + $userType = $this->userContext->getUserType(); + $isValid = in_array($userType, $this->allowedUserTypes) + && $this->authorization->isAllowed('Magento_Catalog::edit_product_design'); + + if (!$isValid) { + $this->_addMessages( + [ + sprintf( + $this->context->retrieveMessageTemplate(self::ERROR_INSUFFICIENT_PERMISSIONS), + 'custom_layout_update' + ) + ] + ); + } + + return $isValid; + } +} diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php new file mode 100644 index 0000000000000..2f883b5f4146b --- /dev/null +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php @@ -0,0 +1,101 @@ +userContext = $this->createMock(UserContextInterface::class); + $this->authorization = $this->createMock(AuthorizationInterface::class); + $this->context = $this->createMock(Product::class); + $this->context + ->method('retrieveMessageTemplate') + ->with('insufficientPermissions') + ->willReturn('oh no "%s"'); + $this->validator = new LayoutUpdatePermissions( + $this->userContext, + $this->authorization + ); + $this->validator->init($this->context); + } + + /** + * @param $value + * @param $userContext + * @param $isAllowed + * @param $isValid + * @dataProvider configurationsProvider + */ + public function testValidationConfiguration($value, $userContext, $isAllowed, $isValid) + { + $this->userContext + ->method('getUserType') + ->willReturn($userContext); + + $this->authorization + ->method('isAllowed') + ->with('Magento_Catalog::edit_product_design') + ->willReturn($isAllowed); + + $result = $this->validator->isValid(['custom_layout_update' => $value]); + $messages = $this->validator->getMessages(); + + self::assertSame($isValid, $result); + + if ($isValid) { + self::assertSame([], $messages); + } else { + self::assertSame(['oh no "custom_layout_update"'], $messages); + } + } + + public function configurationsProvider() + { + return [ + ['', null, null, true], + [null, null, null, true], + ['foo', UserContextInterface::USER_TYPE_ADMIN, true, true], + ['foo', UserContextInterface::USER_TYPE_INTEGRATION, true, true], + ['foo', UserContextInterface::USER_TYPE_ADMIN, false, false], + ['foo', UserContextInterface::USER_TYPE_INTEGRATION, false, false], + ['foo', 'something', null, false], + ]; + } +} diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdateTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdateTest.php new file mode 100644 index 0000000000000..d1e8b879f6a08 --- /dev/null +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdateTest.php @@ -0,0 +1,97 @@ +createMock(ValidatorFactory::class); + $validationState = $this->createMock(ValidationStateInterface::class); + $this->layoutValidator = $this->createMock(Validator::class); + $validatorFactory->method('create') + ->with(['validationState' => $validationState]) + ->willReturn($this->layoutValidator); + + $this->validator = new LayoutUpdate( + $validatorFactory, + $validationState + ); + } + + public function testValidationIsSkippedWithDataNotPresent() + { + $this->layoutValidator + ->expects($this->never()) + ->method('isValid'); + + $result = $this->validator->isValid([]); + self::assertTrue($result); + } + + public function testValidationFailsProperly() + { + $this->layoutValidator + ->method('isValid') + ->with('foo') + ->willReturn(false); + + $contextMock = $this->createMock(Product::class); + $contextMock + ->method('retrieveMessageTemplate') + ->with('invalidLayoutUpdate') + ->willReturn('oh no'); + $this->validator->init($contextMock); + + $result = $this->validator->isValid(['custom_layout_update' => 'foo']); + $messages = $this->validator->getMessages(); + self::assertFalse($result); + self::assertSame(['oh no'], $messages); + } + + public function testInvalidDataException() + { + $this->layoutValidator + ->method('isValid') + ->willThrowException(new \Exception('foo')); + + $contextMock = $this->createMock(Product::class); + $contextMock + ->method('retrieveMessageTemplate') + ->with('invalidLayoutUpdate') + ->willReturn('oh no'); + $this->validator->init($contextMock); + + $result = $this->validator->isValid(['custom_layout_update' => 'foo']); + $messages = $this->validator->getMessages(); + self::assertFalse($result); + self::assertSame(['oh no'], $messages); + } +} diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index 56307a01e1cb6..a15c1d5e7b220 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -16,7 +16,8 @@ "magento/module-import-export": "*", "magento/module-media-storage": "*", "magento/module-store": "*", - "magento/module-tax": "*" + "magento/module-tax": "*", + "magento/module-authorization": "*" }, "type": "magento2-module", "license": [ diff --git a/app/code/Magento/CatalogImportExport/etc/di.xml b/app/code/Magento/CatalogImportExport/etc/di.xml index 6906272b11d68..4e2fe390e0b17 100644 --- a/app/code/Magento/CatalogImportExport/etc/di.xml +++ b/app/code/Magento/CatalogImportExport/etc/di.xml @@ -25,7 +25,14 @@ Magento\CatalogImportExport\Model\Import\Product\Validator\Website Magento\CatalogImportExport\Model\Import\Product\Validator\Weight Magento\CatalogImportExport\Model\Import\Product\Validator\Quantity + Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdate + Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdatePermissions
+ + + Magento\Framework\Config\ValidationState\Required + + diff --git a/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php new file mode 100644 index 0000000000000..1bb2037462f3b --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php @@ -0,0 +1,101 @@ +userContext = $this->createMock(UserContextInterface::class); + $this->authorization = $this->createMock(AuthorizationInterface::class); + $this->context = $this->createMock(Product::class); + $this->context + ->method('retrieveMessageTemplate') + ->with('insufficientPermissions') + ->willReturn('oh no "%s"'); + $this->validator = new LayoutUpdatePermissions( + $this->userContext, + $this->authorization + ); + $this->validator->init($this->context); + } + + /** + * @param $value + * @param $userContext + * @param $isAllowed + * @param $isValid + * @dataProvider configurationsProvider + */ + public function testValidationConfiguration($value, $userContext, $isAllowed, $isValid) + { + $this->userContext + ->method('getUserType') + ->willReturn($userContext); + + $this->authorization + ->method('isAllowed') + ->with('Magento_Catalog::edit_product_design') + ->willReturn($isAllowed); + + $result = $this->validator->isValid(['custom_layout_update' => $value]); + $messages = $this->validator->getMessages(); + + self::assertSame($isValid, $result); + + if ($isValid) { + self::assertSame([], $messages); + } else { + self::assertSame(['oh no "custom_layout_update"'], $messages); + } + } + + public function configurationsProvider() + { + return [ + ['', null, null, true], + [null, null, null, true], + ['foo', UserContextInterface::USER_TYPE_ADMIN, true, true], + ['foo', UserContextInterface::USER_TYPE_INTEGRATION, true, true], + ['foo', UserContextInterface::USER_TYPE_ADMIN, false, false], + ['foo', UserContextInterface::USER_TYPE_INTEGRATION, false, false], + ['foo', 'something', null, false], + ]; + } +} diff --git a/app/etc/di.xml b/app/etc/di.xml index cccae25b467eb..5c10216ba757d 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1500,6 +1500,16 @@ + + + true + + + + + false + + urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 41cd85e6ec2f6..4863aadfac0c9 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -95,6 +95,7 @@ protected function tearDown() try { $product = $productRepository->get($productSku, false, null, true); $productRepository->delete($product); + // phpcs:disable Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (NoSuchEntityException $e) { // nothing to delete } @@ -2335,6 +2336,8 @@ public function testImportImageForNonDefaultStore() */ public function testProductsWithMultipleStoresWhenMediaIsDisabled(): void { + $this->loginAdminUserWithUsername(\Magento\TestFramework\Bootstrap::ADMIN_NAME); + $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); $source = $this->objectManager->create( @@ -2417,4 +2420,22 @@ private function importFile(string $fileName): void $this->_model->importData(); } + + /** + * Set the current admin session user based on a username + * + * @param string $username + */ + private function loginAdminUserWithUsername(string $username) + { + $user = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\User\Model\User::class + )->loadByUsername($username); + + /** @var $session \Magento\Backend\Model\Auth\Session */ + $session = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Backend\Model\Auth\Session::class + ); + $session->setUser($user); + } } diff --git a/lib/internal/Magento/Framework/Config/Test/Unit/ValidationState/ConfigurableTest.php b/lib/internal/Magento/Framework/Config/Test/Unit/ValidationState/ConfigurableTest.php new file mode 100644 index 0000000000000..cbd9e43632489 --- /dev/null +++ b/lib/internal/Magento/Framework/Config/Test/Unit/ValidationState/ConfigurableTest.php @@ -0,0 +1,30 @@ +isValidationRequired()); + } + + public function testFalse() + { + $state = new Configurable(false); + self::assertFalse($state->isValidationRequired()); + } +} diff --git a/lib/internal/Magento/Framework/Config/ValidationState/Configurable.php b/lib/internal/Magento/Framework/Config/ValidationState/Configurable.php new file mode 100644 index 0000000000000..c996b2a3e135d --- /dev/null +++ b/lib/internal/Magento/Framework/Config/ValidationState/Configurable.php @@ -0,0 +1,38 @@ +required = $required; + } + + /** + * @inheritdoc + */ + public function isValidationRequired(): bool + { + return $this->required; + } +} From 13e06bd99ac2056a623a13621357e9a49afd993a Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Fri, 14 Jun 2019 14:30:58 -0500 Subject: [PATCH 106/372] MC-16118: Email template name config update - Updated email option array value --- .../Magento/Config/Model/Config/Source/Email/Template.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Config/Model/Config/Source/Email/Template.php b/app/code/Magento/Config/Model/Config/Source/Email/Template.php index 04222733418d3..c6b28cd7c46a9 100644 --- a/app/code/Magento/Config/Model/Config/Source/Email/Template.php +++ b/app/code/Magento/Config/Model/Config/Source/Email/Template.php @@ -62,6 +62,12 @@ public function toOptionArray() $templateLabel = $this->_emailConfig->getTemplateLabel($templateId); $templateLabel = __('%1 (Default)', $templateLabel); array_unshift($options, ['value' => $templateId, 'label' => $templateLabel]); + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); return $options; } } From 939eaf4e1e254376bfd2e398d2c4f6ce288bfa5b Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Fri, 14 Jun 2019 14:38:27 -0500 Subject: [PATCH 107/372] MC-16118: Email template name config update - Updated email template unit test --- .../Model/Config/Source/Email/TemplateTest.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php index b29ad244e7a81..a5878a04e3e60 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php @@ -76,9 +76,21 @@ public function testToOptionArray() $this->returnValue('Template New') ); $expectedResult = [ - ['value' => 'template_new', 'label' => 'Template New (Default)'], - ['value' => 'template_one', 'label' => 'Template One'], - ['value' => 'template_two', 'label' => 'Template Two'], + [ + 'value' => 'template_new', + 'label' => 'Template New (Default)', + '__disableTmpl' => true + ], + [ + 'value' => 'template_one', + 'label' => 'Template One', + '__disableTmpl' => true + ], + [ + 'value' => 'template_two', + 'label' => 'Template Two', + '__disableTmpl' => true + ], ]; $this->_model->setPath('template/new'); $this->assertEquals($expectedResult, $this->_model->toOptionArray()); From 327cd700be97b505fe9bd61052a3da58cd0d46e5 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Fri, 14 Jun 2019 16:15:44 -0500 Subject: [PATCH 108/372] MC-16118: Email template name config update - Resolved static test failures --- app/code/Magento/Config/Model/Config/Source/Email/Template.php | 2 ++ .../Test/Unit/Model/Config/Source/Email/TemplateTest.php | 3 +++ 2 files changed, 5 insertions(+) diff --git a/app/code/Magento/Config/Model/Config/Source/Email/Template.php b/app/code/Magento/Config/Model/Config/Source/Email/Template.php index c6b28cd7c46a9..e4f1ae65bcacd 100644 --- a/app/code/Magento/Config/Model/Config/Source/Email/Template.php +++ b/app/code/Magento/Config/Model/Config/Source/Email/Template.php @@ -6,6 +6,8 @@ namespace Magento\Config\Model\Config\Source\Email; /** + * Source for template + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php index a5878a04e3e60..9fabe6fef0c8e 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php @@ -6,6 +6,9 @@ namespace Magento\Config\Test\Unit\Model\Config\Source\Email; +/** + * Test class for Template. + */ class TemplateTest extends \PHPUnit\Framework\TestCase { /** From 03d1ccc5526d6a8639e75c9748aeda2b01896162 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Mon, 17 Jun 2019 08:27:32 -0500 Subject: [PATCH 109/372] MC-16284: Visible message alert --- .../base/web/js/form/element/file-uploader.js | 9 +------- .../Image/Adapter/AbstractAdapter.php | 21 ++++++++++++++++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js index f4b267758cf1d..a53481ad13868 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js @@ -427,8 +427,7 @@ define([ _.each(this.aggregatedErrors, function (error) { notification().add({ error: true, - // %s to be used as placeholders for html injection - message: '%s' + error.filename + '%s ' + $t('was not uploaded.') + '%s' + error.message, + message: error.message, /** * Adds constructed error notification to aggregatedErrorMessages @@ -436,12 +435,6 @@ define([ * @param {String} constructedMessage */ insertMethod: function (constructedMessage) { - // html is escaped in message body for notification widget; prepend unescaped html here - constructedMessage = constructedMessage - .replace('%s', '') - .replace('%s', '') - .replace('%s', '
'); - aggregatedErrorMessages.push(constructedMessage); } }); diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php index 6042e4eee491d..276a8a719d6a8 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php +++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php @@ -3,11 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Image\Adapter; use Magento\Framework\App\Filesystem\DirectoryList; /** + * Class AbstractAdapter + * * @file Abstract.php * @author Magento Core Team * @SuppressWarnings(PHPMD.TooManyFields) @@ -169,7 +173,8 @@ abstract public function open($fileName); /** * Save image to specific path. - * If some folders of path does not exist they will be created + * + * If some folders of the path do not exist they will be created. * * @param null|string $destination * @param null|string $newName @@ -620,6 +625,7 @@ protected function _checkDimensions($frameWidth, $frameHeight) $frameHeight !== null && $frameHeight <= 0 || empty($frameWidth) && empty($frameHeight) ) { + //phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception('Invalid image dimensions.'); } } @@ -687,6 +693,7 @@ protected function _prepareDestination($destination = null, $newName = null) $this->directoryWrite->create($this->directoryWrite->getRelativePath($destination)); } catch (\Magento\Framework\Exception\FileSystemException $e) { $this->logger->critical($e); + //phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception('Unable to write file into directory ' . $destination . '. Access forbidden.'); } } @@ -714,11 +721,19 @@ protected function _canProcess() public function validateUploadFile($filePath) { if (!file_exists($filePath)) { - throw new \InvalidArgumentException("File '{$filePath}' does not exists."); + throw new \InvalidArgumentException('Upload file does not exist.'); + } + + try { + $imageSize = getimagesize($filePath); + } catch (\Exception $e) { + $imageSize = false; } - if (!getimagesize($filePath)) { + + if (!$imageSize) { throw new \InvalidArgumentException('Disallowed file type.'); } + $this->checkDependencies(); $this->open($filePath); From 9dd3e4b1c6fee2bf2796f7e9778275f0ac398c85 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Mon, 17 Jun 2019 08:43:02 -0500 Subject: [PATCH 110/372] MC-16284: Visible message alert --- .../Ui/view/base/web/js/form/element/file-uploader.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js index a53481ad13868..68c9e7308bc02 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js @@ -427,7 +427,7 @@ define([ _.each(this.aggregatedErrors, function (error) { notification().add({ error: true, - message: error.message, + message: '%s' + error.message, // %s to be used as placeholder for html injection, /** * Adds constructed error notification to aggregatedErrorMessages @@ -435,6 +435,11 @@ define([ * @param {String} constructedMessage */ insertMethod: function (constructedMessage) { + var errorMsgBodyHtml = 'File was not uploaded.
'; + + // html is escaped in message body for notification widget; prepend unescaped html here + constructedMessage = constructedMessage.replace('%s', errorMsgBodyHtml); + aggregatedErrorMessages.push(constructedMessage); } }); From 4cea9401c486671e5428e6da835398427faec330 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Mon, 17 Jun 2019 08:44:36 -0500 Subject: [PATCH 111/372] MC-16284: Visible message alert --- .../Magento/Ui/view/base/web/js/form/element/file-uploader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js index 68c9e7308bc02..2db7aef0acf61 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js @@ -427,7 +427,7 @@ define([ _.each(this.aggregatedErrors, function (error) { notification().add({ error: true, - message: '%s' + error.message, // %s to be used as placeholder for html injection, + message: '%s' + error.message, // %s to be used as placeholder for html injection /** * Adds constructed error notification to aggregatedErrorMessages From 48dba482ef080aa937875427c2127f6b6ffbcbe7 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Mon, 17 Jun 2019 11:44:56 -0500 Subject: [PATCH 112/372] MC-16284: Visible message alert --- .../Ui/view/base/web/js/form/element/file-uploader.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js index 2db7aef0acf61..73bef62910644 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js @@ -435,7 +435,10 @@ define([ * @param {String} constructedMessage */ insertMethod: function (constructedMessage) { - var errorMsgBodyHtml = 'File was not uploaded.
'; + var escapedFileName = $('
').text(error.filename).html(), + errorMsgBodyHtml = '%s %s.
' + .replace('%s', escapedFileName) + .replace('%s', $t('was not uploaded')); // html is escaped in message body for notification widget; prepend unescaped html here constructedMessage = constructedMessage.replace('%s', errorMsgBodyHtml); From 5439b01c11464fab72122cb8b549b3fc844b1713 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Mon, 17 Jun 2019 12:41:02 -0500 Subject: [PATCH 113/372] MC-15979: New Customer Attribute Options Issue - Resolved incorrect attribute meta data resolver --- .../Magento/Customer/Model/AttributeMetadataResolver.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php index a41d52cdc45a4..acc54424c3acc 100644 --- a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php +++ b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php @@ -129,7 +129,14 @@ public function getAttributesMeta( $meta['arguments']['data']['config']['options'] = $this->countryWithWebsiteSource ->getAllOptions(); } else { - $meta['arguments']['data']['config']['options'] = $attribute->getSource()->getAllOptions(); + $options = $attribute->getSource()->getAllOptions(); + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = ['label' => true]; + } + ); + $meta['arguments']['data']['config']['options'] = $options; } } From ffc30aa55a16272a4c698c466a199ceb5e01db40 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 4 Jun 2019 21:21:40 -0500 Subject: [PATCH 114/372] MC-16041: Prevent errors from incorrect configuration --- .../Controller/Adminhtml/Page/InlineEdit.php | 27 ++-- .../Adminhtml/Page/PostDataProcessor.php | 1 + .../Cms/Controller/Adminhtml/Page/Save.php | 4 - .../PageRepository/ValidationComposite.php | 92 +++++++++++++ .../Validator/LayoutUpdateValidator.php | 128 ++++++++++++++++++ .../PageRepository/ValidatorInterface.php | 27 ++++ app/code/Magento/Cms/etc/di.xml | 11 +- 7 files changed, 275 insertions(+), 15 deletions(-) create mode 100644 app/code/Magento/Cms/Model/PageRepository/ValidationComposite.php create mode 100644 app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php create mode 100644 app/code/Magento/Cms/Model/PageRepository/ValidatorInterface.php diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php index 8774d7e69adfe..77f648e5f12c8 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php @@ -7,6 +7,7 @@ use Magento\Backend\App\Action\Context; use Magento\Cms\Api\PageRepositoryInterface as PageRepository; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\Result\JsonFactory; use Magento\Cms\Api\Data\PageInterface; @@ -15,7 +16,7 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class InlineEdit extends \Magento\Backend\App\Action +class InlineEdit extends \Magento\Backend\App\Action implements HttpPostActionInterface { /** * Authorization level of a basic admin session @@ -56,6 +57,8 @@ public function __construct( } /** + * Process the request + * * @return \Magento\Framework\Controller\ResultInterface * @throws \Magento\Framework\Exception\LocalizedException */ @@ -68,10 +71,12 @@ public function execute() $postItems = $this->getRequest()->getParam('items', []); if (!($this->getRequest()->getParam('isAjax') && count($postItems))) { - return $resultJson->setData([ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ]); + return $resultJson->setData( + [ + 'messages' => [__('Please correct the data sent.')], + 'error' => true, + ] + ); } foreach (array_keys($postItems) as $pageId) { @@ -79,7 +84,6 @@ public function execute() $page = $this->pageRepository->getById($pageId); try { $pageData = $this->filterPost($postItems[$pageId]); - $this->validatePost($pageData, $page, $error, $messages); $extendedPageData = $page->getData(); $this->setCmsPageData($page, $extendedPageData, $pageData); $this->pageRepository->save($page); @@ -98,10 +102,12 @@ public function execute() } } - return $resultJson->setData([ - 'messages' => $messages, - 'error' => $error - ]); + return $resultJson->setData( + [ + 'messages' => $messages, + 'error' => $error + ] + ); } /** @@ -128,6 +134,7 @@ protected function filterPost($postData = []) * @param bool $error * @param array $messages * @return void + * @deprecated */ protected function validatePost(array $pageData, \Magento\Cms\Model\Page $page, &$error, array &$messages) { diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php index 9b8933c8dba2e..f934cac6da11d 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php @@ -80,6 +80,7 @@ public function filter($data) * * @param array $data * @return bool Return FALSE if some item is invalid + * @deprecated */ public function validate($data) { diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php index 37cb45753174f..569f6b256163f 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php @@ -107,10 +107,6 @@ public function execute() ['page' => $model, 'request' => $this->getRequest()] ); - if (!$this->dataProcessor->validate($data)) { - return $resultRedirect->setPath('*/*/edit', ['page_id' => $model->getId(), '_current' => true]); - } - try { $this->pageRepository->save($model); $this->messageManager->addSuccessMessage(__('You saved the page.')); diff --git a/app/code/Magento/Cms/Model/PageRepository/ValidationComposite.php b/app/code/Magento/Cms/Model/PageRepository/ValidationComposite.php new file mode 100644 index 0000000000000..9fd94d4c11e1c --- /dev/null +++ b/app/code/Magento/Cms/Model/PageRepository/ValidationComposite.php @@ -0,0 +1,92 @@ +repository = $repository; + $this->validators = $validators; + } + + /** + * @inheritdoc + */ + public function save(PageInterface $page) + { + foreach ($this->validators as $validator) { + $validator->validate($page); + } + + return $this->repository->save($page); + } + + /** + * @inheritdoc + */ + public function getById($pageId) + { + return $this->repository->getById($pageId); + } + + /** + * @inheritdoc + */ + public function getList(SearchCriteriaInterface $searchCriteria) + { + return $this->repository->getList($searchCriteria); + } + + /** + * @inheritdoc + */ + public function delete(PageInterface $page) + { + return $this->repository->delete($page); + } + + /** + * @inheritdoc + */ + public function deleteById($pageId) + { + return $this->repository->deleteById($pageId); + } +} diff --git a/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php b/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php new file mode 100644 index 0000000000000..8cfb6f1433b63 --- /dev/null +++ b/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php @@ -0,0 +1,128 @@ +validatorFactory = $validatorFactory; + $this->validationState = $validationState; + } + + /** + * Validate the data before saving + * + * @param PageInterface $page + * @throws LocalizedException + */ + public function validate(PageInterface $page): void + { + $this->validateRequiredFields($page); + $this->validateLayoutUpdate($page); + $this->validateCustomLayoutUpdate($page); + } + + /** + * Validate required fields + * + * @param PageInterface $page + * @throws LocalizedException + */ + private function validateRequiredFields(PageInterface $page): void + { + if (empty($page->getTitle())) { + throw new LocalizedException(__(sprintf('Required field "%s" is empty.', 'title'))); + } + } + + /** + * Validate layout update + * + * @param PageInterface $page + * @throws LocalizedException + */ + private function validateLayoutUpdate(PageInterface $page): void + { + $layoutXmlValidator = $this->getLayoutValidator(); + + try { + if (!empty($page->getLayoutUpdateXml()) + && !$layoutXmlValidator->isValid($page->getLayoutUpdateXml()) + ) { + throw new LocalizedException(__('Layout update is invalid')); + } + } catch (ValidationException|ValidationSchemaException $e) { + throw new LocalizedException(__('Layout update is invalid')); + } + } + + /** + * Validate custom layout update + * + * @param PageInterface $page + * @throws LocalizedException + */ + private function validateCustomLayoutUpdate(PageInterface $page): void + { + $layoutXmlValidator = $this->getLayoutValidator(); + + try { + if (!empty($page->getCustomLayoutUpdateXml()) + && !$layoutXmlValidator->isValid($page->getCustomLayoutUpdateXml()) + ) { + throw new LocalizedException(__('Custom layout update is invalid')); + } + } catch (ValidationException|ValidationSchemaException $e) { + throw new LocalizedException(__('Custom layout update is invalid')); + } + } + + /** + * Return a new validator + * + * @return Validator + */ + private function getLayoutValidator(): Validator + { + return $this->validatorFactory->create( + [ + 'validationState' => $this->validationState, + ] + ); + } +} diff --git a/app/code/Magento/Cms/Model/PageRepository/ValidatorInterface.php b/app/code/Magento/Cms/Model/PageRepository/ValidatorInterface.php new file mode 100644 index 0000000000000..ff5c7648a9fa2 --- /dev/null +++ b/app/code/Magento/Cms/Model/PageRepository/ValidatorInterface.php @@ -0,0 +1,27 @@ + - + @@ -232,5 +232,14 @@ + + + + Magento\Cms\Model\PageRepository + + Magento\Cms\Model\PageRepository\Validator\LayoutUpdateValidator + + + From ba19d6dfa713e3555a4cac91457362f8182ef0e5 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 17 Jun 2019 16:13:58 -0500 Subject: [PATCH 115/372] MC-16724: Prevent errors from incorrect import data --- .../LayoutUpdate/PermissionsValidatorTest.php | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100644 app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php diff --git a/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php deleted file mode 100644 index 1bb2037462f3b..0000000000000 --- a/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php +++ /dev/null @@ -1,101 +0,0 @@ -userContext = $this->createMock(UserContextInterface::class); - $this->authorization = $this->createMock(AuthorizationInterface::class); - $this->context = $this->createMock(Product::class); - $this->context - ->method('retrieveMessageTemplate') - ->with('insufficientPermissions') - ->willReturn('oh no "%s"'); - $this->validator = new LayoutUpdatePermissions( - $this->userContext, - $this->authorization - ); - $this->validator->init($this->context); - } - - /** - * @param $value - * @param $userContext - * @param $isAllowed - * @param $isValid - * @dataProvider configurationsProvider - */ - public function testValidationConfiguration($value, $userContext, $isAllowed, $isValid) - { - $this->userContext - ->method('getUserType') - ->willReturn($userContext); - - $this->authorization - ->method('isAllowed') - ->with('Magento_Catalog::edit_product_design') - ->willReturn($isAllowed); - - $result = $this->validator->isValid(['custom_layout_update' => $value]); - $messages = $this->validator->getMessages(); - - self::assertSame($isValid, $result); - - if ($isValid) { - self::assertSame([], $messages); - } else { - self::assertSame(['oh no "custom_layout_update"'], $messages); - } - } - - public function configurationsProvider() - { - return [ - ['', null, null, true], - [null, null, null, true], - ['foo', UserContextInterface::USER_TYPE_ADMIN, true, true], - ['foo', UserContextInterface::USER_TYPE_INTEGRATION, true, true], - ['foo', UserContextInterface::USER_TYPE_ADMIN, false, false], - ['foo', UserContextInterface::USER_TYPE_INTEGRATION, false, false], - ['foo', 'something', null, false], - ]; - } -} From 425c34f75f3d43c145248fe0a04772c28b5e288a Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 17 Jun 2019 16:52:46 -0500 Subject: [PATCH 116/372] MC-16041: Prevent errors from incorrect configuration --- .../ValidationCompositeTest.php | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php new file mode 100644 index 0000000000000..f73396230a669 --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php @@ -0,0 +1,145 @@ +subject = $this->createMock(PageRepositoryInterface::class); + } + + /** + * @param $validators + * @expectedException \InvalidArgumentException + * @dataProvider constructorArgumentProvider + */ + public function testConstructorValidation($validators) + { + new ValidationComposite($this->subject, $validators); + } + + public function testSaveInvokesValidatorsWithSucess() + { + $validator1 = $this->createMock(ValidatorInterface::class); + $validator2 = $this->createMock(ValidatorInterface::class); + $page = $this->createMock(PageInterface::class); + + // Assert each are called + $validator1 + ->expects($this->once()) + ->method('validate') + ->with($page); + $validator2 + ->expects($this->once()) + ->method('validate') + ->with($page); + + // Assert that the success is called + $this->subject + ->expects($this->once()) + ->method('save') + ->with($page) + ->willReturn('foo'); + + $composite = new ValidationComposite($this->subject, [$validator1, $validator2]); + $result = $composite->save($page); + + self::assertSame('foo', $result); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Oh no. That isn't right. + */ + public function testSaveInvokesValidatorsWithErrors() + { + $validator1 = $this->createMock(ValidatorInterface::class); + $validator2 = $this->createMock(ValidatorInterface::class); + $page = $this->createMock(PageInterface::class); + + // Assert the first is called + $validator1 + ->expects($this->once()) + ->method('validate') + ->with($page) + ->willThrowException(new LocalizedException(__('Oh no. That isn\'t right.'))); + + // Assert the second is NOT called + $validator2 + ->expects($this->never()) + ->method('validate'); + + // Assert that the success is NOT called + $this->subject + ->expects($this->never()) + ->method('save'); + + $composite = new ValidationComposite($this->subject, [$validator1, $validator2]); + $composite->save($page); + } + + /** + * @param $method + * @param $arg + * @dataProvider passthroughMethodDataProvider + */ + public function testPassthroughMethods($method, $arg) + { + $this->subject + ->method($method) + ->with($arg) + ->willReturn('foo'); + + $composite = new ValidationComposite($this->subject, []); + $result = $composite->{$method}($arg); + + self::assertSame('foo', $result); + } + + public function constructorArgumentProvider() + { + return [ + [[null], false], + [[''], false], + [['foo'], false], + [[new \stdClass()], false], + [[$this->createMock(ValidatorInterface::class), 'foo'], false], + ]; + } + + public function passthroughMethodDataProvider() + { + return [ + ['save', $this->createMock(PageInterface::class)], + ['getById', 1], + ['getList', $this->createMock(SearchCriteriaInterface::class)], + ['delete', $this->createMock(PageInterface::class)], + ['deleteById', 1], + ]; + } +} From 9e322c82af00ee46451aa90d3adf6174edd02b1f Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Tue, 18 Jun 2019 11:32:50 +0300 Subject: [PATCH 117/372] MC-17303: Customer login fix --- .../Customer/Controller/Account/LoginPost.php | 2 ++ .../Customer/Model/Plugin/CustomerNotification.php | 7 +++++++ app/code/Magento/Customer/Model/Session.php | 12 ++++++++++-- app/code/Magento/Rss/Controller/Feed.php | 2 ++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 9afaab4121644..48221b00bbb4d 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -26,6 +26,8 @@ use Magento\Framework\Phrase; /** + * Post login customer action. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class LoginPost extends AbstractAccount implements CsrfAwareActionInterface, HttpPostActionInterface diff --git a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php index 9b655fc843529..577c97a19268a 100644 --- a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php +++ b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php @@ -15,6 +15,11 @@ use Magento\Framework\Exception\NoSuchEntityException; use Psr\Log\LoggerInterface; +/** + * Plugin before \Magento\Framework\App\Action\AbstractAction::dispatch. + * + * Plugin to remove notifications from cache. + */ class CustomerNotification { /** @@ -66,6 +71,8 @@ public function __construct( } /** + * Removes notifications from cache. + * * @param AbstractAction $subject * @param RequestInterface $request * @return void diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php index c37a28d04fc52..e6612fe77a9bc 100644 --- a/app/code/Magento/Customer/Model/Session.php +++ b/app/code/Magento/Customer/Model/Session.php @@ -17,6 +17,7 @@ * @api * @method string getNoReferer() * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @since 100.0.2 */ class Session extends \Magento\Framework\Session\SessionManager @@ -354,8 +355,9 @@ public function setCustomerGroupId($id) } /** - * Get customer group id - * If customer is not logged in system, 'not logged in' group id will be returned + * Get customer group id. + * + * If customer is not logged in system, 'not logged in' group id will be returned. * * @return int */ @@ -407,6 +409,8 @@ public function checkCustomerId($customerId) } /** + * Sets customer as logged in. + * * @param Customer $customer * @return $this */ @@ -420,6 +424,8 @@ public function setCustomerAsLoggedIn($customer) } /** + * Sets customer as logged in. + * * @param CustomerData $customer * @return $this */ @@ -567,6 +573,8 @@ public function regenerateId() } /** + * Creates \Magento\Framework\UrlInterface object. + * * @return \Magento\Framework\UrlInterface */ protected function _createUrl() diff --git a/app/code/Magento/Rss/Controller/Feed.php b/app/code/Magento/Rss/Controller/Feed.php index 634540dde5d96..c3ef4fb80833e 100644 --- a/app/code/Magento/Rss/Controller/Feed.php +++ b/app/code/Magento/Rss/Controller/Feed.php @@ -76,6 +76,8 @@ public function __construct( } /** + * Authenticate not logged in customer. + * * @return bool */ protected function auth() From 878140b1a1df622107cb09be33598da59e933a6c Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Tue, 18 Jun 2019 08:51:04 -0500 Subject: [PATCH 118/372] MC-16284: Visible message alert * Updated Integration test --- .../Framework/Image/Adapter/InterfaceTest.php | 39 ++++++++++++++++++- .../Magento/Framework/Image/_files/empty.png | 0 .../Framework/Image/_files/notanimage.txt | 1 + 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Image/_files/empty.png create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Image/_files/notanimage.txt diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php index bc8281d55ac4f..59ad82334a958 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php @@ -703,12 +703,47 @@ public function testValidateUploadFile() } /** + * @dataProvider testValidateUploadFileExceptionDataProvider * @expectedException \InvalidArgumentException + * @param string $fileName + * @param string $expectedErrorMsg + * @param bool $useFixture */ - public function testValidateUploadFileException() + public function testValidateUploadFileException($fileName, $expectedErrorMsg, $useFixture) { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $imageAdapter = $objectManager->get(\Magento\Framework\Image\AdapterFactory::class)->create(); - $imageAdapter->validateUploadFile(__FILE__); + $filePath = $useFixture ? $this->_getFixture($fileName) : $fileName; + + try { + $imageAdapter->validateUploadFile($filePath); + } catch (\InvalidArgumentException $e) { + $this->assertEquals($expectedErrorMsg, $e->getMessage()); + throw $e; + } + } + + /** + * @return array + */ + public function testValidateUploadFileExceptionDataProvider() + { + return [ + 'image_notfound' => [ + 'fileName' => 'notfound.png', + 'expectedErrorMsg' => 'Upload file does not exist.', + 'useFixture' => false + ], + 'image_empty' => [ + 'fileName' => 'empty.png', + 'expectedErrorMsg' => 'Disallowed file type.', + 'useFixture' => true + ], + 'notanimage' => [ + 'fileName' => 'notanimage.txt', + 'expectedErrorMsg' => 'Disallowed file type.', + 'useFixture' => true + ] + ]; } } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/_files/empty.png b/dev/tests/integration/testsuite/Magento/Framework/Image/_files/empty.png new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/_files/notanimage.txt b/dev/tests/integration/testsuite/Magento/Framework/Image/_files/notanimage.txt new file mode 100644 index 0000000000000..81bc3abd37125 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/_files/notanimage.txt @@ -0,0 +1 @@ +Not an image. From 5f4222b47413c88b906ea8fbaa341b35ec6d47d5 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 18 Jun 2019 09:49:15 -0500 Subject: [PATCH 119/372] MC-16041: Prevent errors from incorrect configuration --- .../Validator/LayoutUpdateValidator.php | 2 +- .../Validator/LayoutUpdateValidatorTest.php | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php diff --git a/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php b/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php index 8cfb6f1433b63..721fd9efbdd91 100644 --- a/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php +++ b/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php @@ -66,7 +66,7 @@ public function validate(PageInterface $page): void private function validateRequiredFields(PageInterface $page): void { if (empty($page->getTitle())) { - throw new LocalizedException(__(sprintf('Required field "%s" is empty.', 'title'))); + throw new LocalizedException(__('Required field "%1" is empty.', 'title')); } } diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php new file mode 100644 index 0000000000000..8fbea15250732 --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php @@ -0,0 +1,121 @@ +createMock(ValidatorFactory::class); + $this->layoutValidator = $this->createMock(Validator::class); + $layoutValidatorState = $this->createMock(ValidationStateInterface::class); + + $layoutValidatorFactory + ->method('create') + ->with(['validationState' => $layoutValidatorState]) + ->willReturn($this->layoutValidator); + + $this->validator = new LayoutUpdateValidator($layoutValidatorFactory, $layoutValidatorState); + } + + /** + * @dataProvider validationSetDataProvider + */ + public function testValidate($data, $expectedExceptionMessage, $layoutValidatorException, $isLayoutValid = false) + { + if ($expectedExceptionMessage) { + $this->expectException(LocalizedException::class); + $this->expectExceptionMessage($expectedExceptionMessage); + } + + if ($layoutValidatorException) { + $this->layoutValidator + ->method('isValid') + ->with($data['getLayoutUpdateXml'] ?? $data['getCustomLayoutUpdateXml']) + ->willThrowException($layoutValidatorException); + } elseif (!empty($data['getLayoutUpdateXml'])) { + $this->layoutValidator + ->method('isValid') + ->with($data['getLayoutUpdateXml']) + ->willReturn($isLayoutValid); + } elseif (!empty($data['getCustomLayoutUpdateXml'])) { + $this->layoutValidator + ->method('isValid') + ->with($data['getCustomLayoutUpdateXml']) + ->willReturn($isLayoutValid); + } + + $page = $this->createMock(PageInterface::class); + foreach ($data as $method => $value) { + $page + ->method($method) + ->willReturn($value); + } + + self::assertNull($this->validator->validate($page)); + } + + public function validationSetDataProvider() + { + $layoutError = 'Layout update is invalid'; + $customLayoutError = 'Custom layout update is invalid'; + + return [ + [['getTitle' => ''], 'Required field "title" is empty.', null], + [['getTitle' => null], 'Required field "title" is empty.', null], + [['getTitle' => false], 'Required field "title" is empty.', null], + [['getTitle' => 0], 'Required field "title" is empty.', null], + [['getTitle' => '0'], 'Required field "title" is empty.', null], + [['getTitle' => []], 'Required field "title" is empty.', null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => ''], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => null], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => false], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 0], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => '0'], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => []], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, new ValidationException], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, new SchemaException(__(''))], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], null, null, true], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => ''], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => null], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => false], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 0], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => '0'], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => []], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, new ValidationException], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, new SchemaException(__(''))], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], null, null, true], + ]; + } +} From d7b059f3689ef29ac58cd46eb16140c84e7193e7 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 18 Jun 2019 10:47:08 -0500 Subject: [PATCH 120/372] MC-16041: Prevent errors from incorrect configuration --- .../Adminhtml/Page/PostDataProcessor.php | 3 +-- .../Validator/LayoutUpdateValidatorTest.php | 14 ++++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php index f934cac6da11d..46f68955531a3 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php @@ -12,8 +12,7 @@ use Magento\Framework\Config\Dom\ValidationSchemaException; /** - * Class PostDataProcessor - * @package Magento\Cms\Controller\Adminhtml\Page + * Processes form data */ class PostDataProcessor { diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php index 8fbea15250732..83db12d77ab3d 100644 --- a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php @@ -6,11 +6,11 @@ declare(strict_types=1); -namespace Magento\Cms\Model\PageRepository\Validator; +namespace Magento\Cms\Test\Unit\Model\PageRepository\Validator; use Magento\Cms\Api\Data\PageInterface; use Magento\Framework\Config\Dom\ValidationException; -use Magento\Framework\Config\Dom\ValidationSchemaException as SchemaException; +use Magento\Framework\Config\Dom\ValidationSchemaException; use Magento\Framework\Config\ValidationStateInterface; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\View\Model\Layout\Update\ValidatorFactory; @@ -88,6 +88,8 @@ public function validationSetDataProvider() { $layoutError = 'Layout update is invalid'; $customLayoutError = 'Custom layout update is invalid'; + $validationException = new ValidationException('Invalid format'); + $schemaException = new ValidationSchemaException(__('Invalid format')); return [ [['getTitle' => ''], 'Required field "title" is empty.', null], @@ -103,8 +105,8 @@ public function validationSetDataProvider() [['getTitle' => 'foo', 'getLayoutUpdateXml' => '0'], null, null], [['getTitle' => 'foo', 'getLayoutUpdateXml' => []], null, null], [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, null], - [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, new ValidationException], - [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, new SchemaException(__(''))], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, $validationException], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, $schemaException], [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], null, null, true], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => ''], null, null], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => null], null, null], @@ -113,8 +115,8 @@ public function validationSetDataProvider() [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => '0'], null, null], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => []], null, null], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, null], - [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, new ValidationException], - [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, new SchemaException(__(''))], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, $validationException], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, $schemaException], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], null, null, true], ]; } From a3180003aec1eff6dcacc05e5c39fc633496d5bb Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 18 Jun 2019 11:23:02 -0500 Subject: [PATCH 121/372] MC-16041: Prevent errors from incorrect configuration --- app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php | 4 ++-- .../Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php index 77f648e5f12c8..2237f35ed0b84 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php @@ -84,6 +84,7 @@ public function execute() $page = $this->pageRepository->getById($pageId); try { $pageData = $this->filterPost($postItems[$pageId]); + $this->validatePost($pageData, $page, $error, $messages); $extendedPageData = $page->getData(); $this->setCmsPageData($page, $extendedPageData, $pageData); $this->pageRepository->save($page); @@ -134,11 +135,10 @@ protected function filterPost($postData = []) * @param bool $error * @param array $messages * @return void - * @deprecated */ protected function validatePost(array $pageData, \Magento\Cms\Model\Page $page, &$error, array &$messages) { - if (!($this->dataProcessor->validate($pageData) && $this->dataProcessor->validateRequireEntry($pageData))) { + if (!$this->dataProcessor->validateRequireEntry($pageData)) { $error = true; foreach ($this->messageManager->getMessages(true)->getItems() as $error) { $messages[] = $this->getErrorWithPageId($page, $error->getText()); diff --git a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php index 9d51431b26d8f..ea5e8d607f485 100644 --- a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php +++ b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php @@ -102,10 +102,6 @@ public function prepareMocksForTestExecute() ->method('filter') ->with($postData[1]) ->willReturnArgument(0); - $this->dataProcessor->expects($this->once()) - ->method('validate') - ->with($postData[1]) - ->willReturn(false); $this->messageManager->expects($this->once()) ->method('getMessages') ->with(true) From 073ce7843732f336c148249d9457f0850c105c77 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 18 Jun 2019 12:46:40 -0500 Subject: [PATCH 122/372] MC-16041: Prevent errors from incorrect configuration --- .../Adminhtml/Page/InlineEditTest.php | 88 +++++++++++-------- .../Validator/LayoutUpdateValidatorTest.php | 1 + 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php index ea5e8d607f485..681e62d159863 100644 --- a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php +++ b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php @@ -118,19 +118,23 @@ public function prepareMocksForTestExecute() ->willReturn('1'); $this->cmsPage->expects($this->atLeastOnce()) ->method('getData') - ->willReturn([ - 'layout' => '1column', - 'identifier' => 'test-identifier' - ]); + ->willReturn( + [ + 'layout' => '1column', + 'identifier' => 'test-identifier' + ] + ); $this->cmsPage->expects($this->once()) ->method('setData') - ->with([ - 'layout' => '1column', - 'title' => '404 Not Found', - 'identifier' => 'no-route', - 'custom_theme' => '1', - 'custom_root_template' => '2' - ]); + ->with( + [ + 'layout' => '1column', + 'title' => '404 Not Found', + 'identifier' => 'no-route', + 'custom_theme' => '1', + 'custom_root_template' => '2' + ] + ); $this->jsonFactory->expects($this->once()) ->method('create') ->willReturn($this->resultJson); @@ -145,13 +149,15 @@ public function testExecuteWithLocalizedException() ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__('LocalizedException'))); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [ - '[Page ID: 1] Error message', - '[Page ID: 1] LocalizedException' - ], - 'error' => true - ]) + ->with( + [ + 'messages' => [ + '[Page ID: 1] Error message', + '[Page ID: 1] LocalizedException' + ], + 'error' => true + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); @@ -166,13 +172,15 @@ public function testExecuteWithRuntimeException() ->willThrowException(new \RuntimeException(__('RuntimeException'))); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [ - '[Page ID: 1] Error message', - '[Page ID: 1] RuntimeException' - ], - 'error' => true - ]) + ->with( + [ + 'messages' => [ + '[Page ID: 1] Error message', + '[Page ID: 1] RuntimeException' + ], + 'error' => true + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); @@ -187,13 +195,15 @@ public function testExecuteWithException() ->willThrowException(new \Exception(__('Exception'))); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [ - '[Page ID: 1] Error message', - '[Page ID: 1] Something went wrong while saving the page.' - ], - 'error' => true - ]) + ->with( + [ + 'messages' => [ + '[Page ID: 1] Error message', + '[Page ID: 1] Something went wrong while saving the page.' + ], + + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); @@ -214,12 +224,14 @@ public function testExecuteWithoutData() ); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [ - 'Please correct the data sent.' - ], - 'error' => true - ]) + ->with( + [ + 'messages' => [ + 'Please correct the data sent.' + ], + 'error' => true + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php index 83db12d77ab3d..487a90bb9a185 100644 --- a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php @@ -9,6 +9,7 @@ namespace Magento\Cms\Test\Unit\Model\PageRepository\Validator; use Magento\Cms\Api\Data\PageInterface; +use Magento\Cms\Model\PageRepository\Validator\LayoutUpdateValidator; use Magento\Framework\Config\Dom\ValidationException; use Magento\Framework\Config\Dom\ValidationSchemaException; use Magento\Framework\Config\ValidationStateInterface; From f86eafd52c2a90608c62cfa5569d8abf1092fa2c Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Wed, 19 Jun 2019 08:41:24 -0500 Subject: [PATCH 123/372] MC-16284: Visible message alert --- .../Magento/Framework/Image/Adapter/AbstractAdapter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php index 276a8a719d6a8..5a2102708b414 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php +++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php @@ -291,7 +291,7 @@ public function getMimeType() if ($this->_fileMimeType) { return $this->_fileMimeType; } else { - $this->_fileMimeType = image_type_to_mime_type($this->getImageType()); + $this->_fileMimeType = image_type_to_mime_type((int) $this->getImageType()); return $this->_fileMimeType; } } @@ -523,7 +523,7 @@ public function backgroundColor($value = null) */ protected function _getFileAttributes() { - $pathinfo = pathinfo($this->_fileName); + $pathinfo = pathinfo((string) $this->_fileName); $this->_fileSrcPath = $pathinfo['dirname']; $this->_fileSrcName = $pathinfo['basename']; @@ -675,7 +675,7 @@ protected function _prepareDestination($destination = null, $newName = null) $destination = $this->_fileSrcPath; } else { if (empty($newName)) { - $info = pathinfo($destination); + $info = pathinfo((string) $destination); $newName = $info['basename']; $destination = $info['dirname']; } From fe7c222607d72226dbc93c56a810d47cdfa16d0e Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 19 Jun 2019 11:49:47 -0500 Subject: [PATCH 124/372] MC-15978: Catalog Product Attribute Set Name --- .../Magento/Catalog/Model/Product/AttributeSet/Options.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php index d0c7103851499..26ca1f4d31c73 100644 --- a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php +++ b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php @@ -33,6 +33,10 @@ public function toOptionArray() $this->options = $this->collectionFactory->create() ->setEntityTypeFilter($this->product->getTypeId()) ->toOptionArray(); + + array_walk($this->options, function (&$option) { + $option['__disableTmpl'] = true; + }); } return $this->options; } From 5752b6568517fb707deff7ef3a4dad629d94b005 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 19 Jun 2019 12:03:22 -0500 Subject: [PATCH 125/372] MC-15978: Catalog Product Attribute Set Name --- .../Magento/Catalog/Model/Product/AttributeSet/Options.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php index 26ca1f4d31c73..ab3f7b1a84fb8 100644 --- a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php +++ b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php @@ -5,6 +5,9 @@ */ namespace Magento\Catalog\Model\Product\AttributeSet; +/** + * Attribute Set Options + */ class Options implements \Magento\Framework\Data\OptionSourceInterface { /** From b7dbf8991629cfc120f6de237e01056c3362a309 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 19 Jun 2019 14:21:08 -0500 Subject: [PATCH 126/372] MC-15978: Catalog Product Attribute Set Name --- .../Catalog/Model/Product/AttributeSet/Options.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php index ab3f7b1a84fb8..57d08916bcd40 100644 --- a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php +++ b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php @@ -11,7 +11,7 @@ class Options implements \Magento\Framework\Data\OptionSourceInterface { /** - * @var null|array + * @var array */ protected $options; @@ -28,7 +28,7 @@ public function __construct( } /** - * @return array|null + * @inheritDoc */ public function toOptionArray() { @@ -37,10 +37,14 @@ public function toOptionArray() ->setEntityTypeFilter($this->product->getTypeId()) ->toOptionArray(); - array_walk($this->options, function (&$option) { - $option['__disableTmpl'] = true; - }); + array_walk( + $this->options, + function (&$option) { + $option['__disableTmpl'] = true; + } + ); } + return $this->options; } } From 4d0ae578c4adb31c2ae51db1102973d20cdc5e9f Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 19 Jun 2019 15:36:03 -0500 Subject: [PATCH 127/372] MC-17581: Import Export --- lib/internal/Magento/Framework/Archive/Zip.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index c41f8b28ce348..eee2a3bf4a55e 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -54,7 +54,7 @@ public function unpack($source, $destination) $zip = new \ZipArchive(); if ($zip->open($source) === true) { $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); - if ($filename) { + if (!preg_match('#[:"*?|<>%]#', $filename)) { $zip->extractTo(dirname($destination), $filename); rename(dirname($destination).'/'.$filename, $destination); } else { From 0599bb53cfa42bcfc47f4db2cfd1a36fd5a7d8ee Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Wed, 19 Jun 2019 15:55:19 -0500 Subject: [PATCH 128/372] MC-16724: Prevent errors from incorrect import data --- .../Magento/CatalogImportExport/Model/Import/Product.php | 5 +++-- .../Import/Product/Validator/LayoutUpdatePermissions.php | 5 +---- .../Import/Product/Validator/LayoutUpdatePermissionsTest.php | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 036bd5de0fb27..9088868a595fa 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -301,8 +301,9 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually', ValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES => 'Value for multiselect attribute %s contains duplicated values', 'invalidNewToDateValue' => 'Make sure new_to_date is later than or the same as new_from_date', - 'invalidLayoutUpdate' => 'Invalid layout update', - 'insufficientPermissions' => 'You do not have permissions to update "%s"', + // Can't add new translated strings in patch release + 'invalidLayoutUpdate' => 'Invalid format.', + 'insufficientPermissions' => 'Invalid format.', ]; //@codingStandardsIgnoreEnd diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php index d1df04b8e95c8..50d38cedfb754 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php @@ -68,10 +68,7 @@ public function isValid($data): bool if (!$isValid) { $this->_addMessages( [ - sprintf( - $this->context->retrieveMessageTemplate(self::ERROR_INSUFFICIENT_PERMISSIONS), - 'custom_layout_update' - ) + $this->context->retrieveMessageTemplate(self::ERROR_INSUFFICIENT_PERMISSIONS), ] ); } diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php index 2f883b5f4146b..e018fc0cf5ccf 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php @@ -48,7 +48,7 @@ protected function setUp() $this->context ->method('retrieveMessageTemplate') ->with('insufficientPermissions') - ->willReturn('oh no "%s"'); + ->willReturn('oh no'); $this->validator = new LayoutUpdatePermissions( $this->userContext, $this->authorization @@ -82,7 +82,7 @@ public function testValidationConfiguration($value, $userContext, $isAllowed, $i if ($isValid) { self::assertSame([], $messages); } else { - self::assertSame(['oh no "custom_layout_update"'], $messages); + self::assertSame(['oh no'], $messages); } } From cb86e985f7067679fdfd10b9d526cf473e66629d Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Thu, 20 Jun 2019 10:09:15 +0300 Subject: [PATCH 129/372] MC-17303: Customer login fix --- app/code/Magento/Customer/Controller/Account/LoginPost.php | 1 - app/code/Magento/Customer/Controller/Ajax/Login.php | 1 - app/code/Magento/Customer/Model/Session.php | 1 + app/code/Magento/Rss/Controller/Feed.php | 1 - 4 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 48221b00bbb4d..4091a068e3094 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -184,7 +184,6 @@ public function execute() if (!empty($login['username']) && !empty($login['password'])) { try { $customer = $this->customerAccountManagement->authenticate($login['username'], $login['password']); - $this->session->regenerateId(); $this->session->setCustomerDataAsLoggedIn($customer); if ($this->getCookieManager()->getCookie('mage-cache-sessid')) { $metadata = $this->getCookieMetadataFactory()->createCookieMetadata(); diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php index d5425bfc27332..1215c47ab9902 100644 --- a/app/code/Magento/Customer/Controller/Ajax/Login.php +++ b/app/code/Magento/Customer/Controller/Ajax/Login.php @@ -190,7 +190,6 @@ public function execute() $credentials['username'], $credentials['password'] ); - $this->customerSession->regenerateId(); $this->customerSession->setCustomerDataAsLoggedIn($customer); $redirectRoute = $this->getAccountRedirect()->getRedirectCookie(); if ($this->cookieManager->getCookie('mage-cache-sessid')) { diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php index e6612fe77a9bc..ca15b8ab2034a 100644 --- a/app/code/Magento/Customer/Model/Session.php +++ b/app/code/Magento/Customer/Model/Session.php @@ -431,6 +431,7 @@ public function setCustomerAsLoggedIn($customer) */ public function setCustomerDataAsLoggedIn($customer) { + $this->regenerateId(); $this->_httpContext->setValue(Context::CONTEXT_AUTH, true, false); $this->setCustomerData($customer); diff --git a/app/code/Magento/Rss/Controller/Feed.php b/app/code/Magento/Rss/Controller/Feed.php index c3ef4fb80833e..4c5acf97bde8c 100644 --- a/app/code/Magento/Rss/Controller/Feed.php +++ b/app/code/Magento/Rss/Controller/Feed.php @@ -86,7 +86,6 @@ protected function auth() list($login, $password) = $this->httpAuthentication->getCredentials(); try { $customer = $this->customerAccountManagement->authenticate($login, $password); - $this->customerSession->regenerateId(); $this->customerSession->setCustomerDataAsLoggedIn($customer); } catch (\Exception $e) { $this->logger->critical($e); From ab4641cc603e76a63b2768679de2e08dc55081c3 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Thu, 20 Jun 2019 12:24:35 +0300 Subject: [PATCH 130/372] MC-17303: Customer login fix --- .../Test/Unit/Controller/Account/LoginPostTest.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php index 762c76b695dee..78acc339284c2 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php @@ -292,9 +292,8 @@ public function testExecuteSuccessCustomRedirect() ->method('setCustomerDataAsLoggedIn') ->with($customerMock) ->willReturnSelf(); - $this->session->expects($this->once()) - ->method('regenerateId') - ->willReturnSelf(); + $this->session->expects($this->never()) + ->method('regenerateId'); $this->accountRedirect->expects($this->never()) ->method('getRedirect') @@ -357,9 +356,8 @@ public function testExecuteSuccess() ->method('setCustomerDataAsLoggedIn') ->with($customerMock) ->willReturnSelf(); - $this->session->expects($this->once()) - ->method('regenerateId') - ->willReturnSelf(); + $this->session->expects($this->never()) + ->method('regenerateId'); $this->accountRedirect->expects($this->once()) ->method('getRedirect') From 492a377cf660964b11d512b9cec26df8f5b88310 Mon Sep 17 00:00:00 2001 From: Andrii Meysar Date: Thu, 20 Jun 2019 13:10:49 +0300 Subject: [PATCH 131/372] MC-16042: Zip archive validation --- .../Magento/Framework/Archive/Zip.php | 35 ++----------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index 925adda48504c..20f408a605c10 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -53,11 +53,10 @@ public function unpack($source, $destination) { $zip = new \ZipArchive(); if ($zip->open($source) === true) { - $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); - $filename = $this->filterExcludedFiles($filename); + $zip->renameIndex(0, basename($destination)); + $filename = $zip->getNameIndex(0) ?: ''; if ($filename) { $zip->extractTo(dirname($destination), $filename); - rename(dirname($destination).'/'.$filename, $destination); } else { $destination = ''; } @@ -68,34 +67,4 @@ public function unpack($source, $destination) return $destination; } - - /** - * Filter file names with relative paths. - * - * @param string $path - * @return string - */ - private function filterRelativePaths(string $path): string - { - if ($path && preg_match('#^\s*(../)|(/../)#i', $path)) { - $path = ''; - } - - return $path; - } - - /** - * Filter excluded files. - * - * @param string $file - * @return string - */ - private function filterExcludedFiles(string $file): string - { - if ($file && preg_match('/^\.htaccess$/', $file)) { - $file = ''; - } - - return $file; - } } From 5aa361068d0f5722d4d4587e66255ff0977b2db2 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 20 Jun 2019 12:11:48 -0500 Subject: [PATCH 132/372] MC-17581: Import Export --- app/code/Magento/ImportExport/Model/Import/Source/Zip.php | 8 +++++++- lib/internal/Magento/Framework/Archive/Zip.php | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Import/Source/Zip.php b/app/code/Magento/ImportExport/Model/Import/Source/Zip.php index 6fa87ab5d5c4d..7e69d837d6526 100644 --- a/app/code/Magento/ImportExport/Model/Import/Source/Zip.php +++ b/app/code/Magento/ImportExport/Model/Import/Source/Zip.php @@ -33,6 +33,12 @@ public function __construct( throw new ValidatorException(__('Sorry, but the data is invalid or the file is not uploaded.')); } $directory->delete($directory->getRelativePath($file)); - parent::__construct($csvFile, $directory, $options); + + try { + parent::__construct($csvFile, $directory, $options); + } catch (\LogicException $e) { + $directory->delete($directory->getRelativePath($csvFile)); + throw $e; + } } } diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index eee2a3bf4a55e..2cb6e47d39426 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -54,7 +54,8 @@ public function unpack($source, $destination) $zip = new \ZipArchive(); if ($zip->open($source) === true) { $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); - if (!preg_match('#[:"*?|<>%]#', $filename)) { + if ($filename && !preg_match('#[:"*?|<>%]#', $filename)) { + // extract first entry in zip file to destination directory $zip->extractTo(dirname($destination), $filename); rename(dirname($destination).'/'.$filename, $destination); } else { From dedd073a80bebb83233c6d937c0f3cee61d74612 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra Date: Fri, 21 Jun 2019 12:26:24 +0300 Subject: [PATCH 133/372] MC-17650: Change Confirmation key generation --- app/code/Magento/Customer/Model/Customer.php | 10 +++++-- .../Customer/Test/Unit/Model/CustomerTest.php | 29 ++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index 1287dbe5df708..32b0a9c1ec481 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -20,6 +20,7 @@ use Magento\Framework\Reflection\DataObjectProcessor; use Magento\Store\Model\ScopeInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Math\Random; /** * Customer model @@ -180,7 +181,7 @@ class Customer extends \Magento\Framework\Model\AbstractModel protected $_encryptor; /** - * @var \Magento\Framework\Math\Random + * @var Random */ protected $mathRandom; @@ -248,6 +249,7 @@ class Customer extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data * @param AccountConfirmation|null $accountConfirmation + * @param Random|null $mathRandom * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -272,7 +274,8 @@ public function __construct( \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - AccountConfirmation $accountConfirmation = null + AccountConfirmation $accountConfirmation = null, + Random $mathRandom = null ) { $this->metadataService = $metadataService; $this->_scopeConfig = $scopeConfig; @@ -291,6 +294,7 @@ public function __construct( $this->indexerRegistry = $indexerRegistry; $this->accountConfirmation = $accountConfirmation ?: ObjectManager::getInstance() ->get(AccountConfirmation::class); + $this->mathRandom = $mathRandom ?: ObjectManager::getInstance()->get(Random::class); parent::__construct( $context, $registry, @@ -805,7 +809,7 @@ public function isConfirmationRequired() */ public function getRandomConfirmationKey() { - return md5(uniqid()); + return $this->mathRandom->getRandomString(32); } /** diff --git a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php index 65831069aa1fb..8bb37adc875cc 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php @@ -15,6 +15,7 @@ use Magento\Customer\Model\AccountConfirmation; use Magento\Customer\Model\ResourceModel\Address\CollectionFactory as AddressCollectionFactory; use Magento\Customer\Api\Data\CustomerInterfaceFactory; +use Magento\Framework\Math\Random; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -86,6 +87,14 @@ class CustomerTest extends \PHPUnit\Framework\TestCase */ private $dataObjectHelper; + /** + * @var Random|\PHPUnit_Framework_MockObject_MockObject + */ + private $mathRandom; + + /** + * @inheritdoc + */ protected function setUp() { $this->_website = $this->createMock(\Magento\Store\Model\Website::class); @@ -130,6 +139,7 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['populateWithArray']) ->getMock(); + $this->mathRandom = $this->createMock(Random::class); $this->_model = $helper->getObject( \Magento\Customer\Model\Customer::class, @@ -146,7 +156,8 @@ protected function setUp() 'accountConfirmation' => $this->accountConfirmation, '_addressesFactory' => $this->addressesFactory, 'customerDataFactory' => $this->customerDataFactory, - 'dataObjectHelper' => $this->dataObjectHelper + 'dataObjectHelper' => $this->dataObjectHelper, + 'mathRandom' => $this->mathRandom, ] ); } @@ -383,4 +394,20 @@ public function testGetDataModel() $this->_model->getDataModel(); $this->assertEquals($customerDataObject, $this->_model->getDataModel()); } + + /** + * Check getRandomConfirmationKey use cryptographically secure function + * + * @return void + */ + public function testGetRandomConfirmationKey() : void + { + $this->mathRandom + ->expects($this->once()) + ->method('getRandomString') + ->with(32) + ->willReturn('random_string'); + + $this->_model->getRandomConfirmationKey(); + } } From fe9deec39afeab1a30cb4a7c2507b754fa2c6930 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra Date: Fri, 21 Jun 2019 15:09:53 +0300 Subject: [PATCH 134/372] MC-17650: Change Confirmation key generation --- .../Customer/Test/Unit/Model/CustomerTest.php | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php index 8bb37adc875cc..170cd001e5b9e 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php @@ -230,15 +230,17 @@ public function testSendNewAccountEmailWithoutStoreId() ->method('getTransport') ->will($this->returnValue($transportMock)); - $this->_model->setData([ - 'website_id' => 1, - 'store_id' => 1, - 'email' => 'email@example.com', - 'firstname' => 'FirstName', - 'lastname' => 'LastName', - 'middlename' => 'MiddleName', - 'prefix' => 'Name Prefix', - ]); + $this->_model->setData( + [ + 'website_id' => 1, + 'store_id' => 1, + 'email' => 'email@example.com', + 'firstname' => 'FirstName', + 'lastname' => 'LastName', + 'middlename' => 'MiddleName', + 'prefix' => 'Name Prefix', + ] + ); $this->_model->sendNewAccountEmail('registered'); } From ce3e108be879190254b2d5ae38b0125ca73abae6 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Fri, 21 Jun 2019 11:41:15 -0500 Subject: [PATCH 135/372] MC-17648: Registration email confirmation --- app/code/Magento/Customer/Model/AccountManagement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index cfb788a2516a2..e030f2107356b 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -977,6 +977,7 @@ protected function sendEmailConfirmation(CustomerInterface $customer, $redirectU $templateType = self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD; } $this->getEmailNotification()->newAccount($customer, $templateType, $redirectUrl, $customer->getStoreId()); + $customer->setConfirmation(null); } catch (MailException $e) { // If we are not able to send a new account email, this should be ignored $this->logger->critical($e); From 69cec9091e52bdfd15ed65c4903fe890dca393fe Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Mon, 24 Jun 2019 15:09:20 +0300 Subject: [PATCH 136/372] MC-17303: Customer login fix --- .../Unit/Controller/Account/LoginPostTest.php | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php index 78acc339284c2..13cf195ab5f69 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php @@ -93,13 +93,14 @@ protected function setUp() $this->session = $this->getMockBuilder(\Magento\Customer\Model\Session::class) ->disableOriginalConstructor() - ->setMethods([ - 'isLoggedIn', - 'setCustomerDataAsLoggedIn', - 'regenerateId', - 'setUsername', - ]) - ->getMock(); + ->setMethods( + [ + 'isLoggedIn', + 'setCustomerDataAsLoggedIn', + 'regenerateId', + 'setUsername', + ] + )->getMock(); $this->accountManagement = $this->getMockBuilder(\Magento\Customer\Api\AccountManagementInterface::class) ->getMockForAbstractClass(); @@ -253,10 +254,12 @@ public function testExecuteSuccessCustomRedirect() $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMockForAbstractClass(); @@ -334,10 +337,12 @@ public function testExecuteSuccess() $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMockForAbstractClass(); @@ -424,10 +429,12 @@ public function testExecuteWithException( $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $exception = new $exceptionData['exception'](__($exceptionData['message'])); @@ -486,11 +493,12 @@ protected function prepareContext() $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) ->disableOriginalConstructor() - ->setMethods([ - 'isPost', - 'getPost', - ]) - ->getMock(); + ->setMethods( + [ + 'isPost', + 'getPost', + ] + )->getMock(); $this->resultRedirect = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) ->disableOriginalConstructor() From 6f33211850d2c2666b99278b23200cd542ae20d2 Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Mon, 24 Jun 2019 16:23:19 -0500 Subject: [PATCH 137/372] MC-16284: Visible message alert --- .../Adminhtml/Product/Gallery/Upload.php | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php index ff7311e931755..779617254f6ad 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php @@ -8,6 +8,7 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\LocalizedException; class Upload extends \Magento\Backend\App\Action implements HttpPostActionInterface { @@ -23,6 +24,16 @@ class Upload extends \Magento\Backend\App\Action implements HttpPostActionInterf */ protected $resultRawFactory; + /** + * @var array + */ + private $allowedMimeTypes = [ + 'jpg' => 'image/jpg', + 'jpeg' => 'image/jpeg', + 'gif' => 'image/png', + 'png' => 'image/gif' + ]; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory @@ -45,7 +56,12 @@ public function execute() \Magento\MediaStorage\Model\File\Uploader::class, ['fileId' => 'image'] ); - $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']); + $uploader->setAllowedExtensions($this->getAllowedExtensions()); + + if (!$uploader->checkMimeType($this->getAllowedMimeTypes())) { + throw new LocalizedException(__('Disallowed File Type.')); + } + /** @var \Magento\Framework\Image\Adapter\AdapterInterface $imageAdapter */ $imageAdapter = $this->_objectManager->get(\Magento\Framework\Image\AdapterFactory::class)->create(); $uploader->addValidateCallback('catalog_product_image', $imageAdapter, 'validateUploadFile'); @@ -78,4 +94,24 @@ public function execute() $response->setContents(json_encode($result)); return $response; } + + /** + * Get the set of allowed file extensions. + * + * @return array + */ + private function getAllowedExtensions() + { + return array_keys($this->allowedMimeTypes); + } + + /** + * Get the set of allowed mime types. + * + * @return array + */ + private function getAllowedMimeTypes() + { + return array_values($this->allowedMimeTypes); + } } From 31caade6fa679b6c492120cd73ef3d0c50f9b00f Mon Sep 17 00:00:00 2001 From: Andrew Molina Date: Mon, 24 Jun 2019 16:39:30 -0500 Subject: [PATCH 138/372] MC-16284: Visible message alert --- .../Catalog/Controller/Adminhtml/Product/Gallery/Upload.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php index 779617254f6ad..820f2e5e5b8cd 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php @@ -1,6 +1,5 @@ Date: Mon, 24 Jun 2019 17:45:41 -0500 Subject: [PATCH 139/372] MC-16110: Fixing column name for store --- .../Listing/Column/Store/Options.php | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php index 1fc13390e30b5..907eb74e20fa2 100644 --- a/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php +++ b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php @@ -68,6 +68,26 @@ public function toOptionArray() return $this->options; } + /** + * Sanitize website/store option name + * + * @param string $name + * + * @return string + */ + protected function sanitizeName($name) + { + $matches = []; + preg_match('/\$[:]*{(.)*}/', $name, $matches); + if (count($matches) > 0) { + $name = $this->escaper->escapeHtml($this->escaper->escapeJs($name)); + } else { + $name = $this->escaper->escapeHtml($name); + } + + return $name; + } + /** * Generate current options * @@ -88,20 +108,20 @@ protected function generateCurrentOptions() /** @var \Magento\Store\Model\Store $store */ foreach ($storeCollection as $store) { if ($store->getGroupId() == $group->getId()) { - $name = $this->escaper->escapeHtml($store->getName()); + $name = $this->sanitizeName($store->getName()); $stores[$name]['label'] = str_repeat(' ', 8) . $name; $stores[$name]['value'] = $store->getId(); } } if (!empty($stores)) { - $name = $this->escaper->escapeHtml($group->getName()); + $name = $this->sanitizeName($group->getName()); $groups[$name]['label'] = str_repeat(' ', 4) . $name; $groups[$name]['value'] = array_values($stores); } } } if (!empty($groups)) { - $name = $this->escaper->escapeHtml($website->getName()); + $name = $this->sanitizeName($website->getName()); $this->currentOptions[$name]['label'] = $name; $this->currentOptions[$name]['value'] = array_values($groups); } From 6db05a87e98474826e406890ef9d0643e279d568 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 24 Jun 2019 23:00:18 -0500 Subject: [PATCH 140/372] MC-16724: Prevent errors from incorrect import data --- .../Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php index 681e62d159863..7f2ff2086df91 100644 --- a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php +++ b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php @@ -201,7 +201,7 @@ public function testExecuteWithException() '[Page ID: 1] Error message', '[Page ID: 1] Something went wrong while saving the page.' ], - + 'error' => true ] ) ->willReturnSelf(); From 6705536c470405e535374c8c226b8b878fb68bae Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Wed, 26 Jun 2019 14:43:38 -0500 Subject: [PATCH 141/372] MC-17806: Store name rendering in customer section - Resolved template issue for store name in customer admin section - Updated unit test for related issue --- app/code/Magento/Store/Model/System/Store.php | 6 ++++++ .../Store/Test/Unit/Model/System/StoreTest.php | 9 +++++---- .../Ui/view/base/web/js/grid/editing/record.js | 5 +++++ .../web/js/lib/knockout/bindings/optgroup.js | 17 ++++++++++++----- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Store/Model/System/Store.php b/app/code/Magento/Store/Model/System/Store.php index 86eec555f1d59..f0ec7a375add4 100644 --- a/app/code/Magento/Store/Model/System/Store.php +++ b/app/code/Magento/Store/Model/System/Store.php @@ -152,6 +152,12 @@ public function getStoreValuesForForm($empty = false, $all = false) } } } + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); return $options; } diff --git a/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php index 9cc4bb6ac8e5b..a9208876eaa76 100644 --- a/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php @@ -262,14 +262,15 @@ public function getStoreValuesForFormDataProvider() 'storeGroupId' => $groupId, 'groupWebsiteId' => $websiteId, 'expectedResult' => [ - ['label' => '', 'value' => ''], - ['label' => __('All Store Views'), 'value' => 0], - ['label' => $websiteName, 'value' => []], + ['label' => '', 'value' => '','__disableTmpl' => true], + ['label' => __('All Store Views'), 'value' => 0,'__disableTmpl' => true], + ['label' => $websiteName, 'value' => [],'__disableTmpl' => true], [ 'label' => str_repeat($nonEscapableNbspChar, 4) . $groupName, 'value' => [ ['label' => str_repeat($nonEscapableNbspChar, 4) . $storeName, 'value' => $storeId] - ] + ], + '__disableTmpl' => true ], ] ], diff --git a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js index 9b8998368c5ff..14bed73a694c6 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js @@ -134,6 +134,11 @@ define([ field = utils.extend({}, fields.base, field); + field.__disableTmpl = { + label: true, + options: true + }; + return utils.template(field, { record: this, column: column diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index 2925c5859eddd..148256f72d01c 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -222,10 +222,14 @@ define([ ko.utils.setTextContent(option, allBindings.get('optionsCaption')); ko.selectExtensions.writeValue(option, undefined); } else if (typeof arrayEntry[optionsValue] === 'undefined') { // empty value === optgroup - option = utils.template(optgroupTmpl, { - label: arrayEntry[optionsText], - title: arrayEntry[optionsText + 'title'] - }); + if (arrayEntry['__disableTmpl']) { + option = ''; + } else { + option = utils.template(optgroupTmpl, { + label: arrayEntry[optionsText], + title: arrayEntry[optionsText + 'title'] + }); + } option = ko.utils.parseHtmlFragment(option)[0]; } else { @@ -302,11 +306,14 @@ define([ space = '\u2007\u2007\u2007'; obj[optionTitle] = applyToObject(option, optionsText + 'title', value); - if (disabled) { obj.disabled = disabled; } + if ("__disableTmpl" in option) { + obj.__disableTmpl = option.__disableTmpl; + } + label = label.replace(nbspRe, '').trim(); if (Array.isArray(value)) { From f4479aa992334e22c5fba0829c7b75c14821109e Mon Sep 17 00:00:00 2001 From: Cari Spruiell Date: Wed, 26 Jun 2019 15:05:48 -0500 Subject: [PATCH 142/372] MC-16112: Signifyd Guarantee Option - fix options, actions, mass actions rendering --- .../Catalog/Ui/Component/Product/MassAction.php | 2 +- .../Magento/Translation/Model/Inline/Parser.php | 13 ++++++++++++- .../Component/Form/Element/AbstractOptionsField.php | 7 +++++++ app/code/Magento/Ui/Component/MassAction.php | 2 +- .../Framework/View/Element/UiComponent/Context.php | 8 ++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php index 894e2b701b5ac..e54605fbe3ee1 100644 --- a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php +++ b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php @@ -49,7 +49,7 @@ public function prepare() : void foreach ($this->getChildComponents() as $actionComponent) { $actionType = $actionComponent->getConfiguration()['type']; if ($this->isActionAllowed($actionType)) { - $config['actions'][] = $actionComponent->getConfiguration(); + $config['actions'][] = array_merge($actionComponent->getConfiguration(), ['__disableTmpl' => true]); } } $origConfig = $this->getConfiguration(); diff --git a/app/code/Magento/Translation/Model/Inline/Parser.php b/app/code/Magento/Translation/Model/Inline/Parser.php index e0b2ce40405d1..9dc123854e871 100644 --- a/app/code/Magento/Translation/Model/Inline/Parser.php +++ b/app/code/Magento/Translation/Model/Inline/Parser.php @@ -6,6 +6,9 @@ namespace Magento\Translation\Model\Inline; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Escaper; + /** * This class is responsible for parsing content and applying necessary html element * wrapping and client scripts for inline translation. @@ -196,6 +199,9 @@ public function processAjaxPost(array $translateParams) /** @var $validStoreId int */ $validStoreId = $this->_storeManager->getStore()->getId(); + /** @var $escaper Escaper */ + $escaper = ObjectManager::getInstance()->get(Escaper::class); + /** @var $resource \Magento\Translation\Model\ResourceModel\StringUtils */ $resource = $this->_resourceFactory->create(); foreach ($translateParams as $param) { @@ -209,7 +215,12 @@ public function processAjaxPost(array $translateParams) $storeId = $validStoreId; } } - $resource->saveTranslate($param['original'], $param['custom'], null, $storeId); + $resource->saveTranslate( + $param['original'], + $escaper->escapeHtml($param['custom']), + null, + $storeId + ); } return $this->getCacheManger()->updateAndGetTranslations(); diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php index 09583f65bf157..55b4ae15cdce1 100644 --- a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php +++ b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php @@ -59,6 +59,13 @@ public function prepare() if (empty($config['rawOptions'])) { $options = $this->convertOptionsValueToString($options); } + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); + $config['options'] = array_values(array_merge_recursive($config['options'], $options)); } $this->setData('config', (array)$config); diff --git a/app/code/Magento/Ui/Component/MassAction.php b/app/code/Magento/Ui/Component/MassAction.php index 4cca8d4c012bb..5af263dd861ce 100644 --- a/app/code/Magento/Ui/Component/MassAction.php +++ b/app/code/Magento/Ui/Component/MassAction.php @@ -28,7 +28,7 @@ public function prepare() if ($disabledAction) { continue; } - $config['actions'][] = $componentConfig; + $config['actions'][] = array_merge($componentConfig, ['__disableTmpl' => true]); } $origConfig = $this->getConfiguration(); diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index fbb84712b2afd..e95a9d44edbbd 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -382,6 +382,14 @@ protected function prepareDataSource(array & $data, UiComponentInterface $compon } } $data = $component->prepareDataSource($data); + foreach ($data['data']['items'] as & $item) { + $name = $component->getData('name'); + if (array_key_exists($name, $item) && is_array($item[$name])) { + foreach ($item[$name] as $action => &$actionItem) { + !is_array($actionItem) ?: $actionItem['__disableTmpl'] = true; + } + } + } } /** From f829086961d62dad8d185cbf112f6d6d5547e113 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Wed, 26 Jun 2019 16:27:44 -0500 Subject: [PATCH 143/372] MC-17806: Store name rendering in customer section - Resolved static and integration test failures --- .../base/web/js/lib/knockout/bindings/optgroup.js | 2 +- .../UrlRewrite/Block/Catalog/Edit/FormTest.php | 15 +++++++++------ .../UrlRewrite/Block/Cms/Page/Edit/FormTest.php | 5 +++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index 148256f72d01c..81ce64f64ce55 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -222,7 +222,7 @@ define([ ko.utils.setTextContent(option, allBindings.get('optionsCaption')); ko.selectExtensions.writeValue(option, undefined); } else if (typeof arrayEntry[optionsValue] === 'undefined') { // empty value === optgroup - if (arrayEntry['__disableTmpl']) { + if (arrayEntry.__disableTmpl) { option = ''; } else { option = utils.template(optgroupTmpl, { diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php index 8dcc309514733..c1cfa3cf02d50 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php @@ -234,10 +234,11 @@ public static function getEntityStoresDataProvider() null, ['entity_id' => 3, 'store_ids' => [1]], [ - ['label' => 'Main Website', 'value' => []], + ['label' => 'Main Website', 'value' => [], '__disableTmpl' => true], [ 'label' => '    Main Website Store', - 'value' => [['label' => '    Default Store View', 'value' => 1]] + 'value' => [['label' => '    Default Store View', 'value' => 1]], + '__disableTmpl' => true ] ], ], @@ -245,10 +246,11 @@ public static function getEntityStoresDataProvider() ['entity_id' => 2, 'name' => 'product2', 'url_key' => 'product2', 'store_ids' => [1]], null, [ - ['label' => 'Main Website', 'value' => []], + ['label' => 'Main Website', 'value' => [], '__disableTmpl' => true], [ 'label' => '    Main Website Store', - 'value' => [['label' => '    Default Store View', 'value' => 1]] + 'value' => [['label' => '    Default Store View', 'value' => 1]], + '__disableTmpl' => true ] ] ], @@ -256,10 +258,11 @@ public static function getEntityStoresDataProvider() ['entity_id' => 2, 'name' => 'product2', 'url_key' => 'product2', 'store_ids' => [1]], ['entity_id' => 3, 'name' => 'product3', 'url_key' => 'product3', 'store_ids' => [1]], [ - ['label' => 'Main Website', 'value' => []], + ['label' => 'Main Website', 'value' => [], '__disableTmpl' => true], [ 'label' => '    Main Website Store', - 'value' => [['label' => '    Default Store View', 'value' => 1]] + 'value' => [['label' => '    Default Store View', 'value' => 1]], + '__disableTmpl' => true ] ] ] diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php index c3b93efece456..5bbd276402157 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php @@ -78,10 +78,11 @@ public function testGetEntityStores() $form = $this->_getFormInstance($args); $expectedStores = [ - ['label' => 'Main Website', 'value' => []], + ['label' => 'Main Website', 'value' => [], '__disableTmpl' => true], [ 'label' => '    Main Website Store', - 'value' => [['label' => '    Default Store View', 'value' => 1]] + 'value' => [['label' => '    Default Store View', 'value' => 1]], + '__disableTmpl' => true ], ]; $this->assertEquals($expectedStores, $form->getElement('store_id')->getValues()); From 8572d837c58a8717dd6d75835c1b793e13cc8198 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Wed, 26 Jun 2019 16:58:21 -0500 Subject: [PATCH 144/372] MC-17806: Store name rendering in customer section - Resolved static test failures --- .../Ui/view/base/web/js/lib/knockout/bindings/optgroup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index 81ce64f64ce55..a1646e0cff068 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -310,7 +310,7 @@ define([ obj.disabled = disabled; } - if ("__disableTmpl" in option) { + if (option.hasOwnProperty("__disableTmpl")) { obj.__disableTmpl = option.__disableTmpl; } From c44db50097ca188f27cca2aced224ca57a61913b Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Thu, 27 Jun 2019 10:41:03 -0500 Subject: [PATCH 145/372] MC-17806: Store name rendering in customer section - Resolved static test failures --- app/code/Magento/Store/Model/System/Store.php | 2 ++ app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php | 3 +++ .../Ui/view/base/web/js/lib/knockout/bindings/optgroup.js | 2 +- .../Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php | 2 ++ .../Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Model/System/Store.php b/app/code/Magento/Store/Model/System/Store.php index f0ec7a375add4..53338a8fec5ae 100644 --- a/app/code/Magento/Store/Model/System/Store.php +++ b/app/code/Magento/Store/Model/System/Store.php @@ -118,6 +118,7 @@ public function getStoreValuesForForm($empty = false, $all = false) $options[] = ['label' => __('All Store Views'), 'value' => 0]; } + //phpcs:ignore Magento2.Functions.DiscouragedFunction $nonEscapableNbspChar = html_entity_decode(' ', ENT_NOQUOTES, 'UTF-8'); foreach ($this->_websiteCollection as $website) { @@ -404,6 +405,7 @@ public function getStoreCollection() /** * Load/Reload collection(s) by type + * * Allowed types: website, group, store or null for all * * @param string $type diff --git a/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php index a9208876eaa76..6befb28e35383 100644 --- a/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php @@ -6,6 +6,9 @@ namespace Magento\Store\Test\Unit\Model\System; +/** + * Class StoreTest covers Magento\Store\Model\System\Store. + */ class StoreTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index a1646e0cff068..1c4ab4eaebb47 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -310,7 +310,7 @@ define([ obj.disabled = disabled; } - if (option.hasOwnProperty("__disableTmpl")) { + if (option.hasOwnProperty('__disableTmpl')) { obj.__disableTmpl = option.__disableTmpl; } diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php index c1cfa3cf02d50..65cba5947ba05 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php @@ -190,6 +190,7 @@ public function testGetEntityStoresCategoryStoresException() * * @static * @return array + * phpcs:disable Magento2.Functions.StaticFunction */ public static function formPostInitDataProvider() { @@ -226,6 +227,7 @@ public static function formPostInitDataProvider() * * @static * @return array + * phpcs:disable Magento2.Functions.StaticFunction */ public static function getEntityStoresDataProvider() { diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php index 5bbd276402157..041a2c268a55a 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php @@ -111,6 +111,7 @@ public function testGetEntityStoresProductStoresException() * * @static * @return array + * phpcs:disable Magento2.Functions.StaticFunction */ public static function formPostInitDataProvider() { From 64421d8acf0004ac3f1688a825948a2770fb1331 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu Date: Thu, 27 Jun 2019 12:10:47 -0500 Subject: [PATCH 146/372] MC-17806: Store name rendering in customer section - Resolved static test failures --- .../Ui/view/base/web/js/lib/knockout/bindings/optgroup.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index 1c4ab4eaebb47..6ff7c1f673213 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -306,6 +306,7 @@ define([ space = '\u2007\u2007\u2007'; obj[optionTitle] = applyToObject(option, optionsText + 'title', value); + if (disabled) { obj.disabled = disabled; } From 1a3dacd7e27b8befa81ce7d2aedd45b4853dd273 Mon Sep 17 00:00:00 2001 From: Cari Spruiell Date: Thu, 27 Jun 2019 13:27:11 -0500 Subject: [PATCH 147/372] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Ui/Component/Product/MassActionTest.php | 24 ++++++---- .../Translation/Model/Inline/Parser.php | 47 +++++++++++-------- .../Form/Element/AbstractOptionsField.php | 13 +++-- .../Ui/Test/Unit/Component/MassActionTest.php | 6 ++- .../View/Element/UiComponent/Context.php | 15 ++++-- 5 files changed, 66 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php index dcd50d4739d70..1b2a58672a5c9 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php @@ -103,7 +103,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'first_action', 'label' => 'First Action', - 'url' => '/module/controller/firstAction' + 'url' => '/module/controller/firstAction', + '__disableTmpl' => true ], ], [ @@ -122,7 +123,8 @@ public function getPrepareDataProvider() : array 'label' => 'Second Sub Action 2', 'url' => '/module/controller/secondSubAction2' ], - ] + ], + '__disableTmpl' => true ], ], [ @@ -141,7 +143,8 @@ public function getPrepareDataProvider() : array 'label' => 'Second Sub Action 2', 'url' => '/module/controller/disable' ], - ] + ], + '__disableTmpl' => true ], ], [ @@ -160,7 +163,8 @@ public function getPrepareDataProvider() : array 'label' => 'Second Sub Action 2', 'url' => '/module/controller/disable' ], - ] + ], + '__disableTmpl' => true ], false, false @@ -170,7 +174,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'delete', 'label' => 'First Action', - 'url' => '/module/controller/delete' + 'url' => '/module/controller/delete', + '__disableTmpl' => true ], ], [ @@ -178,7 +183,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'delete', 'label' => 'First Action', - 'url' => '/module/controller/delete' + 'url' => '/module/controller/delete', + '__disableTmpl' => true ], false, false @@ -188,7 +194,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'delete', 'label' => 'First Action', - 'url' => '/module/controller/attributes' + 'url' => '/module/controller/attributes', + '__disableTmpl' => true ], ], [ @@ -196,7 +203,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'delete', 'label' => 'First Action', - 'url' => '/module/controller/attributes' + 'url' => '/module/controller/attributes', + '__disableTmpl' => true ], false, false diff --git a/app/code/Magento/Translation/Model/Inline/Parser.php b/app/code/Magento/Translation/Model/Inline/Parser.php index 9dc123854e871..c64622acbb6c0 100644 --- a/app/code/Magento/Translation/Model/Inline/Parser.php +++ b/app/code/Magento/Translation/Model/Inline/Parser.php @@ -6,12 +6,8 @@ namespace Magento\Translation\Model\Inline; -use Magento\Framework\App\ObjectManager; -use Magento\Framework\Escaper; - /** - * This class is responsible for parsing content and applying necessary html element - * wrapping and client scripts for inline translation. + * Parses content and applies necessary html element wrapping and client scripts for inline translation. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -135,6 +131,8 @@ class Parser implements \Magento\Framework\Translate\Inline\ParserInterface private $relatedCacheTypes; /** + * Return cache manager + * * @return \Magento\Translation\Model\Inline\CacheManager * * @deprecated 100.1.0 @@ -152,8 +150,8 @@ private function getCacheManger() /** * Initialize base inline translation model * - * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Translation\Model\ResourceModel\StringUtilsFactory $resource + * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Zend_Filter_Interface $inputFilter * @param \Magento\Framework\App\State $appState * @param \Magento\Framework\App\Cache\TypeListInterface $appCache @@ -199,9 +197,6 @@ public function processAjaxPost(array $translateParams) /** @var $validStoreId int */ $validStoreId = $this->_storeManager->getStore()->getId(); - /** @var $escaper Escaper */ - $escaper = ObjectManager::getInstance()->get(Escaper::class); - /** @var $resource \Magento\Translation\Model\ResourceModel\StringUtils */ $resource = $this->_resourceFactory->create(); foreach ($translateParams as $param) { @@ -217,7 +212,7 @@ public function processAjaxPost(array $translateParams) } $resource->saveTranslate( $param['original'], - $escaper->escapeHtml($param['custom']), + $param['custom'], null, $storeId ); @@ -247,7 +242,7 @@ protected function _validateTranslationParams(array $translateParams) /** * Apply input filter to values of translation parameters * - * @param array &$translateParams + * @param array $translateParams * @param array $fieldNames Names of fields values of which are to be filtered * @return void */ @@ -371,7 +366,7 @@ protected function _applySpecialTagsFormat($tagHtml, $tagName, $trArr) * Format translation for simple tags. Added translate mode attribute for vde requests. * * @param string $tagHtml - * @param string $tagName + * @param string $tagName * @param array $trArr * @return string */ @@ -397,7 +392,7 @@ protected function _applySimpleTagsFormat($tagHtml, $tagName, $trArr) * Get translate data by regexp * * @param string $regexp - * @param string &$text + * @param string $text * @param string|array $locationCallback * @param array $options * @return array @@ -412,7 +407,7 @@ private function _getTranslateData($regexp, &$text, $locationCallback, $options 'shown' => htmlspecialchars_decode($matches[1][0]), 'translated' => htmlspecialchars_decode($matches[2][0]), 'original' => htmlspecialchars_decode($matches[3][0]), - 'location' => htmlspecialchars_decode(call_user_func($locationCallback, $matches, $options)), + 'location' => htmlspecialchars_decode($locationCallback($matches, $options)), ] ); $text = substr_replace($text, $matches[1][0], $matches[0][1], strlen($matches[0][0])); @@ -523,16 +518,28 @@ private function _getHtmlQuote() */ private function _specialTags() { - $this->_translateTags($this->_content, $this->_allowedTagsGlobal, '_applySpecialTagsFormat'); - $this->_translateTags($this->_content, $this->_allowedTagsSimple, '_applySimpleTagsFormat'); + $this->_translateTags( + $this->_content, + $this->_allowedTagsGlobal, + function ($tagHtml, $tagName, $trArr) { + return $this->_applySpecialTagsFormat($tagHtml, $tagName, $trArr); + } + ); + $this->_translateTags( + $this->_content, + $this->_allowedTagsSimple, + function ($tagHtml, $tagName, $trArr) { + return $this->_applySimpleTagsFormat($tagHtml, $tagName, $trArr); + } + ); } /** * Prepare simple tags * - * @param string &$content + * @param string $content * @param array $tagsList - * @param string|array $formatCallback + * @param callable $formatCallback * @return void */ private function _translateTags(&$content, $tagsList, $formatCallback) @@ -586,10 +593,10 @@ private function _translateTags(&$content, $tagsList, $formatCallback) if (array_key_exists($tagName, $this->_allowedTagsGlobal) && $tagBodyOpenStartPosition > $tagMatch[0][1] ) { - $tagHtmlHead = call_user_func([$this, $formatCallback], $tagHtml, $tagName, $trArr); + $tagHtmlHead = $formatCallback($tagHtml, $tagName, $trArr); $headTranslateTags .= substr($tagHtmlHead, strlen($tagHtml)); } else { - $tagHtml = call_user_func([$this, $formatCallback], $tagHtml, $tagName, $trArr); + $tagHtml = $formatCallback($tagHtml, $tagName, $trArr); } } diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php index 55b4ae15cdce1..1229fbeec77c7 100644 --- a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php +++ b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php @@ -9,6 +9,8 @@ use Magento\Framework\View\Element\UiComponent\ContextInterface; /** + * Class AbstractOptionsField + * * @api * @since 100.1.0 */ @@ -91,11 +93,14 @@ abstract public function getIsSelected($optionValue); */ protected function convertOptionsValueToString(array $options) { - array_walk($options, function (&$value) { - if (isset($value['value']) && is_scalar($value['value'])) { - $value['value'] = (string)$value['value']; + array_walk( + $options, + function (&$value) { + if (isset($value['value']) && is_scalar($value['value'])) { + $value['value'] = (string)$value['value']; + } } - }); + ); return $options; } } diff --git a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php index b2f494351597f..c2e064bb3b069 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php @@ -104,7 +104,8 @@ public function getPrepareDataProvider() [ 'type' => 'first_action', 'label' => 'First Action', - 'url' => '/module/controller/firstAction' + 'url' => '/module/controller/firstAction', + '__disableTmpl' => true ], ], [ @@ -123,7 +124,8 @@ public function getPrepareDataProvider() 'label' => 'Second Sub Action 2', 'url' => '/module/controller/secondSubAction2' ], - ] + ], + '__disableTmpl' => true ], ], ]; diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index e95a9d44edbbd..62ee657bbd6d0 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -372,6 +372,7 @@ public function getUrl($route = '', $params = []) * @param array $data * @param UiComponentInterface $component * @return void + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ protected function prepareDataSource(array & $data, UiComponentInterface $component) { @@ -382,11 +383,15 @@ protected function prepareDataSource(array & $data, UiComponentInterface $compon } } $data = $component->prepareDataSource($data); - foreach ($data['data']['items'] as & $item) { - $name = $component->getData('name'); - if (array_key_exists($name, $item) && is_array($item[$name])) { - foreach ($item[$name] as $action => &$actionItem) { - !is_array($actionItem) ?: $actionItem['__disableTmpl'] = true; + if (isset($data['data']['items'])) { + foreach ($data['data']['items'] as & $item) { + $name = $component->getData('name'); + if (array_key_exists($name, $item) && is_array($item[$name])) { + foreach ($item[$name] as $action => &$actionItem) { + if (is_array($actionItem)) { + $actionItem['__disableTmpl'] = true; + } + } } } } From 269137ffcd98c696c59f9da6dd3bcf8a499b602f Mon Sep 17 00:00:00 2001 From: Cari Spruiell Date: Thu, 27 Jun 2019 15:38:13 -0500 Subject: [PATCH 148/372] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Test/Unit/Ui/Component/Product/MassActionTest.php | 3 +++ .../Magento/Catalog/Ui/Component/Product/MassAction.php | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php index 1b2a58672a5c9..c704d9f89581d 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php @@ -12,6 +12,9 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Element\UiComponent\ContextInterface; +/** + * MassAction test + */ class MassActionTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php index e54605fbe3ee1..8db1bf8268b66 100644 --- a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php +++ b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php @@ -12,6 +12,9 @@ use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Ui\Component\AbstractComponent; +/** + * Class MassAction + */ class MassAction extends AbstractComponent { const NAME = 'massaction'; @@ -40,7 +43,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function prepare() : void { @@ -64,7 +67,7 @@ public function prepare() : void } /** - * {@inheritdoc} + * @inheritdoc */ public function getComponentName() : string { From 03d5342b206b0b4fa9fefa7e6df0ec61229021e7 Mon Sep 17 00:00:00 2001 From: Cari Spruiell Date: Fri, 28 Jun 2019 11:09:41 -0500 Subject: [PATCH 149/372] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Ui/Component/Listing/Columns/ProductActions.php | 1 + .../Cms/Ui/Component/Listing/Column/BlockActions.php | 2 ++ .../Cms/Ui/Component/Listing/Column/PageActions.php | 7 +++++-- .../Customer/Ui/Component/Listing/Column/Actions.php | 1 + .../Ui/Component/Listing/Column/GroupActions.php | 4 +++- .../Ui/Component/Listing/Column/SynonymActions.php | 4 +++- .../Theme/Ui/Component/Listing/Column/EditAction.php | 3 ++- .../Theme/Ui/Component/Listing/Column/ViewAction.php | 3 ++- .../Framework/View/Element/UiComponent/Context.php | 12 ------------ 9 files changed, 19 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php index 0c4efa87c1a32..596b0f4118599 100644 --- a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php +++ b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php @@ -60,6 +60,7 @@ public function prepareDataSource(array $dataSource) ), 'label' => __('Edit'), 'hidden' => false, + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php index 6e9eef47281c0..65940c5d7b4f9 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php @@ -70,6 +70,7 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Edit'), + '__disableTmpl' => true, ], 'delete' => [ 'href' => $this->urlBuilder->getUrl( @@ -84,6 +85,7 @@ public function prepareDataSource(array $dataSource) 'message' => __('Are you sure you want to delete a %1 record?', $title), ], 'post' => true, + '__disableTmpl' => true, ], ]; } diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php index cfac3bbf54956..ca86aec033554 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php @@ -77,7 +77,8 @@ public function prepareDataSource(array $dataSource) if (isset($item['page_id'])) { $item[$name]['edit'] = [ 'href' => $this->urlBuilder->getUrl($this->editUrl, ['page_id' => $item['page_id']]), - 'label' => __('Edit') + 'label' => __('Edit'), + '__disableTmpl' => true, ]; $title = $this->getEscaper()->escapeHtml($item['title']); $item[$name]['delete'] = [ @@ -89,6 +90,7 @@ public function prepareDataSource(array $dataSource) '__disableTmpl' => true, ], 'post' => true, + '__disableTmpl' => true, ]; } if (isset($item['identifier'])) { @@ -98,7 +100,8 @@ public function prepareDataSource(array $dataSource) isset($item['_first_store_id']) ? $item['_first_store_id'] : null, isset($item['store_code']) ? $item['store_code'] : null ), - 'label' => __('View') + 'label' => __('View'), + '__disableTmpl' => true, ]; } } diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php index d6a4067ef3db6..9441beeb7dc61 100644 --- a/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php +++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php @@ -60,6 +60,7 @@ public function prepareDataSource(array $dataSource) ), 'label' => __('Edit'), 'hidden' => false, + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php index 6870bd1136d10..12f6f2705125b 100644 --- a/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php +++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php @@ -79,6 +79,7 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Edit'), + '__disableTmpl' => true ], ]; @@ -102,7 +103,8 @@ public function prepareDataSource(array $dataSource) $this->escaper->escapeJs($title) ) ], - 'post' => true + 'post' => true, + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php b/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php index 8cc9b809ff888..f42ce50d2804b 100644 --- a/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php +++ b/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php @@ -63,11 +63,13 @@ public function prepareDataSource(array $dataSource) 'confirm' => [ 'title' => __('Delete'), 'message' => __('Are you sure you want to delete synonym group with id: %1?', $item['group_id']) - ] + ], + '__disableTmpl' => true ]; $item[$name]['edit'] = [ 'href' => $this->urlBuilder->getUrl(self::SYNONYM_URL_PATH_EDIT, ['group_id' => $item['group_id']]), 'label' => __('View/Edit'), + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php b/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php index 801f30ce30b0a..1eeeaccff88ce 100644 --- a/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php +++ b/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php @@ -73,7 +73,8 @@ public function prepareDataSource(array $dataSource) 'scope_id' => $scopeId, ] ), - 'label' => __('Edit') + 'label' => __('Edit'), + '__disableTmpl' => true, ] ]; } diff --git a/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php b/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php index 774d5bab660af..9e47e2c52bddf 100644 --- a/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php +++ b/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php @@ -65,7 +65,8 @@ public function prepareDataSource(array $dataSource) : array $urlEntityParamName => $item[$indexField] ] ), - 'label' => __('View') + 'label' => __('View'), + '__disableTmpl' => true, ] ]; } diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index 62ee657bbd6d0..c49832dac9636 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -383,18 +383,6 @@ protected function prepareDataSource(array & $data, UiComponentInterface $compon } } $data = $component->prepareDataSource($data); - if (isset($data['data']['items'])) { - foreach ($data['data']['items'] as & $item) { - $name = $component->getData('name'); - if (array_key_exists($name, $item) && is_array($item[$name])) { - foreach ($item[$name] as $action => &$actionItem) { - if (is_array($actionItem)) { - $actionItem['__disableTmpl'] = true; - } - } - } - } - } } /** From 0ff326fc4574fbf1dc7140adad69bc46c22141b6 Mon Sep 17 00:00:00 2001 From: Cari Spruiell Date: Fri, 28 Jun 2019 11:13:03 -0500 Subject: [PATCH 150/372] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Magento/Framework/View/Element/UiComponent/Context.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index c49832dac9636..fbb84712b2afd 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -372,7 +372,6 @@ public function getUrl($route = '', $params = []) * @param array $data * @param UiComponentInterface $component * @return void - * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ protected function prepareDataSource(array & $data, UiComponentInterface $component) { From 05cd916091d467c7c7ead9ce537d30d4c0507636 Mon Sep 17 00:00:00 2001 From: Cari Spruiell Date: Fri, 28 Jun 2019 12:54:42 -0500 Subject: [PATCH 151/372] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Listing/Column/BlockActionsTest.php | 13 +++-- .../Listing/Column/PageActionsTest.php | 4 +- .../Component/Listing/Column/ActionsTest.php | 6 ++- .../Listing/Column/EditActionTest.php | 4 ++ .../Listing/Column/ViewActionTest.php | 50 +++++++++++++++---- 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php index 6981a7983049e..4ffe4a6ad8774 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php @@ -56,10 +56,13 @@ protected function setUp() ->setMethods(['escapeHtmlAttr']) ->getMock(); - $this->blockActions = $objectManager->getObject(BlockActions::class, [ - 'context' => $context, - 'urlBuilder' => $this->urlBuilder - ]); + $this->blockActions = $objectManager->getObject( + BlockActions::class, + [ + 'context' => $context, + 'urlBuilder' => $this->urlBuilder + ] + ); $objectManager->setBackwardCompatibleProperty($this->blockActions, 'escaper', $this->escaper); } @@ -93,6 +96,7 @@ public function testPrepareDataSource() 'edit' => [ 'href' => 'test/url/edit', 'label' => __('Edit'), + '__disableTmpl' => true, ], 'delete' => [ 'href' => 'test/url/delete', @@ -102,6 +106,7 @@ public function testPrepareDataSource() 'message' => __('Are you sure you want to delete a %1 record?', $title), ], 'post' => true, + '__disableTmpl' => true, ], ], ], diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php index 32bbeed0788a3..53d8ee5220768 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php @@ -65,6 +65,7 @@ public function testPrepareItemsByPageId() 'edit' => [ 'href' => 'test/url/edit', 'label' => __('Edit'), + '__disableTmpl' => true, ], 'delete' => [ 'href' => 'test/url/delete', @@ -75,6 +76,7 @@ public function testPrepareItemsByPageId() '__disableTmpl' => true, ], 'post' => true, + '__disableTmpl' => true, ], ], ], @@ -84,7 +86,6 @@ public function testPrepareItemsByPageId() ->method('escapeHtml') ->with($title) ->willReturn($title); - // Configure mocks and object data $urlBuilderMock->expects($this->any()) ->method('getUrl') @@ -106,7 +107,6 @@ public function testPrepareItemsByPageId() ], ] ); - $model->setName($name); $items = $model->prepareDataSource($items); // Run test diff --git a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php index 056c7e71e1827..4a16acd98d827 100644 --- a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php +++ b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php @@ -7,6 +7,9 @@ use Magento\Customer\Ui\Component\Listing\Column\Actions; +/** + * Class ActionsTest + */ class ActionsTest extends \PHPUnit\Framework\TestCase { /** @var Actions */ @@ -64,7 +67,8 @@ public function testPrepareDataSource() 'edit' => [ 'href' => 'http://magento.com/customer/index/edit', 'label' => new \Magento\Framework\Phrase('Edit'), - 'hidden' => false + 'hidden' => false, + '__disableTmpl' => true, ] ] ], diff --git a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php index 2ac959d0a9881..22cc1c9e89fbe 100644 --- a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php +++ b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php @@ -9,6 +9,9 @@ use Magento\Store\Model\ScopeInterface; use Magento\Theme\Ui\Component\Listing\Column\EditAction; +/** + * Class EditActionTest + */ class EditActionTest extends \PHPUnit\Framework\TestCase { /** @var EditAction */ @@ -64,6 +67,7 @@ public function testPrepareDataSource($dataSourceItem, $scope, $scopeId) 'edit' => [ 'href' => 'http://magento.com/theme/design_config/edit', 'label' => new \Magento\Framework\Phrase('Edit'), + '__disableTmpl' => true, ] ], ]; diff --git a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php index 03d1fe70f2f07..5e2fe51043885 100644 --- a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php +++ b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php @@ -99,20 +99,52 @@ public function getPrepareDataSourceDataProvider() { return [ [ - ['name' => 'itemName', 'config' => []], - [['itemName' => '', 'entity_id' => 1]], - [['itemName' => ['view' => ['href' => 'url', 'label' => __('View')]], 'entity_id' => 1]], + [ + 'name' => 'itemName', + 'config' => [] + ], + [ + ['itemName' => '', 'entity_id' => 1] + ], + [ + [ + 'itemName' => [ + 'view' => [ + 'href' => 'url', + 'label' => __('View'), + '__disableTmpl' => true, + ] + ], + 'entity_id' => 1 + ] + ], '#', ['id' => 1] ], [ - ['name' => 'itemName', 'config' => [ - 'viewUrlPath' => 'url_path', - 'urlEntityParamName' => 'theme_id', - 'indexField' => 'theme_id'] + [ + 'name' => 'itemName', + 'config' => [ + 'viewUrlPath' => 'url_path', + 'urlEntityParamName' => 'theme_id', + 'indexField' => 'theme_id' + ] + ], + [ + ['itemName' => '', 'theme_id' => 2] + ], + [ + [ + 'itemName' => [ + 'view' => [ + 'href' => 'url', + 'label' => __('View'), + '__disableTmpl' => true, + ] + ], + 'theme_id' => 2 + ] ], - [['itemName' => '', 'theme_id' => 2]], - [['itemName' => ['view' => ['href' => 'url', 'label' => __('View')]], 'theme_id' => 2]], 'url_path', ['theme_id' => 2] ] From cdf56a8105361fa4c4a339369b0bfd0128cee76a Mon Sep 17 00:00:00 2001 From: Roman Hanin Date: Mon, 8 Jul 2019 09:06:51 -0500 Subject: [PATCH 152/372] MC-17309: Sql builder readability --- .../Rule/Model/Condition/Sql/Builder.php | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 33e1bf97c3474..961474b9d286f 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -145,11 +145,8 @@ protected function _joinTablesToCollection( * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - protected function _getMappedSqlCondition( - AbstractCondition $condition, - string $value = '', - bool $isDefaultStoreUsed = true - ): string { + protected function _getMappedSqlCondition(AbstractCondition $condition, string $value = ''): string + { $argument = $condition->getMappedSqlField(); // If rule hasn't valid argument - create negative expression to prevent incorrect rule behavior. @@ -241,6 +238,7 @@ protected function _getMappedSqlCombination( * @param AbstractCollection $collection * @param Combine $combine * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ public function attachConditionToCollection( AbstractCollection $collection, @@ -250,29 +248,45 @@ public function attachConditionToCollection( $this->_joinTablesToCollection($collection, $combine); $whereExpression = (string)$this->_getMappedSqlCombination($combine); if (!empty($whereExpression)) { - if (!empty($combine->getConditions())) { - $conditions = ''; - $attributeField = ''; - foreach ($combine->getConditions() as $condition) { - if ($condition->getData('attribute') === \Magento\Catalog\Api\Data\ProductInterface::SKU) { - $conditions = $condition->getData('value'); - $attributeField = $condition->getMappedSqlField(); - } - } + $collection->getSelect()->where($whereExpression); + $this->buildConditions($collection, $combine); + } + } - $collection->getSelect()->where($whereExpression); + /** + * Build sql conditions from combination. + * + * @param AbstractCollection $collection + * @param Combine $combine + * @return void + */ + private function buildConditions(AbstractCollection $collection, Combine $combine) : void + { + if (!empty($combine->getConditions())) { + $conditions = ''; + $attributeField = ''; + foreach ($combine->getConditions() as $condition) { + if ($condition->getData('attribute') === \Magento\Catalog\Api\Data\ProductInterface::SKU) { + $conditions = $condition->getData('value'); + $attributeField = $condition->getMappedSqlField(); + } + } - if (!empty($conditions) && !empty($attributeField)) { - $conditions = explode(',', $conditions); - foreach ($conditions as &$condition) { - $condition = "'" . trim($condition) . "'"; - } - $conditions = implode(', ', $conditions); - $collection->getSelect()->order("FIELD($attributeField, $conditions)"); + if (!empty($conditions) && !empty($attributeField)) { + $conditions = explode(',', $conditions); + foreach ($conditions as &$condition) { + $condition = trim($condition); } - } else { - // Select ::where method adds braces even on empty expression - $collection->getSelect()->where($whereExpression); + $conditions = implode(', ', $conditions); + $collection->getSelect()->order( + $this->_connection->quoteInto( + "FIELD(?, ?)", + [ + $attributeField, + $conditions + ] + ) + ); } } } From 60c3c25db3b0ad5eae6f700dfbb6d60d8f64314f Mon Sep 17 00:00:00 2001 From: Cari Spruiell Date: Mon, 8 Jul 2019 14:11:58 -0500 Subject: [PATCH 153/372] MC-16112: Signifyd Guarantee Option - fix test failure --- .../Magento/Ui/Component/Form/Element/AbstractOptionsField.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php index 1229fbeec77c7..d8d1733ffdef9 100644 --- a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php +++ b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php @@ -11,6 +11,7 @@ /** * Class AbstractOptionsField * + * phpcs:disable Magento2.Classes.AbstractApi * @api * @since 100.1.0 */ From 20ed50f4a77a961ad34869e3167dc3047a7cd7ad Mon Sep 17 00:00:00 2001 From: Roman Hanin Date: Tue, 9 Jul 2019 12:11:34 -0500 Subject: [PATCH 154/372] MC-17309: Sql builder readability --- app/code/Magento/Rule/Model/Condition/Sql/Builder.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 961474b9d286f..6b1692c9723db 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -149,9 +149,11 @@ protected function _getMappedSqlCondition(AbstractCondition $condition, string $ { $argument = $condition->getMappedSqlField(); - // If rule hasn't valid argument - create negative expression to prevent incorrect rule behavior. + // If rule hasn't valid argument - prevent incorrect rule behavior. if (empty($argument)) { return $this->_expressionFactory->create(['expression' => '1 = -1']); + } elseif (preg_match('/[^a-z0-9\-_\.\`]/i', $argument) > 0) { + throw new \Magento\Framework\Exception\LocalizedException(__('Invalid field')); } $conditionOperator = $condition->getOperatorForValidate(); @@ -192,7 +194,6 @@ protected function _getMappedSqlCondition(AbstractCondition $condition, string $ ); } } - return $this->_expressionFactory->create( ['expression' => $expression] ); From 06a7fcd3295aa5429ccae25c6080d1625fd0aa83 Mon Sep 17 00:00:00 2001 From: Roman Hanin Date: Tue, 9 Jul 2019 14:25:45 -0500 Subject: [PATCH 155/372] MC-17309: Sql builder readability --- app/code/Magento/Rule/Model/Condition/Sql/Builder.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 6b1692c9723db..f44b788354103 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -145,8 +145,11 @@ protected function _joinTablesToCollection( * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - protected function _getMappedSqlCondition(AbstractCondition $condition, string $value = ''): string - { + protected function _getMappedSqlCondition( + AbstractCondition $condition, + string $value = '', + bool $isDefaultStoreUsed = true + ): string { $argument = $condition->getMappedSqlField(); // If rule hasn't valid argument - prevent incorrect rule behavior. From 04f44c3295679ce5efbf21b37bafca8717887579 Mon Sep 17 00:00:00 2001 From: Mark Berube Date: Mon, 15 Jul 2019 14:12:33 -0500 Subject: [PATCH 156/372] MC-18101: Validate file deletion path on data export --- .../ImportExport/Controller/Adminhtml/Export/File/Delete.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Delete.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Delete.php index 6996ba90c3e10..4ba0d024ef68f 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Delete.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Delete.php @@ -67,6 +67,11 @@ public function execute() } $directory = $this->filesystem->getDirectoryRead(DirectoryList::VAR_DIR); $path = $directory->getAbsolutePath() . 'export/' . $fileName; + + if (!$directory->isFile($path)) { + throw new LocalizedException(__('Sorry, but the data is invalid or the file is not uploaded.')); + } + $this->file->deleteFile($path); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); From c98cfd565d5f660bca73221214ac8241105777e7 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Tue, 16 Jul 2019 16:54:17 +0300 Subject: [PATCH 157/372] MC-18099: Changes in Downloadable product upload controller --- .../Adminhtml/Downloadable/File/Upload.php | 30 +++++++++++------- .../Adminhtml/Downloadable/FileTest.php | 31 +++++++++++++++++-- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php index 83b2797050db9..c8f7a4ff4a507 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php @@ -7,6 +7,8 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Exception\FileSystemException; +use Magento\Framework\Exception\LocalizedException; /** * Class Upload @@ -76,23 +78,27 @@ public function __construct( */ public function execute() { - $type = $this->getRequest()->getParam('type'); - $tmpPath = ''; - if ($type == 'samples') { - $tmpPath = $this->_sample->getBaseTmpPath(); - } elseif ($type == 'links') { - $tmpPath = $this->_link->getBaseTmpPath(); - } elseif ($type == 'link_samples') { - $tmpPath = $this->_link->getBaseSampleTmpPath(); - } - try { + $type = $this->getRequest()->getParam('type'); + $tmpPath = ''; + if ($type == 'samples') { + $tmpPath = $this->_sample->getBaseTmpPath(); + } elseif ($type == 'links') { + $tmpPath = $this->_link->getBaseTmpPath(); + } elseif ($type == 'link_samples') { + $tmpPath = $this->_link->getBaseSampleTmpPath(); + } else { + throw new LocalizedException(__('Upload type can not be determined.')); + } + $uploader = $this->uploaderFactory->create(['fileId' => $type]); $result = $this->_fileHelper->uploadFromTmp($tmpPath, $uploader); if (!$result) { - throw new \Exception('File can not be moved from temporary folder to the destination folder.'); + throw new FileSystemException( + __('File can not be moved from temporary folder to the destination folder.') + ); } unset($result['tmp_name'], $result['path']); @@ -101,7 +107,7 @@ public function execute() $relativePath = rtrim($tmpPath, '/') . '/' . ltrim($result['file'], '/'); $this->storageDatabase->saveFile($relativePath); } - } catch (\Exception $e) { + } catch (\Throwable $e) { $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; } diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php index 60c2a41fae49f..ac35fa9a23b1d 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php @@ -1,4 +1,9 @@ [ + 'tmp_name' => 'test.txt', + 'name' => 'result.txt', + ], + ]; + $this->getRequest()->setPostValue($postData); + + $this->getRequest()->setMethod('POST'); + $this->dispatch('backend/admin/downloadable_file/upload'); + $body = $this->getResponse()->getBody(); + $result = Bootstrap::getObjectManager()->get(Json::class)->unserialize($body); + $this->assertEquals('Upload type can not be determined.', $result['error']); + $this->assertEquals(0, $result['errorcode']); + } } From 54986eddee7fc6311a03978640a17e3b9085c02f Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Tue, 16 Jul 2019 13:44:56 -0500 Subject: [PATCH 158/372] MC-17700: Downloadable Product links --- .../Mftf/Test/SearchEntityResultsTest.xml | 2 + ...ownloadableProductFromShoppingCartTest.xml | 2 + ...OnePageCheckoutWithAllProductTypesTest.xml | 2 + ...dDownloadableProductToShoppingCartTest.xml | 2 + ...oadableProductFromMiniShoppingCartTest.xml | 2 + .../StorefrontClearAllCompareProductsTest.xml | 2 + .../Console/Command/DomainsAddCommand.php | 118 ++++++++++++++ .../Console/Command/DomainsRemoveCommand.php | 120 ++++++++++++++ .../Console/Command/DomainsShowCommand.php | 79 +++++++++ .../Model/Link/ContentValidator.php | 29 +++- .../Model/Sample/ContentValidator.php | 24 ++- .../Model/Url/DomainValidator.php | 124 ++++++++++++++ .../Patch/Data/AddDownloadableHostsConfig.php | 151 ++++++++++++++++++ ...AddDefaultImageDownloadableProductTest.xml | 2 + ...AddDefaultVideoDownloadableProductTest.xml | 7 +- ...bleProductAndAssignItToCustomStoreTest.xml | 2 + ...wnloadableProductWithCustomOptionsTest.xml | 2 + ...loadableProductWithDefaultSetLinksTest.xml | 2 + ...eDownloadableProductWithGroupPriceTest.xml | 2 + ...nCreateDownloadableProductWithLinkTest.xml | 2 + ...DownloadableProductWithManageStockTest.xml | 2 + ...oadableProductWithOutOfStockStatusTest.xml | 2 + ...ownloadableProductWithSpecialPriceTest.xml | 2 + ...teDownloadableProductWithTierPriceText.xml | 6 + ...ductWithoutFillingQuantityAndStockTest.xml | 2 + ...wnloadableProductWithoutTaxClassIdTest.xml | 2 + .../AdminDeleteDownloadableProductTest.xml | 2 + ...oveDefaultImageDownloadableProductTest.xml | 2 + ...oveDefaultVideoDownloadableProductTest.xml | 6 + ...ceCatalogSearchDownloadableProductTest.xml | 20 +++ ...loadableProductFromGuestToCustomerTest.xml | 2 + ...ductsListWidgetDownloadableProductTest.xml | 7 + .../Unit/Model/Link/ContentValidatorTest.php | 13 ++ app/code/Magento/Downloadable/etc/di.xml | 9 ++ app/code/Magento/Downloadable/i18n/en_US.csv | 1 + .../Api/ProductRepositoryInterfaceTest.php | 48 +++++- .../Api/ProductRepositoryTest.php | 18 +++ .../Mtf/Util/Command/Cli/EnvWhitelist.php | 40 +++++ .../ProductTypeSwitchingOnUpdateTest.php | 15 +- .../AddProductsToShoppingCartEntityTest.php | 16 +- ...ePageCheckoutOfflinePaymentMethodsTest.php | 29 ++++ ...eProductFromMiniShoppingCartEntityTest.php | 24 ++- .../TestCase/PrintOrderFrontendGuestTest.php | 18 ++- .../AddProductToWishlistEntityTest.php | 27 +++- ...ProductInCustomerWishlistOnBackendTest.php | 27 +++- ...ProductInCustomerWishlistOnBackendTest.php | 27 +++- ...ote_with_downloadable_product_rollback.php | 8 + .../Model/Url/DomainValidatorTest.php | 93 +++++++++++ ...able_product_with_files_and_sample_url.php | 12 +- ...uct_with_files_and_sample_url_rollback.php | 11 ++ .../_files/product_downloadable.php | 25 ++- .../_files/product_downloadable_rollback.php | 24 ++- .../product_downloadable_with_files.php | 21 ++- 53 files changed, 1191 insertions(+), 46 deletions(-) create mode 100644 app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php create mode 100644 app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php create mode 100644 app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php create mode 100644 app/code/Magento/Downloadable/Model/Url/DomainValidator.php create mode 100644 app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php create mode 100644 dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/EnvWhitelist.php create mode 100644 dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml index 19db201e91f40..f98e715963d2e 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml @@ -368,6 +368,7 @@ + @@ -379,6 +380,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml index 1a51e1e02fe86..1eee2d510e7bc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml @@ -20,6 +20,7 @@ + @@ -32,6 +33,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml index 3ec73aec580d5..56d1b97974bbc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml @@ -20,6 +20,7 @@ + @@ -109,6 +110,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml index 7a4655bb19ce3..734cedd2c1a3a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml @@ -18,6 +18,7 @@ + @@ -32,6 +33,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml index 461139b6d4b3f..ed2e2c62f54b3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml @@ -19,6 +19,7 @@ + @@ -31,6 +32,7 @@ + diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml index 2b88657c6ca2b..e27650ff251db 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml @@ -20,6 +20,7 @@ + @@ -94,6 +95,7 @@ + diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php new file mode 100644 index 0000000000000..8158296678dea --- /dev/null +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -0,0 +1,118 @@ +configWriter = $configWriter; + $this->domainValidator = $domainValidator; + parent::__construct(); + } + + /** + * @inheritdoc + */ + protected function configure() + { + $description = 'Add domains to the downloadable domains whitelist'; + + $this->setName('downloadable:domains:add') + ->setDescription($description) + ->setDefinition( + [ + new InputArgument( + self::INPUT_KEY_DOMAINS, + InputArgument::IS_ARRAY, + 'Domains name' + ) + ] + ); + parent::configure(); + } + + /** + * @inheritdoc + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { + $newDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); + $newDomains = array_filter(array_map('trim', $newDomains), 'strlen'); + + $whitelist = $this->domainValidator->getEnvDomainWhitelist() ?: []; + foreach ($newDomains as $newDomain) { + if (in_array($newDomain, $whitelist)) { + $output->writeln( + "$newDomain is already in the whitelist" + ); + continue; + } else { + array_push($whitelist, $newDomain); + $output->writeln( + "$newDomain was added to the whitelist" + ); + } + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + $this->domainValidator::PARAM_DOWNLOADABLE_DOMAINS => $whitelist + ] + ] + ); + } + + } catch (\Exception $e) { + $output->writeln('' . $e->getMessage() . ''); + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { + $output->writeln($e->getTraceAsString()); + } + return; + } + } +} diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php new file mode 100644 index 0000000000000..1fa02ae6359b4 --- /dev/null +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -0,0 +1,120 @@ +configWriter = $configWriter; + $this->domainValidator = $domainValidator; + parent::__construct(); + } + + /** + * @inheritdoc + */ + protected function configure() + { + $description = 'Remove domains from the downloadable domains whitelist'; + + $this->setName('downloadable:domains:remove') + ->setDescription($description) + ->setDefinition( + [ + new InputArgument( + self::INPUT_KEY_DOMAINS, + InputArgument::IS_ARRAY, + 'Domain names' + ) + ] + ); + parent::configure(); + } + + /** + * @inheritdoc + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { + $removeDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); + $removeDomains = array_filter(array_map('trim', $removeDomains), 'strlen'); + + $whitelist = $this->domainValidator->getEnvDomainWhitelist() ?: []; + foreach ($removeDomains as $removeDomain) { + if (in_array($removeDomain, $whitelist)) { + $index = array_search($removeDomain, $whitelist); + unset($whitelist[$index]); + $output->writeln( + "$removeDomain was removed from the whitelist" + ); + continue; + } else { + $output->writeln( + "$removeDomain is absent in the whitelist" + ); + } + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + $this->domainValidator::PARAM_DOWNLOADABLE_DOMAINS => $whitelist + ] + ], + true + ); + } + + } catch (\Exception $e) { + $output->writeln('' . $e->getMessage() . ''); + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { + $output->writeln($e->getTraceAsString()); + } + return; + } + } +} diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php new file mode 100644 index 0000000000000..70e031eb3e410 --- /dev/null +++ b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php @@ -0,0 +1,79 @@ +configWriter = $configWriter; + $this->domainValidator = $domainValidator; + parent::__construct(); + } + + /** + * @inheritdoc + */ + protected function configure() + { + $description = 'Display downloadable domains whitelist'; + + $this->setName('downloadable:domains:show') + ->setDescription($description); + parent::configure(); + } + + /** + * @inheritdoc + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + $whitelist = implode("\n", $this->domainValidator->getEnvDomainWhitelist() ?: []); + $output->writeln( + "Downloadable domains whitelist:\n$whitelist" + ); + + } catch (\Exception $e) { + $output->writeln('' . $e->getMessage() . ''); + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { + $output->writeln($e->getTraceAsString()); + } + return; + } + } +} diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php index 8497bf7de6592..08345c8079ddc 100644 --- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php @@ -12,12 +12,23 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Url\Validator as UrlValidator; +use Magento\Downloadable\Model\Url\DomainValidator; /** * Class to validate Link Content. */ class ContentValidator { + /** + * @var DomainValidator + */ + private $domainValidator; + + /** + * @var File + */ + private $fileHelper; + /** * @var FileContentValidator */ @@ -28,24 +39,22 @@ class ContentValidator */ protected $urlValidator; - /** - * @var File - */ - private $fileHelper; - /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator * @param File|null $fileHelper + * @param DomainValidator|null $domainValidator */ public function __construct( FileContentValidator $fileContentValidator, UrlValidator $urlValidator, - File $fileHelper = null + File $fileHelper = null, + DomainValidator $domainValidator = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); + $this->domainValidator = $domainValidator ?? ObjectManager::getInstance()->get(DomainValidator::class); } /** @@ -91,7 +100,9 @@ public function isValid(LinkInterface $link, $validateLinkContent = true, $valid protected function validateLinkResource(LinkInterface $link) { if ($link->getLinkType() === 'url') { - if (!$this->urlValidator->isValid($link->getLinkUrl())) { + if (!$this->urlValidator->isValid($link->getLinkUrl()) + || !$this->domainValidator->isValid($link->getLinkUrl()) + ) { throw new InputException(__('Link URL must have valid format.')); } } elseif ($link->getLinkFileContent()) { @@ -113,7 +124,9 @@ protected function validateLinkResource(LinkInterface $link) protected function validateSampleResource(LinkInterface $link) { if ($link->getSampleType() === 'url') { - if (!$this->urlValidator->isValid($link->getSampleUrl())) { + if (!$this->urlValidator->isValid($link->getSampleUrl()) + || !$this->domainValidator->isValid($link->getSampleUrl()) + ) { throw new InputException(__('Sample URL must have valid format.')); } } elseif ($link->getSampleFileContent()) { diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php index 7348b04793a8f..7b8c65580f160 100644 --- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php @@ -12,12 +12,23 @@ use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Url\Validator as UrlValidator; +use Magento\Downloadable\Model\Url\DomainValidator; /** * Class to validate Sample Content. */ class ContentValidator { + /** + * @var File + */ + private $fileHelper; + + /** + * @var DomainValidator + */ + private $domainValidator; + /** * @var UrlValidator */ @@ -28,24 +39,22 @@ class ContentValidator */ protected $fileContentValidator; - /** - * @var File - */ - private $fileHelper; - /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator * @param File|null $fileHelper + * @param DomainValidator|null $domainValidator */ public function __construct( FileContentValidator $fileContentValidator, UrlValidator $urlValidator, - File $fileHelper = null + File $fileHelper = null, + DomainValidator $domainValidator = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); + $this->domainValidator = $domainValidator ?? ObjectManager::getInstance()->get(DomainValidator::class); } /** @@ -79,7 +88,8 @@ public function isValid(SampleInterface $sample, $validateSampleContent = true) protected function validateSampleResource(SampleInterface $sample) { if ($sample->getSampleType() === 'url') { - if (!$this->urlValidator->isValid($sample->getSampleUrl())) { + if (!$this->urlValidator->isValid($sample->getSampleUrl()) + || !$this->domainValidator->isValid($sample->getSampleUrl())) { throw new InputException(__('Sample URL must have valid format.')); } } elseif ($sample->getSampleFileContent()) { diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php new file mode 100644 index 0000000000000..5cdd954edb15f --- /dev/null +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -0,0 +1,124 @@ +deploymentConfig = $deploymentConfig; + $this->ipValidator = $ipValidator; + $this->uriHandler = $uriHandler; + + $this->initMessageTemplates(); + } + + /** + * Validate url input. + * + * Assert parsed host of $value is contained within environment whitelist + * + * @param string $value + * @return bool + */ + public function isValid($value): bool + { + $host = $this->getHost($value); + + $isIpAddress = $this->ipValidator->isValid($host); + $isValid = !$isIpAddress && in_array($host, $this->getEnvDomainWhitelist()); + + if (!$isValid) { + $this->_error(self::INVALID_HOST, $host); + } + + return $isValid; + } + + /** + * Get environment whitelist + * + * @return array + */ + public function getEnvDomainWhitelist(): array + { + return array_map('strtolower', $this->deploymentConfig->get(self::PARAM_DOWNLOADABLE_DOMAINS) ?? []); + } + + /** + * Extract host from url + * + * @param string $url + * @return string + */ + private function getHost($url): string + { + $host = $this->uriHandler->parse($url)->getHost(); + + if ($host === null) { + return ''; + } + + // ipv6 hosts are brace-delimited in url; they are removed here for subsequent validation + return trim($host, '[] '); + } + + /** + * Initialize message templates with translating + * + * @return void + */ + private function initMessageTemplates() + { + if (!$this->_messageTemplates) { + $this->_messageTemplates = [ + self::INVALID_HOST => __('Host "%value%" is not allowed.'), + ]; + } + } +} diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php new file mode 100644 index 0000000000000..d63d28256809e --- /dev/null +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -0,0 +1,151 @@ +uriHandler = $uriHandler; + $this->scopeResolver = $scopeResolver; + $this->configWriter = $configWriter; + $this->moduleDataSetup = $moduleDataSetup; + } + + /** + * @inheritdoc + */ + public function apply() + { + if ($this->moduleDataSetup->tableExists('downloadable_link')) { + $select = $this->moduleDataSetup->getConnection() + ->select() + ->from( + $this->moduleDataSetup->getTable('downloadable_link'), + ['link_url'] + )->where('link_type = ?', 'url'); + + foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { + $this->addHost($link['link_url']); + } + + $select = $this->moduleDataSetup->getConnection() + ->select() + ->from( + $this->moduleDataSetup->getTable('downloadable_link'), + ['sample_url'] + )->where('sample_type = ?', 'url'); + + foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { + $this->addHost($link['sample_url']); + } + } + + if ($this->moduleDataSetup->tableExists('downloadable_sample')) { + $select = $this->moduleDataSetup->getConnection() + ->select() + ->from( + $this->moduleDataSetup->getTable('downloadable_sample'), + ['sample_url'] + )->where('sample_type = ?', 'url'); + + foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { + $this->addHost($link['sample_url']); + } + } + + foreach ($this->scopeResolver->getScopes() as $scope) { + $this->addHost($scope->getBaseUrl()); + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + DomainValidator::PARAM_DOWNLOADABLE_DOMAINS => array_unique($this->whitelist) + ] + ] + ); + } + + /** + * Add host to whitelist + * + * @param string $url + */ + private function addHost($url) + { + $host = $this->uriHandler->parse($url)->getHost(); + if ($host && !in_array($host, $this->whitelist)) { + $this->whitelist[] = $host; + } + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return []; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml index 3d779740849c5..15e64b9bbd35f 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml @@ -19,9 +19,11 @@ + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml index a7acdfded29b6..4bbd815e8db01 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml @@ -18,7 +18,12 @@ - + + + + + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml index 5d7e4518525f7..fc638633fbf3f 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml @@ -25,6 +25,7 @@ + @@ -40,6 +41,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml index 0ae2c1254be01..f45e5f1a47e43 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml @@ -20,6 +20,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml index eadefabb8bbcb..d9b4e8087cbc9 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml @@ -20,6 +20,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml index 8bd4305e6b358..afac869d69c3f 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml @@ -20,6 +20,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml index d8bd641e84e55..8b38f91f8719c 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml @@ -20,6 +20,7 @@ + @@ -27,6 +28,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml index 3efd4b8ab276f..081230760e1d4 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml @@ -20,6 +20,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml index 07f7c40bb3560..a815d838c29d9 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml @@ -20,6 +20,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml index 275e72b2ec8cb..f0cc503f74c4d 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml @@ -20,6 +20,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml index ca4e560506ad0..f6455766a0907 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml @@ -19,6 +19,12 @@ + + + + + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml index f326a047c32b5..6e29fe13d85e6 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml @@ -20,6 +20,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml index 8e33a082d0ba2..757ac7958f5cd 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml @@ -20,6 +20,7 @@ + @@ -37,6 +38,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml index d3c2d6e5d71a4..83e0c587c078e 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml @@ -18,6 +18,7 @@ + @@ -33,6 +34,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml index 3ee6cef47738b..3597c12e82df0 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml @@ -19,9 +19,11 @@ + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml index d8bbbb2b4d62b..bc929cd3a68c7 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml @@ -18,6 +18,12 @@ + + + + + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml index 66177b6875dd9..19477fb804848 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml @@ -19,6 +19,7 @@ + @@ -27,6 +28,9 @@ + + + @@ -39,6 +43,7 @@ + @@ -47,6 +52,9 @@ + + + @@ -59,6 +67,7 @@ + @@ -67,6 +76,9 @@ + + + @@ -79,6 +91,7 @@ + @@ -87,6 +100,9 @@ + + + @@ -99,6 +115,7 @@ + @@ -107,5 +124,8 @@ + + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml index b960d15b2fdf1..25dfe1adcb7c8 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml @@ -18,6 +18,7 @@ + @@ -31,6 +32,7 @@ + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml index 4864d11c884bc..9fed2d68c98ca 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml @@ -20,6 +20,13 @@ + + + + + + + diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php index 771fbc37e5e13..152e3699f9691 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php @@ -28,6 +28,11 @@ class ContentValidatorTest extends \PHPUnit\Framework\TestCase */ protected $urlValidatorMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $domainValidatorMock; + /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -52,6 +57,7 @@ protected function setUp() $this->fileValidatorMock = $this->createMock(\Magento\Downloadable\Model\File\ContentValidator::class); $this->urlValidatorMock = $this->createMock(\Magento\Framework\Url\Validator::class); + $this->domainValidatorMock = $this->createMock(\Magento\Downloadable\Model\Url\DomainValidator::class); $this->linkFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); $this->sampleFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); $this->fileMock = $this->createMock(File::class); @@ -62,6 +68,7 @@ protected function setUp() 'fileContentValidator' => $this->fileValidatorMock, 'urlValidator' => $this->urlValidatorMock, 'fileHelper' => $this->fileMock, + 'domainValidator' => $this->domainValidatorMock, ] ); } @@ -83,6 +90,7 @@ public function testIsValid() ]; $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $linkMock = $this->getLinkMock($linkData); $this->assertTrue($this->validator->isValid($linkMock)); } @@ -103,6 +111,7 @@ public function testIsValidSkipLinkContent() ]; $this->fileValidatorMock->expects($this->once())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->never())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->never())->method('isValid')->will($this->returnValue(true)); $linkMock = $this->getLinkMock($linkData); $this->assertTrue($this->validator->isValid($linkMock, false)); } @@ -123,6 +132,7 @@ public function testIsValidSkipSampleContent() ]; $this->fileValidatorMock->expects($this->never())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->once())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->once())->method('isValid')->will($this->returnValue(true)); $linkMock = $this->getLinkMock($linkData); $this->assertTrue($this->validator->isValid($linkMock, true, false)); } @@ -146,6 +156,7 @@ public function testIsValidThrowsExceptionIfSortOrderIsInvalid($sortOrder) ]; $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $contentMock = $this->getLinkMock($linkContentData); $this->validator->isValid($contentMock); } @@ -181,6 +192,7 @@ public function testIsValidThrowsExceptionIfPriceIsInvalid($price) ]; $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $contentMock = $this->getLinkMock($linkContentData); $this->validator->isValid($contentMock); } @@ -214,6 +226,7 @@ public function testIsValidThrowsExceptionIfNumberOfDownloadsIsInvalid($numberOf 'sample_type' => 'file', ]; $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $contentMock = $this->getLinkMock($linkContentData); $this->validator->isValid($contentMock); diff --git a/app/code/Magento/Downloadable/etc/di.xml b/app/code/Magento/Downloadable/etc/di.xml index 4e9b0b55afb0b..8ee05029333b8 100644 --- a/app/code/Magento/Downloadable/etc/di.xml +++ b/app/code/Magento/Downloadable/etc/di.xml @@ -164,4 +164,13 @@ indexer + + + + Magento\Downloadable\Console\Command\DomainsAddCommand + Magento\Downloadable\Console\Command\DomainsRemoveCommand + Magento\Downloadable\Console\Command\DomainsShowCommand + + + diff --git a/app/code/Magento/Downloadable/i18n/en_US.csv b/app/code/Magento/Downloadable/i18n/en_US.csv index 87427bf483966..6158f1c579722 100644 --- a/app/code/Magento/Downloadable/i18n/en_US.csv +++ b/app/code/Magento/Downloadable/i18n/en_US.csv @@ -118,3 +118,4 @@ Downloads,Downloads "Use Content-Disposition","Use Content-Disposition" "Disable Guest Checkout if Cart Contains Downloadable Items","Disable Guest Checkout if Cart Contains Downloadable Items" "Guest checkout will only work with shareable.","Guest checkout will only work with shareable." +"Host ""%value"" is not allowed.","Host ""%value"" is not allowed." diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 3e935e1d7ae9b..8c82f2ed84538 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -9,6 +9,8 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\Data\StockItemInterface; +use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Console\Command\DomainsRemoveCommand; use Magento\Downloadable\Model\Link; use Magento\Store\Model\Store; use Magento\Store\Model\Website; @@ -22,6 +24,7 @@ use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; +use Symfony\Component\Console\Tester\CommandTester; /** * @magentoAppIsolation enabled @@ -55,6 +58,34 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract ], ]; + /** + * @inheritDoc + */ + protected function setUp() + { + parent::setUp(); + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var DomainsAddCommand $domainsAddCommand */ + $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); + $command = new CommandTester($domainsAddCommand); + $command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['example.com']]); + } + + /** + * @inheritDoc + */ + protected function tearDown() + { + parent::tearDown(); + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var DomainsRemoveCommand $domainsRemoveCommand */ + $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); + $command = new CommandTester($domainsRemoveCommand); + $command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['example.com']]); + } + /** * @magentoApiDataFixture Magento/Catalog/_files/products_related.php */ @@ -607,6 +638,7 @@ public function testProductOptions() public function testProductWithMediaGallery() { $testImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg'; + // @codingStandardsIgnoreLine $encodedImage = base64_encode(file_get_contents($testImagePath)); //create a product with media gallery $filename1 = 'tiny1' . time() . '.jpg'; @@ -731,11 +763,11 @@ public function testUpdateWithExtensionAttributes(): void protected function updateProduct($product) { if (isset($product['custom_attributes'])) { - for ($i=0; $itestImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg'; + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + /** @var DomainsAddCommand $domainsAddCommand */ + $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); + $command = new CommandTester($domainsAddCommand); + $command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['www.example.com']]); } /** @@ -37,6 +48,13 @@ public function tearDown() { $this->deleteProductBySku(self::PRODUCT_SKU); parent::tearDown(); + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + /** @var DomainsRemoveCommand $domainsRemoveCommand */ + $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); + $command = new CommandTester($domainsRemoveCommand); + $command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['www.example.com']]); } protected function getLinkData() diff --git a/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/EnvWhitelist.php b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/EnvWhitelist.php new file mode 100644 index 0000000000000..294cc32e8f712 --- /dev/null +++ b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/EnvWhitelist.php @@ -0,0 +1,40 @@ +catalogProductIndex = $catalogProductIndex; $this->catalogProductEdit = $catalogProductEdit; $this->fixtureFactory = $fixtureFactory; + $this->envWhitelist = $envWhitelist; } /** @@ -89,6 +100,7 @@ public function __inject( public function test($productOrigin, $product, $actionName) { // Preconditions + $this->envWhitelist->addHost('example.com'); list($fixtureClass, $dataset) = explode('::', $productOrigin); $productOrigin = $this->fixtureFactory->createByCode(trim($fixtureClass), ['dataset' => trim($dataset)]); $productOrigin->persist(); @@ -144,5 +156,6 @@ protected function clearDownloadableData() $downloadableInfoTab = $this->catalogProductEdit->getProductForm()->getSection('downloadable_information'); $downloadableInfoTab->getDownloadableBlock('Links')->clearDownloadableData(); $downloadableInfoTab->setIsDownloadable('No'); + $this->envWhitelist->removeHost('example.com'); } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php index 7d6bd93180230..fba5a2b062343 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php @@ -14,6 +14,7 @@ use Magento\Mtf\TestCase\Injectable; use Magento\Mtf\TestStep\TestStepFactory; use Magento\Mtf\Util\Command\Cli\Cache; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -99,6 +100,13 @@ class AddProductsToShoppingCartEntityTest extends Injectable */ private $cache; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Prepare test data. * @@ -108,6 +116,7 @@ class AddProductsToShoppingCartEntityTest extends Injectable * @param CheckoutCart $cartPage * @param TestStepFactory $testStepFactory * @param Cache $cache + * @param EnvWhitelist $envWhitelist * @return void */ public function __prepare( @@ -116,7 +125,8 @@ public function __prepare( CatalogProductView $catalogProductView, CheckoutCart $cartPage, TestStepFactory $testStepFactory, - Cache $cache + Cache $cache, + EnvWhitelist $envWhitelist ) { $this->browser = $browser; $this->fixtureFactory = $fixtureFactory; @@ -124,6 +134,7 @@ public function __prepare( $this->cartPage = $cartPage; $this->testStepFactory = $testStepFactory; $this->cache = $cache; + $this->envWhitelist = $envWhitelist; } /** @@ -146,6 +157,7 @@ public function test( // Preconditions $this->configData = $configData; $this->flushCache = $flushCache; + $this->envWhitelist->addHost('example.com'); $this->testStepFactory->create( \Magento\Config\Test\TestStep\SetupConfigurationStep::class, @@ -224,7 +236,7 @@ public function tearDown() $_ENV['app_frontend_url'] = preg_replace('/(http[s]?)/', 'http', $_ENV['app_frontend_url']); $this->cache->flush(); } - + $this->envWhitelist->removeHost('example.com'); $this->testStepFactory->create( \Magento\Config\Test\TestStep\SetupConfigurationStep::class, ['configData' => $this->configData, 'rollback' => true, 'flushCache' => $this->flushCache] diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.php index 54f59b03ef81d..6f5512b2e8293 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\TestCase; use Magento\Mtf\TestCase\Scenario; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -43,6 +44,23 @@ class OnePageCheckoutOfflinePaymentMethodsTest extends Scenario const SEVERITY = 'S0'; /* end tags */ + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + + /** + * Perform needed injections + * + * @param EnvWhitelist $envWhitelist + */ + public function __inject(EnvWhitelist $envWhitelist) + { + $this->envWhitelist = $envWhitelist; + } + /** * Runs one page checkout test. * @@ -50,6 +68,17 @@ class OnePageCheckoutOfflinePaymentMethodsTest extends Scenario */ public function test() { + $this->envWhitelist->addHost('example.com'); $this->executeScenario(); } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php index af267cfa30ec1..36b4f4b3eb39b 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php @@ -12,6 +12,7 @@ use Magento\Mtf\Fixture\FixtureInterface; use Magento\Mtf\TestCase\Injectable; use Magento\Customer\Test\Fixture\Customer; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -58,22 +59,32 @@ class UpdateProductFromMiniShoppingCartEntityTest extends Injectable */ protected $fixtureFactory; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Inject data. * * @param CmsIndex $cmsIndex * @param CatalogProductView $catalogProductView * @param FixtureFactory $fixtureFactory + * @param EnvWhitelist $envWhitelist * @return void */ public function __inject( CmsIndex $cmsIndex, CatalogProductView $catalogProductView, - FixtureFactory $fixtureFactory + FixtureFactory $fixtureFactory, + EnvWhitelist $envWhitelist ) { $this->cmsIndex = $cmsIndex; $this->catalogProductView = $catalogProductView; $this->fixtureFactory = $fixtureFactory; + $this->envWhitelist = $envWhitelist; } /** @@ -97,6 +108,7 @@ public function test( Customer $customer = null ) { // Preconditions: + $this->envWhitelist->addHost('example.com'); if ($customer !== null) { $customer->persist(); } @@ -162,4 +174,14 @@ protected function addToCart(FixtureInterface $product) ); $addToCartStep->run(); } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php index 01e43defde814..9eb13734531d9 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php @@ -8,6 +8,7 @@ use Magento\Mtf\Client\BrowserInterface; use Magento\Mtf\TestCase\Scenario; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -41,14 +42,25 @@ class PrintOrderFrontendGuestTest extends Scenario */ protected $browser; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Prepare data. * * @param BrowserInterface $browser + * @param EnvWhitelist $envWhitelist */ - public function __prepare(BrowserInterface $browser) - { + public function __prepare( + BrowserInterface $browser, + EnvWhitelist $envWhitelist + ) { $this->browser = $browser; + $this->envWhitelist = $envWhitelist; } /** @@ -58,6 +70,7 @@ public function __prepare(BrowserInterface $browser) */ public function test() { + $this->envWhitelist->addHost('example.com'); $this->executeScenario(); } @@ -68,6 +81,7 @@ public function test() */ public function tearDown() { + $this->envWhitelist->removeHost('example.com'); $this->browser->closeWindow(); } } diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php index 9c5ffb9dd8013..c12b2d0991224 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php @@ -7,6 +7,7 @@ namespace Magento\Wishlist\Test\TestCase; use Magento\Customer\Test\Fixture\Customer; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Test Flow: @@ -30,15 +31,26 @@ class AddProductToWishlistEntityTest extends AbstractWishlistTest const MVP = 'no'; /* end tags */ + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Prepare data for test * * @param Customer $customer + * @param EnvWhitelist $envWhitelist * @return array */ - public function __prepare(Customer $customer) - { + public function __prepare( + Customer $customer, + EnvWhitelist $envWhitelist + ) { $customer->persist(); + $this->envWhitelist = $envWhitelist; return ['customer' => $customer]; } @@ -53,6 +65,7 @@ public function __prepare(Customer $customer) */ public function test(Customer $customer, $product, $configure = true) { + $this->envWhitelist->addHost('example.com'); $product = $this->createProducts($product)[0]; // Steps: @@ -61,4 +74,14 @@ public function test(Customer $customer, $product, $configure = true) return ['product' => $product]; } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php index ee3bf77a1aa0d..27c60281660bb 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Test\Fixture\Customer; use Magento\Customer\Test\Page\Adminhtml\CustomerIndex; use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -35,15 +36,26 @@ class ConfigureProductInCustomerWishlistOnBackendTest extends AbstractWishlistTe const MVP = 'no'; /* end tags */ + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Create customer. * * @param Customer $customer + * @param EnvWhitelist $envWhitelist * @return array */ - public function __prepare(Customer $customer) - { + public function __prepare( + Customer $customer, + EnvWhitelist $envWhitelist + ) { $customer->persist(); + $this->envWhitelist = $envWhitelist; return ['customer' => $customer]; } @@ -64,6 +76,7 @@ public function test( CustomerIndexEdit $customerIndexEdit ) { // Preconditions + $this->envWhitelist->addHost('example.com'); $product = $this->createProducts($product)[0]; $this->loginCustomer($customer); $this->addToWishlist([$product]); @@ -80,4 +93,14 @@ public function test( return['product' => $product]; } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php index f81f87d5b6227..1bba73cdf5e9f 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Test\Fixture\Customer; use Magento\Customer\Test\Page\Adminhtml\CustomerIndex; use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Test Flow: @@ -34,15 +35,26 @@ class ViewProductInCustomerWishlistOnBackendTest extends AbstractWishlistTest const MVP = 'no'; /* end tags */ + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Prepare customer for test. * * @param Customer $customer + * @param EnvWhitelist $envWhitelist * @return array */ - public function __prepare(Customer $customer) - { + public function __prepare( + Customer $customer, + EnvWhitelist $envWhitelist + ) { $customer->persist(); + $this->envWhitelist = $envWhitelist; return ['customer' => $customer]; } @@ -63,6 +75,7 @@ public function test( CustomerIndexEdit $customerIndexEdit ) { // Preconditions + $this->envWhitelist->addHost('example.com'); $product = $this->createProducts($product)[0]; $this->loginCustomer($customer); $this->addToWishlist([$product], true); @@ -74,4 +87,14 @@ public function test( return['product' => $product]; } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product_rollback.php new file mode 100644 index 0000000000000..4048c672037b2 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product_rollback.php @@ -0,0 +1,8 @@ +deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); + + $objectManager = Bootstrap::getObjectManager(); + + $this->model = $objectManager->create( + DomainValidator::class, + ['deploymentConfig' => $this->deploymentConfig] + ); + } + + /** + * @param string $urlInput + * @param array $envDomainWhitelist + * @param bool $isValid + * + * @magentoDataFixture Magento/Store/_files/second_store.php + * @magentoConfigFixture current_store web/unsecure/base_url http://example.com/ + * @magentoConfigFixture current_store web/secure/base_url https://secure.example.com/ + * @magentoConfigFixture fixture_second_store_store web/unsecure/base_url http://example2.com/ + * @magentoConfigFixture fixture_second_store_store web/secure/base_url https://secure.example2.com/ + * @dataProvider isValidDataProvider + */ + public function testIsValid(string $urlInput, array $envDomainWhitelist, bool $isValid) + { + $this->deploymentConfig + ->expects($this->any()) + ->method('get') + ->with(DomainValidator::PARAM_DOWNLOADABLE_DOMAINS) + ->willReturn($envDomainWhitelist); + + $this->assertEquals( + $isValid, + $this->model->isValid($urlInput), + 'Failed asserting is ' . ($isValid ? 'valid' : 'not valid') . ': ' . $urlInput . + PHP_EOL . + 'Domain whitelist: ' . implode(', ', $envDomainWhitelist) + ); + } + + public function isValidDataProvider() + { + return [ + ['http://example.com', ['example.co'], false], + [' http://example.com ', ['example.com'], false], + ['http://example.com', ['example.com'], true], + ['https://example.com', ['example.com'], true], + ['https://example.com/downloadable.pdf', ['example.com'], true], + ['https://example.com:8080/downloadable.pdf', ['example.com'], true], + ['http://secure.example.com', ['secure.example.com'], true], + ['https://secure.example.com', ['secure.example.com'], true], + ['https://ultra.secure.example.com', ['secure.example.com'], false], + ['http://example2.com', ['example2.com'], true], + ['https://example2.com', ['example2.com'], true], + ['http://subdomain.example2.com', ['example2.com'], false], + ['https://adobe.com', ['adobe.com'], true], + ['https://subdomain.adobe.com', ['adobe.com'], false], + ['https://ADOBE.COm', ['adobe.com'], true], + ['https://adobe.com', ['ADOBE.COm'], true], + ['http://127.0.0.1', ['127.0.0.1'], false], + ['http://[::1]', ['::1'], false], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php index 9c0b328fc1664..df6d717ed1012 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php @@ -3,10 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); + +use Magento\Downloadable\Console\Command\DomainsAddCommand; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +/** @var DomainsAddCommand $domainsAddCommand */ +$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); +$command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['example.com', 'sampleurl.com']]); + /** * @var \Magento\Catalog\Model\Product $product */ @@ -74,6 +80,7 @@ */ $sampleContent = $objectManager->create(\Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class)->create(); $sampleContent->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $sampleContent->setName('jellyfish_1_3.jpg'); @@ -92,10 +99,10 @@ */ $content = $objectManager->create(\Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class)->create(); $content->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $content->setName('jellyfish_2_4.jpg'); -//$content->setName(''); $sampleLink->setLinkFileContent($content); $links[] = $sampleLink; @@ -146,6 +153,7 @@ \Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class )->create(); $content->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $content->setName('jellyfish_1_4.jpg'); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php index 9ad910eed8739..dbaf4ea6f67b3 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php @@ -3,4 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +use Magento\Downloadable\Console\Command\DomainsRemoveCommand; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var DomainsRemoveCommand $domainsRemoveCommand */ +$domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsRemoveCommand); +$command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['sampleurl.com']]); + +// @codingStandardsIgnoreLine require __DIR__ . '/product_downloadable_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php index 19cf449912b66..56277a75cd801 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php @@ -3,10 +3,27 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -/** - * @var \Magento\Catalog\Model\Product $product - */ -$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); + +use Magento\Downloadable\Console\Command\DomainsAddCommand; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var DomainsAddCommand $domainsAddCommand */ +$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); +$command->execute( + [ + DomainsAddCommand::INPUT_KEY_DOMAINS => [ + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' + ] + ] +); + +/** @var \Magento\Catalog\Model\Product $product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); $product ->setTypeId(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) ->setId(1) diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php index 996fbb01d72c4..22619d25ee4ec 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php @@ -3,23 +3,41 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +use Magento\Downloadable\Console\Command\DomainsRemoveCommand; use Magento\Framework\Exception\NoSuchEntityException; \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var DomainsRemoveCommand $domainsRemoveCommand */ +$domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsRemoveCommand); +$command->execute( + [ + DomainsRemoveCommand::INPUT_KEY_DOMAINS => [ + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' + ] + ] +); + /** @var \Magento\Framework\Registry $registry */ -$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); +$registry = $objectManager->get(\Magento\Framework\Registry::class); $registry->unregister('isSecureArea'); $registry->register('isSecureArea', true); /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ -$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() +$productRepository = $objectManager ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); try { $product = $productRepository->get('downloadable-product', false, null, true); $productRepository->delete($product); -} catch (NoSuchEntityException $e) { +} catch (NoSuchEntityException $e) { // @codingStandardsIgnoreLine } $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php index 86aa61a99e1e8..47eb6c450e9ec 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php @@ -4,8 +4,25 @@ * See COPYING.txt for license details. */ +use Magento\Downloadable\Console\Command\DomainsAddCommand; + \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var DomainsAddCommand $domainsAddCommand */ +$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); +$command->execute( + [ + DomainsAddCommand::INPUT_KEY_DOMAINS => [ + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' + ] + ] +); + /** * @var \Magento\Catalog\Model\Product $product */ @@ -81,10 +98,10 @@ */ $content = $objectManager->create(\Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class)->create(); $content->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $content->setName('jellyfish_2_4.jpg'); -//$content->setName(''); $link->setLinkFileContent($content); /** @@ -92,6 +109,7 @@ */ $sampleContent = $objectManager->create(\Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class)->create(); $sampleContent->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $sampleContent->setName('jellyfish_1_3.jpg'); @@ -136,6 +154,7 @@ \Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class )->create(); $content->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $content->setName('jellyfish_1_4.jpg'); From a4a636212042681b97b3a3713ea11811ee7b8c25 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Wed, 17 Jul 2019 08:52:54 +0300 Subject: [PATCH 159/372] MC-18099: Changes in Downloadable product upload controller --- .../Adminhtml/Downloadable/File/Upload.php | 6 ++-- .../Checkout/Test/Block/Cart/Sidebar/Item.php | 18 ++++++++++ .../Adminhtml/Downloadable/FileTest.php | 35 ++++++++++++++----- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php index c8f7a4ff4a507..a7c32eed8bb15 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php @@ -81,11 +81,11 @@ public function execute() try { $type = $this->getRequest()->getParam('type'); $tmpPath = ''; - if ($type == 'samples') { + if ($type === 'samples') { $tmpPath = $this->_sample->getBaseTmpPath(); - } elseif ($type == 'links') { + } elseif ($type === 'links') { $tmpPath = $this->_link->getBaseTmpPath(); - } elseif ($type == 'link_samples') { + } elseif ($type === 'link_samples') { $tmpPath = $this->_link->getBaseSampleTmpPath(); } else { throw new LocalizedException(__('Upload type can not be determined.')); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php index c00687d91c1ee..038c411768969 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php @@ -62,6 +62,7 @@ class Item extends Sidebar */ public function removeItemFromMiniCart() { + $this->waitForDeleteButtonVisible(); $this->_rootElement->find($this->removeItem)->click(); $element = $this->browser->find($this->confirmModal); /** @var \Magento\Ui\Test\Block\Adminhtml\Modal $modal */ @@ -70,6 +71,23 @@ public function removeItemFromMiniCart() $modal->waitModalWindowToDisappear(); } + /** + * Wait for Delete button is visible in the block. + * + * @return bool|null + */ + private function waitForDeleteButtonVisible() + { + $rootElement = $this->_rootElement; + $deleteButtonSelector = $this->removeItem; + return $rootElement->waitUntil( + function () use ($rootElement, $deleteButtonSelector) { + $element = $rootElement->find($deleteButtonSelector); + return $element->isVisible() ? true : null; + } + ); + } + /** * Click "Edit item" button. * diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php index ac35fa9a23b1d..20e36e6594638 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php @@ -7,36 +7,53 @@ namespace Magento\Downloadable\Controller\Adminhtml\Downloadable; use Magento\Framework\Serialize\Serializer\Json; -use Magento\TestFramework\Helper\Bootstrap; /** * Magento\Downloadable\Controller\Adminhtml\Downloadable\File * * @magentoAppArea adminhtml - * - * phpcs:disable Magento2.Functions.DiscouragedFunction - * phpcs:disable Magento2.Security.Superglobal */ class FileTest extends \Magento\TestFramework\TestCase\AbstractBackendController { + /** + * @var Json + */ + private $jsonSerializer; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->jsonSerializer = $this->_objectManager->get(Json::class); + } + /** * @inheritdoc */ protected function tearDown() { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $filePath = dirname(__DIR__) . '/_files/sample.tmp'; + // phpcs:ignore Magento2.Functions.DiscouragedFunction if (is_file($filePath)) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction unlink($filePath); } } public function testUploadAction() { + // phpcs:ignore Magento2.Functions.DiscouragedFunction copy(dirname(__DIR__) . '/_files/sample.txt', dirname(__DIR__) . '/_files/sample.tmp'); + // phpcs:ignore Magento2.Security.Superglobal $_FILES = [ 'samples' => [ 'name' => 'sample.txt', 'type' => 'text/plain', + // phpcs:ignore Magento2.Functions.DiscouragedFunction 'tmp_name' => dirname(__DIR__) . '/_files/sample.tmp', 'error' => 0, 'size' => 0, @@ -46,7 +63,7 @@ public function testUploadAction() $this->getRequest()->setMethod('POST'); $this->dispatch('backend/admin/downloadable_file/upload/type/samples'); $body = $this->getResponse()->getBody(); - $result = Bootstrap::getObjectManager()->get(Json::class)->unserialize($body); + $result = $this->jsonSerializer->unserialize($body); $this->assertEquals(0, $result['error']); } @@ -58,9 +75,11 @@ public function testUploadAction() */ public function testUploadProhibitedExtensions($fileName) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $path = dirname(__DIR__) . '/_files/'; + // phpcs:ignore Magento2.Functions.DiscouragedFunction copy($path . 'sample.txt', $path . 'sample.tmp'); - + // phpcs:ignore Magento2.Security.Superglobal $_FILES = [ 'samples' => [ 'name' => $fileName, @@ -74,7 +93,7 @@ public function testUploadProhibitedExtensions($fileName) $this->getRequest()->setMethod('POST'); $this->dispatch('backend/admin/downloadable_file/upload/type/samples'); $body = $this->getResponse()->getBody(); - $result = Bootstrap::getObjectManager()->get(Json::class)->unserialize($body); + $result = $this->jsonSerializer->unserialize($body); self::assertArrayHasKey('errorcode', $result); self::assertEquals(0, $result['errorcode']); @@ -113,7 +132,7 @@ public function testUploadWrongUploadType(): void $this->getRequest()->setMethod('POST'); $this->dispatch('backend/admin/downloadable_file/upload'); $body = $this->getResponse()->getBody(); - $result = Bootstrap::getObjectManager()->get(Json::class)->unserialize($body); + $result = $this->jsonSerializer->unserialize($body); $this->assertEquals('Upload type can not be determined.', $result['error']); $this->assertEquals(0, $result['errorcode']); } From 88dd934c0a18875c3caf700f2c999e1938085915 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 09:51:31 -0500 Subject: [PATCH 160/372] MC-17700: Downloadable Product links --- .../Magento/Catalog/Api/ProductRepositoryInterfaceTest.php | 4 ++-- .../Magento/Downloadable/Model/Url/DomainValidatorTest.php | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 8c82f2ed84538..b9afaf1518b8c 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -65,7 +65,7 @@ protected function setUp() { parent::setUp(); - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var DomainsAddCommand $domainsAddCommand */ $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); $command = new CommandTester($domainsAddCommand); @@ -79,7 +79,7 @@ protected function tearDown() { parent::tearDown(); - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var DomainsRemoveCommand $domainsRemoveCommand */ $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); $command = new CommandTester($domainsRemoveCommand); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php index 81ce83fc694ba..970b8add3e52f 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php @@ -53,7 +53,6 @@ protected function setUp() public function testIsValid(string $urlInput, array $envDomainWhitelist, bool $isValid) { $this->deploymentConfig - ->expects($this->any()) ->method('get') ->with(DomainValidator::PARAM_DOWNLOADABLE_DOMAINS) ->willReturn($envDomainWhitelist); From 76b829fcc8928fd60b6548924b00a257821bdbdb Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 10:25:47 -0500 Subject: [PATCH 161/372] MC-17700: Downloadable Product links --- .../Magento/Downloadable/Model/Link/ContentValidator.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php index 08345c8079ddc..e9ed4920a24bc 100644 --- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php @@ -42,19 +42,19 @@ class ContentValidator /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator + * @param DomainValidator $domainValidator * @param File|null $fileHelper - * @param DomainValidator|null $domainValidator */ public function __construct( FileContentValidator $fileContentValidator, UrlValidator $urlValidator, - File $fileHelper = null, - DomainValidator $domainValidator = null + DomainValidator $domainValidator, + File $fileHelper = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; + $this->domainValidator = $domainValidator; $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); - $this->domainValidator = $domainValidator ?? ObjectManager::getInstance()->get(DomainValidator::class); } /** From f93bdedf6d363733b841d1393f943ea839d48c86 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 11:33:57 -0500 Subject: [PATCH 162/372] MC-17700: Downloadable Product links --- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index d63d28256809e..b467a88e1a913 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -76,7 +76,8 @@ public function apply() ->from( $this->moduleDataSetup->getTable('downloadable_link'), ['link_url'] - )->where('link_type = ?', 'url'); + ) + ->where('link_type = ?', 'url'); foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { $this->addHost($link['link_url']); @@ -87,7 +88,8 @@ public function apply() ->from( $this->moduleDataSetup->getTable('downloadable_link'), ['sample_url'] - )->where('sample_type = ?', 'url'); + ) + ->where('sample_type = ?', 'url'); foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { $this->addHost($link['sample_url']); @@ -100,7 +102,8 @@ public function apply() ->from( $this->moduleDataSetup->getTable('downloadable_sample'), ['sample_url'] - )->where('sample_type = ?', 'url'); + ) + ->where('sample_type = ?', 'url'); foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { $this->addHost($link['sample_url']); From c855748d577dcd1603a66ead27014f30ae2b1eba Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 11:46:04 -0500 Subject: [PATCH 163/372] MC-17700: Downloadable Product links --- .../Downloadable/Model/Sample/ContentValidator.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php index 7b8c65580f160..7c53a228f27c8 100644 --- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php @@ -42,19 +42,19 @@ class ContentValidator /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator + * @param DomainValidator $domainValidator * @param File|null $fileHelper - * @param DomainValidator|null $domainValidator */ public function __construct( FileContentValidator $fileContentValidator, UrlValidator $urlValidator, - File $fileHelper = null, - DomainValidator $domainValidator = null + DomainValidator $domainValidator, + File $fileHelper = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; + $this->domainValidator = $domainValidator; $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); - $this->domainValidator = $domainValidator ?? ObjectManager::getInstance()->get(DomainValidator::class); } /** From 74a9c24a7fc90c96365db51cc0263246c2e7ae2e Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 13:43:11 -0500 Subject: [PATCH 164/372] MC-17700: Downloadable Product links --- app/code/Magento/Downloadable/Model/Url/DomainValidator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php index 5cdd954edb15f..66e4365564d67 100644 --- a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -19,12 +19,12 @@ class DomainValidator extends \Zend_Validate_Abstract /** * Invalid host message key */ - const INVALID_HOST = 'invalidHost'; + private const INVALID_HOST = 'invalidHost'; /** * Path to the allowed domains in the deployment config */ - const PARAM_DOWNLOADABLE_DOMAINS = 'downloadable_domains'; + public const PARAM_DOWNLOADABLE_DOMAINS = 'downloadable_domains'; /** * @var IpValidator From 64427a9d0fdf07b78043c6d1780d69b1493ce919 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 13:48:03 -0500 Subject: [PATCH 165/372] MC-17700: Downloadable Product links --- .../Magento/Downloadable/Console/Command/DomainsAddCommand.php | 2 +- .../Downloadable/Console/Command/DomainsRemoveCommand.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php index 8158296678dea..015314b722fe8 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -25,7 +25,7 @@ class DomainsAddCommand extends Command /** * Name of domains input argument */ - const INPUT_KEY_DOMAINS = 'domains'; + public const INPUT_KEY_DOMAINS = 'domains'; /** * @var ConfigWriter diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php index 1fa02ae6359b4..0ad812d3bd71a 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -25,7 +25,7 @@ class DomainsRemoveCommand extends Command /** * Name of domains input argument */ - const INPUT_KEY_DOMAINS = 'domains'; + public const INPUT_KEY_DOMAINS = 'domains'; /** * @var ConfigWriter From ff9a9dda4cdc3f499603ab4bbafee95d0c9b6d29 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Wed, 17 Jul 2019 13:57:38 -0500 Subject: [PATCH 166/372] MC-17700: Downloadable Product links - CR changes --- .../Api/DomainManagerInterface.php | 36 +++++++ .../Console/Command/DomainsAddCommand.php | 52 +++------ .../Console/Command/DomainsRemoveCommand.php | 52 +++------ .../Console/Command/DomainsShowCommand.php | 26 ++--- .../Downloadable/Model/DomainManager.php | 100 ++++++++++++++++++ .../Model/Url/DomainValidator.php | 24 ++--- .../Patch/Data/AddDownloadableHostsConfig.php | 26 ++--- app/code/Magento/Downloadable/etc/di.xml | 1 + 8 files changed, 185 insertions(+), 132 deletions(-) create mode 100644 app/code/Magento/Downloadable/Api/DomainManagerInterface.php create mode 100644 app/code/Magento/Downloadable/Model/DomainManager.php diff --git a/app/code/Magento/Downloadable/Api/DomainManagerInterface.php b/app/code/Magento/Downloadable/Api/DomainManagerInterface.php new file mode 100644 index 0000000000000..9174d81621b15 --- /dev/null +++ b/app/code/Magento/Downloadable/Api/DomainManagerInterface.php @@ -0,0 +1,36 @@ +configWriter = $configWriter; - $this->domainValidator = $domainValidator; + $this->domainManager = $domainManager; parent::__construct(); } @@ -80,33 +69,18 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { + $whitelistBefore = $this->domainManager->getEnvDomainWhitelist(); $newDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); $newDomains = array_filter(array_map('trim', $newDomains), 'strlen'); - $whitelist = $this->domainValidator->getEnvDomainWhitelist() ?: []; - foreach ($newDomains as $newDomain) { - if (in_array($newDomain, $whitelist)) { - $output->writeln( - "$newDomain is already in the whitelist" - ); - continue; - } else { - array_push($whitelist, $newDomain); - $output->writeln( - "$newDomain was added to the whitelist" - ); - } - } + $this->domainManager->addEnvDomains($newDomains); - $this->configWriter->saveConfig( - [ - ConfigFilePool::APP_ENV => [ - $this->domainValidator::PARAM_DOWNLOADABLE_DOMAINS => $whitelist - ] - ] - ); + foreach (array_diff($this->domainManager->getEnvDomainWhitelist(), $whitelistBefore) as $newHost) { + $output->writeln( + $newHost . ' was added to the whitelist.' + ); + } } - } catch (\Exception $e) { $output->writeln('' . $e->getMessage() . ''); if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php index 0ad812d3bd71a..74c0803e3d9a5 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -10,10 +10,8 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; -use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; -use Magento\Downloadable\Model\Url\DomainValidator; -use Magento\Framework\Config\File\ConfigFilePool; /** * Class DomainsRemoveCommand @@ -28,27 +26,19 @@ class DomainsRemoveCommand extends Command public const INPUT_KEY_DOMAINS = 'domains'; /** - * @var ConfigWriter + * @var DomainManager */ - private $configWriter; - - /** - * @var DomainValidator - */ - private $domainValidator; + private $domainManager; /** * DomainsRemoveCommand constructor. * - * @param ConfigWriter $configWriter - * @param DomainValidator $domainValidator + * @param DomainManager $domainManager */ public function __construct( - ConfigWriter $configWriter, - DomainValidator $domainValidator + DomainManager $domainManager ) { - $this->configWriter = $configWriter; - $this->domainValidator = $domainValidator; + $this->domainManager = $domainManager; parent::__construct(); } @@ -80,35 +70,17 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { + $whitelistBefore = $this->domainManager->getEnvDomainWhitelist(); $removeDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); $removeDomains = array_filter(array_map('trim', $removeDomains), 'strlen'); + $this->domainManager->removeEnvDomains($removeDomains); - $whitelist = $this->domainValidator->getEnvDomainWhitelist() ?: []; - foreach ($removeDomains as $removeDomain) { - if (in_array($removeDomain, $whitelist)) { - $index = array_search($removeDomain, $whitelist); - unset($whitelist[$index]); - $output->writeln( - "$removeDomain was removed from the whitelist" - ); - continue; - } else { - $output->writeln( - "$removeDomain is absent in the whitelist" - ); - } + foreach (array_diff($whitelistBefore, $this->domainManager->getEnvDomainWhitelist()) as $removedHost) { + $output->writeln( + $removedHost . ' was removed from the whitelist.' + ); } - - $this->configWriter->saveConfig( - [ - ConfigFilePool::APP_ENV => [ - $this->domainValidator::PARAM_DOWNLOADABLE_DOMAINS => $whitelist - ] - ], - true - ); } - } catch (\Exception $e) { $output->writeln('' . $e->getMessage() . ''); if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php index 70e031eb3e410..dbeb3c7fdd2eb 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php @@ -9,9 +9,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputInterface; - -use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; -use Magento\Downloadable\Model\Url\DomainValidator; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; /** * Class DomainsAddCommand @@ -21,27 +19,18 @@ class DomainsShowCommand extends Command { /** - * @var ConfigWriter + * @var DomainManager */ - private $configWriter; - - /** - * @var DomainValidator - */ - private $domainValidator; + private $domainManager; /** * DomainsShowCommand constructor. - * - * @param ConfigWriter $configWriter - * @param DomainValidator $domainValidator + * @param DomainManager $domainManager */ public function __construct( - ConfigWriter $configWriter, - DomainValidator $domainValidator + DomainManager $domainManager ) { - $this->configWriter = $configWriter; - $this->domainValidator = $domainValidator; + $this->domainManager = $domainManager; parent::__construct(); } @@ -63,11 +52,10 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { try { - $whitelist = implode("\n", $this->domainValidator->getEnvDomainWhitelist() ?: []); + $whitelist = implode("\n", $this->domainManager->getEnvDomainWhitelist()); $output->writeln( "Downloadable domains whitelist:\n$whitelist" ); - } catch (\Exception $e) { $output->writeln('' . $e->getMessage() . ''); if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php new file mode 100644 index 0000000000000..77abfa24e43c2 --- /dev/null +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -0,0 +1,100 @@ +configWriter = $configWriter; + $this->deploymentConfig = $deploymentConfig; + } + + /** + * @inheritdoc + */ + public function getEnvDomainWhitelist(): array + { + return array_map('strtolower', $this->deploymentConfig->get(self::PARAM_DOWNLOADABLE_DOMAINS) ?? []); + } + + /** + * @inheritdoc + */ + public function addEnvDomains($hosts) { + $whitelist = $this->getEnvDomainWhitelist(); + foreach (array_map('strtolower', $hosts) as $host) { + if (!in_array($host, $whitelist)) { + array_push($whitelist, $host); + } + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + self::PARAM_DOWNLOADABLE_DOMAINS => $whitelist + ] + ], + true + ); + } + + /** + * @inheritdoc + */ + public function removeEnvDomains($hosts) { + $whitelist = $this->getEnvDomainWhitelist(); + foreach (array_map('strtolower', $hosts) as $host) { + if (in_array($host, $whitelist)) { + $index = array_search($host, $whitelist); + unset($whitelist[$index]); + } + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + self::PARAM_DOWNLOADABLE_DOMAINS => $whitelist + ] + ], + true + ); + } +} diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php index 66e4365564d67..2d118cd062f5f 100644 --- a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -7,7 +7,7 @@ namespace Magento\Downloadable\Model\Url; -use Magento\Framework\App\DeploymentConfig; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; use Magento\Framework\Validator\Ip as IpValidator; use Zend\Uri\Uri as UriHandler; @@ -37,21 +37,21 @@ class DomainValidator extends \Zend_Validate_Abstract private $uriHandler; /** - * @var DeploymentConfig + * @var DomainManager */ - private $deploymentConfig; + private $domainManager; /** - * @param DeploymentConfig $deploymentConfig + * @param DomainManager $domainManager * @param IpValidator $ipValidator * @param UriHandler $uriHandler */ public function __construct( - DeploymentConfig $deploymentConfig, + DomainManager $domainManager, IpValidator $ipValidator, UriHandler $uriHandler ) { - $this->deploymentConfig = $deploymentConfig; + $this->domainManager = $domainManager; $this->ipValidator = $ipValidator; $this->uriHandler = $uriHandler; @@ -71,7 +71,7 @@ public function isValid($value): bool $host = $this->getHost($value); $isIpAddress = $this->ipValidator->isValid($host); - $isValid = !$isIpAddress && in_array($host, $this->getEnvDomainWhitelist()); + $isValid = !$isIpAddress && in_array($host, $this->domainManager->getEnvDomainWhitelist()); if (!$isValid) { $this->_error(self::INVALID_HOST, $host); @@ -80,16 +80,6 @@ public function isValid($value): bool return $isValid; } - /** - * Get environment whitelist - * - * @return array - */ - public function getEnvDomainWhitelist(): array - { - return array_map('strtolower', $this->deploymentConfig->get(self::PARAM_DOWNLOADABLE_DOMAINS) ?? []); - } - /** * Extract host from url * diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index b467a88e1a913..8bddfb232b331 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -10,9 +10,7 @@ use Magento\Framework\Setup\Patch\DataPatchInterface; use Zend\Uri\Uri as UriHandler; use Magento\Framework\Url\ScopeResolverInterface; -use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; -use Magento\Downloadable\Model\Url\DomainValidator; -use Magento\Framework\Config\File\ConfigFilePool; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; use Magento\Framework\Setup\ModuleDataSetupInterface; /** @@ -31,14 +29,14 @@ class AddDownloadableHostsConfig implements DataPatchInterface private $scopeResolver; /** - * @var ConfigWriter + * @var ModuleDataSetupInterface */ - private $configWriter; + private $moduleDataSetup; /** - * @var ModuleDataSetupInterface + * @var DomainManager */ - private $moduleDataSetup; + private $domainManager; /** * @var array @@ -50,18 +48,18 @@ class AddDownloadableHostsConfig implements DataPatchInterface * * @param UriHandler $uriHandler * @param ScopeResolverInterface $scopeResolver - * @param ConfigWriter $configWriter + * @param DomainManager $domainManager * @param ModuleDataSetupInterface $moduleDataSetup */ public function __construct( UriHandler $uriHandler, ScopeResolverInterface $scopeResolver, - ConfigWriter $configWriter, + DomainManager $domainManager, ModuleDataSetupInterface $moduleDataSetup ) { $this->uriHandler = $uriHandler; $this->scopeResolver = $scopeResolver; - $this->configWriter = $configWriter; + $this->domainManager = $domainManager; $this->moduleDataSetup = $moduleDataSetup; } @@ -114,13 +112,7 @@ public function apply() $this->addHost($scope->getBaseUrl()); } - $this->configWriter->saveConfig( - [ - ConfigFilePool::APP_ENV => [ - DomainValidator::PARAM_DOWNLOADABLE_DOMAINS => array_unique($this->whitelist) - ] - ] - ); + $this->domainManager->addEnvDomains(array_unique($this->whitelist)); } /** diff --git a/app/code/Magento/Downloadable/etc/di.xml b/app/code/Magento/Downloadable/etc/di.xml index 8ee05029333b8..a932e5598f8ae 100644 --- a/app/code/Magento/Downloadable/etc/di.xml +++ b/app/code/Magento/Downloadable/etc/di.xml @@ -92,6 +92,7 @@ + From 4d92c81a066ed0bb00ecdadf992267820150e6f8 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 14:45:12 -0500 Subject: [PATCH 167/372] MC-17700: Downloadable Product links --- .../Model/Url/DomainValidator.php | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php index 2d118cd062f5f..3d44d073af207 100644 --- a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -14,13 +14,8 @@ /** * Class is responsible for checking if downloadable product link domain is allowed. */ -class DomainValidator extends \Zend_Validate_Abstract +class DomainValidator { - /** - * Invalid host message key - */ - private const INVALID_HOST = 'invalidHost'; - /** * Path to the allowed domains in the deployment config */ @@ -54,8 +49,6 @@ public function __construct( $this->domainManager = $domainManager; $this->ipValidator = $ipValidator; $this->uriHandler = $uriHandler; - - $this->initMessageTemplates(); } /** @@ -73,10 +66,6 @@ public function isValid($value): bool $isIpAddress = $this->ipValidator->isValid($host); $isValid = !$isIpAddress && in_array($host, $this->domainManager->getEnvDomainWhitelist()); - if (!$isValid) { - $this->_error(self::INVALID_HOST, $host); - } - return $isValid; } @@ -97,18 +86,4 @@ private function getHost($url): string // ipv6 hosts are brace-delimited in url; they are removed here for subsequent validation return trim($host, '[] '); } - - /** - * Initialize message templates with translating - * - * @return void - */ - private function initMessageTemplates() - { - if (!$this->_messageTemplates) { - $this->_messageTemplates = [ - self::INVALID_HOST => __('Host "%value%" is not allowed.'), - ]; - } - } } From 1a51a17a4f70961151def3799b1aa53295bb2c03 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 14:59:33 -0500 Subject: [PATCH 168/372] MC-17700: Downloadable Product links --- app/code/Magento/Downloadable/Model/DomainManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index 77abfa24e43c2..f343fa2e24703 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -58,7 +58,8 @@ public function getEnvDomainWhitelist(): array /** * @inheritdoc */ - public function addEnvDomains($hosts) { + public function addEnvDomains($hosts) + { $whitelist = $this->getEnvDomainWhitelist(); foreach (array_map('strtolower', $hosts) as $host) { if (!in_array($host, $whitelist)) { From eafcff6c7a584455f1c08e9439804fca5e25a112 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 15:00:04 -0500 Subject: [PATCH 169/372] MC-17700: Downloadable Product links --- app/code/Magento/Downloadable/Model/DomainManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index f343fa2e24703..b3f9cce23cacb 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -80,7 +80,8 @@ public function addEnvDomains($hosts) /** * @inheritdoc */ - public function removeEnvDomains($hosts) { + public function removeEnvDomains($hosts) + { $whitelist = $this->getEnvDomainWhitelist(); foreach (array_map('strtolower', $hosts) as $host) { if (in_array($host, $whitelist)) { From 30cfd33b96dc124989cfd38f24811e0ed3a6079b Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Wed, 17 Jul 2019 15:14:41 -0500 Subject: [PATCH 170/372] MC-17700: Downloadable Product links --- .../Downloadable/Model/Url/DomainValidatorTest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php index 970b8add3e52f..86b5bf3ed05cf 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Downloadable\Model\Url; +use Magento\Downloadable\Model\DomainManager; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\App\DeploymentConfig; @@ -25,16 +26,21 @@ class DomainValidatorTest extends \PHPUnit\Framework\TestCase protected function setUp() { + $objectManager = Bootstrap::getObjectManager(); + $this->deploymentConfig = $this->createPartialMock( DeploymentConfig::class, ['get'] ); - $objectManager = Bootstrap::getObjectManager(); + $domainManager = $objectManager->create( + DomainManager::class, + ['deploymentConfig' => $this->deploymentConfig] + ); $this->model = $objectManager->create( DomainValidator::class, - ['deploymentConfig' => $this->deploymentConfig] + ['domainManager' => $domainManager] ); } From 2763ce536d0597782d2da64b565c3ddb1bf220ea Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Thu, 18 Jul 2019 14:40:32 +0300 Subject: [PATCH 171/372] MC-18099: Changes in Downloadable product upload controller --- .../Adminhtml/Downloadable/FileTest.php | 28 ++++++--- .../Magento/Framework/File/Uploader.php | 57 ++++++++++++++++++- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php index 20e36e6594638..6333d60da3cfe 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php @@ -117,23 +117,35 @@ public function extensionsDataProvider() } /** + * @dataProvider uploadWrongUploadTypeDataProvider * @return void */ - public function testUploadWrongUploadType(): void + public function testUploadWrongUploadType($postData): void { - $postData = [ - 'type' => [ - 'tmp_name' => 'test.txt', - 'name' => 'result.txt', - ], - ]; $this->getRequest()->setPostValue($postData); - $this->getRequest()->setMethod('POST'); + $this->dispatch('backend/admin/downloadable_file/upload'); + $body = $this->getResponse()->getBody(); $result = $this->jsonSerializer->unserialize($body); $this->assertEquals('Upload type can not be determined.', $result['error']); $this->assertEquals(0, $result['errorcode']); } + + public function uploadWrongUploadTypeDataProvider(): array + { + return [ + [ + ['type' => 'test'], + ], + [ + [ + 'type' => [ + 'type1' => 'test', + ], + ], + ], + ]; + } } diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index af19c619ae68f..a6ad3096ff209 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -5,6 +5,7 @@ */ namespace Magento\Framework\File; +use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Validation\ValidationException; @@ -14,6 +15,8 @@ * ATTENTION! This class must be used like abstract class and must added * validation by protected file extension list to extended class * + * @SuppressWarnings(PHPMD.TooManyFields) + * * @api */ class Uploader @@ -160,17 +163,27 @@ class Uploader */ protected $_result; + /** + * @var DirectoryList + */ + private $directoryList; + /** * Init upload * * @param string|array $fileId * @param \Magento\Framework\File\Mime|null $fileMime + * @param DirectoryList|null $directoryList * @throws \DomainException */ public function __construct( $fileId, - Mime $fileMime = null + Mime $fileMime = null, + DirectoryList $directoryList = null ) { + $this->directoryList= $directoryList ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(DirectoryList::class); + $this->_setUploadFileId($fileId); if (!file_exists($this->_file['tmp_name'])) { $code = empty($this->_file['tmp_name']) ? self::TMP_NAME_EMPTY : 0; @@ -550,7 +563,7 @@ private function _getMimeType() */ private function _setUploadFileId($fileId) { - if (is_array($fileId)) { + if (is_array($fileId) && $this->isValidFileId($fileId)) { $this->_uploadType = self::MULTIPLE_STYLE; $this->_file = $fileId; } else { @@ -584,6 +597,46 @@ private function _setUploadFileId($fileId) } } + /** + * Check if $fileId has correct 'tmp_name' field. + * + * @param array $fileId + * @return bool + * @throws \InvalidArgumentException + */ + private function isValidFileId(array $fileId): bool + { + $isValid = false; + if (isset($fileId['tmp_name'])) { + $tmpName = trim($fileId['tmp_name']); + + if (mb_strpos($tmpName, '..') === false) { + $allowedFolders = [ + sys_get_temp_dir(), + $this->directoryList->getPath(DirectoryList::MEDIA), + $this->directoryList->getPath(DirectoryList::VAR_DIR), + $this->directoryList->getPath(DirectoryList::TMP), + $this->directoryList->getPath(DirectoryList::UPLOAD), + ]; + + foreach ($allowedFolders as $allowedFolder) { + if (stripos($tmpName, $allowedFolder) !== false) { + $isValid = true; + break; + } + } + } + } + + if (!$isValid) { + throw new \InvalidArgumentException( + 'Invalid parameter given. A valid $fileId[tmp_name] is expected.' + ); + } + + return $isValid; + } + /** * Create destination folder * From a76a120b60dec8b0664cec98df515ddd3f9feb72 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 18 Jul 2019 10:26:30 -0500 Subject: [PATCH 172/372] MC-17700: Downloadable Product links --- .../Downloadable/Api/LinkRepositoryTest.php | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index 0eb3da755c5f0..7fdfc71227e7c 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -470,6 +470,58 @@ public function testCreateThrowsExceptionIfLinkUrlHasWrongFormat() $this->_webApiCall($this->createServiceInfo, $requestData); } + /** + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Link URL must have valid format. + */ + public function testCreateThrowsExceptionIfLinkUrlUsesDomainNotInWhitelist() + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'link' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'price' => 10, + 'is_shareable' => 1, + 'number_of_downloads' => 100, + 'link_type' => 'url', + 'link_url' => 'http://notAnywhereInEnv.com/', + 'sample_type' => 'url', + 'sample_url' => 'http://www.example.com/', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + + /** + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Sample URL must have valid format. + */ + public function testCreateThrowsExceptionIfSampleUrlUsesDomainNotInWhitelist() + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'link' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'price' => 10, + 'is_shareable' => 1, + 'number_of_downloads' => 100, + 'link_type' => 'url', + 'link_url' => 'http://example.com/', + 'sample_type' => 'url', + 'sample_url' => 'http://www.notAnywhereInEnv.com/', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception From 8e94e71c71c15215593d17dc9ca81747c6f2fdd4 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 18 Jul 2019 12:27:44 -0500 Subject: [PATCH 173/372] MC-17700: Downloadable Product links --- .../AdminCreateDownloadableProductWithDefaultSetLinksTest.xml | 2 +- .../Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml index d9b4e8087cbc9..2fcc87b71bbb4 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml @@ -8,7 +8,7 @@ - + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml index 8b38f91f8719c..e43b8f94c7a3d 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml @@ -8,7 +8,7 @@ - + From 7c199167a89cc0c35ff20bf28aad5771f4ebd17a Mon Sep 17 00:00:00 2001 From: Joan He Date: Thu, 18 Jul 2019 14:25:05 -0500 Subject: [PATCH 174/372] MC-18125: Email template improvement --- lib/internal/Magento/Framework/Filter/Template.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 4881a16b055e7..c330e4d130094 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -79,7 +79,19 @@ class Template implements \Zend_Filter_Interface 'gettemplateprocessor', 'vardirective', 'delete', - 'getdatausingmethod' + 'getdatausingmethod', + '__destruct', + '__call', + '__callStatic', + '__set', + '__unset', + '__sleep', + '__wakeup', + '__invoke', + '__set_state', + '__debugInfo', + '___callParent', + '___callPlugins' ]; /** From 03510d2b455f60c9a2839a1f75dd768a2cf08c1c Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Thu, 18 Jul 2019 14:32:05 -0500 Subject: [PATCH 175/372] MC-17700: Downloadable Product links - CR changes --- .../Downloadable/Api/DomainManagerInterface.php | 8 ++++---- .../Downloadable/Console/Command/DomainsAddCommand.php | 6 +++--- .../Console/Command/DomainsRemoveCommand.php | 6 +++--- .../Console/Command/DomainsShowCommand.php | 2 +- app/code/Magento/Downloadable/Model/DomainManager.php | 10 +++++----- .../Magento/Downloadable/Model/Url/DomainValidator.php | 2 +- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Downloadable/Api/DomainManagerInterface.php b/app/code/Magento/Downloadable/Api/DomainManagerInterface.php index 9174d81621b15..ca98f18e36c33 100644 --- a/app/code/Magento/Downloadable/Api/DomainManagerInterface.php +++ b/app/code/Magento/Downloadable/Api/DomainManagerInterface.php @@ -7,7 +7,7 @@ /** * Interface DomainManagerInterface - * Manage downloadable domains whitelist in the environment config. + * Manage downloadable domains whitelist. */ interface DomainManagerInterface { @@ -16,7 +16,7 @@ interface DomainManagerInterface * * @return array */ - public function getEnvDomainWhitelist(); + public function getDomains(): array; /** * Add host to the whitelist. @@ -24,7 +24,7 @@ public function getEnvDomainWhitelist(); * @param array $hosts * @return void */ - public function addEnvDomains($hosts); + public function addDomains(array $hosts): void; /** * Remove host from the whitelist. @@ -32,5 +32,5 @@ public function addEnvDomains($hosts); * @param array $hosts * @return void */ - public function removeEnvDomains($hosts); + public function removeDomains(array $hosts): void; } diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php index e230d24b2ca73..285bf38eb45b0 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -69,13 +69,13 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { - $whitelistBefore = $this->domainManager->getEnvDomainWhitelist(); + $whitelistBefore = $this->domainManager->getDomains(); $newDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); $newDomains = array_filter(array_map('trim', $newDomains), 'strlen'); - $this->domainManager->addEnvDomains($newDomains); + $this->domainManager->addDomains($newDomains); - foreach (array_diff($this->domainManager->getEnvDomainWhitelist(), $whitelistBefore) as $newHost) { + foreach (array_diff($this->domainManager->getDomains(), $whitelistBefore) as $newHost) { $output->writeln( $newHost . ' was added to the whitelist.' ); diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php index 74c0803e3d9a5..936126c7a21f7 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -70,12 +70,12 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { - $whitelistBefore = $this->domainManager->getEnvDomainWhitelist(); + $whitelistBefore = $this->domainManager->getDomains(); $removeDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); $removeDomains = array_filter(array_map('trim', $removeDomains), 'strlen'); - $this->domainManager->removeEnvDomains($removeDomains); + $this->domainManager->removeDomains($removeDomains); - foreach (array_diff($whitelistBefore, $this->domainManager->getEnvDomainWhitelist()) as $removedHost) { + foreach (array_diff($whitelistBefore, $this->domainManager->getDomains()) as $removedHost) { $output->writeln( $removedHost . ' was removed from the whitelist.' ); diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php index dbeb3c7fdd2eb..a2a705373bb7e 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php @@ -52,7 +52,7 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { try { - $whitelist = implode("\n", $this->domainManager->getEnvDomainWhitelist()); + $whitelist = implode("\n", $this->domainManager->getDomains()); $output->writeln( "Downloadable domains whitelist:\n$whitelist" ); diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index b3f9cce23cacb..3c1c295b296bf 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -50,7 +50,7 @@ public function __construct( /** * @inheritdoc */ - public function getEnvDomainWhitelist(): array + public function getDomains(): array { return array_map('strtolower', $this->deploymentConfig->get(self::PARAM_DOWNLOADABLE_DOMAINS) ?? []); } @@ -58,9 +58,9 @@ public function getEnvDomainWhitelist(): array /** * @inheritdoc */ - public function addEnvDomains($hosts) + public function addDomains(array $hosts): void { - $whitelist = $this->getEnvDomainWhitelist(); + $whitelist = $this->getDomains(); foreach (array_map('strtolower', $hosts) as $host) { if (!in_array($host, $whitelist)) { array_push($whitelist, $host); @@ -80,9 +80,9 @@ public function addEnvDomains($hosts) /** * @inheritdoc */ - public function removeEnvDomains($hosts) + public function removeDomains(array $hosts): void { - $whitelist = $this->getEnvDomainWhitelist(); + $whitelist = $this->getDomains(); foreach (array_map('strtolower', $hosts) as $host) { if (in_array($host, $whitelist)) { $index = array_search($host, $whitelist); diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php index 3d44d073af207..cab7fb134ea33 100644 --- a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -64,7 +64,7 @@ public function isValid($value): bool $host = $this->getHost($value); $isIpAddress = $this->ipValidator->isValid($host); - $isValid = !$isIpAddress && in_array($host, $this->domainManager->getEnvDomainWhitelist()); + $isValid = !$isIpAddress && in_array($host, $this->domainManager->getDomains()); return $isValid; } diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 8bddfb232b331..a6534fa1717f1 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -112,7 +112,7 @@ public function apply() $this->addHost($scope->getBaseUrl()); } - $this->domainManager->addEnvDomains(array_unique($this->whitelist)); + $this->domainManager->addDomains(array_unique($this->whitelist)); } /** From 38182ec65b7d6da2158adb5b11fbb2a9f2404ca9 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 18 Jul 2019 15:14:37 -0500 Subject: [PATCH 176/372] MC-17700: Downloadable Product links --- .../AdminDownloadableProductActionGroup.xml | 17 ++++---- ...bleProductWithInvalidDomainLinkUrlTest.xml | 40 +++++++++++++++++++ 2 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml diff --git a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml index 363911daa41ed..91114e54cb421 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml @@ -40,17 +40,18 @@ + - - - - - - - - + + + + + + + + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml new file mode 100644 index 0000000000000..0291b0bb3110c --- /dev/null +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + <description value="Admin should not be able to create downloadable product with invalid domain link url"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-18282"/> + <group value="Downloadable"/> + <group value="AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest"/> + </annotations> + <before> + <remove keyForRemoval="addDownloadableDomain" /> + </before> + <actionGroup ref="addDownloadableProductLink" stepKey="addDownloadableProductLink"> + <argument name="link" value="downloadableLink"/> + <argument name="index" value="0"/> + </actionGroup> + <actionGroup ref="SaveProductFormNoSuccessCheck" stepKey="saveProduct"/> + <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="Link URL must have valid format." stepKey="seeLinkUrlInvalidMessage" after="saveProduct" /> + <magentoCLI stepKey="addDownloadableDomain2" command="downloadable:domains:add static.magento.com" after="seeLinkUrlInvalidMessage" /> + <checkOption selector="{{AdminProductDownloadableSection.isDownloadableProduct}}" stepKey="checkIsDownloadable" after="addDownloadableDomain2"/> + <checkOption selector="{{AdminProductDownloadableSection.isLinksPurchasedSeparately}}" stepKey="checkIsLinksPurchasedSeparately" after="checkIsDownloadable"/> + <actionGroup ref="addDownloadableProductLink" stepKey="addDownloadableProductLinkAgain" after="checkIsLinksPurchasedSeparately"> + <argument name="link" value="downloadableLink"/> + <argument name="index" value="0"/> + </actionGroup> + <actionGroup ref="saveProductForm" stepKey="saveProductAfterAddingDomainToWhitelist" after="addDownloadableProductLinkAgain" /> + </test> +</tests> From 2453496dfc827e29f4e9d6f2db050085dcf445d2 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov <ikolesov@magento.com> Date: Thu, 18 Jul 2019 16:33:53 -0500 Subject: [PATCH 177/372] MC-17700: Downloadable Product links - CR changes --- .../Console/Command/DomainsShowCommand.php | 2 +- .../Api/ProductRepositoryInterfaceTest.php | 18 +++++++----------- .../Api/ProductRepositoryTest.php | 17 ++++++----------- ...able_product_with_files_and_sample_url.php | 9 ++++----- ...uct_with_files_and_sample_url_rollback.php | 9 ++++----- .../_files/product_downloadable.php | 19 ++++++++----------- .../_files/product_downloadable_rollback.php | 19 ++++++++----------- .../product_downloadable_with_files.php | 19 ++++++++----------- 8 files changed, 46 insertions(+), 66 deletions(-) diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php index a2a705373bb7e..eb4488353a096 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php @@ -12,7 +12,7 @@ use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; /** - * Class DomainsAddCommand + * Class DomainsShowCommand * * Command for listing allowed downloadable domains */ diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index b9afaf1518b8c..2772e80490278 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -9,8 +9,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\Data\StockItemInterface; -use Magento\Downloadable\Console\Command\DomainsAddCommand; -use Magento\Downloadable\Console\Command\DomainsRemoveCommand; +use Magento\Downloadable\Api\DomainManagerInterface; use Magento\Downloadable\Model\Link; use Magento\Store\Model\Store; use Magento\Store\Model\Website; @@ -24,7 +23,6 @@ use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; -use Symfony\Component\Console\Tester\CommandTester; /** * @magentoAppIsolation enabled @@ -66,10 +64,9 @@ protected function setUp() parent::setUp(); $objectManager = Bootstrap::getObjectManager(); - /** @var DomainsAddCommand $domainsAddCommand */ - $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); - $command = new CommandTester($domainsAddCommand); - $command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['example.com']]); + /** @var DomainManagerInterface $domainManager */ + $domainManager = $objectManager->get(DomainManagerInterface::class); + $domainManager->addDomains(['example.com']); } /** @@ -80,10 +77,9 @@ protected function tearDown() parent::tearDown(); $objectManager = Bootstrap::getObjectManager(); - /** @var DomainsRemoveCommand $domainsRemoveCommand */ - $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); - $command = new CommandTester($domainsRemoveCommand); - $command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['example.com']]); + /** @var DomainManagerInterface $domainManager */ + $domainManager = $objectManager->get(DomainManagerInterface::class); + $domainManager->removeDomains(['example.com']); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php index 0415835f2dcb9..c2393d0a5ad2d 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php @@ -7,11 +7,8 @@ namespace Magento\Downloadable\Api; use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Downloadable\Console\Command\DomainsAddCommand; -use Magento\Downloadable\Console\Command\DomainsRemoveCommand; use Magento\Framework\Api\ExtensibleDataInterface; use Magento\TestFramework\TestCase\WebapiAbstract; -use Symfony\Component\Console\Tester\CommandTester; /** * Class ProductRepositoryTest for testing ProductRepository interface with Downloadable Product @@ -35,10 +32,9 @@ protected function setUp() $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var DomainsAddCommand $domainsAddCommand */ - $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); - $command = new CommandTester($domainsAddCommand); - $command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['www.example.com']]); + /** @var DomainManagerInterface $domainManager */ + $domainManager = $objectManager->get(DomainManagerInterface::class); + $domainManager->addDomains(['www.example.com']); } /** @@ -51,10 +47,9 @@ public function tearDown() $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var DomainsRemoveCommand $domainsRemoveCommand */ - $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); - $command = new CommandTester($domainsRemoveCommand); - $command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['www.example.com']]); + /** @var DomainManagerInterface $domainManager */ + $domainManager = $objectManager->get(DomainManagerInterface::class); + $domainManager->removeDomains(['www.example.com']); } protected function getLinkData() diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php index df6d717ed1012..e312d973aeb17 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php @@ -4,14 +4,13 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Api\DomainManagerInterface; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsAddCommand $domainsAddCommand */ -$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); -$command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['example.com', 'sampleurl.com']]); +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->addDomains(['example.com', 'sampleurl.com']); /** * @var \Magento\Catalog\Model\Product $product diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php index dbaf4ea6f67b3..48d6966fb90df 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php @@ -4,14 +4,13 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsRemoveCommand; +use Magento\Downloadable\Api\DomainManagerInterface; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsRemoveCommand $domainsRemoveCommand */ -$domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsRemoveCommand); -$command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['sampleurl.com']]); +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->removeDomains(['sampleurl.com']); // @codingStandardsIgnoreLine require __DIR__ . '/product_downloadable_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php index 56277a75cd801..25344ea447d9a 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php @@ -4,21 +4,18 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Api\DomainManagerInterface; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsAddCommand $domainsAddCommand */ -$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); -$command->execute( +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->addDomains( [ - DomainsAddCommand::INPUT_KEY_DOMAINS => [ - 'example.com', - 'www.example.com', - 'www.sample.example.com', - 'google.com' - ] + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' ] ); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php index 22619d25ee4ec..9a2e1c74fcd33 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php @@ -4,24 +4,21 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsRemoveCommand; +use Magento\Downloadable\Api\DomainManagerInterface; use Magento\Framework\Exception\NoSuchEntityException; \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsRemoveCommand $domainsRemoveCommand */ -$domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsRemoveCommand); -$command->execute( +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->removeDomains( [ - DomainsRemoveCommand::INPUT_KEY_DOMAINS => [ - 'example.com', - 'www.example.com', - 'www.sample.example.com', - 'google.com' - ] + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' ] ); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php index 47eb6c450e9ec..a6c58c586ea16 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php @@ -4,22 +4,19 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Api\DomainManagerInterface; \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsAddCommand $domainsAddCommand */ -$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); -$command->execute( +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->addDomains( [ - DomainsAddCommand::INPUT_KEY_DOMAINS => [ - 'example.com', - 'www.example.com', - 'www.sample.example.com', - 'google.com' - ] + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' ] ); From 4293a7e85f466be422d37a195c5d258f4ae8d810 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 18 Jul 2019 17:27:00 -0500 Subject: [PATCH 178/372] MC-17700: Downloadable Product links --- ...minCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index 0291b0bb3110c..d75c666cb0cb7 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -10,14 +10,12 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest" extends="AdminCreateDownloadableProductWithLinkTest"> <annotations> - <features value="Catalog"/> <stories value="Create Downloadable Product"/> <title value="Create Downloadable Product with invalid domain link url"/> <description value="Admin should not be able to create downloadable product with invalid domain link url"/> <severity value="CRITICAL"/> <testCaseId value="MC-18282"/> <group value="Downloadable"/> - <group value="AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest"/> </annotations> <before> <remove keyForRemoval="addDownloadableDomain" /> From 241271e8417c4264d44682169aa2032e955d6942 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 19 Jul 2019 12:01:10 +0300 Subject: [PATCH 179/372] MC-18099: Changes in Downloadable product upload controller --- .../Magento/Framework/File/UploaderTest.php | 105 ++++++++++++++++++ .../Magento/Framework/File/Uploader.php | 28 +++-- 2 files changed, 124 insertions(+), 9 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php new file mode 100644 index 0000000000000..952df02822a37 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\File; + +use Magento\Framework\App\Filesystem\DirectoryList; + +/** + * Test for \Magento\Framework\File\Uploader + */ +class UploaderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\MediaStorage\Model\File\UploaderFactory + */ + private $uploaderFactory; + + /** + * @var \Magento\Framework\Filesystem + */ + private $filesystem; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->uploaderFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\MediaStorage\Model\File\UploaderFactory::class); + + $this->filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Framework\Filesystem::class); + } + + /** + * @return void + */ + public function testUploadFileFromAllowedFolder(): void + { + $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP); + + $fileName = 'text.txt'; + $tmpDir = 'tmp'; + $filePath = $tmpDirectory->getAbsolutePath($fileName); + $file = fopen($filePath, "wb"); + fwrite($file, 'just a text'); + + $type = [ + 'tmp_name' => $filePath, + 'name' => $fileName, + ]; + + $uploader = $this->uploaderFactory->create(['fileId' => $type]); + $uploader->save($mediaDirectory->getAbsolutePath($tmpDir)); + + $this->assertTrue(is_file($mediaDirectory->getAbsolutePath($tmpDir . DIRECTORY_SEPARATOR . $fileName))); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid parameter given. A valid $fileId[tmp_name] is expected. + * + * @return void + */ + public function testUploadFileFromNotAllowedFolder(): void + { + $fileName = 'text.txt'; + $tmpDir = 'tmp'; + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); + $directoryPath = $tmpDirectory->getAbsolutePath() . $tmpDir; + if (!is_dir($directoryPath)) { + mkdir($directoryPath, 0777, true); + } + $filePath = $directoryPath . DIRECTORY_SEPARATOR . $fileName; + $file = fopen($filePath, "wb"); + fwrite($file, 'just a text'); + + $type = [ + 'tmp_name' => $filePath, + 'name' => $fileName, + ]; + + $this->uploaderFactory->create(['fileId' => $type]); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + parent::tearDown(); + + $tmpDir = 'tmp'; + $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory->delete($tmpDir); + + $logDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); + $logDirectory->delete($tmpDir); + } +} diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index a6ad3096ff209..f9b41709ec7c8 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -563,7 +563,8 @@ private function _getMimeType() */ private function _setUploadFileId($fileId) { - if (is_array($fileId) && $this->isValidFileId($fileId)) { + if (is_array($fileId)) { + $this->validateFileId($fileId); $this->_uploadType = self::MULTIPLE_STYLE; $this->_file = $fileId; } else { @@ -598,19 +599,19 @@ private function _setUploadFileId($fileId) } /** - * Check if $fileId has correct 'tmp_name' field. + * Validates explicitly given uploaded file data. * * @param array $fileId - * @return bool + * @return void * @throws \InvalidArgumentException */ - private function isValidFileId(array $fileId): bool + private function validateFileId(array $fileId): void { $isValid = false; if (isset($fileId['tmp_name'])) { $tmpName = trim($fileId['tmp_name']); - if (mb_strpos($tmpName, '..') === false) { + if (preg_match('/\.\.(\\\|\/)/', $tmpName) !== 1) { $allowedFolders = [ sys_get_temp_dir(), $this->directoryList->getPath(DirectoryList::MEDIA), @@ -619,22 +620,31 @@ private function isValidFileId(array $fileId): bool $this->directoryList->getPath(DirectoryList::UPLOAD), ]; + $disallowedFolders = [ + $this->directoryList->getPath(DirectoryList::LOG), + ]; + foreach ($allowedFolders as $allowedFolder) { - if (stripos($tmpName, $allowedFolder) !== false) { + if (stripos($tmpName, $allowedFolder) === 0) { $isValid = true; break; } } + + foreach ($disallowedFolders as $disallowedFolder) { + if (stripos($tmpName, $disallowedFolder) === 0) { + $isValid = false; + break; + } + } } } if (!$isValid) { throw new \InvalidArgumentException( - 'Invalid parameter given. A valid $fileId[tmp_name] is expected.' + __('Invalid parameter given. A valid $fileId[tmp_name] is expected.') ); } - - return $isValid; } /** From 1647eb46ece170b89e058c69a8a5f95ff2d02de6 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 19 Jul 2019 14:08:02 +0300 Subject: [PATCH 180/372] MC-18099: Changes in Downloadable product upload controller --- .../Magento/Framework/File/UploaderTest.php | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php index 952df02822a37..e38c6a5e81c06 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php @@ -47,8 +47,8 @@ public function testUploadFileFromAllowedFolder(): void $fileName = 'text.txt'; $tmpDir = 'tmp'; $filePath = $tmpDirectory->getAbsolutePath($fileName); - $file = fopen($filePath, "wb"); - fwrite($file, 'just a text'); + + $tmpDirectory->writeFile($fileName, 'just a text'); $type = [ 'tmp_name' => $filePath, @@ -58,7 +58,7 @@ public function testUploadFileFromAllowedFolder(): void $uploader = $this->uploaderFactory->create(['fileId' => $type]); $uploader->save($mediaDirectory->getAbsolutePath($tmpDir)); - $this->assertTrue(is_file($mediaDirectory->getAbsolutePath($tmpDir . DIRECTORY_SEPARATOR . $fileName))); + $this->assertTrue($mediaDirectory->isFile($tmpDir . DIRECTORY_SEPARATOR . $fileName)); } /** @@ -72,13 +72,9 @@ public function testUploadFileFromNotAllowedFolder(): void $fileName = 'text.txt'; $tmpDir = 'tmp'; $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); - $directoryPath = $tmpDirectory->getAbsolutePath() . $tmpDir; - if (!is_dir($directoryPath)) { - mkdir($directoryPath, 0777, true); - } - $filePath = $directoryPath . DIRECTORY_SEPARATOR . $fileName; - $file = fopen($filePath, "wb"); - fwrite($file, 'just a text'); + $filePath = $tmpDirectory->getAbsolutePath() . $tmpDir . DIRECTORY_SEPARATOR . $fileName; + + $tmpDirectory->writeFile($tmpDir . DIRECTORY_SEPARATOR . $fileName, 'just a text'); $type = [ 'tmp_name' => $filePath, @@ -91,15 +87,17 @@ public function testUploadFileFromNotAllowedFolder(): void /** * @inheritdoc */ - protected function tearDown() + public static function tearDownAfterClass() { - parent::tearDown(); + parent::tearDownAfterClass(); + $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Framework\Filesystem::class); $tmpDir = 'tmp'; - $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $mediaDirectory->delete($tmpDir); - $logDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); + $logDirectory = $filesystem->getDirectoryWrite(DirectoryList::LOG); $logDirectory->delete($tmpDir); } } From 6989a910db2c297beb23bfc7629662dd3bab59d5 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 19 Jul 2019 15:43:10 +0300 Subject: [PATCH 181/372] MC-18099: Changes in Downloadable product upload controller --- .../testsuite/Magento/Framework/File/UploaderTest.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php index e38c6a5e81c06..15e52f5b17565 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php @@ -87,17 +87,15 @@ public function testUploadFileFromNotAllowedFolder(): void /** * @inheritdoc */ - public static function tearDownAfterClass() + protected function tearDown() { - parent::tearDownAfterClass(); - $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->get(\Magento\Framework\Filesystem::class); + parent::tearDown(); $tmpDir = 'tmp'; - $mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); $mediaDirectory->delete($tmpDir); - $logDirectory = $filesystem->getDirectoryWrite(DirectoryList::LOG); + $logDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); $logDirectory->delete($tmpDir); } } From 90772dd77c57d7afed71e1af4d0e5869d0c60210 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 19 Jul 2019 08:42:56 -0500 Subject: [PATCH 182/372] MC-17700: Downloadable Product links --- .../Magento/Downloadable/Console/Command/DomainsAddCommand.php | 1 - .../Downloadable/Console/Command/DomainsRemoveCommand.php | 1 - app/code/Magento/Downloadable/Model/DomainManager.php | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php index 285bf38eb45b0..76d9a13f70f1f 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -12,7 +12,6 @@ use Symfony\Component\Console\Input\InputArgument; use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; - /** * Class DomainsAddCommand * diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php index 936126c7a21f7..a30e99a24859c 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -12,7 +12,6 @@ use Symfony\Component\Console\Input\InputArgument; use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; - /** * Class DomainsRemoveCommand * diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index 3c1c295b296bf..e4c5948fa9cd9 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -14,6 +14,7 @@ /** * Class DomainManager + * * Manage downloadable domains whitelist in the environment config. */ class DomainManager implements DomainManagerInterface From a2a47a5e9eb81ad98dd3a1bb54530124cd730455 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 19 Jul 2019 09:35:01 -0500 Subject: [PATCH 183/372] MC-17700: Downloadable Product links --- ...inCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index d75c666cb0cb7..5aa00e3ef48ea 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -34,5 +34,8 @@ <argument name="index" value="0"/> </actionGroup> <actionGroup ref="saveProductForm" stepKey="saveProductAfterAddingDomainToWhitelist" after="addDownloadableProductLinkAgain" /> + <scrollTo selector="{{StorefrontDownloadableProductSection.downloadableLinkByTitle(downloadableLink.title)}}" stepKey="scrollToLinks"/> + <click selector="{{StorefrontDownloadableProductSection.downloadableLinkByTitle(downloadableLink.title)}}" stepKey="selectProductLink"/> + <see selector="{{CheckoutCartProductSection.ProductPriceByName(DownloadableProduct.name)}}" userInput="$52.99" stepKey="assertProductPriceInCart"/> </test> </tests> From 411523e00466128e9b59666064275015318fd0e6 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 19 Jul 2019 14:43:09 -0500 Subject: [PATCH 184/372] MC-17700: Downloadable Product links --- .../Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml index 91114e54cb421..e60e6f6887d09 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml @@ -52,6 +52,7 @@ <checkOption selector="{{AdminProductDownloadableSection.addLinkIsUnlimitedDownloads(index)}}" stepKey="checkDownloadableLinkUnlimited"/> <fillField userInput="{{link.file}}" selector="{{AdminProductDownloadableSection.addLinkFileUrlInput(index)}}" stepKey="fillDownloadableLinkFileUrl"/> <attachFile userInput="{{link.sample}}" selector="{{AdminProductDownloadableSection.addLinkSampleUploadFile(index)}}" stepKey="attachDownloadableLinkUploadSample"/> + <waitForPageLoad stepKey="waitForPageLoadAfterFillingOutForm" /> </actionGroup> <!--Add a downloadable sample file--> From f03348b6eb4f2cbaa120f03d0b967fc829d00d7a Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 22 Jul 2019 10:48:50 -0500 Subject: [PATCH 185/372] MC-17700: Downloadable Product links --- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index a6534fa1717f1..b42d126a9c30a 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -112,7 +112,7 @@ public function apply() $this->addHost($scope->getBaseUrl()); } - $this->domainManager->addDomains(array_unique($this->whitelist)); + $this->domainManager->addDomains($this->whitelist); } /** From f57f4d2e845f90a83d7aee8508753fda6f81f956 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 22 Jul 2019 11:35:54 -0500 Subject: [PATCH 186/372] MC-17700: Downloadable Product links --- ...dminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index 5aa00e3ef48ea..ea7dc8c51388f 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -15,6 +15,7 @@ <description value="Admin should not be able to create downloadable product with invalid domain link url"/> <severity value="CRITICAL"/> <testCaseId value="MC-18282"/> + <useCaseId value="MC-17700"/> <group value="Downloadable"/> </annotations> <before> From 61010964f018362057ae164d2c4cf509a68fe284 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 22 Jul 2019 14:11:16 -0500 Subject: [PATCH 187/372] MC-17700: Downloadable Product links --- .../Downloadable/Model/Link/ContentValidator.php | 16 ++++++++++------ .../Model/Sample/ContentValidator.php | 7 +++++-- ...adableProductWithInvalidDomainLinkUrlTest.xml | 2 +- app/code/Magento/Downloadable/i18n/en_US.csv | 3 ++- .../Downloadable/Api/LinkRepositoryTest.php | 4 ++-- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php index e9ed4920a24bc..28d61986a4f56 100644 --- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php @@ -100,11 +100,13 @@ public function isValid(LinkInterface $link, $validateLinkContent = true, $valid protected function validateLinkResource(LinkInterface $link) { if ($link->getLinkType() === 'url') { - if (!$this->urlValidator->isValid($link->getLinkUrl()) - || !$this->domainValidator->isValid($link->getLinkUrl()) - ) { + if (!$this->urlValidator->isValid($link->getLinkUrl())) { throw new InputException(__('Link URL must have valid format.')); } + + if (!$this->domainValidator->isValid($link->getLinkUrl())) { + throw new InputException(__('Link URL\'s domain is not in list of downloadable_domains in env.php.')); + } } elseif ($link->getLinkFileContent()) { if (!$this->fileContentValidator->isValid($link->getLinkFileContent())) { throw new InputException(__('Provided file content must be valid base64 encoded data.')); @@ -124,11 +126,13 @@ protected function validateLinkResource(LinkInterface $link) protected function validateSampleResource(LinkInterface $link) { if ($link->getSampleType() === 'url') { - if (!$this->urlValidator->isValid($link->getSampleUrl()) - || !$this->domainValidator->isValid($link->getSampleUrl()) - ) { + if (!$this->urlValidator->isValid($link->getSampleUrl())) { throw new InputException(__('Sample URL must have valid format.')); } + + if (!$this->domainValidator->isValid($link->getSampleUrl())) { + throw new InputException(__('Sample URL\'s domain is not in list of downloadable_domains in env.php.')); + } } elseif ($link->getSampleFileContent()) { if (!$this->fileContentValidator->isValid($link->getSampleFileContent())) { throw new InputException(__('Provided file content must be valid base64 encoded data.')); diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php index 7c53a228f27c8..697878017ee8b 100644 --- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php @@ -88,10 +88,13 @@ public function isValid(SampleInterface $sample, $validateSampleContent = true) protected function validateSampleResource(SampleInterface $sample) { if ($sample->getSampleType() === 'url') { - if (!$this->urlValidator->isValid($sample->getSampleUrl()) - || !$this->domainValidator->isValid($sample->getSampleUrl())) { + if (!$this->urlValidator->isValid($sample->getSampleUrl())) { throw new InputException(__('Sample URL must have valid format.')); } + + if (!$this->domainValidator->isValid($sample->getSampleUrl())) { + throw new InputException(__('Sample URL\'s domain is not in list of downloadable_domains in env.php.')); + } } elseif ($sample->getSampleFileContent()) { if (!$this->fileContentValidator->isValid($sample->getSampleFileContent())) { throw new InputException(__('Provided file content must be valid base64 encoded data.')); diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index ea7dc8c51388f..4eb6b82b65918 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -26,7 +26,7 @@ <argument name="index" value="0"/> </actionGroup> <actionGroup ref="SaveProductFormNoSuccessCheck" stepKey="saveProduct"/> - <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="Link URL must have valid format." stepKey="seeLinkUrlInvalidMessage" after="saveProduct" /> + <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="Link URL's domain is not in list of downloadable_domains in env.php." stepKey="seeLinkUrlInvalidMessage" after="saveProduct" /> <magentoCLI stepKey="addDownloadableDomain2" command="downloadable:domains:add static.magento.com" after="seeLinkUrlInvalidMessage" /> <checkOption selector="{{AdminProductDownloadableSection.isDownloadableProduct}}" stepKey="checkIsDownloadable" after="addDownloadableDomain2"/> <checkOption selector="{{AdminProductDownloadableSection.isLinksPurchasedSeparately}}" stepKey="checkIsLinksPurchasedSeparately" after="checkIsDownloadable"/> diff --git a/app/code/Magento/Downloadable/i18n/en_US.csv b/app/code/Magento/Downloadable/i18n/en_US.csv index 6158f1c579722..d5607d7f536ce 100644 --- a/app/code/Magento/Downloadable/i18n/en_US.csv +++ b/app/code/Magento/Downloadable/i18n/en_US.csv @@ -118,4 +118,5 @@ Downloads,Downloads "Use Content-Disposition","Use Content-Disposition" "Disable Guest Checkout if Cart Contains Downloadable Items","Disable Guest Checkout if Cart Contains Downloadable Items" "Guest checkout will only work with shareable.","Guest checkout will only work with shareable." -"Host ""%value"" is not allowed.","Host ""%value"" is not allowed." +"Link URL's domain is not in list of downloadable_domains in env.php.","Link URL's domain is not in list of downloadable_domains in env.php." +"Sample URL's domain is not in list of downloadable_domains in env.php.","Link URL's domain is not in list of downloadable_domains in env.php." diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index 7fdfc71227e7c..3a24aab30cb65 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -473,7 +473,7 @@ public function testCreateThrowsExceptionIfLinkUrlHasWrongFormat() /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception - * @expectedExceptionMessage Link URL must have valid format. + * @expectedExceptionMessage Link URL's domain is not in list of downloadable_domains in env.php. */ public function testCreateThrowsExceptionIfLinkUrlUsesDomainNotInWhitelist() { @@ -499,7 +499,7 @@ public function testCreateThrowsExceptionIfLinkUrlUsesDomainNotInWhitelist() /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception - * @expectedExceptionMessage Sample URL must have valid format. + * @expectedExceptionMessage Sample URL's domain is not in list of downloadable_domains in env.php. */ public function testCreateThrowsExceptionIfSampleUrlUsesDomainNotInWhitelist() { From 7375716d7ddd8269a0bff29d86bc67c5c6815dd4 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 22 Jul 2019 15:47:46 -0500 Subject: [PATCH 188/372] MC-15298: Allow admin to opt out of admin analytics tracking --- .../Magento/AdminAnalytics/Block/Metadata.php | 84 +++++++++++ app/code/Magento/AdminAnalytics/README.md | 1 + .../SelectAdminUsageSettingActionGroup.xml | 19 +++ .../Test/Mftf/Section/AdminHeaderSection.xml | 15 ++ .../Mftf/Section/AdminUsageConfigSection.xml | 16 ++ .../Test/Mftf/Test/TrackingScriptTest.xml | 137 ++++++++++++++++++ app/code/Magento/AdminAnalytics/composer.json | 26 ++++ .../AdminAnalytics/etc/adminhtml/system.xml | 21 +++ .../Magento/AdminAnalytics/etc/config.xml | 18 +++ .../Magento/AdminAnalytics/etc/module.xml | 10 ++ .../Magento/AdminAnalytics/registration.php | 9 ++ .../view/adminhtml/layout/default.xml | 19 +++ .../view/adminhtml/templates/tracking.phtml | 15 ++ 13 files changed, 390 insertions(+) create mode 100644 app/code/Magento/AdminAnalytics/Block/Metadata.php create mode 100644 app/code/Magento/AdminAnalytics/README.md create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/SelectAdminUsageSettingActionGroup.xml create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminHeaderSection.xml create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml create mode 100644 app/code/Magento/AdminAnalytics/composer.json create mode 100644 app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/module.xml create mode 100644 app/code/Magento/AdminAnalytics/registration.php create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml diff --git a/app/code/Magento/AdminAnalytics/Block/Metadata.php b/app/code/Magento/AdminAnalytics/Block/Metadata.php new file mode 100644 index 0000000000000..e89d09ab100eb --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Block/Metadata.php @@ -0,0 +1,84 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Block; + +use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\Template\Context; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Backend\Model\Auth\Session; +use Magento\Framework\App\State; + +/** + * Gets user version and mode + * + * @api + */ +class Metadata extends Template +{ + /** + * @var State + */ + private $appState; + + /** + * @var Session + */ + private $authSession; + + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @param Context $context + * @param ProductMetadataInterface $productMetadata + * @param Session $authSession + * @param State $appState + * @param array $data + */ + public function __construct( + Context $context, + ProductMetadataInterface $productMetadata, + Session $authSession, + State $appState, + array $data = [] + ) { + $this->productMetadata = $productMetadata; + $this->authSession = $authSession; + $this->appState = $appState; + parent::__construct($context, $data); + } + + /** + * Get product version + * + * @return string + */ + public function getMagentoVersion() :string + { + return $this->productMetadata->getVersion(); + } + + /** + * Get current user id (hash generated from email) + * + * @return string + */ + public function getCurrentUser() :string + { + return hash('sha512', 'ADMIN_USER' . $this->authSession->getUser()->getEmail()); + } + /** + * Get Magento mode + * + * @return string + */ + public function getMode() :string + { + return $this->appState->getMode(); + } +} diff --git a/app/code/Magento/AdminAnalytics/README.md b/app/code/Magento/AdminAnalytics/README.md new file mode 100644 index 0000000000000..1280e0fcef10f --- /dev/null +++ b/app/code/Magento/AdminAnalytics/README.md @@ -0,0 +1 @@ +The purpose of Magento\AdminAnalytics module is gather information on which features the users uses and sends it to adobe analytics \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/SelectAdminUsageSettingActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/SelectAdminUsageSettingActionGroup.xml new file mode 100644 index 0000000000000..3b302fe5be18b --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/SelectAdminUsageSettingActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="SelectAdminUsageSetting"> + <arguments> + <argument name="adminUsageValue" type="string" defaultValue="0"/> + </arguments> + <conditionalClick selector="{{AdminUsageConfigSection.adminUsageHeader}}" dependentSelector="{{AdminUsageConfigSection.adminUsageOptions}}" visible="false" stepKey="clickOnAdminUsageHeader"/> + <selectOption selector="{{AdminUsageConfigSection.adminUsageOptions}}" userInput="{{adminUsageValue}}" stepKey="selectOption"/> + <click selector="{{AdminNewStoreGroupActionsSection.saveButton}}" stepKey="clickSaveButton"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminHeaderSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminHeaderSection.xml new file mode 100644 index 0000000000000..cc9f495a60026 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminHeaderSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminHeaderSection"> + <element name="adminTrackingScript" type="text" selector="script[src*='//assets.adobedtm.com/launch']"/> + <element name="adminTrackingMetaData" type="text" selector="//*script[contains('adminAnalyticsMetadata')]"/> + </section> +</sections> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml new file mode 100644 index 0000000000000..ddb89f0bfb72c --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminUsageConfigSection"> + + <element name="adminUsageHeader" type="text" selector="#admin_usage-head"/> + <element name="adminUsageOptions" type="select" selector="#admin_usage_enabled"/> + </section> +</sections> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml new file mode 100644 index 0000000000000..da0d5041a6e34 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="TrackingScriptTest"> + <annotations> + <features value="Backend"/> + <stories value="Checks to see if the tracking script is in the dom of admin and if setting is turned to no it checks if the tracking script in the dom was removed"/> + <title value="Checks to see if the tracking script is in the dom of admin and if setting is turned to no it checks if the tracking script in the dom was removed"/> + <description value="Checks to see if the tracking script is in the dom of admin and if setting is turned to no it checks if the tracking script in the dom was removed"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-18192"/> + <group value="backend"/> + <group value="login"/> + </annotations> + + <!-- Logging in Magento admin and checking for tracking script in dashboard --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <closeAdminNotification stepKey="closeAdminNotification"/> + + <!-- Navigating to advance settings --> + <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettings"/> + <waitForPageLoad stepKey="waitForAdvanceSettings"/> + + <!-- Changing usage setting to Yes --> + <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToYes"> + <argument name="adminUsageValue" value="1"/> + </actionGroup> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrl"/> + + <!-- Checking for tracking script in salesOrderPage --> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPage"/> + <waitForPageLoad stepKey="waitForSalesOrderPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSalesOrder"/> + + <!-- Checking for tracking script in catalogProductsPage --> + <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPage"/> + <waitForPageLoad stepKey="waitForCatalogProductsPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCatalogProducts"/> + + <!-- Checking for tracking script in customersAllCustomersPage --> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPage"/> + <waitForPageLoad stepKey="waitForCustomersAllCustomersPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCustomersAllCustomers"/> + + <!-- Checking for tracking script in marketingCatalogPriceRulePage --> + <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePage"/> + <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlMarketingCatalogPriceRule"/> + + <!-- Checking for tracking script in contentBlocksPage --> + <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPage"/> + <waitForPageLoad stepKey="waitForContentBlocksPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlContentBlocks"/> + + <!-- Checking for tracking script in reportsSearchTermsPage --> + <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPage"/> + <waitForPageLoad stepKey="waitForSearchTermsPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlReportsSearchTerms"/> + + <!-- Checking for tracking script in storesAllStoresPage --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPage"/> + <waitForPageLoad stepKey="waitForStoresAllStoresPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlStoresAllStores"/> + + <!-- Checking for tracking script in systemImportPage --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPage"/> + <waitForPageLoad stepKey="waitForSystemImportPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSystemImport"/> + + <!-- Checking for tracking script in findPartnersAndExtensionsPage --> + <amOnPage url="{{FindPartnersAndExtensionsPage.url}}" stepKey="goToFindPartnersAndExtensionsPage"/> + <waitForPageLoad stepKey="waitForFindPartnersAndExtensionsPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlFindPartnersAndExtensions"/> + + <!-- Navigating to advance settings --> + <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettingsAgain"/> + <waitForPageLoad stepKey="waitForAdvanceSettingsAgain"/> + + <!-- Changing usage setting back to No --> + <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToNo"> + <argument name="adminUsageValue" value="0"/> + </actionGroup> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlTest"/> + + <!-- Checking for removed tracking script in salesOrderPage --> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPageAgain"/> + <waitForPageLoad stepKey="waitForSalesOrderPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSalesOrderTest"/> + + <!-- Checking for removed tracking script in catalogProductsPage --> + <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPageAgain"/> + <waitForPageLoad stepKey="waitForCatalogProductsPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCatalogProductsTest"/> + + <!-- Checking for removed tracking script in customersAllCustomersPage --> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPageAgain"/> + <waitForPageLoad stepKey="waitForCustomersAllCustomersPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCustomersAllCustomersTest"/> + + <!-- Checking for removed tracking script in marketingCatalogPriceRulePage --> + <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePageAgain"/> + <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlMarketingCatalogTest"/> + + <!-- Checking for removed tracking script in contentBlocksPage --> + <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPageAgain"/> + <waitForPageLoad stepKey="waitForContentBlocksPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlContentBlocksTest"/> + + <!-- Checking for removed tracking script in reportsSearchTermsPage --> + <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPageAgain"/> + <waitForPageLoad stepKey="waitForSearchTermsPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlReportsSearchTest"/> + + <!-- Checking for removed tracking script in storesAllStoresPage --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPageAgain"/> + <waitForPageLoad stepKey="waitForStoresAllStoresPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlStoresAllStoresTest"/> + + <!-- Checking for removed tracking script in systemImportPage --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPageAgain"/> + <waitForPageLoad stepKey="waitForSystemImportPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSystemsImportTest"/> + + <!-- Checking for removed tracking script in findPartnersAndExtensionsPage --> + <amOnPage url="{{FindPartnersAndExtensionsPage.url}}" stepKey="goToFindPartnersAndExtensionsPageAgain"/> + <waitForPageLoad stepKey="waitForFindPartnersAndExtensionsPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlFindPartnersTest"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json new file mode 100644 index 0000000000000..085d258c72b57 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-admin-analytics", + "description": "N/A", + "config": { + "sort-packages": true + }, + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-backend": "*" + }, + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\AdminAnalytics\\": "" + } + } +} + diff --git a/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml b/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml new file mode 100644 index 0000000000000..97372e1cca087 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> + <system> + <section id="admin"> + <group id="usage" translate="label" type="text" sortOrder="2000" showInDefault="1" showInWebsite="0" showInStore="0"> + <label>Admin Usage</label> + <field id="enabled" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0"> + <label>Enable Admin Usage Tracking</label> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + <comment>Allow Magento to track admin usage in order to improve the quality and user experience.</comment> + </field> + </group> + </section> + </system> +</config> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml new file mode 100644 index 0000000000000..85b6b6879f083 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/config.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + <default> + <admin> + <usage> + <enabled> + 0 + </enabled> + </usage> + </admin> + </default> +</config> diff --git a/app/code/Magento/AdminAnalytics/etc/module.xml b/app/code/Magento/AdminAnalytics/etc/module.xml new file mode 100644 index 0000000000000..f0990b114e25f --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/module.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_AdminAnalytics"/> +</config> diff --git a/app/code/Magento/AdminAnalytics/registration.php b/app/code/Magento/AdminAnalytics/registration.php new file mode 100644 index 0000000000000..65c9955d396a8 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/registration.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use \Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_AdminAnalytics', __DIR__); diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml new file mode 100644 index 0000000000000..8ec8ac3bfaf54 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" > + <body> + <referenceContainer name="header"> + <block class="Magento\AdminAnalytics\Block\Metadata" name="tracking" as="tracking" template="Magento_AdminAnalytics::tracking.phtml" ifconfig="admin/usage/enabled"> + <arguments> + <argument name="tracking_url" xsi:type="string">//assets.adobedtm.com/launch-EN30eb7ffa064444f1b8b0368ef38fd3a9.min.js</argument> + </arguments> + </block> + </referenceContainer> + </body> +</page> + diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml new file mode 100644 index 0000000000000..e4acd77b13353 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +?> + +<script src="<?= $block->escapeUrl($block->getTrackingUrl()) ?>" async></script> +<script> + var adminAnalyticsMetadata = { + "version": "<?= $block->escapeJs($block->getMagentoVersion()) ?>", + "user": "<?= $block->escapeJs($block->getCurrentUser()) ?>", + "mode": "<?= $block->escapeJs($block->getMode()) ?>" + }; +</script> \ No newline at end of file From 114a25dd9c3936d1b80121343df1c9c95dec94bc Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 23 Jul 2019 09:28:33 -0500 Subject: [PATCH 189/372] MC-17700: Downloadable Product links --- app/code/Magento/Downloadable/i18n/en_US.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/i18n/en_US.csv b/app/code/Magento/Downloadable/i18n/en_US.csv index d5607d7f536ce..1e96413aa08a1 100644 --- a/app/code/Magento/Downloadable/i18n/en_US.csv +++ b/app/code/Magento/Downloadable/i18n/en_US.csv @@ -119,4 +119,4 @@ Downloads,Downloads "Disable Guest Checkout if Cart Contains Downloadable Items","Disable Guest Checkout if Cart Contains Downloadable Items" "Guest checkout will only work with shareable.","Guest checkout will only work with shareable." "Link URL's domain is not in list of downloadable_domains in env.php.","Link URL's domain is not in list of downloadable_domains in env.php." -"Sample URL's domain is not in list of downloadable_domains in env.php.","Link URL's domain is not in list of downloadable_domains in env.php." +"Sample URL's domain is not in list of downloadable_domains in env.php.","Sample URL's domain is not in list of downloadable_domains in env.php." From 19341f41d6cf385bcbdc41d6d900232fae66c9ed Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 23 Jul 2019 11:12:17 -0500 Subject: [PATCH 190/372] MC-17700: Downloadable Product links --- .../Downloadable/Model/DomainManager.php | 4 ++- .../Patch/Data/AddDownloadableHostsConfig.php | 28 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index e4c5948fa9cd9..e1f275902b034 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -64,7 +64,7 @@ public function addDomains(array $hosts): void $whitelist = $this->getDomains(); foreach (array_map('strtolower', $hosts) as $host) { if (!in_array($host, $whitelist)) { - array_push($whitelist, $host); + $whitelist[] = $host; } } @@ -91,6 +91,8 @@ public function removeDomains(array $hosts): void } } + $whitelist = array_values($whitelist); // reindex whitelist to prevent non-sequential keying + $this->configWriter->saveConfig( [ ConfigFilePool::APP_ENV => [ diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index b42d126a9c30a..575a6a4d7180b 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -7,11 +7,14 @@ namespace Magento\Downloadable\Setup\Patch\Data; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; +use Magento\Store\Model\ScopeInterface; use Zend\Uri\Uri as UriHandler; use Magento\Framework\Url\ScopeResolverInterface; use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Backend\App\Area\FrontNameResolver; /** * Adding base url as allowed downloadable domain. @@ -28,6 +31,11 @@ class AddDownloadableHostsConfig implements DataPatchInterface */ private $scopeResolver; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + /** * @var ModuleDataSetupInterface */ @@ -48,17 +56,20 @@ class AddDownloadableHostsConfig implements DataPatchInterface * * @param UriHandler $uriHandler * @param ScopeResolverInterface $scopeResolver + * @param ScopeConfigInterface $scopeConfig * @param DomainManager $domainManager * @param ModuleDataSetupInterface $moduleDataSetup */ public function __construct( UriHandler $uriHandler, ScopeResolverInterface $scopeResolver, + ScopeConfigInterface $scopeConfig, DomainManager $domainManager, ModuleDataSetupInterface $moduleDataSetup ) { $this->uriHandler = $uriHandler; $this->scopeResolver = $scopeResolver; + $this->scopeConfig = $scopeConfig; $this->domainManager = $domainManager; $this->moduleDataSetup = $moduleDataSetup; } @@ -68,6 +79,19 @@ public function __construct( */ public function apply() { + foreach ($this->scopeResolver->getScopes() as $scope) { + $this->addHost($scope->getBaseUrl()); + } + + $customAdminUrl = $this->scopeConfig->getValue( + FrontNameResolver::XML_PATH_CUSTOM_ADMIN_URL, + ScopeInterface::SCOPE_STORE + ); + + if ($customAdminUrl) { + $this->addHost($customAdminUrl); + } + if ($this->moduleDataSetup->tableExists('downloadable_link')) { $select = $this->moduleDataSetup->getConnection() ->select() @@ -108,10 +132,6 @@ public function apply() } } - foreach ($this->scopeResolver->getScopes() as $scope) { - $this->addHost($scope->getBaseUrl()); - } - $this->domainManager->addDomains($this->whitelist); } From 52a1316151042ad68bc6cd1b15da7f4abe4dc499 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 23 Jul 2019 15:20:47 -0500 Subject: [PATCH 191/372] MC-17700: Downloadable Product links --- .../Import/Product/Type/Downloadable.php | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index e03964bd2c386..48ff56184a3ac 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -8,6 +8,7 @@ namespace Magento\DownloadableImportExport\Model\Import\Product\Type; use Magento\CatalogImportExport\Model\Import\Product as ImportProduct; +use Magento\Downloadable\Model\Url\DomainValidator; use Magento\Framework\EntityManager\MetadataPool; use \Magento\Store\Model\Store; @@ -101,6 +102,8 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ const ERROR_COLS_IS_EMPTY = 'emptyOptions'; + private const ERROR_NOT_IN_DOMAIN_WHITELIST = 'notInDomainWhitelist'; + /** * Validation failure message template definitions * @@ -111,7 +114,8 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ self::ERROR_GROUP_TITLE_NOT_FOUND => 'Group titles not found for downloadable products', self::ERROR_OPTION_NO_TITLE => 'Option no title', self::ERROR_MOVE_FILE => 'Error move file', - self::ERROR_COLS_IS_EMPTY => 'Missing sample and links data for the downloadable product' + self::ERROR_COLS_IS_EMPTY => 'Missing sample and links data for the downloadable product', + self::ERROR_NOT_IN_DOMAIN_WHITELIST => 'Link URL' ]; /** @@ -244,6 +248,11 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ */ protected $downloadableHelper; + /** + * @var DomainValidator + */ + private $domainValidator; + /** * Downloadable constructor * @@ -262,12 +271,14 @@ public function __construct( array $params, \Magento\DownloadableImportExport\Helper\Uploader $uploaderHelper, \Magento\DownloadableImportExport\Helper\Data $downloadableHelper, + DomainValidator $domainValidator, MetadataPool $metadataPool = null ) { parent::__construct($attrSetColFac, $prodAttrColFac, $resource, $params, $metadataPool); $this->parameters = $this->_entityModel->getParameters(); $this->_resource = $resource; $this->uploaderHelper = $uploaderHelper; + $this->domainValidator = $domainValidator; $this->downloadableHelper = $downloadableHelper; } @@ -345,7 +356,20 @@ protected function isRowValidSample(array $rowData) } if (isset($rowData[self::COL_DOWNLOADABLE_SAMPLES]) && $rowData[self::COL_DOWNLOADABLE_SAMPLES] != '') { - $result = $this->isTitle($this->prepareSampleData($rowData[self::COL_DOWNLOADABLE_SAMPLES])); + $sampleData = $this->prepareSampleData($rowData[static::COL_DOWNLOADABLE_SAMPLES]); + + $result = $this->isTitle($sampleData); + foreach ($sampleData as $link) { + if (isset($link['sample_type']) && + $link['sample_type'] === 'url' && + isset($link['sample_url']) && + strlen($link['sample_url']) && + !$this->domainValidator->isValid($link['sample_url']) + ) { + $this->_entityModel->addRowError(static::ERROR_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; + } + } } return $result; } @@ -369,7 +393,20 @@ protected function isRowValidLink(array $rowData) if (isset($rowData[self::COL_DOWNLOADABLE_LINKS]) && $rowData[self::COL_DOWNLOADABLE_LINKS] != '' ) { - $result = $this->isTitle($this->prepareLinkData($rowData[self::COL_DOWNLOADABLE_LINKS])); + $linkData = $this->prepareLinkData($rowData[self::COL_DOWNLOADABLE_LINKS]); + $result = $this->isTitle($linkData); + + foreach ($linkData as $link) { + if (isset($link['link_type']) && + $link['link_type'] === 'url' && + isset($link['link_url']) && + strlen($link['link_url']) && + !$this->domainValidator->isValid($link['link_url']) + ) { + $this->_entityModel->addRowError(static::ERROR_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; + } + } } return $result; } From 96a3f238f979af9fb01b4e4bb2c1715db2de00d5 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 23 Jul 2019 16:12:28 -0500 Subject: [PATCH 192/372] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/Downloadable.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index 48ff56184a3ac..db4747c01b448 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -16,6 +16,7 @@ * Class Downloadable * * @SuppressWarnings(PHPMD.TooManyFields) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType { @@ -102,7 +103,9 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ const ERROR_COLS_IS_EMPTY = 'emptyOptions'; - private const ERROR_NOT_IN_DOMAIN_WHITELIST = 'notInDomainWhitelist'; + private const ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST = 'linkUrlNotInDomainWhitelist'; + + private const ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST = 'sampleUrlNotInDomainWhitelist'; /** * Validation failure message template definitions @@ -115,7 +118,10 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ self::ERROR_OPTION_NO_TITLE => 'Option no title', self::ERROR_MOVE_FILE => 'Error move file', self::ERROR_COLS_IS_EMPTY => 'Missing sample and links data for the downloadable product', - self::ERROR_NOT_IN_DOMAIN_WHITELIST => 'Link URL' + self::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST => + 'Link URL\'s domain is not in list of downloadable_domains in env.php.', + self::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST => + 'Sample URL\'s domain is not in list of downloadable_domains in env.php.' ]; /** @@ -344,6 +350,7 @@ public function isRowValid(array $rowData, $rowNum, $isNewProduct = true) * * @param array $rowData * @return bool + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function isRowValidSample(array $rowData) { @@ -366,7 +373,7 @@ protected function isRowValidSample(array $rowData) strlen($link['sample_url']) && !$this->domainValidator->isValid($link['sample_url']) ) { - $this->_entityModel->addRowError(static::ERROR_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); $result = true; } } @@ -379,6 +386,7 @@ protected function isRowValidSample(array $rowData) * * @param array $rowData * @return bool + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function isRowValidLink(array $rowData) { @@ -403,7 +411,7 @@ protected function isRowValidLink(array $rowData) strlen($link['link_url']) && !$this->domainValidator->isValid($link['link_url']) ) { - $this->_entityModel->addRowError(static::ERROR_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); $result = true; } } From 707e50167e3ded4e6dfa979b27685c03699b0106 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 09:07:52 -0500 Subject: [PATCH 193/372] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/Downloadable.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index db4747c01b448..8f7797ea5d1d7 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -268,6 +268,7 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ * @param array $params * @param \Magento\DownloadableImportExport\Helper\Uploader $uploaderHelper * @param \Magento\DownloadableImportExport\Helper\Data $downloadableHelper + * @param DomainValidator $domainValidator * @param MetadataPool $metadataPool */ public function __construct( @@ -874,6 +875,7 @@ protected function parseSampleOption($values) /** * Uploading files into the "downloadable/files" media folder. + * * Return a new file name if the same file is already exists. * * @param string $fileName From 6493df9e3c0167d5489aee91db3b29a1af5c953c Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 09:38:30 -0500 Subject: [PATCH 194/372] MC-17700: Downloadable Product links --- .../Import/Product/Type/DownloadableTest.php | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php index 776ec9f990f5e..fe0f0ebf4839c 100644 --- a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php +++ b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php @@ -5,6 +5,7 @@ */ namespace Magento\DownloadableImportExport\Model\Import\Product\Type; +use Magento\Downloadable\Api\DomainManagerInterface; use Magento\Framework\App\Filesystem\DirectoryList; /** @@ -32,6 +33,11 @@ class DownloadableTest extends \PHPUnit\Framework\TestCase */ const TEST_PRODUCT_SAMPLES_GROUP_NAME = 'TEST Import Samples'; + /** + * @var DomainManagerInterface + */ + private $domainManager; + /** * @var \Magento\CatalogImportExport\Model\Import\Product */ @@ -47,6 +53,9 @@ class DownloadableTest extends \PHPUnit\Framework\TestCase */ protected $productMetadata; + /** + * @inheritDoc + */ protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -56,6 +65,17 @@ protected function setUp() /** @var \Magento\Framework\EntityManager\MetadataPool $metadataPool */ $metadataPool = $this->objectManager->get(\Magento\Framework\EntityManager\MetadataPool::class); $this->productMetadata = $metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); + + $this->domainManager = $this->objectManager->get(DomainManagerInterface::class); + $this->domainManager->addDomains(['www.google.com', 'www.yahoo.com']); + } + + /** + * @inheritDoc + */ + protected function tearDown() + { + $this->domainManager->removeDomains(['www.google.com', 'www.yahoo.com']); } /** @@ -112,7 +132,7 @@ public function testDownloadableImport() $downloadableSamples = $product->getDownloadableSamples(); //TODO: Track Fields: id, link_id, link_file and sample_file) - $expectedLinks= [ + $expectedLinks = [ 'file' => [ 'title' => 'TEST Import Link Title File', 'sort_order' => '78', @@ -154,7 +174,7 @@ public function testDownloadableImport() } //TODO: Track Fields: id, sample_id and sample_file) - $expectedSamples= [ + $expectedSamples = [ 'file' => [ 'title' => 'TEST Import Sample File', 'sort_order' => '178', From 733f55e793da46d5b3fbd9c0c7089a46dc49da64 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 10:33:00 -0500 Subject: [PATCH 195/372] MC-17700: Downloadable Product links --- .../Import/Product/Type/Downloadable.php | 102 ++++++++++-------- 1 file changed, 58 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index 8f7797ea5d1d7..b69b8ddacdfca 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -16,7 +16,6 @@ * Class Downloadable * * @SuppressWarnings(PHPMD.TooManyFields) - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType { @@ -351,34 +350,34 @@ public function isRowValid(array $rowData, $rowNum, $isNewProduct = true) * * @param array $rowData * @return bool - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function isRowValidSample(array $rowData) { - $result = false; - if (isset($rowData[self::COL_DOWNLOADABLE_SAMPLES]) - && $rowData[self::COL_DOWNLOADABLE_SAMPLES] != '' - && $this->sampleGroupTitle($rowData) == '') { - $this->_entityModel->addRowError(self::ERROR_GROUP_TITLE_NOT_FOUND, $this->rowNum); + $hasSampleLinkData = ( + isset($rowData[self::COL_DOWNLOADABLE_SAMPLES]) && + $rowData[self::COL_DOWNLOADABLE_SAMPLES] != '' + ); + + if (!$hasSampleLinkData) { + return false; + } + + $sampleData = $this->prepareSampleData($rowData[static::COL_DOWNLOADABLE_SAMPLES]); + + if ($this->sampleGroupTitle($rowData) == '') { $result = true; + $this->_entityModel->addRowError(self::ERROR_GROUP_TITLE_NOT_FOUND, $this->rowNum); } - if (isset($rowData[self::COL_DOWNLOADABLE_SAMPLES]) - && $rowData[self::COL_DOWNLOADABLE_SAMPLES] != '') { - $sampleData = $this->prepareSampleData($rowData[static::COL_DOWNLOADABLE_SAMPLES]); - - $result = $this->isTitle($sampleData); - foreach ($sampleData as $link) { - if (isset($link['sample_type']) && - $link['sample_type'] === 'url' && - isset($link['sample_url']) && - strlen($link['sample_url']) && - !$this->domainValidator->isValid($link['sample_url']) - ) { - $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); - $result = true; - } + + $result = $result ?? $this->isTitle($sampleData); + + foreach ($sampleData as $link) { + if ($this->hasDomainNotInWhitelist($link, 'sample_type', 'sample_url')) { + $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; } } + return $result; } @@ -387,36 +386,34 @@ protected function isRowValidSample(array $rowData) * * @param array $rowData * @return bool - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function isRowValidLink(array $rowData) { - $result = false; - if (isset($rowData[self::COL_DOWNLOADABLE_LINKS]) && - $rowData[self::COL_DOWNLOADABLE_LINKS] != '' && - $this->linksAdditionalAttributes($rowData, 'group_title', self::DEFAULT_GROUP_TITLE) == '' - ) { + $hasLinkData = ( + isset($rowData[self::COL_DOWNLOADABLE_LINKS]) && + $rowData[self::COL_DOWNLOADABLE_LINKS] != '' + ); + + if (!$hasLinkData) { + return false; + } + + $linkData = $this->prepareLinkData($rowData[self::COL_DOWNLOADABLE_LINKS]); + + if ($this->linksAdditionalAttributes($rowData, 'group_title', self::DEFAULT_GROUP_TITLE) == '') { $this->_entityModel->addRowError(self::ERROR_GROUP_TITLE_NOT_FOUND, $this->rowNum); $result = true; } - if (isset($rowData[self::COL_DOWNLOADABLE_LINKS]) && - $rowData[self::COL_DOWNLOADABLE_LINKS] != '' - ) { - $linkData = $this->prepareLinkData($rowData[self::COL_DOWNLOADABLE_LINKS]); - $result = $this->isTitle($linkData); - - foreach ($linkData as $link) { - if (isset($link['link_type']) && - $link['link_type'] === 'url' && - isset($link['link_url']) && - strlen($link['link_url']) && - !$this->domainValidator->isValid($link['link_url']) - ) { - $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); - $result = true; - } + + $result = $result ?? $this->isTitle($linkData); + + foreach ($linkData as $link) { + if ($this->hasDomainNotInWhitelist($link, 'link_type', 'link_url')) { + $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; } } + return $result; } @@ -908,4 +905,21 @@ protected function clear() $this->productIds = []; return $this; } + + /** + * @param array $link + * @param string $linkTypeKey + * @param string $linkUrlKey + * @return bool + */ + private function hasDomainNotInWhitelist(array $link, string $linkTypeKey, string $linkUrlKey): bool + { + return ( + isset($link[$linkTypeKey]) && + $link[$linkTypeKey] === 'url' && + isset($link[$linkUrlKey]) && + strlen($link[$linkUrlKey]) && + !$this->domainValidator->isValid($link[$linkUrlKey]) + ); + } } From fb4ad49f8e22339229241c3a654ab12f9b313b7f Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 11:22:05 -0500 Subject: [PATCH 196/372] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/Downloadable.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index b69b8ddacdfca..0528f2759c4ee 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -907,6 +907,8 @@ protected function clear() } /** + * Does link contain url not in whitelist? + * * @param array $link * @param string $linkTypeKey * @param string $linkUrlKey From 1a548a201b1b3afca20d1700e3b07f4dd0acd0bd Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 12:52:21 -0500 Subject: [PATCH 197/372] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/DownloadableTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php index fe0f0ebf4839c..a3230d61e262c 100644 --- a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php +++ b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php @@ -10,6 +10,7 @@ /** * @magentoAppArea adminhtml + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DownloadableTest extends \PHPUnit\Framework\TestCase { From a5eb4fc57817fb79c1e8409aaa0d8602bada75c4 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 13:14:02 -0500 Subject: [PATCH 198/372] MC-17700: Downloadable Product links --- ...CreateDownloadableProductWithInvalidDomainLinkUrlTest.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index 4eb6b82b65918..f2e4bdfb4890f 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -28,7 +28,10 @@ <actionGroup ref="SaveProductFormNoSuccessCheck" stepKey="saveProduct"/> <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="Link URL's domain is not in list of downloadable_domains in env.php." stepKey="seeLinkUrlInvalidMessage" after="saveProduct" /> <magentoCLI stepKey="addDownloadableDomain2" command="downloadable:domains:add static.magento.com" after="seeLinkUrlInvalidMessage" /> - <checkOption selector="{{AdminProductDownloadableSection.isDownloadableProduct}}" stepKey="checkIsDownloadable" after="addDownloadableDomain2"/> + <actionGroup ref="fillMainProductFormNoWeight" stepKey="fillDownloadableProductFormAgain" after="addDownloadableDomain2"> + <argument name="product" value="DownloadableProduct"/> + </actionGroup> + <checkOption selector="{{AdminProductDownloadableSection.isDownloadableProduct}}" stepKey="checkIsDownloadable" after="fillDownloadableProductFormAgain"/> <checkOption selector="{{AdminProductDownloadableSection.isLinksPurchasedSeparately}}" stepKey="checkIsLinksPurchasedSeparately" after="checkIsDownloadable"/> <actionGroup ref="addDownloadableProductLink" stepKey="addDownloadableProductLinkAgain" after="checkIsLinksPurchasedSeparately"> <argument name="link" value="downloadableLink"/> From b60fead6de598f78c6811a2d30fdede49d3c773c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 24 Jul 2019 15:24:58 -0500 Subject: [PATCH 199/372] Allow admin to opt out of admin analytics tracking - created modal, database table --- .../Magento/AdminAnalytics/Block/Setting.php | 52 +++++++++ .../Adminhtml/Config/DisableAdminUsage.php | 100 +++++++++++++++++ .../Adminhtml/Config/EnableAdminUsage.php | 100 +++++++++++++++++ .../Adminhtml/Config/MarkUserNotified.php | 95 ++++++++++++++++ .../Model/Condition/CanViewNotification.php | 104 +++++++++++++++++ .../Model/ContentProviderInterface.php | 24 ++++ .../Model/ResourceModel/Viewer/Logger.php | 106 ++++++++++++++++++ .../AdminAnalytics/Model/Viewer/Log.php | 54 +++++++++ .../AdminAnalytics/etc/adminhtml/routes.xml | 14 +++ .../Magento/AdminAnalytics/etc/config.xml | 18 --- .../Magento/AdminAnalytics/etc/db_schema.xml | 30 +++++ .../etc/db_schema_whitelist.json | 15 +++ .../view/adminhtml/layout/default.xml | 2 + .../adminhtml/templates/confirm_popup.phtml | 86 ++++++++++++++ 14 files changed, 782 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Block/Setting.php create mode 100644 app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php create mode 100644 app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php create mode 100644 app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php create mode 100644 app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php create mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php create mode 100644 app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php create mode 100644 app/code/Magento/AdminAnalytics/Model/Viewer/Log.php create mode 100644 app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml delete mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/db_schema.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml diff --git a/app/code/Magento/AdminAnalytics/Block/Setting.php b/app/code/Magento/AdminAnalytics/Block/Setting.php new file mode 100644 index 0000000000000..516c854c29337 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Block/Setting.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Block; + +use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\Template\Context; +use Magento\Config\Model\Config\Factory; + +class Setting extends Template +{ + private $configFactory; + /** + * @param Context $context + * @param Factory $configFactory + * @param array $data + */ + public function __construct( + Context $context, + Factory $configFactory, + array $data = [] + ) { + $this->configFactory = $configFactory; + parent::__construct($context, $data); + } + + /** + * Sets the admin usage's configuration setting to yes + */ + public function enableAdminUsage() + { + $configModel = $this->configFactory->create(); + $configModel->setDataByPath('admin/usage/enabled', 1); + $configModel->save(); + } + + /** + * Sets the admin usage's configuration setting to no + */ + public function disableAdminUsage() + { + $configModel = $this->configFactory->create(); + $configModel->setDataByPath('admin/usage/enabled', 0); + $configModel->save(); + } + + public function showModal() { + return false; + } +} diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php new file mode 100644 index 0000000000000..eced53d960e0e --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; + +use Magento\Backend\App\Action; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Controller\ResultFactory; +use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; +use Magento\Framework\App\ProductMetadataInterface; +use Psr\Log\LoggerInterface; +use Magento\Config\Model\Config\Factory; + +/** + * Controller to record that the current admin user has seen the release notification content + */ +class DisableAdminUsage extends Action +{ + + + private $configFactory; + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var NotificationLogger + */ + private $notificationLogger; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * MarkUserNotified constructor. + * + * @param Action\Context $context + * @param ProductMetadataInterface $productMetadata + * @param NotificationLogger $notificationLogger + * @param LoggerInterface $logger + */ + public function __construct( + Action\Context $context, + ProductMetadataInterface $productMetadata, + NotificationLogger $notificationLogger, + Factory $configFactory, + LoggerInterface $logger + ) { + parent::__construct($context); + $this->configFactory = $configFactory; + $this->productMetadata = $productMetadata; + $this->notificationLogger = $notificationLogger; + $this->logger = $logger; + } + public function disableAdminUsage() + { + $configModel = $this->configFactory->create(); + $configModel->setDataByPath('admin/usage/enabled', 0); + $configModel->save(); + } + + public function markUserNotified() + { + $responseContent = [ + 'success' => $this->notificationLogger->log( + $this->_auth->getUser()->getId(), + $this->productMetadata->getVersion(), + 0 + ), + 'error_message' => '' + ]; + + $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); + return $resultJson->setData($responseContent); + } + /** + * Log information about the last shown advertisement + * + * @return \Magento\Framework\Controller\ResultInterface + */ + public function execute() + { + $this->disableAdminUsage(); + $this->markUserNotified(); + } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } +} diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php new file mode 100644 index 0000000000000..ea93212dbc2d0 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; + +use Magento\Backend\App\Action; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Controller\ResultFactory; +use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; +use Magento\Framework\App\ProductMetadataInterface; +use Psr\Log\LoggerInterface; +use Magento\Config\Model\Config\Factory; + +/** + * Controller to record that the current admin user has seen the release notification content + */ +class EnableAdminUsage extends Action +{ + + + private $configFactory; + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var NotificationLogger + */ + private $notificationLogger; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * MarkUserNotified constructor. + * + * @param Action\Context $context + * @param ProductMetadataInterface $productMetadata + * @param NotificationLogger $notificationLogger + * @param LoggerInterface $logger + */ + public function __construct( + Action\Context $context, + ProductMetadataInterface $productMetadata, + NotificationLogger $notificationLogger, + Factory $configFactory, + LoggerInterface $logger + ) { + parent::__construct($context); + $this->configFactory = $configFactory; + $this->productMetadata = $productMetadata; + $this->notificationLogger = $notificationLogger; + $this->logger = $logger; + } + public function enableAdminUsage() + { + $configModel = $this->configFactory->create(); + $configModel->setDataByPath('admin/usage/enabled', 1); + $configModel->save(); + } + + public function markUserNotified() + { + $responseContent = [ + 'success' => $this->notificationLogger->log( + $this->_auth->getUser()->getId(), + $this->productMetadata->getVersion(), + 1 + ), + 'error_message' => '' + ]; + + $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); + return $resultJson->setData($responseContent); + } + /** + * Log information about the last shown advertisement + * + * @return \Magento\Framework\Controller\ResultInterface + */ + public function execute() + { + $this->enableAdminUsage(); + $this->markUserNotified(); + } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } +} diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php new file mode 100644 index 0000000000000..4c252329d07a7 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; + +use Magento\Backend\App\Action; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Controller\ResultFactory; +use Magento\ReleaseNotification\Model\ResourceModel\Viewer\Logger as NotificationLogger; +use Magento\Framework\App\ProductMetadataInterface; +use Psr\Log\LoggerInterface; + +/** + * Controller to record that the current admin user has seen the release notification content + */ +class MarkUserNotified extends Action +{ + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var NotificationLogger + */ + private $notificationLogger; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * MarkUserNotified constructor. + * + * @param Action\Context $context + * @param ProductMetadataInterface $productMetadata + * @param NotificationLogger $notificationLogger + * @param LoggerInterface $logger + */ + public function __construct( + Action\Context $context, + ProductMetadataInterface $productMetadata, + NotificationLogger $notificationLogger, + LoggerInterface $logger + ) { + parent::__construct($context); + $this->productMetadata = $productMetadata; + $this->notificationLogger = $notificationLogger; + $this->logger = $logger; + } + + /** + * Log information about the last shown advertisement + * + * @return \Magento\Framework\Controller\ResultInterface + */ + public function execute() + { + try { + $responseContent = [ + 'success' => $this->notificationLogger->log( + $this->_auth->getUser()->getId(), + $this->productMetadata->getVersion() + ), + 'error_message' => '' + ]; + } catch (LocalizedException $e) { + $this->logger->error($e->getMessage()); + $responseContent = [ + 'success' => false, + 'error_message' => $e->getMessage() + ]; + } catch (\Exception $e) { + $this->logger->error($e->getMessage()); + $responseContent = [ + 'success' => false, + 'error_message' => __('It is impossible to log user action') + ]; + } + $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); + return $resultJson->setData($responseContent); + } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php new file mode 100644 index 0000000000000..31311dc015492 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Model\Condition; + +use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; +use Magento\Backend\Model\Auth\Session; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\View\Layout\Condition\VisibilityConditionInterface; +use Magento\Framework\App\CacheInterface; + +/** + * Dynamic validator for UI release notification, manage UI component visibility. + * Return true if the logged in user has not seen the notification. + */ +class CanViewNotification implements VisibilityConditionInterface +{ + /** + * Unique condition name. + * + * @var string + */ + private static $conditionName = 'can_view_notification'; + + /** + * Prefix for cache + * + * @var string + */ + private static $cachePrefix = 'release-notification-popup-'; + + /** + * @var Logger + */ + private $viewerLogger; + + /** + * @var Session + */ + private $session; + + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var CacheInterface + */ + private $cacheStorage; + + /** + * CanViewNotification constructor. + * + * @param Logger $viewerLogger + * @param Session $session + * @param ProductMetadataInterface $productMetadata + * @param CacheInterface $cacheStorage + */ + public function __construct( + Logger $viewerLogger, + Session $session, + ProductMetadataInterface $productMetadata, + CacheInterface $cacheStorage + ) { + $this->viewerLogger = $viewerLogger; + $this->session = $session; + $this->productMetadata = $productMetadata; + $this->cacheStorage = $cacheStorage; + } + + /** + * Validate if notification popup can be shown and set the notification flag + * + * @inheritdoc + */ + public function isVisible(array $arguments) + { + $userId = $this->session->getUser()->getId(); + $cacheKey = self::$cachePrefix . $userId; + $value = $this->cacheStorage->load($cacheKey); + if ($value === false) { + $value = version_compare( + $this->viewerLogger->get($userId)->getLastViewVersion(), + $this->productMetadata->getVersion(), + '<' + ); + $this->cacheStorage->save(false, $cacheKey); + } + return (bool)$value; + } + + /** + * Get condition name + * + * @return string + */ + public function getName() + { + return self::$conditionName; + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php b/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php new file mode 100644 index 0000000000000..ea67be7019e19 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Model; + +/** + * Requests the release notification content data from a defined service + */ +interface ContentProviderInterface +{ + /** + * Retrieves the release notification content data. + * + * @param string $version + * @param string $edition + * @param string $locale + * + * @return string|false + */ + public function getContent($version, $edition, $locale); +} diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php new file mode 100644 index 0000000000000..ac5d7b1f94db4 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -0,0 +1,106 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\AdminAnalytics\Model\ResourceModel\Viewer; + +use Magento\ReleaseNotification\Model\Viewer\Log; +use Magento\ReleaseNotification\Model\Viewer\LogFactory; +use Magento\Framework\App\ResourceConnection; + +/** + * Release notification viewer log data logger. + * + * Saves and retrieves release notification viewer log data. + */ +class Logger +{ + /** + * Log table name + */ + const LOG_TABLE_NAME = 'admin_usage_viewer_log'; + + /** + * @var Resource + */ + private $resource; + + /** + * @var LogFactory + */ + private $logFactory; + + /** + * Logger constructor. + * @param ResourceConnection $resource + * @param LogFactory $logFactory + */ + public function __construct( + ResourceConnection $resource, + LogFactory $logFactory + ) { + $this->resource = $resource; + $this->logFactory = $logFactory; + } + + /** + * Save (insert new or update existing) log. + * + * @param int $viewerId + * @param string $lastViewVersion + * @param int $isAdminUsageEnabled + * @return bool + */ + public function log(int $viewerId, string $lastViewVersion, int $isAdminUsageEnabled) : bool + { + /** @var \Magento\Framework\DB\Adapter\AdapterInterface $connection */ + $connection = $this->resource->getConnection(ResourceConnection::DEFAULT_CONNECTION); + $connection->insertOnDuplicate( + $this->resource->getTableName(self::LOG_TABLE_NAME), + [ + 'viewer_id' => $viewerId, + 'last_view_version' => $lastViewVersion, + 'is_admin_usage_enabled' => $isAdminUsageEnabled + ], + [ + 'last_view_version', + 'is_admin_usage_enabled' + ] + ); + return true; + } + + /** + * Get log by viewer Id. + * + * @param int $viewerId + * @return Log + */ + public function get(int $viewerId) : Log + { + return $this->logFactory->create(['data' => $this->loadLogData($viewerId)]); + } + + /** + * Load release notification viewer log data by viewer id + * + * @param int $viewerId + * @return array + */ + private function loadLogData(int $viewerId) : array + { + $connection = $this->resource->getConnection(); + $select = $connection->select() + ->from($this->resource->getTableName(self::LOG_TABLE_NAME)) + ->where('viewer_id = ?', $viewerId); + + $data = $connection->fetchRow($select); + if (!$data) { + $data = []; + } + return $data; + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php new file mode 100644 index 0000000000000..28621b36d9b79 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Model\Viewer; + +use Magento\Framework\DataObject; + +/** + * Release notification viewer log resource + */ +class Log extends DataObject +{ + /** + * Get log id + * + * @return int + */ + public function getId() + { + return $this->getData('id'); + } + + /** + * Get viewer id + * + * @return int + */ + public function getViewerId() + { + return $this->getData('viewer_id'); + } + + /** + * Get last viewed product version + * + * @return string + */ + public function getLastViewVersion() + { + return $this->getData('last_view_version'); + } + + /** + * Get admin usage enabled + * + * @return int + */ + public function getIsAdminUsageEnabled() + { + return $this->getData('is_admin_usage_enabled'); + } +} diff --git a/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml b/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml new file mode 100644 index 0000000000000..e1024b12bc42d --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> + <router id="admin"> + <route id="adminAnalytics" frontName="adminAnalytics"> + <module name="Magento_AdminAnalytics" /> + </route> + </router> +</config> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml deleted file mode 100644 index 85b6b6879f083..0000000000000 --- a/app/code/Magento/AdminAnalytics/etc/config.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> - <default> - <admin> - <usage> - <enabled> - 0 - </enabled> - </usage> - </admin> - </default> -</config> diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema.xml b/app/code/Magento/AdminAnalytics/etc/db_schema.xml new file mode 100644 index 0000000000000..d640c6af45286 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/db_schema.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="admin_usage_viewer_log" resource="default" engine="innodb" + comment="Admin Notification Viewer Log Table"> + <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" + comment="Log ID"/> + <column xsi:type="int" name="viewer_id" padding="10" unsigned="true" nullable="false" identity="false" + comment="Viewer admin user ID"/> + <column xsi:type="varchar" name="last_view_version" nullable="false" length="16" + comment="Viewer last view on product version"/> + <column xsi:type="smallint" name="is_admin_usage_enabled" padding="5" unsigned="true" nullable="false" identity="false" + default="0" comment="Flag if admin usage is enabled"/> + <constraint xsi:type="primary" referenceId="PRIMARY"> + <column name="id"/> + </constraint> + <constraint xsi:type="foreign" referenceId="ADMIN_NOTIFICATION_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID" + table="admin_notification_viewer_log" column="viewer_id" referenceTable="admin_user" + referenceColumn="user_id" onDelete="CASCADE"/> + <constraint xsi:type="unique" referenceId="ADMIN_NOTIFICATION_VIEWER_LOG_VIEWER_ID"> + <column name="viewer_id"/> + </constraint> + </table> +</schema> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json new file mode 100644 index 0000000000000..01fb68d4b58f7 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -0,0 +1,15 @@ +{ + "admin_usage_viewer_log": { + "column": { + "id": true, + "viewer_id": true, + "last_view_version": true, + "is_admin_usage_enabled": true + }, + "constraint": { + "PRIMARY": true, + "ADMIN_USAGE_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID": true, + "ADMIN_USAGE_VIEWER_LOG_VIEWER_ID": true + } + } +} \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 8ec8ac3bfaf54..86de70f75f75d 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -13,6 +13,8 @@ <argument name="tracking_url" xsi:type="string">//assets.adobedtm.com/launch-EN30eb7ffa064444f1b8b0368ef38fd3a9.min.js</argument> </arguments> </block> + + <block name="confirm_popup_block" template="Magento_AdminAnalytics::confirm_popup.phtml"/> </referenceContainer> </body> </page> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml new file mode 100644 index 0000000000000..59b972fd5b536 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +?> + +<div class="confirmation-modal-content"> + <p>Help us improve Magento Admin by allowing us to collect usage data.</p> + <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> + <p>You can learn more and opt out at any time by following the instructions in <a href="https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html" target="_blank">merchant documentation</a></p> +</div> + +<script> + require([ + 'jquery', + 'Magento_Ui/js/modal/modal' + ], function ($) { + 'use strict'; + + $('.confirmation-modal-content').modal({ + imports: { + logAction: '${ $.provider }:data.logAction' + }, + title: 'Allow admin usage data collection', + autoOpen: true, + type: 'popup', + clickableOverlay: false, + responsive: true, + keyEventHandlers: { + escapeKey: function(){} + }, + opened: function($Event){ + $('.modal-header button.action-close', $Event.srcElement).hide(); + }, + buttons: [ + { + text: $.mage.__(`Don't Allow`), + class: 'action', + click: function(){ + console.log(`I clicked Don't Allow`); + + + var data = { + 'form_key': window.FORM_KEY + }; + console.log(data.logAction) + $.ajax({ + type: 'POST', + url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', + data: data, + showLoader: true + }).done(function (xhr) { + if (xhr.error) { + self.onError(xhr); + } + }).fail(this.onError); + this.closeModal(); + }, + }, + { + text: $.mage.__('Ok'), + class: 'action', + click: function(){ + console.log("I clicked Ok"); + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax({ + type: 'POST', + url: '/magento2ce/admin_michell/adminAnalytics/config/enableAdminUsage', + data: data, + showLoader: true + }).done(function (xhr) { + if (xhr.error) { + self.onError(xhr); + } + }).fail(this.onError); + + this.closeModal(); + }, + } + ], + }); + }); +</script> From 999f2b3cfd31dab579fcbcb51b614a956f8d08dd Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 16:55:35 -0500 Subject: [PATCH 200/372] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/Downloadable.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index 0528f2759c4ee..fbee9c093b04f 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -372,6 +372,11 @@ protected function isRowValidSample(array $rowData) $result = $result ?? $this->isTitle($sampleData); foreach ($sampleData as $link) { + if ($this->hasDomainNotInWhitelist($link, 'link_type', 'link_url')) { + $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; + } + if ($this->hasDomainNotInWhitelist($link, 'sample_type', 'sample_url')) { $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); $result = true; @@ -412,6 +417,11 @@ protected function isRowValidLink(array $rowData) $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); $result = true; } + + if ($this->hasDomainNotInWhitelist($link, 'sample_type', 'sample_url')) { + $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; + } } return $result; From dad6118554bce879499686848257875f95d349f6 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 25 Jul 2019 14:33:42 -0500 Subject: [PATCH 201/372] MC-17700: Downloadable Product links --- .../Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml index 19477fb804848..0e7396541e757 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml @@ -115,7 +115,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> From a242f2dc1b8c6e84a8ee569e6a3bcf0f74881c05 Mon Sep 17 00:00:00 2001 From: Roman Hanin <rganin@adobe.com> Date: Thu, 25 Jul 2019 15:43:44 -0500 Subject: [PATCH 202/372] MC-17147: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails --- .../Catalog/Model/Product/Compare/ListCompare.php | 2 +- .../Model/Product/Compare/ListCompareTest.php | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php index 12dbaf0c29f4e..0cf36214e4c31 100644 --- a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php +++ b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php @@ -90,7 +90,7 @@ public function addProduct($product) $this->_addVisitorToItem($item); $item->loadByProduct($product); - if (!$item->getId()) { + if (!$item->getId() && $item->getProductId()) { $item->addProductData($product); $item->save(); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php index 3fa02aebe9170..24bba7c77c986 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php @@ -44,6 +44,9 @@ protected function tearDown() $this->_session->setCustomerId(null); } + /** + * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + */ public function testAddProductWithSession() { $this->_session->setCustomerId(1); @@ -51,8 +54,15 @@ public function testAddProductWithSession() $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Catalog\Model\Product::class) ->load(1); - $this->_model->addProduct($product); + /** @var $product2 \Magento\Catalog\Model\Product */ + $product2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\Product::class) + ->load(6); + $this->_model->addProducts([$product->getId(), $product2->getId(), 'none', 99]); $this->assertTrue($this->_model->hasItems(1, $this->_visitor->getId())); + $this->assertTrue($this->_model->hasItems(6, $this->_visitor->getId())); + $this->assertFalse($this->_model->hasItems('none', $this->_visitor->getId())); + $this->assertFalse($this->_model->hasItems(99, $this->_visitor->getId())); } public function testAddProductWithoutSession() From 098f26290834b05abedfdc246c7a42c6fab3aaff Mon Sep 17 00:00:00 2001 From: David Haecker <dhaecker@magento.com> Date: Thu, 25 Jul 2019 15:47:02 -0500 Subject: [PATCH 203/372] MC-17700: Downloadable Product links - Fixing mftf cli cmds --- .../Test/Mftf/Test/SearchEntityResultsTest.xml | 2 +- ...DownloadableProductFromShoppingCartTest.xml | 2 +- .../OnePageCheckoutWithAllProductTypesTest.xml | 2 +- ...ddDownloadableProductToShoppingCartTest.xml | 2 +- ...loadableProductFromMiniShoppingCartTest.xml | 2 +- .../StorefrontClearAllCompareProductsTest.xml | 2 +- ...nAddDefaultVideoDownloadableProductTest.xml | 4 ++-- ...ableProductAndAssignItToCustomStoreTest.xml | 4 ++-- ...ownloadableProductWithCustomOptionsTest.xml | 2 +- ...nloadableProductWithDefaultSetLinksTest.xml | 2 +- ...teDownloadableProductWithGroupPriceTest.xml | 2 +- ...eDownloadableProductWithManageStockTest.xml | 2 +- ...loadableProductWithOutOfStockStatusTest.xml | 2 +- ...DownloadableProductWithSpecialPriceTest.xml | 2 +- ...ateDownloadableProductWithTierPriceText.xml | 6 ------ ...oductWithoutFillingQuantityAndStockTest.xml | 2 +- ...ownloadableProductWithoutTaxClassIdTest.xml | 2 +- .../AdminDeleteDownloadableProductTest.xml | 2 +- ...moveDefaultVideoDownloadableProductTest.xml | 4 ++-- ...nceCatalogSearchDownloadableProductTest.xml | 18 +++++++++--------- ...nloadableProductFromGuestToCustomerTest.xml | 2 +- ...oductsListWidgetDownloadableProductTest.xml | 4 ++-- 22 files changed, 33 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml index f98e715963d2e..9a2103ee75a7a 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml @@ -378,9 +378,9 @@ </createData> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> <deleteData stepKey="deleteCategory" createDataKey="createCategory"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="goToFrontPage"/> <actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="searchStorefront"> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml index 1eee2d510e7bc..e16ef70c23e3d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml @@ -31,9 +31,9 @@ </createData> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete downloadable product --> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteDownloadableProduct"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Add downloadable product to the cart --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml index 56d1b97974bbc..e85a47ab7a91d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml @@ -91,6 +91,7 @@ <magentoCLI command="indexer:reindex" stepKey="reindex"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -110,7 +111,6 @@ <!-- Logout customer --> <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="customerLogoutStorefront"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Add Simple Product to cart --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml index 9d595510811aa..ec9852a6a939d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml @@ -32,9 +32,9 @@ <magentoCLI command="cache:flush" stepKey="flushCache"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteProduct"/> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!-- Open Downloadable Product page --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml index 852e46541c4fa..0fa503e1783b5 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml @@ -31,9 +31,9 @@ <magentoCLI command="cache:flush" stepKey="flushCache"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteProduct"/> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!-- Open Downloadable Product page --> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml index 3069ea89099e2..374a4be581bcf 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml @@ -109,6 +109,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Logout --> <actionGroup ref="logout" stepKey="logoutOfAdmin1"/> @@ -122,7 +123,6 @@ <deleteData createDataKey="createBundleProduct1" stepKey="deleteBundleProduct1"/> <deleteData createDataKey="createGroupedProduct1" stepKey="deleteGroupedProduct1"/> <deleteData createDataKey="createDownloadableProduct1" stepKey="deleteDownloadableProduct1"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer1"> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml index 4bbd815e8db01..d95ddaf12470d 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml @@ -19,10 +19,10 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="enableAdminAccountSharing"/> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="setStoreDefaultConfig"/> </after> <!-- Create a downloadable product --> <!-- Replacing steps in base AdminAddDefaultVideoSimpleProductTest --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml index fc638633fbf3f..4f07334640cf3 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml @@ -20,14 +20,15 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> <!-- Login as admin --> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -41,7 +42,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create store view --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml index f45e5f1a47e43..54a2ff606f384 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create Downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml index 2fcc87b71bbb4..8194e600673cb 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml index afac869d69c3f..06cf31b763f1c 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml index 081230760e1d4..fb6a48254fa8d 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml index a815d838c29d9..5e3fe6836f7e9 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create Downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml index f0cc503f74c4d..fb59d51831bae 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml index f6455766a0907..ca4e560506ad0 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml @@ -19,12 +19,6 @@ <group value="Downloadable"/> <group value="mtf_migrated"/> </annotations> - <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> - </before> - <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> - </after> <remove keyForRemoval="addCustomerGroupPrice"/> <!-- Add tier price to product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml index 6e29fe13d85e6..af9487e3e6a23 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml index 757ac7958f5cd..dd7e3331a0ed2 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml index 83e0c587c078e..07124ea4846be 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml @@ -32,9 +32,9 @@ </createData> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteDownloadableProductFilteredBySkuAndName"> <argument name="product" value="$$createDownloadableProduct$$"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml index bc929cd3a68c7..0d98862d9a5e7 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml @@ -19,10 +19,10 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="enableAdminAccountSharing"/> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="setStoreDefaultConfig"/> </after> <!-- Create a downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml index 0e7396541e757..2a320fa674e74 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml @@ -19,7 +19,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -29,7 +29,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchDownloadableBySkuTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> @@ -43,7 +43,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -53,7 +53,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchDownloadableByDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByDescriptionTest"> @@ -67,7 +67,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -77,7 +77,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchDownloadableByShortDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> @@ -91,7 +91,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -101,7 +101,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchDownloadableByPriceTest" extends="AdvanceCatalogSearchSimpleProductByPriceTest"> @@ -125,7 +125,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> </tests> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml index 25dfe1adcb7c8..b9773415059ec 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml @@ -29,10 +29,10 @@ </createData> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <magentoCLI command="config:set {{DisableGuestCheckoutWithDownloadableItems.path}} {{DisableGuestCheckoutWithDownloadableItems.value}}" stepKey="disableGuestCheckoutWithDownloadableItems" /> <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> <deleteData stepKey="deleteCategory" createDataKey="createCategory"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!--Step 1: Go to Storefront as Guest--> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnStorefrontPage"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml index 9fed2d68c98ca..94fca6f507637 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml @@ -21,10 +21,10 @@ </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="loginAsAdmin"/> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="logout"/> </after> <!-- A Cms page containing the New Products Widget gets created here via extends --> From fa604dc7b68c2cbbf94b8379c9a5140c8606a990 Mon Sep 17 00:00:00 2001 From: Roman Hanin <rganin@adobe.com> Date: Thu, 25 Jul 2019 16:24:04 -0500 Subject: [PATCH 204/372] MC-17147: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails --- .../Model/Product/Compare/ListCompare.php | 35 +++++++++++++++++-- .../Model/Product/Compare/ListCompareTest.php | 31 +++++++++++----- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php index 0cf36214e4c31..bfd36360ee559 100644 --- a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php +++ b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php @@ -5,7 +5,10 @@ */ namespace Magento\Catalog\Model\Product\Compare; +use Magento\Catalog\Model\ProductRepository; use Magento\Catalog\Model\ResourceModel\Product\Compare\Item\Collection; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\NoSuchEntityException; /** * Product Compare List Model @@ -51,6 +54,11 @@ class ListCompare extends \Magento\Framework\DataObject */ protected $_compareItemFactory; + /** + * @var ProductRepository + */ + private $productRepository; + /** * Constructor * @@ -60,6 +68,7 @@ class ListCompare extends \Magento\Framework\DataObject * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Model\Visitor $customerVisitor * @param array $data + * @param ProductRepository|null $productRepository */ public function __construct( \Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory, @@ -67,13 +76,15 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Product\Compare\Item $catalogProductCompareItem, \Magento\Customer\Model\Session $customerSession, \Magento\Customer\Model\Visitor $customerVisitor, - array $data = [] + array $data = [], + ProductRepository $productRepository = null ) { $this->_compareItemFactory = $compareItemFactory; $this->_itemCollectionFactory = $itemCollectionFactory; $this->_catalogProductCompareItem = $catalogProductCompareItem; $this->_customerSession = $customerSession; $this->_customerVisitor = $customerVisitor; + $this->productRepository = $productRepository ?: ObjectManager::getInstance()->create(ProductRepository::class); parent::__construct($data); } @@ -82,6 +93,7 @@ public function __construct( * * @param int|\Magento\Catalog\Model\Product $product * @return $this + * @throws \Exception */ public function addProduct($product) { @@ -90,7 +102,7 @@ public function addProduct($product) $this->_addVisitorToItem($item); $item->loadByProduct($product); - if (!$item->getId() && $item->getProductId()) { + if (!$item->getId() && $this->productExists($product)) { $item->addProductData($product); $item->save(); } @@ -98,6 +110,25 @@ public function addProduct($product) return $this; } + /** + * Check product exists. + * + * @param int|\Magento\Catalog\Model\Product $product + * @return bool + */ + private function productExists($product) + { + if ($product instanceof \Magento\Catalog\Model\Product && $product->getId()) { + return true; + } + try { + $product = $this->productRepository->getById((int)$product); + return !empty($product->getId()); + } catch (NoSuchEntityException $e) { + return false; + } + } + /** * Add products to compare list * diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php index 24bba7c77c986..98b264a8991bc 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php @@ -6,10 +6,6 @@ namespace Magento\Catalog\Model\Product\Compare; -/** - * @magentoDataFixture Magento/Catalog/_files/product_simple.php - * @magentoDataFixture Magento/Customer/_files/customer.php - */ class ListCompareTest extends \PHPUnit\Framework\TestCase { /** @@ -45,7 +41,8 @@ protected function tearDown() } /** - * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Customer/_files/customer.php */ public function testAddProductWithSession() { @@ -58,13 +55,29 @@ public function testAddProductWithSession() $product2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Catalog\Model\Product::class) ->load(6); - $this->_model->addProducts([$product->getId(), $product2->getId(), 'none', 99]); + $products = [$product->getId(), $product2->getId()]; + $this->_model->addProducts($products); + $this->assertTrue($this->_model->hasItems(1, $this->_visitor->getId())); - $this->assertTrue($this->_model->hasItems(6, $this->_visitor->getId())); - $this->assertFalse($this->_model->hasItems('none', $this->_visitor->getId())); - $this->assertFalse($this->_model->hasItems(99, $this->_visitor->getId())); } + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testAddProductWithSessionNeg() + { + $this->_session->setCustomerId(1); + $products = ['none', 99]; + $this->_model->addProducts($products); + + $this->assertFalse($this->_model->hasItems(1, $this->_visitor->getId())); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Customer/_files/customer.php + */ public function testAddProductWithoutSession() { /** @var $product \Magento\Catalog\Model\Product */ From 2976918d75f2b2e78904e05d81073f17831f17ca Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 25 Jul 2019 17:02:37 -0500 Subject: [PATCH 205/372] MC-15298: Allow admin to opt out of admin analytics tracking - UI added --- .../Adminhtml/Config/DisableAdminUsage.php | 1 + .../Adminhtml/Config/EnableAdminUsage.php | 1 - .../Model/Condition/CanViewNotification.php | 28 +- .../Http/HttpContentProvider.php | 108 ++++++++ .../Model/ContentProvider/Http/UrlBuilder.php | 64 +++++ .../Model/ResourceModel/Viewer/Logger.php | 4 +- .../DataProvider/Modifier/Notifications.php | 246 ++++++++++++++++++ .../DataProvider/NotificationDataProvider.php | 214 +++++++++++++++ .../Ui/Renderer/NotificationRenderer.php | 208 +++++++++++++++ .../view/adminhtml/layout/default.xml | 7 +- .../adminhtml/templates/confirm_popup.phtml | 5 - .../ui_component/admin_usage_notification.xml | 122 +++++++++ .../view/adminhtml/web/js/modal/component.js | 90 +++++++ 13 files changed, 1075 insertions(+), 23 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php create mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php create mode 100644 app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php create mode 100644 app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php create mode 100644 app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index eced53d960e0e..b81c60e4b3adb 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -22,6 +22,7 @@ class DisableAdminUsage extends Action private $configFactory; + /** * @var ProductMetadataInterface */ diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index ea93212dbc2d0..d1b879ae927ab 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -20,7 +20,6 @@ class EnableAdminUsage extends Action { - private $configFactory; /** * @var ProductMetadataInterface diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 31311dc015492..b33677ea05f26 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -22,14 +22,14 @@ class CanViewNotification implements VisibilityConditionInterface * * @var string */ - private static $conditionName = 'can_view_notification'; + private static $conditionName = 'can_view_admin_usage_notification'; /** * Prefix for cache * * @var string */ - private static $cachePrefix = 'release-notification-popup-'; + private static $cachePrefix = 'admin-usage-notification-popup-'; /** * @var Logger @@ -78,18 +78,18 @@ public function __construct( */ public function isVisible(array $arguments) { - $userId = $this->session->getUser()->getId(); - $cacheKey = self::$cachePrefix . $userId; - $value = $this->cacheStorage->load($cacheKey); - if ($value === false) { - $value = version_compare( - $this->viewerLogger->get($userId)->getLastViewVersion(), - $this->productMetadata->getVersion(), - '<' - ); - $this->cacheStorage->save(false, $cacheKey); - } - return (bool)$value; +// $userId = $this->session->getUser()->getId(); +// $cacheKey = self::$cachePrefix . $userId; +// $value = $this->cacheStorage->load($cacheKey); +// if ($value === false) { +// $value = version_compare( +// $this->viewerLogger->get($userId)->getLastViewVersion(), +// $this->productMetadata->getVersion(), +// '<' +// ); +// $this->cacheStorage->save(false, $cacheKey); +// } + return true; } /** diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php new file mode 100644 index 0000000000000..930cf89966936 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Model\ContentProvider\Http; + +use Magento\AdminAnalytics\Model\ContentProviderInterface; +use Magento\Setup\Module\I18n\Locale; +use Psr\Log\LoggerInterface; +use Magento\Framework\HTTP\ClientInterface; + +/** + * Requests the release notification content data via an HTTP call to a REST API + */ +class HttpContentProvider implements ContentProviderInterface +{ + /** + * @var ClientInterface + */ + private $httpClient; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var UrlBuilder + */ + private $urlBuilder; + + /** + * HttpContentProvider constructor. + * @param ClientInterface $httpClient + * @param UrlBuilder $urlBuilder + * @param LoggerInterface $logger + */ + public function __construct( + ClientInterface $httpClient, + UrlBuilder $urlBuilder, + LoggerInterface $logger + ) { + $this->httpClient = $httpClient; + $this->urlBuilder = $urlBuilder; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function getContent($version, $edition, $locale) + { + $result = false; + + try { + $result = $this->retrieveContent($version, $edition, $locale); + if (!$result) { + $result = $this->retrieveContent($version, $edition, Locale::DEFAULT_SYSTEM_LOCALE); + if (!$result) { + $result = $this->retrieveContent($version, '', 'default'); + } + } + } catch (\Exception $e) { + $this->logger->warning( + sprintf( + 'Failed to retrieve the release notification content. The response is: %s', + empty($result) ? 'Response body is empty.' : $result + ) + ); + } + + return $result; + } + + /** + * Retrieve content from given url + * + * @param string $version + * @param string $edition + * @param string $locale + * @return bool|string + */ + private function retrieveContent($version, $edition, $locale) + { + $url = $this->urlBuilder->getUrl($version, $edition, $locale); + return empty($url) ? false : $this->getResponse($url); + } + + /** + * Returns the response body from the HTTP client + * + * @param $url + * @return string + */ + private function getResponse($url) + { + $this->httpClient->get($url); + $responseBody = $this->httpClient->getBody(); + + if ($this->httpClient->getStatus() === 200 && !empty($responseBody)) { + return $responseBody; + } + + return false; + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php new file mode 100644 index 0000000000000..3898fb82f4ac5 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Model\ContentProvider\Http; + +use Magento\Framework\App\Config\ScopeConfigInterface; + +/** + * Builder to build Url to retrieve the notification content. + */ +class UrlBuilder +{ + /** + * Path to the configuration value which contains an URL that provides the release notification data. + * + * @var string + */ + private static $notificationContentUrlConfigPath = 'system/release_notification/content_url'; + + /** + * Path to the configuration value indicates if use https in notification content request. + * + * @var string + */ + private static $useHttpsFlagConfigPath = 'system/release_notification/use_https'; + + /** + * @var ScopeConfigInterface + */ + private $config; + + /** + * @param ScopeConfigInterface $config + */ + public function __construct(ScopeConfigInterface $config) + { + $this->config = $config; + } + + /** + * Builds the URL to request the release notification content data based on passed parameters. + * + * @param string $version + * @param string $edition + * @param string $locale + * @return string + */ + public function getUrl($version, $edition, $locale) + { + $scheme = $this->config->isSetFlag(self::$useHttpsFlagConfigPath) ? 'https://' : 'http://'; + $baseUrl = $this->config->getValue(self::$notificationContentUrlConfigPath); + if (empty($baseUrl)) { + return ''; + } else { + $url = $scheme . $baseUrl; + $url .= empty($version) ? '' : '/' . $version; + $url .= empty($edition) ? '' : '/' . $edition; + $url .= empty($locale) ? '' : '/' . $locale; + return $url . '.json'; + } + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index ac5d7b1f94db4..5b67d4dfffec1 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -7,8 +7,8 @@ namespace Magento\AdminAnalytics\Model\ResourceModel\Viewer; -use Magento\ReleaseNotification\Model\Viewer\Log; -use Magento\ReleaseNotification\Model\Viewer\LogFactory; +use Magento\AdminAnalytics\Model\Viewer\Log; +use Magento\AdminAnalytics\Model\Viewer\LogFactory; use Magento\Framework\App\ResourceConnection; /** diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php new file mode 100644 index 0000000000000..f93cb1e00f019 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php @@ -0,0 +1,246 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Ui\DataProvider\Modifier; + +use Magento\AdminAnalytics\Model\ContentProviderInterface; +use Magento\AdminAnalytics\Ui\Renderer\NotificationRenderer; +use Magento\Ui\DataProvider\Modifier\ModifierInterface; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\App\CacheInterface; +use Magento\Ui\Component; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Backend\Model\Auth\Session; +use Psr\Log\LoggerInterface; + +/** + * Modifies the metadata returning to the Release Notification data provider + */ +class Notifications implements ModifierInterface +{ + /** + * @var ContentProviderInterface + */ + private $contentProvider; + + /** + * @var NotificationRenderer + */ + private $renderer; + + /** + * Prefix for cache + * + * @var string + */ + private static $cachePrefix = 'release-notification-content-'; + + /** + * @var CacheInterface + */ + private $cacheStorage; + + /** + * @var SerializerInterface + */ + private $serializer; + + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var Session + */ + private $session; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param ContentProviderInterface $contentProvider + * @param NotificationRenderer $render + * @param CacheInterface $cacheStorage + * @param SerializerInterface $serializer + * @param ProductMetadataInterface $productMetadata + * @param Session $session + * @param LoggerInterface $logger + */ + public function __construct( + ContentProviderInterface $contentProvider, + NotificationRenderer $render, + CacheInterface $cacheStorage, + SerializerInterface $serializer, + ProductMetadataInterface $productMetadata, + Session $session, + LoggerInterface $logger + ) { + $this->contentProvider = $contentProvider; + $this->renderer = $render; + $this->cacheStorage = $cacheStorage; + $this->serializer = $serializer; + $this->productMetadata = $productMetadata; + $this->session = $session; + $this->logger = $logger; + } + + /** + * {@inheritdoc} + */ + public function modifyData(array $data) + { + return $data; + } + + /** + * {@inheritdoc} + */ + public function modifyMeta(array $meta) + { + $modalContent = $this->getNotificationContent(); + + if ($modalContent) { + $pages = $modalContent['pages']; + $pageCount = count($pages); + $counter = 1; + + foreach ($pages as $page) { + $meta = $this->buildNotificationMeta($meta, $page, $counter++ == $pageCount); + } + } else { + $meta = $this->hideNotification($meta); + } + + return $meta; + } + + /** + * Builds the notification modal by modifying $meta for the ui component + * + * @param array $meta + * @param array $page + * @param bool $isLastPage + * @return array + */ + private function buildNotificationMeta(array $meta, array $page, $isLastPage) + { + $meta['notification_modal_' . $page['name']]['arguments']['data']['config'] = [ + 'isTemplate' => false, + 'componentType' => Component\Modal::NAME + ]; + + $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children'] + ['notification_text']['arguments']['data']['config'] = [ + 'text' => $this->renderer->getNotificationContent($page) + ]; + + if ($isLastPage) { + $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [ + 'title' => $this->renderer->getNotificationTitle($page), + 'buttons' => [ + [ + 'text' => 'Done', + 'actions' => [ + [ + 'targetName' => '${ $.name }', + 'actionName' => 'closeReleaseNotes' + ] + ], + 'class' => 'release-notification-button-next' + ] + ], + ]; + + $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children'] + ['notification_buttons']['children']['notification_button_next']['arguments']['data']['config'] = [ + 'buttonClasses' => 'hide-release-notification' + ]; + } else { + $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [ + 'title' => $this->renderer->getNotificationTitle($page) + ]; + } + + return $meta; + } + + /** + * Sets the modal to not display if no content is available. + * + * @param array $meta + * @return array + */ + private function hideNotification(array $meta) + { + $meta['notification_modal_1']['arguments']['data']['config']['options'] = [ + 'autoOpen' => false + ]; + + return $meta; + } + + /** + * Returns the notification modal content data + * + * @returns array|false + */ + private function getNotificationContent() + { + $version = strtolower($this->getTargetVersion()); + $edition = strtolower($this->productMetadata->getEdition()); + $locale = strtolower($this->session->getUser()->getInterfaceLocale()); + + $cacheKey = self::$cachePrefix . $version . "-" . $edition . "-" . $locale; + $modalContent = $this->cacheStorage->load($cacheKey); + if ($modalContent === false) { + $modalContent = $this->contentProvider->getContent($version, $edition, $locale); + $this->cacheStorage->save($modalContent, $cacheKey); + } + + return !$modalContent ? $modalContent : $this->unserializeContent($modalContent); + } + + /** + * Unserializes the notification modal content to be used for rendering + * + * @param string $modalContent + * @return array|false + */ + private function unserializeContent($modalContent) + { + $result = false; + + try { + $result = $this->serializer->unserialize($modalContent); + } catch (\InvalidArgumentException $e) { + $this->logger->warning( + sprintf( + 'Failed to unserialize the release notification content. The error is: %s', + $e->getMessage() + ) + ); + } + + return $result; + } + + /** + * Returns the current Magento version used to retrieve the release notification content. + * Version information after the dash (-) character is removed (ex. -dev or -rc). + * + * @return string + */ + private function getTargetVersion() + { + $metadataVersion = $this->productMetadata->getVersion(); + $version = strstr($metadataVersion, '-', true); + + return !$version ? $metadataVersion : $version; + } +} diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php new file mode 100644 index 0000000000000..104d902d3dc94 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php @@ -0,0 +1,214 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Ui\DataProvider; + +use Magento\Framework\Api\Search\SearchCriteriaInterface; +use Magento\Framework\Api\Search\SearchResultInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\Ui\DataProvider\Modifier\ModifierInterface; +use Magento\Ui\DataProvider\Modifier\PoolInterface; + +/** + * Data Provider for the Release Notifications UI component. + */ +class NotificationDataProvider implements DataProviderInterface +{ + /** + * @var PoolInterface + */ + private $pool; + + /** + * Search result object. + * + * @var SearchResultInterface + */ + private $searchResult; + + /** + * Search criteria object. + * + * @var SearchCriteriaInterface + */ + private $searchCriteria; + + /** + * Own name of this provider. + * + * @var string + */ + private $name; + + /** + * Provider configuration data. + * + * @var array + */ + private $data; + + /** + * Provider configuration meta. + * + * @var array + */ + private $meta; + + /** + * @param string $name + * @param SearchResultInterface $searchResult + * @param SearchCriteriaInterface $searchCriteria + * @param PoolInterface $pool + * @param array $meta + * @param array $data + */ + public function __construct( + $name, + SearchResultInterface $searchResult, + SearchCriteriaInterface $searchCriteria, + PoolInterface $pool, + array $meta = [], + array $data = [] + ) { + $this->name = $name; + $this->searchResult = $searchResult; + $this->searchCriteria = $searchCriteria; + $this->pool = $pool; + $this->meta = $meta; + $this->data = $data; + } + + /** + * @inheritdoc + */ + public function getData() + { + /** @var ModifierInterface $modifier */ + foreach ($this->pool->getModifiersInstances() as $modifier) { + $this->data = $modifier->modifyData($this->data); + } + + return $this->data; + } + + /** + * @inheritdoc + */ + public function getMeta() + { + /** @var ModifierInterface $modifier */ + foreach ($this->pool->getModifiersInstances() as $modifier) { + $this->meta = $modifier->modifyMeta($this->meta); + } + return $this->meta; + } + + /** + * @inheritdoc + */ + public function getName() + { + return $this->name; + } + + /** + * @inheritdoc + */ + public function getConfigData() + { + return $this->data['config'] ?? []; + } + + /** + * @inheritdoc + */ + public function setConfigData($config) + { + $this->data['config'] = $config; + + return true; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getFieldMetaInfo($fieldSetName, $fieldName) + { + return []; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getFieldSetMetaInfo($fieldSetName) + { + return []; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getFieldsMetaInfo($fieldSetName) + { + return []; + } + + /** + * @inheritdoc + */ + public function getPrimaryFieldName() + { + return 'release_notification'; + } + + /** + * @inheritdoc + */ + public function getRequestFieldName() + { + return 'release_notification'; + } + + /** + * @inheritdoc + */ + public function addFilter(\Magento\Framework\Api\Filter $filter) + { + } + + /** + * @inheritdoc + */ + public function addOrder($field, $direction) + { + } + + /** + * @inheritdoc + */ + public function setLimit($offset, $size) + { + } + + /** + * @inheritdoc + */ + public function getSearchCriteria() + { + return $this->searchCriteria; + } + + /** + * @inheritdoc + */ + public function getSearchResult() + { + return $this->searchResult; + } +} diff --git a/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php b/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php new file mode 100644 index 0000000000000..b66e213670f76 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php @@ -0,0 +1,208 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Ui\Renderer; + +use Magento\Framework\Escaper; + +/** + * Builds the HTML for the release notification modals + */ +class NotificationRenderer +{ + /** + * @var Escaper + */ + private $escaper; + + /** + * @param Escaper $escaper + */ + public function __construct( + Escaper $escaper + ) { + $this->escaper = $escaper; + } + + /** + * Returns the HTML for notification's title to the ui component + * + * @param array $page + * @return string + */ + public function getNotificationTitle(array $page) + { + $title = $this->escaper->escapeHtml($page['mainContent']['title']); + $imageUrl = $this->escaper->escapeUrl($page['mainContent']['imageUrl']); + $content = ""; + + if (!empty($imageUrl)) { + $content .= "<div class='release-notification-title-with-image' style='background-image: url(\"" . $imageUrl + . "\")'>"; + $content .= $title; + $content .= "</div>"; + } else { + $content = $title; + } + + return $content; + } + + /** + * Returns the HTML for the content in the notification ui component + * + * @param array $page + * @return string + */ + public function getNotificationContent(array $page) + { + $content = $this->buildMainContent($page['mainContent']); + $content .= $this->buildSubHeadings($page['subHeading']); + $content .= $this->buildFooter($page['footer']); + + return $content; + } + + /** + * Builds the HTML for the main content in the notification ui component + * + * @param array $mainContent + * @return string + */ + private function buildMainContent(array $mainContent) + { + $content = $this->buildContentTextAreas($mainContent['content']); + $content .= $this->buildLists($mainContent['lists']); + + return $this->formatContentWithLinks($content); + } + + /** + * Builds the HTML for the main text areas in the notification ui component + * + * @param array $contentAreas + * @return string + */ + private function buildContentTextAreas(array $contentAreas) + { + $content = ""; + $lastContentArea = end($contentAreas); + + foreach ($contentAreas as $contentArea) { + $content .= "<p>"; + $content .= $this->escaper->escapeHtml($contentArea['text']); + $content .= "</p>"; + if ($contentArea != $lastContentArea) { + $content .= "<br />"; + } + } + + return $content; + } + + /** + * Builds the HTML for the bullet list content in the notification ui component + * + * @param array $lists + * @return string + */ + private function buildLists(array $lists) + { + $content = "<ul>"; + + foreach ($lists as $listItem) { + $content .= "<li><span>"; + $content .= $this->escaper->escapeHtml($listItem['text']); + $content .= "</span></li>"; + } + + $content .= "</ul>"; + + return $content; + } + + /** + * Builds the HTML for the highlighted sub heads for the overview page in the notification ui component + * + * @param array $subHeadings + * @return string + */ + private function buildSubHeadings(array $subHeadings) + { + $content = ""; + + foreach ($subHeadings as $subHeading) { + if (!empty($subHeading['imageUrl'])) { + $content .= "<div class='highlight-item' style='background-image: url(\"" + . $this->escaper->escapeUrl($subHeading['imageUrl']) . "\")'>"; + } else { + $content .= "<div class='highlight-item-no-image'>"; + } + + $content .= "<h3>"; + $content .= $this->escaper->escapeHtml($subHeading['title']); + $content .= "</h3>"; + $content .= "<p>"; + $content .= $this->formatContentWithLinks($subHeading['content']); + $content .= "</p>"; + $content .= "</div>"; + } + + return $content; + } + + /** + * Builds the HTML for the footer content in the notification ui component + * + * @param array $footer + * @return string + */ + private function buildFooter(array $footer) + { + $content = "<p>"; + $content .= $this->escaper->escapeHtml($footer['content']); + $content .= "</p>"; + + return $this->formatContentWithLinks($content); + } + + /** + * Searches a given string for a URL, formats it to an HTML anchor tag, and returns the original string in the + * correct HTML format. + * + * @param string $content + * @return string + */ + private function formatContentWithLinks($content) + { + $urlRegex = '#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#'; + $urlTextRegex = '/\[(.*?)\]/'; + + preg_match_all($urlRegex, $content, $urlMatches); + preg_match_all($urlTextRegex, $content, $urlTextMatches); + + foreach ($urlMatches[0] as $key => $urlMatch) { + if (!empty($urlTextMatches[0])) { + $linkMatch = $urlMatch . " " . $urlTextMatches[0][$key]; + $content = str_replace( + $linkMatch, + "<a target='_blank' href='{$this->escaper->escapeUrl($urlMatch)}'> + {$this->escaper->escapeHtml($urlTextMatches[1][$key])}</a>", + $content + ); + } else { + $content = str_replace( + $urlMatch, + "<a target='_blank' href='{$this->escaper->escapeUrl($urlMatch)}'> + {$this->escaper->escapeUrl($urlMatch)}</a>", + $content + ); + } + } + + return $content; + } +} diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 86de70f75f75d..5339fbc894a41 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -14,8 +14,13 @@ </arguments> </block> - <block name="confirm_popup_block" template="Magento_AdminAnalytics::confirm_popup.phtml"/> + </referenceContainer> + <referenceContainer name="content"> + <uiComponent name="admin_usage_notification"> + <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> + </uiComponent> + </referenceContainer> </body> </page> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml index 59b972fd5b536..ddd9b7acf03dd 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml @@ -38,13 +38,9 @@ text: $.mage.__(`Don't Allow`), class: 'action', click: function(){ - console.log(`I clicked Don't Allow`); - - var data = { 'form_key': window.FORM_KEY }; - console.log(data.logAction) $.ajax({ type: 'POST', url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', @@ -62,7 +58,6 @@ text: $.mage.__('Ok'), class: 'action', click: function(){ - console.log("I clicked Ok"); var data = { 'form_key': window.FORM_KEY }; diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml new file mode 100644 index 0000000000000..6f9cca8696019 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="provider" xsi:type="string">admin_usage_notification.admin_usage_notification_data_source</item> + </item> + <item name="label" xsi:type="string" translate="true">Release Notification</item> + <item name="template" xsi:type="string">templates/form/collapsible</item> + </argument> + <settings> + <namespace>admin_usage_notification</namespace> + <dataScope>data</dataScope> + <deps> + <dep>admin_usage_notification.admin_usage_notification_data_source</dep> + </deps> + </settings> + <dataSource name="admin_usage_notification_data_source"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item> + </item> + </argument> + <dataProvider class="Magento\AdminAnalytics\Ui\DataProvider\NotificationDataProvider" name="admin_usage_notification_data_source"> + <settings> + <requestFieldName>id</requestFieldName> + <primaryFieldName>entity_id</primaryFieldName> + </settings> + </dataProvider> + </dataSource> + <modal name="notification_modal_1" component="Magento_AdminAnalytics/js/modal/component"> + <settings> + <state>true</state> + <options> + <option name="modalClass" xsi:type="string">admin-usage-notification</option> + <option name="title" xsi:type="string" translate="true">Allow admin usage data collection</option> + <option name="autoOpen" xsi:type="boolean">true</option> + <option name="type" xsi:type="string">popup</option> + <option name="clickableOverlay" xsi:type="boolean">false</option> + <option name="responsive" xsi:type="boolean">true</option> + <option name="innerScroll" xsi:type="boolean">false</option> + + </options> + </settings> + <fieldset name="notification_fieldset"> + <settings> + <label/> + </settings> + <container name="notification_text" template="ui/form/components/complex"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string"/> + <item name="additionalClasses" xsi:type="string">release-notification-text</item> + <item name="text" xsi:type="string" translate="true"><![CDATA[ + <p>Help us improve Magento Admin by allowing us to collect usage data.</p> + <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> + <p>You can learn more and opt out at any time by following the instructions in <a href="https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html" target="_blank">merchant documentation</a></p> +]]></item> + </item> + </argument> + </container> + <container name="notification_buttons"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="onCancel" xsi:type="string">actionCancel</item> + <item name="options" xsi:type="array"> + <item name="buttons" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="text" xsi:type="string">Don't Allow</item> + <item name="class" xsi:type="string">action-secondary</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="string">actionCancel</item> + </item> + </item> + <item name="2" xsi:type="array"> + <item name="text" xsi:type="string">Allow</item> + <item name="class" xsi:type="string">action-primary</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="string">actionDone</item> + </item> + </item> + </item> + </item> + </item> + </argument> + + <button name="dont_allow_modal_button"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="title" xsi:type="string">Don't Allow</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="targetName" xsi:type="string">${ $.parentName}.notification_modal_1</item> + <item name="actionName" xsi:type="string">dontAllow</item> + </item> + </item> + </item> + </argument> + </button> + <button name="allow_modal_button"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="title" xsi:type="string">Allow</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="targetName" xsi:type="string">${ $.parentName}.notification_modal_1</item> + <item name="actionName" xsi:type="string">actionDone</item> + </item> + </item> + </item> + </argument> + </button> + </container> + </fieldset> + </modal> + +</form> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js new file mode 100644 index 0000000000000..db203f6fe8007 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -0,0 +1,90 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define( + [ + 'jquery', + 'Magento_Ui/js/modal/modal-component' + ], + function ($, Modal) { + 'use strict'; + + console.log('Hello two'); + + return Modal.extend( + { + defaults: { + imports: { + logAction: '${ $.provider }:data.logAction' + } + }, + keyEventHandlers: { + escapeKey: function (){} + }, + opened: function ($Event) { + $('.modal-header button.action-close', $Event.srcElement).hide(); + }, + + dontAllow: function(){ + console.log("Clicked") + }, + actionDone: function() { + console.log("Clicked") + }, + buttons: [ + { + text: $.mage.__(`Don't Allow`), + class: 'action', + click: function () { + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax( + { + type: 'POST', + url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', + data: data, + showLoader: true + } + ).done( + function (xhr) { + if (xhr.error) { + self.onError(xhr); + } + } + ).fail(this.onError); + this.closeModal(); + }, + }, + { + text: $.mage.__('Ok'), + class: 'action', + click: function () { + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax( + { + type: 'POST', + url: '/magento2ce/admin_michell/adminAnalytics/config/enableAdminUsage', + data: data, + showLoader: true + } + ).done( + function (xhr) { + if (xhr.error) { + self.onError(xhr); + } + } + ).fail(this.onError); + + this.closeModal(); + }, + } + ], + } + ); + } +); From d63c892696be93bd9ab024518a66900c6186fe15 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 26 Jul 2019 09:47:01 -0500 Subject: [PATCH 206/372] MC-15978: Catalog Product Attribute Set Name --- .../DataProvider/Product/Form/Modifier/AttributeSet.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php index 0733d21bf47d7..3420965597c5e 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php @@ -78,7 +78,13 @@ public function getOptions() \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::SORT_ORDER_ASC ); - return $collection->getData(); + $collectionData = $collection->getData(); + + array_walk($collectionData, function (&$attribute) { + $attribute['__disableTmpl'] = true; + }); + + return $collectionData; } /** From 90fe08e2d0710f5e48b5c9b2b8f6c63d7e917396 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 26 Jul 2019 11:06:19 -0500 Subject: [PATCH 207/372] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/DownloadableTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php index a3230d61e262c..15dd157a3154b 100644 --- a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php +++ b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php @@ -68,7 +68,7 @@ protected function setUp() $this->productMetadata = $metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); $this->domainManager = $this->objectManager->get(DomainManagerInterface::class); - $this->domainManager->addDomains(['www.google.com', 'www.yahoo.com']); + $this->domainManager->addDomains(['www.bing.com', 'www.google.com', 'www.yahoo.com']); } /** @@ -76,7 +76,7 @@ protected function setUp() */ protected function tearDown() { - $this->domainManager->removeDomains(['www.google.com', 'www.yahoo.com']); + $this->domainManager->removeDomains(['www.bing.com', 'www.google.com', 'www.yahoo.com']); } /** From c4ee9853403f287be94b26ffea1a2bb75fb8a671 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 26 Jul 2019 11:09:25 -0500 Subject: [PATCH 208/372] MC-17700: Downloadable Product links --- .../testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php index 59ad82334a958..3b7273e088105 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php @@ -736,7 +736,7 @@ public function testValidateUploadFileExceptionDataProvider() ], 'image_empty' => [ 'fileName' => 'empty.png', - 'expectedErrorMsg' => 'Disallowed file type.', + 'expectedErrorMsg' => 'Wrong file size.', 'useFixture' => true ], 'notanimage' => [ From 1c8cb1e0d3f4fa00749e98a767a3467f5d0a9498 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Fri, 26 Jul 2019 12:55:09 -0500 Subject: [PATCH 209/372] MC-15298: Allow admin to opt out of admin analytics tracking - Added dialog box, opt out feature --- .../Model/Condition/CanViewNotification.php | 26 +++-- .../ui_component/admin_usage_notification.xml | 85 +++++--------- .../view/adminhtml/web/js/modal/component.js | 104 ++++++++---------- 3 files changed, 86 insertions(+), 129 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index b33677ea05f26..f6dd6ecb9ff3c 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -78,18 +78,20 @@ public function __construct( */ public function isVisible(array $arguments) { -// $userId = $this->session->getUser()->getId(); -// $cacheKey = self::$cachePrefix . $userId; -// $value = $this->cacheStorage->load($cacheKey); -// if ($value === false) { -// $value = version_compare( -// $this->viewerLogger->get($userId)->getLastViewVersion(), -// $this->productMetadata->getVersion(), -// '<' -// ); -// $this->cacheStorage->save(false, $cacheKey); -// } - return true; + $userId = $this->session->getUser()->getId(); + $cacheKey = self::$cachePrefix . $userId; + $value = $this->cacheStorage->load($cacheKey); + if ($value === false) { + $value = version_compare( + $this->viewerLogger->get($userId)->getLastViewVersion(), + $this->productMetadata->getVersion(), + '<' + ); + $this->cacheStorage->save(false, $cacheKey); + } + + return (bool)$value; + } /** diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index 6f9cca8696019..f9d11d2a6a7fe 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -10,7 +10,7 @@ <item name="js_config" xsi:type="array"> <item name="provider" xsi:type="string">admin_usage_notification.admin_usage_notification_data_source</item> </item> - <item name="label" xsi:type="string" translate="true">Release Notification</item> + <item name="label" xsi:type="string" translate="true">Admin Usage Notification</item> <item name="template" xsi:type="string">templates/form/collapsible</item> </argument> <settings> @@ -21,6 +21,17 @@ </deps> </settings> <dataSource name="admin_usage_notification_data_source"> + <argument name="dataProvider" xsi:type="configurableObject"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="data" xsi:type="array"> + <item name="enableLogAction" xsi:type="url" path="adminAnalytics/config/enableAdminUsage"/> + <item name="disableLogAction" xsi:type="url" path="adminAnalytics/config/disableAdminUsage"/> + + </item> + </item> + </argument> + </argument> <argument name="data" xsi:type="array"> <item name="js_config" xsi:type="array"> <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item> @@ -39,12 +50,27 @@ <options> <option name="modalClass" xsi:type="string">admin-usage-notification</option> <option name="title" xsi:type="string" translate="true">Allow admin usage data collection</option> - <option name="autoOpen" xsi:type="boolean">true</option> + <option name="autoOpen" xsi:type="array">true</option> <option name="type" xsi:type="string">popup</option> <option name="clickableOverlay" xsi:type="boolean">false</option> <option name="responsive" xsi:type="boolean">true</option> <option name="innerScroll" xsi:type="boolean">false</option> - + <option name="buttons" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="text" xsi:type="string" translate="true">Don't Allow</item> + <item name="class" xsi:type="string">action-secondary</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="string">disableAdminUsage</item> + </item> + </item> + <item name="1" xsi:type="array"> + <item name="text" xsi:type="string" translate="true">Allow</item> + <item name="class" xsi:type="string">action-primary</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="string">enableAdminUsage</item> + </item> + </item> + </option> </options> </settings> <fieldset name="notification_fieldset"> @@ -64,59 +90,6 @@ </item> </argument> </container> - <container name="notification_buttons"> - <argument name="data" xsi:type="array"> - <item name="config" xsi:type="array"> - <item name="onCancel" xsi:type="string">actionCancel</item> - <item name="options" xsi:type="array"> - <item name="buttons" xsi:type="array"> - <item name="0" xsi:type="array"> - <item name="text" xsi:type="string">Don't Allow</item> - <item name="class" xsi:type="string">action-secondary</item> - <item name="actions" xsi:type="array"> - <item name="0" xsi:type="string">actionCancel</item> - </item> - </item> - <item name="2" xsi:type="array"> - <item name="text" xsi:type="string">Allow</item> - <item name="class" xsi:type="string">action-primary</item> - <item name="actions" xsi:type="array"> - <item name="0" xsi:type="string">actionDone</item> - </item> - </item> - </item> - </item> - </item> - </argument> - - <button name="dont_allow_modal_button"> - <argument name="data" xsi:type="array"> - <item name="config" xsi:type="array"> - <item name="title" xsi:type="string">Don't Allow</item> - <item name="actions" xsi:type="array"> - <item name="0" xsi:type="array"> - <item name="targetName" xsi:type="string">${ $.parentName}.notification_modal_1</item> - <item name="actionName" xsi:type="string">dontAllow</item> - </item> - </item> - </item> - </argument> - </button> - <button name="allow_modal_button"> - <argument name="data" xsi:type="array"> - <item name="config" xsi:type="array"> - <item name="title" xsi:type="string">Allow</item> - <item name="actions" xsi:type="array"> - <item name="0" xsi:type="array"> - <item name="targetName" xsi:type="string">${ $.parentName}.notification_modal_1</item> - <item name="actionName" xsi:type="string">actionDone</item> - </item> - </item> - </item> - </argument> - </button> - </container> </fieldset> </modal> - </form> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index db203f6fe8007..6c449e45f7aad 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -11,80 +11,62 @@ define( function ($, Modal) { 'use strict'; - console.log('Hello two'); - return Modal.extend( { defaults: { imports: { - logAction: '${ $.provider }:data.logAction' + enableLogAction: '${ $.provider }:data.enableLogAction', + disableLogAction: '${ $.provider }:data.disableLogAction' } }, keyEventHandlers: { - escapeKey: function (){} - }, - opened: function ($Event) { - $('.modal-header button.action-close', $Event.srcElement).hide(); - }, - - dontAllow: function(){ - console.log("Clicked") + escapeKey: function () { + } }, - actionDone: function() { - console.log("Clicked") + opened: function () { + $('.modal-header button.action-close').hide(); }, - buttons: [ - { - text: $.mage.__(`Don't Allow`), - class: 'action', - click: function () { - var data = { - 'form_key': window.FORM_KEY - }; - $.ajax( - { - type: 'POST', - url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', - data: data, - showLoader: true - } - ).done( - function (xhr) { - if (xhr.error) { - self.onError(xhr); - } + enableAdminUsage: function () { + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax( + { + type: 'POST', + url: this.enableLogAction, + data: data, + showLoader: true + } + ).done( + function (xhr) { + if (xhr.error) { + self.onError(xhr); } - ).fail(this.onError); - this.closeModal(); - }, + } + ).fail(this.onError); + this.closeModal(); }, - { - text: $.mage.__('Ok'), - class: 'action', - click: function () { - var data = { - 'form_key': window.FORM_KEY - }; - $.ajax( - { - type: 'POST', - url: '/magento2ce/admin_michell/adminAnalytics/config/enableAdminUsage', - data: data, - showLoader: true + disableAdminUsage: function () { + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax( + { + type: 'POST', + url: this.disableLogAction, + data: data, + showLoader: true + } + ).done( + function (xhr) { + if (xhr.error) { + self.onError(xhr); } - ).done( - function (xhr) { - if (xhr.error) { - self.onError(xhr); - } - } - ).fail(this.onError); - - this.closeModal(); - }, + } + ).fail(this.onError); + this.closeModal(); } - ], } - ); + ) } ); From d4cb1c8f71dadb784d495359c8bc524b7037ed96 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Fri, 26 Jul 2019 15:57:44 -0500 Subject: [PATCH 210/372] MC-15298: Allow admin to opt out of admin analytics tracking - cleaned up code --- .../Magento/AdminAnalytics/Block/Setting.php | 52 ---- .../Adminhtml/Config/DisableAdminUsage.php | 25 +- .../Adminhtml/Config/EnableAdminUsage.php | 23 +- .../Adminhtml/Config/MarkUserNotified.php | 95 ------- .../Model/Condition/CanViewNotification.php | 32 +-- .../Model/ResourceModel/Viewer/Logger.php | 31 +-- .../AdminAnalytics/Model/Viewer/Log.php | 24 +- .../DataProvider/Modifier/Notifications.php | 246 ------------------ .../DataProvider/NotificationDataProvider.php | 6 +- .../Ui/Renderer/NotificationRenderer.php | 208 --------------- .../Magento/AdminAnalytics/etc/db_schema.xml | 17 +- .../etc/db_schema_whitelist.json | 7 +- 12 files changed, 70 insertions(+), 696 deletions(-) delete mode 100644 app/code/Magento/AdminAnalytics/Block/Setting.php delete mode 100644 app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php delete mode 100644 app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php delete mode 100644 app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php diff --git a/app/code/Magento/AdminAnalytics/Block/Setting.php b/app/code/Magento/AdminAnalytics/Block/Setting.php deleted file mode 100644 index 516c854c29337..0000000000000 --- a/app/code/Magento/AdminAnalytics/Block/Setting.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\AdminAnalytics\Block; - -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context; -use Magento\Config\Model\Config\Factory; - -class Setting extends Template -{ - private $configFactory; - /** - * @param Context $context - * @param Factory $configFactory - * @param array $data - */ - public function __construct( - Context $context, - Factory $configFactory, - array $data = [] - ) { - $this->configFactory = $configFactory; - parent::__construct($context, $data); - } - - /** - * Sets the admin usage's configuration setting to yes - */ - public function enableAdminUsage() - { - $configModel = $this->configFactory->create(); - $configModel->setDataByPath('admin/usage/enabled', 1); - $configModel->save(); - } - - /** - * Sets the admin usage's configuration setting to no - */ - public function disableAdminUsage() - { - $configModel = $this->configFactory->create(); - $configModel->setDataByPath('admin/usage/enabled', 0); - $configModel->save(); - } - - public function showModal() { - return false; - } -} diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index b81c60e4b3adb..eb31e54e8041b 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -7,20 +7,18 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\Controller\ResultInterface; use Psr\Log\LoggerInterface; use Magento\Config\Model\Config\Factory; /** - * Controller to record that the current admin user has seen the release notification content + * Controller to record Admin analytics usage log */ class DisableAdminUsage extends Action { - - private $configFactory; /** @@ -39,11 +37,12 @@ class DisableAdminUsage extends Action private $logger; /** - * MarkUserNotified constructor. + * DisableAdminUsage constructor. * * @param Action\Context $context * @param ProductMetadataInterface $productMetadata * @param NotificationLogger $notificationLogger + * @param Factory $configFactory * @param LoggerInterface $logger */ public function __construct( @@ -59,6 +58,10 @@ public function __construct( $this->notificationLogger = $notificationLogger; $this->logger = $logger; } + + /** + * Changes the value of config/admin/usage/enabled + */ public function disableAdminUsage() { $configModel = $this->configFactory->create(); @@ -66,13 +69,16 @@ public function disableAdminUsage() $configModel->save(); } + /** + * Log information about the last admin usage selection + * + * @return ResultInterface + */ public function markUserNotified() { $responseContent = [ 'success' => $this->notificationLogger->log( - $this->_auth->getUser()->getId(), - $this->productMetadata->getVersion(), - 0 + $this->productMetadata->getVersion() ), 'error_message' => '' ]; @@ -80,10 +86,11 @@ public function markUserNotified() $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); return $resultJson->setData($responseContent); } + /** * Log information about the last shown advertisement * - * @return \Magento\Framework\Controller\ResultInterface + * @return ResultInterface */ public function execute() { diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index d1b879ae927ab..9ce119f0c424f 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -7,15 +7,15 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\Controller\ResultInterface; use Psr\Log\LoggerInterface; use Magento\Config\Model\Config\Factory; /** - * Controller to record that the current admin user has seen the release notification content + * Controller to record that the current admin user has responded to Admin Analytics notice */ class EnableAdminUsage extends Action { @@ -42,6 +42,7 @@ class EnableAdminUsage extends Action * @param Action\Context $context * @param ProductMetadataInterface $productMetadata * @param NotificationLogger $notificationLogger + * @param Factory $configFactory * @param LoggerInterface $logger */ public function __construct( @@ -57,6 +58,10 @@ public function __construct( $this->notificationLogger = $notificationLogger; $this->logger = $logger; } + + /** + * Changes the value of config/admin/usage/enabled + */ public function enableAdminUsage() { $configModel = $this->configFactory->create(); @@ -64,13 +69,16 @@ public function enableAdminUsage() $configModel->save(); } + /** + * Log information about the last user response + * + * @return ResultInterface + */ public function markUserNotified() { $responseContent = [ 'success' => $this->notificationLogger->log( - $this->_auth->getUser()->getId(), - $this->productMetadata->getVersion(), - 1 + $this->productMetadata->getVersion() ), 'error_message' => '' ]; @@ -78,6 +86,7 @@ public function markUserNotified() $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); return $resultJson->setData($responseContent); } + /** * Log information about the last shown advertisement * @@ -88,8 +97,10 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - + /** + * IsAllow allows function to be visible + * * @return bool */ protected function _isAllowed() diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php deleted file mode 100644 index 4c252329d07a7..0000000000000 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; - -use Magento\Backend\App\Action; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Controller\ResultFactory; -use Magento\ReleaseNotification\Model\ResourceModel\Viewer\Logger as NotificationLogger; -use Magento\Framework\App\ProductMetadataInterface; -use Psr\Log\LoggerInterface; - -/** - * Controller to record that the current admin user has seen the release notification content - */ -class MarkUserNotified extends Action -{ - /** - * @var ProductMetadataInterface - */ - private $productMetadata; - - /** - * @var NotificationLogger - */ - private $notificationLogger; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * MarkUserNotified constructor. - * - * @param Action\Context $context - * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param LoggerInterface $logger - */ - public function __construct( - Action\Context $context, - ProductMetadataInterface $productMetadata, - NotificationLogger $notificationLogger, - LoggerInterface $logger - ) { - parent::__construct($context); - $this->productMetadata = $productMetadata; - $this->notificationLogger = $notificationLogger; - $this->logger = $logger; - } - - /** - * Log information about the last shown advertisement - * - * @return \Magento\Framework\Controller\ResultInterface - */ - public function execute() - { - try { - $responseContent = [ - 'success' => $this->notificationLogger->log( - $this->_auth->getUser()->getId(), - $this->productMetadata->getVersion() - ), - 'error_message' => '' - ]; - } catch (LocalizedException $e) { - $this->logger->error($e->getMessage()); - $responseContent = [ - 'success' => false, - 'error_message' => $e->getMessage() - ]; - } catch (\Exception $e) { - $this->logger->error($e->getMessage()); - $responseContent = [ - 'success' => false, - 'error_message' => __('It is impossible to log user action') - ]; - } - $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); - return $resultJson->setData($responseContent); - } - - /** - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } -} diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index f6dd6ecb9ff3c..a8a6b58bffbfc 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -10,9 +10,11 @@ use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\View\Layout\Condition\VisibilityConditionInterface; use Magento\Framework\App\CacheInterface; +use function Magento\PAT\Reports\Utils\readResponseTimeReport; /** * Dynamic validator for UI release notification, manage UI component visibility. + * * Return true if the logged in user has not seen the notification. */ class CanViewNotification implements VisibilityConditionInterface @@ -36,11 +38,6 @@ class CanViewNotification implements VisibilityConditionInterface */ private $viewerLogger; - /** - * @var Session - */ - private $session; - /** * @var ProductMetadataInterface */ @@ -55,18 +52,15 @@ class CanViewNotification implements VisibilityConditionInterface * CanViewNotification constructor. * * @param Logger $viewerLogger - * @param Session $session * @param ProductMetadataInterface $productMetadata * @param CacheInterface $cacheStorage */ public function __construct( Logger $viewerLogger, - Session $session, ProductMetadataInterface $productMetadata, CacheInterface $cacheStorage ) { $this->viewerLogger = $viewerLogger; - $this->session = $session; $this->productMetadata = $productMetadata; $this->cacheStorage = $cacheStorage; } @@ -78,20 +72,18 @@ public function __construct( */ public function isVisible(array $arguments) { - $userId = $this->session->getUser()->getId(); - $cacheKey = self::$cachePrefix . $userId; + $currentProductVersion = $this->productMetadata->getVersion(); + $cacheKey = self::$cachePrefix.$currentProductVersion; $value = $this->cacheStorage->load($cacheKey); - if ($value === false) { - $value = version_compare( - $this->viewerLogger->get($userId)->getLastViewVersion(), - $this->productMetadata->getVersion(), - '<' - ); - $this->cacheStorage->save(false, $cacheKey); + if ($value != $currentProductVersion) { + $versionViewed = $this->viewerLogger->get($currentProductVersion)->getLastViewVersion(); + $versionExists = isset($versionViewed); + if ($versionExists) { + $this->cacheStorage->save($versionViewed, $cacheKey); + } + return !$versionExists; } - - return (bool)$value; - + return false; } /** diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 5b67d4dfffec1..6c6a76365fbbe 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -12,7 +12,7 @@ use Magento\Framework\App\ResourceConnection; /** - * Release notification viewer log data logger. + * Admin Analytics log data logger. * * Saves and retrieves release notification viewer log data. */ @@ -21,7 +21,7 @@ class Logger /** * Log table name */ - const LOG_TABLE_NAME = 'admin_usage_viewer_log'; + const LOG_TABLE_NAME = 'admin_analytics_usage_version_log'; /** * @var Resource @@ -49,53 +49,48 @@ public function __construct( /** * Save (insert new or update existing) log. * - * @param int $viewerId * @param string $lastViewVersion - * @param int $isAdminUsageEnabled * @return bool */ - public function log(int $viewerId, string $lastViewVersion, int $isAdminUsageEnabled) : bool + public function log(string $lastViewVersion) : bool { /** @var \Magento\Framework\DB\Adapter\AdapterInterface $connection */ $connection = $this->resource->getConnection(ResourceConnection::DEFAULT_CONNECTION); $connection->insertOnDuplicate( $this->resource->getTableName(self::LOG_TABLE_NAME), [ - 'viewer_id' => $viewerId, - 'last_view_version' => $lastViewVersion, - 'is_admin_usage_enabled' => $isAdminUsageEnabled + 'last_viewed_in_version' => $lastViewVersion, ], [ - 'last_view_version', - 'is_admin_usage_enabled' + 'last_viewed_in_version', ] ); return true; } /** - * Get log by viewer Id. + * Get log by the last view version. * - * @param int $viewerId + * @param string $lastViewVersion * @return Log */ - public function get(int $viewerId) : Log + public function get(string $lastViewVersion) : Log { - return $this->logFactory->create(['data' => $this->loadLogData($viewerId)]); + return $this->logFactory->create(['data' => $this->loadLogData($lastViewVersion)]); } /** - * Load release notification viewer log data by viewer id + * Load release notification viewer log data by last view version * - * @param int $viewerId + * @param string $lastViewVersion * @return array */ - private function loadLogData(int $viewerId) : array + private function loadLogData(string $lastViewVersion) : array { $connection = $this->resource->getConnection(); $select = $connection->select() ->from($this->resource->getTableName(self::LOG_TABLE_NAME)) - ->where('viewer_id = ?', $viewerId); + ->where('last_viewed_in_version = ?', $lastViewVersion); $data = $connection->fetchRow($select); if (!$data) { diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php index 28621b36d9b79..3ba1d15d716d7 100644 --- a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -8,7 +8,7 @@ use Magento\Framework\DataObject; /** - * Release notification viewer log resource + * Admin Analytics log resource */ class Log extends DataObject { @@ -22,16 +22,6 @@ public function getId() return $this->getData('id'); } - /** - * Get viewer id - * - * @return int - */ - public function getViewerId() - { - return $this->getData('viewer_id'); - } - /** * Get last viewed product version * @@ -39,16 +29,6 @@ public function getViewerId() */ public function getLastViewVersion() { - return $this->getData('last_view_version'); - } - - /** - * Get admin usage enabled - * - * @return int - */ - public function getIsAdminUsageEnabled() - { - return $this->getData('is_admin_usage_enabled'); + return $this->getData('last_viewed_in_version'); } } diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php deleted file mode 100644 index f93cb1e00f019..0000000000000 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php +++ /dev/null @@ -1,246 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Ui\DataProvider\Modifier; - -use Magento\AdminAnalytics\Model\ContentProviderInterface; -use Magento\AdminAnalytics\Ui\Renderer\NotificationRenderer; -use Magento\Ui\DataProvider\Modifier\ModifierInterface; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\App\CacheInterface; -use Magento\Ui\Component; -use Magento\Framework\App\ProductMetadataInterface; -use Magento\Backend\Model\Auth\Session; -use Psr\Log\LoggerInterface; - -/** - * Modifies the metadata returning to the Release Notification data provider - */ -class Notifications implements ModifierInterface -{ - /** - * @var ContentProviderInterface - */ - private $contentProvider; - - /** - * @var NotificationRenderer - */ - private $renderer; - - /** - * Prefix for cache - * - * @var string - */ - private static $cachePrefix = 'release-notification-content-'; - - /** - * @var CacheInterface - */ - private $cacheStorage; - - /** - * @var SerializerInterface - */ - private $serializer; - - /** - * @var ProductMetadataInterface - */ - private $productMetadata; - - /** - * @var Session - */ - private $session; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @param ContentProviderInterface $contentProvider - * @param NotificationRenderer $render - * @param CacheInterface $cacheStorage - * @param SerializerInterface $serializer - * @param ProductMetadataInterface $productMetadata - * @param Session $session - * @param LoggerInterface $logger - */ - public function __construct( - ContentProviderInterface $contentProvider, - NotificationRenderer $render, - CacheInterface $cacheStorage, - SerializerInterface $serializer, - ProductMetadataInterface $productMetadata, - Session $session, - LoggerInterface $logger - ) { - $this->contentProvider = $contentProvider; - $this->renderer = $render; - $this->cacheStorage = $cacheStorage; - $this->serializer = $serializer; - $this->productMetadata = $productMetadata; - $this->session = $session; - $this->logger = $logger; - } - - /** - * {@inheritdoc} - */ - public function modifyData(array $data) - { - return $data; - } - - /** - * {@inheritdoc} - */ - public function modifyMeta(array $meta) - { - $modalContent = $this->getNotificationContent(); - - if ($modalContent) { - $pages = $modalContent['pages']; - $pageCount = count($pages); - $counter = 1; - - foreach ($pages as $page) { - $meta = $this->buildNotificationMeta($meta, $page, $counter++ == $pageCount); - } - } else { - $meta = $this->hideNotification($meta); - } - - return $meta; - } - - /** - * Builds the notification modal by modifying $meta for the ui component - * - * @param array $meta - * @param array $page - * @param bool $isLastPage - * @return array - */ - private function buildNotificationMeta(array $meta, array $page, $isLastPage) - { - $meta['notification_modal_' . $page['name']]['arguments']['data']['config'] = [ - 'isTemplate' => false, - 'componentType' => Component\Modal::NAME - ]; - - $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children'] - ['notification_text']['arguments']['data']['config'] = [ - 'text' => $this->renderer->getNotificationContent($page) - ]; - - if ($isLastPage) { - $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [ - 'title' => $this->renderer->getNotificationTitle($page), - 'buttons' => [ - [ - 'text' => 'Done', - 'actions' => [ - [ - 'targetName' => '${ $.name }', - 'actionName' => 'closeReleaseNotes' - ] - ], - 'class' => 'release-notification-button-next' - ] - ], - ]; - - $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children'] - ['notification_buttons']['children']['notification_button_next']['arguments']['data']['config'] = [ - 'buttonClasses' => 'hide-release-notification' - ]; - } else { - $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [ - 'title' => $this->renderer->getNotificationTitle($page) - ]; - } - - return $meta; - } - - /** - * Sets the modal to not display if no content is available. - * - * @param array $meta - * @return array - */ - private function hideNotification(array $meta) - { - $meta['notification_modal_1']['arguments']['data']['config']['options'] = [ - 'autoOpen' => false - ]; - - return $meta; - } - - /** - * Returns the notification modal content data - * - * @returns array|false - */ - private function getNotificationContent() - { - $version = strtolower($this->getTargetVersion()); - $edition = strtolower($this->productMetadata->getEdition()); - $locale = strtolower($this->session->getUser()->getInterfaceLocale()); - - $cacheKey = self::$cachePrefix . $version . "-" . $edition . "-" . $locale; - $modalContent = $this->cacheStorage->load($cacheKey); - if ($modalContent === false) { - $modalContent = $this->contentProvider->getContent($version, $edition, $locale); - $this->cacheStorage->save($modalContent, $cacheKey); - } - - return !$modalContent ? $modalContent : $this->unserializeContent($modalContent); - } - - /** - * Unserializes the notification modal content to be used for rendering - * - * @param string $modalContent - * @return array|false - */ - private function unserializeContent($modalContent) - { - $result = false; - - try { - $result = $this->serializer->unserialize($modalContent); - } catch (\InvalidArgumentException $e) { - $this->logger->warning( - sprintf( - 'Failed to unserialize the release notification content. The error is: %s', - $e->getMessage() - ) - ); - } - - return $result; - } - - /** - * Returns the current Magento version used to retrieve the release notification content. - * Version information after the dash (-) character is removed (ex. -dev or -rc). - * - * @return string - */ - private function getTargetVersion() - { - $metadataVersion = $this->productMetadata->getVersion(); - $version = strstr($metadataVersion, '-', true); - - return !$version ? $metadataVersion : $version; - } -} diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php index 104d902d3dc94..a3acf279c7a9a 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php @@ -13,7 +13,7 @@ use Magento\Ui\DataProvider\Modifier\PoolInterface; /** - * Data Provider for the Release Notifications UI component. + * Data Provider for the Admin usage UI component. */ class NotificationDataProvider implements DataProviderInterface { @@ -164,7 +164,7 @@ public function getFieldsMetaInfo($fieldSetName) */ public function getPrimaryFieldName() { - return 'release_notification'; + return 'admin_analytics'; } /** @@ -172,7 +172,7 @@ public function getPrimaryFieldName() */ public function getRequestFieldName() { - return 'release_notification'; + return 'admin_analytics'; } /** diff --git a/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php b/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php deleted file mode 100644 index b66e213670f76..0000000000000 --- a/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php +++ /dev/null @@ -1,208 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Ui\Renderer; - -use Magento\Framework\Escaper; - -/** - * Builds the HTML for the release notification modals - */ -class NotificationRenderer -{ - /** - * @var Escaper - */ - private $escaper; - - /** - * @param Escaper $escaper - */ - public function __construct( - Escaper $escaper - ) { - $this->escaper = $escaper; - } - - /** - * Returns the HTML for notification's title to the ui component - * - * @param array $page - * @return string - */ - public function getNotificationTitle(array $page) - { - $title = $this->escaper->escapeHtml($page['mainContent']['title']); - $imageUrl = $this->escaper->escapeUrl($page['mainContent']['imageUrl']); - $content = ""; - - if (!empty($imageUrl)) { - $content .= "<div class='release-notification-title-with-image' style='background-image: url(\"" . $imageUrl - . "\")'>"; - $content .= $title; - $content .= "</div>"; - } else { - $content = $title; - } - - return $content; - } - - /** - * Returns the HTML for the content in the notification ui component - * - * @param array $page - * @return string - */ - public function getNotificationContent(array $page) - { - $content = $this->buildMainContent($page['mainContent']); - $content .= $this->buildSubHeadings($page['subHeading']); - $content .= $this->buildFooter($page['footer']); - - return $content; - } - - /** - * Builds the HTML for the main content in the notification ui component - * - * @param array $mainContent - * @return string - */ - private function buildMainContent(array $mainContent) - { - $content = $this->buildContentTextAreas($mainContent['content']); - $content .= $this->buildLists($mainContent['lists']); - - return $this->formatContentWithLinks($content); - } - - /** - * Builds the HTML for the main text areas in the notification ui component - * - * @param array $contentAreas - * @return string - */ - private function buildContentTextAreas(array $contentAreas) - { - $content = ""; - $lastContentArea = end($contentAreas); - - foreach ($contentAreas as $contentArea) { - $content .= "<p>"; - $content .= $this->escaper->escapeHtml($contentArea['text']); - $content .= "</p>"; - if ($contentArea != $lastContentArea) { - $content .= "<br />"; - } - } - - return $content; - } - - /** - * Builds the HTML for the bullet list content in the notification ui component - * - * @param array $lists - * @return string - */ - private function buildLists(array $lists) - { - $content = "<ul>"; - - foreach ($lists as $listItem) { - $content .= "<li><span>"; - $content .= $this->escaper->escapeHtml($listItem['text']); - $content .= "</span></li>"; - } - - $content .= "</ul>"; - - return $content; - } - - /** - * Builds the HTML for the highlighted sub heads for the overview page in the notification ui component - * - * @param array $subHeadings - * @return string - */ - private function buildSubHeadings(array $subHeadings) - { - $content = ""; - - foreach ($subHeadings as $subHeading) { - if (!empty($subHeading['imageUrl'])) { - $content .= "<div class='highlight-item' style='background-image: url(\"" - . $this->escaper->escapeUrl($subHeading['imageUrl']) . "\")'>"; - } else { - $content .= "<div class='highlight-item-no-image'>"; - } - - $content .= "<h3>"; - $content .= $this->escaper->escapeHtml($subHeading['title']); - $content .= "</h3>"; - $content .= "<p>"; - $content .= $this->formatContentWithLinks($subHeading['content']); - $content .= "</p>"; - $content .= "</div>"; - } - - return $content; - } - - /** - * Builds the HTML for the footer content in the notification ui component - * - * @param array $footer - * @return string - */ - private function buildFooter(array $footer) - { - $content = "<p>"; - $content .= $this->escaper->escapeHtml($footer['content']); - $content .= "</p>"; - - return $this->formatContentWithLinks($content); - } - - /** - * Searches a given string for a URL, formats it to an HTML anchor tag, and returns the original string in the - * correct HTML format. - * - * @param string $content - * @return string - */ - private function formatContentWithLinks($content) - { - $urlRegex = '#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#'; - $urlTextRegex = '/\[(.*?)\]/'; - - preg_match_all($urlRegex, $content, $urlMatches); - preg_match_all($urlTextRegex, $content, $urlTextMatches); - - foreach ($urlMatches[0] as $key => $urlMatch) { - if (!empty($urlTextMatches[0])) { - $linkMatch = $urlMatch . " " . $urlTextMatches[0][$key]; - $content = str_replace( - $linkMatch, - "<a target='_blank' href='{$this->escaper->escapeUrl($urlMatch)}'> - {$this->escaper->escapeHtml($urlTextMatches[1][$key])}</a>", - $content - ); - } else { - $content = str_replace( - $urlMatch, - "<a target='_blank' href='{$this->escaper->escapeUrl($urlMatch)}'> - {$this->escaper->escapeUrl($urlMatch)}</a>", - $content - ); - } - } - - return $content; - } -} diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema.xml b/app/code/Magento/AdminAnalytics/etc/db_schema.xml index d640c6af45286..b9607ce77d150 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema.xml +++ b/app/code/Magento/AdminAnalytics/etc/db_schema.xml @@ -7,24 +7,17 @@ --> <schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> - <table name="admin_usage_viewer_log" resource="default" engine="innodb" + <table name="admin_analytics_usage_version_log" resource="default" engine="innodb" comment="Admin Notification Viewer Log Table"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Log ID"/> - <column xsi:type="int" name="viewer_id" padding="10" unsigned="true" nullable="false" identity="false" - comment="Viewer admin user ID"/> - <column xsi:type="varchar" name="last_view_version" nullable="false" length="16" - comment="Viewer last view on product version"/> - <column xsi:type="smallint" name="is_admin_usage_enabled" padding="5" unsigned="true" nullable="false" identity="false" - default="0" comment="Flag if admin usage is enabled"/> + <column xsi:type="varchar" name="last_viewed_in_version" nullable="false" length="50" + comment="Viewer last viewed on product version"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" referenceId="ADMIN_NOTIFICATION_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID" - table="admin_notification_viewer_log" column="viewer_id" referenceTable="admin_user" - referenceColumn="user_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" referenceId="ADMIN_NOTIFICATION_VIEWER_LOG_VIEWER_ID"> - <column name="viewer_id"/> + <constraint xsi:type="unique" referenceId="ADMIN_ANALYTICS_USAGE_VERSION_LOG_LAST_VIEWED_IN_VERSION"> + <column name="last_viewed_in_version"/> </constraint> </table> </schema> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json index 01fb68d4b58f7..26cd4e9c6bcf4 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -2,14 +2,11 @@ "admin_usage_viewer_log": { "column": { "id": true, - "viewer_id": true, - "last_view_version": true, - "is_admin_usage_enabled": true + "last_viewed_in_version": true }, "constraint": { "PRIMARY": true, - "ADMIN_USAGE_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID": true, - "ADMIN_USAGE_VIEWER_LOG_VIEWER_ID": true + "ADMIN_ANALYTICS_USAGE_VERSION_LOG_LAST_VIEWED_IN_VERSION": true } } } \ No newline at end of file From e0a00fbeec82bc173844608b9f95b3b6d646ffa7 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Mon, 29 Jul 2019 09:33:44 +0300 Subject: [PATCH 211/372] MC-18699: Fixing integration test --- .../testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php index 59ad82334a958..3b7273e088105 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php @@ -736,7 +736,7 @@ public function testValidateUploadFileExceptionDataProvider() ], 'image_empty' => [ 'fileName' => 'empty.png', - 'expectedErrorMsg' => 'Disallowed file type.', + 'expectedErrorMsg' => 'Wrong file size.', 'useFixture' => true ], 'notanimage' => [ From 234945755b8701b2ee9b651837701e5d14d6886c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 29 Jul 2019 08:29:13 -0500 Subject: [PATCH 212/372] MC-15298: Allow admin to opt out of admin analytics tracking - added block --- app/code/Magento/AdminAnalytics/Block/Metadata.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/Block/Metadata.php b/app/code/Magento/AdminAnalytics/Block/Metadata.php index e89d09ab100eb..2a669829a8211 100644 --- a/app/code/Magento/AdminAnalytics/Block/Metadata.php +++ b/app/code/Magento/AdminAnalytics/Block/Metadata.php @@ -73,7 +73,7 @@ public function getCurrentUser() :string return hash('sha512', 'ADMIN_USER' . $this->authSession->getUser()->getEmail()); } /** - * Get Magento mode + * Get Magento mode that the user is using * * @return string */ From 3a7554b281103ac506e406bb8c1b9a1b53db2419 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 29 Jul 2019 08:34:02 -0500 Subject: [PATCH 213/372] MC-15298: Allow admin to opt out of admin analytics tracking - added routes,system,module --- app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml | 2 +- app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml | 2 +- app/code/Magento/AdminAnalytics/etc/module.xml | 1 + .../Magento/AdminAnalytics/view/adminhtml/layout/default.xml | 1 + .../AdminAnalytics/view/adminhtml/templates/tracking.phtml | 2 +- 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml b/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml index e1024b12bc42d..5b5f2b52210b0 100644 --- a/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml +++ b/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml @@ -11,4 +11,4 @@ <module name="Magento_AdminAnalytics" /> </route> </router> -</config> \ No newline at end of file +</config> diff --git a/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml b/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml index 97372e1cca087..d6867e74c4760 100644 --- a/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml +++ b/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml @@ -18,4 +18,4 @@ </group> </section> </system> -</config> \ No newline at end of file +</config> diff --git a/app/code/Magento/AdminAnalytics/etc/module.xml b/app/code/Magento/AdminAnalytics/etc/module.xml index f0990b114e25f..e27c90db11e29 100644 --- a/app/code/Magento/AdminAnalytics/etc/module.xml +++ b/app/code/Magento/AdminAnalytics/etc/module.xml @@ -8,3 +8,4 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Magento_AdminAnalytics"/> </config> + diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 5339fbc894a41..62a9dda8b090c 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -24,3 +24,4 @@ </body> </page> + diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml index e4acd77b13353..03c4c848aa44a 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml @@ -12,4 +12,4 @@ "user": "<?= $block->escapeJs($block->getCurrentUser()) ?>", "mode": "<?= $block->escapeJs($block->getMode()) ?>" }; -</script> \ No newline at end of file +</script> From 7ade44e833f918a8f3429b25e0531dd95387f65f Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 29 Jul 2019 13:09:35 -0500 Subject: [PATCH 214/372] MC-18721: Customer Inline editor option error - Resolved incorrect template disabling - Updated template render logic during recursive render --- app/code/Magento/Ui/view/base/web/js/grid/editing/record.js | 5 ----- lib/web/mage/utils/template.js | 4 +++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js index 14bed73a694c6..9b8998368c5ff 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js @@ -134,11 +134,6 @@ define([ field = utils.extend({}, fields.base, field); - field.__disableTmpl = { - label: true, - options: true - }; - return utils.template(field, { record: this, column: column diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 4032c9387904d..08d6ea42306ae 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -136,7 +136,9 @@ define([ cycles = 0; while (~tmpl.indexOf(opener) && (typeof maxCycles === 'undefined' || cycles < maxCycles)) { - tmpl = template(tmpl, data); + if (!isTmplIgnored(tmpl, data)) { + tmpl = template(tmpl, data); + } if (tmpl === last) { break; From c2e3a90d7a4b3cb9ca7bdeb7dc4f36d1f537ad6e Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 29 Jul 2019 14:34:30 -0500 Subject: [PATCH 215/372] MC-15298: Allow admin to opt out of admin analytics tracking - added test --- .../Section/AdminUsageNotificationSection.xml | 16 ++ .../Test/Mftf/Test/TrackingScriptTest.xml | 221 +++++++++--------- .../ui_component/admin_usage_notification.xml | 2 +- .../view/adminhtml/web/js/modal/component.js | 13 +- .../Config/Test/Mftf/Page/AdminConfigPage.xml | 3 + .../Test/Mftf/Page/ReportsSearchTermsPage.xml | 12 + 6 files changed, 150 insertions(+), 117 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Page/ReportsSearchTermsPage.xml diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml new file mode 100644 index 0000000000000..0a28e5f198669 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminUsageNotificationSection"> + <element name="adminUsageDialogBox" type="text" selector="//*[@class='modal-inner-wrap'][last()]"/> + <element name="adminUsageAllowButton" type="text" selector="//*[@id='html-body']/div[4]/aside[2]/div[2]/footer/button[2]"/> +<!-- <element name="adminUsageDontAllowButton" type="text" selector="//*button[contains('Don't Allow')]"/>--> + </section> +</sections> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml index da0d5041a6e34..f2ed558ea8832 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml @@ -21,117 +21,114 @@ </annotations> <!-- Logging in Magento admin and checking for tracking script in dashboard --> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <closeAdminNotification stepKey="closeAdminNotification"/> - - <!-- Navigating to advance settings --> - <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettings"/> - <waitForPageLoad stepKey="waitForAdvanceSettings"/> - - <!-- Changing usage setting to Yes --> - <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToYes"> - <argument name="adminUsageValue" value="1"/> - </actionGroup> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrl"/> - - <!-- Checking for tracking script in salesOrderPage --> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPage"/> - <waitForPageLoad stepKey="waitForSalesOrderPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSalesOrder"/> - - <!-- Checking for tracking script in catalogProductsPage --> - <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPage"/> - <waitForPageLoad stepKey="waitForCatalogProductsPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCatalogProducts"/> - - <!-- Checking for tracking script in customersAllCustomersPage --> - <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPage"/> - <waitForPageLoad stepKey="waitForCustomersAllCustomersPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCustomersAllCustomers"/> - - <!-- Checking for tracking script in marketingCatalogPriceRulePage --> - <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePage"/> - <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlMarketingCatalogPriceRule"/> - - <!-- Checking for tracking script in contentBlocksPage --> - <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPage"/> - <waitForPageLoad stepKey="waitForContentBlocksPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlContentBlocks"/> - - <!-- Checking for tracking script in reportsSearchTermsPage --> - <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPage"/> - <waitForPageLoad stepKey="waitForSearchTermsPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlReportsSearchTerms"/> - - <!-- Checking for tracking script in storesAllStoresPage --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPage"/> - <waitForPageLoad stepKey="waitForStoresAllStoresPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlStoresAllStores"/> - - <!-- Checking for tracking script in systemImportPage --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPage"/> - <waitForPageLoad stepKey="waitForSystemImportPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSystemImport"/> - - <!-- Checking for tracking script in findPartnersAndExtensionsPage --> - <amOnPage url="{{FindPartnersAndExtensionsPage.url}}" stepKey="goToFindPartnersAndExtensionsPage"/> - <waitForPageLoad stepKey="waitForFindPartnersAndExtensionsPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlFindPartnersAndExtensions"/> - - <!-- Navigating to advance settings --> - <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettingsAgain"/> - <waitForPageLoad stepKey="waitForAdvanceSettingsAgain"/> - - <!-- Changing usage setting back to No --> - <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToNo"> - <argument name="adminUsageValue" value="0"/> - </actionGroup> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlTest"/> - - <!-- Checking for removed tracking script in salesOrderPage --> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPageAgain"/> - <waitForPageLoad stepKey="waitForSalesOrderPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSalesOrderTest"/> - - <!-- Checking for removed tracking script in catalogProductsPage --> - <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPageAgain"/> - <waitForPageLoad stepKey="waitForCatalogProductsPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCatalogProductsTest"/> - - <!-- Checking for removed tracking script in customersAllCustomersPage --> - <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPageAgain"/> - <waitForPageLoad stepKey="waitForCustomersAllCustomersPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCustomersAllCustomersTest"/> - - <!-- Checking for removed tracking script in marketingCatalogPriceRulePage --> - <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePageAgain"/> - <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlMarketingCatalogTest"/> - - <!-- Checking for removed tracking script in contentBlocksPage --> - <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPageAgain"/> - <waitForPageLoad stepKey="waitForContentBlocksPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlContentBlocksTest"/> - - <!-- Checking for removed tracking script in reportsSearchTermsPage --> - <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPageAgain"/> - <waitForPageLoad stepKey="waitForSearchTermsPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlReportsSearchTest"/> - - <!-- Checking for removed tracking script in storesAllStoresPage --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPageAgain"/> - <waitForPageLoad stepKey="waitForStoresAllStoresPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlStoresAllStoresTest"/> - - <!-- Checking for removed tracking script in systemImportPage --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPageAgain"/> - <waitForPageLoad stepKey="waitForSystemImportPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSystemsImportTest"/> - - <!-- Checking for removed tracking script in findPartnersAndExtensionsPage --> - <amOnPage url="{{FindPartnersAndExtensionsPage.url}}" stepKey="goToFindPartnersAndExtensionsPageAgain"/> - <waitForPageLoad stepKey="waitForFindPartnersAndExtensionsPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlFindPartnersTest"/> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> + + <wait time="10" stepKey="waitTenSecondsAgainAgain"/> + + <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageDialogBox}}" stepKey="seeDialogBox"/> + <wait time="10" stepKey="waitTenSecondsAgain"/> + <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" stepKey="seeAllowButton"/> +<!-- <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageDialogBox}}" stepKey="seeDialogBox"/>--> + <wait time="10" stepKey="waitTenSeconds"/> + +<!-- <!– Navigating to advance settings –>--> +<!-- <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettings"/>--> +<!-- <waitForPageLoad stepKey="waitForAdvanceSettings"/>--> + +<!-- <!– Changing usage setting to Yes –>--> +<!-- <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToYes">--> +<!-- <argument name="adminUsageValue" value="1"/>--> +<!-- </actionGroup>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrl"/>--> + +<!-- <!– Checking for tracking script in salesOrderPage –>--> +<!-- <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPage"/>--> +<!-- <waitForPageLoad stepKey="waitForSalesOrderPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSalesOrder"/>--> + +<!-- <!– Checking for tracking script in catalogProductsPage –>--> +<!-- <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPage"/>--> +<!-- <waitForPageLoad stepKey="waitForCatalogProductsPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCatalogProducts"/>--> + +<!-- <!– Checking for tracking script in customersAllCustomersPage –>--> +<!-- <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPage"/>--> +<!-- <waitForPageLoad stepKey="waitForCustomersAllCustomersPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCustomersAllCustomers"/>--> + +<!-- <!– Checking for tracking script in marketingCatalogPriceRulePage –>--> +<!-- <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePage"/>--> +<!-- <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlMarketingCatalogPriceRule"/>--> + +<!-- <!– Checking for tracking script in contentBlocksPage –>--> +<!-- <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPage"/>--> +<!-- <waitForPageLoad stepKey="waitForContentBlocksPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlContentBlocks"/>--> + +<!-- <!– Checking for tracking script in reportsSearchTermsPage –>--> +<!-- <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPage"/>--> +<!-- <waitForPageLoad stepKey="waitForSearchTermsPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlReportsSearchTerms"/>--> + +<!-- <!– Checking for tracking script in storesAllStoresPage –>--> +<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPage"/>--> +<!-- <waitForPageLoad stepKey="waitForStoresAllStoresPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlStoresAllStores"/>--> + +<!-- <!– Checking for tracking script in systemImportPage –>--> +<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPage"/>--> +<!-- <waitForPageLoad stepKey="waitForSystemImportPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSystemImport"/>--> + +<!-- <!– Navigating to advance settings –>--> +<!-- <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettingsAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForAdvanceSettingsAgain"/>--> + +<!-- <!– Changing usage setting back to No –>--> +<!-- <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToNo">--> +<!-- <argument name="adminUsageValue" value="0"/>--> +<!-- </actionGroup>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlTest"/>--> + +<!-- <!– Checking for removed tracking script in salesOrderPage –>--> +<!-- <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForSalesOrderPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSalesOrderTest"/>--> + +<!-- <!– Checking for removed tracking script in catalogProductsPage –>--> +<!-- <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForCatalogProductsPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCatalogProductsTest"/>--> + +<!-- <!– Checking for removed tracking script in customersAllCustomersPage –>--> +<!-- <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForCustomersAllCustomersPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCustomersAllCustomersTest"/>--> + +<!-- <!– Checking for removed tracking script in marketingCatalogPriceRulePage –>--> +<!-- <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlMarketingCatalogTest"/>--> + +<!-- <!– Checking for removed tracking script in contentBlocksPage –>--> +<!-- <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForContentBlocksPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlContentBlocksTest"/>--> + +<!-- <!– Checking for removed tracking script in reportsSearchTermsPage –>--> +<!-- <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForSearchTermsPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlReportsSearchTest"/>--> + +<!-- <!– Checking for removed tracking script in storesAllStoresPage –>--> +<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForStoresAllStoresPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlStoresAllStoresTest"/>--> + +<!-- <!– Checking for removed tracking script in systemImportPage –>--> +<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForSystemImportPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSystemsImportTest"/>--> </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index f9d11d2a6a7fe..7c6d1d43006de 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -50,7 +50,7 @@ <options> <option name="modalClass" xsi:type="string">admin-usage-notification</option> <option name="title" xsi:type="string" translate="true">Allow admin usage data collection</option> - <option name="autoOpen" xsi:type="array">true</option> + <option name="autoOpen" xsi:type="boolean">true</option> <option name="type" xsi:type="string">popup</option> <option name="clickableOverlay" xsi:type="boolean">false</option> <option name="responsive" xsi:type="boolean">true</option> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 6c449e45f7aad..2cf9df87196f6 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -17,13 +17,18 @@ define( imports: { enableLogAction: '${ $.provider }:data.enableLogAction', disableLogAction: '${ $.provider }:data.disableLogAction' + }, + options: { + keyEventHandlers: { + escapeKey: function () { return; } + } } }, - keyEventHandlers: { - escapeKey: function () { - } + initModal: function () { + this.options.opened = this.onOpened.bind(this); + this._super(); }, - opened: function () { + onOpened: function () { $('.modal-header button.action-close').hide(); }, enableAdminUsage: function () { diff --git a/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml b/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml index 7a62dfff8323b..688623b612c27 100644 --- a/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml +++ b/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml @@ -21,4 +21,7 @@ <page name="AdminConfigGeneralPage" url="admin/system_config/edit/section/general/" area="admin" module="Magento_Config"> <section name="GeneralSection"/> </page> + <page name="AdminConfigAdvancedAdmin" url="admin/system_config/edit/section/admin/" area="admin" module="Magento_Config"> + <section name="AdvanceAdminSection"/> + </page> </pages> diff --git a/app/code/Magento/Reports/Test/Mftf/Page/ReportsSearchTermsPage.xml b/app/code/Magento/Reports/Test/Mftf/Page/ReportsSearchTermsPage.xml new file mode 100644 index 0000000000000..e9e60c6d6dccb --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Page/ReportsSearchTermsPage.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="ReportsSearchTermPage" url="search/term/report/" area="admin" module="Magento_Reports"> + <section name="ReportsSearchTermSection"/> + </page> +</pages> From 6ce7e16641a225a22ac0e1e78a0e34b232f08b6d Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 29 Jul 2019 14:49:23 -0500 Subject: [PATCH 216/372] MC-15978: Catalog Product Attribute Set Name --- .../Ui/DataProvider/Product/Form/Modifier/AttributeSet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php index 3420965597c5e..474b139810267 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php @@ -78,7 +78,7 @@ public function getOptions() \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::SORT_ORDER_ASC ); - $collectionData = $collection->getData(); + $collectionData = $collection->getData() ?? []; array_walk($collectionData, function (&$attribute) { $attribute['__disableTmpl'] = true; From 60bee1108ee49ae6317f0ef4f5a150523949e8a8 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 29 Jul 2019 14:53:38 -0500 Subject: [PATCH 217/372] MC-15978: Catalog Product Attribute Set Name --- .../testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php index 59ad82334a958..3b7273e088105 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php @@ -736,7 +736,7 @@ public function testValidateUploadFileExceptionDataProvider() ], 'image_empty' => [ 'fileName' => 'empty.png', - 'expectedErrorMsg' => 'Disallowed file type.', + 'expectedErrorMsg' => 'Wrong file size.', 'useFixture' => true ], 'notanimage' => [ From 615da2c895f97e07e311f4e2c277641ac9d2d3ca Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 29 Jul 2019 15:59:20 -0500 Subject: [PATCH 218/372] MC-18125: Email template improvement --- lib/internal/Magento/Framework/Filter/Template.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index c330e4d130094..0cd2935a24b1d 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -82,16 +82,16 @@ class Template implements \Zend_Filter_Interface 'getdatausingmethod', '__destruct', '__call', - '__callStatic', + '__callstatic', '__set', '__unset', '__sleep', '__wakeup', '__invoke', '__set_state', - '__debugInfo', - '___callParent', - '___callPlugins' + '__debuginfo', + '___callparent', + '___callplugins' ]; /** From febabea0d40b52d53553ac98b68b8a300e8195f8 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 29 Jul 2019 18:39:55 -0500 Subject: [PATCH 219/372] MC-18721: Customer Inline editor option error - Resolved funtional test failures --- lib/web/mage/utils/template.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 08d6ea42306ae..e954ca50bac81 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -40,7 +40,7 @@ define([ * To limit recursion for a specific property add __disableTmpl: {propertyName: numberOfCycles}. * * @param {String} tmpl - * @param {Object} target + * @param {Object | undefined} target * @returns {Boolean|Object} */ function isTmplIgnored(tmpl, target) { @@ -136,7 +136,7 @@ define([ cycles = 0; while (~tmpl.indexOf(opener) && (typeof maxCycles === 'undefined' || cycles < maxCycles)) { - if (!isTmplIgnored(tmpl, data)) { + if (!isTmplIgnored(tmpl)) { tmpl = template(tmpl, data); } From 525ddef7eb4d0fa849c6111f47bf4eace338b8cf Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 30 Jul 2019 09:07:53 -0500 Subject: [PATCH 220/372] MC-15978: Catalog Product Attribute Set Name --- .../Product/Form/Modifier/AttributeSet.php | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php index 474b139810267..53c9595b59e76 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php @@ -80,15 +80,18 @@ public function getOptions() $collectionData = $collection->getData() ?? []; - array_walk($collectionData, function (&$attribute) { - $attribute['__disableTmpl'] = true; - }); + array_walk( + $collectionData, + function (&$attribute) { + $attribute['__disableTmpl'] = true; + } + ); return $collectionData; } /** - * {@inheritdoc} + * @inheritdoc * @since 101.0.0 */ public function modifyMeta(array $meta) @@ -122,17 +125,20 @@ public function modifyMeta(array $meta) } /** - * {@inheritdoc} + * @inheritdoc * @since 101.0.0 */ public function modifyData(array $data) { - return array_replace_recursive($data, [ - $this->locator->getProduct()->getId() => [ - self::DATA_SOURCE_DEFAULT => [ - 'attribute_set_id' => $this->locator->getProduct()->getAttributeSetId() - ], + return array_replace_recursive( + $data, + [ + $this->locator->getProduct()->getId() => [ + self::DATA_SOURCE_DEFAULT => [ + 'attribute_set_id' => $this->locator->getProduct()->getAttributeSetId() + ], + ] ] - ]); + ); } } From cf29d0de077caae296bfc6151aecd4a9fd082d5a Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 30 Jul 2019 11:38:38 -0500 Subject: [PATCH 221/372] MC-15298: Allow admin to opt out of admin analytics tracking - added conditionalClick to action groups --- .../CloseAllDialogBoxesActionGroup.xml | 20 ++++ .../Section/AdminUsageNotificationSection.xml | 9 +- .../Test/Mftf/Test/TrackingScriptTest.xml | 112 +----------------- .../LoginAdminWithCredentialsActionGroup.xml | 1 + .../ActionGroup/LoginAsAdminActionGroup.xml | 1 + 5 files changed, 31 insertions(+), 112 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml new file mode 100644 index 0000000000000..4fd7fd17c57ee --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="CloseAllDialogBoxes"> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" visible="true" stepKey="clickCloseButtonIfVisible1"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" visible="true" stepKey="clickCloseButtonIfVisible2"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" visible="true" stepKey="clickCloseButtonIfVisible3"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" visible="true" stepKey="clickCloseButtonIfVisible4"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" visible="true" stepKey="clickCloseButtonIfVisible5"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" visible="true" stepKey="clickCloseButtonIfVisible6"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" visible="true" stepKey="clickAllowButtonIfVisible"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml index 0a28e5f198669..388214df275a7 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml @@ -10,7 +10,12 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminUsageNotificationSection"> <element name="adminUsageDialogBox" type="text" selector="//*[@class='modal-inner-wrap'][last()]"/> - <element name="adminUsageAllowButton" type="text" selector="//*[@id='html-body']/div[4]/aside[2]/div[2]/footer/button[2]"/> -<!-- <element name="adminUsageDontAllowButton" type="text" selector="//*button[contains('Don't Allow')]"/>--> + <element name="adminUsageAllowButton" type="text" selector=".modal-popup .action-secondary"/> + <element name="releaseNotificationCloseButton1" type="text" selector="//aside[1]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton2" type="text" selector="//aside[2]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton3" type="text" selector="//aside[3]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton4" type="text" selector="//aside[4]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton5" type="text" selector="//aside[5]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton6" type="text" selector="//aside[6]/div[2]/header/button"/> </section> </sections> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml index f2ed558ea8832..58bcacc190cff 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml @@ -20,115 +20,7 @@ <group value="login"/> </annotations> - <!-- Logging in Magento admin and checking for tracking script in dashboard --> - <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - - <wait time="10" stepKey="waitTenSecondsAgainAgain"/> - - <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageDialogBox}}" stepKey="seeDialogBox"/> - <wait time="10" stepKey="waitTenSecondsAgain"/> - <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" stepKey="seeAllowButton"/> -<!-- <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageDialogBox}}" stepKey="seeDialogBox"/>--> - <wait time="10" stepKey="waitTenSeconds"/> - -<!-- <!– Navigating to advance settings –>--> -<!-- <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettings"/>--> -<!-- <waitForPageLoad stepKey="waitForAdvanceSettings"/>--> - -<!-- <!– Changing usage setting to Yes –>--> -<!-- <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToYes">--> -<!-- <argument name="adminUsageValue" value="1"/>--> -<!-- </actionGroup>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrl"/>--> - -<!-- <!– Checking for tracking script in salesOrderPage –>--> -<!-- <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPage"/>--> -<!-- <waitForPageLoad stepKey="waitForSalesOrderPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSalesOrder"/>--> - -<!-- <!– Checking for tracking script in catalogProductsPage –>--> -<!-- <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPage"/>--> -<!-- <waitForPageLoad stepKey="waitForCatalogProductsPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCatalogProducts"/>--> - -<!-- <!– Checking for tracking script in customersAllCustomersPage –>--> -<!-- <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPage"/>--> -<!-- <waitForPageLoad stepKey="waitForCustomersAllCustomersPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCustomersAllCustomers"/>--> - -<!-- <!– Checking for tracking script in marketingCatalogPriceRulePage –>--> -<!-- <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePage"/>--> -<!-- <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlMarketingCatalogPriceRule"/>--> - -<!-- <!– Checking for tracking script in contentBlocksPage –>--> -<!-- <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPage"/>--> -<!-- <waitForPageLoad stepKey="waitForContentBlocksPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlContentBlocks"/>--> - -<!-- <!– Checking for tracking script in reportsSearchTermsPage –>--> -<!-- <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPage"/>--> -<!-- <waitForPageLoad stepKey="waitForSearchTermsPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlReportsSearchTerms"/>--> - -<!-- <!– Checking for tracking script in storesAllStoresPage –>--> -<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPage"/>--> -<!-- <waitForPageLoad stepKey="waitForStoresAllStoresPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlStoresAllStores"/>--> - -<!-- <!– Checking for tracking script in systemImportPage –>--> -<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPage"/>--> -<!-- <waitForPageLoad stepKey="waitForSystemImportPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSystemImport"/>--> - -<!-- <!– Navigating to advance settings –>--> -<!-- <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettingsAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForAdvanceSettingsAgain"/>--> - -<!-- <!– Changing usage setting back to No –>--> -<!-- <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToNo">--> -<!-- <argument name="adminUsageValue" value="0"/>--> -<!-- </actionGroup>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlTest"/>--> - -<!-- <!– Checking for removed tracking script in salesOrderPage –>--> -<!-- <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForSalesOrderPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSalesOrderTest"/>--> - -<!-- <!– Checking for removed tracking script in catalogProductsPage –>--> -<!-- <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForCatalogProductsPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCatalogProductsTest"/>--> - -<!-- <!– Checking for removed tracking script in customersAllCustomersPage –>--> -<!-- <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForCustomersAllCustomersPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCustomersAllCustomersTest"/>--> - -<!-- <!– Checking for removed tracking script in marketingCatalogPriceRulePage –>--> -<!-- <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlMarketingCatalogTest"/>--> - -<!-- <!– Checking for removed tracking script in contentBlocksPage –>--> -<!-- <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForContentBlocksPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlContentBlocksTest"/>--> - -<!-- <!– Checking for removed tracking script in reportsSearchTermsPage –>--> -<!-- <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForSearchTermsPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlReportsSearchTest"/>--> - -<!-- <!– Checking for removed tracking script in storesAllStoresPage –>--> -<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForStoresAllStoresPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlStoresAllStoresTest"/>--> - -<!-- <!– Checking for removed tracking script in systemImportPage –>--> -<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForSystemImportPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSystemsImportTest"/>--> + <!-- Logging in Magento admin --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml index 6aaa612b249b6..b5510404c9630 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml @@ -16,6 +16,7 @@ <amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}" stepKey="navigateToAdmin"/> <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminPassword}}" stepKey="fillPassword"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml index b2fbadcbe38e2..9c1963119d381 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml @@ -16,6 +16,7 @@ <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser.username}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminUser.password}}" stepKey="fillPassword"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> </actionGroups> From e9394a35e9bf9ed0871563d85592a803e6ca516c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 30 Jul 2019 12:57:46 -0500 Subject: [PATCH 222/372] MC-15298: Allow admin to opt out of admin analytics tracking - fixed conditionalClick --- .../Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml index b5510404c9630..e423c68dd938b 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml @@ -16,8 +16,8 @@ <amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}" stepKey="navigateToAdmin"/> <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminPassword}}" stepKey="fillPassword"/> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> </actionGroups> From 04a9f107c0aa55d100001efdaa0d22cba79c3755 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 26 Jul 2019 11:11:25 -0500 Subject: [PATCH 223/372] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update to show all products regardless of status --- app/code/Magento/Catalog/Model/ProductLink/Search.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ProductLink/Search.php b/app/code/Magento/Catalog/Model/ProductLink/Search.php index 8750345aa222b..2ad838fc6c01d 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/Search.php +++ b/app/code/Magento/Catalog/Model/ProductLink/Search.php @@ -58,7 +58,6 @@ public function prepareCollection( ): \Magento\Catalog\Model\ResourceModel\Product\Collection { $productCollection = $this->productCollectionFactory->create(); $productCollection->addAttributeToSelect(ProductInterface::NAME); - $productCollection->setVisibility($this->catalogVisibility->getVisibleInCatalogIds()); $productCollection->setPage($pageNum, $limit); $this->filter->addFilter($productCollection, 'fulltext', ['fulltext' => $searchKey]); $productCollection->setPage($pageNum, $limit); From fa4844dfd36b14fd9a3f5f6f00209522bbf79c31 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 26 Jul 2019 14:17:43 -0500 Subject: [PATCH 224/372] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update tests --- .../Magento/Catalog/Model/ProductLink/Search.php | 4 +++- .../Controller/Adminhtml/Product/SearchTest.php | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductLink/Search.php b/app/code/Magento/Catalog/Model/ProductLink/Search.php index 2ad838fc6c01d..ad7f3370ab3fe 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/Search.php +++ b/app/code/Magento/Catalog/Model/ProductLink/Search.php @@ -10,7 +10,9 @@ use Magento\Catalog\Api\Data\ProductInterface; -/** Returns collection of product visible in catalog by search key */ +/** + * Returns collection of product visible in catalog by search key + */ class Search { /** diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 8a33543e93439..cdc2b4ca55e68 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -57,6 +57,20 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('{"options":[],"total":0}', $responseBody); + $this->assertContains('"total":1}', $responseBody); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/multiple_mixed_products.php + */ + public function testExecuteEnabledAndDisabledProducts() : void + { + $this->getRequest() + ->setPostValue('searchKey', 'simple') + ->setPostValue('page', 1) + ->setPostValue('limit', 50); + $this->dispatch('backend/catalog/product/search'); + $responseBody = $this->getResponse()->getBody(); + $this->assertContains('"total":3}', $responseBody); } } From f641a988ae56f463fbac39dd56a19feaaf325606 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Mon, 29 Jul 2019 11:57:05 -0500 Subject: [PATCH 225/372] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update tests --- .../Catalog/Controller/Adminhtml/Product/SearchTest.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index cdc2b4ca55e68..ee9ed5f656080 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -38,7 +38,8 @@ public function testExecuteNonExistingSearchKey() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('{"options":[],"total":0}', $responseBody); + $jsonResponse = json_decode($responseBody); + $this->assertEmpty($jsonResponse['options']); } /** @@ -57,7 +58,8 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('"total":1}', $responseBody); + $jsonResponse = json_decode($responseBody); + $this->assertEquals(1, $jsonResponse['total']); } /** @@ -71,6 +73,7 @@ public function testExecuteEnabledAndDisabledProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('"total":3}', $responseBody); + $jsonResponse = json_decode($responseBody); + $this->assertEquals(7, $jsonResponse['total']); } } From cf9e61f56998189c9cc6eccd5fbf95c60dfe1ce8 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Mon, 29 Jul 2019 13:36:35 -0500 Subject: [PATCH 226/372] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update tests --- .../Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index ee9ed5f656080..875c7f87d6009 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -60,6 +60,7 @@ public function testExecuteNotVisibleIndividuallyProducts() : void $responseBody = $this->getResponse()->getBody(); $jsonResponse = json_decode($responseBody); $this->assertEquals(1, $jsonResponse['total']); + $this->assertCount(1, $jsonResponse['options']); } /** @@ -75,5 +76,6 @@ public function testExecuteEnabledAndDisabledProducts() : void $responseBody = $this->getResponse()->getBody(); $jsonResponse = json_decode($responseBody); $this->assertEquals(7, $jsonResponse['total']); + $this->assertCount(7, $jsonResponse['options']); } } From 9c4c61dac3b04e3819b3d4c4fff41ea6836b412c Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Mon, 29 Jul 2019 15:50:23 -0500 Subject: [PATCH 227/372] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update tests --- .../Catalog/Controller/Adminhtml/Product/SearchTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 875c7f87d6009..0704d59a1431c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -38,7 +38,7 @@ public function testExecuteNonExistingSearchKey() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody); + $jsonResponse = json_decode($responseBody, true); $this->assertEmpty($jsonResponse['options']); } @@ -58,7 +58,7 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody); + $jsonResponse = json_decode($responseBody, true); $this->assertEquals(1, $jsonResponse['total']); $this->assertCount(1, $jsonResponse['options']); } @@ -74,7 +74,7 @@ public function testExecuteEnabledAndDisabledProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody); + $jsonResponse = json_decode($responseBody, true); $this->assertEquals(7, $jsonResponse['total']); $this->assertCount(7, $jsonResponse['options']); } From 564f4411775cc0495a8dd8bffc6a110989c75b7d Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 31 Jul 2019 10:34:53 +0300 Subject: [PATCH 228/372] MC-17878: Fix delete attribute behavior --- .../Model/ResourceModel/Entity/Attribute.php | 21 ++++++++++- .../Api/ProductAttributeRepositoryTest.php | 20 +++++++++- .../Indexer/Product/Flat/ProcessorTest.php | 25 +++++++------ .../Filter/_files/attribute_with_option.php | 1 + .../Model/ResourceModel/Eav/AttributeTest.php | 10 ++++- .../Catalog/_files/category_attribute.php | 3 +- .../Catalog/_files/product_attribute.php | 3 +- .../_files/product_system_attribute.php | 16 ++++++++ .../product_system_attribute_rollback.php | 37 +++++++++++++++++++ .../Search/_files/date_attribute.php | 1 + .../Search/_files/filterable_attribute.php | 2 + .../Search/_files/filterable_attributes.php | 1 + .../Swatches/_files/swatch_attribute.php | 1 + 13 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute_rollback.php diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php index 0e7a46125d872..364e4d31d4d1d 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php @@ -11,7 +11,9 @@ use Magento\Eav\Model\Entity\Attribute as EntityAttribute; use Magento\Framework\App\ObjectManager; use Magento\Framework\DB\Select; +use Magento\Framework\Exception\CouldNotDeleteException; use Magento\Framework\Model\AbstractModel; +use Magento\Framework\Model\ResourceModel\Db\AbstractDb; /** * EAV attribute resource model @@ -20,7 +22,7 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 */ -class Attribute extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb +class Attribute extends AbstractDb { /** * Eav Entity attributes cache @@ -189,6 +191,23 @@ protected function _beforeSave(AbstractModel $object) return parent::_beforeSave($object); } + /** + * @inheritdoc + * + * @param AbstractModel $attribute + * @return AbstractDb + * @throws CouldNotDeleteException + */ + protected function _beforeDelete(AbstractModel $attribute) + { + /** @var $attribute \Magento\Eav\Api\Data\AttributeInterface */ + if ($attribute->getId() && !$attribute->getIsUserDefined()) { + throw new CouldNotDeleteException(__("The system attribute can't be deleted.")); + } + + return parent::_beforeDelete($attribute); + } + /** * Save additional attribute data after save attribute * diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php index 386bd9fc9aeeb..42aa92652a5f1 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php @@ -4,12 +4,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Catalog\Api; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; -use Magento\TestFramework\Helper\Bootstrap; +/** + * API tests for \Magento\Catalog\Model\Product\Attribute\Repository. + */ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract { const SERVICE_NAME = 'catalogProductAttributeRepositoryV1'; @@ -130,6 +131,7 @@ public function testCreateWithExceptionIfAttributeAlreadyExists() try { $this->createAttribute($attributeCode); $this->fail("Expected exception"); + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (\SoapFault $e) { //Expects soap exception } catch (\Exception $e) { @@ -320,6 +322,20 @@ public function testDeleteById() $this->assertTrue($this->deleteAttribute($attributeCode)); } + /** + * Trying to delete system attribute. + * + * @magentoApiDataFixture Magento/Catalog/_files/product_system_attribute.php + * @expectedException \Exception + * @expectedExceptionMessage The system attribute can't be deleted. + * @return void + */ + public function testDeleteSystemAttributeById(): void + { + $attributeCode = 'test_attribute_code_333'; + $this->deleteAttribute($attributeCode); + } + /** * @return void */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php index bbaf453938705..9ae9cc6b6629f 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php @@ -5,8 +5,10 @@ */ namespace Magento\Catalog\Model\Indexer\Product\Flat; +use Magento\Catalog\Model\Product\Attribute\Repository; + /** - * Class FullTest + * Integration tests for \Magento\Catalog\Model\Indexer\Product\Flat\Processor. */ class ProcessorTest extends \Magento\TestFramework\Indexer\TestCase { @@ -64,22 +66,23 @@ public function testSaveAttribute() } /** - * @magentoDbIsolation enabled + * @magentoDbIsolation disabled * @magentoAppIsolation enabled * @magentoAppArea adminhtml - * @magentoDataFixture Magento/Catalog/_files/multiple_products.php + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat.php * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1 */ public function testDeleteAttribute() { - /** @var $product \Magento\Catalog\Model\Product */ - $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Product::class - ); - - /** @var \Magento\Catalog\Model\ResourceModel\Product $productResource */ - $productResource = $product->getResource(); - $productResource->getAttribute('media_gallery')->delete(); + /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $model */ + $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class); + /** @var Repository $productAttributeRepository */ + $productAttributeRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(Repository::class); + $productAttrubute = $productAttributeRepository->get('flat_attribute'); + $productAttributeId = $productAttrubute->getAttributeId(); + $model->load($productAttributeId)->delete(); $this->assertTrue($this->_processor->getIndexer()->isInvalid()); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php index 833d1b114a0b5..b4431678b2016 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php @@ -20,6 +20,7 @@ 'is_global' => 1, 'frontend_input' => 'select', 'is_filterable' => 1, + 'is_user_defined' => 1, 'option' => ['value' => ['option_0' => [0 => 'Option Label']]], 'backend_type' => 'int', ] diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Eav/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Eav/AttributeTest.php index 349853c8a3935..498c3167ed734 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Eav/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Eav/AttributeTest.php @@ -5,6 +5,9 @@ */ namespace Magento\Catalog\Model\ResourceModel\Eav; +/** + * Test for \Magento\Catalog\Model\ResourceModel\Eav\Attribute. + */ class AttributeTest extends \PHPUnit\Framework\TestCase { /** @@ -19,6 +22,11 @@ protected function setUp() ); } + /** + * Test Create -> Read -> Update -> Delete attribute operations. + * + * @return void + */ public function testCRUD() { $this->_model->setAttributeCode( @@ -31,7 +39,7 @@ public function testCRUD() )->getId() )->setFrontendLabel( 'test' - ); + )->setIsUserDefined(1); $crud = new \Magento\TestFramework\Entity($this->_model, ['frontend_label' => uniqid()]); $crud->testCrud(); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_attribute.php index 37398abdb8f7d..29b4a05c4dcbe 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_attribute.php @@ -9,5 +9,6 @@ ->create(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class); $attribute->setAttributeCode('test_attribute_code_666') ->setEntityTypeId(3) - ->setIsGlobal(1); + ->setIsGlobal(1) + ->setIsUserDefined(1); $attribute->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php index b5187d5d80768..b59675c5a28ae 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php @@ -10,5 +10,6 @@ $attribute->setAttributeCode('test_attribute_code_333') ->setEntityTypeId(4) ->setIsGlobal(1) - ->setPrice(95); + ->setPrice(95) + ->setIsUserDefined(1); $attribute->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute.php new file mode 100644 index 0000000000000..1e7429cc831f5 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute.php @@ -0,0 +1,16 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +// phpcs:ignore Magento2.Security.IncludeFile +require __DIR__ . '/product_attribute.php'; +/** @var $attributeRepository \Magento\Catalog\Model\Product\Attribute\Repository */ +$attributeRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\Product\Attribute\Repository::class); +/** @var $attribute \Magento\Eav\Api\Data\AttributeInterface */ +$attribute = $attributeRepository->get('test_attribute_code_333'); + +$attributeRepository->save($attribute->setIsUserDefined(0)); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute_rollback.php new file mode 100644 index 0000000000000..0f997ff4b4941 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute_rollback.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Exception\NoSuchEntityException; + +/** @var $attributeRepository \Magento\Catalog\Model\Product\Attribute\Repository */ +$attributeRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\Product\Attribute\Repository::class); + +try { + /** @var $attribute \Magento\Eav\Api\Data\AttributeInterface */ + $attribute = $attributeRepository->get('test_attribute_code_333'); + $attributeRepository->save($attribute->setIsUserDefined(1)); + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch +} catch (NoSuchEntityException $e) { +} +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +try { + $attribute = $attributeRepository->get('test_attribute_code_333'); + if ($attribute->getId()) { + $attribute->delete(); + } + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch +} catch (\Exception $e) { +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/date_attribute.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/date_attribute.php index c7e118f4a4e2b..d11248a47a0cc 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/date_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/date_attribute.php @@ -25,6 +25,7 @@ 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), 'is_global' => 1, 'is_filterable' => 1, + 'is_user_defined' => 1, 'backend_type' => 'datetime', 'frontend_input' => 'date', 'frontend_label' => 'Test Date', diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attribute.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attribute.php index 9188bb9657633..a74669e9890af 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attribute.php @@ -21,6 +21,7 @@ 'is_global' => 1, 'frontend_input' => 'select', 'is_filterable' => 1, + 'is_user_defined' => 1, 'option' => [ 'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']], 'order' => ['option_0' => 1, 'option_1' => 2], @@ -48,6 +49,7 @@ 'is_global' => 1, 'frontend_input' => 'multiselect', 'is_filterable' => 1, + 'is_user_defined' => 1, 'option' => [ 'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']], 'order' => ['option_0' => 1, 'option_1' => 2], diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes.php index f4f3337a253c0..03269b88ee2a1 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes.php @@ -78,6 +78,7 @@ 'entity_type_id' => $productEntityTypeId, 'is_global' => 1, 'is_filterable' => 1, + 'is_user_defined' => 1, 'backend_type' => 'datetime', 'frontend_input' => 'date', 'frontend_label' => 'Test Date', diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/swatch_attribute.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/swatch_attribute.php index 182f4781a9632..202fd0a8c73d5 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/_files/swatch_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/swatch_attribute.php @@ -16,6 +16,7 @@ 'backend_type' => '', 'is_searchable' => 0, 'is_filterable' => 0, + 'is_user_defined' => 1, 'is_filterable_in_search' => 0, 'frontend_label' => 'Attribute ', 'entity_type_id' => 4 From 98f99ae4cec56ab6b567c7430a15e5f78c52af85 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Wed, 31 Jul 2019 16:09:19 +0300 Subject: [PATCH 229/372] MC-18750: Failed function test Magento\FunctionalTestingFramework.functional.StorefrontUKCustomerCheckoutWithCouponTest --- .../Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml index ebf24e710fe39..13928dd91ec75 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml @@ -18,6 +18,7 @@ </annotations> <before> + <magentoCLI command="downloadable:domains:add" arguments="example.com static.magento.com" stepKey="addDownloadableDomain"/> <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminPanel"/> <createData entity="ApiDownloadableProduct" stepKey="createDownloadableProduct"> <field key="price">20.00</field> @@ -38,6 +39,7 @@ </createData> </before> <after> + <magentoCLI command="downloadable:domains:remove" arguments="example.com static.magento.com" stepKey="removeDownloadableDomain"/> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteProduct"/> <deleteData createDataKey="virtualProduct" stepKey="deleteVirtualProduct"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> @@ -127,4 +129,4 @@ <see selector="{{AdminOrderTotalSection.grandTotal}}" userInput="$15.00" stepKey="seeGrandTotal"/> <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Pending" stepKey="seeOrderStatus"/> </test> -</tests> \ No newline at end of file +</tests> From 3f0cac5163284b87c00b80f1cc69db1b74180724 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 08:21:33 -0500 Subject: [PATCH 230/372] MC-15298: Allow admin to opt out of admin analytics tracking - --- .../Adminhtml/Config/DisableAdminUsage.php | 10 +--------- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 12 +----------- .../ActionGroup/CloseAllDialogBoxesActionGroup.xml | 8 +------- .../Mftf/Section/AdminUsageNotificationSection.xml | 8 +------- .../AdminAnalytics/etc/db_schema_whitelist.json | 2 +- .../view/adminhtml/web/js/modal/component.js | 4 +++- 6 files changed, 8 insertions(+), 36 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index eb31e54e8041b..73635ddfee313 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -88,7 +88,7 @@ public function markUserNotified() } /** - * Log information about the last shown advertisement + * Changes the admin usage to no, and marks user notified * * @return ResultInterface */ @@ -97,12 +97,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 9ce119f0c424f..e2ecb700e2b4c 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -88,7 +88,7 @@ public function markUserNotified() } /** - * Log information about the last shown advertisement + * Changes the admin usage to yes, and marks user notified * * @return \Magento\Framework\Controller\ResultInterface */ @@ -97,14 +97,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * IsAllow allows function to be visible - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml index 4fd7fd17c57ee..71c039773f6bf 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml @@ -9,12 +9,6 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="CloseAllDialogBoxes"> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" visible="true" stepKey="clickCloseButtonIfVisible1"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" visible="true" stepKey="clickCloseButtonIfVisible2"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" visible="true" stepKey="clickCloseButtonIfVisible3"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" visible="true" stepKey="clickCloseButtonIfVisible4"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" visible="true" stepKey="clickCloseButtonIfVisible5"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" visible="true" stepKey="clickCloseButtonIfVisible6"/> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" visible="true" stepKey="clickAllowButtonIfVisible"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml index 388214df275a7..8bd6263d35e38 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml @@ -10,12 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminUsageNotificationSection"> <element name="adminUsageDialogBox" type="text" selector="//*[@class='modal-inner-wrap'][last()]"/> - <element name="adminUsageAllowButton" type="text" selector=".modal-popup .action-secondary"/> - <element name="releaseNotificationCloseButton1" type="text" selector="//aside[1]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton2" type="text" selector="//aside[2]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton3" type="text" selector="//aside[3]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton4" type="text" selector="//aside[4]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton5" type="text" selector="//aside[5]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton6" type="text" selector="//aside[6]/div[2]/header/button"/> + <element name="adminUsageDontAllowButton" type="text" selector=".modal-popup .action-secondary"/> </section> </sections> diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json index 26cd4e9c6bcf4..626e3ec14bc90 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -1,5 +1,5 @@ { - "admin_usage_viewer_log": { + "admin_analytics_usage_version_log": { "column": { "id": true, "last_viewed_in_version": true diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 2cf9df87196f6..17cffb33f043c 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -20,7 +20,8 @@ define( }, options: { keyEventHandlers: { - escapeKey: function () { return; } + escapeKey: function () { + return; } } } }, @@ -32,6 +33,7 @@ define( $('.modal-header button.action-close').hide(); }, enableAdminUsage: function () { + var data = { 'form_key': window.FORM_KEY }; From 254676a98582dbd1c3894a3a5e3c9d84179894a4 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Wed, 31 Jul 2019 16:22:13 +0300 Subject: [PATCH 231/372] MC-18749: Failed funtional test Magento\FunctionalTestingFramework.functional.StorefrontPrintOrderGuestTest --- .../Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml index 5c0d405102464..0bd8ab4855e97 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml @@ -19,6 +19,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI command="downloadable:domains:add" arguments="example.com static.magento.com" stepKey="addDownloadableDomain"/> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> <createData entity="ApiCategory" stepKey="createCategory"/> @@ -207,6 +208,7 @@ <actionGroup ref="orderSelectFlatRateShipping" stepKey="selectFlatRate"/> </before> <after> + <magentoCLI command="downloadable:domains:remove" arguments="example.com static.magento.com" stepKey="removeDownloadableDomain"/> <deleteData createDataKey="downloadableProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> @@ -275,4 +277,4 @@ <see userInput="Flat Rate - Fixed" selector="{{StorefrontOrderDetailsSection.shippingMethod}}" stepKey="assertShippingMethodOnPrintOrder"/> <switchToPreviousTab stepKey="switchToPreviousTab"/> </test> -</tests> \ No newline at end of file +</tests> From c2cc4ec892db647e348841b8eab1c7c3edabd81b Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 10:25:04 -0500 Subject: [PATCH 232/372] MC-15298: Allow admin to opt out of admin analytics tracking - Added UI component --- .../Adminhtml/Config/DisableAdminUsage.php | 10 +++- .../Adminhtml/Config/EnableAdminUsage.php | 12 +++- .../AdminAnalytics/ViewModel/Notification.php | 56 +++++++++++++++++++ .../etc/db_schema_whitelist.json | 2 +- .../view/adminhtml/layout/default.xml | 15 +++-- .../view/adminhtml/requirejs-config.js | 14 +++++ .../adminhtml/templates/notification.phtml | 16 ++++++ .../view/adminhtml/web/js/modal/component.js | 29 ++++++---- .../modal/component-mixin.js | 29 ++++++++++ 9 files changed, 164 insertions(+), 19 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/ViewModel/Notification.php create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/requirejs-config.js create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/templates/notification.phtml create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 73635ddfee313..eb31e54e8041b 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -88,7 +88,7 @@ public function markUserNotified() } /** - * Changes the admin usage to no, and marks user notified + * Log information about the last shown advertisement * * @return ResultInterface */ @@ -97,4 +97,12 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index e2ecb700e2b4c..9ce119f0c424f 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -88,7 +88,7 @@ public function markUserNotified() } /** - * Changes the admin usage to yes, and marks user notified + * Log information about the last shown advertisement * * @return \Magento\Framework\Controller\ResultInterface */ @@ -97,4 +97,14 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * IsAllow allows function to be visible + * + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/ViewModel/Notification.php b/app/code/Magento/AdminAnalytics/ViewModel/Notification.php new file mode 100644 index 0000000000000..5b4a51c5b6539 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/ViewModel/Notification.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\ViewModel; + +/** + * Class Notification + */ +class Notification implements \Magento\Framework\View\Element\Block\ArgumentInterface +{ + /** + * @var \Magento\AdminAnalytics\Model\Condition\CanViewNotification + */ + private $canViewNotificationAnalytics; + + /** + * @var \Magento\ReleaseNotification\Model\Condition\CanViewNotification + */ + private $canViewNotificationRelease; + + /** + * Notification constructor. + * @param \Magento\AdminAnalytics\Model\Condition\CanViewNotification $canViewNotificationAnalytics + * @param \Magento\ReleaseNotification\Model\Condition\CanViewNotification $canViewNotificationRelease + */ + public function __construct( + \Magento\AdminAnalytics\Model\Condition\CanViewNotification $canViewNotificationAnalytics, + \Magento\ReleaseNotification\Model\Condition\CanViewNotification $canViewNotificationRelease + ) { + $this->canViewNotificationAnalytics = $canViewNotificationAnalytics; + $this->canViewNotificationRelease = $canViewNotificationRelease; + } + + /** + * Determine if the analytics popup is visible + * + * @return bool + */ + public function isAnalyticsVisible(): bool + { + return $this->canViewNotificationAnalytics->isVisible([]); + } + + /** + * Determine if the release popup is visible + * + * @return bool + */ + public function isReleaseVisible(): bool + { + return $this->canViewNotificationRelease->isVisible([]); + } +} diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json index 626e3ec14bc90..26cd4e9c6bcf4 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -1,5 +1,5 @@ { - "admin_analytics_usage_version_log": { + "admin_usage_viewer_log": { "column": { "id": true, "last_viewed_in_version": true diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 62a9dda8b090c..688bbc1e41888 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -13,14 +13,17 @@ <argument name="tracking_url" xsi:type="string">//assets.adobedtm.com/launch-EN30eb7ffa064444f1b8b0368ef38fd3a9.min.js</argument> </arguments> </block> - - </referenceContainer> <referenceContainer name="content"> - <uiComponent name="admin_usage_notification"> - <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> - </uiComponent> - </referenceContainer> + <uiComponent name="admin_usage_notification"> + <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> + </uiComponent> + <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> + <arguments> + <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> + </arguments> + </block> + </referenceContainer> </body> </page> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/requirejs-config.js b/app/code/Magento/AdminAnalytics/view/adminhtml/requirejs-config.js new file mode 100644 index 0000000000000..1361210929789 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/requirejs-config.js @@ -0,0 +1,14 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +var config = { + config: { + mixins: { + 'Magento_ReleaseNotification/js/modal/component': { + 'Magento_AdminAnalytics/js/release-notification/modal/component-mixin': true + } + } + } +}; diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/notification.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/notification.phtml new file mode 100644 index 0000000000000..4b1f971670184 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/notification.phtml @@ -0,0 +1,16 @@ + +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +?> + +<script> + define('analyticsPopupConfig', function () { + return { + analyticsVisible: <?= $block->getNotification()->isAnalyticsVisible() ? 1 : 0; ?>, + releaseVisible: <?= $block->getNotification()->isReleaseVisible() ? 1 : 0; ?>, + } + }); +</script> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 17cffb33f043c..8afa4861dd153 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -3,12 +3,14 @@ * See COPYING.txt for license details. */ -define( - [ +define([ + 'underscore', 'jquery', - 'Magento_Ui/js/modal/modal-component' - ], - function ($, Modal) { + 'Magento_Ui/js/modal/modal-component', + 'uiRegistry', + 'analyticsPopupConfig' +], + function (_, $, Modal, registry, analyticsPopupConfig) { 'use strict'; return Modal.extend( @@ -20,10 +22,10 @@ define( }, options: { keyEventHandlers: { - escapeKey: function () { - return; } + escapeKey: function () { return; } } - } + }, + notificationWindow: null, }, initModal: function () { this.options.opened = this.onOpened.bind(this); @@ -33,7 +35,6 @@ define( $('.modal-header button.action-close').hide(); }, enableAdminUsage: function () { - var data = { 'form_key': window.FORM_KEY }; @@ -51,6 +52,7 @@ define( } } ).fail(this.onError); + this.openReleasePopup(); this.closeModal(); }, disableAdminUsage: function () { @@ -71,8 +73,15 @@ define( } } ).fail(this.onError); + this.openReleasePopup(); this.closeModal(); - } + }, + openReleasePopup: function () { + if (analyticsPopupConfig.releaseVisible) { + var notificationModal = registry.get('release_notification.release_notification.notification_modal_1'); + notificationModal.initializeContentAfterAnalytics(); + } + }, } ) } diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js new file mode 100644 index 0000000000000..342046986186c --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js @@ -0,0 +1,29 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { + 'use strict'; + + var deferred = $.Deferred(); + var mixin = { + initializeContent: function () { + var initializeContent = this._super.bind(this); + if (!analyticsPopupConfig.analyticsVisible) { + initializeContent(); + } else { + deferred.then(function () { + initializeContent(); + }); + } + }, + initializeContentAfterAnalytics: function () { + deferred.resolve(); + } + }; + + return function (target) { + return target.extend(mixin); + }; +}); From ad9293979e0c2afd02000fd540f1f4a20a7c3312 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 11:46:20 -0500 Subject: [PATCH 233/372] MC-15298: Allow admin to opt out of admin analytics tracking - added function that allows admin usage notification to be shown first --- .../Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml index 71c039773f6bf..4fd7fd17c57ee 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml @@ -9,6 +9,12 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="CloseAllDialogBoxes"> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" visible="true" stepKey="clickCloseButtonIfVisible1"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" visible="true" stepKey="clickCloseButtonIfVisible2"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" visible="true" stepKey="clickCloseButtonIfVisible3"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" visible="true" stepKey="clickCloseButtonIfVisible4"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" visible="true" stepKey="clickCloseButtonIfVisible5"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" visible="true" stepKey="clickCloseButtonIfVisible6"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" visible="true" stepKey="clickAllowButtonIfVisible"/> </actionGroup> </actionGroups> From f1840ce0c8b42310b11c0a9e16eaf9d4129df0d1 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 15:34:43 -0500 Subject: [PATCH 234/372] MC-15298: Allow admin to opt out of admin analytics tracking - Fixed static errors --- .../Adminhtml/Config/DisableAdminUsage.php | 16 ++++------------ .../Adminhtml/Config/EnableAdminUsage.php | 18 ++++-------------- .../Model/Condition/CanViewNotification.php | 4 ++-- .../etc/db_schema_whitelist.json | 2 +- .../ui_component/admin_usage_notification.xml | 2 +- .../view/adminhtml/web/js/modal/component.js | 7 +++++-- .../modal/component-mixin.js | 1 + 7 files changed, 18 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index eb31e54e8041b..82d8ac6480b0d 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -39,11 +39,11 @@ class DisableAdminUsage extends Action /** * DisableAdminUsage constructor. * - * @param Action\Context $context + * @param Action\Context $context * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param Factory $configFactory - * @param LoggerInterface $logger + * @param NotificationLogger $notificationLogger + * @param Factory $configFactory + * @param LoggerInterface $logger */ public function __construct( Action\Context $context, @@ -97,12 +97,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 9ce119f0c424f..899d05d317e6f 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -39,11 +39,11 @@ class EnableAdminUsage extends Action /** * MarkUserNotified constructor. * - * @param Action\Context $context + * @param Action\Context $context * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param Factory $configFactory - * @param LoggerInterface $logger + * @param NotificationLogger $notificationLogger + * @param Factory $configFactory + * @param LoggerInterface $logger */ public function __construct( Action\Context $context, @@ -97,14 +97,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * IsAllow allows function to be visible - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index a8a6b58bffbfc..861fb0a385f91 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -51,9 +51,9 @@ class CanViewNotification implements VisibilityConditionInterface /** * CanViewNotification constructor. * - * @param Logger $viewerLogger + * @param Logger $viewerLogger * @param ProductMetadataInterface $productMetadata - * @param CacheInterface $cacheStorage + * @param CacheInterface $cacheStorage */ public function __construct( Logger $viewerLogger, diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json index 26cd4e9c6bcf4..626e3ec14bc90 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -1,5 +1,5 @@ { - "admin_usage_viewer_log": { + "admin_analytics_usage_version_log": { "column": { "id": true, "last_viewed_in_version": true diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index 7c6d1d43006de..090259af427bf 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -85,7 +85,7 @@ <item name="text" xsi:type="string" translate="true"><![CDATA[ <p>Help us improve Magento Admin by allowing us to collect usage data.</p> <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> - <p>You can learn more and opt out at any time by following the instructions in <a href="https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html" target="_blank">merchant documentation</a></p> + <p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/m2/ce/user_guide/stores/admin.html" target="_blank">merchant documentation</a></p> ]]></item> </item> </argument> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 8afa4861dd153..55335f17139af 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -38,6 +38,7 @@ define([ var data = { 'form_key': window.FORM_KEY }; + $.ajax( { type: 'POST', @@ -59,6 +60,7 @@ define([ var data = { 'form_key': window.FORM_KEY }; + $.ajax( { type: 'POST', @@ -77,12 +79,13 @@ define([ this.closeModal(); }, openReleasePopup: function () { + var notificationModal = registry.get('release_notification.release_notification.notification_modal_1'); + if (analyticsPopupConfig.releaseVisible) { - var notificationModal = registry.get('release_notification.release_notification.notification_modal_1'); notificationModal.initializeContentAfterAnalytics(); } }, } - ) + ); } ); diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js index 342046986186c..fdfb85dd11813 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js @@ -10,6 +10,7 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { var mixin = { initializeContent: function () { var initializeContent = this._super.bind(this); + if (!analyticsPopupConfig.analyticsVisible) { initializeContent(); } else { From 12f6ed91d8281780412cab46b0b8e3028f9c6b45 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 21:19:36 -0500 Subject: [PATCH 235/372] MC-15298: Allow admin to opt out of admin analytics tracking - corrected static errors --- .../Model/Condition/CanViewNotification.php | 31 ++--- .../Http/HttpContentProvider.php | 108 ------------------ .../Model/ContentProvider/Http/UrlBuilder.php | 64 ----------- .../Model/ResourceModel/Viewer/Logger.php | 17 ++- .../Condition/CanViewNotificationTest.php | 87 ++++++++++++++ .../DataProvider/NotificationDataProvider.php | 3 + app/code/Magento/AdminAnalytics/composer.json | 2 +- .../view/adminhtml/web/js/modal/component.js | 8 +- 8 files changed, 120 insertions(+), 200 deletions(-) delete mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php delete mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php create mode 100644 app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 861fb0a385f91..1af8702e55108 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -6,8 +6,6 @@ namespace Magento\AdminAnalytics\Model\Condition; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; -use Magento\Backend\Model\Auth\Session; -use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\View\Layout\Condition\VisibilityConditionInterface; use Magento\Framework\App\CacheInterface; use function Magento\PAT\Reports\Utils\readResponseTimeReport; @@ -31,18 +29,13 @@ class CanViewNotification implements VisibilityConditionInterface * * @var string */ - private static $cachePrefix = 'admin-usage-notification-popup-'; + private static $cachePrefix = 'admin-usage-notification-popup'; /** * @var Logger */ private $viewerLogger; - /** - * @var ProductMetadataInterface - */ - private $productMetadata; - /** * @var CacheInterface */ @@ -51,37 +44,33 @@ class CanViewNotification implements VisibilityConditionInterface /** * CanViewNotification constructor. * - * @param Logger $viewerLogger - * @param ProductMetadataInterface $productMetadata - * @param CacheInterface $cacheStorage + * @param Logger $viewerLogger + * @param CacheInterface $cacheStorage */ public function __construct( Logger $viewerLogger, - ProductMetadataInterface $productMetadata, CacheInterface $cacheStorage ) { $this->viewerLogger = $viewerLogger; - $this->productMetadata = $productMetadata; $this->cacheStorage = $cacheStorage; } /** * Validate if notification popup can be shown and set the notification flag * + * @param array $arguments Attributes from element node. * @inheritdoc */ public function isVisible(array $arguments) { - $currentProductVersion = $this->productMetadata->getVersion(); - $cacheKey = self::$cachePrefix.$currentProductVersion; + $cacheKey = self::$cachePrefix; $value = $this->cacheStorage->load($cacheKey); - if ($value != $currentProductVersion) { - $versionViewed = $this->viewerLogger->get($currentProductVersion)->getLastViewVersion(); - $versionExists = isset($versionViewed); - if ($versionExists) { - $this->cacheStorage->save($versionViewed, $cacheKey); + if ($value !== 'log-exists') { + $logExists = $this->viewerLogger->checkLogExists(); + if ($logExists) { + $this->cacheStorage->save('log-exists', $cacheKey); } - return !$versionExists; + return !$logExists; } return false; } diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php deleted file mode 100644 index 930cf89966936..0000000000000 --- a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php +++ /dev/null @@ -1,108 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Model\ContentProvider\Http; - -use Magento\AdminAnalytics\Model\ContentProviderInterface; -use Magento\Setup\Module\I18n\Locale; -use Psr\Log\LoggerInterface; -use Magento\Framework\HTTP\ClientInterface; - -/** - * Requests the release notification content data via an HTTP call to a REST API - */ -class HttpContentProvider implements ContentProviderInterface -{ - /** - * @var ClientInterface - */ - private $httpClient; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var UrlBuilder - */ - private $urlBuilder; - - /** - * HttpContentProvider constructor. - * @param ClientInterface $httpClient - * @param UrlBuilder $urlBuilder - * @param LoggerInterface $logger - */ - public function __construct( - ClientInterface $httpClient, - UrlBuilder $urlBuilder, - LoggerInterface $logger - ) { - $this->httpClient = $httpClient; - $this->urlBuilder = $urlBuilder; - $this->logger = $logger; - } - - /** - * @inheritdoc - */ - public function getContent($version, $edition, $locale) - { - $result = false; - - try { - $result = $this->retrieveContent($version, $edition, $locale); - if (!$result) { - $result = $this->retrieveContent($version, $edition, Locale::DEFAULT_SYSTEM_LOCALE); - if (!$result) { - $result = $this->retrieveContent($version, '', 'default'); - } - } - } catch (\Exception $e) { - $this->logger->warning( - sprintf( - 'Failed to retrieve the release notification content. The response is: %s', - empty($result) ? 'Response body is empty.' : $result - ) - ); - } - - return $result; - } - - /** - * Retrieve content from given url - * - * @param string $version - * @param string $edition - * @param string $locale - * @return bool|string - */ - private function retrieveContent($version, $edition, $locale) - { - $url = $this->urlBuilder->getUrl($version, $edition, $locale); - return empty($url) ? false : $this->getResponse($url); - } - - /** - * Returns the response body from the HTTP client - * - * @param $url - * @return string - */ - private function getResponse($url) - { - $this->httpClient->get($url); - $responseBody = $this->httpClient->getBody(); - - if ($this->httpClient->getStatus() === 200 && !empty($responseBody)) { - return $responseBody; - } - - return false; - } -} diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php deleted file mode 100644 index 3898fb82f4ac5..0000000000000 --- a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\AdminAnalytics\Model\ContentProvider\Http; - -use Magento\Framework\App\Config\ScopeConfigInterface; - -/** - * Builder to build Url to retrieve the notification content. - */ -class UrlBuilder -{ - /** - * Path to the configuration value which contains an URL that provides the release notification data. - * - * @var string - */ - private static $notificationContentUrlConfigPath = 'system/release_notification/content_url'; - - /** - * Path to the configuration value indicates if use https in notification content request. - * - * @var string - */ - private static $useHttpsFlagConfigPath = 'system/release_notification/use_https'; - - /** - * @var ScopeConfigInterface - */ - private $config; - - /** - * @param ScopeConfigInterface $config - */ - public function __construct(ScopeConfigInterface $config) - { - $this->config = $config; - } - - /** - * Builds the URL to request the release notification content data based on passed parameters. - * - * @param string $version - * @param string $edition - * @param string $locale - * @return string - */ - public function getUrl($version, $edition, $locale) - { - $scheme = $this->config->isSetFlag(self::$useHttpsFlagConfigPath) ? 'https://' : 'http://'; - $baseUrl = $this->config->getValue(self::$notificationContentUrlConfigPath); - if (empty($baseUrl)) { - return ''; - } else { - $url = $scheme . $baseUrl; - $url .= empty($version) ? '' : '/' . $version; - $url .= empty($edition) ? '' : '/' . $edition; - $url .= empty($locale) ? '' : '/' . $locale; - return $url . '.json'; - } - } -} diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 6c6a76365fbbe..505257f051472 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -79,18 +79,29 @@ public function get(string $lastViewVersion) : Log return $this->logFactory->create(['data' => $this->loadLogData($lastViewVersion)]); } + /** + * Get log by the last view version. + * + * @return boolean + */ + public function checkLogExists() : bool + { + $data = $this->logFactory->create(['data' => $this->loadLogData()]); + $lastViewedVersion = $data->getLastViewVersion(); + return isset($lastViewedVersion); + } + /** * Load release notification viewer log data by last view version * - * @param string $lastViewVersion * @return array */ - private function loadLogData(string $lastViewVersion) : array + private function loadLogData() : array { $connection = $this->resource->getConnection(); $select = $connection->select() ->from($this->resource->getTableName(self::LOG_TABLE_NAME)) - ->where('last_viewed_in_version = ?', $lastViewVersion); + ->limit(['count' => 1]); $data = $connection->fetchRow($select); if (!$data) { diff --git a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php new file mode 100644 index 0000000000000..75306ddcd85ea --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Test\Unit\Model\Condition; + +use Magento\AdminAnalytics\Model\Condition\CanViewNotification; +use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; +use Magento\AdminAnalytics\Model\Viewer\Log; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\App\CacheInterface; + +class CanViewNotificationTest extends \PHPUnit\Framework\TestCase +{ + /** @var CanViewNotification */ + private $canViewNotification; + + /** @var Logger|\PHPUnit_Framework_MockObject_MockObject */ + private $viewerLoggerMock; + + /** @var ProductMetadataInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $productMetadataMock; + + /** @var Log|\PHPUnit_Framework_MockObject_MockObject */ + private $logMock; + + /** @var $cacheStorageMock \PHPUnit_Framework_MockObject_MockObject|CacheInterface */ + private $cacheStorageMock; + + public function setUp() + { + $this->cacheStorageMock = $this->getMockBuilder(CacheInterface::class) + ->getMockForAbstractClass(); + $this->logMock = $this->getMockBuilder(Log::class) + ->getMock(); + $this->viewerLoggerMock = $this->getMockBuilder(Logger::class) + ->disableOriginalConstructor() + ->getMock(); + $this->productMetadataMock = $this->getMockBuilder(ProductMetadataInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $objectManager = new ObjectManager($this); + $this->canViewNotification = $objectManager->getObject( + CanViewNotification::class, + [ + 'viewerLogger' => $this->viewerLoggerMock, + 'productMetadata' => $this->productMetadataMock, + 'cacheStorage' => $this->cacheStorageMock, + ] + ); + } + + /** + * @param $expected + * @param $cacheResponse + * @param $logExists + * @dataProvider isVisibleProvider + */ + public function testIsVisibleLoadDataFromLog($expected, $cacheResponse, $logExists) + { + $this->cacheStorageMock->expects($this->once()) + ->method('load') + ->with('admin-usage-notification-popup') + ->willReturn($cacheResponse); + $this->viewerLoggerMock + ->method('checkLogExists') + ->willReturn($logExists); + $this->cacheStorageMock + ->method('save') + ->with('log-exists', 'admin-usage-notification-popup'); + $this->assertEquals($expected, $this->canViewNotification->isVisible([])); + } + + /** + * @return array + */ + public function isVisibleProvider() + { + return [ + [true, false, false], + [false, 'log-exists', true], + [false, false, true], + ]; + } +} diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php index a3acf279c7a9a..8b3e25e2a6d2e 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php @@ -180,6 +180,7 @@ public function getRequestFieldName() */ public function addFilter(\Magento\Framework\Api\Filter $filter) { + return null; } /** @@ -187,6 +188,7 @@ public function addFilter(\Magento\Framework\Api\Filter $filter) */ public function addOrder($field, $direction) { + return null; } /** @@ -194,6 +196,7 @@ public function addOrder($field, $direction) */ public function setLimit($offset, $size) { + return null; } /** diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json index 085d258c72b57..7fa6c721d44c8 100644 --- a/app/code/Magento/AdminAnalytics/composer.json +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "~7.1.3||~7.2.0", + "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", "magento/module-backend": "*" }, diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 55335f17139af..091098a059a99 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -22,7 +22,9 @@ define([ }, options: { keyEventHandlers: { - escapeKey: function () { return; } + escapeKey: function () { + return; + } } }, notificationWindow: null, @@ -79,10 +81,10 @@ define([ this.closeModal(); }, openReleasePopup: function () { - var notificationModal = registry.get('release_notification.release_notification.notification_modal_1'); + var notifiModal = registry.get('release_notification.release_notification.notification_modal_1'); if (analyticsPopupConfig.releaseVisible) { - notificationModal.initializeContentAfterAnalytics(); + notifiModal.initializeContentAfterAnalytics(); } }, } From 6d966b9f8998bc46db0a8b3bcea6d636d3c586db Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 21:31:01 -0500 Subject: [PATCH 236/372] MC-15298: Allow admin to opt out of admin analytics tracking - corrected composer.json --- app/code/Magento/AdminAnalytics/composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json index 7fa6c721d44c8..0c930560425f4 100644 --- a/app/code/Magento/AdminAnalytics/composer.json +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -7,7 +7,10 @@ "require": { "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", - "magento/module-backend": "*" + "magento/module-backend": "*", + "magento/Config": "*", + "magento/Ui": "*", + "magento/ReleaseNotification": "*" }, "type": "magento2-module", "license": [ From 923198b5d1c4ae9bc053a3451b8e03eaa47d846b Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Thu, 1 Aug 2019 10:26:02 +0300 Subject: [PATCH 237/372] MC-18750: Failed function test Magento\FunctionalTestingFramework.functional.StorefrontUKCustomerCheckoutWithCouponTest --- .../Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml index 13928dd91ec75..482e2fb6233a6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml @@ -19,7 +19,6 @@ <before> <magentoCLI command="downloadable:domains:add" arguments="example.com static.magento.com" stepKey="addDownloadableDomain"/> - <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminPanel"/> <createData entity="ApiDownloadableProduct" stepKey="createDownloadableProduct"> <field key="price">20.00</field> </createData> @@ -44,6 +43,7 @@ <deleteData createDataKey="virtualProduct" stepKey="deleteVirtualProduct"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> <deleteData createDataKey="createSalesRule" stepKey="deleteSalesRule"/> + <actionGroup ref="AdminOrdersGridClearFiltersActionGroup" stepKey="clearOrderFilters"/> <actionGroup ref="logout" stepKey="logout"/> </after> @@ -108,6 +108,9 @@ <seeElement selector="{{StorefrontMiniCartSection.emptyMiniCart}}" stepKey="assertEmptyCart" /> <grabTextFrom selector="{{CheckoutSuccessMainSection.orderLink}}" stepKey="orderId"/> + <!-- Login to Admin Page --> + <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminPanel"/> + <!-- Open Order Index Page --> <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToOrders"/> <waitForPageLoad stepKey="waitForPageLoad5"/> From ae388490572ba10eddb5ba598ebc057326b4943c Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 1 Aug 2019 19:17:29 +0300 Subject: [PATCH 238/372] MC-18830: [FT] [MFTF] AdminCreateCustomerWithCountryUSATest fluky because of bad design --- .../Mftf/Section/AdminCustomerAddressesGridActionsSection.xml | 1 + .../Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesGridActionsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesGridActionsSection.xml index e743c4af66d9f..3ecbf5ff450c8 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesGridActionsSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesGridActionsSection.xml @@ -17,5 +17,6 @@ <element name="filters" type="button" selector="button[data-action='grid-filter-expand']" timeout="30"/> <element name="ok" type="button" selector="//button[@data-role='action']//span[text()='OK']" timeout="30"/> <element name="headerRow" type="text" selector=".admin__data-grid-header-row.row.row-gutter"/> + <element name="clearFilter" type="button" selector=".admin__data-grid-header .admin__data-grid-filters-current button.action-clear" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml index 43f2aa7f8de95..a487571c43534 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml @@ -85,6 +85,7 @@ <see selector="{{AdminCustomerAddressesDefaultBillingSection.addressDetails}}" userInput="{{US_Address_CA.telephone}}" stepKey="seePhoneNumberInDefaultAddressSection"/> <!--Assert Customer Address Grid --> + <conditionalClick selector="{{AdminCustomerAddressesGridActionsSection.clearFilter}}" dependentSelector="{{AdminCustomerAddressesGridActionsSection.clearFilter}}" visible="true" stepKey="clearAddressesGridFilter"/> <see selector="{{AdminCustomerAddressesGridSection.customerAddressGrid}}" userInput="{{US_Address_CA.street}}" stepKey="seeStreetAddress"/> <see selector="{{AdminCustomerAddressesGridSection.customerAddressGrid}}" userInput="{{US_Address_CA.city}}" stepKey="seeCity"/> <see selector="{{AdminCustomerAddressesGridSection.customerAddressGrid}}" userInput="{{US_Address_CA.country}}" stepKey="seeCountry"/> From ec58fb1e25978d6866e0254eb12b31859a5787e7 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 1 Aug 2019 11:43:53 -0500 Subject: [PATCH 239/372] MC-17700: Downloadable Product links --- .../Patch/Data/AddDownloadableHostsConfig.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 575a6a4d7180b..8393c9f8551f2 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -9,7 +9,9 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; +use Magento\Framework\UrlInterface; use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\Store; use Zend\Uri\Uri as UriHandler; use Magento\Framework\Url\ScopeResolverInterface; use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; @@ -80,7 +82,17 @@ public function __construct( public function apply() { foreach ($this->scopeResolver->getScopes() as $scope) { - $this->addHost($scope->getBaseUrl()); + /** @var $scope Store */ + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); } $customAdminUrl = $this->scopeConfig->getValue( From dd170ed0a01a0653ab44f43998de4c9f9597a275 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 1 Aug 2019 12:20:45 -0500 Subject: [PATCH 240/372] MC-17700: Downloadable Product links --- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 8393c9f8551f2..4bb0c38ce4c11 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -7,6 +7,7 @@ namespace Magento\Downloadable\Setup\Patch\Data; +use Magento\Config\Model\Config\Backend\Admin\Custom; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Framework\UrlInterface; @@ -81,7 +82,11 @@ public function __construct( */ public function apply() { - foreach ($this->scopeResolver->getScopes() as $scope) { + $customStoreScope = $this->scopeResolver->getScope(Custom::CONFIG_SCOPE_ID); + $storeScopes = $this->scopeResolver->getScopes(); + $allStoreScopes = array_merge($storeScopes, [$customStoreScope]); + + foreach ($allStoreScopes as $scope) { /** @var $scope Store */ $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, false)); $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, true)); From 6e8b5943de72bb2a6570ec240c737e6f5aa5ff8d Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 1 Aug 2019 14:33:38 -0500 Subject: [PATCH 241/372] MC-17700: Downloadable Product links --- .../Patch/Data/AddDownloadableHostsConfig.php | 53 +++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 4bb0c38ce4c11..958a9f58153a0 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -9,6 +9,7 @@ use Magento\Config\Model\Config\Backend\Admin\Custom; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Framework\UrlInterface; use Magento\Store\Model\ScopeInterface; @@ -87,17 +88,7 @@ public function apply() $allStoreScopes = array_merge($storeScopes, [$customStoreScope]); foreach ($allStoreScopes as $scope) { - /** @var $scope Store */ - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); + $this->addStoreAndWebsiteUrlsFromScope($scope); } $customAdminUrl = $this->scopeConfig->getValue( @@ -152,6 +143,42 @@ public function apply() $this->domainManager->addDomains($this->whitelist); } + /** + * Add stores and website urls from store scope + * + * @param Store $scope + */ + private function addStoreAndWebsiteUrlsFromScope(Store $scope) + { + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); + + try { + $website = $scope->getWebsite(); + } catch (NoSuchEntityException $e) { + return; + } + + if ($website) { + $this->addHost($website->getConfig(Store::XML_PATH_SECURE_BASE_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_UNSECURE_BASE_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_SECURE_BASE_LINK_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_UNSECURE_BASE_LINK_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_SECURE_BASE_MEDIA_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_UNSECURE_BASE_MEDIA_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_SECURE_BASE_STATIC_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_UNSECURE_BASE_STATIC_URL)); + } + } + /** * Add host to whitelist * @@ -159,6 +186,10 @@ public function apply() */ private function addHost($url) { + if (!is_string($url)) { + return; + } + $host = $this->uriHandler->parse($url)->getHost(); if ($host && !in_array($host, $this->whitelist)) { $this->whitelist[] = $host; From d713dac0293adc342826e2e6999b4b770a662166 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 1 Aug 2019 16:29:17 -0500 Subject: [PATCH 242/372] MC-18115: Email template preview bugfix --- .../Block/Adminhtml/Template/Preview.php | 12 +- .../Adminhtml/Email/Template/Popup.php | 4 +- .../Adminhtml/Email/Template/Preview.php | 9 +- .../Block/Adminhtml/Template/PreviewTest.php | 21 --- .../Adminhtml/Email/Template/PreviewTest.php | 15 +- .../ViewModel/Template/Preview/FormTest.php | 154 ++++++++++++++++++ .../Email/ViewModel/Template/Preview/Form.php | 71 ++++++++ .../adminhtml_email_template_preview.xml | 6 +- .../templates/preview/iframeswitcher.phtml | 31 +++- .../adminhtml/templates/template/edit.phtml | 3 +- 10 files changed, 268 insertions(+), 58 deletions(-) create mode 100644 app/code/Magento/Email/Test/Unit/ViewModel/Template/Preview/FormTest.php create mode 100644 app/code/Magento/Email/ViewModel/Template/Preview/Form.php diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index 5fabc584403bd..ec5596e2194a1 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -3,12 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); -/** - * Adminhtml system template preview block - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\Email\Block\Adminhtml\Template; /** @@ -55,16 +51,12 @@ public function __construct( * Prepare html output * * @return string - * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Exception */ protected function _toHtml() { $request = $this->getRequest(); - if (!$request instanceof \Magento\Framework\App\RequestSafetyInterface || !$request->isSafeMethod()) { - throw new \Magento\Framework\Exception\LocalizedException(__('Wrong request.')); - } - $storeId = $this->getAnyStoreView()->getId(); /** @var $template \Magento\Email\Model\Template */ $template = $this->_emailFactory->create(); diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php index 31d172935da7f..4f36eedd09b83 100644 --- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php +++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php @@ -7,12 +7,12 @@ namespace Magento\Email\Controller\Adminhtml\Email\Template; -use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Rendering popup email template. */ -class Popup extends \Magento\Backend\App\Action implements HttpGetActionInterface +class Popup extends \Magento\Backend\App\Action implements HttpPostActionInterface { /** * @var \Magento\Framework\View\Result\PageFactory diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php index c1a8eec07e461..a92836b2995a2 100644 --- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php +++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php @@ -4,19 +4,21 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Email\Controller\Adminhtml\Email\Template; +use Magento\Email\Controller\Adminhtml\Email\Template; use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Rendering email template preview. */ -class Preview extends \Magento\Email\Controller\Adminhtml\Email\Template implements HttpGetActionInterface +class Preview extends Template implements HttpGetActionInterface, HttpPostActionInterface { /** * Preview transactional email action. - * - * @return void */ public function execute() { @@ -24,7 +26,6 @@ public function execute() $this->_view->loadLayout(); $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Email Preview')); $this->_view->renderLayout(); - $this->getResponse()->setHeader('Content-Security-Policy', "script-src 'self'"); } catch (\Exception $e) { $this->messageManager->addErrorMessage( __('An error occurred. The email template can not be opened for preview.') diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 83eda7e39a810..4d168ffbf2bdc 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -152,9 +152,6 @@ protected function setUp() */ public function testToHtml($requestParamMap) { - $this->request->expects($this->atLeastOnce()) - ->method('isSafeMethod') - ->willReturn(true); $this->request->expects($this->any()) ->method('getParam') ->willReturnMap($requestParamMap); @@ -171,24 +168,6 @@ public function testToHtml($requestParamMap) $this->assertEquals(self::MALICIOUS_TEXT, $this->preview->toHtml()); } - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testToHtmlWithException() - { - $this->request->expects($this->atLeastOnce()) - ->method('isSafeMethod') - ->willReturn(false); - $this->template - ->expects($this->never()) - ->method('getDesignConfig'); - $this->expectException(\Magento\Framework\Exception\LocalizedException::class); - $this->expectExceptionMessage( - (string)__('Wrong request.') - ); - $this->preview->toHtml(); - } - /** * Data provider * diff --git a/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php index 9a67bf59dd4bf..d4584ce86dff2 100644 --- a/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php @@ -54,11 +54,6 @@ class PreviewTest extends \PHPUnit\Framework\TestCase */ protected $pageTitleMock; - /** - * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $responseMock; - protected function setUp() { $objectManager = new ObjectManager($this); @@ -84,16 +79,11 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) - ->setMethods(['setHeader']) - ->getMockForAbstractClass(); - $this->context = $objectManager->getObject( \Magento\Backend\App\Action\Context::class, [ 'request' => $this->requestMock, - 'view' => $this->viewMock, - 'response' => $this->responseMock + 'view' => $this->viewMock ] ); $this->object = $objectManager->getObject( @@ -118,9 +108,6 @@ public function testExecute() $this->pageTitleMock->expects($this->once()) ->method('prepend') ->willReturnSelf(); - $this->responseMock->expects($this->once()) - ->method('setHeader') - ->with('Content-Security-Policy', "script-src 'self'"); $this->assertNull($this->object->execute()); } diff --git a/app/code/Magento/Email/Test/Unit/ViewModel/Template/Preview/FormTest.php b/app/code/Magento/Email/Test/Unit/ViewModel/Template/Preview/FormTest.php new file mode 100644 index 0000000000000..88c323c923c45 --- /dev/null +++ b/app/code/Magento/Email/Test/Unit/ViewModel/Template/Preview/FormTest.php @@ -0,0 +1,154 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Email\Test\Unit\ViewModel\Template\Preview; + +use Magento\Email\ViewModel\Template\Preview\Form; +use Magento\Framework\App\Request\Http; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * Class FormTest + * + * @covers \Magento\Email\ViewModel\Template\Preview\Form + */ +class FormTest extends \PHPUnit\Framework\TestCase +{ + /** @var Form */ + protected $form; + + /** @var Http|\PHPUnit_Framework_MockObject_MockObject */ + protected $requestMock; + + protected function setUp() + { + $this->requestMock = $this->createPartialMock( + Http::class, + ['getParam', 'getMethod'] + ); + + $objectManagerHelper = new ObjectManager($this); + + $this->form = $objectManagerHelper->getObject( + Form::class, + ['request'=> $this->requestMock] + ); + } + + /** + * Tests that the form is created with the expected fields based on the request type. + * + * @dataProvider getFormFieldsDataProvider + * @param string $httpMethod + * @param array $httpParams + * @param array $expectedFields + * @throws LocalizedException + */ + public function testGetFormFields(string $httpMethod, array $httpParams, array $expectedFields) + { + $this->requestMock->expects($this->once()) + ->method('getMethod') + ->willReturn($httpMethod); + + $this->requestMock->expects($this->any()) + ->method('getParam') + ->willReturnMap($httpParams); + + $actualFields = $this->form->getFormFields(); + + $this->assertEquals($expectedFields, $actualFields); + } + + /** + * Tests that an exception is thrown when a required parameter is missing for the request type. + * + * @dataProvider getFormFieldsInvalidDataProvider + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Missing expected parameter + * @param string $httpMethod + * @param array $httpParams + */ + public function testGetFormFieldsMissingParameter(string $httpMethod, array $httpParams) + { + $this->requestMock->expects($this->once()) + ->method('getMethod') + ->willReturn($httpMethod); + + $this->requestMock->expects($this->once()) + ->method('getParam') + ->willReturnMap($httpParams); + + $this->form->getFormFields(); + } + + /** + * @return array + */ + public function getFormFieldsDataProvider() + { + return [ + 'get_request_valid' => [ + 'httpMethod' => 'GET', + 'httpParams' => [ + ['id', null, 1] + ], + 'expectedFields' => [ + 'id' => 1 + ] + ], + 'get_request_valid_ignore_params' => [ + 'httpMethod' => 'GET', + 'httpParams' => [ + ['id', null, 1], + ['text', null, 'Hello World'], + ['type', null, 2], + ['styles', null, ''] + ], + 'expectedFields' => [ + 'id' => 1 + ] + ], + 'post_request_valid' => [ + 'httpMethod' => 'POST', + 'httpParams' => [ + ['text', null, 'Hello World'], + ['type', null, 2], + ['styles', null, ''] + ], + 'expectedFields' => [ + 'text' => 'Hello World', + 'type' => 2, + 'styles' => '' + ] + ] + ]; + } + + /** + * @return array + */ + public function getFormFieldsInvalidDataProvider() + { + return [ + 'get_request_missing_id' => [ + 'httpMethod' => 'GET', + 'httpParams' => [ + ['text', null, 'Hello World'], + ['type', null, 2], + ['styles', null, ''] + ] + ], + 'post_request_missing_text' => [ + 'httpMethod' => 'POST', + 'httpParams' => [ + ['type', null, 2], + ['styles', null, ''] + ] + ] + ]; + } +} diff --git a/app/code/Magento/Email/ViewModel/Template/Preview/Form.php b/app/code/Magento/Email/ViewModel/Template/Preview/Form.php new file mode 100644 index 0000000000000..9db93cb94a299 --- /dev/null +++ b/app/code/Magento/Email/ViewModel/Template/Preview/Form.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Email\ViewModel\Template\Preview; + +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\View\Element\Block\ArgumentInterface; + +/** + * Class Form + */ +class Form implements ArgumentInterface +{ + private $expectedParamsGetRequest = [ + 'id' + ]; + + private $expectedParamsPostRequest = [ + 'text', + 'type', + 'styles' + ]; + + /** + * @var RequestInterface + */ + private $request; + + /** + * @param RequestInterface $request + */ + public function __construct(RequestInterface $request) + { + $this->request = $request; + } + + /** + * Gets the fields to be included in the email preview form. + * + * @return array + * @throws LocalizedException + */ + public function getFormFields() + { + $params = $fields = []; + $method = $this->request->getMethod(); + + if ($method === 'GET') { + $params = $this->expectedParamsGetRequest; + } elseif ($method === 'POST') { + $params = $this->expectedParamsPostRequest; + } + + foreach ($params as $paramName) { + $fieldValue = $this->request->getParam($paramName); + if ($fieldValue === null) { + throw new LocalizedException( + __("Missing expected parameter \"$paramName\" while attempting to generate template preview.") + ); + } + $fields[$paramName] = $fieldValue; + } + + return $fields; + } +} diff --git a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml index 97f31c618f9b7..e7cbc675ce386 100644 --- a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml +++ b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml @@ -12,7 +12,11 @@ <referenceContainer name="backend.page" remove="true"/> <referenceContainer name="menu.wrapper" remove="true"/> <referenceContainer name="root"> - <block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_Email::preview/iframeswitcher.phtml"/> + <block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_Email::preview/iframeswitcher.phtml"> + <arguments> + <argument name="preview_form_view_model" xsi:type="object">Magento\Email\ViewModel\Template\Preview\Form</argument> + </arguments> + </block> </referenceContainer> </body> </page> diff --git a/app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml b/app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml index 4d26b59b093e2..29ceb71a138e4 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml @@ -7,13 +7,34 @@ /** @var \Magento\Backend\Block\Page $block */ ?> <div id="preview" class="cms-revision-preview"> - <iframe - name="preview_iframe" + <iframe name="preview_iframe" id="preview_iframe" frameborder="0" title="<?= $block->escapeHtmlAttr(__('Preview')) ?>" width="100%" - sandbox="allow-forms allow-pointer-lock" - src="<?= $block->escapeUrl($block->getUrl('*/*/popup', ['_current' => true])) ?>" - /> + sandbox="allow-same-origin allow-pointer-lock" + ></iframe> + <form id="preview_form" + action="<?= $block->escapeUrl($block->getUrl('*/*/popup')) ?>" + method="post" + target="preview_iframe" + > + <input type="hidden" name="form_key" value="<?= /* @noEscape */ $block->getFormKey() ?>" /> + <?php foreach ($block->getPreviewFormViewModel()->getFormFields() as $name => $value) : ?> + <input type="hidden" name="<?= $block->escapeHtmlAttr($name) ?>" value="<?= $block->escapeHtmlAttr($value) ?>"/> + <?php endforeach; ?> + </form> </div> +<script> +require([ + 'jquery' +], function($) { + $(document).ready(function() { + $('#preview_form').submit(); + }); + + $('#preview_iframe').load(function() { + $(this).height($(this).contents().height()); + }); +}); +</script> diff --git a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml index 9653156e85e80..d99a2703e3f9c 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml @@ -48,7 +48,7 @@ use Magento\Framework\App\TemplateTypesInterface; <?= /* @noEscape */ $block->getFormHtml() ?> </form> -<form action="<?= $block->escapeUrl($block->getPreviewUrl()) ?>" method="get" id="email_template_preview_form" target="_blank"> +<form action="<?= $block->escapeUrl($block->getPreviewUrl()) ?>" method="post" id="email_template_preview_form" target="_blank"> <?= /* @noEscape */ $block->getBlockHtml('formkey') ?> <div class="no-display"> <input type="hidden" id="preview_type" name="type" value="<?= /* @noEscape */ $block->isTextType() ? 1 : 2 ?>" /> @@ -148,6 +148,7 @@ require([ } else { $('preview_type').value = <?= (int) $block->getTemplateType() ?>; } + if (typeof tinyMCE == 'undefined' || !tinyMCE.get('template_text')) { $('preview_text').value = $('template_text').value; } else { From 2f1860b9876094d7933bac3cf2ab7595f4bca0a4 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Thu, 1 Aug 2019 16:37:22 -0500 Subject: [PATCH 243/372] MC-17648: Registration email confirmation bugfix --- .../Customer/Api/AccountManagementMeTest.php | 27 ++++++++++--- .../Customer/Api/AccountManagementTest.php | 38 +++++++++++-------- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php index 31894c1332ad5..3c5a5a6770f5a 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php @@ -215,6 +215,15 @@ public function testGetCustomerData() public function testGetCustomerActivateCustomer() { + // Update the customer's confirmation key to a known value + $this->customerData = $this->customerHelper->updateSampleCustomer( + $this->customerData[Customer::ID], + [ + 'id' => $this->customerData[Customer::ID], + 'confirmation' => CustomerHelper::CONFIRMATION + ] + ); + $serviceInfo = [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH . '/activate', @@ -228,14 +237,22 @@ public function testGetCustomerActivateCustomer() 'token' => $this->token ] ]; - $requestData = ['confirmationKey' => $this->customerData[CustomerInterface::CONFIRMATION]]; + + $requestData = ['confirmationKey' => CustomerHelper::CONFIRMATION]; if (TESTS_WEB_API_ADAPTER === 'soap') { $requestData['customerId'] = 0; } - $customerResponseData = $this->_webApiCall($serviceInfo, $requestData); - $this->assertEquals($this->customerData[CustomerInterface::ID], $customerResponseData[CustomerInterface::ID]); - // Confirmation key is removed after confirmation - $this->assertFalse(isset($customerResponseData[CustomerInterface::CONFIRMATION])); + + try { + $customerResponseData = $this->_webApiCall($serviceInfo, $requestData); + $this->assertEquals( + $this->customerData[CustomerInterface::ID], + $customerResponseData[CustomerInterface::ID] + ); + } catch (\Exception $e) { + $this->fail('Customer is not activated.'); + } + } /** diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php index b2276d79f5ecf..a93bbcbdf04b2 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php @@ -249,7 +249,15 @@ public function testCreateCustomerWithoutOptionalFields() public function testActivateCustomer() { $customerData = $this->_createCustomer(); - $this->assertNotNull($customerData[Customer::CONFIRMATION], 'Customer activation is not required'); + + // Update the customer's confirmation key to a known value + $customerData = $this->customerHelper->updateSampleCustomer( + $customerData[Customer::ID], + [ + 'id' => $customerData[Customer::ID], + 'confirmation' => CustomerHelper::CONFIRMATION + ] + ); $serviceInfo = [ 'rest' => [ @@ -265,16 +273,15 @@ public function testActivateCustomer() $requestData = [ 'email' => $customerData[Customer::EMAIL], - 'confirmationKey' => $customerData[Customer::CONFIRMATION], + 'confirmationKey' => CustomerHelper::CONFIRMATION ]; - $result = $this->_webApiCall($serviceInfo, $requestData); - - $this->assertEquals($customerData[Customer::ID], $result[Customer::ID], 'Wrong customer!'); - $this->assertTrue( - !isset($result[Customer::CONFIRMATION]) || $result[Customer::CONFIRMATION] === null, - 'Customer is not activated!' - ); + try { + $result = $this->_webApiCall($serviceInfo, $requestData); + $this->assertEquals($customerData[Customer::ID], $result[Customer::ID], 'Wrong customer!'); + } catch (\Exception $e) { + $this->fail('Customer is not activated.'); + } } public function testGetCustomerActivateCustomer() @@ -294,14 +301,15 @@ public function testGetCustomerActivateCustomer() ]; $requestData = [ 'email' => $customerData[Customer::EMAIL], - 'confirmationKey' => $customerData[Customer::CONFIRMATION], + 'confirmationKey' => CustomerHelper::CONFIRMATION ]; - $customerResponseData = $this->_webApiCall($serviceInfo, $requestData); - - $this->assertEquals($customerData[Customer::ID], $customerResponseData[Customer::ID]); - // Confirmation key is removed after confirmation - $this->assertFalse(isset($customerResponseData[Customer::CONFIRMATION])); + try { + $customerResponseData = $this->_webApiCall($serviceInfo, $requestData); + $this->assertEquals($customerData[Customer::ID], $customerResponseData[Customer::ID]); + } catch (\Exception $e) { + $this->fail('Customer is not activated.'); + } } public function testValidateResetPasswordLinkToken() From a282e764dcaaa44942dba29835aa5b6efd3745d5 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Thu, 1 Aug 2019 16:56:56 -0500 Subject: [PATCH 244/372] MC-17648: Registration email confirmation bugfix * Removed extra newline --- .../testsuite/Magento/Customer/Api/AccountManagementMeTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php index 3c5a5a6770f5a..f3c981f74b83f 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php @@ -252,7 +252,6 @@ public function testGetCustomerActivateCustomer() } catch (\Exception $e) { $this->fail('Customer is not activated.'); } - } /** From d18dfe8554e158282b59870c75f64bdef3492301 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 2 Aug 2019 08:39:13 -0500 Subject: [PATCH 245/372] MC-17700: Downloadable Product links --- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 958a9f58153a0..0e88bd166b604 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -158,8 +158,11 @@ private function addStoreAndWebsiteUrlsFromScope(Store $scope) $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, true)); $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, false)); $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); + + try { + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); + } catch (\UnexpectedValueException $e) {} //@codingStandardsIgnoreLine try { $website = $scope->getWebsite(); From d1144d42126167b284edf08e859ac87bb3766df3 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Fri, 2 Aug 2019 08:49:02 -0500 Subject: [PATCH 246/372] MC-17648: Registration email confirmation bugfix --- .../Magento/Customer/Api/AccountManagementMeTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php index f3c981f74b83f..808906c64a5b2 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php @@ -217,9 +217,9 @@ public function testGetCustomerActivateCustomer() { // Update the customer's confirmation key to a known value $this->customerData = $this->customerHelper->updateSampleCustomer( - $this->customerData[Customer::ID], + $this->customerData[CustomerInterface::ID], [ - 'id' => $this->customerData[Customer::ID], + 'id' => $this->customerData[CustomerInterface::ID], 'confirmation' => CustomerHelper::CONFIRMATION ] ); From 8334ad0daa529f5345c536112b9194c6d2f73683 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Fri, 2 Aug 2019 09:09:38 -0500 Subject: [PATCH 247/372] MC-17648: Registration email confirmation bugfix --- .../Magento/Customer/Api/AccountManagementMeTest.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php index 808906c64a5b2..88bb3a8d59afd 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php @@ -215,15 +215,6 @@ public function testGetCustomerData() public function testGetCustomerActivateCustomer() { - // Update the customer's confirmation key to a known value - $this->customerData = $this->customerHelper->updateSampleCustomer( - $this->customerData[CustomerInterface::ID], - [ - 'id' => $this->customerData[CustomerInterface::ID], - 'confirmation' => CustomerHelper::CONFIRMATION - ] - ); - $serviceInfo = [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH . '/activate', From e62450604e7742381e2358400bb197f49035e4bb Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Fri, 2 Aug 2019 22:59:59 -0700 Subject: [PATCH 248/372] MC-15298: Allow admin to opt out of admin analytics tracking - Updated composer, DisableAdminUsage, EnableAdminUsage --- .../Adminhtml/Config/DisableAdminUsage.php | 8 + .../Adminhtml/Config/EnableAdminUsage.php | 8 + app/code/Magento/AdminAnalytics/composer.json | 6 +- package-lock.json | 861 ++++++++++++++++++ 4 files changed, 880 insertions(+), 3 deletions(-) create mode 100644 package-lock.json diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 82d8ac6480b0d..a5bf4640c6504 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -97,4 +97,12 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 899d05d317e6f..397176f37b9d6 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -97,4 +97,12 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json index 0c930560425f4..0b977a23ad3ca 100644 --- a/app/code/Magento/AdminAnalytics/composer.json +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -8,9 +8,9 @@ "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", "magento/module-backend": "*", - "magento/Config": "*", - "magento/Ui": "*", - "magento/ReleaseNotification": "*" + "magento/module-config": "*", + "magento/module-ui": "*", + "magento/module-release-notification": "*" }, "type": "magento2-module", "license": [ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000..b3e14ddab5aa6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,861 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "acorn": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==" + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz", + "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^6.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz", + "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==", + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" + }, + "espree": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz", + "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==", + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "requires": { + "flat-cache": "^2.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "inquirer": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", + "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + } + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.5.tgz", + "integrity": "sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA==", + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "requires": { + "mkdirp": "^0.5.1" + } + } + } +} From a70b6c9bb88109300d8f89cd3b93661a8500a238 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Sat, 3 Aug 2019 15:16:12 -0700 Subject: [PATCH 249/372] MC-15298: Allow admin to opt out of admin analytics tracking - edited DisableAdmin, EnableAdmin, admin_usage_notification --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 2 ++ .../Controller/Adminhtml/Config/EnableAdminUsage.php | 2 ++ ...nDataProvider.php => AdminUsageNotificationDataProvider.php} | 2 +- .../view/adminhtml/ui_component/admin_usage_notification.xml | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) rename app/code/Magento/AdminAnalytics/Ui/DataProvider/{NotificationDataProvider.php => AdminUsageNotificationDataProvider.php} (98%) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index a5bf4640c6504..16667737f59a3 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -99,6 +99,8 @@ public function execute() } /** + * Determines if its allowed + * * @return bool */ protected function _isAllowed() diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 397176f37b9d6..9d68121c147a4 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -99,6 +99,8 @@ public function execute() } /** + * Determines if its allowed + * * @return bool */ protected function _isAllowed() diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php similarity index 98% rename from app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php rename to app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php index 8b3e25e2a6d2e..9ab7c8b2c501e 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php @@ -15,7 +15,7 @@ /** * Data Provider for the Admin usage UI component. */ -class NotificationDataProvider implements DataProviderInterface +class AdminUsageNotificationDataProvider implements DataProviderInterface { /** * @var PoolInterface diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index 090259af427bf..5547946eb66c1 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -37,7 +37,7 @@ <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item> </item> </argument> - <dataProvider class="Magento\AdminAnalytics\Ui\DataProvider\NotificationDataProvider" name="admin_usage_notification_data_source"> + <dataProvider class="Magento\AdminAnalytics\Ui\DataProvider\AdminUsageNotificationDataProvider" name="admin_usage_notification_data_source"> <settings> <requestFieldName>id</requestFieldName> <primaryFieldName>entity_id</primaryFieldName> From 1a4a5066c3f3f8b0ad12b17e68ea617ccac9c119 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Mon, 5 Aug 2019 11:56:24 +0300 Subject: [PATCH 250/372] MC-15577: Fix url output --- lib/internal/Magento/Framework/Escaper.php | 25 ++++++++++++++++++- .../Framework/Test/Unit/EscaperTest.php | 23 +++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index cb4636471cd75..5fac9633bb372 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -28,6 +28,11 @@ class Escaper */ private $logger; + /** + * @var \Magento\Framework\Translate\InlineInterface + */ + private $translateInline; + /** * @var string[] */ @@ -335,8 +340,11 @@ public function escapeJsQuote($data, $quote = '\'') */ public function escapeXssInUrl($data) { + $data = (string)$data; + $this->getTranslateInline()->processResponseBody($data); + return htmlspecialchars( - $this->escapeScriptIdentifiers((string)$data), + $this->escapeScriptIdentifiers($data), $this->htmlSpecialCharsFlag | ENT_HTML5 | ENT_HTML401, 'UTF-8', false @@ -430,4 +438,19 @@ private function filterProhibitedTags(array $allowedTags): array return $allowedTags; } + + /** + * Resolve inline translator. + * + * @return \Magento\Framework\Translate\InlineInterface + */ + private function getTranslateInline() + { + if ($this->translateInline === null) { + $this->translateInline = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Translate\InlineInterface::class); + } + + return $this->translateInline; + } } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index bc12b0bd1227c..802477c0ee7bf 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -7,6 +7,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\Escaper; +use Magento\Framework\Translate\Inline; /** * \Magento\Framework\Escaper test case @@ -16,26 +17,40 @@ class EscaperTest extends \PHPUnit\Framework\TestCase /** * @var \Magento\Framework\Escaper */ - protected $escaper = null; + protected $escaper; /** * @var \Magento\Framework\ZendEscaper */ private $zendEscaper; + /** + * @var Inline + */ + private $translateInline; + /** * @var \Psr\Log\LoggerInterface */ private $loggerMock; + /** + * @inheritdoc + */ protected function setUp() { + $objectManagerHelper = new ObjectManager($this); $this->escaper = new Escaper(); $this->zendEscaper = new \Magento\Framework\ZendEscaper(); + $this->translateInline = $objectManagerHelper->getObject(Inline::class); $this->loggerMock = $this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class); - $objectManagerHelper = new ObjectManager($this); $objectManagerHelper->setBackwardCompatibleProperty($this->escaper, 'escaper', $this->zendEscaper); $objectManagerHelper->setBackwardCompatibleProperty($this->escaper, 'logger', $this->loggerMock); + $objectManagerHelper->setBackwardCompatibleProperty( + $this->escaper, + 'translateInline', + $this->translateInline + ); } /** @@ -390,6 +405,10 @@ public function escapeDataProvider() 'http://test.com/?redirect=\x64\x61\x74\x61\x3a\x74\x65\x78\x74x2cCPHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg', 'http://test.com/?redirect=:\x74\x65\x78\x74x2cCPHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg', ], + [ + 'http://test.com/?redirect={{{j}}{{j}}{{j}}{{j}}}avascript:alert(1)', + 'http://test.com/?redirect=:alert(1)', + ], ]; } } From 004db8edd825a3fd8798c89ed52885d66fcf579d Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 08:37:25 -0500 Subject: [PATCH 251/372] MC-15298: Allow admin to opt out of admin analytics tracking - edited DisableAdmin, EnableAdmin --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 10 ---------- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 16667737f59a3..82d8ac6480b0d 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -97,14 +97,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * Determines if its allowed - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 9d68121c147a4..899d05d317e6f 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -97,14 +97,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * Determines if its allowed - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } From 3d1721e6a948727c96009544bb58685f30388b86 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 08:51:39 -0500 Subject: [PATCH 252/372] MC-15298: Allow admin to opt out of admin analytics tracking - edited CanViewNotificationTest's namespace --- .../Test/Unit/Condition/CanViewNotificationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php index 75306ddcd85ea..00309f9527015 100644 --- a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php +++ b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php @@ -3,7 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\AdminAnalytics\Test\Unit\Model\Condition; +namespace Magento\AdminAnalytics\Test\Unit\Condition; use Magento\AdminAnalytics\Model\Condition\CanViewNotification; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; From 7d3f1c72994b8e7509aaa8a19a8cdcde6a300f43 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 09:53:30 -0500 Subject: [PATCH 253/372] MC-15298: Allow admin to opt out of admin analytics tracking - Edited composer.json, DisableAdminUsage, and EnableAdminUsage --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 10 ++++++++++ .../Controller/Adminhtml/Config/EnableAdminUsage.php | 10 ++++++++++ composer.lock | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 82d8ac6480b0d..7165a705233a0 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -97,4 +97,14 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * Checks if DisableAdminUsage is allowed + * + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 899d05d317e6f..b6414b2a5996b 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -97,4 +97,14 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * Checks if EnableAdminUsage is allowed + * + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/composer.lock b/composer.lock index 8c9f79cac256f..e376df91e863d 100644 --- a/composer.lock +++ b/composer.lock @@ -2402,7 +2402,7 @@ }, { "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "email": "backendtea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", From fd2b4ed135d9cd0420bb92790e0522f331879fe4 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 11:27:15 -0500 Subject: [PATCH 254/372] MC-15298: Allow admin to opt out of admin analytics tracking - Implemented HttpPostActionInterface to EnableAdminUsage, DisableAdminUsage --- .../Adminhtml/Config/DisableAdminUsage.php | 13 ++----------- .../Adminhtml/Config/EnableAdminUsage.php | 13 ++----------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 7165a705233a0..356f27498fa6b 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -7,6 +7,7 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; @@ -17,7 +18,7 @@ /** * Controller to record Admin analytics usage log */ -class DisableAdminUsage extends Action +class DisableAdminUsage extends Action implements HttpPostActionInterface { private $configFactory; @@ -97,14 +98,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * Checks if DisableAdminUsage is allowed - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index b6414b2a5996b..28f22533a42bd 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -7,6 +7,7 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; @@ -17,7 +18,7 @@ /** * Controller to record that the current admin user has responded to Admin Analytics notice */ -class EnableAdminUsage extends Action +class EnableAdminUsage extends Action implements HttpPostActionInterface { private $configFactory; @@ -97,14 +98,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * Checks if EnableAdminUsage is allowed - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } From 65d4444aeb618555c5b3609f0d7e2f240636b089 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 14:10:39 -0500 Subject: [PATCH 255/372] MC-17593: add mftw test case - updated LoginUser, AdminAuthLogin --- .../Backend/Test/Handler/Ui/LoginUser.php | 1 + .../Backend/Test/Page/AdminAuthLogin.php | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php index 01d8401b22fe1..39f5866a3c2ad 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php @@ -47,6 +47,7 @@ public function persist(FixtureInterface $fixture = null) $loginForm->fill($fixture); $loginForm->submit(); $loginPage->waitForHeaderBlock(); + $loginPage->dismissAdminUsageNotification(); } } } diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index c836c4db81ef1..1501a21163b50 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -40,6 +40,11 @@ class AdminAuthLogin extends Page */ protected $messagesBlock = '.messages'; + /** + * Admin Analytics selector + */ + protected $adminUsageSelector ='.modal-inner-wrap'; + /** * Constructor. */ @@ -98,4 +103,23 @@ function () use ($browser, $selector) { } ); } -} + + public function dismissAdminUsageNotification() + { + $browser = $this->browser; + $selector = $this->adminUsageSelector; + $browser->waitUntil( + function () use ($browser, $selector) { + $item = $browser->find($selector); + if ($item->isVisible()) { + return true; + } + usleep(200000); + return true; + } + ); + if ($this->browser->find($selector)->isVisible()) { + $this->browser->find($selector)->click(); + } + } +} \ No newline at end of file From e6bceb3d653d29e1d2215b17fcce80afe6765873 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 14:36:22 -0500 Subject: [PATCH 256/372] MC-15298: Allow admin to opt out of admin analytics tracking - Edited DisableAdminUsage, EnableAdminUsage, AdminUsasgeNotificationDataProvider, admin_usage_notification, component, component-mixin, componser --- .../Adminhtml/Config/DisableAdminUsage.php | 11 +++++++++ .../Adminhtml/Config/EnableAdminUsage.php | 11 +++++++++ .../AdminUsageNotificationDataProvider.php | 9 -------- .../ui_component/admin_usage_notification.xml | 2 +- .../view/adminhtml/web/js/modal/component.js | 23 +++++++++++++++++++ .../modal/component-mixin.js | 10 ++++++-- composer.json | 1 + composer.lock | 2 +- 8 files changed, 56 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 356f27498fa6b..170067bcc5dbd 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -98,4 +98,15 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * Checks if DisableAdminUsage is allowed + * + * @return bool + */ + protected function _isAllowed() + { + $isAllowed = parent::_isAllowed(); + return $isAllowed; + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 28f22533a42bd..cdb00f12e1d3d 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -98,4 +98,15 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * Checks if EnableAdminUsage is allowed + * + * @return bool + */ + protected function _isAllowed() + { + $isAllowed = parent::_isAllowed(); + return $isAllowed; + } } diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php index 9ab7c8b2c501e..5e8bc2d9160d4 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php @@ -86,11 +86,6 @@ public function __construct( */ public function getData() { - /** @var ModifierInterface $modifier */ - foreach ($this->pool->getModifiersInstances() as $modifier) { - $this->data = $modifier->modifyData($this->data); - } - return $this->data; } @@ -99,10 +94,6 @@ public function getData() */ public function getMeta() { - /** @var ModifierInterface $modifier */ - foreach ($this->pool->getModifiersInstances() as $modifier) { - $this->meta = $modifier->modifyMeta($this->meta); - } return $this->meta; } diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index 5547946eb66c1..3c35f1937783b 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -85,7 +85,7 @@ <item name="text" xsi:type="string" translate="true"><![CDATA[ <p>Help us improve Magento Admin by allowing us to collect usage data.</p> <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> - <p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/m2/ce/user_guide/stores/admin.html" target="_blank">merchant documentation</a></p> + <p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/m2/ce/user_guide/stores/admin.html" target="_blank">merchant documentation</a>.</p> ]]></item> </item> </argument> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 091098a059a99..1725cf3dce330 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -22,6 +22,9 @@ define([ }, options: { keyEventHandlers: { + /** + * Prevents escape key from exiting out of modal + */ escapeKey: function () { return; } @@ -29,13 +32,25 @@ define([ }, notificationWindow: null, }, + + /** + * Initializes modal on opened function + */ initModal: function () { this.options.opened = this.onOpened.bind(this); this._super(); }, + + /** + * Once the modal is opened it hides the X + */ onOpened: function () { $('.modal-header button.action-close').hide(); }, + + /** + * Changes admin usage setting to yes + */ enableAdminUsage: function () { var data = { 'form_key': window.FORM_KEY @@ -58,6 +73,10 @@ define([ this.openReleasePopup(); this.closeModal(); }, + + /** + * Changes admin usage setting to no + */ disableAdminUsage: function () { var data = { 'form_key': window.FORM_KEY @@ -80,6 +99,10 @@ define([ this.openReleasePopup(); this.closeModal(); }, + + /** + * Allows admin usage popup to be shown first and then new release notification + */ openReleasePopup: function () { var notifiModal = registry.get('release_notification.release_notification.notification_modal_1'); diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js index fdfb85dd11813..0cab32739a3b3 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js @@ -6,8 +6,10 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { 'use strict'; - var deferred = $.Deferred(); - var mixin = { + var deferred = $.Deferred(), mixin = { + /** + * Initializes content only if its visible + */ initializeContent: function () { var initializeContent = this._super.bind(this); @@ -19,6 +21,10 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { }); } }, + + /** + * Initializes release notification content after admin analytics + */ initializeContentAfterAnalytics: function () { deferred.resolve(); } diff --git a/composer.json b/composer.json index 7235e75f2326e..a2d5624ea6fd7 100644 --- a/composer.json +++ b/composer.json @@ -99,6 +99,7 @@ }, "replace": { "magento/module-marketplace": "*", + "magento/module-admin-analytics": "*", "magento/module-admin-notification": "*", "magento/module-advanced-pricing-import-export": "*", "magento/module-amqp": "*", diff --git a/composer.lock b/composer.lock index e376df91e863d..52a40e589fd98 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0cf49b3b5a47076608e87c7ddb566073", + "content-hash": "630adf0f19937bd3303fd1e72a68efad", "packages": [ { "name": "braintree/braintree_php", From 2503817fa0302820ac7c1a7f59d4160b221d2c01 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 15:55:55 -0500 Subject: [PATCH 257/372] MC-15298: Allow admin to opt out of admin analytics tracking - Edited component, component-mixin, AdminAuthLogin static failures --- .../AdminAnalytics/view/adminhtml/web/js/modal/component.js | 2 +- .../web/js/release-notification/modal/component-mixin.js | 5 ++++- .../tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 1725cf3dce330..bfe9ec3d97e99 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -30,7 +30,7 @@ define([ } } }, - notificationWindow: null, + notificationWindow: null }, /** diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js index 0cab32739a3b3..ffecd031cbb43 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js @@ -6,7 +6,9 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { 'use strict'; - var deferred = $.Deferred(), mixin = { + var deferred = $.Deferred(), + + mixin = { /** * Initializes content only if its visible */ @@ -34,3 +36,4 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { return target.extend(mixin); }; }); + diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index 1501a21163b50..7201054121dca 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -122,4 +122,4 @@ function () use ($browser, $selector) { $this->browser->find($selector)->click(); } } -} \ No newline at end of file +} From 8b60dd092c86b0ba7457a8e2dcd9d266b4662d7c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 16:39:43 -0500 Subject: [PATCH 258/372] MC-15298: Allow admin to opt out of admin analytics tracking - Edited component static failure --- .../AdminAnalytics/view/adminhtml/web/js/modal/component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index bfe9ec3d97e99..bc09890d0d0b4 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -109,7 +109,7 @@ define([ if (analyticsPopupConfig.releaseVisible) { notifiModal.initializeContentAfterAnalytics(); } - }, + } } ); } From 35a278548c483ff1e5d0161ff5e2980446820267 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 20:13:43 -0500 Subject: [PATCH 259/372] MC-15298: Allow admin to opt out of admin analytics tracking - Edited CreateTest, IndexTest, default.xml, adminhtml_dashboard_index --- .../layout/adminhtml_dashboard_index.xml | 22 +++++++++++++++++++ .../view/adminhtml/layout/default.xml | 10 --------- .../Adminhtml/Dashboard/IndexTest.php | 4 ++-- .../Controller/Adminhtml/Order/CreateTest.php | 2 +- 4 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml new file mode 100644 index 0000000000000..3069db1ecc2bb --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <body> + <referenceContainer name="content"> + <uiComponent name="admin_usage_notification"> + <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> + </uiComponent> + <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> + <arguments> + <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> + </arguments> + </block> + </referenceContainer> + </body> +</page> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 688bbc1e41888..05f7df8284164 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -14,16 +14,6 @@ </arguments> </block> </referenceContainer> - <referenceContainer name="content"> - <uiComponent name="admin_usage_notification"> - <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> - </uiComponent> - <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> - <arguments> - <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> - </arguments> - </block> - </referenceContainer> </body> </page> diff --git a/dev/tests/integration/testsuite/Magento/ReleaseNotification/Controller/Adminhtml/Dashboard/IndexTest.php b/dev/tests/integration/testsuite/Magento/ReleaseNotification/Controller/Adminhtml/Dashboard/IndexTest.php index 2f89f70a6c872..ffe3ccf49ebad 100644 --- a/dev/tests/integration/testsuite/Magento/ReleaseNotification/Controller/Adminhtml/Dashboard/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/ReleaseNotification/Controller/Adminhtml/Dashboard/IndexTest.php @@ -72,7 +72,7 @@ public function testExecuteEmptyContent() $this->assertEquals(200, $this->getResponse()->getHttpResponseCode()); $actual = $this->getResponse()->getBody(); - $this->assertNotContains('"autoOpen":true', $actual); + $this->assertContains('"autoOpen":false', $actual); } public function testExecuteFalseContent() @@ -87,6 +87,6 @@ public function testExecuteFalseContent() $this->assertEquals(200, $this->getResponse()->getHttpResponseCode()); $actual = $this->getResponse()->getBody(); - $this->assertNotContains('"autoOpen":true', $actual); + $this->assertContains('"autoOpen":false', $actual); } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php index a07616474a410..3d0eb2d4d75e9 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php @@ -55,7 +55,7 @@ public function testLoadBlockAction() $this->getRequest()->setParam('block', ','); $this->getRequest()->setParam('json', 1); $this->dispatch('backend/sales/order_create/loadBlock'); - $this->assertEquals('{"message":""}', $this->getResponse()->getBody()); + $this->assertContains('"message":""}', $this->getResponse()->getBody()); } /** From 45e708cacfecd84181ff437c08733d93540b9086 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Tue, 6 Aug 2019 11:02:50 +0300 Subject: [PATCH 260/372] MC-15577: Fix url output --- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 802477c0ee7bf..426081e71fde1 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -406,8 +406,8 @@ public function escapeDataProvider() 'http://test.com/?redirect=:\x74\x65\x78\x74x2cCPHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg', ], [ - 'http://test.com/?redirect={{{j}}{{j}}{{j}}{{j}}}avascript:alert(1)', - 'http://test.com/?redirect=:alert(1)', + 'http://test.com/?{{{test}}{{test_translated}}{{tes_origin}}{{theme}}}', + 'http://test.com/?test', ], ]; } From c75e923887f687ae88c859ddce6d82dfee402860 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 6 Aug 2019 11:51:56 +0300 Subject: [PATCH 261/372] MC-15930: [FT] [MFTF] AddOutOfStockProductToCompareListTest or functionality is wrong --- .../Controller/Product/Compare/Add.php | 61 ++++++++++++++++++- .../Controller/Product/Compare/Remove.php | 6 +- .../AddOutOfStockProductToCompareListTest.xml | 14 ++--- .../Checker/AddToCompareAvailability.php | 9 ++- ...refrontOnePageCheckoutJsValidationTest.xml | 1 + 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index 2b989dde9809f..8b854361fd4ef 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -6,15 +6,72 @@ */ namespace Magento\Catalog\Controller\Product\Compare; -use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\ViewModel\Product\Checker\AddToCompareAvailability; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\Data\Form\FormKey\Validator; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\View\Result\PageFactory; /** * Add item to compare list action. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Add extends \Magento\Catalog\Controller\Product\Compare implements HttpPostActionInterface { + /** + * @var AddToCompareAvailability + */ + private $compareAvailability; + + /** + * @param \Magento\Framework\App\Action\Context $context + * @param \Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory + * @param \Magento\Catalog\Model\ResourceModel\Product\Compare\Item\CollectionFactory $itemCollectionFactory + * @param \Magento\Customer\Model\Session $customerSession + * @param \Magento\Customer\Model\Visitor $customerVisitor + * @param \Magento\Catalog\Model\Product\Compare\ListCompare $catalogProductCompareList + * @param \Magento\Catalog\Model\Session $catalogSession + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param Validator $formKeyValidator + * @param PageFactory $resultPageFactory + * @param ProductRepositoryInterface $productRepository + * @param AddToCompareAvailability|null $compareAvailability + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + \Magento\Framework\App\Action\Context $context, + \Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory, + \Magento\Catalog\Model\ResourceModel\Product\Compare\Item\CollectionFactory $itemCollectionFactory, + \Magento\Customer\Model\Session $customerSession, + \Magento\Customer\Model\Visitor $customerVisitor, + \Magento\Catalog\Model\Product\Compare\ListCompare $catalogProductCompareList, + \Magento\Catalog\Model\Session $catalogSession, + \Magento\Store\Model\StoreManagerInterface $storeManager, + Validator $formKeyValidator, + PageFactory $resultPageFactory, + ProductRepositoryInterface $productRepository, + AddToCompareAvailability $compareAvailability = null + ) { + parent::__construct( + $context, + $compareItemFactory, + $itemCollectionFactory, + $customerSession, + $customerVisitor, + $catalogProductCompareList, + $catalogSession, + $storeManager, + $formKeyValidator, + $resultPageFactory, + $productRepository + ); + + $this->compareAvailability = $compareAvailability + ?: $this->_objectManager->get(AddToCompareAvailability::class); + } + /** * Add item to compare list. * @@ -37,7 +94,7 @@ public function execute() $product = null; } - if ($product && (int)$product->getStatus() !== Status::STATUS_DISABLED) { + if ($product && $this->compareAvailability->isAvailableForCompare($product)) { $this->_catalogProductCompareList->addProduct($product); $productName = $this->_objectManager->get( \Magento\Framework\Escaper::class diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php b/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php index acf0f1b754c12..f5d56dc9e6b0e 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php @@ -6,6 +6,7 @@ */ namespace Magento\Catalog\Controller\Product\Compare; +use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\Exception\NoSuchEntityException; @@ -17,12 +18,13 @@ class Remove extends \Magento\Catalog\Controller\Product\Compare implements Http /** * Remove item from compare list. * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @return \Magento\Framework\Controller\ResultInterface */ public function execute() { $productId = (int)$this->getRequest()->getParam('product'); - if ($productId) { + if ($this->_formKeyValidator->validate($this->getRequest()) && $productId) { $storeId = $this->_storeManager->getStore()->getId(); try { /** @var \Magento\Catalog\Model\Product $product */ @@ -31,7 +33,7 @@ public function execute() $product = null; } - if ($product && $product->isSalable()) { + if ($product && (int)$product->getStatus() !== Status::STATUS_DISABLED) { /** @var $item \Magento\Catalog\Model\Product\Compare\Item */ $item = $this->_compareItemFactory->create(); if ($this->_customerSession->isLoggedIn()) { diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index 31204c7b4b0bf..9a0f5ad002725 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -18,13 +18,10 @@ <testCaseId value="MAGETWO-98644"/> <useCaseId value="MAGETWO-98522"/> <group value="Catalog"/> - <skip> - <issueId value="MC-15930"/> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <magentoCLI command="config:set cataloginventory/options/show_out_of_stock 0" stepKey="displayOutOfStockNo"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> <createData entity="SimpleSubCategory" stepKey="category"/> <createData entity="SimpleProduct4" stepKey="product"> @@ -32,7 +29,7 @@ </createData> </before> <after> - <magentoCLI command="config:set cataloginventory/options/show_out_of_stock 0" stepKey="displayOutOfStockNo2"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> <deleteData createDataKey="product" stepKey="deleteProduct"/> <deleteData createDataKey="category" stepKey="deleteCategory"/> @@ -40,23 +37,24 @@ </after> <!--Open product page--> <comment userInput="Open product page" stepKey="openProdPage"/> - <amOnPage url="{{StorefrontProductPage.url($$product.name$$)}}" stepKey="goToSimpleProductPage"/> + <amOnPage url="{{StorefrontProductPage.url($$product.custom_attributes[url_key]$$)}}" stepKey="goToSimpleProductPage"/> <waitForPageLoad stepKey="waitForSimpleProductPage"/> <!--'Add to compare' link is not available--> <comment userInput="'Add to compare' link is not available" stepKey="addToCompareLinkAvailability"/> <dontSeeElement selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="dontSeeAddToCompareLink"/> <!--Turn on 'out on stock' config--> <comment userInput="Turn on 'out of stock' config" stepKey="onOutOfStockConfig"/> - <magentoCLI command="config:set cataloginventory/options/show_out_of_stock 1" stepKey="displayOutOfStockYes"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/> <!--Clear cache and reindex--> <comment userInput="Clear cache and reindex" stepKey="cleanCache"/> <magentoCLI command="indexer:reindex" stepKey="reindex"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> <!--Open product page--> <comment userInput="Open product page" stepKey="openProductPage"/> - <amOnPage url="{{StorefrontProductPage.url($$product.name$$)}}" stepKey="goToSimpleProductPage2"/> + <amOnPage url="{{StorefrontProductPage.url($$product.custom_attributes[url_key]$$)}}" stepKey="goToSimpleProductPage2"/> <waitForPageLoad stepKey="waitForSimpleProductPage2"/> <!--Click on 'Add to Compare' link--> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="seeAddToCompareLink"/> <comment userInput="Click on 'Add to Compare' link" stepKey="clickOnAddToCompareLink"/> <click selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="clickOnAddToCompare"/> <waitForPageLoad stepKey="waitForProdAddToCmpList"/> diff --git a/app/code/Magento/Catalog/ViewModel/Product/Checker/AddToCompareAvailability.php b/app/code/Magento/Catalog/ViewModel/Product/Checker/AddToCompareAvailability.php index 27829155af292..00bac7e61b5b4 100644 --- a/app/code/Magento/Catalog/ViewModel/Product/Checker/AddToCompareAvailability.php +++ b/app/code/Magento/Catalog/ViewModel/Product/Checker/AddToCompareAvailability.php @@ -10,6 +10,7 @@ use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\StockConfigurationInterface; +use Magento\Catalog\Model\Product\Attribute\Source\Status; /** * Check is available add to compare. @@ -37,7 +38,11 @@ public function __construct(StockConfigurationInterface $stockConfiguration) */ public function isAvailableForCompare(ProductInterface $product): bool { - return $this->isInStock($product) || $this->stockConfiguration->isShowOutOfStock(); + if ((int)$product->getStatus() !== Status::STATUS_DISABLED) { + return $this->isInStock($product) || $this->stockConfiguration->isShowOutOfStock(); + } + + return false; } /** @@ -53,6 +58,6 @@ private function isInStock(ProductInterface $product): bool return $product->isSalable(); } - return isset($quantityAndStockStatus['is_in_stock']) && $quantityAndStockStatus['is_in_stock']; + return $quantityAndStockStatus['is_in_stock'] ?? false; } } diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutJsValidationTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutJsValidationTest.xml index 63751ad697ede..8ed8e590eb229 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutJsValidationTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutJsValidationTest.xml @@ -11,6 +11,7 @@ <test name="StorefrontOnePageCheckoutJsValidationTest"> <annotations> <features value="Checkout"/> + <stories value="Checkout"/> <title value="Js validation error messages must be absent for required fields after checkout start."/> <description value="Js validation error messages must be absent for required fields after checkout start."/> <severity value="MAJOR" /> From a079c9139a1ae30f28f85b1f693a28e787e0f0b2 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 6 Aug 2019 17:06:42 +0300 Subject: [PATCH 262/372] MC-18967: [IT] Magento.SendFriend.Controller.SendmailTest fail on 2.3.3-develop --- .../testsuite/Magento/SendFriend/Controller/SendmailTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php index 8dbe9468923fb..1d6adf52466d2 100644 --- a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php +++ b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php @@ -24,10 +24,11 @@ class SendmailTest extends AbstractController /** * Share the product to friend as logged in customer * + * @magentoAppArea frontend * @magentoDbIsolation enabled * @magentoAppIsolation enabled - * @magentoConfigFixture default/sendfriend/email/allow_guest 0 - * @magentoConfigFixture default/sendfriend/email/enabled 1 + * @magentoConfigFixture default_store sendfriend/email/allow_guest 0 + * @magentoConfigFixture default_store sendfriend/email/enabled 1 * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/products.php */ From 52abb64c9491bf5a33dc6f77e5f4c04a0c8cfe3a Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 09:55:21 -0500 Subject: [PATCH 263/372] MC-15298: Allow admin to opt out of admin analytics tracking - admin analytics css --- .../web/css/source/_module.less | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 app/design/adminhtml/Magento/backend/Magento_AdminAnalytics/web/css/source/_module.less diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminAnalytics/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminAnalytics/web/css/source/_module.less new file mode 100644 index 0000000000000..05c0653a9bac3 --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_AdminAnalytics/web/css/source/_module.less @@ -0,0 +1,43 @@ +// /** +// * Copyright © Magento, Inc. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Magento_AdminAnalytics Modal on dashboard +// --------------------------------------------- + +.admin-usage-notification { + -webkit-transition: visibility 0s .5s, opacity .5s ease; + transition: visibility 0s .5s, opacity .5s ease; + + &._show { + -webkit-transition: opacity .5s ease; + opacity: 1; + transition: opacity .5s ease; + visibility: visible; + } + + .modal-inner-wrap { + .modal-content, + .modal-header { + padding-left: 4rem; + padding-right: 4rem; + + .action-close { + display: none; + } + } + + -webkit-transform: translateX(0); + -webkit-transition: -webkit-transform 0s; + transition: transform 0s; + transform: translateX(0); + margin-top: 13rem; + max-width: 75rem; + } + + .admin__fieldset { + padding: 0; + } +} From 3ce548211bb881c7eee2a8121d303d98efdcb9b8 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 11:00:51 -0500 Subject: [PATCH 264/372] MC-15298: Allow admin to opt out of admin analytics tracking - edited AdminAuthLogin --- .../tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index 7201054121dca..8154f4bf1f20c 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -43,7 +43,7 @@ class AdminAuthLogin extends Page /** * Admin Analytics selector */ - protected $adminUsageSelector ='.modal-inner-wrap'; + protected $adminUsageSelector ='.action-secondary'; /** * Constructor. From f681416e6975126c310dc68f8795db02b397054a Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 14:06:05 -0500 Subject: [PATCH 265/372] MC-15298: Allow admin to opt out of admin analytics tracking - changes based on review --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 9 ++++++--- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 10 ++++++---- .../Model/Condition/CanViewNotification.php | 4 +--- .../Model/ResourceModel/Viewer/Logger.php | 8 +++----- app/code/Magento/AdminAnalytics/Model/Viewer/Log.php | 4 ++-- .../Test/Unit/Condition/CanViewNotificationTest.php | 3 +++ app/code/Magento/AdminAnalytics/etc/module.xml | 1 - 7 files changed, 21 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 170067bcc5dbd..d0e5cff85d9a4 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -20,6 +20,9 @@ */ class DisableAdminUsage extends Action implements HttpPostActionInterface { + /** + * @var Factory + */ private $configFactory; /** @@ -63,7 +66,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - public function disableAdminUsage() + private function disableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 0); @@ -75,7 +78,7 @@ public function disableAdminUsage() * * @return ResultInterface */ - public function markUserNotified() + private function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( @@ -104,7 +107,7 @@ public function execute() * * @return bool */ - protected function _isAllowed() + public function _isAllowed() { $isAllowed = parent::_isAllowed(); return $isAllowed; diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index cdb00f12e1d3d..be2a8ce1d3ca3 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -20,7 +20,9 @@ */ class EnableAdminUsage extends Action implements HttpPostActionInterface { - + /** + * @var Factory + */ private $configFactory; /** * @var ProductMetadataInterface @@ -63,7 +65,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - public function enableAdminUsage() + private function enableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 1); @@ -75,7 +77,7 @@ public function enableAdminUsage() * * @return ResultInterface */ - public function markUserNotified() + private function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( @@ -104,7 +106,7 @@ public function execute() * * @return bool */ - protected function _isAllowed() + public function _isAllowed() { $isAllowed = parent::_isAllowed(); return $isAllowed; diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 1af8702e55108..76591ffe5cc10 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -11,9 +11,7 @@ use function Magento\PAT\Reports\Utils\readResponseTimeReport; /** - * Dynamic validator for UI release notification, manage UI component visibility. - * - * Return true if the logged in user has not seen the notification. + * Dynamic validator for UI admin analytics notification, manage UI component visibility. */ class CanViewNotification implements VisibilityConditionInterface { diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 505257f051472..38fdd2afed7a7 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -34,7 +34,6 @@ class Logger private $logFactory; /** - * Logger constructor. * @param ResourceConnection $resource * @param LogFactory $logFactory */ @@ -71,16 +70,15 @@ public function log(string $lastViewVersion) : bool /** * Get log by the last view version. * - * @param string $lastViewVersion * @return Log */ - public function get(string $lastViewVersion) : Log + public function get() : Log { - return $this->logFactory->create(['data' => $this->loadLogData($lastViewVersion)]); + return $this->logFactory->create(['data' => $this->loadLogData()]); } /** - * Get log by the last view version. + * Checks is log already exists. * * @return boolean */ diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php index 3ba1d15d716d7..e97b8f94e12ba 100644 --- a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -17,7 +17,7 @@ class Log extends DataObject * * @return int */ - public function getId() + public function getId() : int { return $this->getData('id'); } @@ -27,7 +27,7 @@ public function getId() * * @return string */ - public function getLastViewVersion() + public function getLastViewVersion() : ?string { return $this->getData('last_viewed_in_version'); } diff --git a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php index 00309f9527015..7819f2f017a01 100644 --- a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php +++ b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php @@ -12,6 +12,9 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\App\CacheInterface; +/** + * Class CanViewNotificationTest + */ class CanViewNotificationTest extends \PHPUnit\Framework\TestCase { /** @var CanViewNotification */ diff --git a/app/code/Magento/AdminAnalytics/etc/module.xml b/app/code/Magento/AdminAnalytics/etc/module.xml index e27c90db11e29..f0990b114e25f 100644 --- a/app/code/Magento/AdminAnalytics/etc/module.xml +++ b/app/code/Magento/AdminAnalytics/etc/module.xml @@ -8,4 +8,3 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Magento_AdminAnalytics"/> </config> - From 86c936941e5c4614fa7400e14f4f5b1ea61d2dcb Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 14:22:27 -0500 Subject: [PATCH 266/372] MC-17593: handle mtf and mftf failures - edited CanViewNotification,HttpContentProvider,Urlbuilder, config --- .../Backend/Test/Page/AdminAuthLogin.php | 23 ++++++------------ .../Magento/Ui/Test/Block/Adminhtml/Modal.php | 24 +++++++++++++++++++ .../UpdateAdminUserRoleEntityTest.php | 2 ++ .../Test/TestStep/LoginUserOnBackendStep.php | 2 ++ 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index 8154f4bf1f20c..b9c6140971409 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -43,7 +43,7 @@ class AdminAuthLogin extends Page /** * Admin Analytics selector */ - protected $adminUsageSelector ='.action-secondary'; + protected $adminUsageSelector ='.modal-inner-wrap'; /** * Constructor. @@ -87,6 +87,11 @@ public function getMessagesBlock() return Factory::getBlockFactory()->getMagentoBackendMessages($this->browser->find($this->messagesBlock)); } + public function getModalBlock() + { + return Factory::getBlockFactory()->getMagentoUiAdminhtmlModal($this->browser->find('.modal-inner-wrap')); + } + /** * Wait for Header block is visible in the page. * @@ -106,20 +111,6 @@ function () use ($browser, $selector) { public function dismissAdminUsageNotification() { - $browser = $this->browser; - $selector = $this->adminUsageSelector; - $browser->waitUntil( - function () use ($browser, $selector) { - $item = $browser->find($selector); - if ($item->isVisible()) { - return true; - } - usleep(200000); - return true; - } - ); - if ($this->browser->find($selector)->isVisible()) { - $this->browser->find($selector)->click(); - } + $this->getModalBlock()->dismissIfModalAppears(); } } diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php index 5c27776c09620..eb949dccb7ffc 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php @@ -163,6 +163,30 @@ function () { ); } + /** + * Dismiss the modal if it appears + * + * @return void + */ + public function dismissIfModalAppears() + { + $browser = $this->browser; + $selector = $this->dismissWarningSelector; + $browser->waitUntil( + function () use ($browser, $selector) { + $item = $browser->find($selector); + if ($item->isVisible()) { + return true; + } + $this->waitModalAnimationFinished(); + return true; + } + ); + if ($this->browser->find($selector)->isVisible()) { + $this->browser->find($selector)->click(); + } + } + /** * Waiting until CSS animation is done. * Transition-duration is set at this file: "<magento_root>/lib/web/css/source/components/_modals.less" diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php index 58450abc71633..c7031e9fccbeb 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php @@ -102,6 +102,8 @@ public function testUpdateAdminUserRolesEntity( $this->adminAuthLogin->open(); $this->adminAuthLogin->getLoginBlock()->fill($user); $this->adminAuthLogin->getLoginBlock()->submit(); + $this->adminAuthLogin->waitForHeaderBlock(); + $this->adminAuthLogin->dismissAdminUsageNotification(); $this->rolePage->open(); $this->rolePage->getRoleGrid()->searchAndOpen($filter); $this->userRoleEditRole->getRoleFormTabs()->fill($role); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php index c244e27d42899..93e5002a34d1b 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php @@ -119,6 +119,8 @@ private function login() { $this->adminAuth->getLoginBlock()->fill($this->user); $this->adminAuth->getLoginBlock()->submit(); + $this->adminAuthLogin->waitForHeaderBlock(); + $this->adminAuthLogin->dismissAdminUsageNotification(); $this->adminAuth->getLoginBlock()->waitFormNotVisible(); } } From c191c7efe133bc5e616e7fdeafb21de8780b519b Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 14:26:33 -0500 Subject: [PATCH 267/372] MC-15298: Allow admin to opt out of admin analytics tracking - made disableAdminUsage, enableAdminUsage, markUserNotified public functions --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 4 ++-- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index d0e5cff85d9a4..d5205f27f6ac2 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -66,7 +66,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - private function disableAdminUsage() + public function disableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 0); @@ -78,7 +78,7 @@ private function disableAdminUsage() * * @return ResultInterface */ - private function markUserNotified() : ResultInterface + public function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index be2a8ce1d3ca3..963954d917b4f 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -65,7 +65,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - private function enableAdminUsage() + public function enableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 1); @@ -77,7 +77,7 @@ private function enableAdminUsage() * * @return ResultInterface */ - private function markUserNotified() : ResultInterface + public function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( From 7d36b8b02fbdf648d97c9fa1ba8ba332ea715785 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 16:35:22 -0500 Subject: [PATCH 268/372] MC-15298: Allow admin to opt out of admin analytics tracking - added declare(strict_types=1) --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 1 + .../Controller/Adminhtml/Config/EnableAdminUsage.php | 1 + .../AdminAnalytics/Model/Condition/CanViewNotification.php | 2 ++ app/code/Magento/AdminAnalytics/Model/Viewer/Log.php | 2 ++ 4 files changed, 6 insertions(+) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index d5205f27f6ac2..3bd5fe8afbebf 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 963954d917b4f..ed55f8556df30 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 76591ffe5cc10..03b99f404e01e 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\AdminAnalytics\Model\Condition; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php index e97b8f94e12ba..cd29783113d03 100644 --- a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\AdminAnalytics\Model\Viewer; use Magento\Framework\DataObject; From 28eeac6307821addd475798aa73a2383554b367d Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 17:04:40 -0500 Subject: [PATCH 269/372] MC-17593: handle mtf and mftf failures - changed test files --- .../Magento/Backend/Test/Page/AdminAuthLogin.php | 15 +++++++++++++-- .../Test/TestCase/DeleteAdminUserEntityTest.php | 2 ++ .../Test/TestCase/DeleteUserRoleEntityTest.php | 2 ++ .../User/Test/TestCase/UnlockAdminUserTest.php | 2 ++ .../Test/TestCase/UpdateAdminUserEntityTest.php | 2 ++ .../User/Test/TestStep/LoginUserOnBackendStep.php | 4 ++-- 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index b9c6140971409..4b72bb836523a 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -80,16 +80,22 @@ public function getHeaderBlock() /** * Get global messages block. * - * @return \Magento\Backend\Test\Block\Messages + * @return \Magento\Ui\Test\Block\Adminhtml\Modal + */ public function getMessagesBlock() { return Factory::getBlockFactory()->getMagentoBackendMessages($this->browser->find($this->messagesBlock)); } + /** + * Get modal block + * + * @return void + */ public function getModalBlock() { - return Factory::getBlockFactory()->getMagentoUiAdminhtmlModal($this->browser->find('.modal-inner-wrap')); + return Factory::getBlockFactory()->getMagentoUiAdminhtmlModal($this->browser->find($this->adminUsageSelector)); } /** @@ -109,6 +115,11 @@ function () use ($browser, $selector) { ); } + /** + * Dismiss admin usage notification + * + * @return void + */ public function dismissAdminUsageNotification() { $this->getModalBlock()->dismissIfModalAppears(); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php index 42914cd697bfd..81d9fe8393aee 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php @@ -117,6 +117,8 @@ public function testDeleteAdminUserEntity( $this->adminAuthLogin->open(); $this->adminAuthLogin->getLoginBlock()->fill($user); $this->adminAuthLogin->getLoginBlock()->submit(); + $this->adminAuthLogin->waitForHeaderBlock(); + $this->adminAuthLogin->dismissAdminUsageNotification(); } $this->userIndex->open(); $this->userIndex->getUserGrid()->searchAndOpen($filter); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php index 47c5a4095830d..2a1c9feb440b9 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php @@ -117,6 +117,8 @@ public function testDeleteAdminUserRole( $this->adminAuthLogin->open(); $this->adminAuthLogin->getLoginBlock()->fill($adminUser); $this->adminAuthLogin->getLoginBlock()->submit(); + $this->adminAuthLogin->waitForHeaderBlock(); + $this->adminAuthLogin->dismissAdminUsageNotification(); } $this->userRoleIndex->open(); $this->userRoleIndex->getRoleGrid()->searchAndOpen($filter); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php index 6a43be4afd422..8db927ccda29b 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php @@ -124,6 +124,8 @@ public function test( $this->adminAuth->open(); $this->adminAuth->getLoginBlock()->fill($incorrectUser); $this->adminAuth->getLoginBlock()->submit(); + $this->adminAuth->waitForHeaderBlock(); + $this->adminAuth->dismissAdminUsageNotification(); } // Test steps diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php index e8869de13462a..dab4cec22c86d 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php @@ -147,6 +147,8 @@ public function testUpdateAdminUser( $this->adminAuth->open(); $this->adminAuth->getLoginBlock()->fill($initialUser); $this->adminAuth->getLoginBlock()->submit(); + $this->adminAuth->waitForHeaderBlock(); + $this->adminAuth->dismissAdminUsageNotification(); } $this->userIndex->open(); $this->userIndex->getUserGrid()->searchAndOpen($filter); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php index 93e5002a34d1b..3e2a3a3d59fc1 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php @@ -119,8 +119,8 @@ private function login() { $this->adminAuth->getLoginBlock()->fill($this->user); $this->adminAuth->getLoginBlock()->submit(); - $this->adminAuthLogin->waitForHeaderBlock(); - $this->adminAuthLogin->dismissAdminUsageNotification(); + $this->adminAuth->waitForHeaderBlock(); + $this->adminAuth->dismissAdminUsageNotification(); $this->adminAuth->getLoginBlock()->waitFormNotVisible(); } } From 94a8f6d69c448f50aacdfb5e08ed89dd2f3e5663 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Tue, 6 Aug 2019 23:02:10 -0500 Subject: [PATCH 270/372] MC-15298: Allow admin to opt out of admin analytics tracking - MTf fix --- .../app/Magento/User/Test/TestCase/UnlockAdminUserTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php index 8db927ccda29b..6a43be4afd422 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php @@ -124,8 +124,6 @@ public function test( $this->adminAuth->open(); $this->adminAuth->getLoginBlock()->fill($incorrectUser); $this->adminAuth->getLoginBlock()->submit(); - $this->adminAuth->waitForHeaderBlock(); - $this->adminAuth->dismissAdminUsageNotification(); } // Test steps From b9855cb6675d9841fb2221510f7c3a83a92147ef Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 7 Aug 2019 10:07:47 -0500 Subject: [PATCH 271/372] MC-15298: Allow admin to opt out of admin analytics tracking - deleted unused files --- .../Model/ContentProviderInterface.php | 24 ------ .../adminhtml/templates/confirm_popup.phtml | 81 ------------------- 2 files changed, 105 deletions(-) delete mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php delete mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php b/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php deleted file mode 100644 index ea67be7019e19..0000000000000 --- a/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Model; - -/** - * Requests the release notification content data from a defined service - */ -interface ContentProviderInterface -{ - /** - * Retrieves the release notification content data. - * - * @param string $version - * @param string $edition - * @param string $locale - * - * @return string|false - */ - public function getContent($version, $edition, $locale); -} diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml deleted file mode 100644 index ddd9b7acf03dd..0000000000000 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -?> - -<div class="confirmation-modal-content"> - <p>Help us improve Magento Admin by allowing us to collect usage data.</p> - <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> - <p>You can learn more and opt out at any time by following the instructions in <a href="https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html" target="_blank">merchant documentation</a></p> -</div> - -<script> - require([ - 'jquery', - 'Magento_Ui/js/modal/modal' - ], function ($) { - 'use strict'; - - $('.confirmation-modal-content').modal({ - imports: { - logAction: '${ $.provider }:data.logAction' - }, - title: 'Allow admin usage data collection', - autoOpen: true, - type: 'popup', - clickableOverlay: false, - responsive: true, - keyEventHandlers: { - escapeKey: function(){} - }, - opened: function($Event){ - $('.modal-header button.action-close', $Event.srcElement).hide(); - }, - buttons: [ - { - text: $.mage.__(`Don't Allow`), - class: 'action', - click: function(){ - var data = { - 'form_key': window.FORM_KEY - }; - $.ajax({ - type: 'POST', - url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', - data: data, - showLoader: true - }).done(function (xhr) { - if (xhr.error) { - self.onError(xhr); - } - }).fail(this.onError); - this.closeModal(); - }, - }, - { - text: $.mage.__('Ok'), - class: 'action', - click: function(){ - var data = { - 'form_key': window.FORM_KEY - }; - $.ajax({ - type: 'POST', - url: '/magento2ce/admin_michell/adminAnalytics/config/enableAdminUsage', - data: data, - showLoader: true - }).done(function (xhr) { - if (xhr.error) { - self.onError(xhr); - } - }).fail(this.onError); - - this.closeModal(); - }, - } - ], - }); - }); -</script> From 7b0b55a021c30d2af52b784b4022f689081e8d0c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 7 Aug 2019 12:28:43 -0500 Subject: [PATCH 272/372] MC-15298: Allow admin to opt out of admin analytics tracking - edited files based on review --- .../{ViewModel => Block}/Notification.php | 21 +- .../Adminhtml/Config/DisableAdminUsage.php | 8 +- .../Adminhtml/Config/EnableAdminUsage.php | 8 +- .../Model/Condition/CanViewNotification.php | 9 +- .../Model/ResourceModel/Viewer/Logger.php | 9 +- .../AdminAnalytics/Model/Viewer/Log.php | 2 +- .../AdminUsageNotificationDataProvider.php | 184 +----------------- .../Magento/AdminAnalytics/etc/db_schema.xml | 2 +- .../layout/adminhtml_dashboard_index.xml | 2 +- 9 files changed, 36 insertions(+), 209 deletions(-) rename app/code/Magento/AdminAnalytics/{ViewModel => Block}/Notification.php (57%) diff --git a/app/code/Magento/AdminAnalytics/ViewModel/Notification.php b/app/code/Magento/AdminAnalytics/Block/Notification.php similarity index 57% rename from app/code/Magento/AdminAnalytics/ViewModel/Notification.php rename to app/code/Magento/AdminAnalytics/Block/Notification.php index 5b4a51c5b6539..7988e2139a3d3 100644 --- a/app/code/Magento/AdminAnalytics/ViewModel/Notification.php +++ b/app/code/Magento/AdminAnalytics/Block/Notification.php @@ -3,32 +3,37 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); -namespace Magento\AdminAnalytics\ViewModel; +namespace Magento\AdminAnalytics\Block; + +use Magento\Framework\View\Element\Block\ArgumentInterface; +use Magento\AdminAnalytics\Model\Condition\CanViewNotification as AdminAnalyticsNotification; +use Magento\ReleaseNotification\Model\Condition\CanViewNotification as ReleaseNotification; /** * Class Notification */ -class Notification implements \Magento\Framework\View\Element\Block\ArgumentInterface +class Notification implements ArgumentInterface { /** - * @var \Magento\AdminAnalytics\Model\Condition\CanViewNotification + * @var AdminAnalyticsNotification */ private $canViewNotificationAnalytics; /** - * @var \Magento\ReleaseNotification\Model\Condition\CanViewNotification + * @var ReleaseNotification */ private $canViewNotificationRelease; /** * Notification constructor. - * @param \Magento\AdminAnalytics\Model\Condition\CanViewNotification $canViewNotificationAnalytics - * @param \Magento\ReleaseNotification\Model\Condition\CanViewNotification $canViewNotificationRelease + * @param AdminAnalyticsNotification $canViewNotificationAnalytics + * @param ReleaseNotification $canViewNotificationRelease */ public function __construct( - \Magento\AdminAnalytics\Model\Condition\CanViewNotification $canViewNotificationAnalytics, - \Magento\ReleaseNotification\Model\Condition\CanViewNotification $canViewNotificationRelease + AdminAnalyticsNotification $canViewNotificationAnalytics, + ReleaseNotification $canViewNotificationRelease ) { $this->canViewNotificationAnalytics = $canViewNotificationAnalytics; $this->canViewNotificationRelease = $canViewNotificationRelease; diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 3bd5fe8afbebf..29a9479d72a96 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -8,7 +8,7 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; -use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; @@ -67,7 +67,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - public function disableAdminUsage() + private function disableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 0); @@ -79,7 +79,7 @@ public function disableAdminUsage() * * @return ResultInterface */ - public function markUserNotified() : ResultInterface + private function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( @@ -108,7 +108,7 @@ public function execute() * * @return bool */ - public function _isAllowed() + protected function _isAllowed() { $isAllowed = parent::_isAllowed(); return $isAllowed; diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index ed55f8556df30..35113d4a6b737 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -8,7 +8,7 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; -use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; @@ -66,7 +66,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - public function enableAdminUsage() + private function enableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 1); @@ -78,7 +78,7 @@ public function enableAdminUsage() * * @return ResultInterface */ - public function markUserNotified() : ResultInterface + private function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( @@ -107,7 +107,7 @@ public function execute() * * @return bool */ - public function _isAllowed() + protected function _isAllowed() { $isAllowed = parent::_isAllowed(); return $isAllowed; diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 03b99f404e01e..1012f205d6bf3 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -10,7 +10,6 @@ use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; use Magento\Framework\View\Layout\Condition\VisibilityConditionInterface; use Magento\Framework\App\CacheInterface; -use function Magento\PAT\Reports\Utils\readResponseTimeReport; /** * Dynamic validator for UI admin analytics notification, manage UI component visibility. @@ -42,8 +41,6 @@ class CanViewNotification implements VisibilityConditionInterface private $cacheStorage; /** - * CanViewNotification constructor. - * * @param Logger $viewerLogger * @param CacheInterface $cacheStorage */ @@ -58,10 +55,10 @@ public function __construct( /** * Validate if notification popup can be shown and set the notification flag * - * @param array $arguments Attributes from element node. + * @param array $arguments Attributes from element node. * @inheritdoc */ - public function isVisible(array $arguments) + public function isVisible(array $arguments): bool { $cacheKey = self::$cachePrefix; $value = $this->cacheStorage->load($cacheKey); @@ -80,7 +77,7 @@ public function isVisible(array $arguments) * * @return string */ - public function getName() + public function getName(): string { return self::$conditionName; } diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 38fdd2afed7a7..b185e263f4801 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -74,7 +74,7 @@ public function log(string $lastViewVersion) : bool */ public function get() : Log { - return $this->logFactory->create(['data' => $this->loadLogData()]); + return $this->logFactory->create(['data' => $this->loadLatestLogData()]); } /** @@ -84,7 +84,7 @@ public function get() : Log */ public function checkLogExists() : bool { - $data = $this->logFactory->create(['data' => $this->loadLogData()]); + $data = $this->logFactory->create(['data' => $this->loadLatestLogData()]); $lastViewedVersion = $data->getLastViewVersion(); return isset($lastViewedVersion); } @@ -94,11 +94,12 @@ public function checkLogExists() : bool * * @return array */ - private function loadLogData() : array + private function loadLatestLogData() : array { $connection = $this->resource->getConnection(); $select = $connection->select() - ->from($this->resource->getTableName(self::LOG_TABLE_NAME)) + ->from(['log_table' => $this->resource->getTableName(self::LOG_TABLE_NAME)]) + ->order('log_table.id desc') ->limit(['count' => 1]); $data = $connection->fetchRow($select); diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php index cd29783113d03..0c3b6b81ec811 100644 --- a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -19,7 +19,7 @@ class Log extends DataObject * * @return int */ - public function getId() : int + public function getId() : ?int { return $this->getData('id'); } diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php index 5e8bc2d9160d4..961a5663730a2 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php @@ -6,81 +6,14 @@ namespace Magento\AdminAnalytics\Ui\DataProvider; -use Magento\Framework\Api\Search\SearchCriteriaInterface; -use Magento\Framework\Api\Search\SearchResultInterface; -use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; -use Magento\Ui\DataProvider\Modifier\ModifierInterface; -use Magento\Ui\DataProvider\Modifier\PoolInterface; +use Magento\Ui\DataProvider\AbstractDataProvider; +use Magento\Framework\Api\Filter; /** * Data Provider for the Admin usage UI component. */ -class AdminUsageNotificationDataProvider implements DataProviderInterface +class AdminUsageNotificationDataProvider extends AbstractDataProvider { - /** - * @var PoolInterface - */ - private $pool; - - /** - * Search result object. - * - * @var SearchResultInterface - */ - private $searchResult; - - /** - * Search criteria object. - * - * @var SearchCriteriaInterface - */ - private $searchCriteria; - - /** - * Own name of this provider. - * - * @var string - */ - private $name; - - /** - * Provider configuration data. - * - * @var array - */ - private $data; - - /** - * Provider configuration meta. - * - * @var array - */ - private $meta; - - /** - * @param string $name - * @param SearchResultInterface $searchResult - * @param SearchCriteriaInterface $searchCriteria - * @param PoolInterface $pool - * @param array $meta - * @param array $data - */ - public function __construct( - $name, - SearchResultInterface $searchResult, - SearchCriteriaInterface $searchCriteria, - PoolInterface $pool, - array $meta = [], - array $data = [] - ) { - $this->name = $name; - $this->searchResult = $searchResult; - $this->searchCriteria = $searchCriteria; - $this->pool = $pool; - $this->meta = $meta; - $this->data = $data; - } - /** * @inheritdoc */ @@ -92,117 +25,8 @@ public function getData() /** * @inheritdoc */ - public function getMeta() - { - return $this->meta; - } - - /** - * @inheritdoc - */ - public function getName() - { - return $this->name; - } - - /** - * @inheritdoc - */ - public function getConfigData() - { - return $this->data['config'] ?? []; - } - - /** - * @inheritdoc - */ - public function setConfigData($config) - { - $this->data['config'] = $config; - - return true; - } - - /** - * @inheritdoc - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function getFieldMetaInfo($fieldSetName, $fieldName) - { - return []; - } - - /** - * @inheritdoc - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function getFieldSetMetaInfo($fieldSetName) - { - return []; - } - - /** - * @inheritdoc - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function getFieldsMetaInfo($fieldSetName) - { - return []; - } - - /** - * @inheritdoc - */ - public function getPrimaryFieldName() - { - return 'admin_analytics'; - } - - /** - * @inheritdoc - */ - public function getRequestFieldName() - { - return 'admin_analytics'; - } - - /** - * @inheritdoc - */ - public function addFilter(\Magento\Framework\Api\Filter $filter) + public function addFilter(Filter $filter) { return null; } - - /** - * @inheritdoc - */ - public function addOrder($field, $direction) - { - return null; - } - - /** - * @inheritdoc - */ - public function setLimit($offset, $size) - { - return null; - } - - /** - * @inheritdoc - */ - public function getSearchCriteria() - { - return $this->searchCriteria; - } - - /** - * @inheritdoc - */ - public function getSearchResult() - { - return $this->searchResult; - } } diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema.xml b/app/code/Magento/AdminAnalytics/etc/db_schema.xml index b9607ce77d150..ef1a657dc8243 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema.xml +++ b/app/code/Magento/AdminAnalytics/etc/db_schema.xml @@ -20,4 +20,4 @@ <column name="last_viewed_in_version"/> </constraint> </table> -</schema> \ No newline at end of file +</schema> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml index 3069db1ecc2bb..829c5ed3f8103 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml @@ -14,7 +14,7 @@ </uiComponent> <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> <arguments> - <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> + <argument name="notification" xsi:type="object">Magento\AdminAnalytics\Block\Notification</argument> </arguments> </block> </referenceContainer> From 6b5c503e5e1795dde824707f951dd3ea1c7fddb4 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Wed, 7 Aug 2019 13:32:53 -0500 Subject: [PATCH 273/372] MC-15298: Allow admin to opt out of admin analytics tracking - static and health fix --- .../Adminhtml/Config/DisableAdminUsage.php | 16 ++++--------- .../Adminhtml/Config/EnableAdminUsage.php | 16 ++++--------- composer.lock | 23 +++++++++---------- 3 files changed, 21 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 29a9479d72a96..01790b4a417d1 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -41,6 +41,11 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface */ private $logger; + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Backend::admin'; + /** * DisableAdminUsage constructor. * @@ -102,15 +107,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * Checks if DisableAdminUsage is allowed - * - * @return bool - */ - protected function _isAllowed() - { - $isAllowed = parent::_isAllowed(); - return $isAllowed; - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 35113d4a6b737..d61f69e484fdd 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -40,6 +40,11 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface */ private $logger; + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Backend::admin'; + /** * MarkUserNotified constructor. * @@ -101,15 +106,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * Checks if EnableAdminUsage is allowed - * - * @return bool - */ - protected function _isAllowed() - { - $isAllowed = parent::_isAllowed(); - return $isAllowed; - } } diff --git a/composer.lock b/composer.lock index 768b9fec82f28..675848c495915 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - - "content-hash": "a4299e3f4f0d4dd4915f37a5dde8e2ed", + "content-hash": "b5c5eeedfc8a724202af911b637f7b16", "packages": [ { "name": "braintree/braintree_php", @@ -1553,28 +1552,28 @@ "authors": [ { "name": "Jim Wigginton", - "role": "Lead Developer", - "email": "terrafrost@php.net" + "email": "terrafrost@php.net", + "role": "Lead Developer" }, { "name": "Patrick Monnerat", - "role": "Developer", - "email": "pm@datasphere.ch" + "email": "pm@datasphere.ch", + "role": "Developer" }, { "name": "Andreas Fischer", - "role": "Developer", - "email": "bantu@phpbb.com" + "email": "bantu@phpbb.com", + "role": "Developer" }, { "name": "Hans-Jürgen Petrich", - "role": "Developer", - "email": "petrich@tronic-media.com" + "email": "petrich@tronic-media.com", + "role": "Developer" }, { "name": "Graham Campbell", - "role": "Developer", - "email": "graham@alt-three.com" + "email": "graham@alt-three.com", + "role": "Developer" } ], "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", From 7ebf19be1f1bf6c9814c42df09cbb1c83ceff25f Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Wed, 7 Aug 2019 13:35:34 -0500 Subject: [PATCH 274/372] MC-15298: Allow admin to opt out of admin analytics tracking - static and health fix --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 10 +++++----- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 01790b4a417d1..48937c3019caf 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -21,6 +21,11 @@ */ class DisableAdminUsage extends Action implements HttpPostActionInterface { + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Backend::admin'; + /** * @var Factory */ @@ -41,11 +46,6 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface */ private $logger; - /** - * Authorization level of a basic admin session - */ - const ADMIN_RESOURCE = 'Magento_Backend::admin'; - /** * DisableAdminUsage constructor. * diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index d61f69e484fdd..9d16a789a2aa4 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -21,6 +21,11 @@ */ class EnableAdminUsage extends Action implements HttpPostActionInterface { + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Backend::admin'; + /** * @var Factory */ @@ -40,11 +45,6 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface */ private $logger; - /** - * Authorization level of a basic admin session - */ - const ADMIN_RESOURCE = 'Magento_Backend::admin'; - /** * MarkUserNotified constructor. * From 70c27d391c1aa9b5aa031f2309bf1ad919aceb5f Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 7 Aug 2019 14:46:13 -0500 Subject: [PATCH 275/372] MC-15298: Allow admin to opt out of admin analytics tracking - added protected isAllowed --- .../Adminhtml/Config/DisableAdminUsage.php | 24 +++++++----------- .../Adminhtml/Config/EnableAdminUsage.php | 25 ++++++++----------- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 48937c3019caf..13a13e8d24036 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -13,7 +13,6 @@ use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Controller\ResultInterface; -use Psr\Log\LoggerInterface; use Magento\Config\Model\Config\Factory; /** @@ -21,11 +20,6 @@ */ class DisableAdminUsage extends Action implements HttpPostActionInterface { - /** - * Authorization level of a basic admin session - */ - const ADMIN_RESOURCE = 'Magento_Backend::admin'; - /** * @var Factory */ @@ -41,11 +35,6 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface */ private $notificationLogger; - /** - * @var LoggerInterface - */ - private $logger; - /** * DisableAdminUsage constructor. * @@ -53,20 +42,17 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface * @param ProductMetadataInterface $productMetadata * @param NotificationLogger $notificationLogger * @param Factory $configFactory - * @param LoggerInterface $logger */ public function __construct( Action\Context $context, ProductMetadataInterface $productMetadata, NotificationLogger $notificationLogger, - Factory $configFactory, - LoggerInterface $logger + Factory $configFactory ) { parent::__construct($context); $this->configFactory = $configFactory; $this->productMetadata = $productMetadata; $this->notificationLogger = $notificationLogger; - $this->logger = $logger; } /** @@ -107,4 +93,12 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * @inheritDoc + */ + protected function _isAllowed() + { + return $this->_authorization->isAllowed(static::ADMIN_RESOURCE); + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 9d16a789a2aa4..aee300c2f6e84 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -13,7 +13,6 @@ use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Controller\ResultInterface; -use Psr\Log\LoggerInterface; use Magento\Config\Model\Config\Factory; /** @@ -21,15 +20,11 @@ */ class EnableAdminUsage extends Action implements HttpPostActionInterface { - /** - * Authorization level of a basic admin session - */ - const ADMIN_RESOURCE = 'Magento_Backend::admin'; - /** * @var Factory */ private $configFactory; + /** * @var ProductMetadataInterface */ @@ -40,11 +35,6 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface */ private $notificationLogger; - /** - * @var LoggerInterface - */ - private $logger; - /** * MarkUserNotified constructor. * @@ -52,20 +42,17 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface * @param ProductMetadataInterface $productMetadata * @param NotificationLogger $notificationLogger * @param Factory $configFactory - * @param LoggerInterface $logger */ public function __construct( Action\Context $context, ProductMetadataInterface $productMetadata, NotificationLogger $notificationLogger, - Factory $configFactory, - LoggerInterface $logger + Factory $configFactory ) { parent::__construct($context); $this->configFactory = $configFactory; $this->productMetadata = $productMetadata; $this->notificationLogger = $notificationLogger; - $this->logger = $logger; } /** @@ -106,4 +93,12 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * @inheritDoc + */ + protected function _isAllowed() + { + return $this->_authorization->isAllowed(static::ADMIN_RESOURCE); + } } From ba2390fe8b468a757fb9e4c8465d0f8577d4deda Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 8 Aug 2019 09:06:35 -0500 Subject: [PATCH 276/372] MC-15298: Allow admin to opt out of admin analytics tracking - added config, rm packaged-lock --- .../LoginAdminWithCredentialsActionGroup.xml | 14 + .../ActionGroup/LoginAsAdminActionGroup.xml | 14 + .../Magento/AdminAnalytics/etc/config.xml | 18 + .../LoginAdminWithCredentialsActionGroup.xml | 1 - .../ActionGroup/LoginAsAdminActionGroup.xml | 1 - package-lock.json | 861 ------------------ 6 files changed, 46 insertions(+), 863 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml delete mode 100644 package-lock.json diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml new file mode 100644 index 0000000000000..d9f5e5dbcb106 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="LoginAdminWithCredentialsActionGroup"> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible" before="closeAdminNotification"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml new file mode 100644 index 0000000000000..5cf7be8a6fe11 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="LoginAsAdmin"> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible" before="closeAdminNotification"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml new file mode 100644 index 0000000000000..ba683f13c11e3 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/config.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + <default> + <admin> + <usage> + <enabled> + 1 + </enabled> + </usage> + </admin> + </default> +</config> \ No newline at end of file diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml index e423c68dd938b..6aaa612b249b6 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml @@ -17,7 +17,6 @@ <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminPassword}}" stepKey="fillPassword"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml index 9c1963119d381..b2fbadcbe38e2 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml @@ -16,7 +16,6 @@ <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser.username}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminUser.password}}" stepKey="fillPassword"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> </actionGroups> diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index b3e14ddab5aa6..0000000000000 --- a/package-lock.json +++ /dev/null @@ -1,861 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" - }, - "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==" - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" - } - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz", - "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^6.0.0", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - } - }, - "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz", - "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==", - "requires": { - "eslint-visitor-keys": "^1.0.0" - } - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" - }, - "espree": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz", - "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==", - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "requires": { - "flat-cache": "^2.0.1" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - }, - "import-fresh": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", - "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "inquirer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", - "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "requires": { - "glob": "^7.1.3" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "requires": { - "is-promise": "^2.1.0" - } - }, - "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", - "requires": { - "tslib": "^1.9.0" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - } - } - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.5.tgz", - "integrity": "sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA==", - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "v8-compile-cache": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", - "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "requires": { - "mkdirp": "^0.5.1" - } - } - } -} From 3b0d7b7ef25e854fba0f437b5ce18b84fb51aa5f Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 8 Aug 2019 10:46:39 -0500 Subject: [PATCH 277/372] MC-15298: Allow admin to opt out of admin analytics tracking - Updated files based on review --- app/code/Magento/AdminAnalytics/Block/Metadata.php | 4 ++-- .../Magento/AdminAnalytics/Block/Notification.php | 1 - .../Adminhtml/Config/DisableAdminUsage.php | 10 +++++----- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 12 +++++------- .../Model/Condition/CanViewNotification.php | 4 ++-- .../Model/ResourceModel/Viewer/Logger.php | 8 ++++---- app/code/Magento/AdminAnalytics/README.md | 2 +- .../Test/Mftf/Section/AdminUsageConfigSection.xml | 1 - 8 files changed, 19 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Block/Metadata.php b/app/code/Magento/AdminAnalytics/Block/Metadata.php index 2a669829a8211..30a911d996f50 100644 --- a/app/code/Magento/AdminAnalytics/Block/Metadata.php +++ b/app/code/Magento/AdminAnalytics/Block/Metadata.php @@ -5,8 +5,8 @@ */ namespace Magento\AdminAnalytics\Block; -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context; +use Magento\Backend\Block\Template; +use Magento\Backend\Block\Template\Context; use Magento\Framework\App\ProductMetadataInterface; use Magento\Backend\Model\Auth\Session; use Magento\Framework\App\State; diff --git a/app/code/Magento/AdminAnalytics/Block/Notification.php b/app/code/Magento/AdminAnalytics/Block/Notification.php index 7988e2139a3d3..1b4314e585b74 100644 --- a/app/code/Magento/AdminAnalytics/Block/Notification.php +++ b/app/code/Magento/AdminAnalytics/Block/Notification.php @@ -27,7 +27,6 @@ class Notification implements ArgumentInterface private $canViewNotificationRelease; /** - * Notification constructor. * @param AdminAnalyticsNotification $canViewNotificationAnalytics * @param ReleaseNotification $canViewNotificationRelease */ diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 13a13e8d24036..34a9ef4f75b98 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -38,10 +38,10 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface /** * DisableAdminUsage constructor. * - * @param Action\Context $context + * @param Action\Context $context * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param Factory $configFactory + * @param NotificationLogger $notificationLogger + * @param Factory $configFactory */ public function __construct( Action\Context $context, @@ -56,7 +56,7 @@ public function __construct( } /** - * Changes the value of config/admin/usage/enabled + * Change the value of config/admin/usage/enabled */ private function disableAdminUsage() { @@ -70,7 +70,7 @@ private function disableAdminUsage() * * @return ResultInterface */ - private function markUserNotified() : ResultInterface + private function markUserNotified(): ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index aee300c2f6e84..f70dd57aa59d6 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -36,12 +36,10 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface private $notificationLogger; /** - * MarkUserNotified constructor. - * - * @param Action\Context $context + * @param Action\Context $context * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param Factory $configFactory + * @param NotificationLogger $notificationLogger + * @param Factory $configFactory */ public function __construct( Action\Context $context, @@ -56,7 +54,7 @@ public function __construct( } /** - * Changes the value of config/admin/usage/enabled + * Change the value of config/admin/usage/enabled */ private function enableAdminUsage() { @@ -70,7 +68,7 @@ private function enableAdminUsage() * * @return ResultInterface */ - private function markUserNotified() : ResultInterface + private function markUserNotified(): ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 1012f205d6bf3..222261d4abfb5 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -12,7 +12,7 @@ use Magento\Framework\App\CacheInterface; /** - * Dynamic validator for UI admin analytics notification, manage UI component visibility. + * Dynamic validator for UI admin analytics notification, control UI component visibility. */ class CanViewNotification implements VisibilityConditionInterface { @@ -41,7 +41,7 @@ class CanViewNotification implements VisibilityConditionInterface private $cacheStorage; /** - * @param Logger $viewerLogger + * @param Logger $viewerLogger * @param CacheInterface $cacheStorage */ public function __construct( diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index b185e263f4801..5c225ebfeceb5 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -51,7 +51,7 @@ public function __construct( * @param string $lastViewVersion * @return bool */ - public function log(string $lastViewVersion) : bool + public function log(string $lastViewVersion): bool { /** @var \Magento\Framework\DB\Adapter\AdapterInterface $connection */ $connection = $this->resource->getConnection(ResourceConnection::DEFAULT_CONNECTION); @@ -72,7 +72,7 @@ public function log(string $lastViewVersion) : bool * * @return Log */ - public function get() : Log + public function get(): Log { return $this->logFactory->create(['data' => $this->loadLatestLogData()]); } @@ -82,7 +82,7 @@ public function get() : Log * * @return boolean */ - public function checkLogExists() : bool + public function checkLogExists(): bool { $data = $this->logFactory->create(['data' => $this->loadLatestLogData()]); $lastViewedVersion = $data->getLastViewVersion(); @@ -94,7 +94,7 @@ public function checkLogExists() : bool * * @return array */ - private function loadLatestLogData() : array + private function loadLatestLogData(): array { $connection = $this->resource->getConnection(); $select = $connection->select() diff --git a/app/code/Magento/AdminAnalytics/README.md b/app/code/Magento/AdminAnalytics/README.md index 1280e0fcef10f..1aaf204ba04bb 100644 --- a/app/code/Magento/AdminAnalytics/README.md +++ b/app/code/Magento/AdminAnalytics/README.md @@ -1 +1 @@ -The purpose of Magento\AdminAnalytics module is gather information on which features the users uses and sends it to adobe analytics \ No newline at end of file +The purpose of Magento\AdminAnalytics module is to gather information on which features the admins use, to help improve Magento admin experience. \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml index ddb89f0bfb72c..634ebf855d940 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml @@ -9,7 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminUsageConfigSection"> - <element name="adminUsageHeader" type="text" selector="#admin_usage-head"/> <element name="adminUsageOptions" type="select" selector="#admin_usage_enabled"/> </section> From f96b7aed68d649bdd03293620d4ef0f2948e62cc Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 8 Aug 2019 11:00:49 -0500 Subject: [PATCH 278/372] MC-15298: Allow admin to opt out of admin analytics tracking - Updated README --- app/code/Magento/AdminAnalytics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/README.md b/app/code/Magento/AdminAnalytics/README.md index 1aaf204ba04bb..e905344031ad3 100644 --- a/app/code/Magento/AdminAnalytics/README.md +++ b/app/code/Magento/AdminAnalytics/README.md @@ -1 +1 @@ -The purpose of Magento\AdminAnalytics module is to gather information on which features the admins use, to help improve Magento admin experience. \ No newline at end of file +The Magento\AdminAnalytics module gathers information about the features Magento administrators use. This information will be used to help improve the user experience on the Magento Admin. \ No newline at end of file From e70e30484b746b316575014d0727fbe092a9bec3 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 8 Aug 2019 14:37:42 -0500 Subject: [PATCH 279/372] MC-15298: Allow admin to opt out of admin analytics tracking - removed config --- app/code/Magento/AdminAnalytics/etc/config.xml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml deleted file mode 100644 index ba683f13c11e3..0000000000000 --- a/app/code/Magento/AdminAnalytics/etc/config.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> - <default> - <admin> - <usage> - <enabled> - 1 - </enabled> - </usage> - </admin> - </default> -</config> \ No newline at end of file From 912f8c5a963383655584a074c7d7c0cf1a9057bc Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 8 Aug 2019 16:24:59 -0500 Subject: [PATCH 280/372] MC-15298: Allow admin to opt out of admin analytics tracking --- .../{Block => ViewModel}/Metadata.php | 16 ++++------------ .../{Block => ViewModel}/Notification.php | 4 ++-- .../layout/adminhtml_dashboard_index.xml | 2 +- .../view/adminhtml/layout/default.xml | 3 ++- .../view/adminhtml/templates/tracking.phtml | 6 +++--- 5 files changed, 12 insertions(+), 19 deletions(-) rename app/code/Magento/AdminAnalytics/{Block => ViewModel}/Metadata.php (81%) rename app/code/Magento/AdminAnalytics/{Block => ViewModel}/Notification.php (93%) diff --git a/app/code/Magento/AdminAnalytics/Block/Metadata.php b/app/code/Magento/AdminAnalytics/ViewModel/Metadata.php similarity index 81% rename from app/code/Magento/AdminAnalytics/Block/Metadata.php rename to app/code/Magento/AdminAnalytics/ViewModel/Metadata.php index 30a911d996f50..9b1accbe0c823 100644 --- a/app/code/Magento/AdminAnalytics/Block/Metadata.php +++ b/app/code/Magento/AdminAnalytics/ViewModel/Metadata.php @@ -3,20 +3,17 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\AdminAnalytics\Block; +namespace Magento\AdminAnalytics\ViewModel; -use Magento\Backend\Block\Template; -use Magento\Backend\Block\Template\Context; use Magento\Framework\App\ProductMetadataInterface; use Magento\Backend\Model\Auth\Session; use Magento\Framework\App\State; +use Magento\Framework\View\Element\Block\ArgumentInterface; /** * Gets user version and mode - * - * @api */ -class Metadata extends Template +class Metadata implements ArgumentInterface { /** * @var State @@ -34,23 +31,18 @@ class Metadata extends Template private $productMetadata; /** - * @param Context $context * @param ProductMetadataInterface $productMetadata * @param Session $authSession * @param State $appState - * @param array $data */ public function __construct( - Context $context, ProductMetadataInterface $productMetadata, Session $authSession, - State $appState, - array $data = [] + State $appState ) { $this->productMetadata = $productMetadata; $this->authSession = $authSession; $this->appState = $appState; - parent::__construct($context, $data); } /** diff --git a/app/code/Magento/AdminAnalytics/Block/Notification.php b/app/code/Magento/AdminAnalytics/ViewModel/Notification.php similarity index 93% rename from app/code/Magento/AdminAnalytics/Block/Notification.php rename to app/code/Magento/AdminAnalytics/ViewModel/Notification.php index 1b4314e585b74..030e027b83fce 100644 --- a/app/code/Magento/AdminAnalytics/Block/Notification.php +++ b/app/code/Magento/AdminAnalytics/ViewModel/Notification.php @@ -5,14 +5,14 @@ */ declare(strict_types=1); -namespace Magento\AdminAnalytics\Block; +namespace Magento\AdminAnalytics\ViewModel; use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\AdminAnalytics\Model\Condition\CanViewNotification as AdminAnalyticsNotification; use Magento\ReleaseNotification\Model\Condition\CanViewNotification as ReleaseNotification; /** - * Class Notification + * Control display of admin analytics and release notification modals */ class Notification implements ArgumentInterface { diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml index 829c5ed3f8103..3069db1ecc2bb 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml @@ -14,7 +14,7 @@ </uiComponent> <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> <arguments> - <argument name="notification" xsi:type="object">Magento\AdminAnalytics\Block\Notification</argument> + <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> </arguments> </block> </referenceContainer> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 05f7df8284164..7e379a17c78d7 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -8,9 +8,10 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" > <body> <referenceContainer name="header"> - <block class="Magento\AdminAnalytics\Block\Metadata" name="tracking" as="tracking" template="Magento_AdminAnalytics::tracking.phtml" ifconfig="admin/usage/enabled"> + <block name="tracking" as="tracking" template="Magento_AdminAnalytics::tracking.phtml" ifconfig="admin/usage/enabled"> <arguments> <argument name="tracking_url" xsi:type="string">//assets.adobedtm.com/launch-EN30eb7ffa064444f1b8b0368ef38fd3a9.min.js</argument> + <argument name="metadata" xsi:type="object">Magento\AdminAnalytics\ViewModel\Metadata</argument> </arguments> </block> </referenceContainer> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml index 03c4c848aa44a..0ea5c753c9337 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml @@ -8,8 +8,8 @@ <script src="<?= $block->escapeUrl($block->getTrackingUrl()) ?>" async></script> <script> var adminAnalyticsMetadata = { - "version": "<?= $block->escapeJs($block->getMagentoVersion()) ?>", - "user": "<?= $block->escapeJs($block->getCurrentUser()) ?>", - "mode": "<?= $block->escapeJs($block->getMode()) ?>" + "version": "<?= $block->escapeJs($block->getMetadata()->getMagentoVersion()) ?>", + "user": "<?= $block->escapeJs($block->getMetadata()->getCurrentUser()) ?>", + "mode": "<?= $block->escapeJs($block->getMetadata()->getMode()) ?>" }; </script> From 6af74d9925c94280f8a7e773dc7d07b49abaf197 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Fri, 9 Aug 2019 15:48:03 +0300 Subject: [PATCH 281/372] MC-19023: PayPal Express Checkout Payflow Edition don't work (Internal Error) --- .../frontend/web/js/action/set-payment-information-extended.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js index 4085da82f4151..263d5747f2842 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js @@ -21,6 +21,8 @@ define([ var serviceUrl, payload; + delete paymentData.__disableTmpl; + skipBilling = skipBilling || false; payload = { cartId: quote.getQuoteId(), From faddcf9e32093dbbf94e684144d5e6272533294b Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Fri, 9 Aug 2019 15:19:30 -0500 Subject: [PATCH 282/372] MC-19115: Admin Analytics tracking should be enabled by default - Enabling tracking by Default --- app/code/Magento/AdminAnalytics/etc/config.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml new file mode 100644 index 0000000000000..ba683f13c11e3 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/config.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + <default> + <admin> + <usage> + <enabled> + 1 + </enabled> + </usage> + </admin> + </default> +</config> \ No newline at end of file From 16aa234c85476ffa7f68b91ff72c412b6fdb1cc5 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 9 Aug 2019 15:20:24 -0500 Subject: [PATCH 283/372] MC-18977: Revert change of ENGCOM-3260 --- .../Model/ReportXml/ModuleIterator.php | 2 +- .../Model/ReportXml/ModuleIteratorTest.php | 2 +- .../Backend/Block/Dashboard/Orders/Grid.php | 6 +-- .../Magento/Backend/Block/Dashboard/Sales.php | 6 +-- .../Block/Dashboard/Tab/Products/Ordered.php | 6 +-- .../Backend/Block/Dashboard/Totals.php | 6 +-- app/code/Magento/Backend/Model/Menu/Item.php | 6 +-- .../Block/Checkout/Cart/Item/Renderer.php | 4 +- .../Model/ResourceModel/Indexer/Price.php | 40 +++++++++---------- .../ResourceModel/Selection/Collection.php | 4 +- .../Block/Adminhtml/Helper/Form/Wysiwyg.php | 6 +-- .../Product/Edit/Tab/Alerts/Price.php | 6 +-- .../Product/Edit/Tab/Alerts/Stock.php | 6 +-- .../Adminhtml/Product/Edit/Tab/Inventory.php | 6 +-- .../Edit/Tab/Price/Group/AbstractGroup.php | 6 +-- .../Block/Adminhtml/Product/Edit/Tabs.php | 8 ++-- .../Catalog/Block/Adminhtml/Product/Grid.php | 6 +-- .../Block/Product/ProductList/Related.php | 6 +-- .../Block/Product/ProductList/Upsell.php | 6 +-- app/code/Magento/Catalog/Model/Product.php | 6 +-- .../ResourceModel/Product/Collection.php | 6 +-- .../Product/Compare/Item/Collection.php | 5 ++- .../Product/Indexer/Price/DefaultPrice.php | 6 +-- .../Indexer/Price/Query/BaseFinalPrice.php | 6 +-- .../Product/Edit/Tab/InventoryTest.php | 2 +- .../Catalog/Test/Unit/Model/ProductTest.php | 4 +- .../ResourceModel/Product/CollectionTest.php | 2 +- .../Form/Modifier/AdvancedPricingTest.php | 2 +- .../Product/Form/Modifier/AdvancedPricing.php | 2 +- .../ResourceModel/Advanced/Collection.php | 4 +- .../ResourceModel/Fulltext/Collection.php | 4 +- .../Model/ResourceModel/Search/Collection.php | 4 +- .../Checkout/Block/Cart/Item/Renderer.php | 6 +-- app/code/Magento/Checkout/Block/Cart/Link.php | 6 +-- app/code/Magento/Checkout/Block/Link.php | 6 +-- .../Model/Layout/DepersonalizePluginTest.php | 2 +- .../Config/Structure/AbstractElement.php | 12 ++---- .../Structure/Element/AbstractComposite.php | 4 +- .../Model/Config/Structure/Element/Field.php | 4 +- .../Model/Config/Structure/Element/Group.php | 4 +- .../Config/Structure/Element/Section.php | 4 +- .../Element/AbstractCompositeTest.php | 4 +- .../Model/Product/Type/Plugin.php | 8 ++-- .../Magento/Customer/Block/Form/Register.php | 6 +-- .../Helper/Session/CurrentCustomer.php | 4 +- .../Customer/Model/Customer/Source/Group.php | 2 +- .../Test/Unit/Block/Form/RegisterTest.php | 2 +- .../Helper/Session/CurrentCustomerTest.php | 4 +- .../Unit/Model/Customer/Source/GroupTest.php | 6 +-- .../Magento/Deploy/Collector/Collector.php | 12 +++--- .../Block/Checkout/Cart/Item/Renderer.php | 4 +- .../Model/Product/Type/Plugin.php | 8 ++-- .../Grouped/AssociatedProductsCollection.php | 4 +- .../Test/Unit/Model/ProductTest.php | 11 ++--- .../Model/Export/Config/Converter.php | 6 +-- .../Model/Import/Config/Converter.php | 8 ++-- .../Model/Export/Config/ConverterTest.php | 2 +- .../Model/Import/Config/ConverterTest.php | 2 +- ...ductAttributeFormBuildFrontTabObserver.php | 8 ++-- .../ProductAttributeGridBuildObserver.php | 8 ++-- .../Model/Module/Collect.php | 8 ++-- .../Test/Unit/Model/Module/CollectTest.php | 1 + .../PageCache/Model/DepersonalizeChecker.php | 6 +-- .../Unit/Model/DepersonalizeCheckerTest.php | 4 +- .../Model/Layout/DepersonalizePluginTest.php | 14 ++----- .../ResourceModel/Product/Collection.php | 4 +- .../Index/Collection/AbstractCollection.php | 4 +- .../Product/Lowstock/Collection.php | 4 +- .../ResourceModel/Product/CollectionTest.php | 2 +- .../Review/Block/Adminhtml/Product/Grid.php | 4 +- .../Review/Model/ResourceModel/Rating.php | 6 +-- .../Review/Product/Collection.php | 4 +- .../Product/Form/Modifier/ReviewTest.php | 2 +- .../Product/Form/Modifier/Review.php | 2 +- .../Search/Block/Adminhtml/Dashboard/Last.php | 6 +-- .../Search/Block/Adminhtml/Dashboard/Top.php | 6 +-- .../Observer/AddFieldsToAttributeObserver.php | 8 ++-- .../AddSwatchAttributeTypeObserver.php | 8 ++-- .../AddFieldsToAttributeObserverTest.php | 2 +- .../AddSwatchAttributeTypeObserverTest.php | 2 +- .../Tax/Model/App/Action/ContextPlugin.php | 6 +-- .../Tax/Observer/AfterAddressSaveObserver.php | 8 ++-- .../Tax/Observer/CustomerLoggedInObserver.php | 8 ++-- .../Unit/App/Action/ContextPluginTest.php | 4 +- .../Observer/AfterAddressSaveObserverTest.php | 8 ++-- .../Observer/CustomerLoggedInObserverTest.php | 4 +- .../layout/sales_email_item_price.xml | 12 +----- .../Weee/Model/App/Action/ContextPlugin.php | 6 +-- .../Weee/Observer/AfterAddressSave.php | 8 ++-- .../Weee/Observer/CustomerLoggedIn.php | 6 +-- .../Unit/App/Action/ContextPluginTest.php | 4 +- .../Unit/Observer/AfterAddressSaveTest.php | 10 ++--- .../Unit/Observer/CustomerLoggedInTest.php | 4 +- .../Wishlist/Test/Unit/Helper/RssTest.php | 4 +- app/etc/di.xml | 1 - .../Block/Account/Dashboard/AddressTest.php | 2 +- .../Test/Legacy/_files/obsolete_methods.php | 4 +- .../Framework/App/Helper/AbstractHelper.php | 4 +- .../Magento/Framework/App/Helper/Context.php | 8 ++-- .../Magento/Framework/Module/Manager.php | 16 ++++++-- .../Module/ModuleManagerInterface.php | 26 ------------ .../Module/Test/Unit/ManagerTest.php | 3 +- .../Unit/Plugin/DbStatusValidatorTest.php | 2 +- .../File/Collector/Decorator/ModuleOutput.php | 6 +-- 104 files changed, 283 insertions(+), 326 deletions(-) delete mode 100644 lib/internal/Magento/Framework/Module/ModuleManagerInterface.php diff --git a/app/code/Magento/Analytics/Model/ReportXml/ModuleIterator.php b/app/code/Magento/Analytics/Model/ReportXml/ModuleIterator.php index 4d62344197405..fecbf2033c1ba 100644 --- a/app/code/Magento/Analytics/Model/ReportXml/ModuleIterator.php +++ b/app/code/Magento/Analytics/Model/ReportXml/ModuleIterator.php @@ -5,7 +5,7 @@ */ namespace Magento\Analytics\Model\ReportXml; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; /** * Iterator for ReportXml modules diff --git a/app/code/Magento/Analytics/Test/Unit/Model/ReportXml/ModuleIteratorTest.php b/app/code/Magento/Analytics/Test/Unit/Model/ReportXml/ModuleIteratorTest.php index b08d41ac829b7..5288bcd306af9 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/ReportXml/ModuleIteratorTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/ReportXml/ModuleIteratorTest.php @@ -7,7 +7,7 @@ namespace Magento\Analytics\Test\Unit\Model\ReportXml; use Magento\Analytics\Model\ReportXml\ModuleIterator; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; /** diff --git a/app/code/Magento/Backend/Block/Dashboard/Orders/Grid.php b/app/code/Magento/Backend/Block/Dashboard/Orders/Grid.php index bca7f13b0cee3..0a73430aad0f3 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Orders/Grid.php +++ b/app/code/Magento/Backend/Block/Dashboard/Orders/Grid.php @@ -19,21 +19,21 @@ class Grid extends \Magento\Backend\Block\Dashboard\Grid protected $_collectionFactory; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory, array $data = [] ) { diff --git a/app/code/Magento/Backend/Block/Dashboard/Sales.php b/app/code/Magento/Backend/Block/Dashboard/Sales.php index 3455ff087a799..b388339460102 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Sales.php +++ b/app/code/Magento/Backend/Block/Dashboard/Sales.php @@ -18,20 +18,20 @@ class Sales extends \Magento\Backend\Block\Dashboard\Bar protected $_template = 'Magento_Backend::dashboard/salebar.phtml'; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_moduleManager = $moduleManager; diff --git a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Ordered.php b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Ordered.php index 7dc897a62a320..a0b1571bd17bb 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Ordered.php +++ b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Ordered.php @@ -19,21 +19,21 @@ class Ordered extends \Magento\Backend\Block\Dashboard\Grid protected $_collectionFactory; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Sales\Model\ResourceModel\Report\Bestsellers\CollectionFactory $collectionFactory * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Sales\Model\ResourceModel\Report\Bestsellers\CollectionFactory $collectionFactory, array $data = [] ) { diff --git a/app/code/Magento/Backend/Block/Dashboard/Totals.php b/app/code/Magento/Backend/Block/Dashboard/Totals.php index e57a6249af47d..20bcfebe31a8d 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Totals.php +++ b/app/code/Magento/Backend/Block/Dashboard/Totals.php @@ -22,20 +22,20 @@ class Totals extends \Magento\Backend\Block\Dashboard\Bar protected $_template = 'Magento_Backend::dashboard/totalbar.phtml'; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_moduleManager = $moduleManager; diff --git a/app/code/Magento/Backend/Model/Menu/Item.php b/app/code/Magento/Backend/Model/Menu/Item.php index d535e9c84df24..67c6216cbbc06 100644 --- a/app/code/Magento/Backend/Model/Menu/Item.php +++ b/app/code/Magento/Backend/Model/Menu/Item.php @@ -145,7 +145,7 @@ class Item protected $_moduleList; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $_moduleManager; @@ -163,7 +163,7 @@ class Item * @param \Magento\Backend\Model\MenuFactory $menuFactory * @param \Magento\Backend\Model\UrlInterface $urlModel * @param \Magento\Framework\Module\ModuleListInterface $moduleList - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( @@ -173,7 +173,7 @@ public function __construct( \Magento\Backend\Model\MenuFactory $menuFactory, \Magento\Backend\Model\UrlInterface $urlModel, \Magento\Framework\Module\ModuleListInterface $moduleList, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_validator = $validator; diff --git a/app/code/Magento/Bundle/Block/Checkout/Cart/Item/Renderer.php b/app/code/Magento/Bundle/Block/Checkout/Cart/Item/Renderer.php index c0a2d9d43034d..863f273225693 100644 --- a/app/code/Magento/Bundle/Block/Checkout/Cart/Item/Renderer.php +++ b/app/code/Magento/Bundle/Block/Checkout/Cart/Item/Renderer.php @@ -32,7 +32,7 @@ class Renderer extends \Magento\Checkout\Block\Cart\Item\Renderer * @param \Magento\Framework\Url\Helper\Data $urlHelper * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param PriceCurrencyInterface $priceCurrency - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param InterpretationStrategyInterface $messageInterpretationStrategy * @param Configuration $bundleProductConfiguration * @param array $data @@ -46,7 +46,7 @@ public function __construct( \Magento\Framework\Url\Helper\Data $urlHelper, \Magento\Framework\Message\ManagerInterface $messageManager, PriceCurrencyInterface $priceCurrency, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, InterpretationStrategyInterface $messageInterpretationStrategy, Configuration $bundleProductConfiguration, array $data = [] diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php index b71853cde41ac..077ebd4422aab 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php @@ -85,7 +85,7 @@ class Price implements DimensionalIndexerInterface private $eventManager; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -97,7 +97,7 @@ class Price implements DimensionalIndexerInterface * @param BasePriceModifier $basePriceModifier * @param JoinAttributeProcessor $joinAttributeProcessor * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param bool $fullReindexAction * @param string $connectionName * @@ -111,7 +111,7 @@ public function __construct( BasePriceModifier $basePriceModifier, JoinAttributeProcessor $joinAttributeProcessor, \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, $fullReindexAction = false, $connectionName = 'indexer' ) { @@ -139,16 +139,16 @@ public function executeByDimensions(array $dimensions, \Traversable $entityIds) $temporaryPriceTable = $this->indexTableStructureFactory->create( [ - 'tableName' => $this->tableMaintainer->getMainTmpTable($dimensions), - 'entityField' => 'entity_id', - 'customerGroupField' => 'customer_group_id', - 'websiteField' => 'website_id', - 'taxClassField' => 'tax_class_id', - 'originalPriceField' => 'price', - 'finalPriceField' => 'final_price', - 'minPriceField' => 'min_price', - 'maxPriceField' => 'max_price', - 'tierPriceField' => 'tier_price', + 'tableName' => $this->tableMaintainer->getMainTmpTable($dimensions), + 'entityField' => 'entity_id', + 'customerGroupField' => 'customer_group_id', + 'websiteField' => 'website_id', + 'taxClassField' => 'tax_class_id', + 'originalPriceField' => 'price', + 'finalPriceField' => 'final_price', + 'minPriceField' => 'min_price', + 'maxPriceField' => 'max_price', + 'tierPriceField' => 'tier_price', ] ); @@ -335,9 +335,9 @@ private function prepareBundlePriceByType($priceType, array $dimensions, $entity ); $finalPrice = $connection->getLeastSql( [ - $price, - $connection->getIfNullSql($specialPriceExpr, $price), - $connection->getIfNullSql($tierPrice, $price), + $price, + $connection->getIfNullSql($specialPriceExpr, $price), + $connection->getIfNullSql($tierPrice, $price), ] ); } else { @@ -477,8 +477,8 @@ private function calculateBundleSelectionPrice($dimensions, $priceType) $priceExpr = $connection->getLeastSql( [ - $priceExpr, - $connection->getIfNullSql($tierExpr, $priceExpr), + $priceExpr, + $connection->getIfNullSql($tierExpr, $priceExpr), ] ); } else { @@ -495,8 +495,8 @@ private function calculateBundleSelectionPrice($dimensions, $priceType) ); $priceExpr = $connection->getLeastSql( [ - $specialExpr, - $connection->getIfNullSql($tierExpr, $price), + $specialExpr, + $connection->getIfNullSql($tierExpr, $price), ] ); } diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php index 21ba1f75ba90b..7b3f6dd8bbefa 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php @@ -61,7 +61,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -88,7 +88,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg.php b/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg.php index a829c058d89bf..c58ed58370e3a 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg.php @@ -26,7 +26,7 @@ class Wysiwyg extends \Magento\Framework\Data\Form\Element\Textarea /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager = null; @@ -46,7 +46,7 @@ class Wysiwyg extends \Magento\Framework\Data\Form\Element\Textarea * @param \Magento\Framework\Escaper $escaper * @param \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig * @param \Magento\Framework\View\LayoutInterface $layout - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Backend\Helper\Data $backendData * @param array $data */ @@ -56,7 +56,7 @@ public function __construct( \Magento\Framework\Escaper $escaper, \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig, \Magento\Framework\View\LayoutInterface $layout, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Backend\Helper\Data $backendData, array $data = [] ) { diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Price.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Price.php index e754ab9700517..386fe1333a7e9 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Price.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Price.php @@ -19,7 +19,7 @@ class Price extends Extended /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -32,14 +32,14 @@ class Price extends Extended * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper * @param \Magento\ProductAlert\Model\PriceFactory $priceFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\ProductAlert\Model\PriceFactory $priceFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_priceFactory = $priceFactory; diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Stock.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Stock.php index 2c6647fd57be6..ede478cabe783 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Stock.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Stock.php @@ -19,7 +19,7 @@ class Stock extends Extended /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -32,14 +32,14 @@ class Stock extends Extended * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper * @param \Magento\ProductAlert\Model\StockFactory $stockFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\ProductAlert\Model\StockFactory $stockFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_stockFactory = $stockFactory; diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php index 9278b84362e77..782147e1e8ef6 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php @@ -18,7 +18,7 @@ class Inventory extends \Magento\Backend\Block\Widget protected $_template = 'Magento_Catalog::catalog/product/tab/inventory.phtml'; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -53,7 +53,7 @@ class Inventory extends \Magento\Backend\Block\Widget * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\CatalogInventory\Model\Source\Backorders $backorders * @param \Magento\CatalogInventory\Model\Source\Stock $stock - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Framework\Registry $coreRegistry * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration @@ -63,7 +63,7 @@ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\CatalogInventory\Model\Source\Backorders $backorders, \Magento\CatalogInventory\Model\Source\Stock $stock, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Framework\Registry $coreRegistry, \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry, \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration, diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Price/Group/AbstractGroup.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Price/Group/AbstractGroup.php index 42990116e933f..5ffd3d1dda38d 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Price/Group/AbstractGroup.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Price/Group/AbstractGroup.php @@ -41,7 +41,7 @@ abstract class AbstractGroup extends Widget implements RendererInterface /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -81,7 +81,7 @@ abstract class AbstractGroup extends Widget implements RendererInterface * @param \Magento\Backend\Block\Template\Context $context * @param GroupRepositoryInterface $groupRepository * @param \Magento\Directory\Helper\Data $directoryHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Framework\Registry $registry * @param GroupManagementInterface $groupManagement * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder @@ -92,7 +92,7 @@ public function __construct( \Magento\Backend\Block\Template\Context $context, GroupRepositoryInterface $groupRepository, \Magento\Directory\Helper\Data $directoryHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Framework\Registry $registry, GroupManagementInterface $groupManagement, \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php index 51c326763b09c..37ad3f4bea20e 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php @@ -14,7 +14,7 @@ use Magento\Catalog\Helper\Data; use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory; use Magento\Framework\Json\EncoderInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Registry; use Magento\Framework\Translate\InlineInterface; @@ -65,7 +65,7 @@ class Tabs extends WidgetTabs protected $_collectionFactory; /** - * @var ModuleManagerInterface + * @var Manager */ protected $_moduleManager; @@ -78,7 +78,7 @@ class Tabs extends WidgetTabs * @param Context $context * @param EncoderInterface $jsonEncoder * @param Session $authSession - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param CollectionFactory $collectionFactory * @param Catalog $helperCatalog * @param Data $catalogData @@ -91,7 +91,7 @@ public function __construct( Context $context, EncoderInterface $jsonEncoder, Session $authSession, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, CollectionFactory $collectionFactory, Catalog $helperCatalog, Data $catalogData, diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php index 7e43f2fc064ad..01408ade56432 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php @@ -16,7 +16,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -59,7 +59,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended * @param \Magento\Catalog\Model\Product\Type $type * @param \Magento\Catalog\Model\Product\Attribute\Source\Status $status * @param \Magento\Catalog\Model\Product\Visibility $visibility - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data * * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -73,7 +73,7 @@ public function __construct( \Magento\Catalog\Model\Product\Type $type, \Magento\Catalog\Model\Product\Attribute\Source\Status $status, \Magento\Catalog\Model\Product\Visibility $visibility, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_websiteFactory = $websiteFactory; diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php index 088619511545f..6de70bb971367 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php @@ -46,7 +46,7 @@ class Related extends \Magento\Catalog\Block\Product\AbstractProduct implements protected $_checkoutCart; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -55,7 +55,7 @@ class Related extends \Magento\Catalog\Block\Product\AbstractProduct implements * @param \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart * @param \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( @@ -63,7 +63,7 @@ public function __construct( \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart, \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility, \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_checkoutCart = $checkoutCart; diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php index d888f44a6fbfb..24822447ae915 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php @@ -60,7 +60,7 @@ class Upsell extends \Magento\Catalog\Block\Product\AbstractProduct implements protected $_checkoutCart; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -69,7 +69,7 @@ class Upsell extends \Magento\Catalog\Block\Product\AbstractProduct implements * @param \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart * @param \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( @@ -77,7 +77,7 @@ public function __construct( \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart, \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility, \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_checkoutCart = $checkoutCart; diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index fc9fffb2a7e9a..fc3cc11cade54 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -177,7 +177,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements protected $_catalogProduct = null; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -381,7 +381,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements * @param Product\Attribute\Source\Status $catalogProductStatus * @param Product\Media\Config $catalogProductMediaConfig * @param Product\Type $catalogProductType - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Helper\Product $catalogProduct * @param ResourceModel\Product $resource * @param ResourceModel\Product\Collection $resourceCollection @@ -422,7 +422,7 @@ public function __construct( \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus, \Magento\Catalog\Model\Product\Media\Config $catalogProductMediaConfig, Product\Type $catalogProductType, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Helper\Product $catalogProduct, \Magento\Catalog\Model\ResourceModel\Product $resource, \Magento\Catalog\Model\ResourceModel\Product\Collection $resourceCollection, diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index dbd6a7a2e1094..384b6ddcefc31 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -191,7 +191,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager = null; @@ -315,7 +315,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -344,7 +344,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php index dc3411743a066..92741cf9ba88e 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php @@ -64,7 +64,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -76,6 +76,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Product\Compare\Item $catalogProductCompareItem * @param \Magento\Catalog\Helper\Product\Compare $catalogProductCompare * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection + * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -89,7 +90,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php index 9643f4c3a7181..b64cca4ff1b26 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php @@ -40,7 +40,7 @@ class DefaultPrice extends AbstractIndexer implements PriceInterface /** * Core data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -73,7 +73,7 @@ class DefaultPrice extends AbstractIndexer implements PriceInterface * @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy * @param \Magento\Eav\Model\Config $eavConfig * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param string|null $connectionName * @param IndexTableStructureFactory $indexTableStructureFactory * @param PriceModifierInterface[] $priceModifiers @@ -83,7 +83,7 @@ public function __construct( \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy, \Magento\Eav\Model\Config $eavConfig, \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, $connectionName = null, IndexTableStructureFactory $indexTableStructureFactory = null, array $priceModifiers = [] diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/Query/BaseFinalPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/Query/BaseFinalPrice.php index a3f463d53e7a8..77407ed699fbd 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/Query/BaseFinalPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/Query/BaseFinalPrice.php @@ -37,7 +37,7 @@ class BaseFinalPrice private $joinAttributeProcessor; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -69,7 +69,7 @@ class BaseFinalPrice /** * @param \Magento\Framework\App\ResourceConnection $resource * @param JoinAttributeProcessor $joinAttributeProcessor - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool * @param string $connectionName @@ -77,7 +77,7 @@ class BaseFinalPrice public function __construct( \Magento\Framework\App\ResourceConnection $resource, JoinAttributeProcessor $joinAttributeProcessor, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Framework\EntityManager\MetadataPool $metadataPool, $connectionName = 'indexer' diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Edit/Tab/InventoryTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Edit/Tab/InventoryTest.php index 2008d0b9414c5..19c578e976cdd 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Edit/Tab/InventoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Edit/Tab/InventoryTest.php @@ -85,7 +85,7 @@ protected function setUp() $this->backordersMock = $this->createMock(\Magento\CatalogInventory\Model\Source\Backorders::class); $this->stockMock = $this->createMock(\Magento\CatalogInventory\Model\Source\Stock::class); $this->coreRegistryMock = $this->createMock(\Magento\Framework\Registry::class); - $this->moduleManager = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManager = $this->createMock(\Magento\Framework\Module\Manager::class); $this->storeManagerMock = $this->getMockForAbstractClass( \Magento\Store\Model\StoreManagerInterface::class, [], diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php index 8bf8473080c54..2ef848ca5aada 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php @@ -40,7 +40,7 @@ class ProductTest extends \PHPUnit\Framework\TestCase protected $model; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManager; @@ -215,7 +215,7 @@ protected function setUp() $this->categoryIndexerMock = $this->getMockForAbstractClass(\Magento\Framework\Indexer\IndexerInterface::class); $this->moduleManager = $this->createPartialMock( - \Magento\Framework\Module\ModuleManagerInterface::class, + \Magento\Framework\Module\Manager::class, ['isEnabled'] ); $this->extensionAttributes = $this->getMockBuilder(\Magento\Framework\Api\ExtensionAttributesInterface::class) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php index 6370a4a7a27e2..0316b2e374d2f 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php @@ -98,7 +98,7 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['getStore', 'getId', 'getWebsiteId']) ->getMockForAbstractClass(); - $moduleManager = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $moduleManager = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); $catalogProductFlatState = $this->getMockBuilder(\Magento\Catalog\Model\Indexer\Product\Flat\State::class) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AdvancedPricingTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AdvancedPricingTest.php index e9f9349100f15..e455ad47ee626 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AdvancedPricingTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AdvancedPricingTest.php @@ -11,7 +11,7 @@ use Magento\Customer\Api\GroupManagementInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Directory\Helper\Data as DirectoryHelper; use Magento\Catalog\Model\ResourceModel\Product as ProductResource; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 9ad75b5fda923..00132c6ad89e8 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -14,7 +14,7 @@ use Magento\Customer\Api\GroupManagementInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Ui\Component\Container; use Magento\Ui\Component\Form\Element\DataType\Number; use Magento\Ui\Component\Form\Element\DataType\Price; diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index 1946dd35b8d37..a37cd80056b00 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -125,7 +125,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param Product\OptionFactory $productOptionFactory @@ -160,7 +160,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 4f84f3868c6a3..a596354a0c8cd 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -146,7 +146,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -185,7 +185,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php index 6cdcc7c55a26f..e625ccbe51fe3 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php @@ -50,7 +50,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -74,7 +74,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php b/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php index 4941bf8451bf8..c99c9041941b1 100644 --- a/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php +++ b/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php @@ -85,7 +85,7 @@ class Renderer extends \Magento\Framework\View\Element\Template implements protected $priceCurrency; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ public $moduleManager; @@ -105,7 +105,7 @@ class Renderer extends \Magento\Framework\View\Element\Template implements * @param \Magento\Framework\Url\Helper\Data $urlHelper * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param PriceCurrencyInterface $priceCurrency - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param InterpretationStrategyInterface $messageInterpretationStrategy * @param array $data * @param ItemResolverInterface|null $itemResolver @@ -120,7 +120,7 @@ public function __construct( \Magento\Framework\Url\Helper\Data $urlHelper, \Magento\Framework\Message\ManagerInterface $messageManager, PriceCurrencyInterface $priceCurrency, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, InterpretationStrategyInterface $messageInterpretationStrategy, array $data = [], ItemResolverInterface $itemResolver = null diff --git a/app/code/Magento/Checkout/Block/Cart/Link.php b/app/code/Magento/Checkout/Block/Cart/Link.php index 6ea5137521106..9e6db1754d9e4 100644 --- a/app/code/Magento/Checkout/Block/Cart/Link.php +++ b/app/code/Magento/Checkout/Block/Cart/Link.php @@ -13,7 +13,7 @@ class Link extends \Magento\Framework\View\Element\Html\Link { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -24,14 +24,14 @@ class Link extends \Magento\Framework\View\Element\Html\Link /** * @param \Magento\Framework\View\Element\Template\Context $context - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Checkout\Helper\Cart $cartHelper * @param array $data * @codeCoverageIgnore */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Checkout\Helper\Cart $cartHelper, array $data = [] ) { diff --git a/app/code/Magento/Checkout/Block/Link.php b/app/code/Magento/Checkout/Block/Link.php index 3d0740181f4a5..4ab2981e9185e 100644 --- a/app/code/Magento/Checkout/Block/Link.php +++ b/app/code/Magento/Checkout/Block/Link.php @@ -13,7 +13,7 @@ class Link extends \Magento\Framework\View\Element\Html\Link { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -24,14 +24,14 @@ class Link extends \Magento\Framework\View\Element\Html\Link /** * @param \Magento\Framework\View\Element\Template\Context $context - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Checkout\Helper\Data $checkoutHelper * @param array $data * @codeCoverageIgnore */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Checkout\Helper\Data $checkoutHelper, array $data = [] ) { diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php index 3cc80e14fd026..350f9954208fa 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -43,7 +43,7 @@ protected function setUp() ); $this->checkoutSessionMock = $this->createPartialMock(\Magento\Checkout\Model\Session::class, ['clearStorage']); $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); $this->cacheConfigMock = $this->createMock(\Magento\PageCache\Model\Config::class); $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); diff --git a/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php b/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php index db815ec87ed76..23a3dea1a7029 100644 --- a/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php +++ b/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php @@ -40,7 +40,7 @@ abstract class AbstractElement implements StructureElementInterface protected $_storeManager; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -50,15 +50,11 @@ abstract class AbstractElement implements StructureElementInterface private $elementVisibility; /** - * Construct. - * * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager */ - public function __construct( - StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager - ) { + public function __construct(StoreManagerInterface $storeManager, \Magento\Framework\Module\Manager $moduleManager) + { $this->_storeManager = $storeManager; $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/AbstractComposite.php b/app/code/Magento/Config/Model/Config/Structure/Element/AbstractComposite.php index efb918226aa31..a14114a116e78 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/AbstractComposite.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/AbstractComposite.php @@ -23,12 +23,12 @@ abstract class AbstractComposite extends \Magento\Config\Model\Config\Structure\ /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param Iterator $childrenIterator */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, Iterator $childrenIterator ) { parent::__construct($storeManager, $moduleManager); diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/Field.php b/app/code/Magento/Config/Model/Config/Structure/Element/Field.php index 6a8cc6e767466..834b2a9e17e37 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/Field.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/Field.php @@ -56,7 +56,7 @@ class Field extends \Magento\Config\Model\Config\Structure\AbstractElement /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Config\Model\Config\BackendFactory $backendFactory * @param \Magento\Config\Model\Config\SourceFactory $sourceFactory * @param \Magento\Config\Model\Config\CommentFactory $commentFactory @@ -65,7 +65,7 @@ class Field extends \Magento\Config\Model\Config\Structure\AbstractElement */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Config\Model\Config\BackendFactory $backendFactory, \Magento\Config\Model\Config\SourceFactory $sourceFactory, \Magento\Config\Model\Config\CommentFactory $commentFactory, diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/Group.php b/app/code/Magento/Config/Model/Config/Structure/Element/Group.php index db479e8b795a0..1ca0afa942f8d 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/Group.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/Group.php @@ -29,14 +29,14 @@ class Group extends AbstractComposite /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param Iterator\Field $childrenIterator * @param \Magento\Config\Model\Config\BackendClone\Factory $cloneModelFactory * @param Dependency\Mapper $dependencyMapper */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Config\Model\Config\Structure\Element\Iterator\Field $childrenIterator, \Magento\Config\Model\Config\BackendClone\Factory $cloneModelFactory, \Magento\Config\Model\Config\Structure\Element\Dependency\Mapper $dependencyMapper diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/Section.php b/app/code/Magento/Config/Model/Config/Structure/Element/Section.php index 134411fbd87ca..80c029dfea2d0 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/Section.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/Section.php @@ -22,13 +22,13 @@ class Section extends AbstractComposite /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param Iterator $childrenIterator * @param \Magento\Framework\AuthorizationInterface $authorization */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, Iterator $childrenIterator, \Magento\Framework\AuthorizationInterface $authorization ) { diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/AbstractCompositeTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/AbstractCompositeTest.php index e448b628ef020..8c54a02a491c0 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/AbstractCompositeTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/AbstractCompositeTest.php @@ -29,7 +29,7 @@ class AbstractCompositeTest extends \PHPUnit\Framework\TestCase protected $_iteratorMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface | \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager | \PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; @@ -56,7 +56,7 @@ protected function setUp() ->getMockForAbstractClass(); $this->_iteratorMock = $this->createMock(\Magento\Config\Model\Config\Structure\Element\Iterator::class); $this->_storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManager::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); $this->_model = $this->getMockForAbstractClass( \Magento\Config\Model\Config\Structure\Element\AbstractComposite::class, [$this->_storeManagerMock, $this->moduleManagerMock, $this->_iteratorMock] diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php index e8b7299a03db9..cb4ac975cd582 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php @@ -6,7 +6,7 @@ */ namespace Magento\ConfigurableProduct\Model\Product\Type; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; /** * Type plugin. @@ -14,14 +14,14 @@ class Plugin { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/Customer/Block/Form/Register.php b/app/code/Magento/Customer/Block/Form/Register.php index a190ccde50b5a..59966768a2eda 100644 --- a/app/code/Magento/Customer/Block/Form/Register.php +++ b/app/code/Magento/Customer/Block/Form/Register.php @@ -23,7 +23,7 @@ class Register extends \Magento\Directory\Block\Data protected $_customerSession; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -41,7 +41,7 @@ class Register extends \Magento\Directory\Block\Data * @param \Magento\Framework\App\Cache\Type\Config $configCacheType * @param \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionCollectionFactory * @param \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryCollectionFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Model\Url $customerUrl * @param array $data @@ -55,7 +55,7 @@ public function __construct( \Magento\Framework\App\Cache\Type\Config $configCacheType, \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionCollectionFactory, \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryCollectionFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Customer\Model\Session $customerSession, \Magento\Customer\Model\Url $customerUrl, array $data = [] diff --git a/app/code/Magento/Customer/Helper/Session/CurrentCustomer.php b/app/code/Magento/Customer/Helper/Session/CurrentCustomer.php index 5cd09aca9f873..d48ff5918c3f3 100644 --- a/app/code/Magento/Customer/Helper/Session/CurrentCustomer.php +++ b/app/code/Magento/Customer/Helper/Session/CurrentCustomer.php @@ -10,7 +10,7 @@ use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ViewInterface; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Framework\View\LayoutInterface; /** @@ -45,7 +45,7 @@ class CurrentCustomer protected $request; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; diff --git a/app/code/Magento/Customer/Model/Customer/Source/Group.php b/app/code/Magento/Customer/Model/Customer/Source/Group.php index efcc7d0fe93a4..1064152b20fd5 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/Group.php +++ b/app/code/Magento/Customer/Model/Customer/Source/Group.php @@ -6,7 +6,7 @@ namespace Magento\Customer\Model\Customer\Source; use Magento\Customer\Api\Data\GroupSearchResultsInterface; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Customer\Api\Data\GroupInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; diff --git a/app/code/Magento/Customer/Test/Unit/Block/Form/RegisterTest.php b/app/code/Magento/Customer/Test/Unit/Block/Form/RegisterTest.php index b93b9f40d75b2..d234ebfb334d6 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Form/RegisterTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Form/RegisterTest.php @@ -40,7 +40,7 @@ class RegisterTest extends \PHPUnit\Framework\TestCase /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Customer\Model\Session */ private $_customerSession; - /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Module\ModuleManagerInterface */ + /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Module\Manager */ private $_moduleManager; /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Customer\Model\Url */ diff --git a/app/code/Magento/Customer/Test/Unit/Helper/Session/CurrentCustomerTest.php b/app/code/Magento/Customer/Test/Unit/Helper/Session/CurrentCustomerTest.php index 03158d05db8e4..15ced1ce66d06 100644 --- a/app/code/Magento/Customer/Test/Unit/Helper/Session/CurrentCustomerTest.php +++ b/app/code/Magento/Customer/Test/Unit/Helper/Session/CurrentCustomerTest.php @@ -47,7 +47,7 @@ class CurrentCustomerTest extends \PHPUnit\Framework\TestCase protected $requestMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; @@ -80,7 +80,7 @@ protected function setUp() $this->customerDataMock = $this->createMock(\Magento\Customer\Api\Data\CustomerInterface::class); $this->customerRepositoryMock = $this->createMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); $this->viewMock = $this->createMock(\Magento\Framework\App\View::class); $this->currentCustomer = new \Magento\Customer\Helper\Session\CurrentCustomer( diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php index 9128d7c675262..bc4c19bc23ac1 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php @@ -6,7 +6,7 @@ namespace Magento\Customer\Test\Unit\Model\Customer\Source; use Magento\Customer\Model\Customer\Source\Group; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SearchCriteria; @@ -23,7 +23,7 @@ class GroupTest extends \PHPUnit\Framework\TestCase private $model; /** - * @var ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManagerMock; @@ -49,7 +49,7 @@ class GroupTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->moduleManagerMock = $this->getMockBuilder(ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(Manager::class) ->disableOriginalConstructor() ->getMock(); $this->groupRepositoryMock = $this->getMockBuilder(GroupRepositoryInterface::class) diff --git a/app/code/Magento/Deploy/Collector/Collector.php b/app/code/Magento/Deploy/Collector/Collector.php index 7742f2971a2fe..b09001a7ac04c 100644 --- a/app/code/Magento/Deploy/Collector/Collector.php +++ b/app/code/Magento/Deploy/Collector/Collector.php @@ -9,7 +9,7 @@ use Magento\Deploy\Package\Package; use Magento\Deploy\Package\PackageFactory; use Magento\Deploy\Package\PackageFile; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\View\Asset\PreProcessor\FileNameResolver; /** @@ -45,8 +45,8 @@ class Collector implements CollectorInterface * @var PackageFactory */ private $packageFactory; - - /** @var \Magento\Framework\Module\ModuleManagerInterface */ + + /** @var \Magento\Framework\Module\Manager */ private $moduleManager; /** @@ -66,19 +66,19 @@ class Collector implements CollectorInterface * @param SourcePool $sourcePool * @param FileNameResolver $fileNameResolver * @param PackageFactory $packageFactory - * @param ModuleManagerInterface|null $moduleManager + * @param Manager|null $moduleManager */ public function __construct( SourcePool $sourcePool, FileNameResolver $fileNameResolver, PackageFactory $packageFactory, - ModuleManagerInterface $moduleManager = null + Manager $moduleManager = null ) { $this->sourcePool = $sourcePool; $this->fileNameResolver = $fileNameResolver; $this->packageFactory = $packageFactory; $this->moduleManager = $moduleManager ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\Module\ModuleManagerInterface::class); + ->get(\Magento\Framework\Module\Manager::class); } /** diff --git a/app/code/Magento/Downloadable/Block/Checkout/Cart/Item/Renderer.php b/app/code/Magento/Downloadable/Block/Checkout/Cart/Item/Renderer.php index 51efc74738043..8b8a9b6bf2895 100644 --- a/app/code/Magento/Downloadable/Block/Checkout/Cart/Item/Renderer.php +++ b/app/code/Magento/Downloadable/Block/Checkout/Cart/Item/Renderer.php @@ -37,7 +37,7 @@ class Renderer extends \Magento\Checkout\Block\Cart\Item\Renderer * @param \Magento\Framework\Url\Helper\Data $urlHelper * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param PriceCurrencyInterface $priceCurrency - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param InterpretationStrategyInterface $messageInterpretationStrategy * @param \Magento\Downloadable\Helper\Catalog\Product\Configuration $downloadableProductConfiguration * @param array $data @@ -51,7 +51,7 @@ public function __construct( \Magento\Framework\Url\Helper\Data $urlHelper, \Magento\Framework\Message\ManagerInterface $messageManager, PriceCurrencyInterface $priceCurrency, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, InterpretationStrategyInterface $messageInterpretationStrategy, \Magento\Downloadable\Helper\Catalog\Product\Configuration $downloadableProductConfiguration, array $data = [] diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Plugin.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Plugin.php index 4777b2bae07a5..350edb5b8495e 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Plugin.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Plugin.php @@ -6,7 +6,7 @@ */ namespace Magento\GroupedProduct\Model\Product\Type; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; /** * Plugin. @@ -14,14 +14,14 @@ class Plugin { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Type/Grouped/AssociatedProductsCollection.php b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Type/Grouped/AssociatedProductsCollection.php index 519da20510815..c492939232b15 100644 --- a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Type/Grouped/AssociatedProductsCollection.php +++ b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Type/Grouped/AssociatedProductsCollection.php @@ -41,7 +41,7 @@ class AssociatedProductsCollection extends \Magento\Catalog\Model\ResourceModel\ * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -67,7 +67,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php index cec7931c1c61f..78fa2445ff583 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php @@ -30,7 +30,7 @@ class ProductTest extends \PHPUnit\Framework\TestCase protected $model; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManager; @@ -159,14 +159,9 @@ class ProductTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->categoryIndexerMock = $this->getMockForAbstractClass( - \Magento\Framework\Indexer\IndexerInterface::class - ); + $this->categoryIndexerMock = $this->getMockForAbstractClass(\Magento\Framework\Indexer\IndexerInterface::class); - $this->moduleManager = $this->createPartialMock( - \Magento\Framework\Module\ModuleManagerInterface::class, - ['isEnabled'] - ); + $this->moduleManager = $this->createPartialMock(\Magento\Framework\Module\Manager::class, ['isEnabled']); $this->stockItemFactoryMock = $this->createPartialMock( \Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory::class, ['create'] diff --git a/app/code/Magento/ImportExport/Model/Export/Config/Converter.php b/app/code/Magento/ImportExport/Model/Export/Config/Converter.php index 20ab81ec1cd5b..298f63d18f88d 100644 --- a/app/code/Magento/ImportExport/Model/Export/Config/Converter.php +++ b/app/code/Magento/ImportExport/Model/Export/Config/Converter.php @@ -5,7 +5,7 @@ */ namespace Magento\ImportExport\Model\Export\Config; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\App\Utility\Classes; /** @@ -14,14 +14,14 @@ class Converter implements \Magento\Framework\Config\ConverterInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/ImportExport/Model/Import/Config/Converter.php b/app/code/Magento/ImportExport/Model/Import/Config/Converter.php index f2d1596ec3d9d..a1eb8470b4dd6 100644 --- a/app/code/Magento/ImportExport/Model/Import/Config/Converter.php +++ b/app/code/Magento/ImportExport/Model/Import/Config/Converter.php @@ -5,7 +5,7 @@ */ namespace Magento\ImportExport\Model\Import\Config; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\App\Utility\Classes; /** @@ -14,14 +14,14 @@ class Converter implements \Magento\Framework\Config\ConverterInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/ConverterTest.php b/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/ConverterTest.php index c888c6b447348..e08f382d94003 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/ConverterTest.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/ConverterTest.php @@ -21,7 +21,7 @@ class ConverterTest extends \PHPUnit\Framework\TestCase protected $filePath; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManager; diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/ConverterTest.php b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/ConverterTest.php index b29a04322ce4f..69118d2e2a319 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/ConverterTest.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/ConverterTest.php @@ -21,7 +21,7 @@ class ConverterTest extends \PHPUnit\Framework\TestCase protected $filePath; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManager; diff --git a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php index 0b9cb377d1d08..ce618f97883b0 100644 --- a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php +++ b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php @@ -8,7 +8,7 @@ namespace Magento\LayeredNavigation\Observer\Edit\Tab\Front; use Magento\Config\Model\Config\Source; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Event\ObserverInterface; /** @@ -22,15 +22,15 @@ class ProductAttributeFormBuildFrontTabObserver implements ObserverInterface protected $optionList; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Source\Yesno $optionList */ - public function __construct(ModuleManagerInterface $moduleManager, Source\Yesno $optionList) + public function __construct(Manager $moduleManager, Source\Yesno $optionList) { $this->optionList = $optionList; $this->moduleManager = $moduleManager; diff --git a/app/code/Magento/LayeredNavigation/Observer/Grid/ProductAttributeGridBuildObserver.php b/app/code/Magento/LayeredNavigation/Observer/Grid/ProductAttributeGridBuildObserver.php index b98230c1ebe3c..57a20cf17371d 100644 --- a/app/code/Magento/LayeredNavigation/Observer/Grid/ProductAttributeGridBuildObserver.php +++ b/app/code/Magento/LayeredNavigation/Observer/Grid/ProductAttributeGridBuildObserver.php @@ -7,7 +7,7 @@ */ namespace Magento\LayeredNavigation\Observer\Grid; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Event\ObserverInterface; /** @@ -16,16 +16,16 @@ class ProductAttributeGridBuildObserver implements ObserverInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** * Construct. * - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/NewRelicReporting/Model/Module/Collect.php b/app/code/Magento/NewRelicReporting/Model/Module/Collect.php index 0d8a94fbed940..fe5389e258aa5 100644 --- a/app/code/Magento/NewRelicReporting/Model/Module/Collect.php +++ b/app/code/Magento/NewRelicReporting/Model/Module/Collect.php @@ -6,7 +6,7 @@ namespace Magento\NewRelicReporting\Model\Module; use Magento\Framework\Module\FullModuleList; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Module\ModuleListInterface; use Magento\NewRelicReporting\Model\Config; use Magento\NewRelicReporting\Model\Module; @@ -22,7 +22,7 @@ class Collect protected $moduleList; /** - * @var ModuleManagerInterface + * @var Manager */ protected $moduleManager; @@ -46,14 +46,14 @@ class Collect * * @param ModuleListInterface $moduleList * @param FullModuleList $fullModuleList - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param \Magento\NewRelicReporting\Model\ModuleFactory $moduleFactory * @param \Magento\NewRelicReporting\Model\ResourceModel\Module\CollectionFactory $moduleCollectionFactory */ public function __construct( ModuleListInterface $moduleList, FullModuleList $fullModuleList, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, \Magento\NewRelicReporting\Model\ModuleFactory $moduleFactory, \Magento\NewRelicReporting\Model\ResourceModel\Module\CollectionFactory $moduleCollectionFactory ) { diff --git a/app/code/Magento/NewRelicReporting/Test/Unit/Model/Module/CollectTest.php b/app/code/Magento/NewRelicReporting/Test/Unit/Model/Module/CollectTest.php index 3c30d95b77de0..4286406d6e9ab 100644 --- a/app/code/Magento/NewRelicReporting/Test/Unit/Model/Module/CollectTest.php +++ b/app/code/Magento/NewRelicReporting/Test/Unit/Model/Module/CollectTest.php @@ -8,6 +8,7 @@ use Magento\NewRelicReporting\Model\Module\Collect; use Magento\Framework\Module\FullModuleList; use Magento\Framework\Module\ModuleListInterface; +use Magento\Framework\Module\Manager; use Magento\NewRelicReporting\Model\Module; /** diff --git a/app/code/Magento/PageCache/Model/DepersonalizeChecker.php b/app/code/Magento/PageCache/Model/DepersonalizeChecker.php index 4012499d5da5a..3023efb7a71a6 100644 --- a/app/code/Magento/PageCache/Model/DepersonalizeChecker.php +++ b/app/code/Magento/PageCache/Model/DepersonalizeChecker.php @@ -20,7 +20,7 @@ class DepersonalizeChecker /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -33,12 +33,12 @@ class DepersonalizeChecker /** * @param \Magento\Framework\App\RequestInterface $request - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param Config $cacheConfig */ public function __construct( \Magento\Framework\App\RequestInterface $request, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, Config $cacheConfig ) { $this->request = $request; diff --git a/app/code/Magento/PageCache/Test/Unit/Model/DepersonalizeCheckerTest.php b/app/code/Magento/PageCache/Test/Unit/Model/DepersonalizeCheckerTest.php index 6857c637bab84..8cc933853a492 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/DepersonalizeCheckerTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/DepersonalizeCheckerTest.php @@ -18,7 +18,7 @@ class DepersonalizeCheckerTest extends \PHPUnit\Framework\TestCase private $requestMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManagerMock; @@ -30,7 +30,7 @@ class DepersonalizeCheckerTest extends \PHPUnit\Framework\TestCase public function setup() { $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); $this->cacheConfigMock = $this->createMock(\Magento\PageCache\Model\Config::class); } diff --git a/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php index 5ba0182ecc57a..9731811ea8a97 100644 --- a/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -46,17 +46,9 @@ protected function setUp() $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createPartialMock( - \Magento\Framework\Module\ModuleManagerInterface::class, - ['isEnabled'] - ); - $this->cacheConfigMock = $this->createPartialMock( - \Magento\PageCache\Model\Config::class, - ['isEnabled'] - ); - $this->depersonalizeCheckerMock = $this->createMock( - \Magento\PageCache\Model\DepersonalizeChecker::class - ); + $this->moduleManagerMock = $this->createPartialMock(\Magento\Framework\Module\Manager::class, ['isEnabled']); + $this->cacheConfigMock = $this->createPartialMock(\Magento\PageCache\Model\Config::class, ['isEnabled']); + $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); $this->plugin = $this->objectManager->getObject( \Magento\Persistent\Model\Layout\DepersonalizePlugin::class, diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php index 8c985238efe47..ab76cad8da5c4 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php @@ -77,7 +77,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -111,7 +111,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php index ec514f45ff65a..5b4cf39d65def 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php @@ -44,7 +44,7 @@ abstract class AbstractCollection extends \Magento\Catalog\Model\ResourceModel\P * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -69,7 +69,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php index c02de01117a74..39d673911111f 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php @@ -63,7 +63,7 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -94,7 +94,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php b/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php index 3f1857b352dbc..23067457081a6 100644 --- a/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php +++ b/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php @@ -29,7 +29,7 @@ use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Select; use Magento\Framework\Event\ManagerInterface; -use Magento\Framework\Module\ModuleManagerInterface as Manager; +use Magento\Framework\Module\Manager as Manager; use Magento\Framework\Stdlib\DateTime; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; diff --git a/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php b/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php index 509e826e6f7d3..d3bbdf9a7eb40 100644 --- a/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php +++ b/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php @@ -29,7 +29,7 @@ class Grid extends \Magento\Catalog\Block\Adminhtml\Product\Grid * @param \Magento\Catalog\Model\Product\Type $type * @param \Magento\Catalog\Model\Product\Attribute\Source\Status $status * @param \Magento\Catalog\Model\Product\Visibility $visibility - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Store\Model\ResourceModel\Website\CollectionFactory $websitesFactory * @param array $data * @@ -44,7 +44,7 @@ public function __construct( \Magento\Catalog\Model\Product\Type $type, \Magento\Catalog\Model\Product\Attribute\Source\Status $status, \Magento\Catalog\Model\Product\Visibility $visibility, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Store\Model\ResourceModel\Website\CollectionFactory $websitesFactory, array $data = [] ) { diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index 42c14e16a50e2..37a93d40b1107 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -29,7 +29,7 @@ class Rating extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb protected $_storeManager; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -46,7 +46,7 @@ class Rating extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Psr\Log\LoggerInterface $logger - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param Review\Summary $reviewSummary * @param string $connectionName @@ -55,7 +55,7 @@ class Rating extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Psr\Log\LoggerInterface $logger, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Review\Model\ResourceModel\Review\Summary $reviewSummary, $connectionName = null, diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index 7175baa92a2f8..ab264ef1b6179 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -75,7 +75,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -103,7 +103,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php b/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php index e1e5503ad475f..1000821dd1897 100644 --- a/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php +++ b/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php @@ -8,7 +8,7 @@ use Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier\AbstractModifierTest; use Magento\Framework\UrlInterface; use Magento\Review\Ui\DataProvider\Product\Form\Modifier\Review; -use \Magento\Framework\Module\Manager as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Ui\DataProvider\Modifier\ModifierInterface; /** diff --git a/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php b/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php index 433be1c860988..5f1401a201e3f 100644 --- a/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php +++ b/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php @@ -12,7 +12,7 @@ use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Ui\Component\Form; use Magento\Framework\UrlInterface; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Framework\App\ObjectManager; /** diff --git a/app/code/Magento/Search/Block/Adminhtml/Dashboard/Last.php b/app/code/Magento/Search/Block/Adminhtml/Dashboard/Last.php index ad8d247b2a6fb..ff49f4a15b06a 100644 --- a/app/code/Magento/Search/Block/Adminhtml/Dashboard/Last.php +++ b/app/code/Magento/Search/Block/Adminhtml/Dashboard/Last.php @@ -24,7 +24,7 @@ class Last extends \Magento\Backend\Block\Dashboard\Grid protected $_queriesFactory; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -36,14 +36,14 @@ class Last extends \Magento\Backend\Block\Dashboard\Grid /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Search\Model\ResourceModel\Query\CollectionFactory $queriesFactory * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Search\Model\ResourceModel\Query\CollectionFactory $queriesFactory, array $data = [] ) { diff --git a/app/code/Magento/Search/Block/Adminhtml/Dashboard/Top.php b/app/code/Magento/Search/Block/Adminhtml/Dashboard/Top.php index 63893f788673d..3e10e1137d6b6 100644 --- a/app/code/Magento/Search/Block/Adminhtml/Dashboard/Top.php +++ b/app/code/Magento/Search/Block/Adminhtml/Dashboard/Top.php @@ -24,7 +24,7 @@ class Top extends \Magento\Backend\Block\Dashboard\Grid protected $_queriesFactory; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -36,14 +36,14 @@ class Top extends \Magento\Backend\Block\Dashboard\Grid /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Search\Model\ResourceModel\Query\CollectionFactory $queriesFactory * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Search\Model\ResourceModel\Query\CollectionFactory $queriesFactory, array $data = [] ) { diff --git a/app/code/Magento/Swatches/Observer/AddFieldsToAttributeObserver.php b/app/code/Magento/Swatches/Observer/AddFieldsToAttributeObserver.php index 3ef202af95a1a..303f1eda2e40a 100644 --- a/app/code/Magento/Swatches/Observer/AddFieldsToAttributeObserver.php +++ b/app/code/Magento/Swatches/Observer/AddFieldsToAttributeObserver.php @@ -6,7 +6,7 @@ namespace Magento\Swatches\Observer; use Magento\Config\Model\Config\Source; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Event\Observer as EventObserver; use Magento\Framework\Event\ObserverInterface; @@ -21,15 +21,15 @@ class AddFieldsToAttributeObserver implements ObserverInterface protected $yesNo; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Source\Yesno $yesNo */ - public function __construct(ModuleManagerInterface $moduleManager, Source\Yesno $yesNo) + public function __construct(Manager $moduleManager, Source\Yesno $yesNo) { $this->moduleManager = $moduleManager; $this->yesNo = $yesNo; diff --git a/app/code/Magento/Swatches/Observer/AddSwatchAttributeTypeObserver.php b/app/code/Magento/Swatches/Observer/AddSwatchAttributeTypeObserver.php index ca75da3321698..fb8c185cc545b 100644 --- a/app/code/Magento/Swatches/Observer/AddSwatchAttributeTypeObserver.php +++ b/app/code/Magento/Swatches/Observer/AddSwatchAttributeTypeObserver.php @@ -6,7 +6,7 @@ namespace Magento\Swatches\Observer; use Magento\Config\Model\Config\Source; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Event\Observer as EventObserver; use Magento\Framework\Event\ObserverInterface; @@ -16,14 +16,14 @@ class AddSwatchAttributeTypeObserver implements ObserverInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php b/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php index f8ba5c20250ad..45c680366264b 100644 --- a/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php @@ -10,7 +10,7 @@ */ class AddFieldsToAttributeObserverTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; /** @var \Magento\Config\Model\Config\Source\Yesno|\PHPUnit_Framework_MockObject_MockObject */ diff --git a/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php b/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php index 24afa1045e5cb..f78797d93cb0d 100644 --- a/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php @@ -10,7 +10,7 @@ */ class AddSwatchAttributeTypeObserverTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; /** @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject */ diff --git a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php index bba9bc3f3ebe7..4eb3995448709 100644 --- a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php @@ -34,7 +34,7 @@ class ContextPlugin /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -50,7 +50,7 @@ class ContextPlugin * @param \Magento\Framework\App\Http\Context $httpContext * @param \Magento\Tax\Model\Calculation\Proxy $calculation * @param \Magento\Tax\Helper\Data $taxHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\PageCache\Model\Config $cacheConfig */ public function __construct( @@ -58,7 +58,7 @@ public function __construct( \Magento\Framework\App\Http\Context $httpContext, \Magento\Tax\Model\Calculation\Proxy $calculation, \Magento\Tax\Helper\Data $taxHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\PageCache\Model\Config $cacheConfig ) { $this->customerSession = $customerSession; diff --git a/app/code/Magento/Tax/Observer/AfterAddressSaveObserver.php b/app/code/Magento/Tax/Observer/AfterAddressSaveObserver.php index ef84eac32e95a..cf5d939b35c01 100644 --- a/app/code/Magento/Tax/Observer/AfterAddressSaveObserver.php +++ b/app/code/Magento/Tax/Observer/AfterAddressSaveObserver.php @@ -8,7 +8,7 @@ use Magento\Customer\Model\Address; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; use Magento\Tax\Helper\Data; @@ -26,7 +26,7 @@ class AfterAddressSaveObserver implements ObserverInterface /** * Module manager * - * @var ModuleManagerInterface + * @var Manager */ private $moduleManager; @@ -46,13 +46,13 @@ class AfterAddressSaveObserver implements ObserverInterface /** * @param Data $taxHelper - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Config $cacheConfig * @param TaxAddressManagerInterface $addressManager */ public function __construct( Data $taxHelper, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, Config $cacheConfig, TaxAddressManagerInterface $addressManager ) { diff --git a/app/code/Magento/Tax/Observer/CustomerLoggedInObserver.php b/app/code/Magento/Tax/Observer/CustomerLoggedInObserver.php index 00b3a9f9e09ad..c1e4ad66d75d7 100644 --- a/app/code/Magento/Tax/Observer/CustomerLoggedInObserver.php +++ b/app/code/Magento/Tax/Observer/CustomerLoggedInObserver.php @@ -9,7 +9,7 @@ use Magento\Customer\Model\Session; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; use Magento\Tax\Helper\Data; @@ -33,7 +33,7 @@ class CustomerLoggedInObserver implements ObserverInterface /** * Module manager * - * @var ModuleManagerInterface + * @var Manager */ private $moduleManager; @@ -60,7 +60,7 @@ class CustomerLoggedInObserver implements ObserverInterface * @param GroupRepositoryInterface $groupRepository * @param Session $customerSession * @param Data $taxHelper - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Config $cacheConfig * @param TaxAddressManagerInterface $addressManager */ @@ -68,7 +68,7 @@ public function __construct( GroupRepositoryInterface $groupRepository, Session $customerSession, Data $taxHelper, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, Config $cacheConfig, TaxAddressManagerInterface $addressManager ) { diff --git a/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php b/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php index 020baa0c30ec5..a6c7e9bb8685a 100644 --- a/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php @@ -38,7 +38,7 @@ class ContextPluginTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManagerMock; @@ -89,7 +89,7 @@ protected function setUp() ) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php b/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php index 2e957e528e294..571cc7173bc92 100644 --- a/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php +++ b/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php @@ -6,7 +6,7 @@ namespace Magento\Tax\Test\Unit\Observer; use Magento\Framework\Event\Observer; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; @@ -31,7 +31,7 @@ class AfterAddressSaveObserverTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManagerMock; @@ -65,7 +65,7 @@ protected function setUp() ->setMethods(['getCustomerAddress']) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); @@ -77,7 +77,7 @@ protected function setUp() ->setMethods(['isCatalogPriceDisplayAffectedByTax']) ->disableOriginalConstructor() ->getMock(); - + $this->addressManagerMock = $this->getMockBuilder(TaxAddressManagerInterface::class) ->setMethods(['setDefaultAddressAfterSave', 'setDefaultAddressAfterLogIn']) ->disableOriginalConstructor() diff --git a/app/code/Magento/Tax/Test/Unit/Observer/CustomerLoggedInObserverTest.php b/app/code/Magento/Tax/Test/Unit/Observer/CustomerLoggedInObserverTest.php index facbb6733b5c8..c577f1727552f 100644 --- a/app/code/Magento/Tax/Test/Unit/Observer/CustomerLoggedInObserverTest.php +++ b/app/code/Magento/Tax/Test/Unit/Observer/CustomerLoggedInObserverTest.php @@ -31,7 +31,7 @@ class CustomerLoggedInObserverTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManagerMock; @@ -82,7 +82,7 @@ protected function setUp() ) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Tax/view/frontend/layout/sales_email_item_price.xml b/app/code/Magento/Tax/view/frontend/layout/sales_email_item_price.xml index 5dc1e5c72313d..35bcfc265eafc 100644 --- a/app/code/Magento/Tax/view/frontend/layout/sales_email_item_price.xml +++ b/app/code/Magento/Tax/view/frontend/layout/sales_email_item_price.xml @@ -5,8 +5,7 @@ * See COPYING.txt for license details. */ --> -<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="items"> <block class="Magento\Tax\Block\Item\Price\Renderer" name="item_price" template="Magento_Tax::email/items/price/row.phtml"> @@ -16,11 +15,4 @@ </block> </referenceBlock> </body> -</page> - - - - - - - +</page> \ No newline at end of file diff --git a/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php b/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php index 5d5426660d8f1..aae6f769eb500 100644 --- a/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php @@ -33,7 +33,7 @@ class ContextPlugin protected $weeeHelper; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -63,7 +63,7 @@ class ContextPlugin * @param \Magento\Weee\Model\Tax $weeeTax * @param \Magento\Tax\Helper\Data $taxHelper * @param \Magento\Weee\Helper\Data $weeeHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\PageCache\Model\Config $cacheConfig * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig @@ -74,7 +74,7 @@ public function __construct( \Magento\Weee\Model\Tax $weeeTax, \Magento\Tax\Helper\Data $taxHelper, \Magento\Weee\Helper\Data $weeeHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\PageCache\Model\Config $cacheConfig, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig diff --git a/app/code/Magento/Weee/Observer/AfterAddressSave.php b/app/code/Magento/Weee/Observer/AfterAddressSave.php index 9acea506adf67..ba15854b2dff4 100644 --- a/app/code/Magento/Weee/Observer/AfterAddressSave.php +++ b/app/code/Magento/Weee/Observer/AfterAddressSave.php @@ -8,7 +8,7 @@ use Magento\Customer\Model\Address; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; use Magento\Weee\Helper\Data; @@ -26,7 +26,7 @@ class AfterAddressSave implements ObserverInterface /** * Module manager * - * @var ModuleManagerInterface + * @var Manager */ private $moduleManager; @@ -46,13 +46,13 @@ class AfterAddressSave implements ObserverInterface /** * @param Data $weeeHelper - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Config $cacheConfig * @param TaxAddressManagerInterface $addressManager */ public function __construct( Data $weeeHelper, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, Config $cacheConfig, TaxAddressManagerInterface $addressManager ) { diff --git a/app/code/Magento/Weee/Observer/CustomerLoggedIn.php b/app/code/Magento/Weee/Observer/CustomerLoggedIn.php index 95299d96cabd2..0b22c24d7fa25 100644 --- a/app/code/Magento/Weee/Observer/CustomerLoggedIn.php +++ b/app/code/Magento/Weee/Observer/CustomerLoggedIn.php @@ -8,7 +8,7 @@ use Magento\Customer\Model\Session; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; use Magento\Weee\Helper\Data; @@ -52,13 +52,13 @@ class CustomerLoggedIn implements ObserverInterface /** * @param Data $weeeHelper - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Config $cacheConfig * @param TaxAddressManagerInterface $addressManager */ public function __construct( Data $weeeHelper, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, Config $cacheConfig, TaxAddressManagerInterface $addressManager ) { diff --git a/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php b/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php index b720f42378fa9..c829b524527a6 100644 --- a/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php @@ -39,7 +39,7 @@ class ContextPluginTest extends \PHPUnit\Framework\TestCase protected $taxCalculationMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManagerMock; @@ -93,7 +93,7 @@ protected function setUp() ) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Weee/Test/Unit/Observer/AfterAddressSaveTest.php b/app/code/Magento/Weee/Test/Unit/Observer/AfterAddressSaveTest.php index a7b88f5727126..868d603f34b8c 100644 --- a/app/code/Magento/Weee/Test/Unit/Observer/AfterAddressSaveTest.php +++ b/app/code/Magento/Weee/Test/Unit/Observer/AfterAddressSaveTest.php @@ -18,7 +18,7 @@ class AfterAddressSaveTest extends \PHPUnit\Framework\TestCase * @var ObjectManager */ private $objectManager; - + /** * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject */ @@ -27,7 +27,7 @@ class AfterAddressSaveTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManagerMock; @@ -42,7 +42,7 @@ class AfterAddressSaveTest extends \PHPUnit\Framework\TestCase * @var \Magento\Weee\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ private $weeeHelperMock; - + /** * @var TaxAddressManagerInterface|MockObject */ @@ -61,7 +61,7 @@ protected function setUp() ->setMethods(['getCustomerAddress']) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); @@ -129,7 +129,7 @@ public function testExecute( $this->addressManagerMock->expects($isNeedSetAddress ? $this->once() : $this->never()) ->method('setDefaultAddressAfterSave') ->with($address); - + $this->session->execute($this->observerMock); } diff --git a/app/code/Magento/Weee/Test/Unit/Observer/CustomerLoggedInTest.php b/app/code/Magento/Weee/Test/Unit/Observer/CustomerLoggedInTest.php index 06d1dbedcfd80..af8c2e70a8ff6 100644 --- a/app/code/Magento/Weee/Test/Unit/Observer/CustomerLoggedInTest.php +++ b/app/code/Magento/Weee/Test/Unit/Observer/CustomerLoggedInTest.php @@ -21,7 +21,7 @@ class CustomerLoggedInTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManagerMock; @@ -59,7 +59,7 @@ protected function setUp() ) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Wishlist/Test/Unit/Helper/RssTest.php b/app/code/Magento/Wishlist/Test/Unit/Helper/RssTest.php index b55766d77fee3..d0397be83fac7 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Helper/RssTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Helper/RssTest.php @@ -46,7 +46,7 @@ class RssTest extends \PHPUnit\Framework\TestCase protected $customerRepositoryMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; @@ -80,7 +80,7 @@ protected function setUp() $this->customerRepositoryMock = $this->getMockBuilder(\Magento\Customer\Api\CustomerRepositoryInterface::class) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/etc/di.xml b/app/etc/di.xml index edb206a83c00a..2863c5d4708df 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -65,7 +65,6 @@ <preference for="Magento\Framework\Config\CacheInterface" type="Magento\Framework\App\Cache\Type\Config" /> <preference for="Magento\Framework\Config\ValidationStateInterface" type="Magento\Framework\App\Arguments\ValidationState" /> <preference for="Magento\Framework\Module\ModuleListInterface" type="Magento\Framework\Module\ModuleList" /> - <preference for="Magento\Framework\Module\ModuleManagerInterface" type="Magento\Framework\Module\Manager" /> <preference for="Magento\Framework\Component\ComponentRegistrarInterface" type="Magento\Framework\Component\ComponentRegistrar"/> <preference for="Magento\Framework\Event\ConfigInterface" type="Magento\Framework\Event\Config" /> <preference for="Magento\Framework\Event\InvokerInterface" type="Magento\Framework\Event\Invoker\InvokerDefault" /> diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/AddressTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/AddressTest.php index b159dceadfb77..c5b76807f1ff9 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/AddressTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/AddressTest.php @@ -69,7 +69,7 @@ public function testGetCustomer() public function testGetCustomerMissingCustomer() { - $moduleManager = $this->objectManager->get(\Magento\Framework\Module\ModuleManagerInterface::class); + $moduleManager = $this->objectManager->get(\Magento\Framework\Module\Manager::class); if ($moduleManager->isEnabled('Magento_PageCache')) { $customerDataFactory = $this->objectManager->create( \Magento\Customer\Api\Data\CustomerInterfaceFactory::class diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php index 9417baea67ba9..ff8e7db0f4260 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php @@ -1982,8 +1982,8 @@ ['_escapeDefaultValue', 'Magento\Framework\Code\Generator\EntityAbstract'], ['urlEncode', 'Magento\Framework\App\Helper\AbstractHelper', 'Magento\Framework\Url\EncoderInterface::encode'], ['urlDecode', 'Magento\Framework\App\Helper\AbstractHelper', 'Magento\Framework\Url\DecoderInterface::decode'], - ['isModuleEnabled', 'Magento\Framework\App\Helper\AbstractHelper', '\Magento\Framework\Module\ModuleManagerInterface::isEnabled()'], - ['isModuleOutputEnabled', 'Magento\Framework\App\Helper\AbstractHelper', '\Magento\Framework\Module\ModuleManagerInterface::isOutputEnabled()'], + ['isModuleEnabled', 'Magento\Framework\App\Helper\AbstractHelper', 'Magento\Framework\Module\Manager::isEnabled()'], + ['isModuleOutputEnabled', 'Magento\Framework\App\Helper\AbstractHelper', 'Magento\Framework\Module\Manager::isOutputEnabled()'], ['_packToTar', 'Magento\Framework\Archive\Tar'], ['_parseHeader', 'Magento\Framework\Archive\Tar'], ['getIdentities', 'Magento\Wishlist\Block\Link'], diff --git a/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php b/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php index 7875e0c8885f5..1a76610bc0811 100644 --- a/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php +++ b/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php @@ -27,7 +27,7 @@ abstract class AbstractHelper protected $_request; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -125,7 +125,7 @@ protected function _getModuleName() * * @param string $moduleName Full module name * @return boolean - * use \Magento\Framework\Module\ModuleManagerInterface::isOutputEnabled() + * use \Magento\Framework\Module\Manager::isOutputEnabled() */ public function isModuleOutputEnabled($moduleName = null) { diff --git a/lib/internal/Magento/Framework/App/Helper/Context.php b/lib/internal/Magento/Framework/App/Helper/Context.php index cc57f109cc8ec..5b90df8c55205 100644 --- a/lib/internal/Magento/Framework/App/Helper/Context.php +++ b/lib/internal/Magento/Framework/App/Helper/Context.php @@ -21,7 +21,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -79,7 +79,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface * @param \Magento\Framework\Url\EncoderInterface $urlEncoder * @param \Magento\Framework\Url\DecoderInterface $urlDecoder * @param \Psr\Log\LoggerInterface $logger - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Framework\App\RequestInterface $httpRequest * @param \Magento\Framework\Cache\ConfigInterface $cacheConfig * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -94,7 +94,7 @@ public function __construct( \Magento\Framework\Url\EncoderInterface $urlEncoder, \Magento\Framework\Url\DecoderInterface $urlDecoder, \Psr\Log\LoggerInterface $logger, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Framework\App\RequestInterface $httpRequest, \Magento\Framework\Cache\ConfigInterface $cacheConfig, \Magento\Framework\Event\ManagerInterface $eventManager, @@ -119,7 +119,7 @@ public function __construct( /** * Get module manager. * - * @return \Magento\Framework\Module\ModuleManagerInterface + * @return \Magento\Framework\Module\Manager */ public function getModuleManager() { diff --git a/lib/internal/Magento/Framework/Module/Manager.php b/lib/internal/Magento/Framework/Module/Manager.php index 659ada3c20ac8..b47349631a033 100644 --- a/lib/internal/Magento/Framework/Module/Manager.php +++ b/lib/internal/Magento/Framework/Module/Manager.php @@ -12,9 +12,14 @@ namespace Magento\Framework\Module; /** - * @inheritdoc + * Module status manager + * + * Usage: + * ```php + * $manager->isEnabled('Vendor_Module'); + * ``` */ -class Manager implements ModuleManagerInterface +class Manager { /** * @var Output\ConfigInterface @@ -49,9 +54,12 @@ public function __construct( } /** - * @inheritdoc + * Whether a module is enabled in the configuration or not + * + * @param string $moduleName Fully-qualified module name + * @return boolean */ - public function isEnabled(string $moduleName): bool + public function isEnabled($moduleName) { return $this->moduleList->has($moduleName); } diff --git a/lib/internal/Magento/Framework/Module/ModuleManagerInterface.php b/lib/internal/Magento/Framework/Module/ModuleManagerInterface.php deleted file mode 100644 index decc91200354d..0000000000000 --- a/lib/internal/Magento/Framework/Module/ModuleManagerInterface.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\Module; - -/** - * Module status manager - * - * Usage: - * ```php - * $manager->isEnabled('Vendor_Module'); - * ``` - */ -interface ModuleManagerInterface -{ - /** - * Retrieve whether or not a module is enabled by configuration - * - * @param string $moduleName Fully-qualified module name, e.g. Magento_Config - * @return boolean Whether or not the module is enabled in the configuration - */ - public function isEnabled(string $moduleName): bool; -} diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php index e4cf4c41599e9..748474943a436 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php @@ -16,7 +16,7 @@ class ManagerTest extends \PHPUnit\Framework\TestCase const XML_PATH_OUTPUT_ENABLED = 'custom/is_module_output_enabled'; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $_model; @@ -73,7 +73,6 @@ public function testIsEnabled() public function testIsOutputEnabledReturnsFalseForDisabledModule() { - $this->_moduleList->expects($this->once())->method('has')->with('Disabled_Module')->willReturn(false); $this->_outputConfig->expects($this->any())->method('isSetFlag')->will($this->returnValue(true)); $this->assertFalse($this->_model->isOutputEnabled('Disabled_Module')); } diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php index 7a631eed1adbf..bfd916dbfba5b 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php @@ -35,7 +35,7 @@ class DbStatusValidatorTest extends \PHPUnit\Framework\TestCase protected $requestMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManager; diff --git a/lib/internal/Magento/Framework/View/File/Collector/Decorator/ModuleOutput.php b/lib/internal/Magento/Framework/View/File/Collector/Decorator/ModuleOutput.php index 71fa8d2c0ae6b..34f32b2f6b7b2 100644 --- a/lib/internal/Magento/Framework/View/File/Collector/Decorator/ModuleOutput.php +++ b/lib/internal/Magento/Framework/View/File/Collector/Decorator/ModuleOutput.php @@ -6,7 +6,7 @@ namespace Magento\Framework\View\File\Collector\Decorator; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\View\Design\ThemeInterface; use Magento\Framework\View\File; use Magento\Framework\View\File\CollectorInterface; @@ -26,7 +26,7 @@ class ModuleOutput implements CollectorInterface /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -38,7 +38,7 @@ class ModuleOutput implements CollectorInterface */ public function __construct( CollectorInterface $subject, - ModuleManagerInterface $moduleManager + Manager $moduleManager ) { $this->subject = $subject; $this->moduleManager = $moduleManager; From 9687ccf68d7d6c8b6059e3bc018e28ac60915962 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov <ishakhsuvarov@magento.com> Date: Fri, 9 Aug 2019 15:37:29 -0500 Subject: [PATCH 284/372] MSI-2471: Fix Elasticsearch support for MSI --- .../Indexer/Fulltext/Action/DataProvider.php | 81 ------------ .../Plugin/StockedProductsFilterPlugin.php | 91 +++++++++++++ .../StockedProductsFilterPluginTest.php | 125 ++++++++++++++++++ app/code/Magento/CatalogSearch/etc/di.xml | 3 + 4 files changed, 219 insertions(+), 81 deletions(-) create mode 100644 app/code/Magento/CatalogSearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php create mode 100644 app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index 09d4f0068459a..cd2529a8fd725 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -7,14 +7,9 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product\Attribute\Source\Status; -use Magento\CatalogInventory\Api\Data\StockStatusInterface; -use Magento\CatalogInventory\Api\StockConfigurationInterface; -use Magento\CatalogInventory\Api\StockStatusCriteriaInterface; -use Magento\CatalogInventory\Api\StockStatusRepositoryInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Select; use Magento\Store\Model\Store; -use Magento\Framework\App\ObjectManager; /** * Catalog search full test search data provider. @@ -129,16 +124,6 @@ class DataProvider */ private $antiGapMultiplier; - /** - * @var StockConfigurationInterface - */ - private $stockConfiguration; - - /** - * @var StockStatusRepositoryInterface - */ - private $stockStatusRepository; - /** * @param ResourceConnection $resource * @param \Magento\Catalog\Model\Product\Type $catalogProductType @@ -563,8 +548,6 @@ public function prepareProductIndex($indexData, $productData, $storeId) { $index = []; - $indexData = $this->filterOutOfStockProducts($indexData, $storeId); - foreach ($this->getSearchableAttributes('static') as $attribute) { $attributeCode = $attribute->getAttributeCode(); @@ -689,68 +672,4 @@ private function filterAttributeValue($value) { return preg_replace('/\s+/iu', ' ', trim(strip_tags($value))); } - - /** - * Filter out of stock products for products. - * - * @param array $indexData - * @param int $storeId - * @return array - */ - private function filterOutOfStockProducts($indexData, $storeId): array - { - if (!$this->getStockConfiguration()->isShowOutOfStock($storeId)) { - $productIds = array_keys($indexData); - $stockStatusCriteria = $this->createStockStatusCriteria(); - $stockStatusCriteria->setProductsFilter($productIds); - $stockStatusCollection = $this->getStockStatusRepository()->getList($stockStatusCriteria); - $stockStatuses = $stockStatusCollection->getItems(); - $stockStatuses = array_filter( - $stockStatuses, - function (StockStatusInterface $stockStatus) { - return StockStatusInterface::STATUS_IN_STOCK == $stockStatus->getStockStatus(); - } - ); - $indexData = array_intersect_key($indexData, $stockStatuses); - } - return $indexData; - } - - /** - * Get stock configuration. - * - * @return StockConfigurationInterface - */ - private function getStockConfiguration() - { - if (null === $this->stockConfiguration) { - $this->stockConfiguration = ObjectManager::getInstance()->get(StockConfigurationInterface::class); - } - return $this->stockConfiguration; - } - - /** - * Create stock status criteria. - * - * Substitution of autogenerated factory in backward compatibility reasons. - * - * @return StockStatusCriteriaInterface - */ - private function createStockStatusCriteria() - { - return ObjectManager::getInstance()->create(StockStatusCriteriaInterface::class); - } - - /** - * Get stock status repository. - * - * @return StockStatusRepositoryInterface - */ - private function getStockStatusRepository() - { - if (null === $this->stockStatusRepository) { - $this->stockStatusRepository = ObjectManager::getInstance()->get(StockStatusRepositoryInterface::class); - } - return $this->stockStatusRepository; - } } diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php b/app/code/Magento/CatalogSearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php new file mode 100644 index 0000000000000..02e48c5d8a1c0 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php @@ -0,0 +1,91 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogSearch\Model\Indexer\Plugin; + +use Magento\CatalogInventory\Api\StockConfigurationInterface; +use Magento\CatalogInventory\Api\StockStatusRepositoryInterface; +use Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory; +use Magento\CatalogInventory\Api\Data\StockStatusInterface; +use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider; + +/** + * Plugin for filtering child products that are out of stock for preventing their saving to catalog search index. + * + * This plugin reverts changes introduced in commit 9ab466d8569ea556cb01393989579c3aac53d9a3 which break extensions + * relying on stocks. Plugin location is changed for consistency purposes. + */ +class StockedProductsFilterPlugin +{ + /** + * @var StockConfigurationInterface + */ + private $stockConfiguration; + + /** + * @var StockStatusRepositoryInterface + */ + private $stockStatusRepository; + + /** + * @var StockStatusCriteriaInterfaceFactory + */ + private $stockStatusCriteriaFactory; + + /** + * @param StockConfigurationInterface $stockConfiguration + * @param StockStatusRepositoryInterface $stockStatusRepository + * @param StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory + */ + public function __construct( + StockConfigurationInterface $stockConfiguration, + StockStatusRepositoryInterface $stockStatusRepository, + StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory + ) { + $this->stockConfiguration = $stockConfiguration; + $this->stockStatusRepository = $stockStatusRepository; + $this->stockStatusCriteriaFactory = $stockStatusCriteriaFactory; + } + + /** + * Filter out of stock options for configurable product. + * + * @param DataProvider $dataProvider + * @param array $indexData + * @param array $productData + * @param int $storeId + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforePrepareProductIndex( + DataProvider $dataProvider, + array $indexData, + array $productData, + int $storeId + ): array { + if (!$this->stockConfiguration->isShowOutOfStock($storeId)) { + $productIds = array_keys($indexData); + $stockStatusCriteria = $this->stockStatusCriteriaFactory->create(); + $stockStatusCriteria->setProductsFilter($productIds); + $stockStatusCollection = $this->stockStatusRepository->getList($stockStatusCriteria); + $stockStatuses = $stockStatusCollection->getItems(); + $stockStatuses = array_filter( + $stockStatuses, + function (StockStatusInterface $stockStatus) { + return StockStatusInterface::STATUS_IN_STOCK == $stockStatus->getStockStatus(); + } + ); + $indexData = array_intersect_key($indexData, $stockStatuses); + } + + return [ + $indexData, + $productData, + $storeId, + ]; + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php new file mode 100644 index 0000000000000..eb3060c16a143 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogSearch\Test\Unit\Model\Indexer\Plugin; + +use Magento\CatalogSearch\Model\Indexer\Plugin\StockedProductsFilterPlugin; +use Magento\CatalogInventory\Api\StockConfigurationInterface; +use Magento\CatalogInventory\Api\StockStatusRepositoryInterface; +use Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory; +use Magento\CatalogInventory\Api\StockStatusCriteriaInterface; +use Magento\CatalogInventory\Api\Data\StockStatusCollectionInterface; +use Magento\CatalogInventory\Api\Data\StockStatusInterface; +use Magento\CatalogInventory\Model\Stock; +use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider; + +/** + * Test for Magento\CatalogSearch\Model\Indexer\Plugin\StockedProductsFilterPlugin class. + * + * This plugin reverts changes introduced in commit 9ab466d8569ea556cb01393989579c3aac53d9a3 which break extensions + * relying on stocks. Plugin location is changed for consistency purposes. + */ +class StockedProductsFilterPluginTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var StockConfigurationInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $stockConfigurationMock; + + /** + * @var StockStatusRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $stockStatusRepositoryMock; + + /** + * @var StockStatusCriteriaInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $stockStatusCriteriaFactoryMock; + + /** + * @var StockedProductsFilterPlugin + */ + private $plugin; + + /** + * {@inheritdoc} + */ + protected function setUp() + { + $this->stockConfigurationMock = $this->getMockBuilder(StockConfigurationInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->stockStatusRepositoryMock = $this->getMockBuilder(StockStatusRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->stockStatusCriteriaFactoryMock = $this->getMockBuilder(StockStatusCriteriaInterfaceFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->plugin = new StockedProductsFilterPlugin( + $this->stockConfigurationMock, + $this->stockStatusRepositoryMock, + $this->stockStatusCriteriaFactoryMock + ); + } + + /** + * @return void + */ + public function testBeforePrepareProductIndex(): void + { + /** @var DataProvider|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */ + $dataProviderMock = $this->getMockBuilder(DataProvider::class)->disableOriginalConstructor()->getMock(); + $indexData = [ + 1 => [], + 2 => [], + ]; + $productData = []; + $storeId = 1; + + $this->stockConfigurationMock + ->expects($this->once()) + ->method('isShowOutOfStock') + ->willReturn(false); + + $stockStatusCriteriaMock = $this->getMockBuilder(StockStatusCriteriaInterface::class)->getMock(); + $stockStatusCriteriaMock + ->expects($this->once()) + ->method('setProductsFilter') + ->willReturn(true); + $this->stockStatusCriteriaFactoryMock + ->expects($this->once()) + ->method('create') + ->willReturn($stockStatusCriteriaMock); + + $stockStatusMock = $this->getMockBuilder(StockStatusInterface::class)->getMock(); + $stockStatusMock->expects($this->atLeastOnce()) + ->method('getStockStatus') + ->willReturnOnConsecutiveCalls(Stock::STOCK_IN_STOCK, Stock::STOCK_OUT_OF_STOCK); + $stockStatusCollectionMock = $this->getMockBuilder(StockStatusCollectionInterface::class)->getMock(); + $stockStatusCollectionMock + ->expects($this->once()) + ->method('getItems') + ->willReturn([ + 1 => $stockStatusMock, + 2 => $stockStatusMock, + ]); + $this->stockStatusRepositoryMock + ->expects($this->once()) + ->method('getList') + ->willReturn($stockStatusCollectionMock); + + list ($indexData, $productData, $storeId) = $this->plugin->beforePrepareProductIndex( + $dataProviderMock, + $indexData, + $productData, + $storeId + ); + + $this->assertEquals([1], array_keys($indexData)); + } +} diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml index 28d5035308dee..63de2dc00926b 100644 --- a/app/code/Magento/CatalogSearch/etc/di.xml +++ b/app/code/Magento/CatalogSearch/etc/di.xml @@ -373,4 +373,7 @@ </argument> </arguments> </type> + <type name="Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider"> + <plugin name="stockedProductsFilterPlugin" type="Magento\CatalogSearch\Model\Indexer\Plugin\StockedProductsFilterPlugin"/> + </type> </config> From fa628ed3f3134dcd319a0e57a961ff6323f6ef30 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov <ishakhsuvarov@magento.com> Date: Fri, 9 Aug 2019 16:59:37 -0500 Subject: [PATCH 285/372] MSI-2471: Fixed static test failure --- .../Model/Indexer/Plugin/StockedProductsFilterPluginTest.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php index eb3060c16a143..b9909ec2c74b2 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php @@ -104,10 +104,7 @@ public function testBeforePrepareProductIndex(): void $stockStatusCollectionMock ->expects($this->once()) ->method('getItems') - ->willReturn([ - 1 => $stockStatusMock, - 2 => $stockStatusMock, - ]); + ->willReturn([1 => $stockStatusMock, 2 => $stockStatusMock]); $this->stockStatusRepositoryMock ->expects($this->once()) ->method('getList') From fd73c392026c990721600e5e49f4b096973d99c7 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Mon, 12 Aug 2019 15:35:51 +0300 Subject: [PATCH 286/372] MC-19075: Html text are visible on frontend --- .../Checkout/view/frontend/templates/onepage/review/item.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml index 2a7ccc38e9d83..8e83526b4ceaa 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml @@ -30,7 +30,7 @@ $taxDataHelper = $this->helper(Magento\Tax\Helper\Data::class); <?php if (isset($_formatedOptionValue['full_view'])) :?> <?= $block->escapeHtml($_formatedOptionValue['full_view']) ?> <?php else :?> - <?= $block->escapeHtml($_formatedOptionValue['value']) ?> + <?= /* @noEscape */ $_formatedOptionValue['value'] ?> <?php endif; ?> </dd> <?php endforeach; ?> From ee853472c01c0d7e02da6f8659d0f13657a47854 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Mon, 12 Aug 2019 18:18:55 +0300 Subject: [PATCH 287/372] MC-19140: [DHL] You are still on New Shipment page after creating the shipment --- .../view/adminhtml/templates/order/packaging/popup.phtml | 2 +- .../Magento/Shipping/view/adminhtml/templates/view/form.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml index cd25cb919adb5..28322d9534926 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml @@ -31,7 +31,7 @@ $girthEnabled = $block->isDisplayGirthValue() && $block->isGirthAllowed() ? 1 : packaging.sendCreateLabelRequest(); }); packaging.setLabelCreatedCallback(function(response){ - setLocation("<?php $block->escapeJs($block->escapeUrl($block->getUrl( + setLocation("<?= $block->escapeJs($block->escapeUrl($block->getUrl( 'sales/order/view', ['order_id' => $block->getShipment()->getOrderId()] ))); ?>"); diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml index f105562151082..44fe4b9ccd353 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml @@ -85,7 +85,7 @@ $order = $block->getShipment()->getOrder(); window.packaging.sendCreateLabelRequest(); }); window.packaging.setLabelCreatedCallback(function () { - setLocation("<?php $block->escapeUrl($block->getUrl('adminhtml/order_shipment/view', ['shipment_id' => $block->getShipment()->getId()])); ?>"); + setLocation("<?= $block->escapeUrl($block->getUrl('adminhtml/order_shipment/view', ['shipment_id' => $block->getShipment()->getId()])); ?>"); }); }; From f49f1f5592c9263e339bf42f2e842cc1fcfe63e6 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 12 Aug 2019 11:48:59 -0500 Subject: [PATCH 288/372] MC-19061: Revert ticket MC-17003 --- .../Order/Creditmemo/Create/Adjustments.php | 16 ----- .../Order/Creditmemo/Create/Items.php | 17 +---- ...dminCheckingCreditMemoUpdateTotalsTest.xml | 3 + .../order/creditmemo/create/items.phtml | 3 - .../web/css/source/module/order/_total.less | 4 -- .../Adminhtml/Order/Creditmemo/Totals.php | 68 ------------------- .../Test/TestStep/CreateCreditMemoStep.php | 32 +-------- 7 files changed, 5 insertions(+), 138 deletions(-) diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php index 1210391f70ddb..50d29c195968c 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php @@ -111,20 +111,4 @@ public function getShippingLabel() } return $label; } - - /** - * Get update totals url. - * - * @return string - */ - public function getUpdateTotalsUrl(): string - { - return $this->getUrl( - 'sales/*/updateQty', - [ - 'order_id' => $this->getSource()->getOrderId(), - 'invoice_id' => $this->getRequest()->getParam('invoice_id', null), - ] - ); - } } diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php index 389c29bedf4c3..65163f9ed5d82 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php @@ -56,12 +56,7 @@ protected function _prepareLayout() $this->addChild( 'update_button', \Magento\Backend\Block\Widget\Button::class, - ['label' => __('Update Qty\'s'), 'class' => 'update-button secondary', 'onclick' => $onclick] - ); - $this->addChild( - 'update_totals_button', - \Magento\Backend\Block\Widget\Button::class, - ['label' => __('Update Totals'), 'class' => 'update-totals-button secondary', 'onclick' => $onclick] + ['label' => __('Update Qty\'s'), 'class' => 'update-button', 'onclick' => $onclick] ); if ($this->getCreditmemo()->canRefund()) { @@ -181,16 +176,6 @@ public function getUpdateButtonHtml() return $this->getChildHtml('update_button'); } - /** - * Get update totals button html - * - * @return string - */ - public function getUpdateTotalsButtonHtml(): string - { - return $this->getChildHtml('update_totals_button'); - } - /** * Get update url * diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml index 8cd2b8ee60edd..45ea09a06ed26 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml @@ -18,6 +18,9 @@ <testCaseId value="MC-18159"/> <useCaseId value="MC-17003"/> <group value="sales"/> + <skip> + <issueId value="MC-17003"/> + </skip> </annotations> <before> <!--Create product--> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml index 31aefd8d2ca57..16ab1750efeb6 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml @@ -100,7 +100,6 @@ <span class="title"><?= $block->escapeHtml(__('Refund Totals')) ?></span> </div> <?= $block->getChildHtml('creditmemo_totals') ?> - <div class="totals-actions"><?= $block->getUpdateTotalsButtonHtml() ?></div> <div class="order-totals-actions"> <div class="field choice admin__field admin__field-option field-append-comments"> <input id="notify_customer" @@ -140,8 +139,6 @@ require(['jquery'], function(jQuery){ //<![CDATA[ var submitButtons = jQuery('.submit-button'); -var updateButtons = jQuery('.update-button,.update-totals-button'); -var fields = jQuery('.qty-input,.order-subtotal-table input[type="text"]'); function enableButtons(buttons) { buttons.removeClass('disabled').prop('disabled', false); diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less index 6e663b15c89cc..f2369ad8f35e1 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less @@ -22,10 +22,6 @@ } } -.totals-actions { - text-align: right; -} - .order-totals-actions { margin-top: @indent__s; .actions { diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php index 28bb00757dac1..d98c5696c81f8 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php @@ -27,34 +27,6 @@ class Totals extends \Magento\Sales\Test\Block\Adminhtml\Order\Totals */ protected $capture = '[name="invoice[capture_case]"]'; - /** - * Refund Shipping css selector. - * - * @var string - */ - private $refundShippingSelector = '#shipping_amount'; - - /** - * Adjustment Refund css selector. - * - * @var string - */ - private $adjustmentRefundSelector = '#adjustment_positive'; - - /** - * Adjustment Fee css selector. - * - * @var string - */ - private $adjustmentFeeSelector = '#adjustment_negative'; - - /** - * Update Totals button css selector. - * - * @var string - */ - private $updateTotalsSelector = '.update-totals-button'; - /** * Submit invoice. * @@ -85,44 +57,4 @@ public function setCaptureOption($option) { $this->_rootElement->find($this->capture, Locator::SELECTOR_CSS, 'select')->setValue($option); } - - /** - * Get Refund Shipping input element. - * - * @return \Magento\Mtf\Client\ElementInterface - */ - public function getRefundShippingElement() - { - return $this->_rootElement->find($this->refundShippingSelector, Locator::SELECTOR_CSS); - } - - /** - * Get Adjustment Refund input element. - * - * @return \Magento\Mtf\Client\ElementInterface - */ - public function getAdjustmentRefundElement() - { - return $this->_rootElement->find($this->adjustmentRefundSelector, Locator::SELECTOR_CSS); - } - - /** - * Get Adjustment Fee input element. - * - * @return \Magento\Mtf\Client\ElementInterface - */ - public function getAdjustmentFeeElement() - { - return $this->_rootElement->find($this->adjustmentFeeSelector, Locator::SELECTOR_CSS); - } - - /** - * Click update totals button. - * - * @return void - */ - public function clickUpdateTotals() - { - $this->_rootElement->find($this->updateTotalsSelector)->click(); - } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php index 25b576a06dd3f..45298c5898c25 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php @@ -95,12 +95,8 @@ public function run() if ($this->compare($items, $refundData)) { $this->orderCreditMemoNew->getFormBlock()->updateQty(); } - $hasChangeTotals = $this->isTotalsDataChanged($refundData); - $this->orderCreditMemoNew->getFormBlock()->fillFormData($refundData); - if ($hasChangeTotals) { - $this->orderCreditMemoNew->getTotalsBlock()->clickUpdateTotals(); - } + $this->orderCreditMemoNew->getFormBlock()->fillFormData($refundData); $this->orderCreditMemoNew->getFormBlock()->submit(); } @@ -120,30 +116,4 @@ protected function getCreditMemoIds() $this->salesOrderView->getOrderForm()->openTab('creditmemos'); return $this->salesOrderView->getOrderForm()->getTab('creditmemos')->getGridBlock()->getIds(); } - - /** - * Is totals data changed. - * - * @param array $data - * @return bool - */ - private function isTotalsDataChanged(array $data): bool - { - $compareData = [ - 'shipping_amount' => - $this->orderCreditMemoNew->getTotalsBlock()->getRefundShippingElement()->getValue(), - 'adjustment_positive' => - $this->orderCreditMemoNew->getTotalsBlock()->getAdjustmentRefundElement()->getValue(), - 'adjustment_negative' => - $this->orderCreditMemoNew->getTotalsBlock()->getAdjustmentFeeElement()->getValue(), - ]; - - foreach ($compareData as $fieldName => $fieldValue) { - if (isset($data['form_data'][$fieldName]) && $fieldValue != $data['form_data'][$fieldName]) { - return true; - } - } - - return false; - } } From 09ec6714cc137b411d8facb3025164d94429e910 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Mon, 12 Aug 2019 14:08:56 -0500 Subject: [PATCH 289/372] MC-19115: Admin Analytics tracking should be enabled by default - Added caching in product metadata to improve performance --- .../Magento/Framework/App/ProductMetadata.php | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/App/ProductMetadata.php b/lib/internal/Magento/Framework/App/ProductMetadata.php index c9fde94352a71..3683d7ecf61d9 100644 --- a/lib/internal/Magento/Framework/App/ProductMetadata.php +++ b/lib/internal/Magento/Framework/App/ProductMetadata.php @@ -28,6 +28,11 @@ class ProductMetadata implements ProductMetadataInterface */ const PRODUCT_NAME = 'Magento'; + /** + * Magento version cache prefix + */ + const CACHE_PREFIX = 'mage-version'; + /** * Product version * @@ -47,11 +52,21 @@ class ProductMetadata implements ProductMetadataInterface private $composerInformation; /** + * @var CacheInterface + */ + private $cache; + + /** + * ProductMetadata constructor. * @param ComposerJsonFinder $composerJsonFinder + * @param \Magento\Framework\App\CacheInterface $cache */ - public function __construct(ComposerJsonFinder $composerJsonFinder) - { + public function __construct( + ComposerJsonFinder $composerJsonFinder, + CacheInterface $cache = null + ) { $this->composerJsonFinder = $composerJsonFinder; + $this->cache = $cache ?? ObjectManager::getInstance()->get(CacheInterface::class); } /** @@ -61,6 +76,8 @@ public function __construct(ComposerJsonFinder $composerJsonFinder) */ public function getVersion() { + $versionFromCache = $this->cache->load(self::CACHE_PREFIX); + $this->version = $this->version ?: $versionFromCache; if (!$this->version) { if (!($this->version = $this->getSystemPackageVersion())) { if ($this->getComposerInformation()->isMagentoRoot()) { @@ -68,6 +85,7 @@ public function getVersion() } else { $this->version = 'UNKNOWN'; } + $this->cache->save($this->version, self::CACHE_PREFIX, [Config::CACHE_TAG]); } } return $this->version; From f1b284b478356cb7b3a544049b35b8e3f5062eb5 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 12 Aug 2019 15:51:45 -0500 Subject: [PATCH 290/372] MC-18977: Revert change of ENGCOM-3260 - fix static failures --- app/code/Magento/Catalog/Block/Product/ProductList/Related.php | 1 + app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php | 1 + app/code/Magento/Catalog/Model/Product.php | 1 + app/code/Magento/Tax/Model/App/Action/ContextPlugin.php | 2 ++ 4 files changed, 5 insertions(+) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php index 6de70bb971367..24811d61a7715 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php @@ -141,6 +141,7 @@ public function getIdentities() { $identities = []; foreach ($this->getItems() as $item) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $identities = array_merge($identities, $item->getIdentities()); } return $identities; diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php index 24822447ae915..fa1beaf6e0ea8 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php @@ -264,6 +264,7 @@ public function getIdentities() { $identities = []; foreach ($this->getItems() as $item) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $identities = array_merge($identities, $item->getIdentities()); } return $identities; diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index fc3cc11cade54..2af54b8086a73 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -837,6 +837,7 @@ public function getStoreIds() } foreach ($websiteIds as $websiteId) { $websiteStores = $this->_storeManager->getWebsite($websiteId)->getStoreIds(); + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $storeIds = array_merge($storeIds, $websiteStores); } } diff --git a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php index 4eb3995448709..992f206279b26 100644 --- a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php @@ -52,6 +52,8 @@ class ContextPlugin * @param \Magento\Tax\Helper\Data $taxHelper * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\PageCache\Model\Config $cacheConfig + * + * phpcs:ignore Magento2.Classes.DiscouragedDependencies */ public function __construct( \Magento\Customer\Model\Session $customerSession, From 1ab19302128366b99a6847af3133de23be2ad5c8 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 12 Aug 2019 16:07:56 -0500 Subject: [PATCH 291/372] MC-19161: Revert ENGCOM-2983 --- .../Config/ConfigOptionsListConstants.php | 19 ---- .../Setup/Controller/DatabaseCheck.php | 36 +------- .../Magento/Setup/Model/ConfigGenerator.php | 14 +-- .../Magento/Setup/Model/ConfigOptionsList.php | 48 +--------- .../Model/ConfigOptionsList/DriverOptions.php | 72 --------------- setup/src/Magento/Setup/Model/Installer.php | 30 +------ .../Setup/Model/RequestDataConverter.php | 8 -- .../Test/Unit/Model/ConfigGeneratorTest.php | 12 --- .../Test/Unit/Model/ConfigOptionsListTest.php | 21 +---- .../Test/Unit/Module/ConfigGeneratorTest.php | 9 +- .../Validator/AdminCredentialsValidator.php | 15 +--- .../Magento/Setup/Validator/DbValidator.php | 22 ----- setup/view/magento/setup/add-database.phtml | 88 ------------------- 13 files changed, 11 insertions(+), 383 deletions(-) delete mode 100644 setup/src/Magento/Setup/Model/ConfigOptionsList/DriverOptions.php diff --git a/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php b/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php index ab32504baaa0e..6bdb74ef7b89a 100644 --- a/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php +++ b/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php @@ -21,7 +21,6 @@ class ConfigOptionsListConstants const CONFIG_PATH_CRYPT_KEY = 'crypt/key'; const CONFIG_PATH_SESSION_SAVE = 'session/save'; const CONFIG_PATH_RESOURCE_DEFAULT_SETUP = 'resource/default_setup/connection'; - const CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS = 'db/connection/default/driver_options'; const CONFIG_PATH_DB_CONNECTION_DEFAULT = 'db/connection/default'; const CONFIG_PATH_DB_CONNECTIONS = 'db/connection'; const CONFIG_PATH_DB_PREFIX = 'db/table_prefix'; @@ -65,10 +64,6 @@ class ConfigOptionsListConstants const INPUT_KEY_DB_MODEL = 'db-model'; const INPUT_KEY_DB_INIT_STATEMENTS = 'db-init-statements'; const INPUT_KEY_DB_ENGINE = 'db-engine'; - const INPUT_KEY_DB_SSL_KEY = 'db-ssl-key'; - const INPUT_KEY_DB_SSL_CERT = 'db-ssl-cert'; - const INPUT_KEY_DB_SSL_CA = 'db-ssl-ca'; - const INPUT_KEY_DB_SSL_VERIFY = 'db-ssl-verify'; const INPUT_KEY_RESOURCE = 'resource'; const INPUT_KEY_SKIP_DB_VALIDATION = 'skip-db-validation'; const INPUT_KEY_CACHE_HOSTS = 'http-cache-hosts'; @@ -109,20 +104,6 @@ class ConfigOptionsListConstants const KEY_MODEL = 'model'; const KEY_INIT_STATEMENTS = 'initStatements'; const KEY_ACTIVE = 'active'; - const KEY_DRIVER_OPTIONS = 'driver_options'; - /**#@-*/ - - /**#@+ - * Array keys for database driver options configurations - */ - const KEY_MYSQL_SSL_KEY = \PDO::MYSQL_ATTR_SSL_KEY; - const KEY_MYSQL_SSL_CERT = \PDO::MYSQL_ATTR_SSL_CERT; - const KEY_MYSQL_SSL_CA = \PDO::MYSQL_ATTR_SSL_CA; - /** - * Constant \PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT cannot be used as it was introduced in PHP 7.1.4 - * and Magento 2 is currently supporting PHP 7.1.3. - */ - const KEY_MYSQL_SSL_VERIFY = 1014; /**#@-*/ /** diff --git a/setup/src/Magento/Setup/Controller/DatabaseCheck.php b/setup/src/Magento/Setup/Controller/DatabaseCheck.php index 4b88a8732d2c7..4511abccaf09b 100644 --- a/setup/src/Magento/Setup/Controller/DatabaseCheck.php +++ b/setup/src/Magento/Setup/Controller/DatabaseCheck.php @@ -5,7 +5,6 @@ */ namespace Magento\Setup\Controller; -use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Setup\Validator\DbValidator; use Zend\Json\Json; use Zend\Mvc\Controller\AbstractActionController; @@ -41,25 +40,7 @@ public function indexAction() try { $params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY); $password = isset($params['password']) ? $params['password'] : ''; - $driverOptions = []; - if ($this->isDriverOptionsGiven($params)) { - if (empty($params['driverOptionsSslVerify'])) { - $params['driverOptionsSslVerify'] = 0; - } - $driverOptions = [ - ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => $params['driverOptionsSslKey'], - ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => $params['driverOptionsSslCert'], - ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => $params['driverOptionsSslCa'], - ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => (int) $params['driverOptionsSslVerify'], - ]; - } - $this->dbValidator->checkDatabaseConnectionWithDriverOptions( - $params['name'], - $params['host'], - $params['user'], - $password, - $driverOptions - ); + $this->dbValidator->checkDatabaseConnection($params['name'], $params['host'], $params['user'], $password); $tablePrefix = isset($params['tablePrefix']) ? $params['tablePrefix'] : ''; $this->dbValidator->checkDatabaseTablePrefix($tablePrefix); return new JsonModel(['success' => true]); @@ -67,19 +48,4 @@ public function indexAction() return new JsonModel(['success' => false, 'error' => $e->getMessage()]); } } - - /** - * Is Driver Options Given - * - * @param array $params - * @return bool - */ - private function isDriverOptionsGiven($params) - { - return !( - empty($params['driverOptionsSslKey']) || - empty($params['driverOptionsSslCert']) || - empty($params['driverOptionsSslCa']) - ); - } } diff --git a/setup/src/Magento/Setup/Model/ConfigGenerator.php b/setup/src/Magento/Setup/Model/ConfigGenerator.php index 88421797e59df..80a20ff2e80f3 100644 --- a/setup/src/Magento/Setup/Model/ConfigGenerator.php +++ b/setup/src/Magento/Setup/Model/ConfigGenerator.php @@ -14,7 +14,6 @@ use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\App\State; use Magento\Framework\Math\Random; -use Magento\Setup\Model\ConfigOptionsList\DriverOptions; /** * Creates deployment config data based on user input array @@ -63,11 +62,6 @@ class ConfigGenerator */ private $cryptKeyGenerator; - /** - * @var DriverOptions - */ - private $driverOptions; - /** * Constructor * @@ -75,20 +69,17 @@ class ConfigGenerator * @param DeploymentConfig $deploymentConfig * @param ConfigDataFactory|null $configDataFactory * @param CryptKeyGeneratorInterface|null $cryptKeyGenerator - * @param DriverOptions|null $driverOptions */ public function __construct( Random $random, DeploymentConfig $deploymentConfig, ConfigDataFactory $configDataFactory = null, - CryptKeyGeneratorInterface $cryptKeyGenerator = null, - DriverOptions $driverOptions = null + CryptKeyGeneratorInterface $cryptKeyGenerator = null ) { $this->random = $random; $this->deploymentConfig = $deploymentConfig; $this->configDataFactory = $configDataFactory ?? ObjectManager::getInstance()->get(ConfigDataFactory::class); $this->cryptKeyGenerator = $cryptKeyGenerator ?? ObjectManager::getInstance()->get(CryptKeyGenerator::class); - $this->driverOptions = $driverOptions ?? ObjectManager::getInstance()->get(DriverOptions::class); } /** @@ -190,9 +181,6 @@ public function createDbConfig(array $data) $configData->set($dbConnectionPrefix . ConfigOptionsListConstants::KEY_ACTIVE, '1'); } - $driverOptions = $this->driverOptions->getDriverOptions($data); - $configData->set($dbConnectionPrefix . ConfigOptionsListConstants::KEY_DRIVER_OPTIONS, $driverOptions); - return $configData; } diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList.php b/setup/src/Magento/Setup/Model/ConfigOptionsList.php index 313e08d6c92ca..4568c70403772 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList.php @@ -11,9 +11,7 @@ use Magento\Framework\Encryption\KeyValidator; use Magento\Framework\Setup\ConfigOptionsListInterface; use Magento\Framework\Setup\Option\FlagConfigOption; -use Magento\Framework\Setup\Option\SelectConfigOption; use Magento\Framework\Setup\Option\TextConfigOption; -use Magento\Setup\Model\ConfigOptionsList\DriverOptions; use Magento\Setup\Validator\DbValidator; /** @@ -55,24 +53,17 @@ class ConfigOptionsList implements ConfigOptionsListInterface \Magento\Setup\Model\ConfigOptionsList\Lock::class, ]; - /** - * @var DriverOptions - */ - private $driverOptions; - /** * Constructor * * @param ConfigGenerator $configGenerator * @param DbValidator $dbValidator * @param KeyValidator|null $encryptionKeyValidator - * @param DriverOptions|null $driverOptions */ public function __construct( ConfigGenerator $configGenerator, DbValidator $dbValidator, - KeyValidator $encryptionKeyValidator = null, - DriverOptions $driverOptions = null + KeyValidator $encryptionKeyValidator = null ) { $this->configGenerator = $configGenerator; $this->dbValidator = $dbValidator; @@ -81,7 +72,6 @@ public function __construct( $this->configOptionsCollection[] = $objectManager->get($className); } $this->encryptionKeyValidator = $encryptionKeyValidator ?: $objectManager->get(KeyValidator::class); - $this->driverOptions = $driverOptions ?? $objectManager->get(DriverOptions::class); } /** @@ -172,36 +162,6 @@ public function getOptions() ConfigOptionsListConstants::CONFIG_PATH_CACHE_HOSTS, 'http Cache hosts' ), - new TextConfigOption( - ConfigOptionsListConstants::INPUT_KEY_DB_SSL_KEY, - TextConfigOption::FRONTEND_WIZARD_TEXT, - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . - '/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY, - 'Full path of client key file in order to establish db connection through SSL', - null - ), - new TextConfigOption( - ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CERT, - TextConfigOption::FRONTEND_WIZARD_TEXT, - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . - '/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT, - 'Full path of client certificate file in order to establish db connection through SSL', - null - ), - new TextConfigOption( - ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CA, - TextConfigOption::FRONTEND_WIZARD_TEXT, - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . - '/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_CA, - 'Full path of server certificate file in order to establish db connection through SSL', - null - ), - new FlagConfigOption( - ConfigOptionsListConstants::INPUT_KEY_DB_SSL_VERIFY, - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . - '/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY, - 'Verify server certification' - ), ]; foreach ($this->configOptionsCollection as $configOptionsList) { @@ -387,14 +347,12 @@ private function validateDbSettings(array $options, DeploymentConfig $deployment ) { try { $options = $this->getDbSettings($options, $deploymentConfig); - $driverOptions = $this->driverOptions->getDriverOptions($options); - $this->dbValidator->checkDatabaseConnectionWithDriverOptions( + $this->dbValidator->checkDatabaseConnection( $options[ConfigOptionsListConstants::INPUT_KEY_DB_NAME], $options[ConfigOptionsListConstants::INPUT_KEY_DB_HOST], $options[ConfigOptionsListConstants::INPUT_KEY_DB_USER], - $options[ConfigOptionsListConstants::INPUT_KEY_DB_PASSWORD], - $driverOptions + $options[ConfigOptionsListConstants::INPUT_KEY_DB_PASSWORD] ); } catch (\Exception $exception) { $errors[] = $exception->getMessage(); diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/DriverOptions.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/DriverOptions.php deleted file mode 100644 index 5910899354911..0000000000000 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/DriverOptions.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Setup\Model\ConfigOptionsList; - -use Magento\Framework\Config\ConfigOptionsListConstants; - -/** - * MySql driver options - */ -class DriverOptions -{ - /** - * Get driver options. - * - * @param array $options - * @return array - */ - public function getDriverOptions(array $options): array - { - $driverOptionKeys = [ - ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_KEY, - ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CERT, - ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CA, - ]; - $booleanDriverOptionKeys = [ - ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_VERIFY, - ]; - $driverOptions = []; - foreach ($driverOptionKeys as $configKey => $driverOptionKey) { - if ($this->optionExists($options, $driverOptionKey)) { - $driverOptions[$configKey] = $options[$driverOptionKey]; - } - } - foreach ($booleanDriverOptionKeys as $configKey => $driverOptionKey) { - $driverOptions[$configKey] = $this->booleanValue($options, $driverOptionKey); - } - - return $driverOptions; - } - - /** - * Check if provided option exists. - * - * @param array $options - * @param string $driverOptionKey - * @return bool - */ - private function optionExists(array $options, string $driverOptionKey): bool - { - return isset($options[$driverOptionKey]) - && ($options[$driverOptionKey] === false || !empty($options[$driverOptionKey])); - } - - /** - * Transforms checkbox flag value into boolean. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#value - * - * @param array $options - * @param string $driverOptionKey - * @return bool - */ - private function booleanValue(array $options, string $driverOptionKey): bool - { - return isset($options[$driverOptionKey]) && (bool)$options[$driverOptionKey]; - } -} diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php index f80a35937d5dc..2510817c2e010 100644 --- a/setup/src/Magento/Setup/Model/Installer.php +++ b/setup/src/Magento/Setup/Model/Installer.php @@ -1371,32 +1371,7 @@ private function deleteDeploymentConfig() */ private function assertDbAccessible() { - $driverOptionKeys = [ - ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' . - ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY, - - ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' . - ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT, - - ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' . - ConfigOptionsListConstants::KEY_MYSQL_SSL_CA, - - ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' . - ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY - ]; - $driverOptions = []; - foreach ($driverOptionKeys as $driverOptionKey => $driverOptionConfig) { - $config = $this->deploymentConfig->get($driverOptionConfig); - if ($config !== null) { - $driverOptions[$driverOptionKey] = $config; - } - } - - $this->dbValidator->checkDatabaseConnectionWithDriverOptions( + $this->dbValidator->checkDatabaseConnection( $this->deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . '/' . ConfigOptionsListConstants::KEY_NAME @@ -1412,8 +1387,7 @@ private function assertDbAccessible() $this->deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . '/' . ConfigOptionsListConstants::KEY_PASSWORD - ), - $driverOptions + ) ); $prefix = $this->deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . diff --git a/setup/src/Magento/Setup/Model/RequestDataConverter.php b/setup/src/Magento/Setup/Model/RequestDataConverter.php index 4964dbe596d85..0ed5dc669c95f 100644 --- a/setup/src/Magento/Setup/Model/RequestDataConverter.php +++ b/setup/src/Magento/Setup/Model/RequestDataConverter.php @@ -51,14 +51,6 @@ private function convertDeploymentConfigForm(array $source) isset($source['db']['tablePrefix']) ? $source['db']['tablePrefix'] : ''; $result[BackendConfigOptionsList::INPUT_KEY_BACKEND_FRONTNAME] = isset($source['config']['address']['admin']) ? $source['config']['address']['admin'] : ''; - $result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_KEY] = isset($source['db']['driverOptionsSslKey']) - ? $source['db']['driverOptionsSslKey'] : ''; - $result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_CERT] = isset($source['db']['driverOptionsSslCert']) - ? $source['db']['driverOptionsSslCert'] : ''; - $result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_CA] = isset($source['db']['driverOptionsSslCa']) - ? $source['db']['driverOptionsSslCa'] : ''; - $result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_VERIFY] = isset($source['db']['driverOptionsSslVerify']) - ? $source['db']['driverOptionsSslVerify'] : ''; $result[SetupConfigOptionsList::INPUT_KEY_ENCRYPTION_KEY] = isset($source['config']['encrypt']['key']) ? $source['config']['encrypt']['key'] : null; $result[SetupConfigOptionsList::INPUT_KEY_SESSION_SAVE] = isset($source['config']['sessionSave']['type']) diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigGeneratorTest.php index 63a92bd4a1982..a388c72fc834b 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigGeneratorTest.php @@ -11,7 +11,6 @@ use Magento\Framework\Config\Data\ConfigData; use Magento\Framework\Config\Data\ConfigDataFactory; use Magento\Setup\Model\ConfigGenerator; -use Magento\Setup\Model\ConfigOptionsList\DriverOptions; /** * Test for Magento\Setup\Model\ConfigGenerator class. @@ -33,11 +32,6 @@ class ConfigGeneratorTest extends \PHPUnit\Framework\TestCase */ private $configDataMock; - /** - * @var DriverOptions - */ - private $driverOptionsMock; - public function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -59,17 +53,11 @@ public function setUp() $configDataFactoryMock->method('create') ->willReturn($this->configDataMock); - $this->driverOptionsMock = $this->getMockBuilder(DriverOptions::class) - ->disableOriginalConstructor() - ->setMethods(['getDriverOptions']) - ->getMock(); - $this->model = $objectManager->getObject( ConfigGenerator::class, [ 'deploymentConfig' => $this->deploymentConfigMock, 'configDataFactory' => $configDataFactoryMock, - 'driverOptions' => $this->driverOptionsMock, ] ); } diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php index 435f03f9de60b..a3ade400fd363 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php @@ -37,29 +37,12 @@ class ConfigOptionsListTest extends \PHPUnit\Framework\TestCase */ private $dbValidator; - /** - * @var \Magento\Framework\Encryption\KeyValidator|\PHPUnit_Framework_MockObject_MockObject - */ - private $encryptionKeyValidator; - - /** - * @var ConfigOptionsList\DriverOptions - */ - private $driverOptionsMock; - protected function setUp() { $this->generator = $this->createMock(\Magento\Setup\Model\ConfigGenerator::class); $this->deploymentConfig = $this->createMock(\Magento\Framework\App\DeploymentConfig::class); $this->dbValidator = $this->createMock(\Magento\Setup\Validator\DbValidator::class); - $this->encryptionKeyValidator = $this->createMock(\Magento\Framework\Encryption\KeyValidator::class); - $this->driverOptionsMock = $this->createMock(ConfigOptionsList\DriverOptions::class); - $this->object = new ConfigOptionsList( - $this->generator, - $this->dbValidator, - $this->encryptionKeyValidator, - $this->driverOptionsMock - ); + $this->object = new ConfigOptionsList($this->generator, $this->dbValidator); } public function testGetOptions() @@ -181,7 +164,7 @@ private function prepareValidationMocks() $this->dbValidator->expects($this->once())->method('checkDatabaseTablePrefix')->willReturn($configDataMock); $this->dbValidator ->expects($this->once()) - ->method('checkDatabaseConnectionWithDriverOptions') + ->method('checkDatabaseConnection') ->willReturn($configDataMock); } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php index ea4261b271582..d4cdee4b84bab 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php @@ -15,7 +15,6 @@ use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Setup\Model\CryptKeyGenerator; use PHPUnit\Framework\TestCase; -use Magento\Setup\Model\ConfigOptionsList\DriverOptions; /** * Test for Magento\Setup\Model\ConfigGenerator class. @@ -48,17 +47,11 @@ protected function setUp() $configDataFactoryMock = (new ObjectManager($this)) ->getObject(ConfigDataFactory::class, ['objectManager' => $objectManagerMock]); - $driverOptions = $this->getMockBuilder(DriverOptions::class) - ->disableOriginalConstructor() - ->setMethods(['getDriverOptions']) - ->getMock(); - $this->configGeneratorObject = new ConfigGenerator( $randomMock, $deployConfig, $configDataFactoryMock, - $cryptKeyGenerator, - $driverOptions + $cryptKeyGenerator ); } diff --git a/setup/src/Magento/Setup/Validator/AdminCredentialsValidator.php b/setup/src/Magento/Setup/Validator/AdminCredentialsValidator.php index 23e41df900d4f..d8380bca54f7b 100644 --- a/setup/src/Magento/Setup/Validator/AdminCredentialsValidator.php +++ b/setup/src/Magento/Setup/Validator/AdminCredentialsValidator.php @@ -5,10 +5,8 @@ */ namespace Magento\Setup\Validator; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Config\ConfigOptionsListConstants as ConfigOption; use Magento\Setup\Model\AdminAccount; -use Magento\Setup\Model\Installer; use Magento\Setup\Model\ConfigOptionsList\DriverOptions; /** @@ -31,29 +29,21 @@ class AdminCredentialsValidator */ private $setupFactory; - /** - * @var DriverOptions - */ - private $driverOptions; - /** * Initialize dependencies. * * @param \Magento\Setup\Model\AdminAccountFactory $adminAccountFactory * @param \Magento\Setup\Module\ConnectionFactory $connectionFactory * @param \Magento\Setup\Module\SetupFactory $setupFactory - * @param DriverOptions|null $driverOptions */ public function __construct( \Magento\Setup\Model\AdminAccountFactory $adminAccountFactory, \Magento\Setup\Module\ConnectionFactory $connectionFactory, - \Magento\Setup\Module\SetupFactory $setupFactory, - DriverOptions $driverOptions = null + \Magento\Setup\Module\SetupFactory $setupFactory ) { $this->connectionFactory = $connectionFactory; $this->adminAccountFactory = $adminAccountFactory; $this->setupFactory = $setupFactory; - $this->driverOptions = $driverOptions ?? ObjectManager::getInstance()->get(DriverOptions::class); } /** @@ -65,8 +55,6 @@ public function __construct( */ public function validate(array $data) { - $driverOptions = $this->driverOptions->getDriverOptions($data); - $dbConnection = $this->connectionFactory->create( [ ConfigOption::KEY_NAME => $data[ConfigOption::INPUT_KEY_DB_NAME], @@ -74,7 +62,6 @@ public function validate(array $data) ConfigOption::KEY_USER => $data[ConfigOption::INPUT_KEY_DB_USER], ConfigOption::KEY_PASSWORD => $data[ConfigOption::INPUT_KEY_DB_PASSWORD], ConfigOption::KEY_PREFIX => $data[ConfigOption::INPUT_KEY_DB_PREFIX], - ConfigOption::KEY_DRIVER_OPTIONS => $driverOptions ] ); diff --git a/setup/src/Magento/Setup/Validator/DbValidator.php b/setup/src/Magento/Setup/Validator/DbValidator.php index 01ed537f887cd..075e48140e150 100644 --- a/setup/src/Magento/Setup/Validator/DbValidator.php +++ b/setup/src/Magento/Setup/Validator/DbValidator.php @@ -78,27 +78,6 @@ public function checkDatabaseTablePrefix($prefix) */ public function checkDatabaseConnection($dbName, $dbHost, $dbUser, $dbPass = '') { - return $this->checkDatabaseConnectionWithDriverOptions($dbName, $dbHost, $dbUser, $dbPass, []); - } - - /** - * Checks Database Connection with Driver Options - * - * @param string $dbName - * @param string $dbHost - * @param string $dbUser - * @param string $dbPass - * @param array $driverOptions - * @return bool - * @throws \Magento\Setup\Exception - */ - public function checkDatabaseConnectionWithDriverOptions( - $dbName, - $dbHost, - $dbUser, - $dbPass = '', - $driverOptions = [] - ) { // establish connection to information_schema view to retrieve information about user and table privileges $connection = $this->connectionFactory->create( [ @@ -107,7 +86,6 @@ public function checkDatabaseConnectionWithDriverOptions( ConfigOptionsListConstants::KEY_USER => $dbUser, ConfigOptionsListConstants::KEY_PASSWORD => $dbPass, ConfigOptionsListConstants::KEY_ACTIVE => true, - ConfigOptionsListConstants::KEY_DRIVER_OPTIONS => $driverOptions, ] ); diff --git a/setup/view/magento/setup/add-database.phtml b/setup/view/magento/setup/add-database.phtml index c858d92cfef55..f36024c112823 100644 --- a/setup/view/magento/setup/add-database.phtml +++ b/setup/view/magento/setup/add-database.phtml @@ -475,94 +475,6 @@ */ ?> - -<div class="row form-row"> - <div class="col-m-3"> - <label class="form-label" for="dbDriverOptionsSslKey"> - Driver Options - SSL Key - </label> - </div> - <div class="col-m-4"> - <input - id="dbDriverOptionsSslKey" - class="form-el-input" - tooltip-placement="right" - tooltip="File that contains X509 key" - tooltip-trigger="focus" - tooltip-append-to-body="true" - type="text" - name="dbDriverOptionsSslKey" - ng-model="db.driverOptionsSslKey" - placeholder="/path/to/client-key.pem" - > - </div> -</div> - -<div class="row form-row"> - <div class="col-m-3"> - <label class="form-label" for="dbDriverOptionsSslCert"> - Driver Options - SSL Certificate - </label> - </div> - <div class="col-m-4"> - <input - id="dbDriverOptionsSslCert" - class="form-el-input" - tooltip-placement="right" - tooltip="File that contains X509 certificate" - tooltip-trigger="focus" - tooltip-append-to-body="true" - type="text" - name="dbDriverOptionsSslCert" - ng-model="db.driverOptionsSslCert" - placeholder="/path/to/client-cert.pem" - > - </div> -</div> - -<div class="row form-row"> - <div class="col-m-3"> - <label class="form-label" for="dbDriverOptionsSslCa"> - Driver Options - SSL Certificate Authorities - </label> - </div> - <div class="col-m-4"> - <input - id="dbDriverOptionsSslCa" - class="form-el-input" - tooltip-placement="right" - tooltip="File that contains list of trusted SSL Certificate Authorities" - tooltip-trigger="focus" - tooltip-append-to-body="true" - type="text" - name="dbDriverOptionsSslCa" - ng-model="db.driverOptionsSslCa" - placeholder="/path/to/ca.pem" - > - </div> -</div> - -<div class="row form-row"> - <div class="col-m-3"> - <label class="form-label"> - Driver Options - SSL Verification - </label> - </div> - <div class="col-m-4"> - <div class="form-row"> - <input - id="dbDriverOptionsSslVerify" - class="form-el-checkbox" - type="checkbox" - ng-model="db.driverOptionsSslVerify" - ng-checked="db.driverOptionsSslVerify" - > - <label class="form-label" for="dbDriverOptionsSslVerify"> - Perform verification against the server CA certificate and against the server host name in its certificate - </label> - </div> - </div> -</div> </fieldset> </form> From ee52bbe016d6afe072761ef18d5110c7513c26ce Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 13 Aug 2019 09:50:11 +0300 Subject: [PATCH 292/372] MC-19084: Browser console error after applying gift card account during checkout --- .../Checkout/view/frontend/web/js/sidebar.js | 3 +- .../Ui/view/frontend/web/js/view/messages.js | 3 +- .../css/source/module/checkout/_checkout.less | 39 ++++++++++--------- lib/web/jquery/ui-modules/effect-fade.js | 3 -- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js index e67b04e6104cc..472f7588d5b6c 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js @@ -13,7 +13,8 @@ define([ 'jquery-ui-modules/widget', 'mage/decorate', 'mage/collapsible', - 'mage/cookies' + 'mage/cookies', + 'jquery-ui-modules/effect-fade' ], function ($, authenticationPopup, customerData, alert, confirm, _) { 'use strict'; diff --git a/app/code/Magento/Ui/view/frontend/web/js/view/messages.js b/app/code/Magento/Ui/view/frontend/web/js/view/messages.js index 57a590c87179a..b2fb3f216199b 100644 --- a/app/code/Magento/Ui/view/frontend/web/js/view/messages.js +++ b/app/code/Magento/Ui/view/frontend/web/js/view/messages.js @@ -10,7 +10,8 @@ define([ 'ko', 'jquery', 'uiComponent', - '../model/messageList' + '../model/messageList', + 'jquery-ui-modules/effect-blind' ], function (ko, $, Component, globalMessages) { 'use strict'; diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less index a2daf0da247d1..ce3f45c990b96 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less @@ -78,27 +78,28 @@ } .abs-discount-code { - .actions-toolbar { - display: table-cell; - vertical-align: top; - width: 1%; - - .primary { - float: left; - .action { - &:extend(.abs-revert-to-action-secondary all); - border-bottom-left-radius: 0; - border-top-left-radius: 0; - margin: 0 0 0 -2px; - white-space: nowrap; - width: auto; - } - } - } - .form-discount { + .form-discount { display: table; width: 100%; - + + .actions-toolbar { + display: table-cell; + vertical-align: top; + width: 1%; + + .primary { + float: left; + .action { + &:extend(.abs-revert-to-action-secondary all); + border-bottom-left-radius: 0; + border-top-left-radius: 0; + margin: 0 0 0 -2px; + white-space: nowrap; + width: auto; + } + } + } + > .field { > .label { display: none; diff --git a/lib/web/jquery/ui-modules/effect-fade.js b/lib/web/jquery/ui-modules/effect-fade.js index ba289cbeb0180..46db40fc8a42e 100644 --- a/lib/web/jquery/ui-modules/effect-fade.js +++ b/lib/web/jquery/ui-modules/effect-fade.js @@ -7,9 +7,6 @@ * http://jquery.org/license * * http://api.jqueryui.com/fade-effect/ - * - * Depends: - * jquery.ui.effect.js */ define([ From c5574b8eb9c7f30f59a5e58d85462deb71279e2a Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 13 Aug 2019 10:20:42 +0300 Subject: [PATCH 293/372] MC-19075: Html text are visible on frontend --- .../Checkout/view/frontend/templates/onepage/review/item.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml index 8e83526b4ceaa..b3b94cfae18dc 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml @@ -28,7 +28,7 @@ $taxDataHelper = $this->helper(Magento\Tax\Helper\Data::class); <dt><?= $block->escapeHtml($_option['label']) ?></dt> <dd> <?php if (isset($_formatedOptionValue['full_view'])) :?> - <?= $block->escapeHtml($_formatedOptionValue['full_view']) ?> + <?= /* @noEscape */ $_formatedOptionValue['full_view'] ?> <?php else :?> <?= /* @noEscape */ $_formatedOptionValue['value'] ?> <?php endif; ?> From 76b668bc8a5b0a83bb3414660eaa793d969cf8ff Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 13 Aug 2019 12:04:13 +0300 Subject: [PATCH 294/372] MC-19023: PayPal Express Checkout Payflow Edition don't work (Internal Error) --- .../web/js/action/select-payment-method.js | 9 +- .../set-payment-information-extended.js | 25 +++++- .../set-payment-information-extended.test.js | 86 +++++++++++++++++++ 3 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js index 6bda10fceb7b9..34f1700749794 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js @@ -12,10 +12,11 @@ define([ 'use strict'; return function (paymentMethod) { - paymentMethod.__disableTmpl = { - title: true - }; - + if (paymentMethod) { + paymentMethod.__disableTmpl = { + title: true + }; + } quote.paymentMethod(paymentMethod); }; }); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js index 263d5747f2842..9de8a93905c99 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js @@ -13,16 +13,33 @@ define([ 'Magento_Checkout/js/model/error-processor', 'Magento_Customer/js/model/customer', 'Magento_Checkout/js/action/get-totals', - 'Magento_Checkout/js/model/full-screen-loader' -], function (quote, urlBuilder, storage, errorProcessor, customer, getTotalsAction, fullScreenLoader) { + 'Magento_Checkout/js/model/full-screen-loader', + 'underscore' +], function (quote, urlBuilder, storage, errorProcessor, customer, getTotalsAction, fullScreenLoader, _) { 'use strict'; + /** + * Filter template data. + * + * @param {Object|Array} data + */ + var filterTemplateData = function (data) { + return _.each(data, function (value, key, list) { + if (_.isArray(value) || _.isObject(value)) { + list[key] = filterTemplateData(value); + } + + if (key === '__disableTmpl') { + delete list[key]; + } + }); + }; + return function (messageContainer, paymentData, skipBilling) { var serviceUrl, payload; - delete paymentData.__disableTmpl; - + paymentData = filterTemplateData(paymentData); skipBilling = skipBilling || false; payload = { cartId: quote.getQuoteId(), diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js new file mode 100644 index 0000000000000..d928ee9f995d2 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js @@ -0,0 +1,86 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'squire', + 'jquery' +], function (Squire, $) { + 'use strict'; + + var injector = new Squire(), + setPaymentInformation, + serviceUrl = 'http://url', + mocks = { + 'Magento_Checkout/js/model/quote': { + getQuoteId: jasmine.createSpy().and.returnValue(1), + billingAddress: jasmine.createSpy().and.returnValue(null) + }, + 'Magento_Checkout/js/model/url-builder': { + createUrl: jasmine.createSpy().and.returnValue(serviceUrl) + }, + 'mage/storage': { + post: function () {} // jscs:ignore jsDoc + }, + 'Magento_Customer/js/model/customer': { + isLoggedIn: jasmine.createSpy().and.returnValue(false) + }, + 'Magento_Checkout/js/model/full-screen-loader': { + startLoader: jasmine.createSpy(), + stopLoader: jasmine.createSpy() + }, + 'Magento_Checkout/js/action/get-totals': jasmine.createSpy('getTotalsAction'), + 'Magento_Checkout/js/model/error-processor': jasmine.createSpy('errorProcessor') + }; + + beforeEach(function (done) { + injector.mock(mocks); + injector.require( + ['Magento_Checkout/js/action/set-payment-information-extended'], + function (action) { + setPaymentInformation = action; + done(); + }); + }); + + afterEach(function () { + try { + injector.clean(); + injector.remove(); + } catch (e) { + } + }); + + describe('Magento/Checkout/js/action/set-payment-information-extended', function () { + it('Checks that paymentData consist correct data value.', function () { + var messageContainer = jasmine.createSpy('messageContainer'), + deferral = new $.Deferred(), + paymentData = { + method: 'checkmo', + additionalData: null, + __disableTmpl: { + title: true + } + }, + formattedData = { + method: 'checkmo', + additionalData: null + }, + payload = { + cartId: 1, + paymentMethod: formattedData, + billingAddress: null + }; + + spyOn(mocks['mage/storage'], 'post').and.callFake(function () { + return deferral.resolve({}); + }); + + setPaymentInformation(messageContainer, paymentData, false); + expect(mocks['Magento_Checkout/js/model/full-screen-loader'].startLoader).toHaveBeenCalled(); + expect(mocks['mage/storage'].post).toHaveBeenCalledWith(serviceUrl, JSON.stringify(payload)); + expect(mocks['Magento_Checkout/js/model/full-screen-loader'].stopLoader).toHaveBeenCalled(); + }); + }); +}); From 30c3db8364c85f4e39680a1f63717d8b28709a04 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 13 Aug 2019 12:26:00 +0300 Subject: [PATCH 295/372] MC-19014: QueueManagementTest caused flakiness during nightly build Integration test runs --- .../Magento/MysqlMq/Model/ResourceModel/Queue.php | 2 +- .../Test/Unit/Model/ResourceModel/QueueTest.php | 2 +- .../Magento/MysqlMq/Model/QueueManagementTest.php | 12 ++++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/MysqlMq/Model/ResourceModel/Queue.php b/app/code/Magento/MysqlMq/Model/ResourceModel/Queue.php index d50ed851b64a9..2a45eafc63f24 100644 --- a/app/code/Magento/MysqlMq/Model/ResourceModel/Queue.php +++ b/app/code/Magento/MysqlMq/Model/ResourceModel/Queue.php @@ -151,7 +151,7 @@ public function getMessages($queueName, $limit = null) 'queue_message_status.status IN (?)', [QueueManagement::MESSAGE_STATUS_NEW, QueueManagement::MESSAGE_STATUS_RETRY_REQUIRED] )->where('queue.name = ?', $queueName) - ->order('queue_message_status.updated_at ASC'); + ->order(['queue_message_status.updated_at ASC', 'queue_message_status.id ASC']); if ($limit) { $select->limit($limit); diff --git a/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php b/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php index d3fe09a712945..c8669809b3aa2 100644 --- a/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php +++ b/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php @@ -206,7 +206,7 @@ public function testGetMessages() ] )->willReturnSelf(); $select->expects($this->once()) - ->method('order')->with('queue_message_status.updated_at ASC')->willReturnSelf(); + ->method('order')->with(['queue_message_status.updated_at ASC', 'queue_message_status.id ASC'])->willReturnSelf(); $select->expects($this->once())->method('limit')->with($limit)->willReturnSelf(); $connection->expects($this->once())->method('fetchAll')->with($select)->willReturn($messages); $this->assertEquals($messages, $this->queue->getMessages($queueName, $limit)); diff --git a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php index 56dd77d3da17c..8fbbe800d6735 100644 --- a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php @@ -91,13 +91,17 @@ public function testAllFlows() $messages = $this->queueManagement->readMessages('queue2', 1); $message = array_shift($messages); $messageRelationId = $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]; + $this->queueManagement->pushToQueueForRetry($messageRelationId); - for ($i = 0; $i < 2; $i++) { - $this->assertEquals($i, $message[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); - $this->queueManagement->pushToQueueForRetry($message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]); + $retryMessage = null; + for ($i = 1; $i <= 3; $i++) { $messages = $this->queueManagement->readMessages('queue2', 1); $message = array_shift($messages); - $this->assertEquals($messageRelationId, $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]); + if ($message[QueueManagement::MESSAGE_QUEUE_RELATION_ID] == $messageRelationId) { + $retryMessage = $message; + } } + $this->assertNotNull($retryMessage, 'Made retry message not found in queue'); + $this->assertEquals(1, $retryMessage[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); } } From 7c240d94881c76838141dcfb91fe2f6b2208928f Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 13 Aug 2019 13:58:07 +0300 Subject: [PATCH 296/372] MC-19023: PayPal Express Checkout Payflow Edition don't work (Internal Error) --- .../js/action/set-payment-information-extended.test.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js index d928ee9f995d2..66f7731415c05 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js @@ -63,13 +63,12 @@ define([ title: true } }, - formattedData = { - method: 'checkmo', - additionalData: null - }, payload = { cartId: 1, - paymentMethod: formattedData, + paymentMethod: { + method: 'checkmo', + additionalData: null + }, billingAddress: null }; From 9092e5e22c736aca6dff5e0943c214e293ec1c66 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 13 Aug 2019 14:14:38 +0300 Subject: [PATCH 297/372] MC-19014: QueueManagementTest caused flakiness during nightly build Integration test runs --- .../MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php b/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php index c8669809b3aa2..e3c6e6d9aee2a 100644 --- a/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php +++ b/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php @@ -206,7 +206,9 @@ public function testGetMessages() ] )->willReturnSelf(); $select->expects($this->once()) - ->method('order')->with(['queue_message_status.updated_at ASC', 'queue_message_status.id ASC'])->willReturnSelf(); + ->method('order') + ->with(['queue_message_status.updated_at ASC', 'queue_message_status.id ASC']) + ->willReturnSelf(); $select->expects($this->once())->method('limit')->with($limit)->willReturnSelf(); $connection->expects($this->once())->method('fetchAll')->with($select)->willReturn($messages); $this->assertEquals($messages, $this->queue->getMessages($queueName, $limit)); From 8e3edf17c1e352bbf6320e68c06c9a0a402e2e9e Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 13 Aug 2019 15:31:19 +0300 Subject: [PATCH 298/372] MC-19132: Child product image of configurable product not displayed --- lib/internal/Magento/Framework/Image/Adapter/Gd2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php index d52e70ef56a11..5ef6b1802b0a5 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php @@ -297,7 +297,7 @@ private function _fillBackgroundColor(&$imageResourceTo) return $transparentColor; } } catch (\Exception $e) { - throw new \DomainException('Failed to fill image.'); + // fallback to default background color } } list($r, $g, $b) = $this->_backgroundColor; From fe432468b13d1f85c301b60ea890abb4bead5c34 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 13 Aug 2019 08:13:58 -0500 Subject: [PATCH 299/372] MC-18977: Revert change of ENGCOM-3260 - fix static failures --- app/code/Magento/Tax/Model/App/Action/ContextPlugin.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php index 992f206279b26..913fa4c46f0ae 100644 --- a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php @@ -52,13 +52,11 @@ class ContextPlugin * @param \Magento\Tax\Helper\Data $taxHelper * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\PageCache\Model\Config $cacheConfig - * - * phpcs:ignore Magento2.Classes.DiscouragedDependencies */ public function __construct( \Magento\Customer\Model\Session $customerSession, \Magento\Framework\App\Http\Context $httpContext, - \Magento\Tax\Model\Calculation\Proxy $calculation, + \Magento\Tax\Model\Calculation\Proxy $calculation, //phpcs:ignore Magento2.Classes.DiscouragedDependencies \Magento\Tax\Helper\Data $taxHelper, \Magento\Framework\Module\Manager $moduleManager, \Magento\PageCache\Model\Config $cacheConfig From 2c5fd23470c42e9c92e643bc9025cdc6de0e1a56 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 13 Aug 2019 17:00:43 +0300 Subject: [PATCH 300/372] MC-19132: Child product image of configurable product not displayed --- lib/internal/Magento/Framework/Image/Adapter/Gd2.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php index 5ef6b1802b0a5..f8cad0e8821ef 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php @@ -296,6 +296,7 @@ private function _fillBackgroundColor(&$imageResourceTo) imagecolortransparent($imageResourceTo, $transparentColor); return $transparentColor; } + // phpcs:disable Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (\Exception $e) { // fallback to default background color } From bc97aedd25622f040ccba347b5dfc3efdacc3827 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Tue, 13 Aug 2019 17:51:54 +0300 Subject: [PATCH 301/372] MC-19080: Incorrect behavior after shipping methods disabled --- app/code/Magento/Shipping/Model/Shipping.php | 26 +++-- .../Shipping/Test/Unit/Model/ShippingTest.php | 33 ++++++- .../Magento/Shipping/Model/ShippingTest.php | 99 ++++++++++++++----- 3 files changed, 125 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Shipping/Model/Shipping.php b/app/code/Magento/Shipping/Model/Shipping.php index 5470f9a96775b..77e6f3c5219fb 100644 --- a/app/code/Magento/Shipping/Model/Shipping.php +++ b/app/code/Magento/Shipping/Model/Shipping.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Shipping\Model; use Magento\Framework\App\ObjectManager; @@ -272,7 +273,9 @@ public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $req */ private function prepareCarrier(string $carrierCode, RateRequest $request): AbstractCarrier { - $carrier = $this->_carrierFactory->create($carrierCode, $request->getStoreId()); + $carrier = $this->isActive($carrierCode) + ? $this->_carrierFactory->create($carrierCode, $request->getStoreId()) + : null; if (!$carrier) { throw new \RuntimeException('Failed to initialize carrier'); } @@ -425,13 +428,10 @@ public function composePackagesForCarrier($carrier, $request) if (!empty($decimalItems)) { foreach ($decimalItems as $decimalItem) { - $fullItems = array_merge( - $fullItems, - array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']) - ); + $fullItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']); } } else { - $fullItems = array_merge($fullItems, array_fill(0, $qty, $itemWeight)); + $fullItems[] = array_fill(0, $qty, $itemWeight); } } sort($fullItems); @@ -532,4 +532,18 @@ public function setCarrierAvailabilityConfigField($code = 'active') $this->_availabilityConfigField = $code; return $this; } + + /** + * Checks availability of carrier. + * + * @param string $carrierCode + * @return bool|null + */ + private function isActive(string $carrierCode) + { + return $this->_scopeConfig->isSetFlag( + 'carriers/' . $carrierCode . '/' . $this->_availabilityConfigField, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + } } diff --git a/app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php b/app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php index 1df41aeba076b..e5723c38ac568 100644 --- a/app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php @@ -3,12 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Shipping\Test\Unit\Model; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Type as ProductType; use Magento\CatalogInventory\Model\Stock\Item as StockItem; use Magento\CatalogInventory\Model\StockRegistry; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Quote\Model\Quote\Item as QuoteItem; use Magento\Shipping\Model\Carrier\AbstractCarrierInterface; use Magento\Shipping\Model\CarrierFactory; @@ -19,12 +21,14 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject; /** - * @see Shipping + * Unit tests for \Magento\Shipping\Model\Shipping class. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ShippingTest extends \PHPUnit\Framework\TestCase { /** - * Test identification number of product + * Test identification number of product. * * @var int */ @@ -50,22 +54,34 @@ class ShippingTest extends \PHPUnit\Framework\TestCase */ private $carrier; + /** + * @var ScopeConfigInterface|MockObject + */ + private $scopeConfig; + + /** + * @inheritdoc + */ protected function setUp() { $this->stockRegistry = $this->createMock(StockRegistry::class); $this->stockItemData = $this->createMock(StockItem::class); + $this->scopeConfig = $this->createMock(ScopeConfigInterface::class); $this->shipping = (new ObjectManagerHelper($this))->getObject( Shipping::class, [ 'stockRegistry' => $this->stockRegistry, 'carrierFactory' => $this->getCarrierFactory(), + 'scopeConfig' => $this->scopeConfig, ] ); } /** + * Compose Packages For Carrier. * + * @return void */ public function testComposePackages() { @@ -125,14 +141,25 @@ function ($key) { /** * Active flag should be set before collecting carrier rates. + * + * @return void */ public function testCollectCarrierRatesSetActiveFlag() { + $carrierCode = 'carrier'; + $scopeStore = 'store'; + $this->scopeConfig->expects($this->once()) + ->method('isSetFlag') + ->with( + 'carriers/' . $carrierCode . '/active', + $scopeStore + ) + ->willReturn(true); $this->carrier->expects($this->atLeastOnce()) ->method('setActiveFlag') ->with('active'); - $this->shipping->collectCarrierRates('carrier', new RateRequest()); + $this->shipping->collectCarrierRates($carrierCode, new RateRequest()); } /** diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php index 760b24db5ef30..8c5dfb0d0ff5e 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php @@ -3,16 +3,19 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Shipping\Model; use Magento\Framework\DataObject; use Magento\Framework\ObjectManagerInterface; +use Magento\Quote\Model\Quote\Address\RateResult\Error; use Magento\Quote\Model\Quote\Address\RateResult\Method; use Magento\Shipping\Model\Rate\Result; use Magento\TestFramework\Helper\Bootstrap; /** - * Contains list of tests for Shipping model + * Contains list of tests for Shipping model. + * @magentoAppIsolation enabled */ class ShippingTest extends \PHPUnit\Framework\TestCase { @@ -42,22 +45,8 @@ protected function setUp() */ public function testCollectRatesByAddress() { - $address = $this->objectManager->create(DataObject::class, [ - 'data' => [ - 'region_id' => 'CA', - 'postcode' => '11111', - 'lastname' => 'John', - 'firstname' => 'Doe', - 'street' => 'Some street', - 'city' => 'Los Angeles', - 'email' => 'john.doe@example.com', - 'telephone' => '11111111', - 'country_id' => 'US', - 'item_qty' => 1 - ] - ]); /** @var Shipping $result */ - $result = $this->model->collectRatesByAddress($address, 'flatrate'); + $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); static::assertInstanceOf(Shipping::class, $result); return $result->getResult(); @@ -68,19 +57,81 @@ public function testCollectRatesByAddress() * @covers \Magento\Shipping\Model\Shipping::collectRatesByAddress * @param Result $result * @depends testCollectRatesByAddress - * @magentoConfigFixture carriers/flatrate/active 1 - * @magentoConfigFixture carriers/flatrate/price 5.00 */ public function testCollectRates(Result $result) { - $rates = $result->getAllRates(); - static::assertNotEmpty($rates); - - /** @var Method $rate */ - $rate = array_pop($rates); - + $rate = $this->getRate($result); static::assertInstanceOf(Method::class, $rate); static::assertEquals('flatrate', $rate->getData('carrier')); static::assertEquals(5, $rate->getData('price')); } + + /** + * @magentoConfigFixture default_store carriers/flatrate/active 1 + * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 + * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK + * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 + */ + public function testShippingMethodIsActiveAndNotApplicable() + { + $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); + $rate = $this->getRate($result->getResult()); + + static::assertEquals('flatrate', $rate->getData('carrier')); + static::assertEquals( + 'This shipping method is not available. To use this shipping method, please contact us.', + $rate->getData('error_message') + ); + } + + /** + * @magentoConfigFixture default_store carriers/flatrate/active 0 + * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 + * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK + * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 + */ + public function testShippingMethodIsNotActiveAndNotApplicable() + { + $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); + $rate = $this->getRate($result->getResult()); + + static::assertNull($rate); + } + + /** + * @return DataObject + */ + private function getAddress(): DataObject + { + $address = $this->objectManager->create( + DataObject::class, + [ + 'data' => [ + 'region_id' => 'CA', + 'postcode' => '11111', + 'lastname' => 'John', + 'firstname' => 'Doe', + 'street' => 'Some street', + 'city' => 'Los Angeles', + 'email' => 'john.doe@example.com', + 'telephone' => '11111111', + 'country_id' => 'US', + 'item_qty' => 1, + ], + ] + ); + + return $address; + } + + /** + * @param Result $result + * @return Method|Error + */ + private function getRate(Result $result) + { + $rates = $result->getAllRates(); + + return array_pop($rates); + } } From eb6d625269699de731b2be64098f83cab6a045ab Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 13 Aug 2019 09:58:25 -0500 Subject: [PATCH 302/372] MC-19061: Revert ticket MC-17003 --- .../adminhtml/templates/order/creditmemo/create/items.phtml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml index 16ab1750efeb6..22e648e2b5bde 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml @@ -139,7 +139,8 @@ require(['jquery'], function(jQuery){ //<![CDATA[ var submitButtons = jQuery('.submit-button'); - +var updateButtons = jQuery('.update-button'); +var fields = jQuery('.qty-input'); function enableButtons(buttons) { buttons.removeClass('disabled').prop('disabled', false); } From a098f4fe398be310a46f4cc106efc951b64cc8e8 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Tue, 13 Aug 2019 11:13:06 -0500 Subject: [PATCH 303/372] MC-19115: Admin Analytics tracking should be enabled by default - static fix --- lib/internal/Magento/Framework/App/ProductMetadata.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/App/ProductMetadata.php b/lib/internal/Magento/Framework/App/ProductMetadata.php index 3683d7ecf61d9..583638826e766 100644 --- a/lib/internal/Magento/Framework/App/ProductMetadata.php +++ b/lib/internal/Magento/Framework/App/ProductMetadata.php @@ -14,6 +14,7 @@ /** * Class ProductMetadata + * * @package Magento\Framework\App */ class ProductMetadata implements ProductMetadataInterface @@ -29,9 +30,9 @@ class ProductMetadata implements ProductMetadataInterface const PRODUCT_NAME = 'Magento'; /** - * Magento version cache prefix + * Magento version cache key */ - const CACHE_PREFIX = 'mage-version'; + const VERSION_CACHE_KEY = 'mage-version'; /** * Product version @@ -76,7 +77,7 @@ public function __construct( */ public function getVersion() { - $versionFromCache = $this->cache->load(self::CACHE_PREFIX); + $versionFromCache = $this->cache->load(self::VERSION_CACHE_KEY); $this->version = $this->version ?: $versionFromCache; if (!$this->version) { if (!($this->version = $this->getSystemPackageVersion())) { @@ -85,7 +86,7 @@ public function getVersion() } else { $this->version = 'UNKNOWN'; } - $this->cache->save($this->version, self::CACHE_PREFIX, [Config::CACHE_TAG]); + $this->cache->save($this->version, self::VERSION_CACHE_KEY, [Config::CACHE_TAG]); } } return $this->version; From 6d7e1f714c455764255f654a1b88707a0243e1d8 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 13 Aug 2019 11:51:58 -0500 Subject: [PATCH 304/372] MC-19161: Revert ENGCOM-2983 --- setup/src/Magento/Setup/Model/ConfigOptionsList.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList.php b/setup/src/Magento/Setup/Model/ConfigOptionsList.php index 4568c70403772..c080b3c7fc6a1 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList.php @@ -165,6 +165,7 @@ public function getOptions() ]; foreach ($this->configOptionsCollection as $configOptionsList) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $options = array_merge($options, $configOptionsList->getOptions()); } @@ -221,6 +222,7 @@ public function validate(array $options, DeploymentConfig $deploymentConfig) } foreach ($this->configOptionsCollection as $configOptionsList) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $errors = array_merge($errors, $configOptionsList->validate($options, $deploymentConfig)); } From 7d3042fae6bfa3b8f7eb2afa6cd23407b0e44353 Mon Sep 17 00:00:00 2001 From: Kieu Phan <kphan@adobe.com> Date: Tue, 13 Aug 2019 14:23:40 -0500 Subject: [PATCH 305/372] MC-19061: Revert ticket MC-17003 Skip MFTF test --- .../Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml b/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml index a667f40ad327f..afe70243f602c 100644 --- a/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml +++ b/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml @@ -16,6 +16,9 @@ <description value="Watermark images should be able to be uploaded in the admin"/> <severity value="MAJOR"/> <testCaseId value="MC-5796"/> + <skip> + <issueId value="MC-18496"/> + </skip> <group value="Watermark"/> </annotations> <before> From e913ce88010bbee69909e2d3e9cdf28816971eb8 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 14 Aug 2019 15:03:02 +0300 Subject: [PATCH 306/372] MC-19218: Catalog Event created with incorrect start and end dates - revert #22463 --- .../Magento/Framework/Stdlib/DateTime/Timezone.php | 3 +-- .../Stdlib/Test/Unit/DateTime/TimezoneTest.php | 11 ----------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 45c31d367b34a..5b028eda4c71f 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -196,8 +196,7 @@ public function date($date = null, $locale = null, $useTimezone = true, $include public function scopeDate($scope = null, $date = null, $includeTime = false) { $timezone = $this->_scopeConfig->getValue($this->getDefaultTimezonePath(), $this->_scopeType, $scope); - $date = new \DateTime(is_numeric($date) ? '@' . $date : $date); - $date->setTimezone(new \DateTimeZone($timezone)); + $date = new \DateTime(is_numeric($date) ? '@' . $date : $date, new \DateTimeZone($timezone)); if (!$includeTime) { $date->setTime(0, 0, 0); } diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index 3d7d14a394629..d57525590b9e8 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -253,15 +253,4 @@ private function scopeConfigWillReturnConfiguredTimezone($configuredTimezone) { $this->scopeConfig->method('getValue')->with('', '', null)->willReturn($configuredTimezone); } - - public function testCheckIfScopeDateSetsTimeZone() - { - $scopeDate = new \DateTime('now', new \DateTimeZone('America/Vancouver')); - $this->scopeConfig->method('getValue')->willReturn('America/Vancouver'); - - $this->assertEquals( - $scopeDate->getTimezone(), - $this->getTimezone()->scopeDate(0, $scopeDate->getTimestamp())->getTimezone() - ); - } } From ccc5074fba3d60f132908d6bf7ad2fefad0280dc Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 14 Aug 2019 15:07:06 +0300 Subject: [PATCH 307/372] MC-19078: Product is missing from shopping cart after payment cancellation --- .../CheckExpirePersistentQuoteObserver.php | 34 +++++++++++++++++-- ...CheckExpirePersistentQuoteObserverTest.php | 18 +++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php index 1261a90b5843b..862ac561433ed 100644 --- a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php +++ b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php @@ -6,6 +6,9 @@ namespace Magento\Persistent\Observer; use Magento\Framework\Event\ObserverInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Quote\Api\CartRepositoryInterface; +use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\Quote; /** @@ -74,6 +77,11 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface */ private $quote; + /** + * @var CartRepositoryInterface + */ + private $quoteRepository; + /** * @param \Magento\Persistent\Helper\Session $persistentSession * @param \Magento\Persistent\Helper\Data $persistentData @@ -82,6 +90,7 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Magento\Framework\App\RequestInterface $request + * @param CartRepositoryInterface $quoteRepository */ public function __construct( \Magento\Persistent\Helper\Session $persistentSession, @@ -90,7 +99,8 @@ public function __construct( \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Customer\Model\Session $customerSession, \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Framework\App\RequestInterface $request + \Magento\Framework\App\RequestInterface $request, + CartRepositoryInterface $quoteRepository ) { $this->_persistentSession = $persistentSession; $this->quoteManager = $quoteManager; @@ -99,6 +109,7 @@ public function __construct( $this->_eventManager = $eventManager; $this->_persistentData = $persistentData; $this->request = $request; + $this->quoteRepository = $quoteRepository; } /** @@ -146,9 +157,11 @@ public function execute(\Magento\Framework\Event\Observer $observer) */ private function isPersistentQuoteOutdated(): bool { - if ((!$this->_persistentData->isEnabled() || !$this->_persistentData->isShoppingCartPersist()) + if (!($this->_persistentData->isEnabled() && $this->_persistentData->isShoppingCartPersist()) && !$this->_customerSession->isLoggedIn() - && $this->_checkoutSession->getQuoteId()) { + && $this->_checkoutSession->getQuoteId() + && $this->isActiveQuote() + ) { return (bool)$this->getQuote()->getIsPersistent(); } return false; @@ -181,6 +194,21 @@ private function getQuote(): Quote return $this->quote; } + /** + * Check if quote is active. + * + * @return bool + */ + private function isActiveQuote(): bool + { + try { + $this->quoteRepository->getActive($this->_checkoutSession->getQuoteId()); + return true; + } catch (NoSuchEntityException $e) { + return false; + } + } + /** * Check current request is coming from onepage checkout page. * diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php index 2c5b9dad48eb3..31a6ba9f10e7e 100644 --- a/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php @@ -6,6 +6,8 @@ namespace Magento\Persistent\Test\Unit\Observer; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\Quote; /** @@ -63,6 +65,11 @@ class CheckExpirePersistentQuoteObserverTest extends \PHPUnit\Framework\TestCase */ private $quoteMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|CartRepositoryInterface + */ + private $quoteRepositoryMock; + /** * @inheritdoc */ @@ -82,6 +89,7 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['getRequestUri', 'getServer']) ->getMockForAbstractClass(); + $this->quoteRepositoryMock = $this->createMock(CartRepositoryInterface::class); $this->model = new \Magento\Persistent\Observer\CheckExpirePersistentQuoteObserver( $this->sessionMock, @@ -90,7 +98,8 @@ protected function setUp() $this->eventManagerMock, $this->customerSessionMock, $this->checkoutSessionMock, - $this->requestMock + $this->requestMock, + $this->quoteRepositoryMock ); $this->quoteMock = $this->getMockBuilder(Quote::class) ->setMethods(['getCustomerIsGuest', 'getIsPersistent']) @@ -111,12 +120,19 @@ public function testExecuteWhenCanNotApplyPersistentData() public function testExecuteWhenPersistentIsNotEnabled() { + $quoteId = 'quote_id_1'; + $this->persistentHelperMock ->expects($this->once()) ->method('canProcess') ->with($this->observerMock) ->willReturn(true); $this->persistentHelperMock->expects($this->exactly(2))->method('isEnabled')->willReturn(false); + $this->checkoutSessionMock->expects($this->exactly(2))->method('getQuoteId')->willReturn($quoteId); + $this->quoteRepositoryMock->expects($this->once()) + ->method('getActive') + ->with($quoteId) + ->willThrowException(new NoSuchEntityException()); $this->eventManagerMock->expects($this->never())->method('dispatch'); $this->model->execute($this->observerMock); } From 8a4e7c4ca5f3e75fd2f158afa5338c39b5132418 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Wed, 14 Aug 2019 17:22:09 +0300 Subject: [PATCH 308/372] MC-19132: Child product image of configurable product not displayed --- lib/internal/Magento/Framework/Image/Adapter/Gd2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php index f8cad0e8821ef..7e92b336cfdc0 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php @@ -296,7 +296,7 @@ private function _fillBackgroundColor(&$imageResourceTo) imagecolortransparent($imageResourceTo, $transparentColor); return $transparentColor; } - // phpcs:disable Magento2.CodeAnalysis.EmptyBlock.DetectedCatch + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (\Exception $e) { // fallback to default background color } From eb3d1728566f992401bbfb648ab56cf39deecf9b Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Wed, 14 Aug 2019 18:02:38 +0300 Subject: [PATCH 309/372] MC-19080: Incorrect behavior after shipping methods disabled --- app/code/Magento/Shipping/Model/Shipping.php | 12 +- .../Model/CollectRatesTest.php | 118 ++++++++++++++++++ .../Magento/Shipping/Model/ShippingTest.php | 99 ++++----------- .../Magento/Ups/Model/CollectRatesTest.php | 50 ++++++++ 4 files changed, 199 insertions(+), 80 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php diff --git a/app/code/Magento/Shipping/Model/Shipping.php b/app/code/Magento/Shipping/Model/Shipping.php index 77e6f3c5219fb..48127469ea984 100644 --- a/app/code/Magento/Shipping/Model/Shipping.php +++ b/app/code/Magento/Shipping/Model/Shipping.php @@ -273,7 +273,7 @@ public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $req */ private function prepareCarrier(string $carrierCode, RateRequest $request): AbstractCarrier { - $carrier = $this->isActive($carrierCode) + $carrier = $this->isShippingCarrierAvailable($carrierCode) ? $this->_carrierFactory->create($carrierCode, $request->getStoreId()) : null; if (!$carrier) { @@ -363,6 +363,7 @@ public function composePackagesForCarrier($carrier, $request) { $allItems = $request->getAllItems(); $fullItems = []; + $weightItems = []; $maxWeight = (double)$carrier->getConfigData('max_package_weight'); @@ -428,12 +429,13 @@ public function composePackagesForCarrier($carrier, $request) if (!empty($decimalItems)) { foreach ($decimalItems as $decimalItem) { - $fullItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']); + $weightItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']); } } else { - $fullItems[] = array_fill(0, $qty, $itemWeight); + $weightItems[] = array_fill(0, $qty, $itemWeight); } } + $fullItems = array_merge($fullItems, ...$weightItems); sort($fullItems); return $this->_makePieces($fullItems, $maxWeight); @@ -537,9 +539,9 @@ public function setCarrierAvailabilityConfigField($code = 'active') * Checks availability of carrier. * * @param string $carrierCode - * @return bool|null + * @return bool */ - private function isActive(string $carrierCode) + private function isShippingCarrierAvailable(string $carrierCode): bool { return $this->_scopeConfig->isSetFlag( 'carriers/' . $carrierCode . '/' . $this->_availabilityConfigField, diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php new file mode 100644 index 0000000000000..c5e3ab1935a2e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php @@ -0,0 +1,118 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\OfflineShipping\Model; + +use Magento\Framework\DataObject; +use Magento\Framework\ObjectManagerInterface; +use Magento\Quote\Model\Quote\Address\RateResult\Error; +use Magento\Quote\Model\Quote\Address\RateResult\Method; +use Magento\Shipping\Model\Rate\Result; +use Magento\Shipping\Model\Shipping; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Integration tests for offline shipping carriers. + * @magentoAppIsolation enabled + */ +class CollectRatesTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var Shipping + */ + protected $shipping; + + /** + * @var string + */ + protected $carrier = 'flatrate'; + + /** + * @var string + */ + protected $errorMessage = 'This shipping method is not available. To use this shipping method, please contact us.'; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->shipping = $this->objectManager->get(Shipping::class); + } + + /** + * @magentoConfigFixture default_store carriers/flatrate/active 1 + * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 + * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK + * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 + */ + public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() + { + $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); + $rate = $this->getRate($result->getResult()); + + static::assertEquals($this->carrier, $rate->getData('carrier')); + static::assertEquals($this->errorMessage, $rate->getData('error_message')); + } + + /** + * @magentoConfigFixture default_store carriers/flatrate/active 0 + * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 + * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK + * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 + */ + public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() + { + $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); + $rate = $this->getRate($result->getResult()); + + static::assertNull($rate); + } + + /** + * @return DataObject + */ + private function getAddress(): DataObject + { + $address = $this->objectManager->create( + DataObject::class, + [ + 'data' => [ + 'region_id' => 'CA', + 'postcode' => '11111', + 'lastname' => 'John', + 'firstname' => 'Doe', + 'street' => 'Some street', + 'city' => 'Los Angeles', + 'email' => 'john.doe@example.com', + 'telephone' => '11111111', + 'country_id' => 'US', + 'item_qty' => 1, + ], + ] + ); + + return $address; + } + + /** + * @param Result $result + * @return Method|Error + */ + private function getRate(Result $result) + { + $rates = $result->getAllRates(); + + return array_pop($rates); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php index 8c5dfb0d0ff5e..760b24db5ef30 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php @@ -3,19 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Shipping\Model; use Magento\Framework\DataObject; use Magento\Framework\ObjectManagerInterface; -use Magento\Quote\Model\Quote\Address\RateResult\Error; use Magento\Quote\Model\Quote\Address\RateResult\Method; use Magento\Shipping\Model\Rate\Result; use Magento\TestFramework\Helper\Bootstrap; /** - * Contains list of tests for Shipping model. - * @magentoAppIsolation enabled + * Contains list of tests for Shipping model */ class ShippingTest extends \PHPUnit\Framework\TestCase { @@ -45,8 +42,22 @@ protected function setUp() */ public function testCollectRatesByAddress() { + $address = $this->objectManager->create(DataObject::class, [ + 'data' => [ + 'region_id' => 'CA', + 'postcode' => '11111', + 'lastname' => 'John', + 'firstname' => 'Doe', + 'street' => 'Some street', + 'city' => 'Los Angeles', + 'email' => 'john.doe@example.com', + 'telephone' => '11111111', + 'country_id' => 'US', + 'item_qty' => 1 + ] + ]); /** @var Shipping $result */ - $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); + $result = $this->model->collectRatesByAddress($address, 'flatrate'); static::assertInstanceOf(Shipping::class, $result); return $result->getResult(); @@ -57,81 +68,19 @@ public function testCollectRatesByAddress() * @covers \Magento\Shipping\Model\Shipping::collectRatesByAddress * @param Result $result * @depends testCollectRatesByAddress + * @magentoConfigFixture carriers/flatrate/active 1 + * @magentoConfigFixture carriers/flatrate/price 5.00 */ public function testCollectRates(Result $result) { - $rate = $this->getRate($result); - static::assertInstanceOf(Method::class, $rate); - static::assertEquals('flatrate', $rate->getData('carrier')); - static::assertEquals(5, $rate->getData('price')); - } + $rates = $result->getAllRates(); + static::assertNotEmpty($rates); - /** - * @magentoConfigFixture default_store carriers/flatrate/active 1 - * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 - * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK - * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 - */ - public function testShippingMethodIsActiveAndNotApplicable() - { - $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); - $rate = $this->getRate($result->getResult()); + /** @var Method $rate */ + $rate = array_pop($rates); + static::assertInstanceOf(Method::class, $rate); static::assertEquals('flatrate', $rate->getData('carrier')); - static::assertEquals( - 'This shipping method is not available. To use this shipping method, please contact us.', - $rate->getData('error_message') - ); - } - - /** - * @magentoConfigFixture default_store carriers/flatrate/active 0 - * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 - * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK - * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 - */ - public function testShippingMethodIsNotActiveAndNotApplicable() - { - $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); - $rate = $this->getRate($result->getResult()); - - static::assertNull($rate); - } - - /** - * @return DataObject - */ - private function getAddress(): DataObject - { - $address = $this->objectManager->create( - DataObject::class, - [ - 'data' => [ - 'region_id' => 'CA', - 'postcode' => '11111', - 'lastname' => 'John', - 'firstname' => 'Doe', - 'street' => 'Some street', - 'city' => 'Los Angeles', - 'email' => 'john.doe@example.com', - 'telephone' => '11111111', - 'country_id' => 'US', - 'item_qty' => 1, - ], - ] - ); - - return $address; - } - - /** - * @param Result $result - * @return Method|Error - */ - private function getRate(Result $result) - { - $rates = $result->getAllRates(); - - return array_pop($rates); + static::assertEquals(5, $rate->getData('price')); } } diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php new file mode 100644 index 0000000000000..27323bf22f01e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Ups\Model; + +/** + * Integration tests for online shipping carriers. + * @magentoAppIsolation enabled + */ +class CollectRatesTest extends \Magento\OfflineShipping\Model\CollectRatesTest +{ + /** + * @var string + */ + protected $carrier = 'ups'; + + /** + * @var string + */ + protected $errorMessage = 'This shipping method is currently unavailable. ' . + 'If you would like to ship using this shipping method, please contact us.'; + + /** + * @magentoConfigFixture default_store carriers/ups/active 1 + * @magentoConfigFixture default_store carriers/ups/type UPS + * @magentoConfigFixture default_store carriers/ups/sallowspecific 1 + * @magentoConfigFixture default_store carriers/ups/specificcountry UK + * @magentoConfigFixture default_store carriers/ups/showmethod 1 + */ + public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() + { + parent::testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable(); + } + + /** + * @magentoConfigFixture default_store carriers/ups/active 0 + * @magentoConfigFixture default_store carriers/ups/type UPS + * @magentoConfigFixture default_store carriers/ups/sallowspecific 1 + * @magentoConfigFixture default_store carriers/ups/specificcountry UK + * @magentoConfigFixture default_store carriers/ups/showmethod 1 + */ + public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() + { + parent::testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable(); + } +} From 9532e283542714364f2ce7b15508ea8c110e4165 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Wed, 14 Aug 2019 12:20:56 -0500 Subject: [PATCH 310/372] MC-19194: UpdateCartItems mutation does not update cart item quantity - Reverted back commit c7d9130289993310992cb3e4a0b5ec7c3dd196bd and modified functional test --- .../Model/Cart/UpdateCartItem.php | 1 + .../Quote/Guest/UpdateCartItemsTest.php | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php index 81a7779eb98b5..b18c6ad662335 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php @@ -117,6 +117,7 @@ private function updateItemQuantity(int $itemId, Quote $cart, float $quantity) } $cartItem->setQty($quantity); $this->validateCartItem($cartItem); + $this->cartItemRepository->save($cartItem); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php index 988ead7d86df3..13d9bb011d9b2 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php @@ -70,6 +70,16 @@ public function testUpdateCartItemQuantity() $this->assertEquals($itemId, $item['id']); $this->assertEquals($quantity, $item['quantity']); + + $cartQuery = $this->getCartQuery($maskedQuoteId); + $response = $this->graphQlQuery($cartQuery); + + $this->assertArrayHasKey('cart', $response); + + $responseCart = $response['cart']; + $item = current($responseCart['items']); + + $this->assertEquals($quantity, $item['quantity']); } /** @@ -268,6 +278,26 @@ private function getQuery(string $maskedQuoteId, int $itemId, float $quantity): } } } +QUERY; + } + + /** + * @param string $maskedQuoteId + * @return string + */ + private function getCartQuery(string $maskedQuoteId) + { + return <<<QUERY +query { + cart(cart_id: "{$maskedQuoteId}"){ + items{ + product{ + name + } + quantity + } + } +} QUERY; } } From 2fa2eb9d1314c7177a6a4bd8c9d19f90759fdf23 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 14 Aug 2019 14:59:56 -0500 Subject: [PATCH 311/372] MC-19161: Revert ENGCOM-2983 --- .../Magento/Mtf/TestSuite/InjectableTests/acceptance.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml index 6a8e2c615f847..d433f8c3fd06d 100644 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml @@ -21,6 +21,7 @@ </allow> <deny> <tag group="stable" value="no" /> + <tag group="mftf_migrated" value="yes" /> </deny> </rule> </config> From 59e76d9a78e513730ac920cc785c52b9691796aa Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Thu, 15 Aug 2019 09:22:02 +0300 Subject: [PATCH 312/372] MC-19080: Incorrect behavior after shipping methods disabled --- .../testsuite/Magento/Ups/Model/CollectRatesTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php index 27323bf22f01e..3aab12df5f179 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php @@ -31,6 +31,7 @@ class CollectRatesTest extends \Magento\OfflineShipping\Model\CollectRatesTest * @magentoConfigFixture default_store carriers/ups/specificcountry UK * @magentoConfigFixture default_store carriers/ups/showmethod 1 */ + // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() { parent::testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable(); @@ -43,6 +44,7 @@ public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() * @magentoConfigFixture default_store carriers/ups/specificcountry UK * @magentoConfigFixture default_store carriers/ups/showmethod 1 */ + // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() { parent::testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable(); From 08bbdbf0246a09612f893c12587b3fae0d61efa7 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Thu, 15 Aug 2019 14:24:11 +0300 Subject: [PATCH 313/372] MC-19080: Incorrect behavior after shipping methods disabled --- .../Model/CollectRatesTest.php | 79 +----------- .../Shipping/Model/CollectRatesTest.php | 114 ++++++++++++++++++ .../Magento/Ups/Model/CollectRatesTest.php | 2 +- 3 files changed, 120 insertions(+), 75 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php index c5e3ab1935a2e..910b4f570c360 100644 --- a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php @@ -7,30 +7,12 @@ namespace Magento\OfflineShipping\Model; -use Magento\Framework\DataObject; -use Magento\Framework\ObjectManagerInterface; -use Magento\Quote\Model\Quote\Address\RateResult\Error; -use Magento\Quote\Model\Quote\Address\RateResult\Method; -use Magento\Shipping\Model\Rate\Result; -use Magento\Shipping\Model\Shipping; -use Magento\TestFramework\Helper\Bootstrap; - /** * Integration tests for offline shipping carriers. * @magentoAppIsolation enabled */ -class CollectRatesTest extends \PHPUnit\Framework\TestCase +class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesTest { - /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * @var Shipping - */ - protected $shipping; - /** * @var string */ @@ -41,28 +23,16 @@ class CollectRatesTest extends \PHPUnit\Framework\TestCase */ protected $errorMessage = 'This shipping method is not available. To use this shipping method, please contact us.'; - /** - * @inheritdoc - */ - protected function setUp() - { - $this->objectManager = Bootstrap::getObjectManager(); - $this->shipping = $this->objectManager->get(Shipping::class); - } - /** * @magentoConfigFixture default_store carriers/flatrate/active 1 * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 */ + // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() { - $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); - $rate = $this->getRate($result->getResult()); - - static::assertEquals($this->carrier, $rate->getData('carrier')); - static::assertEquals($this->errorMessage, $rate->getData('error_message')); + parent::testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable(); } /** @@ -71,48 +41,9 @@ public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 */ + // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() { - $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); - $rate = $this->getRate($result->getResult()); - - static::assertNull($rate); - } - - /** - * @return DataObject - */ - private function getAddress(): DataObject - { - $address = $this->objectManager->create( - DataObject::class, - [ - 'data' => [ - 'region_id' => 'CA', - 'postcode' => '11111', - 'lastname' => 'John', - 'firstname' => 'Doe', - 'street' => 'Some street', - 'city' => 'Los Angeles', - 'email' => 'john.doe@example.com', - 'telephone' => '11111111', - 'country_id' => 'US', - 'item_qty' => 1, - ], - ] - ); - - return $address; - } - - /** - * @param Result $result - * @return Method|Error - */ - private function getRate(Result $result) - { - $rates = $result->getAllRates(); - - return array_pop($rates); + parent::testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable(); } } diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php new file mode 100644 index 0000000000000..a5994cc604a65 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php @@ -0,0 +1,114 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Shipping\Model; + +use Magento\Framework\DataObject; +use Magento\Framework\ObjectManagerInterface; +use Magento\Quote\Model\Quote\Address\RateResult\Error; +use Magento\Quote\Model\Quote\Address\RateResult\Method; +use Magento\Shipping\Model\Rate\Result; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Integration tests for shipping carriers. + */ +class CollectRatesTest extends \PHPUnit\Framework\TestCase +{ + + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var Shipping + */ + protected $shipping; + + /** + * @var string + */ + protected $carrier = ''; + + /** + * @var string + */ + protected $errorMessage = ''; + + /** + * @inheritdoc + */ + protected function setUp() + { + if (empty($this->carrier) || empty($this->errorMessage)) { + $this->markTestSkipped('Required fields are empty'); + } + $this->objectManager = Bootstrap::getObjectManager(); + $this->shipping = $this->objectManager->get(Shipping::class); + } + + /** + * @return void + */ + public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() + { + $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); + $rate = $this->getRate($result->getResult()); + + static::assertEquals($this->carrier, $rate->getData('carrier')); + static::assertEquals($this->errorMessage, $rate->getData('error_message')); + } + + /** + * @return void + */ + public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() + { + $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); + $rate = $this->getRate($result->getResult()); + + static::assertNull($rate); + } + + /** + * @return DataObject + */ + private function getAddress(): DataObject + { + $address = $this->objectManager->create( + DataObject::class, + [ + 'data' => [ + 'region_id' => 'CA', + 'postcode' => '11111', + 'lastname' => 'John', + 'firstname' => 'Doe', + 'street' => 'Some street', + 'city' => 'Los Angeles', + 'email' => 'john.doe@example.com', + 'telephone' => '11111111', + 'country_id' => 'US', + 'item_qty' => 1, + ], + ] + ); + + return $address; + } + + /** + * @param Result $result + * @return Method|Error + */ + private function getRate(Result $result) + { + $rates = $result->getAllRates(); + + return array_pop($rates); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php index 3aab12df5f179..58f31836a310a 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php @@ -11,7 +11,7 @@ * Integration tests for online shipping carriers. * @magentoAppIsolation enabled */ -class CollectRatesTest extends \Magento\OfflineShipping\Model\CollectRatesTest +class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesTest { /** * @var string From c6cc4b23b4b357adc925d6ae6ded2b43bf37d791 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 15 Aug 2019 17:58:49 +0300 Subject: [PATCH 314/372] MC-19044: [FT] Magento\Downloadable\Test\TestCase\CreateDownloadableProductEntityTest fails on Jenkins --- .../CreateDownloadableProductEntityTest.php | 24 ++++++++++++++++++- .../TestSuite/InjectableTests/acceptance.xml | 2 ++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php index 496b7a280ca18..de71cdff7ae4c 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php @@ -11,6 +11,7 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; use Magento\Downloadable\Test\Fixture\DownloadableProduct; use Magento\Mtf\TestCase\Injectable; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Steps: @@ -53,6 +54,13 @@ class CreateDownloadableProductEntityTest extends Injectable */ protected $catalogProductNew; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Persist category * @@ -73,16 +81,19 @@ public function __prepare(Category $category) * @param Category $category * @param CatalogProductIndex $catalogProductIndexNewPage * @param CatalogProductNew $catalogProductNewPage + * @param EnvWhitelist $envWhitelist * @return void */ public function __inject( Category $category, CatalogProductIndex $catalogProductIndexNewPage, - CatalogProductNew $catalogProductNewPage + CatalogProductNew $catalogProductNewPage, + EnvWhitelist $envWhitelist ) { $this->category = $category; $this->catalogProductIndex = $catalogProductIndexNewPage; $this->catalogProductNew = $catalogProductNewPage; + $this->envWhitelist = $envWhitelist; } /** @@ -95,10 +106,21 @@ public function __inject( public function test(DownloadableProduct $product, Category $category) { // Steps + $this->envWhitelist->addHost('example.com'); $this->catalogProductIndex->open(); $this->catalogProductIndex->getGridPageActionBlock()->addProduct('downloadable'); $productBlockForm = $this->catalogProductNew->getProductForm(); $productBlockForm->fill($product, null, $category); $this->catalogProductNew->getFormPageActions()->save(); } + + /** + * Clean data after running test. + * + * @return void + */ + protected function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml index 6a8e2c615f847..2eae769416c29 100644 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml @@ -13,6 +13,7 @@ </allow> <deny> <tag group="stable" value="no" /> + <tag group="mftf_migrated" value="yes" /> </deny> </rule> <rule scope="variation"> @@ -21,6 +22,7 @@ </allow> <deny> <tag group="stable" value="no" /> + <tag group="mftf_migrated" value="yes" /> </deny> </rule> </config> From 2dbf838540bf9bc0efbad683eb5b743632877bbe Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 15 Aug 2019 13:00:54 -0500 Subject: [PATCH 315/372] MC-19194: UpdateCartItems mutation does not update cart item quantity - fix performance issue --- .../QuoteGraphQl/Model/Cart/UpdateCartItem.php | 5 +---- .../QuoteGraphQl/Model/Resolver/UpdateCartItems.php | 12 +++++++++++- .../GraphQl/Quote/Guest/UpdateCartItemsTest.php | 10 ++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php index b18c6ad662335..7b5c9a57a7be9 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php @@ -93,8 +93,6 @@ public function execute(Quote $cart, int $cartItemId, float $quantity, array $cu ) ); } - - $this->quoteRepository->save($cart); } /** @@ -105,7 +103,7 @@ public function execute(Quote $cart, int $cartItemId, float $quantity, array $cu * @param float $quantity * @throws GraphQlNoSuchEntityException * @throws NoSuchEntityException - * @throws GraphQlNoSuchEntityException + * @throws GraphQlInputException */ private function updateItemQuantity(int $itemId, Quote $cart, float $quantity) { @@ -117,7 +115,6 @@ private function updateItemQuantity(int $itemId, Quote $cart, float $quantity) } $cartItem->setQty($quantity); $this->validateCartItem($cartItem); - $this->cartItemRepository->save($cartItem); } /** diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php index 8066c28e9e48a..241237613b94e 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php @@ -15,6 +15,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Api\CartItemRepositoryInterface; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\Quote; use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; use Magento\QuoteGraphQl\Model\Cart\UpdateCartItem; @@ -39,19 +40,27 @@ class UpdateCartItems implements ResolverInterface */ private $cartItemRepository; + /** + * @var CartRepositoryInterface + */ + private $cartRepository; + /** * @param GetCartForUser $getCartForUser * @param CartItemRepositoryInterface $cartItemRepository * @param UpdateCartItem $updateCartItem + * @param CartRepositoryInterface $cartRepository */ public function __construct( GetCartForUser $getCartForUser, CartItemRepositoryInterface $cartItemRepository, - UpdateCartItem $updateCartItem + UpdateCartItem $updateCartItem, + CartRepositoryInterface $cartRepository ) { $this->getCartForUser = $getCartForUser; $this->cartItemRepository = $cartItemRepository; $this->updateCartItem = $updateCartItem; + $this->cartRepository = $cartRepository; } /** @@ -76,6 +85,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value try { $this->processCartItems($cart, $cartItems); + $this->cartRepository->save($cart); } catch (NoSuchEntityException $e) { throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } catch (LocalizedException $e) { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php index 13d9bb011d9b2..6ac683ef77ade 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php @@ -71,6 +71,7 @@ public function testUpdateCartItemQuantity() $this->assertEquals($itemId, $item['id']); $this->assertEquals($quantity, $item['quantity']); + //Check that update is correctly reflected in cart $cartQuery = $this->getCartQuery($maskedQuoteId); $response = $this->graphQlQuery($cartQuery); @@ -101,6 +102,15 @@ public function testRemoveCartItemIfQuantityIsZero() $responseCart = $response['updateCartItems']['cart']; $this->assertCount(0, $responseCart['items']); + + //Check that update is correctly reflected in cart + $cartQuery = $this->getCartQuery($maskedQuoteId); + $response = $this->graphQlQuery($cartQuery); + + $this->assertArrayHasKey('cart', $response); + + $responseCart = $response['cart']; + $this->assertCount(0, $responseCart['items']); } /** From 98efddb24cc787d94113b9c5a83dae4a5771a9f2 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Thu, 15 Aug 2019 13:50:28 -0500 Subject: [PATCH 316/372] MQE-1702: Bump MFTF version in Magento - MFTF Version Bump --- composer.json | 2 +- composer.lock | 74 +++++++++++++++++++++++++-------------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/composer.json b/composer.json index 60f52e8ebc0bc..8b2cb0b53972a 100644 --- a/composer.json +++ b/composer.json @@ -88,7 +88,7 @@ "friendsofphp/php-cs-fixer": "~2.14.0", "lusitanian/oauth": "~0.8.10", "magento/magento-coding-standard": "~3.0.0", - "magento/magento2-functional-testing-framework": "2.4.3", + "magento/magento2-functional-testing-framework": "2.4.4", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 675848c495915..8af9ead67d9c1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b5c5eeedfc8a724202af911b637f7b16", + "content-hash": "8819d140d0951fefd8e14b052ff0f61a", "packages": [ { "name": "braintree/braintree_php", @@ -1440,13 +1440,13 @@ }, { "name": "John Kelly", - "email": "johnmkelly86@gmail.com", - "role": "Maintainer" + "role": "Maintainer", + "email": "johnmkelly86@gmail.com" }, { "name": "Raúl Araya", - "email": "nubeiro@gmail.com", - "role": "Maintainer" + "role": "Maintainer", + "email": "nubeiro@gmail.com" } ], "description": "Formerly videlalvaro/php-amqplib. This library is a pure PHP implementation of the AMQP protocol. It's been tested against RabbitMQ.", @@ -1552,28 +1552,28 @@ "authors": [ { "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" + "role": "Lead Developer", + "email": "terrafrost@php.net" }, { "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" + "role": "Developer", + "email": "pm@datasphere.ch" }, { "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" + "role": "Developer", + "email": "bantu@phpbb.com" }, { "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" + "role": "Developer", + "email": "petrich@tronic-media.com" }, { "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" + "role": "Developer", + "email": "graham@alt-three.com" } ], "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", @@ -2402,7 +2402,7 @@ }, { "name": "Gert de Pagter", - "email": "backendtea@gmail.com" + "email": "BackEndTea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", @@ -4912,8 +4912,8 @@ "authors": [ { "name": "Ivan Krutov", - "email": "vania-pooh@yandex-team.ru", - "role": "Developer" + "role": "Developer", + "email": "vania-pooh@yandex-team.ru" } ], "description": "A Codeception adapter for Allure report.", @@ -4967,8 +4967,8 @@ "authors": [ { "name": "Ivan Krutov", - "email": "vania-pooh@yandex-team.ru", - "role": "Developer" + "role": "Developer", + "email": "vania-pooh@yandex-team.ru" } ], "description": "PHP API for Allure adapter", @@ -6697,9 +6697,9 @@ "authors": [ { "name": "Phil Bennett", + "role": "Developer", "email": "philipobenito@gmail.com", - "homepage": "http://www.philipobenito.com", - "role": "Developer" + "homepage": "http://www.philipobenito.com" } ], "description": "A fast and intuitive dependency injection container.", @@ -6814,16 +6814,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.4.3", + "version": "2.4.4", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "9e9a20fd4c77833ef41ac07eb076a7f2434ce61c" + "reference": "ab347cf23d01f6bb9d158ab37d2dc56594999beb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/9e9a20fd4c77833ef41ac07eb076a7f2434ce61c", - "reference": "9e9a20fd4c77833ef41ac07eb076a7f2434ce61c", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/ab347cf23d01f6bb9d158ab37d2dc56594999beb", + "reference": "ab347cf23d01f6bb9d158ab37d2dc56594999beb", "shasum": "" }, "require": { @@ -6885,7 +6885,7 @@ "magento", "testing" ], - "time": "2019-08-02T14:26:18+00:00" + "time": "2019-08-15T14:46:36+00:00" }, { "name": "mikey179/vfsstream", @@ -6925,8 +6925,8 @@ "authors": [ { "name": "Frank Kleine", - "homepage": "http://frankkleine.de/", - "role": "Developer" + "role": "Developer", + "homepage": "http://frankkleine.de/" } ], "description": "Virtual file system to mock the real file system in unit tests.", @@ -7700,8 +7700,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", @@ -7970,8 +7970,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "The PHP Unit Testing framework.", @@ -8545,8 +8545,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "Copy/Paste Detector (CPD) for PHP code.", @@ -9542,8 +9542,8 @@ "authors": [ { "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "lead" + "role": "lead", + "email": "arne@blankerts.de" } ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", From b9d468ceb37a9ef32b6ca60e88feac6711e3bb32 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 15 Aug 2019 14:03:32 -0500 Subject: [PATCH 317/372] MC-19145: [CLOUD] Internal error after DHL was configured --- app/code/Magento/Dhl/Model/Carrier.php | 56 ++++++++++--------- app/code/Magento/Ups/Model/Carrier.php | 46 +++++++-------- app/code/Magento/Usps/Model/Carrier.php | 46 +++++++-------- .../Async/ProxyDeferredFactoryTest.php | 31 +++++----- 4 files changed, 95 insertions(+), 84 deletions(-) diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php index 5959294fe6dc7..5d96d4bcbf43a 100644 --- a/app/code/Magento/Dhl/Model/Carrier.php +++ b/app/code/Magento/Dhl/Model/Carrier.php @@ -10,7 +10,6 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Async\CallbackDeferred; -use Magento\Framework\Async\ProxyDeferredFactory; use Magento\Framework\HTTP\AsyncClient\HttpResponseDeferredInterface; use Magento\Framework\HTTP\AsyncClient\Request; use Magento\Framework\HTTP\AsyncClientInterface; @@ -21,6 +20,7 @@ use Magento\Quote\Model\Quote\Address\RateResult\Error; use Magento\Shipping\Model\Carrier\AbstractCarrier; use Magento\Shipping\Model\Rate\Result; +use Magento\Shipping\Model\Rate\Result\ProxyDeferredFactory; use Magento\Framework\Xml\Security; use Magento\Dhl\Model\Validator\XmlValidator; @@ -389,16 +389,17 @@ public function collectRates(RateRequest $request) //Saving $result to use proper result with the callback $this->_result = $result = $this->_getQuotes(); //After quotes are loaded parsing the response. - return $this->proxyDeferredFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($request, $result) { - $this->_result = $result; - $this->_updateFreeMethodQuote($request); - - return $this->_result; - } - ) + return $this->proxyDeferredFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($request, $result) { + $this->_result = $result; + $this->_updateFreeMethodQuote($request); + + return $this->_result; + } + ) + ] ); } @@ -1057,23 +1058,24 @@ protected function _getQuotes() } } - return $this->proxyDeferredFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($deferredResponses, $responseBodies) { - //Loading rates not found in cache - foreach ($deferredResponses as $deferredResponseData) { - $responseBodies[] = [ - 'body' => $deferredResponseData['deferred']->get()->getBody(), - 'date' => $deferredResponseData['date'], - 'request' => $deferredResponseData['request'], - 'from_cache' => false - ]; - } + return $this->proxyDeferredFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($deferredResponses, $responseBodies) { + //Loading rates not found in cache + foreach ($deferredResponses as $deferredResponseData) { + $responseBodies[] = [ + 'body' => $deferredResponseData['deferred']->get()->getBody(), + 'date' => $deferredResponseData['date'], + 'request' => $deferredResponseData['request'], + 'from_cache' => false + ]; + } - return $this->processQuotesResponses($responseBodies); - } - ) + return $this->processQuotesResponses($responseBodies); + } + ) + ] ); } diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php index 5320aeb5bcc8a..72b68c476d88a 100644 --- a/app/code/Magento/Ups/Model/Carrier.php +++ b/app/code/Magento/Ups/Model/Carrier.php @@ -9,7 +9,6 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Async\CallbackDeferred; -use Magento\Framework\Async\ProxyDeferredFactory; use Magento\Framework\DataObject; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\HTTP\AsyncClient\HttpResponseDeferredInterface; @@ -22,6 +21,7 @@ use Magento\Shipping\Model\Carrier\AbstractCarrierOnline; use Magento\Shipping\Model\Carrier\CarrierInterface; use Magento\Shipping\Model\Rate\Result; +use Magento\Shipping\Model\Rate\Result\ProxyDeferredFactory; use Magento\Shipping\Model\Simplexml\Element; use Magento\Ups\Helper\Config; use Magento\Shipping\Model\Shipment\Request as Shipment; @@ -239,15 +239,16 @@ public function collectRates(RateRequest $request) //To use the correct result in the callback. $this->_result = $result = $this->_getQuotes(); - return $this->deferredProxyFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($request, $result) { - $this->_result = $result; - $this->_updateFreeMethodQuote($request); - return $this->getResult(); - } - ) + return $this->deferredProxyFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($request, $result) { + $this->_result = $result; + $this->_updateFreeMethodQuote($request); + return $this->getResult(); + } + ) + ] ); } @@ -782,19 +783,20 @@ protected function _getXmlQuotes() new Request($url, Request::METHOD_POST, ['Content-Type' => 'application/xml'], $xmlRequest) ); - return $this->deferredProxyFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($httpResponse) { - if ($httpResponse->get()->getStatusCode() >= 400) { - $xmlResponse = ''; - } else { - $xmlResponse = $httpResponse->get()->getBody(); - } + return $this->deferredProxyFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($httpResponse) { + if ($httpResponse->get()->getStatusCode() >= 400) { + $xmlResponse = ''; + } else { + $xmlResponse = $httpResponse->get()->getBody(); + } - return $this->_parseXmlResponse($xmlResponse); - } - ) + return $this->_parseXmlResponse($xmlResponse); + } + ) + ] ); } diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index 7136a403003df..1c8ff0ce9efa9 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -8,7 +8,6 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Async\CallbackDeferred; -use Magento\Framework\Async\ProxyDeferredFactory; use Magento\Framework\HTTP\AsyncClient\Request; use Magento\Framework\HTTP\AsyncClientInterface; use Magento\Framework\Xml\Security; @@ -16,6 +15,7 @@ use Magento\Shipping\Helper\Carrier as CarrierHelper; use Magento\Shipping\Model\Carrier\AbstractCarrierOnline; use Magento\Shipping\Model\Rate\Result; +use Magento\Shipping\Model\Rate\Result\ProxyDeferredFactory; use Magento\Usps\Helper\Data as DataHelper; /** @@ -239,16 +239,17 @@ public function collectRates(RateRequest $request) //Saving current result to use the right one in the callback. $this->_result = $result = $this->_getQuotes(); - return $this->proxyDeferredFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($request, $result) { - $this->_result = $result; - $this->_updateFreeMethodQuote($request); + return $this->proxyDeferredFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($request, $result) { + $this->_result = $result; + $this->_updateFreeMethodQuote($request); - return $this->getResult(); - } - ) + return $this->getResult(); + } + ) + ] ); } @@ -555,18 +556,19 @@ protected function _getXmlQuotes() ) ); - return $this->proxyDeferredFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($deferredResponse, $request, $debugData) { - $responseBody = $deferredResponse->get()->getBody(); - $debugData['result'] = $responseBody; - $this->_setCachedQuotes($request, $responseBody); - $this->_debug($debugData); - - return $this->_parseXmlResponse($responseBody); - } - ) + return $this->proxyDeferredFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($deferredResponse, $request, $debugData) { + $responseBody = $deferredResponse->get()->getBody(); + $debugData['result'] = $responseBody; + $this->_setCachedQuotes($request, $responseBody); + $this->_debug($debugData); + + return $this->_parseXmlResponse($responseBody); + } + ) + ] ); } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Async/ProxyDeferredFactoryTest.php b/dev/tests/integration/testsuite/Magento/Framework/Async/ProxyDeferredFactoryTest.php index e4385b598c604..21392e5f7b127 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Async/ProxyDeferredFactoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Async/ProxyDeferredFactoryTest.php @@ -18,7 +18,7 @@ class ProxyDeferredFactoryTest extends TestCase { /** - * @var ProxyDeferredFactory + * @var \TestDeferred\TestClass\ProxyDeferredFactory */ private $factory; @@ -43,6 +43,7 @@ protected function setUp() //phpcs:ignore include_once __DIR__ .'/_files/test_class.php'; \TestDeferred\TestClass::$created = 0; + $this->factory = Bootstrap::getObjectManager()->get(\TestDeferred\TestClass\ProxyDeferredFactory::class); } /* @@ -57,9 +58,10 @@ public function testCreate(): void return new \TestDeferred\TestClass($value); }; /** @var \TestDeferred\TestClass $proxy */ - $proxy = $this->factory->createFor( - \TestDeferred\TestClass::class, - $this->callbackDeferredFactory->create(['callback' => $callback]) + $proxy = $this->factory->create( + [ + 'deferred' => $this->callbackDeferredFactory->create(['callback' => $callback]) + ] ); $this->assertInstanceOf(\TestDeferred\TestClass::class, $proxy); $this->assertEmpty(\TestDeferred\TestClass::$created); @@ -80,9 +82,10 @@ public function testSerialize(): void return new \TestDeferred\TestClass($value); }; /** @var \TestDeferred\TestClass $proxy */ - $proxy = $this->factory->createFor( - \TestDeferred\TestClass::class, - $this->callbackDeferredFactory->create(['callback' => $callback]) + $proxy = $this->factory->create( + [ + 'deferred' => $this->callbackDeferredFactory->create(['callback' => $callback]) + ] ); //phpcs:disable /** @var \TestDeferred\TestClass $unserialized */ @@ -106,9 +109,10 @@ public function testClone(): void return new \TestDeferred\TestClass($value); }; /** @var \TestDeferred\TestClass $proxy */ - $proxy = $this->factory->createFor( - \TestDeferred\TestClass::class, - $this->callbackDeferredFactory->create(['callback' => $callback]) + $proxy = $this->factory->create( + [ + 'deferred' => $this->callbackDeferredFactory->create(['callback' => $callback]) + ] ); $this->assertEquals(0, \TestDeferred\TestClass::$created); $this->assertEquals(0, $called); @@ -137,9 +141,10 @@ public function getValue() }; }; /** @var \TestDeferred\TestClass $proxy */ - $proxy = $this->factory->createFor( - \TestDeferred\TestClass::class, - $this->callbackDeferredFactory->create(['callback' => $callback]) + $proxy = $this->factory->create( + [ + 'deferred' => $this->callbackDeferredFactory->create(['callback' => $callback]) + ] ); $this->assertInstanceOf(\TestDeferred\TestClass::class, $proxy); $this->assertEmpty(\TestDeferred\TestClass::$created); From a2f86726b6c60bf059987ba8fbda7d59c1f1422b Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Fri, 16 Aug 2019 09:45:46 +0300 Subject: [PATCH 318/372] MC-19080: Incorrect behavior after shipping methods disabled --- .../OfflineShipping/Model/CollectRatesTest.php | 2 +- ...ectRatesTest.php => CollectRatesAbstract.php} | 16 ++++++++++------ .../Magento/Ups/Model/CollectRatesTest.php | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) rename dev/tests/integration/testsuite/Magento/Shipping/Model/{CollectRatesTest.php => CollectRatesAbstract.php} (85%) diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php index 910b4f570c360..1b85f99752cf8 100644 --- a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php @@ -11,7 +11,7 @@ * Integration tests for offline shipping carriers. * @magentoAppIsolation enabled */ -class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesTest +class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesAbstract { /** * @var string diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesAbstract.php similarity index 85% rename from dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php rename to dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesAbstract.php index a5994cc604a65..e120f2f64359b 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesAbstract.php @@ -15,11 +15,10 @@ use Magento\TestFramework\Helper\Bootstrap; /** - * Integration tests for shipping carriers. + * Abstract class for testing shipping carriers. */ -class CollectRatesTest extends \PHPUnit\Framework\TestCase +abstract class CollectRatesAbstract extends \PHPUnit\Framework\TestCase { - /** * @var ObjectManagerInterface */ @@ -45,14 +44,13 @@ class CollectRatesTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - if (empty($this->carrier) || empty($this->errorMessage)) { - $this->markTestSkipped('Required fields are empty'); - } $this->objectManager = Bootstrap::getObjectManager(); $this->shipping = $this->objectManager->get(Shipping::class); } /** + * Tests that an error message is displayed when the shipping method is enabled and not applicable. + * * @return void */ public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() @@ -65,6 +63,8 @@ public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() } /** + * Tests that shipping rates don't return when the shipping method is disabled and not applicable. + * * @return void */ public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() @@ -76,6 +76,8 @@ public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicabl } /** + * Returns customer address. + * * @return DataObject */ private function getAddress(): DataObject @@ -102,6 +104,8 @@ private function getAddress(): DataObject } /** + * Returns shipping rate by the result. + * * @param Result $result * @return Method|Error */ diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php index 58f31836a310a..7cfaa8c7de733 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php @@ -11,7 +11,7 @@ * Integration tests for online shipping carriers. * @magentoAppIsolation enabled */ -class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesTest +class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesAbstract { /** * @var string From 789ed270d885afd20425da30b71b94cbedb49ce1 Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Fri, 16 Aug 2019 14:42:08 +0300 Subject: [PATCH 319/372] MC-19089: OnePageCheckoutDeclinedTest fails on Bamboo. Order is placed with incorrect credit card number --- .../frontend/web/js/view/payment/method-renderer/cc-form.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js index ac97e4fa5eb58..5f06d26e2acfc 100644 --- a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js +++ b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js @@ -246,8 +246,10 @@ define( return; } - self.setPaymentPayload(payload); - self.placeOrder(); + if (self.validateCardType()) { + self.setPaymentPayload(payload); + self.placeOrder(); + } }); } }, From 60fc2086c62398f325426c307d8158ff988eb09a Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 16 Aug 2019 15:43:58 +0300 Subject: [PATCH 320/372] MC-19334: Reindex error when website have store without store view --- .../Magento/Store/Model/ScopeTreeProvider.php | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Store/Model/ScopeTreeProvider.php b/app/code/Magento/Store/Model/ScopeTreeProvider.php index da772ec0410e0..a22d5abb8c486 100644 --- a/app/code/Magento/Store/Model/ScopeTreeProvider.php +++ b/app/code/Magento/Store/Model/ScopeTreeProvider.php @@ -78,25 +78,30 @@ public function get() 'scopes' => [], ]; - /** @var Group $group */ - foreach ($groups[$website->getId()] as $group) { - $groupScope = [ - 'scope' => ScopeInterface::SCOPE_GROUP, - 'scope_id' => $group->getId(), - 'scopes' => [], - ]; - - /** @var Store $store */ - foreach ($stores[$group->getId()] as $store) { - $storeScope = [ - 'scope' => ScopeInterface::SCOPE_STORES, - 'scope_id' => $store->getId(), + if (!empty($groups[$website->getId()])) { + /** @var Group $group */ + foreach ($groups[$website->getId()] as $group) { + $groupScope = [ + 'scope' => ScopeInterface::SCOPE_GROUP, + 'scope_id' => $group->getId(), 'scopes' => [], ]; - $groupScope['scopes'][] = $storeScope; + + if (!empty($stores[$group->getId()])) { + /** @var Store $store */ + foreach ($stores[$group->getId()] as $store) { + $storeScope = [ + 'scope' => ScopeInterface::SCOPE_STORES, + 'scope_id' => $store->getId(), + 'scopes' => [], + ]; + $groupScope['scopes'][] = $storeScope; + } + } + $websiteScope['scopes'][] = $groupScope; } - $websiteScope['scopes'][] = $groupScope; } + $defaultScope['scopes'][] = $websiteScope; } From 059b5cc7d1d069d870f80e5ecdead1ea54effcf8 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Fri, 16 Aug 2019 12:08:39 -0500 Subject: [PATCH 321/372] MC-19145: [CLOUD] Internal error after DHL was configured --- app/code/Magento/Dhl/Model/Carrier.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php index 5d96d4bcbf43a..0a1632a45cb0c 100644 --- a/app/code/Magento/Dhl/Model/Carrier.php +++ b/app/code/Magento/Dhl/Model/Carrier.php @@ -819,15 +819,13 @@ protected function _getAllItems() if (!empty($decimalItems)) { foreach ($decimalItems as $decimalItem) { - $fullItems = array_merge( - $fullItems, - array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']) - ); + $fullItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']); } } else { - $fullItems = array_merge($fullItems, array_fill(0, $qty, $this->_getWeight($itemWeight))); + $fullItems[] = array_fill(0, $qty, $this->_getWeight($itemWeight)); } } + $fullItems = array_merge(...$fullItems); sort($fullItems); return $fullItems; From a2397de3e0e26c8c92143069a104403aaa113b91 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 16 Aug 2019 14:14:20 -0500 Subject: [PATCH 322/372] MC-19338: Fix MTF UpgradeSystemTest --- .../tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php index c9b3ce35e84ed..7a82b43dba76d 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php @@ -132,6 +132,8 @@ public function test( // Check application version $this->adminDashboard->open(); + $this->adminDashboard->getModalMessage()->dismissIfModalAppears(); + $this->adminDashboard->getModalMessage()->waitModalWindowToDisappear(); $assertApplicationVersion->processAssert($this->adminDashboard, $version); } } From 5271f434440d2f589c782a996d8d73bedbb36bc8 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 20 Aug 2019 11:32:03 +0300 Subject: [PATCH 323/372] MC-19334: Reindex error when website have store without store view --- .../Command/IndexerReindexCommandTest.php | 61 +++++++++++++++++++ ...second_store_group_with_second_website.php | 21 +++++++ ...ore_group_with_second_website_rollback.php | 8 +++ 3 files changed, 90 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php create mode 100644 dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php b/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php new file mode 100644 index 0000000000000..1779281f2cb80 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Indexer\Console\Command; + +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit_Framework_MockObject_MockObject as Mock; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Tests for \Magento\Indexer\Console\Command\IndexerReindexCommand. + * + * @magentoDbIsolation disabled + */ +class IndexerReindexCommandTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var InputInterface|Mock + */ + private $inputMock; + + /** + * @var OutputInterface|Mock + */ + private $outputMock; + + /** + * @inheritdoc + */ + protected function setUp() + { + Bootstrap::getInstance()->reinitialize(); + $this->objectManager = Bootstrap::getObjectManager(); + + $this->inputMock = $this->getMockBuilder(InputInterface::class) + ->getMockForAbstractClass(); + $this->outputMock = $this->getMockBuilder(OutputInterface::class) + ->getMockForAbstractClass(); + } + + /** + * @magentoDataFixture Magento/Store/_files/second_store_group_with_second_website.php + */ + public function testReindexAll() + { + $command = $this->objectManager->create(IndexerReindexCommand::class); + $status = $command->run($this->inputMock, $this->outputMock); + $this->assertEquals(0, $status, 'Index wasn\'t success'); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php new file mode 100644 index 0000000000000..a66bfb9138716 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php @@ -0,0 +1,21 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require_once __DIR__ . '/website.php'; + +/** + * @var \Magento\Store\Model\Group $storeGroup + */ +$storeGroup = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Group::class); +$storeGroup->setCode('some_group') + ->setName('custom store group') + ->setWebsite($website); +$storeGroup->save($storeGroup); + +/* Refresh stores memory cache */ +$objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website_rollback.php new file mode 100644 index 0000000000000..e014dc9402475 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require_once __DIR__ . '/website_rollback.php'; From 5bc42334e00cb5bd508a026e1edc1809a258ec36 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 20 Aug 2019 12:44:04 +0300 Subject: [PATCH 324/372] MC-19334: Reindex error when website have store without store view --- .../Command/IndexerReindexCommandTest.php | 24 ++++++++++++------- ...second_store_group_with_second_website.php | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php b/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php index 1779281f2cb80..80b6f887d6501 100644 --- a/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php +++ b/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php @@ -17,6 +17,7 @@ * Tests for \Magento\Indexer\Console\Command\IndexerReindexCommand. * * @magentoDbIsolation disabled + * @magentoAppIsolation enabled */ class IndexerReindexCommandTest extends \PHPUnit\Framework\TestCase { @@ -35,18 +36,22 @@ class IndexerReindexCommandTest extends \PHPUnit\Framework\TestCase */ private $outputMock; + /** + * @var IndexerReindexCommand + */ + private $command; + /** * @inheritdoc */ protected function setUp() { - Bootstrap::getInstance()->reinitialize(); $this->objectManager = Bootstrap::getObjectManager(); - $this->inputMock = $this->getMockBuilder(InputInterface::class) - ->getMockForAbstractClass(); - $this->outputMock = $this->getMockBuilder(OutputInterface::class) - ->getMockForAbstractClass(); + $this->inputMock = $this->getMockBuilder(InputInterface::class)->getMockForAbstractClass(); + $this->outputMock = $this->getMockBuilder(OutputInterface::class)->getMockForAbstractClass(); + + $this->command = $this->objectManager->get(IndexerReindexCommand::class); } /** @@ -54,8 +59,11 @@ protected function setUp() */ public function testReindexAll() { - $command = $this->objectManager->create(IndexerReindexCommand::class); - $status = $command->run($this->inputMock, $this->outputMock); - $this->assertEquals(0, $status, 'Index wasn\'t success'); + $status = $this->command->run($this->inputMock, $this->outputMock); + $this->assertEquals( + \Magento\Framework\Console\Cli::RETURN_SUCCESS, + $status, + 'Index wasn\'t success' + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php index a66bfb9138716..799cda7e97423 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php @@ -11,7 +11,7 @@ /** * @var \Magento\Store\Model\Group $storeGroup */ -$storeGroup = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Group::class); +$storeGroup = $objectManager->create(\Magento\Store\Model\Group::class); $storeGroup->setCode('some_group') ->setName('custom store group') ->setWebsite($website); From e6cfdb3152d302c092b3420437e481450e28ea7f Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov <vzabaznov@magento.com> Date: Tue, 20 Aug 2019 13:21:24 -0500 Subject: [PATCH 325/372] MC-19500: fix related-product changes affection on third party extensions --- .../Magento/Catalog/view/frontend/web/js/related-products.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/related-products.js b/app/code/Magento/Catalog/view/frontend/web/js/related-products.js index d17c25d421e02..5845b6d7afe38 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/related-products.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/related-products.js @@ -26,8 +26,8 @@ define([ * @private */ _create: function () { - $(this.options.selectAllLink).on('click', $.proxy(this._selectAllRelated, this)); - $(this.options.relatedCheckbox).on('click', $.proxy(this._addRelatedToProduct, this)); + $(this.options.selectAllLink, this.element).on('click', $.proxy(this._selectAllRelated, this)); + $(this.options.relatedCheckbox, this.element).on('click', $.proxy(this._addRelatedToProduct, this)); this._showRelatedProducts( this.element.find(this.options.elementsSelector), this.element.data('limit'), From 9c4c3a05c7c14de1c1fd3d28f56bd409cd9f2a39 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 21 Aug 2019 09:24:51 +0300 Subject: [PATCH 326/372] MC-19415: Displayed incorrect price - revert MC-17919 --- .../Indexer/Stock/DefaultStock.php | 10 ++- .../Model/Indexer/Stock/Action/FullTest.php | 71 ++++--------------- 2 files changed, 21 insertions(+), 60 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php index 3670b93b8cb48..519466c505539 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php @@ -230,6 +230,8 @@ protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = f { $connection = $this->getConnection(); $qtyExpr = $connection->getCheckSql('cisi.qty > 0', 'cisi.qty', 0); + $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); + $linkField = $metadata->getLinkField(); $select = $connection->select()->from( ['e' => $this->getTable('catalog_product_entity')], @@ -243,6 +245,12 @@ protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = f ['cisi' => $this->getTable('cataloginventory_stock_item')], 'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id', [] + )->joinInner( + ['mcpei' => $this->getTable('catalog_product_entity_int')], + 'e.' . $linkField . ' = mcpei.' . $linkField + . ' AND mcpei.attribute_id = ' . $this->_getAttribute('status')->getId() + . ' AND mcpei.value = ' . ProductStatus::STATUS_ENABLED, + [] )->columns( ['qty' => $qtyExpr] )->where( @@ -284,7 +292,6 @@ protected function _prepareIndexTable($entityIds = null) */ protected function _updateIndex($entityIds) { - $this->deleteOldRecords($entityIds); $connection = $this->getConnection(); $select = $this->_getStockStatusSelect($entityIds, true); $select = $this->getQueryProcessorComposite()->processQuery($select, $entityIds, true); @@ -307,6 +314,7 @@ protected function _updateIndex($entityIds) } } + $this->deleteOldRecords($entityIds); $this->_updateIndexTable($data); return $this; diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php index 00c13619ff2c1..6bf1f5fbf0be2 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php @@ -5,42 +5,24 @@ */ namespace Magento\CatalogInventory\Model\Indexer\Stock\Action; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\ObjectManagerInterface; -use Magento\CatalogInventory\Model\Indexer\Stock\Processor; -use Magento\Catalog\Model\CategoryFactory; -use Magento\Catalog\Block\Product\ListProduct; -use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; -use Magento\Catalog\Model\Product; -use PHPUnit\Framework\TestCase; - /** * Full reindex Test */ -class FullTest extends TestCase +class FullTest extends \PHPUnit\Framework\TestCase { /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * @var Processor + * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor */ protected $_processor; - /** - * @inheritdoc - */ protected function setUp() { - $this->objectManager = Bootstrap::getObjectManager(); - $this->_processor = $this->objectManager->get(Processor::class); + $this->_processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\CatalogInventory\Model\Indexer\Stock\Processor::class + ); } /** - * Reindex all - * * @magentoDbIsolation disabled * @magentoAppIsolation enabled * @magentoDataFixture Magento/Catalog/_files/product_simple.php @@ -49,9 +31,13 @@ public function testReindexAll() { $this->_processor->reindexAll(); - $categoryFactory = $this->objectManager->get(CategoryFactory::class); - /** @var ListProduct $listProduct */ - $listProduct = $this->objectManager->get(ListProduct::class); + $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Catalog\Model\CategoryFactory::class + ); + /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */ + $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Catalog\Block\Product\ListProduct::class + ); $category = $categoryFactory->create()->load(2); $layer = $listProduct->getLayer(); @@ -75,37 +61,4 @@ public function testReindexAll() $this->assertEquals(100, $product->getQty()); } } - - /** - * Reindex with disabled product - * - * @return void - * @magentoDbIsolation disabled - * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Catalog/_files/products_with_layered_navigation_attribute.php - */ - public function testReindexAllWithDisabledProduct(): void - { - $productCollectionFactory = $this->objectManager->get(CollectionFactory::class); - $productCollection = $productCollectionFactory - ->create() - ->addAttributeToSelect('*') - ->addAttributeToFilter('sku', ['eq' => 'simple3']) - ->addAttributeToSort('created_at', 'DESC') - ->joinField( - 'stock_status', - 'cataloginventory_stock_status', - 'stock_status', - 'product_id=entity_id', - '{{table}}.stock_id=1', - 'left' - )->load(); - - $this->assertCount(1, $productCollection); - - /** @var Product $product */ - foreach ($productCollection as $product) { - $this->assertEquals(1, $product->getData('stock_status')); - } - } } From 39504ceabde0a171af102826095a89df2ab9d058 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Wed, 21 Aug 2019 06:43:30 +0000 Subject: [PATCH 327/372] MC-19051: [backport for 2.3.3] Nightly build jobs were failing lately after un-skipping tests in MC-5777 --- .../Catalog/Model/Product/Type/Price.php | 5 +- .../Model/Indexer/ReindexRuleProduct.php | 51 ++++--- .../Model/Indexer/ReindexRuleProductPrice.php | 75 +++++----- .../Product/CollectionProcessor.php | 2 +- ...ProductSelectBuilderByCatalogRulePrice.php | 3 +- ...CatalogProductCollectionPricesObserver.php | 2 +- .../ProcessAdminFinalPriceObserver.php | 3 +- .../ProcessFrontFinalPriceObserver.php | 2 +- .../Pricing/Price/CatalogRulePrice.php | 2 +- .../Indexer/ReindexRuleProductPriceTest.php | 131 ++++++++--------- .../Model/Indexer/ReindexRuleProductTest.php | 135 +++++++++++------- .../Pricing/Price/CatalogRulePriceTest.php | 8 +- 12 files changed, 238 insertions(+), 181 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index dc73baef3f768..23a058b5a57c9 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -596,7 +596,10 @@ public function calculatePrice( ) { \Magento\Framework\Profiler::start('__PRODUCT_CALCULATE_PRICE__'); if ($wId instanceof Store) { + $sId = $wId->getId(); $wId = $wId->getWebsiteId(); + } else { + $sId = $this->_storeManager->getWebsite($wId)->getDefaultGroup()->getDefaultStoreId(); } $finalPrice = $basePrice; @@ -610,7 +613,7 @@ public function calculatePrice( ); if ($rulePrice === false) { - $date = $this->_localeDate->date(null, null, false); + $date = $this->_localeDate->scopeDate($sId); $rulePrice = $this->_ruleFactory->create()->getRulePrice($date, $wId, $gId, $productId); } diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php index 55a234bb8ae27..e589c8595ce2c 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php @@ -8,7 +8,10 @@ use Magento\CatalogRule\Model\Indexer\IndexerTableSwapperInterface as TableSwapper; use Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher; -use Magento\Framework\App\ObjectManager; +use Magento\CatalogRule\Model\Rule; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Model\ScopeInterface; /** * Reindex rule relations with products. @@ -16,7 +19,7 @@ class ReindexRuleProduct { /** - * @var \Magento\Framework\App\ResourceConnection + * @var ResourceConnection */ private $resource; @@ -31,36 +34,40 @@ class ReindexRuleProduct private $tableSwapper; /** - * @param \Magento\Framework\App\ResourceConnection $resource + * @var TimezoneInterface + */ + private $localeDate; + + /** + * @param ResourceConnection $resource * @param ActiveTableSwitcher $activeTableSwitcher - * @param TableSwapper|null $tableSwapper + * @param TableSwapper $tableSwapper + * @param TimezoneInterface $localeDate */ public function __construct( - \Magento\Framework\App\ResourceConnection $resource, + ResourceConnection $resource, ActiveTableSwitcher $activeTableSwitcher, - TableSwapper $tableSwapper = null + TableSwapper $tableSwapper, + TimezoneInterface $localeDate ) { $this->resource = $resource; $this->activeTableSwitcher = $activeTableSwitcher; - $this->tableSwapper = $tableSwapper ?? - ObjectManager::getInstance()->get(TableSwapper::class); + $this->tableSwapper = $tableSwapper; + $this->localeDate = $localeDate; } /** * Reindex information about rule relations with products. * - * @param \Magento\CatalogRule\Model\Rule $rule + * @param Rule $rule * @param int $batchCount * @param bool $useAdditionalTable * @return bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function execute( - \Magento\CatalogRule\Model\Rule $rule, - $batchCount, - $useAdditionalTable = false - ) { + public function execute(Rule $rule, $batchCount, $useAdditionalTable = false) + { if (!$rule->getIsActive() || empty($rule->getWebsiteIds())) { return false; } @@ -84,21 +91,26 @@ public function execute( $ruleId = $rule->getId(); $customerGroupIds = $rule->getCustomerGroupIds(); - $fromTime = strtotime($rule->getFromDate()); - $toTime = strtotime($rule->getToDate()); - $toTime = $toTime ? $toTime + \Magento\CatalogRule\Model\Indexer\IndexBuilder::SECONDS_IN_DAY - 1 : 0; $sortOrder = (int)$rule->getSortOrder(); $actionOperator = $rule->getSimpleAction(); $actionAmount = $rule->getDiscountAmount(); $actionStop = $rule->getStopRulesProcessing(); $rows = []; + foreach ($websiteIds as $websiteId) { + $scopeTz = new \DateTimeZone( + $this->localeDate->getConfigTimezone(ScopeInterface::SCOPE_WEBSITE, $websiteId) + ); + $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp(); + $toTime = $rule->getToDate() + ? (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp() + IndexBuilder::SECONDS_IN_DAY - 1 + : 0; - foreach ($productIds as $productId => $validationByWebsite) { - foreach ($websiteIds as $websiteId) { + foreach ($productIds as $productId => $validationByWebsite) { if (empty($validationByWebsite[$websiteId])) { continue; } + foreach ($customerGroupIds as $customerGroupId) { $rows[] = [ 'rule_id' => $ruleId, @@ -123,6 +135,7 @@ public function execute( if (!empty($rows)) { $connection->insertMultiple($indexTable, $rows); } + return true; } } diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php index 6a87be3c50a64..11ba87730bec1 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php @@ -6,54 +6,58 @@ namespace Magento\CatalogRule\Model\Indexer; +use Magento\Catalog\Model\Product; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Model\StoreManagerInterface; + /** * Reindex product prices according rule settings. */ class ReindexRuleProductPrice { /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ private $storeManager; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder + * @var RuleProductsSelectBuilder */ private $ruleProductsSelectBuilder; /** - * @var \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator + * @var ProductPriceCalculator */ private $productPriceCalculator; /** - * @var \Magento\Framework\Stdlib\DateTime\DateTime + * @var TimezoneInterface */ - private $dateTime; + private $localeDate; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor + * @var RuleProductPricesPersistor */ private $pricesPersistor; /** - * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param StoreManagerInterface $storeManager * @param RuleProductsSelectBuilder $ruleProductsSelectBuilder * @param ProductPriceCalculator $productPriceCalculator - * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime - * @param \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor $pricesPersistor + * @param TimezoneInterface $localeDate + * @param RuleProductPricesPersistor $pricesPersistor */ public function __construct( - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder $ruleProductsSelectBuilder, - \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator $productPriceCalculator, - \Magento\Framework\Stdlib\DateTime\DateTime $dateTime, - \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor $pricesPersistor + StoreManagerInterface $storeManager, + RuleProductsSelectBuilder $ruleProductsSelectBuilder, + ProductPriceCalculator $productPriceCalculator, + TimezoneInterface $localeDate, + RuleProductPricesPersistor $pricesPersistor ) { $this->storeManager = $storeManager; $this->ruleProductsSelectBuilder = $ruleProductsSelectBuilder; $this->productPriceCalculator = $productPriceCalculator; - $this->dateTime = $dateTime; + $this->localeDate = $localeDate; $this->pricesPersistor = $pricesPersistor; } @@ -61,22 +65,16 @@ public function __construct( * Reindex product prices. * * @param int $batchCount - * @param \Magento\Catalog\Model\Product|null $product + * @param Product|null $product * @param bool $useAdditionalTable * @return bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function execute( - $batchCount, - \Magento\Catalog\Model\Product $product = null, - $useAdditionalTable = false - ) { - $fromDate = mktime(0, 0, 0, date('m'), date('d') - 1); - $toDate = mktime(0, 0, 0, date('m'), date('d') + 1); - + public function execute($batchCount, Product $product = null, $useAdditionalTable = false) + { /** * Update products rules prices per each website separately - * because of max join limit in mysql + * because for each website date in website's timezone should be used */ foreach ($this->storeManager->getWebsites() as $website) { $productsStmt = $this->ruleProductsSelectBuilder->build($website->getId(), $product, $useAdditionalTable); @@ -84,6 +82,13 @@ public function execute( $stopFlags = []; $prevKey = null; + $storeGroup = $this->storeManager->getGroup($website->getDefaultGroupId()); + $currentDate = $this->localeDate->scopeDate($storeGroup->getDefaultStoreId(), null, true); + $previousDate = (clone $currentDate)->modify('-1 day'); + $previousDate->setTime(23, 59, 59); + $nextDate = (clone $currentDate)->modify('+1 day'); + $nextDate->setTime(0, 0, 0); + while ($ruleData = $productsStmt->fetch()) { $ruleProductId = $ruleData['product_id']; $productKey = $ruleProductId . @@ -100,12 +105,11 @@ public function execute( } } - $ruleData['from_time'] = $this->roundTime($ruleData['from_time']); - $ruleData['to_time'] = $this->roundTime($ruleData['to_time']); /** * Build prices for each day */ - for ($time = $fromDate; $time <= $toDate; $time += IndexBuilder::SECONDS_IN_DAY) { + foreach ([$previousDate, $currentDate, $nextDate] as $date) { + $time = $date->getTimestamp(); if (($ruleData['from_time'] == 0 || $time >= $ruleData['from_time']) && ($ruleData['to_time'] == 0 || $time <= $ruleData['to_time']) @@ -118,7 +122,7 @@ public function execute( if (!isset($dayPrices[$priceKey])) { $dayPrices[$priceKey] = [ - 'rule_date' => $time, + 'rule_date' => $date, 'website_id' => $ruleData['website_id'], 'customer_group_id' => $ruleData['customer_group_id'], 'product_id' => $ruleProductId, @@ -151,18 +155,7 @@ public function execute( } $this->pricesPersistor->execute($dayPrices, $useAdditionalTable); } - return true; - } - /** - * @param int $timeStamp - * @return int - */ - private function roundTime($timeStamp) - { - if (is_numeric($timeStamp) && $timeStamp != 0) { - $timeStamp = $this->dateTime->timestamp($this->dateTime->date('Y-m-d 00:00:00', $timeStamp)); - } - return $timeStamp; + return true; } } diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php index 0dee9eda5b6e8..1fd6f0cbc986f 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php @@ -90,7 +90,7 @@ public function addPriceData(ProductCollection $productCollection, $joinColumn = ), $connection->quoteInto( 'catalog_rule.rule_date = ?', - $this->dateTime->formatDate($this->localeDate->date(null, null, false), false) + $this->dateTime->formatDate($this->localeDate->scopeDate($store->getId()), false) ), ] ), diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php index 02d2631058a1a..48c463fc18b80 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php @@ -88,7 +88,8 @@ public function __construct( */ public function build($productId) { - $currentDate = $this->dateTime->formatDate($this->localeDate->date(null, null, false), false); + $timestamp = $this->localeDate->scopeTimeStamp($this->storeManager->getStore()); + $currentDate = $this->dateTime->formatDate($timestamp, false); $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $productTable = $this->resource->getTableName('catalog_product_entity'); diff --git a/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php b/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php index a635c5611eff6..bf0c85e671dd7 100644 --- a/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php +++ b/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php @@ -105,7 +105,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($observer->getEvent()->hasDate()) { $date = new \DateTime($observer->getEvent()->getDate()); } else { - $date = $this->localeDate->date(null, null, false); + $date = (new \DateTime())->setTimestamp($this->localeDate->scopeTimeStamp($store)); } $productIds = []; diff --git a/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php b/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php index 2fd23ae391474..89ed519cfb8c8 100644 --- a/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php +++ b/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php @@ -65,7 +65,8 @@ public function __construct( public function execute(\Magento\Framework\Event\Observer $observer) { $product = $observer->getEvent()->getProduct(); - $date = $this->localeDate->date(null, null, false); + $storeId = $product->getStoreId(); + $date = $this->localeDate->scopeDate($storeId); $key = false; $ruleData = $this->coreRegistry->registry('rule_data'); diff --git a/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php b/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php index b27768ae091ed..075fe9e51f7dc 100644 --- a/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php +++ b/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php @@ -80,7 +80,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($observer->hasDate()) { $date = new \DateTime($observer->getEvent()->getDate()); } else { - $date = $this->localeDate->date(null, null, false); + $date = $this->localeDate->scopeDate($storeId); } if ($observer->hasWebsiteId()) { diff --git a/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php b/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php index 8bce5456ffa72..7cbbc547571ab 100644 --- a/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php +++ b/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php @@ -88,7 +88,7 @@ public function getValue() $this->value = (float)$this->product->getData(self::PRICE_CODE) ?: false; } else { $this->value = $this->ruleResource->getRulePrice( - $this->dateTime->date(null, null, false), + $this->dateTime->scopeDate($this->storeManager->getStore()->getId()), $this->storeManager->getStore()->getWebsiteId(), $this->customerSession->getCustomerGroupId(), $this->product->getId() diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductPriceTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductPriceTest.php index 6d7f0673ed281..5f63283df6760 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductPriceTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductPriceTest.php @@ -6,65 +6,62 @@ namespace Magento\CatalogRule\Test\Unit\Model\Indexer; -use Magento\CatalogRule\Model\Indexer\IndexBuilder; +use Magento\Catalog\Model\Product; +use Magento\CatalogRule\Model\Indexer\ProductPriceCalculator; +use Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice; +use Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor; +use Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Api\Data\GroupInterface; +use Magento\Store\Api\Data\WebsiteInterface; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\MockObject\MockObject; class ReindexRuleProductPriceTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice + * @var ReindexRuleProductPrice */ private $model; /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var StoreManagerInterface|MockObject */ private $storeManagerMock; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder|\PHPUnit_Framework_MockObject_MockObject + * @var RuleProductsSelectBuilder|MockObject */ private $ruleProductsSelectBuilderMock; /** - * @var \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator|\PHPUnit_Framework_MockObject_MockObject + * @var ProductPriceCalculator|MockObject */ private $productPriceCalculatorMock; /** - * @var \Magento\Framework\Stdlib\DateTime\DateTime|\PHPUnit_Framework_MockObject_MockObject + * @var TimezoneInterface|MockObject */ - private $dateTimeMock; + private $localeDate; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor|\PHPUnit_Framework_MockObject_MockObject + * @var RuleProductPricesPersistor|MockObject */ private $pricesPersistorMock; protected function setUp() { - $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->ruleProductsSelectBuilderMock = - $this->getMockBuilder(\Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder::class) - ->disableOriginalConstructor() - ->getMock(); - $this->productPriceCalculatorMock = - $this->getMockBuilder(\Magento\CatalogRule\Model\Indexer\ProductPriceCalculator::class) - ->disableOriginalConstructor() - ->getMock(); - $this->dateTimeMock = $this->getMockBuilder(\Magento\Framework\Stdlib\DateTime\DateTime::class) - ->disableOriginalConstructor() - ->getMock(); - $this->pricesPersistorMock = - $this->getMockBuilder(\Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor::class) - ->disableOriginalConstructor() - ->getMock(); - $this->model = new \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice( + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); + $this->ruleProductsSelectBuilderMock = $this->createMock(RuleProductsSelectBuilder::class); + $this->productPriceCalculatorMock = $this->createMock(ProductPriceCalculator::class); + $this->localeDate = $this->createMock(TimezoneInterface::class); + $this->pricesPersistorMock = $this->createMock(RuleProductPricesPersistor::class); + + $this->model = new ReindexRuleProductPrice( $this->storeManagerMock, $this->ruleProductsSelectBuilderMock, $this->productPriceCalculatorMock, - $this->dateTimeMock, + $this->localeDate, $this->pricesPersistorMock ); } @@ -72,19 +69,32 @@ protected function setUp() public function testExecute() { $websiteId = 234; - $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) - ->disableOriginalConstructor() - ->getMock(); - - $websiteMock = $this->getMockBuilder(\Magento\Store\Api\Data\WebsiteInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $websiteMock->expects($this->once())->method('getId')->willReturn($websiteId); - $this->storeManagerMock->expects($this->once())->method('getWebsites')->willReturn([$websiteMock]); - - $statementMock = $this->getMockBuilder(\Zend_Db_Statement_Interface::class) - ->disableOriginalConstructor() - ->getMock(); + $defaultGroupId = 11; + $defaultStoreId = 22; + + $websiteMock = $this->createMock(WebsiteInterface::class); + $websiteMock->expects($this->once()) + ->method('getId') + ->willReturn($websiteId); + $websiteMock->expects($this->once()) + ->method('getDefaultGroupId') + ->willReturn($defaultGroupId); + $this->storeManagerMock->expects($this->once()) + ->method('getWebsites') + ->willReturn([$websiteMock]); + $groupMock = $this->createMock(GroupInterface::class); + $groupMock->method('getId') + ->willReturn($defaultStoreId); + $groupMock->expects($this->once()) + ->method('getDefaultStoreId') + ->willReturn($defaultStoreId); + $this->storeManagerMock->expects($this->once()) + ->method('getGroup') + ->with($defaultGroupId) + ->willReturn($groupMock); + + $productMock = $this->createMock(Product::class); + $statementMock = $this->createMock(\Zend_Db_Statement_Interface::class); $this->ruleProductsSelectBuilderMock->expects($this->once()) ->method('build') ->with($websiteId, $productMock, true) @@ -99,29 +109,22 @@ public function testExecute() 'action_stop' => true ]; - $this->dateTimeMock->expects($this->at(0)) - ->method('date') - ->with('Y-m-d 00:00:00', $ruleData['from_time']) - ->willReturn($ruleData['from_time']); - $this->dateTimeMock->expects($this->at(1)) - ->method('timestamp') - ->with($ruleData['from_time']) - ->willReturn($ruleData['from_time']); - - $this->dateTimeMock->expects($this->at(2)) - ->method('date') - ->with('Y-m-d 00:00:00', $ruleData['to_time']) - ->willReturn($ruleData['to_time']); - $this->dateTimeMock->expects($this->at(3)) - ->method('timestamp') - ->with($ruleData['to_time']) - ->willReturn($ruleData['to_time']); - - $statementMock->expects($this->at(0))->method('fetch')->willReturn($ruleData); - $statementMock->expects($this->at(1))->method('fetch')->willReturn(false); - - $this->productPriceCalculatorMock->expects($this->atLeastOnce())->method('calculate'); - $this->pricesPersistorMock->expects($this->once())->method('execute'); + $this->localeDate->expects($this->once()) + ->method('scopeDate') + ->with($defaultStoreId, null, true) + ->willReturn(new \DateTime()); + + $statementMock->expects($this->at(0)) + ->method('fetch') + ->willReturn($ruleData); + $statementMock->expects($this->at(1)) + ->method('fetch') + ->willReturn(false); + + $this->productPriceCalculatorMock->expects($this->atLeastOnce()) + ->method('calculate'); + $this->pricesPersistorMock->expects($this->once()) + ->method('execute'); $this->assertTrue($this->model->execute(1, $productMock, true)); } diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php index 0dbbaee8d2871..ff566fa3cc774 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php @@ -8,89 +8,107 @@ use Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher; use Magento\CatalogRule\Model\Indexer\IndexerTableSwapperInterface; +use Magento\CatalogRule\Model\Indexer\ReindexRuleProduct; +use Magento\CatalogRule\Model\Rule; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Model\ScopeInterface; +use PHPUnit\Framework\MockObject\MockObject; class ReindexRuleProductTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct + * @var ReindexRuleProduct */ private $model; /** - * @var \Magento\Framework\App\ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + * @var ResourceConnection|MockObject */ private $resourceMock; /** - * @var ActiveTableSwitcher|\PHPUnit_Framework_MockObject_MockObject + * @var ActiveTableSwitcher|MockObject */ private $activeTableSwitcherMock; /** - * @var IndexerTableSwapperInterface|\PHPUnit_Framework_MockObject_MockObject + * @var IndexerTableSwapperInterface|MockObject */ private $tableSwapperMock; + /** + * @var TimezoneInterface|MockObject + */ + private $localeDateMock; + protected function setUp() { - $this->resourceMock = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class) - ->disableOriginalConstructor() - ->getMock(); - $this->activeTableSwitcherMock = $this->getMockBuilder(ActiveTableSwitcher::class) - ->disableOriginalConstructor() - ->getMock(); - $this->tableSwapperMock = $this->getMockForAbstractClass( - IndexerTableSwapperInterface::class - ); - $this->model = new \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct( + $this->resourceMock = $this->createMock(ResourceConnection::class); + $this->activeTableSwitcherMock = $this->createMock(ActiveTableSwitcher::class); + $this->tableSwapperMock = $this->createMock(IndexerTableSwapperInterface::class); + $this->localeDateMock = $this->createMock(TimezoneInterface::class); + + $this->model = new ReindexRuleProduct( $this->resourceMock, $this->activeTableSwitcherMock, - $this->tableSwapperMock + $this->tableSwapperMock, + $this->localeDateMock ); } public function testExecuteIfRuleInactive() { - $ruleMock = $this->getMockBuilder(\Magento\CatalogRule\Model\Rule::class) - ->disableOriginalConstructor() - ->getMock(); - $ruleMock->expects($this->once())->method('getIsActive')->willReturn(false); + $ruleMock = $this->createMock(Rule::class); + $ruleMock->expects($this->once()) + ->method('getIsActive') + ->willReturn(false); $this->assertFalse($this->model->execute($ruleMock, 100, true)); } public function testExecuteIfRuleWithoutWebsiteIds() { - $ruleMock = $this->getMockBuilder(\Magento\CatalogRule\Model\Rule::class) - ->disableOriginalConstructor() - ->getMock(); - $ruleMock->expects($this->once())->method('getIsActive')->willReturn(true); - $ruleMock->expects($this->once())->method('getWebsiteIds')->willReturn(null); + $ruleMock = $this->createMock(Rule::class); + $ruleMock->expects($this->once()) + ->method('getIsActive') + ->willReturn(true); + $ruleMock->expects($this->once()) + ->method('getWebsiteIds') + ->willReturn(null); $this->assertFalse($this->model->execute($ruleMock, 100, true)); } public function testExecute() { + $websiteId = 3; + $websiteTz = 'America/Los_Angeles'; $productIds = [ - 4 => [1 => 1], - 5 => [1 => 1], - 6 => [1 => 1], + 4 => [$websiteId => 1], + 5 => [$websiteId => 1], + 6 => [$websiteId => 1], ]; - $ruleMock = $this->getMockBuilder(\Magento\CatalogRule\Model\Rule::class) - ->disableOriginalConstructor() - ->getMock(); - $ruleMock->expects($this->once())->method('getIsActive')->willReturn(true); - $ruleMock->expects($this->exactly(2))->method('getWebsiteIds')->willReturn(1); - $ruleMock->expects($this->once())->method('getMatchingProductIds')->willReturn($productIds); + + $ruleMock = $this->createMock(Rule::class); + $ruleMock->expects($this->once()) + ->method('getIsActive') + ->willReturn(true); + $ruleMock->expects($this->exactly(2)) + ->method('getWebsiteIds') + ->willReturn([$websiteId]); + $ruleMock->expects($this->once()) + ->method('getMatchingProductIds') + ->willReturn($productIds); $this->tableSwapperMock->expects($this->once()) ->method('getWorkingTableName') ->with('catalogrule_product') ->willReturn('catalogrule_product_replica'); - $connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->resourceMock->expects($this->at(0))->method('getConnection')->willReturn($connectionMock); + $connectionMock = $this->createMock(AdapterInterface::class); + $this->resourceMock->expects($this->at(0)) + ->method('getConnection') + ->willReturn($connectionMock); $this->resourceMock->expects($this->at(1)) ->method('getTableName') ->with('catalogrule_product') @@ -100,21 +118,42 @@ public function testExecute() ->with('catalogrule_product_replica') ->willReturn('catalogrule_product_replica'); - $ruleMock->expects($this->once())->method('getId')->willReturn(100); - $ruleMock->expects($this->once())->method('getCustomerGroupIds')->willReturn([10]); - $ruleMock->expects($this->once())->method('getFromDate')->willReturn('2017-06-21'); - $ruleMock->expects($this->once())->method('getToDate')->willReturn('2017-06-30'); - $ruleMock->expects($this->once())->method('getSortOrder')->willReturn(1); - $ruleMock->expects($this->once())->method('getSimpleAction')->willReturn('simple_action'); - $ruleMock->expects($this->once())->method('getDiscountAmount')->willReturn(43); - $ruleMock->expects($this->once())->method('getStopRulesProcessing')->willReturn(true); + $ruleMock->expects($this->once()) + ->method('getId') + ->willReturn(100); + $ruleMock->expects($this->once()) + ->method('getCustomerGroupIds') + ->willReturn([10]); + $ruleMock->expects($this->atLeastOnce()) + ->method('getFromDate') + ->willReturn('2017-06-21'); + $ruleMock->expects($this->atLeastOnce()) + ->method('getToDate') + ->willReturn('2017-06-30'); + $ruleMock->expects($this->once()) + ->method('getSortOrder') + ->willReturn(1); + $ruleMock->expects($this->once()) + ->method('getSimpleAction') + ->willReturn('simple_action'); + $ruleMock->expects($this->once()) + ->method('getDiscountAmount') + ->willReturn(43); + $ruleMock->expects($this->once()) + ->method('getStopRulesProcessing') + ->willReturn(true); + + $this->localeDateMock->expects($this->once()) + ->method('getConfigTimezone') + ->with(ScopeInterface::SCOPE_WEBSITE, $websiteId) + ->willReturn($websiteTz); $batchRows = [ [ 'rule_id' => 100, 'from_time' => 1498028400, 'to_time' => 1498892399, - 'website_id' => 1, + 'website_id' => $websiteId, 'customer_group_id' => 10, 'product_id' => 4, 'action_operator' => 'simple_action', @@ -126,7 +165,7 @@ public function testExecute() 'rule_id' => 100, 'from_time' => 1498028400, 'to_time' => 1498892399, - 'website_id' => 1, + 'website_id' => $websiteId, 'customer_group_id' => 10, 'product_id' => 5, 'action_operator' => 'simple_action', @@ -141,7 +180,7 @@ public function testExecute() 'rule_id' => 100, 'from_time' => 1498028400, 'to_time' => 1498892399, - 'website_id' => 1, + 'website_id' => $websiteId, 'customer_group_id' => 10, 'product_id' => 6, 'action_operator' => 'simple_action', diff --git a/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php b/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php index cb1a7f53f752c..7514d2bc4b5c5 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php @@ -112,6 +112,7 @@ protected function setUp() */ public function testGetValue() { + $storeId = 5; $coreWebsiteId = 2; $productId = 4; $customerGroupId = 3; @@ -120,9 +121,12 @@ public function testGetValue() $catalogRulePrice = 55.12; $convertedPrice = 45.34; + $this->coreStoreMock->expects($this->once()) + ->method('getId') + ->willReturn($storeId); $this->dataTimeMock->expects($this->once()) - ->method('date') - ->with(null, null, false) + ->method('scopeDate') + ->with($storeId) ->willReturn($date); $this->coreStoreMock->expects($this->once()) ->method('getWebsiteId') From 96f56f1354707933aa7f071d05bd6ae4e8cb2c11 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 21 Aug 2019 14:16:21 +0300 Subject: [PATCH 328/372] MC-19415: Displayed incorrect price - revert MC-18009 --- .../Catalog/Model/ProductLink/Search.php | 1 + .../Adminhtml/Product/SearchTest.php | 23 ++----------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductLink/Search.php b/app/code/Magento/Catalog/Model/ProductLink/Search.php index ad7f3370ab3fe..681c01bb1281b 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/Search.php +++ b/app/code/Magento/Catalog/Model/ProductLink/Search.php @@ -60,6 +60,7 @@ public function prepareCollection( ): \Magento\Catalog\Model\ResourceModel\Product\Collection { $productCollection = $this->productCollectionFactory->create(); $productCollection->addAttributeToSelect(ProductInterface::NAME); + $productCollection->setVisibility($this->catalogVisibility->getVisibleInCatalogIds()); $productCollection->setPage($pageNum, $limit); $this->filter->addFilter($productCollection, 'fulltext', ['fulltext' => $searchKey]); $productCollection->setPage($pageNum, $limit); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 0704d59a1431c..8a33543e93439 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -38,8 +38,7 @@ public function testExecuteNonExistingSearchKey() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody, true); - $this->assertEmpty($jsonResponse['options']); + $this->assertContains('{"options":[],"total":0}', $responseBody); } /** @@ -58,24 +57,6 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody, true); - $this->assertEquals(1, $jsonResponse['total']); - $this->assertCount(1, $jsonResponse['options']); - } - - /** - * @magentoDataFixture Magento/Catalog/_files/multiple_mixed_products.php - */ - public function testExecuteEnabledAndDisabledProducts() : void - { - $this->getRequest() - ->setPostValue('searchKey', 'simple') - ->setPostValue('page', 1) - ->setPostValue('limit', 50); - $this->dispatch('backend/catalog/product/search'); - $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody, true); - $this->assertEquals(7, $jsonResponse['total']); - $this->assertCount(7, $jsonResponse['options']); + $this->assertContains('{"options":[],"total":0}', $responseBody); } } From 1e67a692ec0cb57b5fbed607cfb468eb1d987b7a Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Wed, 21 Aug 2019 18:34:13 +0300 Subject: [PATCH 329/372] MC-19334: Reindex error when website have store without store view --- app/code/Magento/Store/Model/ScopeTreeProvider.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Store/Model/ScopeTreeProvider.php b/app/code/Magento/Store/Model/ScopeTreeProvider.php index a22d5abb8c486..d15030fe88ac6 100644 --- a/app/code/Magento/Store/Model/ScopeTreeProvider.php +++ b/app/code/Magento/Store/Model/ScopeTreeProvider.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Store\Model; use Magento\Framework\App\Config\ScopeConfigInterface; From e81a669dd943159d11b16f239349c2e0ddcac80a Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Thu, 22 Aug 2019 04:53:16 +0000 Subject: [PATCH 330/372] MC-19051: [backport for 2.3.3] Nightly build jobs were failing lately after un-skipping tests in MC-5777 --- .../Model/Indexer/ReindexRuleProductTest.php | 47 +++++-------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php index ff566fa3cc774..a86ab736fb289 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php @@ -89,17 +89,6 @@ public function testExecute() 6 => [$websiteId => 1], ]; - $ruleMock = $this->createMock(Rule::class); - $ruleMock->expects($this->once()) - ->method('getIsActive') - ->willReturn(true); - $ruleMock->expects($this->exactly(2)) - ->method('getWebsiteIds') - ->willReturn([$websiteId]); - $ruleMock->expects($this->once()) - ->method('getMatchingProductIds') - ->willReturn($productIds); - $this->tableSwapperMock->expects($this->once()) ->method('getWorkingTableName') ->with('catalogrule_product') @@ -118,30 +107,18 @@ public function testExecute() ->with('catalogrule_product_replica') ->willReturn('catalogrule_product_replica'); - $ruleMock->expects($this->once()) - ->method('getId') - ->willReturn(100); - $ruleMock->expects($this->once()) - ->method('getCustomerGroupIds') - ->willReturn([10]); - $ruleMock->expects($this->atLeastOnce()) - ->method('getFromDate') - ->willReturn('2017-06-21'); - $ruleMock->expects($this->atLeastOnce()) - ->method('getToDate') - ->willReturn('2017-06-30'); - $ruleMock->expects($this->once()) - ->method('getSortOrder') - ->willReturn(1); - $ruleMock->expects($this->once()) - ->method('getSimpleAction') - ->willReturn('simple_action'); - $ruleMock->expects($this->once()) - ->method('getDiscountAmount') - ->willReturn(43); - $ruleMock->expects($this->once()) - ->method('getStopRulesProcessing') - ->willReturn(true); + $ruleMock = $this->createMock(Rule::class); + $ruleMock->expects($this->once())->method('getIsActive')->willReturn(true); + $ruleMock->expects($this->exactly(2))->method('getWebsiteIds')->willReturn([$websiteId]); + $ruleMock->expects($this->once())->method('getMatchingProductIds')->willReturn($productIds); + $ruleMock->expects($this->once())->method('getId')->willReturn(100); + $ruleMock->expects($this->once())->method('getCustomerGroupIds')->willReturn([10]); + $ruleMock->expects($this->atLeastOnce())->method('getFromDate')->willReturn('2017-06-21'); + $ruleMock->expects($this->atLeastOnce())->method('getToDate')->willReturn('2017-06-30'); + $ruleMock->expects($this->once())->method('getSortOrder')->willReturn(1); + $ruleMock->expects($this->once())->method('getSimpleAction')->willReturn('simple_action'); + $ruleMock->expects($this->once())->method('getDiscountAmount')->willReturn(43); + $ruleMock->expects($this->once())->method('getStopRulesProcessing')->willReturn(true); $this->localeDateMock->expects($this->once()) ->method('getConfigTimezone') From 3910cacc104294b5fb92d562034620300461cfc6 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Thu, 22 Aug 2019 13:48:36 +0300 Subject: [PATCH 331/372] MC-19566: Failing Integration Magento.Catalog.Model.Indexer.Product.Flat.Action.RelationTest.testExecute --- .../Catalog/Model/Indexer/Product/Flat/AbstractAction.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/AbstractAction.php index ebad10e197622..a0acacd4dfd2f 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/AbstractAction.php @@ -254,10 +254,12 @@ protected function _updateRelationProducts($storeId, $productIds = null) * * @param int $storeId * @return \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function _cleanRelationProducts($storeId) { - if (!$this->_productIndexerHelper->isAddChildData()) { + if (!$this->_productIndexerHelper->isAddChildData() || !$this->_isFlatTableExists($storeId)) { return $this; } From 4d338c7df9e23c178e7f09bd9a201942113e1152 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 22 Aug 2019 10:57:21 -0500 Subject: [PATCH 332/372] MC-19145: [CLOUD] Internal error after DHL was configured --- app/code/Magento/Dhl/Model/Carrier.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php index 0a1632a45cb0c..0890466e8a40f 100644 --- a/app/code/Magento/Dhl/Model/Carrier.php +++ b/app/code/Magento/Dhl/Model/Carrier.php @@ -825,8 +825,10 @@ protected function _getAllItems() $fullItems[] = array_fill(0, $qty, $this->_getWeight($itemWeight)); } } - $fullItems = array_merge(...$fullItems); - sort($fullItems); + if ($fullItems) { + $fullItems = array_merge(...$fullItems); + sort($fullItems); + } return $fullItems; } From 7035daca3f6b47038d120813ec7164b76ac4bc94 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 22 Aug 2019 13:42:48 -0500 Subject: [PATCH 333/372] MC-19184: Quick Search is broken --- .../CatalogSearch/view/frontend/templates/result.phtml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml b/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml index c63e6ff4abe0f..921e1a81d8719 100644 --- a/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml +++ b/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml @@ -3,6 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +/** This changes need to valid applying filters and configuration before search process is started. */ +$productList = $block->getProductListHtml(); ?> <?php if ($block->getResultCount()) : ?> <?= /* @noEscape */ $block->getChildHtml('tagged_product_list_rss_link') ?> @@ -16,7 +19,7 @@ </div> </div> <?php endif; ?> - <?= $block->getProductListHtml() ?> + <?= $productList ?> </div> <?php else : ?> From 302070f611e884abbda6460cb6231101a2eefcb4 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Fri, 23 Aug 2019 07:56:11 -0500 Subject: [PATCH 334/372] MC-19184: Quick Search is broken - fixed static tests --- .../Magento/CatalogSearch/view/frontend/templates/result.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml b/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml index 921e1a81d8719..32b26eec9dbe6 100644 --- a/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml +++ b/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml @@ -19,7 +19,7 @@ $productList = $block->getProductListHtml(); </div> </div> <?php endif; ?> - <?= $productList ?> + <?= /* @noEscape */ $productList ?> </div> <?php else : ?> From 35b8a04d5a0f7c919e02c2727bd0a5778fe39e90 Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov <vzabaznov@magento.com> Date: Fri, 23 Aug 2019 09:50:54 -0500 Subject: [PATCH 335/372] MC-19612: Revert MC-15378 --- app/code/Magento/Customer/Model/Visitor.php | 5 +++++ .../Magento/Customer/Controller/AccountTest.php | 15 --------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Customer/Model/Visitor.php b/app/code/Magento/Customer/Model/Visitor.php index 4f129f05aa82c..17394c4d94129 100644 --- a/app/code/Magento/Customer/Model/Visitor.php +++ b/app/code/Magento/Customer/Model/Visitor.php @@ -169,6 +169,11 @@ public function initByRequest($observer) $this->setLastVisitAt((new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT)); + // prevent saving Visitor for safe methods, e.g. GET request + if ($this->requestSafety->isSafeMethod()) { + return $this; + } + if (!$this->getId()) { $this->setSessionId($this->session->getSessionId()); $this->save(); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index 566dfbadedd29..32f12dada57a6 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -798,21 +798,6 @@ public function loginPostRedirectDataProvider() ]; } - /** - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoDataFixture Magento/Customer/_files/customer_address.php - * @magentoAppArea frontend - */ - public function testCheckVisitorModel() - { - /** @var \Magento\Customer\Model\Visitor $visitor */ - $visitor = $this->_objectManager->get(\Magento\Customer\Model\Visitor::class); - $this->login(1); - $this->assertNull($visitor->getId()); - $this->dispatch('customer/account/index'); - $this->assertNotNull($visitor->getId()); - } - /** * @param string $email * @return void From 0023dcec912a1a442d67ab0c8d9cab36490c8be2 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Fri, 23 Aug 2019 16:31:54 -0500 Subject: [PATCH 336/372] MC-19184: Quick Search is broken - fixed performance tests --- .../ResourceModel/Fulltext/Collection/SearchResultApplier.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php index 3ae2d384782c3..b15d99dcc2df3 100644 --- a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php +++ b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php @@ -50,7 +50,6 @@ public function apply() foreach ($this->searchResult->getItems() as $item) { $ids[] = (int)$item->getId(); } - $this->collection->setPageSize(null); $this->collection->getSelect()->where('e.entity_id IN (?)', $ids); $orderList = join(',', $ids); $this->collection->getSelect()->reset(\Magento\Framework\DB\Select::ORDER); From 78fd8117df9a6fc72e51a14786d58eb5504417fb Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 26 Aug 2019 10:01:00 -0500 Subject: [PATCH 337/372] MC-19072: Braintree: Unable to fill "Credit Card Number" and "Expiration Date" fields on Checkout page if "CVV Verification" = No --- .../Braintree/view/frontend/web/template/payment/form.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html b/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html index 9bcb5dad8b636..8da8927a3b247 100644 --- a/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html +++ b/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html @@ -23,7 +23,7 @@ <!-- ko template: getTemplate() --><!-- /ko --> <!--/ko--> </div> - <form id="co-transparent-form-braintree" class="form" data-bind="" method="post" action="#" novalidate="novalidate"> + <form id="co-transparent-form-braintree" class="form" data-bind="afterRender: initHostedFields" method="post" action="#" novalidate="novalidate"> <fieldset data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + getCode()}"> <legend class="legend"> <span><!-- ko i18n: 'Credit Card Information'--><!-- /ko --></span> @@ -87,7 +87,7 @@ <span><!-- ko i18n: 'Card Verification Number'--><!-- /ko --></span> </label> <div class="control _with-tooltip"> - <div data-bind="afterRender: initHostedFields, attr: {id: getCode() + '_cc_cid'}" class="hosted-control hosted-cid"></div> + <div data-bind="attr: {id: getCode() + '_cc_cid'}" class="hosted-control hosted-cid"></div> <div class="hosted-error"><!-- ko i18n: 'Please, enter valid Card Verification Number'--><!-- /ko --></div> <div class="field-tooltip toggle"> From d110db27a979202df882c88c42fc2d0833683659 Mon Sep 17 00:00:00 2001 From: Kieu Phan <kphan@adobe.com> Date: Mon, 26 Aug 2019 16:05:24 -0500 Subject: [PATCH 338/372] MC-18532: Update Changelog based on delivered scope Update Changelog for 2.3.3-develop --- CHANGELOG.md | 417 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04fb46a825f62..4f760535cb91b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,420 @@ +2.3.3 +============= +* GitHub issues: + * [#533](https://github.com/magento/magento2/issues/533) -- By default Allow all access in .htaccess (fixed in [magento/graphql-ce#578](https://github.com/magento/graphql-ce/pull/578)) + * [#601](https://github.com/magento/magento2/issues/601) -- Admin tabs js error. (fixed in [magento/graphql-ce#632](https://github.com/magento/graphql-ce/pull/632)) + * [#631](https://github.com/magento/magento2/issues/631) -- Image Management / Editing (fixed in [magento/graphql-ce#634](https://github.com/magento/graphql-ce/pull/634)) + * [#20124](https://github.com/magento/magento2/issues/20124) -- Sort By label is hidden by Shop By Menu on listing page in iphone5 device (fixed in [magento/magento2#20135](https://github.com/magento/magento2/pull/20135)) + * [#21978](https://github.com/magento/magento2/issues/21978) -- Adding product image: File doesn't exist (fixed in [magento/magento2#22020](https://github.com/magento/magento2/pull/22020)) + * [#22045](https://github.com/magento/magento2/issues/22045) -- Instant Purchase on product page not working properly. (fixed in [magento/magento2#22260](https://github.com/magento/magento2/pull/22260)) + * [#22134](https://github.com/magento/magento2/issues/22134) -- Paypal buttons disable issue - Magento 2.3.1 (fixed in [magento/magento2#22260](https://github.com/magento/magento2/pull/22260)) + * [#22249](https://github.com/magento/magento2/issues/22249) -- Configurable Product Gallery Images Out of Order when More than 10 images (fixed in [magento/magento2#22287](https://github.com/magento/magento2/pull/22287)) + * [#22527](https://github.com/magento/magento2/issues/22527) -- Wishlist and compare icon align issue in product listing page (fixed in [magento/magento2#22532](https://github.com/magento/magento2/pull/22532)) + * [#628](https://github.com/magento/magento2/issues/628) -- Feature Request: Parent entities links in child entities grid. (fixed in [magento/graphql-ce#636](https://github.com/magento/graphql-ce/pull/636)) + * [#640](https://github.com/magento/magento2/issues/640) -- [Insight] Files should not be executable (fixed in [magento/graphql-ce#648](https://github.com/magento/graphql-ce/pull/648)) + * [#603](https://github.com/magento/magento2/issues/603) -- 'Continue' button is disabled even though 'I've read OSL licence' is checked (fixed in [magento/graphql-ce#653](https://github.com/magento/graphql-ce/pull/653)) + * [#22406](https://github.com/magento/magento2/issues/22406) -- Store view specific labels cut in left navigation menu (fixed in [magento/magento2#22423](https://github.com/magento/magento2/pull/22423)) + * [#19515](https://github.com/magento/magento2/issues/19515) -- Create new order from backend saves the credit card when it is told not to (fixed in [magento/magento2#19767](https://github.com/magento/magento2/pull/19767)) + * [#21473](https://github.com/magento/magento2/issues/21473) -- Form element validation is not triggered when validation rules change (fixed in [magento/magento2#21992](https://github.com/magento/magento2/pull/21992)) + * [#22641](https://github.com/magento/magento2/issues/22641) -- Typo Issue and Missing header title at Customer Sales order grid (fixed in [magento/magento2#22643](https://github.com/magento/magento2/pull/22643)) + * [#22647](https://github.com/magento/magento2/issues/22647) -- In customer account create page word not readable, should use '-' after break to new line In mobile view (fixed in [magento/magento2#22656](https://github.com/magento/magento2/pull/22656)) + * [#22395](https://github.com/magento/magento2/issues/22395) -- config:set -le and -lc short form options don't work (fixed in [magento/magento2#22720](https://github.com/magento/magento2/pull/22720)) + * [#198](https://github.com/magento/magento2/issues/198) -- Better Search Please!! NOW (fixed in [magento/graphql-ce#371](https://github.com/magento/graphql-ce/pull/371)) + * [#436](https://github.com/magento/magento2/issues/436) -- [Feature request]custom option attach an image (fixed in [magento/graphql-ce#445](https://github.com/magento/graphql-ce/pull/445)) + * [#309](https://github.com/magento/magento2/issues/309) -- Terrible UI in Backend (fixed in [magento/graphql-ce#504](https://github.com/magento/graphql-ce/pull/504)) + * [#535](https://github.com/magento/magento2/issues/535) -- A few bugs (fixed in [magento/graphql-ce#650](https://github.com/magento/graphql-ce/pull/650)) + * [#658](https://github.com/magento/magento2/issues/658) -- Inline translate malfunctioning (fixed in [magento/graphql-ce#665](https://github.com/magento/graphql-ce/pull/665) and [magento/graphql-ce#744](https://github.com/magento/graphql-ce/pull/744)) + * [#657](https://github.com/magento/magento2/issues/657) -- Feature Request: Grid paging options at the top and the bottom of the grid. (fixed in [magento/graphql-ce#666](https://github.com/magento/graphql-ce/pull/666)) + * [#12612](https://github.com/magento/magento2/issues/12612) -- Array to String conversion error on checkout page when changin country - how to debug (fixed in [magento/magento2#22558](https://github.com/magento/magento2/pull/22558)) + * [#22556](https://github.com/magento/magento2/issues/22556) -- VatValidator::validate returns error if region in quoteAddress is not set (fixed in [magento/magento2#22558](https://github.com/magento/magento2/pull/22558)) + * [#20843](https://github.com/magento/magento2/issues/20843) -- Uncaught TypeError: panel.addClass is not a function when Swatches are disabled (fixed in [magento/magento2#22560](https://github.com/magento/magento2/pull/22560)) + * [#22636](https://github.com/magento/magento2/issues/22636) -- arrow toggle not changing only showing to down It should be toggle as every where is working (fixed in [magento/magento2#22644](https://github.com/magento/magento2/pull/22644)) + * [#22640](https://github.com/magento/magento2/issues/22640) -- Add tax rule form checkbox design is not as per the magento admin panel checkbox design, It is showing default design (fixed in [magento/magento2#22655](https://github.com/magento/magento2/pull/22655)) + * [#20906](https://github.com/magento/magento2/issues/20906) -- Magento backend catalog "Cost" without currency symbol (fixed in [magento/magento2#22739](https://github.com/magento/magento2/pull/22739)) + * [#22771](https://github.com/magento/magento2/issues/22771) -- Magento 2.3.0 can't change text area field height admin form using Ui component (fixed in [magento/magento2#22779](https://github.com/magento/magento2/pull/22779)) + * [#22788](https://github.com/magento/magento2/issues/22788) -- New Shipment emails do not generate (fixed in [magento/magento2#22791](https://github.com/magento/magento2/pull/22791)) + * [#18651](https://github.com/magento/magento2/issues/18651) -- Tierprice can't save float percentage value (fixed in [magento/magento2#19584](https://github.com/magento/magento2/pull/19584)) + * [#21672](https://github.com/magento/magento2/issues/21672) -- Database Media Storage - Design Config fails to save transactional email logo correctly (fixed in [magento/magento2#21675](https://github.com/magento/magento2/pull/21675) and [magento/magento2#21674](https://github.com/magento/magento2/pull/21674)) + * [#22028](https://github.com/magento/magento2/issues/22028) -- Unable to update products via csv file, when products ids from file are from wide id range (fixed in [magento/magento2#22575](https://github.com/magento/magento2/pull/22575)) + * [#21558](https://github.com/magento/magento2/issues/21558) -- Navigation issue of review from product listing when click on review count (fixed in [magento/magento2#22794](https://github.com/magento/magento2/pull/22794)) + * [#22127](https://github.com/magento/magento2/issues/22127) -- Magento 2.3.0: getSize call on configurable collection leads to exception, if no product filters are applied (fixed in [magento/magento2#22186](https://github.com/magento/magento2/pull/22186)) + * [#22639](https://github.com/magento/magento2/issues/22639) -- Without select attribute click on add attribute it display all selected when add attribute again. (fixed in [magento/magento2#22724](https://github.com/magento/magento2/pull/22724)) + * [#22676](https://github.com/magento/magento2/issues/22676) -- Compare Products counter, and My Wish List counter vertical not aligned (fixed in [magento/magento2#22742](https://github.com/magento/magento2/pull/22742)) + * [#6659](https://github.com/magento/magento2/issues/6659) -- Disabled payment methods show in Customer Dashboard (fixed in [magento/magento2#22850](https://github.com/magento/magento2/pull/22850)) + * [#4628](https://github.com/magento/magento2/issues/4628) -- .lib-font-face mixin - Fixed font formats (fixed in [magento/magento2#22854](https://github.com/magento/magento2/pull/22854)) + * [#3795](https://github.com/magento/magento2/issues/3795) -- Validation messages missing from datepicker form elements (fixed in [magento/magento2#21397](https://github.com/magento/magento2/pull/21397)) + * [#22786](https://github.com/magento/magento2/issues/22786) -- The validation for UPS configurations triggers even if UPS is disabled for checkout (fixed in [magento/magento2#22787](https://github.com/magento/magento2/pull/22787)) + * [#22822](https://github.com/magento/magento2/issues/22822) -- [Shipping] The contact us link isn't showing on order tracking page (fixed in [magento/magento2#22823](https://github.com/magento/magento2/pull/22823)) + * [#21852](https://github.com/magento/magento2/issues/21852) -- Random Error while waiting for package deployed (fixed in [magento/magento2#22607](https://github.com/magento/magento2/pull/22607)) + * [#22563](https://github.com/magento/magento2/issues/22563) -- Parallelised execution of static content deploy is broken on 2.3-develop (fixed in [magento/magento2#22607](https://github.com/magento/magento2/pull/22607)) + * [#22736](https://github.com/magento/magento2/issues/22736) -- Cursor position not in right side of search keyword in search box when click on search again (Mobile issue) (fixed in [magento/magento2#22795](https://github.com/magento/magento2/pull/22795)) + * [#22875](https://github.com/magento/magento2/issues/22875) -- Billing Agreements page title need to be improved (fixed in [magento/magento2#22876](https://github.com/magento/magento2/pull/22876)) + * [#21214](https://github.com/magento/magento2/issues/21214) -- Luma theme Apply Discount Code section design improvement (fixed in [magento/magento2#21215](https://github.com/magento/magento2/pull/21215)) + * [#22143](https://github.com/magento/magento2/issues/22143) -- Varnish health check failing due to presence of id_prefix in env.php (fixed in [magento/magento2#22307](https://github.com/magento/magento2/pull/22307)) + * [#22317](https://github.com/magento/magento2/issues/22317) -- CodeSniffer should not mark correctly aligned DocBlock elements as code style violation. (fixed in [magento/magento2#22444](https://github.com/magento/magento2/pull/22444)) + * [#22396](https://github.com/magento/magento2/issues/22396) -- config:set fails with JSON values (fixed in [magento/magento2#22513](https://github.com/magento/magento2/pull/22513)) + * [#22506](https://github.com/magento/magento2/issues/22506) -- Search suggestion panel overlapping on advance reporting button (fixed in [magento/magento2#22520](https://github.com/magento/magento2/pull/22520)) + * [#22869](https://github.com/magento/magento2/issues/22869) -- REST: Updating a customer without store_id sets the store_id to default (fixed in [magento/magento2#22893](https://github.com/magento/magento2/pull/22893)) + * [#22924](https://github.com/magento/magento2/issues/22924) -- Store view label not in the middle of panel (fixed in [magento/magento2#22926](https://github.com/magento/magento2/pull/22926)) + * [#20186](https://github.com/magento/magento2/issues/20186) -- phpcs error on rule classes - must be of the type integer (fixed in [magento/magento2#22947](https://github.com/magento/magento2/pull/22947)) + * [#574](https://github.com/magento/magento2/issues/574) -- Maximum function nesting level of '100' reached (fixed in [magento/graphql-ce#694](https://github.com/magento/graphql-ce/pull/694)) + * [#686](https://github.com/magento/magento2/issues/686) -- Product save validation errors in the admin don't hide the overlay (fixed in [magento/graphql-ce#695](https://github.com/magento/graphql-ce/pull/695)) + * [#22380](https://github.com/magento/magento2/issues/22380) -- Checkout totals order in specific store (fixed in [magento/magento2#22387](https://github.com/magento/magento2/pull/22387)) + * [#18183](https://github.com/magento/magento2/issues/18183) -- Magento 2.2.6 coupon codes don't work anymore (fixed in [magento/magento2#22718](https://github.com/magento/magento2/pull/22718)) + * [#22899](https://github.com/magento/magento2/issues/22899) -- Incorrect return type at getListByCustomerId in PaymentTokenManagementInterface (fixed in [magento/magento2#22914](https://github.com/magento/magento2/pull/22914)) + * [#22686](https://github.com/magento/magento2/issues/22686) -- Shipment Create via API salesShipmentRepositoryV1 throw Fatal error in Admin Order -> Shipment -> View (fixed in [magento/magento2#22687](https://github.com/magento/magento2/pull/22687)) + * [#22767](https://github.com/magento/magento2/issues/22767) -- Not clear logic for loading CMS Pages with setStoreId function (fixed in [magento/magento2#22772](https://github.com/magento/magento2/pull/22772)) + * [#20788](https://github.com/magento/magento2/issues/20788) -- Listing page no equal spacing in product in list view (fixed in [magento/magento2#22931](https://github.com/magento/magento2/pull/22931)) + * [#23030](https://github.com/magento/magento2/issues/23030) -- Magento2 Swatch change Image does not slide to first Image (fixed in [magento/magento2#23033](https://github.com/magento/magento2/pull/23033)) + * [#23034](https://github.com/magento/magento2/issues/23034) -- Wrong behaviour of validation scroll (fixed in [magento/magento2#23035](https://github.com/magento/magento2/pull/23035)) + * [#12696](https://github.com/magento/magento2/issues/12696) -- Integration tests create stub modules in app/code (fixed in [magento/magento2#18459](https://github.com/magento/magento2/pull/18459)) + * [#13266](https://github.com/magento/magento2/issues/13266) -- Topmenu 'last' class not being set if the a parent is inactive (fixed in [magento/magento2#22071](https://github.com/magento/magento2/pull/22071)) + * [#22882](https://github.com/magento/magento2/issues/22882) -- Static content deploy - Don't shows error message, just stack trace (fixed in [magento/magento2#22884](https://github.com/magento/magento2/pull/22884)) + * [#23045](https://github.com/magento/magento2/issues/23045) -- Exceptions from data patches do not show root cause (fixed in [magento/magento2#23046](https://github.com/magento/magento2/pull/23046)) + * [#16446](https://github.com/magento/magento2/issues/16446) -- magento 2.2.2 text swatch switches product image even if attribute feature is disabled (fixed in [magento/magento2#19184](https://github.com/magento/magento2/pull/19184)) + * [#14492](https://github.com/magento/magento2/issues/14492) -- Creating Customer without password is directly confirmed (fixed in [magento/magento2#21394](https://github.com/magento/magento2/pull/21394)) + * [#21671](https://github.com/magento/magento2/issues/21671) -- Database Media Storage - Transaction emails logo not used when pub/media cleared (fixed in [magento/magento2#21674](https://github.com/magento/magento2/pull/21674)) + * [#22425](https://github.com/magento/magento2/issues/22425) -- wrong url redirect when edit product review from Customer view page (fixed in [magento/magento2#22426](https://github.com/magento/magento2/pull/22426)) + * [#22511](https://github.com/magento/magento2/issues/22511) -- Special From Date set to today's date when Use Default Date checked in Store scope (fixed in [magento/magento2#22521](https://github.com/magento/magento2/pull/22521)) + * [#23080](https://github.com/magento/magento2/issues/23080) -- Missing whitespace in mobile navigation for non-English websites (fixed in [magento/magento2#23081](https://github.com/magento/magento2/pull/23081)) + * [#19872](https://github.com/magento/magento2/issues/19872) -- Magento 2.3 category edit page "Select from gallery" button not working. (fixed in [magento/magento2#21131](https://github.com/magento/magento2/pull/21131)) + * [#22092](https://github.com/magento/magento2/issues/22092) -- Assigning Catalog Image from Gallery, then Saving Twice, Clears Image (fixed in [magento/magento2#21131](https://github.com/magento/magento2/pull/21131)) + * [#22087](https://github.com/magento/magento2/issues/22087) -- Products Ordered Report - Not grouped by product (fixed in [magento/magento2#22646](https://github.com/magento/magento2/pull/22646)) + * [#21546](https://github.com/magento/magento2/issues/21546) -- [2.3] Database Media Storage - New Product Images fail to be processed correctly (fixed in [magento/magento2#21605](https://github.com/magento/magento2/pull/21605)) + * [#21604](https://github.com/magento/magento2/issues/21604) -- Database Media Storage - Admin Product Edit page does not handle product images correctly in database storage mode (fixed in [magento/magento2#21605](https://github.com/magento/magento2/pull/21605)) + * [#4247](https://github.com/magento/magento2/issues/4247) -- getProductUrl does not allow to override the scope in backend context (fixed in [magento/magento2#21876](https://github.com/magento/magento2/pull/21876)) + * [#22940](https://github.com/magento/magento2/issues/22940) -- Reset feature does not clear the date (fixed in [magento/magento2#23007](https://github.com/magento/magento2/pull/23007)) + * [#23053](https://github.com/magento/magento2/issues/23053) -- Sendfriend works for products with visibility not visible individually (fixed in [magento/magento2#23118](https://github.com/magento/magento2/pull/23118)) + * [#675](https://github.com/magento/magento2/issues/675) -- Textarea element cols and rows (fixed in [magento/graphql-ce#677](https://github.com/magento/graphql-ce/pull/677)) + * [#682](https://github.com/magento/magento2/issues/682) -- \Magento\Framework\Pricing\PriceCurrencyInterface depends on Magento application code (fixed in [magento/graphql-ce#700](https://github.com/magento/graphql-ce/pull/700)) + * [#681](https://github.com/magento/magento2/issues/681) -- Magento\Framework\Xml\Parser class issues (fixed in [magento/graphql-ce#711](https://github.com/magento/graphql-ce/pull/711)) + * [#22484](https://github.com/magento/magento2/issues/22484) -- Customer address States are duplicated in backend (fixed in [magento/magento2#22637](https://github.com/magento/magento2/pull/22637)) + * [#23138](https://github.com/magento/magento2/issues/23138) -- Magento_Theme. Incorrect configuration file location (fixed in [magento/magento2#23140](https://github.com/magento/magento2/pull/23140)) + * [#22004](https://github.com/magento/magento2/issues/22004) -- ce231 - can't update attribute for all product (fixed in [magento/magento2#22704](https://github.com/magento/magento2/pull/22704)) + * [#22870](https://github.com/magento/magento2/issues/22870) -- ProductRepository fails to update an existing product with a changed SKU (fixed in [magento/magento2#22933](https://github.com/magento/magento2/pull/22933)) + * [#22808](https://github.com/magento/magento2/issues/22808) -- php bin/magento catalog:image:resize error if image is missing (fixed in [magento/magento2#23005](https://github.com/magento/magento2/pull/23005)) + * [#674](https://github.com/magento/magento2/issues/674) -- Widgets in content pages. (fixed in [magento/graphql-ce#709](https://github.com/magento/graphql-ce/pull/709)) + * [#683](https://github.com/magento/magento2/issues/683) -- CMS Router not routing correctly (fixed in [magento/graphql-ce#717](https://github.com/magento/graphql-ce/pull/717)) + * [#9113](https://github.com/magento/magento2/issues/9113) -- [Bug or Feature?] url_path attribute value is not populated for any product (fixed in [magento/graphql-ce#721](https://github.com/magento/graphql-ce/pull/721)) + * [#18337](https://github.com/magento/magento2/issues/18337) -- #search input is missing required attribute aria-expanded. (fixed in [magento/magento2#22942](https://github.com/magento/magento2/pull/22942)) + * [#23213](https://github.com/magento/magento2/issues/23213) -- Static content deploy showing percentage(%) two times in progress bar (fixed in [magento/magento2#23216](https://github.com/magento/magento2/pull/23216)) + * [#23238](https://github.com/magento/magento2/issues/23238) -- Apply coupon button act like remove coupon while create new order from admin (fixed in [magento/magento2#23250](https://github.com/magento/magento2/pull/23250)) + * [#4788](https://github.com/magento/magento2/issues/4788) -- Wrong sitemap product url (fixed in [magento/magento2#23129](https://github.com/magento/magento2/pull/23129)) + * [#22934](https://github.com/magento/magento2/issues/22934) -- Incorrect work of "Use Categories Path for Product URLs" in sitemap generation. (fixed in [magento/magento2#23129](https://github.com/magento/magento2/pull/23129)) + * [#23266](https://github.com/magento/magento2/issues/23266) -- Cannot filter admin user by ID (fixed in [magento/magento2#23267](https://github.com/magento/magento2/pull/23267)) + * [#23285](https://github.com/magento/magento2/issues/23285) -- Credit memo submit button(refund) stays disable after validation fails & unable to enable button (fixed in [magento/magento2#23286](https://github.com/magento/magento2/pull/23286)) + * [#486](https://github.com/magento/magento2/issues/486) -- Take inspiration from other frameworks (fixed in [magento/graphql-ce#714](https://github.com/magento/graphql-ce/pull/714)) + * [#716](https://github.com/magento/magento2/issues/716) -- Wrong mimetype returned by getMimeType from Magento library (fixed in [magento/graphql-ce#723](https://github.com/magento/graphql-ce/pull/723)) + * [#687](https://github.com/magento/magento2/issues/687) -- Improvement Idea: /var/cache/mage--X (fixed in [magento/graphql-ce#749](https://github.com/magento/graphql-ce/pull/749)) + * [#20038](https://github.com/magento/magento2/issues/20038) -- loading icon disappearing before background process completes for braintree payment (Admin order) (fixed in [magento/magento2#22675](https://github.com/magento/magento2/pull/22675)) + * [#23074](https://github.com/magento/magento2/issues/23074) -- Magento 2.3.1 - URL rewrite rules are not creating for product after update url key (fixed in [magento/magento2#23309](https://github.com/magento/magento2/pull/23309)) + * [#622](https://github.com/magento/magento2/issues/622) -- FIX Magento Search Please! (fixed in [magento/graphql-ce#626](https://github.com/magento/graphql-ce/pull/626)) + * [#732](https://github.com/magento/magento2/issues/732) -- Inconsistency between Select and Multiselect form elements. (fixed in [magento/graphql-ce#734](https://github.com/magento/graphql-ce/pull/734)) + * [#13227](https://github.com/magento/magento2/issues/13227) -- Knockout Recently Viewed contains wrong product url (with category path), also not correct url <meta property="og:url"> on product view page (fixed in [magento/magento2#22650](https://github.com/magento/magento2/pull/22650)) + * [#22638](https://github.com/magento/magento2/issues/22638) -- Asterisk(*) sign position does not consistent in admin (fixed in [magento/magento2#22800](https://github.com/magento/magento2/pull/22800)) + * [#22266](https://github.com/magento/magento2/issues/22266) -- Product Alert after login shows 404 page (fixed in [magento/magento2#23218](https://github.com/magento/magento2/pull/23218)) + * [#23230](https://github.com/magento/magento2/issues/23230) -- Sticky header floating under top when there is no buttons in the toolbar (fixed in [magento/magento2#23247](https://github.com/magento/magento2/pull/23247)) + * [#23333](https://github.com/magento/magento2/issues/23333) -- Incorrect payment method translation in order emails (fixed in [magento/magento2#23338](https://github.com/magento/magento2/pull/23338)) + * [#23346](https://github.com/magento/magento2/issues/23346) -- 'Test Connection' button is over-spanned (fixed in [magento/magento2#23367](https://github.com/magento/magento2/pull/23367)) + * [#21380](https://github.com/magento/magento2/issues/21380) -- Cron schedule is being duplicated (fixed in [magento/magento2#23312](https://github.com/magento/magento2/pull/23312)) + * [#21136](https://github.com/magento/magento2/issues/21136) -- Magento installation via metapackage: checkExtensions fails (fixed in [magento/magento2#22116](https://github.com/magento/magento2/pull/22116)) + * [#23233](https://github.com/magento/magento2/issues/23233) -- Alert widget doesn't trigger always method on showing the message (fixed in [magento/magento2#23234](https://github.com/magento/magento2/pull/23234)) + * [#21974](https://github.com/magento/magento2/issues/21974) -- Changes for PayPal affect core config fields with tooltip (fixed in [magento/magento2#23393](https://github.com/magento/magento2/pull/23393)) + * [#23377](https://github.com/magento/magento2/issues/23377) -- Mini cart loader not working first time magento2 (fixed in [magento/magento2#23394](https://github.com/magento/magento2/pull/23394)) + * [#22998](https://github.com/magento/magento2/issues/22998) -- POST on /orders fails when properties in the body are out of sequence (fixed in [magento/magento2#23048](https://github.com/magento/magento2/pull/23048)) + * [#23522](https://github.com/magento/magento2/issues/23522) -- UPS shipping booking and label generation gives error when shipper's street given more than 35 chars (fixed in [magento/magento2#23523](https://github.com/magento/magento2/pull/23523)) + * [#8298](https://github.com/magento/magento2/issues/8298) -- Mobile Menu Behavior at Incorrect Breakpoint (fixed in [magento/magento2#23528](https://github.com/magento/magento2/pull/23528)) + * [#22103](https://github.com/magento/magento2/issues/22103) -- Character Encoding in Plain Text Emails Fails since 2.2.8/2.3.0 due to emails no longer being sent as MIME (fixed in [magento/magento2#23535](https://github.com/magento/magento2/pull/23535)) + * [#23199](https://github.com/magento/magento2/issues/23199) -- NO sender in email header for magento 2 sales order and password change emails to customer (fixed in [magento/magento2#23535](https://github.com/magento/magento2/pull/23535)) + * [#23538](https://github.com/magento/magento2/issues/23538) -- wrong validation happen for max-words validation class (fixed in [magento/magento2#23541](https://github.com/magento/magento2/pull/23541)) + * [#21126](https://github.com/magento/magento2/issues/21126) -- Backend Import behavior design break (fixed in [magento/magento2#21128](https://github.com/magento/magento2/pull/21128)) + * [#23471](https://github.com/magento/magento2/issues/23471) -- Tooltip missing at store view lable in Cms page and Cms block (fixed in [magento/magento2#23474](https://github.com/magento/magento2/pull/23474)) + * [#23466](https://github.com/magento/magento2/issues/23466) -- Cart empty after update qty with -1 and change address. (fixed in [magento/magento2#23477](https://github.com/magento/magento2/pull/23477)) + * [#23467](https://github.com/magento/magento2/issues/23467) -- Phone and Zip not update if customer have no saved address (fixed in [magento/magento2#23494](https://github.com/magento/magento2/pull/23494)) + * [#23222](https://github.com/magento/magento2/issues/23222) -- setup:upgrade should return failure when app:config:import failed (fixed in [magento/magento2#23310](https://github.com/magento/magento2/pull/23310)) + * [#23354](https://github.com/magento/magento2/issues/23354) -- Data saving problem error showing when leave blank qty and update it (fixed in [magento/magento2#23360](https://github.com/magento/magento2/pull/23360)) + * [#23424](https://github.com/magento/magento2/issues/23424) -- Search by keyword didn't work properly with "0" value (fixed in [magento/magento2#23427](https://github.com/magento/magento2/pull/23427)) + * [#16234](https://github.com/magento/magento2/issues/16234) -- Unable to enter `+` character in widget content (fixed in [magento/magento2#23496](https://github.com/magento/magento2/pull/23496)) + * [#9798](https://github.com/magento/magento2/issues/9798) -- Problem adding attribute options to configurable product via REST Api (fixed in [magento/magento2#23529](https://github.com/magento/magento2/pull/23529)) + * [#6287](https://github.com/magento/magento2/issues/6287) -- Customer Admin Shopping Cart View Missing (fixed in [magento/magento2#20918](https://github.com/magento/magento2/pull/20918)) + * [#8258](https://github.com/magento/magento2/issues/8258) -- M2.1.3 : Form validation with identical field names does not work as expected. (fixed in [magento/magento2#15383](https://github.com/magento/magento2/pull/15383)) + * [#13561](https://github.com/magento/magento2/issues/13561) -- Magento 2 and SSL connection to MySQL (fixed in [magento/magento2#18075](https://github.com/magento/magento2/pull/18075)) + * [#22545](https://github.com/magento/magento2/issues/22545) -- Status downloadable product stays pending after succesfull payment (fixed in [magento/magento2#22658](https://github.com/magento/magento2/pull/22658)) + * [#23383](https://github.com/magento/magento2/issues/23383) -- Products which are not assigned to any store are automatically being force-assigned a store ID after being saved (fixed in [magento/magento2#23500](https://github.com/magento/magento2/pull/23500)) + * [#22950](https://github.com/magento/magento2/issues/22950) -- Spacing issue for Gift message section in my account (fixed in [magento/magento2#23226](https://github.com/magento/magento2/pull/23226)) + * [#23606](https://github.com/magento/magento2/issues/23606) -- Default value for report filters might result in errors (fixed in [magento/magento2#23607](https://github.com/magento/magento2/pull/23607)) + * [#736](https://github.com/magento/magento2/issues/736) -- Access to Zend Framework classes (fixed in [magento/graphql-ce#747](https://github.com/magento/graphql-ce/pull/747)) + * [#739](https://github.com/magento/magento2/issues/739) -- Command line install script no longer exists. (fixed in [magento/graphql-ce#753](https://github.com/magento/graphql-ce/pull/753)) + * [#23435](https://github.com/magento/magento2/issues/23435) -- Catalog Products Filter in 2.3.2 (fixed in [magento/magento2#23444](https://github.com/magento/magento2/pull/23444)) + * [#12817](https://github.com/magento/magento2/issues/12817) -- Coupon code with canceled order (fixed in [magento/magento2#20579](https://github.com/magento/magento2/pull/20579)) + * [#23386](https://github.com/magento/magento2/issues/23386) -- Copy Service does not works properly for Entities which extends Data Object and implements ExtensibleDataInterface (fixed in [magento/magento2#23387](https://github.com/magento/magento2/pull/23387)) + * [#23345](https://github.com/magento/magento2/issues/23345) -- Creditmemo getOrder() method loads order incorrectly (fixed in [magento/magento2#23358](https://github.com/magento/magento2/pull/23358)) + * [#22814](https://github.com/magento/magento2/issues/22814) -- Product stock alert - unsubscribe not working (fixed in [magento/magento2#23459](https://github.com/magento/magento2/pull/23459)) + * [#23594](https://github.com/magento/magento2/issues/23594) -- Database Media Storage : php bin/magento catalog:images:resize fails when image does not exist locally (fixed in [magento/magento2#23598](https://github.com/magento/magento2/pull/23598)) + * [#23595](https://github.com/magento/magento2/issues/23595) -- Database Media Storage : php bin/magento catalog:images:resize fails to generate cached images in database (fixed in [magento/magento2#23598](https://github.com/magento/magento2/pull/23598)) + * [#23596](https://github.com/magento/magento2/issues/23596) -- Database Media Storage : Add new product image, cached images not generated (fixed in [magento/magento2#23598](https://github.com/magento/magento2/pull/23598)) + * [#23643](https://github.com/magento/magento2/issues/23643) -- Mime parts of email are no more encoded with quoted printable (fixed in [magento/magento2#23649](https://github.com/magento/magento2/pull/23649)) + * [#23597](https://github.com/magento/magento2/issues/23597) -- Database Media Storage : Difficulty changing mode to database media storage due to poor "Use Default Value" checkbox behaviour (fixed in [magento/magento2#23710](https://github.com/magento/magento2/pull/23710)) + * [#23510](https://github.com/magento/magento2/issues/23510) -- Product customizable options of Area type render issue in Dashboard (fixed in [magento/magento2#23524](https://github.com/magento/magento2/pull/23524)) + * [#22890](https://github.com/magento/magento2/issues/22890) -- Disabled config can be overwritten via admin (fixed in [magento/magento2#22891](https://github.com/magento/magento2/pull/22891)) + * [#23054](https://github.com/magento/magento2/issues/23054) -- Cron job not running after crashed once (fixed in [magento/magento2#23125](https://github.com/magento/magento2/pull/23125)) + * [#23135](https://github.com/magento/magento2/issues/23135) -- Insert Variable popup missing template variables for new templates (fixed in [magento/magento2#23173](https://github.com/magento/magento2/pull/23173)) + * [#23211](https://github.com/magento/magento2/issues/23211) -- Zero Subtotal Checkout erroneously says the default value for "Automatically Invoice All Items" is "Yes" (fixed in [magento/magento2#23688](https://github.com/magento/magento2/pull/23688)) + * [#23624](https://github.com/magento/magento2/issues/23624) -- [Authorize.net accept.js] "Place Order" button not being disabled (fixed in [magento/magento2#23718](https://github.com/magento/magento2/pull/23718)) + * [#23717](https://github.com/magento/magento2/issues/23717) -- dependency injection fails for \Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface (fixed in [magento/magento2#23753](https://github.com/magento/magento2/pull/23753)) + * [#758](https://github.com/magento/magento2/issues/758) -- Coding standards: arrays (fixed in [magento/graphql-ce#759](https://github.com/magento/graphql-ce/pull/759)) + * [#14071](https://github.com/magento/magento2/issues/14071) -- Not able to change a position of last two related products in case of I've 20+ related products. (fixed in [magento/magento2#22984](https://github.com/magento/magento2/pull/22984)) + * [#22112](https://github.com/magento/magento2/issues/22112) -- Shipping address information is lost in billing step (fixed in [magento/magento2#23656](https://github.com/magento/magento2/pull/23656)) + * [#23654](https://github.com/magento/magento2/issues/23654) -- Frontend Label For Custom Order Status not Editable in Magento Admin in Single Store Mode (fixed in [magento/magento2#23681](https://github.com/magento/magento2/pull/23681)) + * [#23751](https://github.com/magento/magento2/issues/23751) -- Database Media Storage : PDF Logo file not database aware (fixed in [magento/magento2#23752](https://github.com/magento/magento2/pull/23752)) + * [#23678](https://github.com/magento/magento2/issues/23678) -- Can't see "Zero Subtotal Checkout" payment method settings if "Offline Payments" module is disabled (fixed in [magento/magento2#23679](https://github.com/magento/magento2/pull/23679)) + * [#23777](https://github.com/magento/magento2/issues/23777) -- "Discount Amount" field is validated after the page load without any action from user in Create New Catalog Rule form (fixed in [magento/magento2#23779](https://github.com/magento/magento2/pull/23779)) + * [#23789](https://github.com/magento/magento2/issues/23789) -- CommentLevelsSniff works incorrect with @magento_import statement. (fixed in [magento/magento2#23790](https://github.com/magento/magento2/pull/23790)) + * [#22702](https://github.com/magento/magento2/issues/22702) -- Toggle icon not working in create configuration Product creation Page (fixed in [magento/magento2#23803](https://github.com/magento/magento2/pull/23803)) + * [#167](https://github.com/magento/magento2/issues/167) -- Fatal error: Class 'Mage' not found (fixed in [magento/graphql-ce#351](https://github.com/magento/graphql-ce/pull/351)) + * [#438](https://github.com/magento/magento2/issues/438) -- [Feature request] Price slider (fixed in [magento/graphql-ce#699](https://github.com/magento/graphql-ce/pull/699)) + * [#702](https://github.com/magento/magento2/issues/702) -- Base table or view not found (fixed in [magento/graphql-ce#779](https://github.com/magento/graphql-ce/pull/779)) + * [#738](https://github.com/magento/magento2/issues/738) -- pub/setup missing in 0.1.0-alpha103 (fixed in [magento/graphql-ce#789](https://github.com/magento/graphql-ce/pull/789)) + * [#23405](https://github.com/magento/magento2/issues/23405) -- 2.3.2 installed and bin/magento setup:upgrade not working (fixed in [magento/magento2#23866](https://github.com/magento/magento2/pull/23866)) + * [#23900](https://github.com/magento/magento2/issues/23900) -- Report->Product->Downloads has wrong ACL (fixed in [magento/magento2#23901](https://github.com/magento/magento2/pull/23901)) + * [#23904](https://github.com/magento/magento2/issues/23904) -- No auto-focus after validation at "Create Configurations" button => User can not see the error message (fixed in [magento/magento2#23905](https://github.com/magento/magento2/pull/23905)) + * [#23916](https://github.com/magento/magento2/issues/23916) -- Missing Validation at some Payment Method Settings (fixed in [magento/magento2#23917](https://github.com/magento/magento2/pull/23917)) + * [#23932](https://github.com/magento/magento2/issues/23932) -- Decimal quantity is not displayed for wishlist items. (fixed in [magento/magento2#23933](https://github.com/magento/magento2/pull/23933)) +* GitHub pull requests: + * [magento/magento2#20135](https://github.com/magento/magento2/pull/20135) -- issue fixed #20124 Sort By label is hidden by Shop By Menu on listing… (by @cedarvinda) + * [magento/magento2#22020](https://github.com/magento/magento2/pull/22020) -- Non existing file, when adding image to gallery with move option. Fix for #21978 (by @dudzio12) + * [magento/magento2#22260](https://github.com/magento/magento2/pull/22260) -- Disabling "Display on Product Details Page" the button is shown anyway. (by @Nazar65) + * [magento/magento2#22287](https://github.com/magento/magento2/pull/22287) -- #222249 configurable product images wrong sorting fix (by @Wirson) + * [magento/magento2#22526](https://github.com/magento/magento2/pull/22526) -- code cleanup (http to https) (by @ravi-chandra3197) + * [magento/magento2#22532](https://github.com/magento/magento2/pull/22532) -- fixed issue 22527 wishlist and compare icon alignment (by @sanjaychouhan-webkul) + * [magento/magento2#22423](https://github.com/magento/magento2/pull/22423) -- Store view specific labels cut in left navigation menu #22406 (by @sudhanshu-bajaj) + * [magento/magento2#22561](https://github.com/magento/magento2/pull/22561) -- [Catalog|Eav] Revert change of PR magento/magento2#13302 not included into revert commit (by @Den4ik) + * [magento/magento2#22569](https://github.com/magento/magento2/pull/22569) -- 2.3 develop pr1 (by @abhinay111222) + * [magento/magento2#22594](https://github.com/magento/magento2/pull/22594) -- Fixed typo issue (by @AfreenScarlet) + * [magento/magento2#22599](https://github.com/magento/magento2/pull/22599) -- Correct spelling (by @ravi-chandra3197) + * [magento/magento2#22621](https://github.com/magento/magento2/pull/22621) -- Resolved Typo (by @UdgamN) + * [magento/magento2#19767](https://github.com/magento/magento2/pull/19767) -- Prevent display of token when save for later is not selected (by @pmclain) + * [magento/magento2#21744](https://github.com/magento/magento2/pull/21744) -- Custom option type select - Allow modify list of single selection option types (by @ihor-sviziev) + * [magento/magento2#21992](https://github.com/magento/magento2/pull/21992) -- #21473: Form element validation is not triggered when validation rules... (by @kisroman) + * [magento/magento2#22493](https://github.com/magento/magento2/pull/22493) -- Update credit-card-number-validator.js (by @justin-at-bounteous) + * [magento/magento2#22643](https://github.com/magento/magento2/pull/22643) -- Fixed typo issue and added missing header in customer sales order grid (by @vishal-7037) + * [magento/magento2#22656](https://github.com/magento/magento2/pull/22656) -- issues #22647 fixed, In customer account create page word not readable, should use '-' after break to new line In mobile view (by @cedarvinda) + * [magento/magento2#22720](https://github.com/magento/magento2/pull/22720) -- Fixed:#22395 (by @satyaprakashpatel) + * [magento/magento2#22558](https://github.com/magento/magento2/pull/22558) -- Additional condition in getRegion() method (by @Leone) + * [magento/magento2#22560](https://github.com/magento/magento2/pull/22560) -- Fix undefined methods 'addClass' and `removeClass` on a PrototypeJS Element (by @markvds) + * [magento/magento2#22606](https://github.com/magento/magento2/pull/22606) -- Fix Exception While Creating an Order in the Admin (by @justin-at-bounteous) + * [magento/magento2#22628](https://github.com/magento/magento2/pull/22628) -- Add a missting colon in the pdf page. (by @Hailong) + * [magento/magento2#22644](https://github.com/magento/magento2/pull/22644) -- Issue fixed #22636 arrow toggle not changing only showing to down It should be toggle as every where is working (by @cedarvinda) + * [magento/magento2#22664](https://github.com/magento/magento2/pull/22664) -- Fixed Typo Error (by @LuciferStrome) + * [magento/magento2#22729](https://github.com/magento/magento2/pull/22729) -- Fixed Typo Issue (by @jitendra-cedcoss) + * [magento/magento2#22734](https://github.com/magento/magento2/pull/22734) -- Ignores allure-results in git. (by @hostep) + * [magento/magento2#22758](https://github.com/magento/magento2/pull/22758) -- Correct spelling (by @ravi-chandra3197) + * [magento/magento2#22798](https://github.com/magento/magento2/pull/22798) -- Disable Travis builds - 2.3-develop (by @okorshenko) + * [magento/magento2#22126](https://github.com/magento/magento2/pull/22126) -- Remove unnecessary form on order success page (by @danielgoodwin97) + * [magento/magento2#22655](https://github.com/magento/magento2/pull/22655) -- Fixed Issue #22640 (by @Surabhi-Cedcoss) + * [magento/magento2#22657](https://github.com/magento/magento2/pull/22657) -- 404 not found form validation url when updating quantity in cart page (by @gulshanchitransh) + * [magento/magento2#22739](https://github.com/magento/magento2/pull/22739) -- Revert "Magento backend catalog cost without currency symbol" as Cost... (by @orlangur) + * [magento/magento2#22779](https://github.com/magento/magento2/pull/22779) -- #22771 Remove hardcoded height for admin textarea (by @serhiyzhovnir) + * [magento/magento2#22791](https://github.com/magento/magento2/pull/22791) -- Fixed issue #22788 (by @gauravagarwal1001) + * [magento/magento2#19584](https://github.com/magento/magento2/pull/19584) -- Tierprice can t save float percentage value 18651 (by @novikor) + * [magento/magento2#21675](https://github.com/magento/magento2/pull/21675) -- [2.3] Database Media Storage - Design Config Save functions to be Database Media Storage aware (by @gwharton) + * [magento/magento2#21917](https://github.com/magento/magento2/pull/21917) -- Prevent duplicate variation error during import of configurable products with numerical SKUs (by @alexander-aleman) + * [magento/magento2#22463](https://github.com/magento/magento2/pull/22463) -- Set timezone on DateTime object not in constructor (by @NathMorgan) + * [magento/magento2#22575](https://github.com/magento/magento2/pull/22575) -- Fix for update products via csv file (fix for 22028) (by @mtwegrzycki) + * [magento/magento2#22794](https://github.com/magento/magento2/pull/22794) -- fixed issue #21558 - Navigation issue of review from product listing (by @sanjaychouhan-webkul) + * [magento/magento2#22844](https://github.com/magento/magento2/pull/22844) -- Allow to specify a field to be checked in the response (by @diazwatson) + * [magento/magento2#22186](https://github.com/magento/magento2/pull/22186) -- 22127: check that products is set (by @davidverholen) + * [magento/magento2#22418](https://github.com/magento/magento2/pull/22418) -- Patch the prototype pollution vulnerability in jQuery < 3.4.0 (CVE-2019-11358) (by @DanielRuf) + * [magento/magento2#22724](https://github.com/magento/magento2/pull/22724) -- Fixed issue #22639: Without select attribute click on add attribute it display all selected when add attribute again. (by @maheshWebkul721) + * [magento/magento2#22742](https://github.com/magento/magento2/pull/22742) -- issue #22676 fixed - Compare Products counter, and My Wish List count... (by @sanjaychouhan-webkul) + * [magento/magento2#22850](https://github.com/magento/magento2/pull/22850) -- only show customer account sections if payment method is active (by @torhoehn) + * [magento/magento2#22854](https://github.com/magento/magento2/pull/22854) -- fix #4628 font-face mixin add fromat option (by @Karlasa) + * [magento/magento2#22868](https://github.com/magento/magento2/pull/22868) -- fix date calculation for report's years interval (by @polkan-msk) + * [magento/magento2#21397](https://github.com/magento/magento2/pull/21397) -- Fixed Validation messages missing from datepicker form elements (by @ravi-chandra3197) + * [magento/magento2#22694](https://github.com/magento/magento2/pull/22694) -- Fixed Issue #20234 (by @surbhi-ranosys) + * [magento/magento2#22787](https://github.com/magento/magento2/pull/22787) -- #22786 Add dependency for UPS required fields to avoid validation for these fields if UPS Shipping is not active (by @serhiyzhovnir) + * [magento/magento2#22823](https://github.com/magento/magento2/pull/22823) -- [Shipping] Adjusting the Contact Us Xpath (by @eduard13) + * [magento/magento2#22830](https://github.com/magento/magento2/pull/22830) -- Removing "if" block and making code more legible (by @matheusgontijo) + * [magento/magento2#22839](https://github.com/magento/magento2/pull/22839) -- FIX: Add missing Stories and Severity to Test cases (by @lbajsarowicz) + * [magento/magento2#22858](https://github.com/magento/magento2/pull/22858) -- Grammatical mistake in the comments (by @sudhanshu-bajaj) + * [magento/magento2#22889](https://github.com/magento/magento2/pull/22889) -- Replace hardcoded CarierCode from createShippingMethod() (by @wigman) + * [magento/magento2#22922](https://github.com/magento/magento2/pull/22922) -- [BUGFIX] Set correct cron instance for catalog_product_frontend_actio... (by @lewisvoncken) + * [magento/magento2#22607](https://github.com/magento/magento2/pull/22607) -- Implement Better Error Handling and Fix Waits on Null PIDs in Parallel SCD Execution (by @davidalger) + * [magento/magento2#22795](https://github.com/magento/magento2/pull/22795) -- fixed issue #22736 - Cursor position not in right side of search keyword in mobile (by @sanjaychouhan-webkul) + * [magento/magento2#22876](https://github.com/magento/magento2/pull/22876) -- Fixed issue #22875 Billing Agreements page title need to be improved (by @amitvishvakarma) + * [magento/magento2#21215](https://github.com/magento/magento2/pull/21215) -- fixed-Discount-Code-improvement-21214 (by @abrarpathan19) + * [magento/magento2#22307](https://github.com/magento/magento2/pull/22307) -- Varnish health check failing due to presence of id_prefix in env.php (by @Nazar65) + * [magento/magento2#22444](https://github.com/magento/magento2/pull/22444) -- magento/magento2#22317: PR#22321 fix. (by @p-bystritsky) + * [magento/magento2#22513](https://github.com/magento/magento2/pull/22513) -- Fixed #22396 config:set fails with JSON values (by @shikhamis11) + * [magento/magento2#22520](https://github.com/magento/magento2/pull/22520) -- Fixed #22506: Search suggestion panel overlapping on advance reporting button (by @webkul-ajaysaini) + * [magento/magento2#22760](https://github.com/magento/magento2/pull/22760) -- [Forwardport] Magento Catalog - fix custom option type text price conversion for mu... (by @ihor-sviziev) + * [magento/magento2#22893](https://github.com/magento/magento2/pull/22893) -- #22869 - defaulting customer storeId fix (by @Wirson) + * [magento/magento2#22926](https://github.com/magento/magento2/pull/22926) -- Store view label not in the middle of panel (by @speedy008) + * [magento/magento2#22947](https://github.com/magento/magento2/pull/22947) -- phpcs error on rule classes - must be of the type integer (by @Nazar65) + * [magento/magento2#22951](https://github.com/magento/magento2/pull/22951) -- Update the contributing.md to match the new beginners guide (by @dmanners) + * [magento/magento2#22387](https://github.com/magento/magento2/pull/22387) -- Checkout totals order in specific store (by @krnshah) + * [magento/magento2#22718](https://github.com/magento/magento2/pull/22718) -- Resolved issue coupon codes don't work anymore #18183 (by @this-adarsh) + * [magento/magento2#22914](https://github.com/magento/magento2/pull/22914) -- #22899 Fix the issue with Incorrect return type at getListByCustomerId in PaymentTokenManagementInterface (by @serhiyzhovnir) + * [magento/magento2#22687](https://github.com/magento/magento2/pull/22687) -- #22686 Shipment view fixed for Fatal error. (by @milindsingh) + * [magento/magento2#22772](https://github.com/magento/magento2/pull/22772) -- Fixed issue #22767: Not clear logic for loading CMS Pages with setStoreId function (by @maheshWebkul721) + * [magento/magento2#22931](https://github.com/magento/magento2/pull/22931) -- [Fixed-20788: Listing page no equal spacing in product in list view] (by @hitesh-wagento) + * [magento/magento2#22965](https://github.com/magento/magento2/pull/22965) -- Simplify if else catalog search full text data provider (by @sankalpshekhar) + * [magento/magento2#23011](https://github.com/magento/magento2/pull/23011) -- Fix typehint (by @amenk) + * [magento/magento2#22920](https://github.com/magento/magento2/pull/22920) -- Mview Indexers getList should return integer values of id's and not strings (by @mhodge13) + * [magento/magento2#23020](https://github.com/magento/magento2/pull/23020) -- Remove direct use of object manager (by @AnshuMishra17) + * [magento/magento2#23033](https://github.com/magento/magento2/pull/23033) -- Issue fix #23030: Swatch change Image does not slide to first Image (by @milindsingh) + * [magento/magento2#23035](https://github.com/magento/magento2/pull/23035) -- [Validator] Fix wrong behaviour of validation scroll (by @Den4ik) + * [magento/magento2#18459](https://github.com/magento/magento2/pull/18459) -- 12696 Delete all test modules after integration tests (by @avstudnitz) + * [magento/magento2#19897](https://github.com/magento/magento2/pull/19897) -- Re-enable PriceBox block caching (by @brucemead) + * [magento/magento2#21200](https://github.com/magento/magento2/pull/21200) -- [FEATURE] Don't load product collection in review observer (by @Den4ik) + * [magento/magento2#22071](https://github.com/magento/magento2/pull/22071) -- Make sure 'last' class is set on top menu (by @arnoudhgz) + * [magento/magento2#22821](https://github.com/magento/magento2/pull/22821) -- Customer Account Forgot Password page title fix (by @textarea) + * [magento/magento2#22884](https://github.com/magento/magento2/pull/22884) -- Show exception message during SCD failure (by @ihor-sviziev) + * [magento/magento2#22989](https://github.com/magento/magento2/pull/22989) -- Properly transliterate German Umlauts (by @amenk) + * [magento/magento2#23036](https://github.com/magento/magento2/pull/23036) -- [Framework] Reassign fields variable after converting to array (by @Den4ik) + * [magento/magento2#23040](https://github.com/magento/magento2/pull/23040) -- Don't create a new account-nav block - use existing instead. (by @vovayatsyuk) + * [magento/magento2#23046](https://github.com/magento/magento2/pull/23046) -- Add more descriptive exception when data patch fails to apply. (by @ashsmith) + * [magento/magento2#23067](https://github.com/magento/magento2/pull/23067) -- Create Security.md file to show on GitHub Security/Policy page (by @piotrekkaminski) + * [magento/magento2#14384](https://github.com/magento/magento2/pull/14384) -- Don't throw shipping method exception when creating quote with only virtual products in API (by @Maikel-Koek) + * [magento/magento2#19184](https://github.com/magento/magento2/pull/19184) -- Fixed magento text swatch switches product image even if attribute feature is disabled #16446 (by @ravi-chandra3197) + * [magento/magento2#21394](https://github.com/magento/magento2/pull/21394) -- [2.3]creating customer without password is directly confirmed 14492 (by @novikor) + * [magento/magento2#21674](https://github.com/magento/magento2/pull/21674) -- [2.3] Database Media Storage - Transactional Emails will now extract image from database in Database Media Storage mode (by @gwharton) + * [magento/magento2#22336](https://github.com/magento/magento2/pull/22336) -- fix clean_cache plugin flush mode (by @thomas-kl1) + * [magento/magento2#22426](https://github.com/magento/magento2/pull/22426) -- Fixed wrong url redirect when edit product review from Customer view page (by @ravi-chandra3197) + * [magento/magento2#22521](https://github.com/magento/magento2/pull/22521) -- Fixed 22511 (by @maheshWebkul721) + * [magento/magento2#22626](https://github.com/magento/magento2/pull/22626) -- resolved typo error (by @nehaguptacedcoss) + * [magento/magento2#22834](https://github.com/magento/magento2/pull/22834) -- #16445 - getRegionHtmlSelect does not have configuration - resolved (by @nikunjskd20) + * [magento/magento2#22937](https://github.com/magento/magento2/pull/22937) -- Mark Elasticsearch 6 support for synonyms (by @aapokiiso) + * [magento/magento2#23081](https://github.com/magento/magento2/pull/23081) -- Fix missing whitespace in mobile navigation for non-English websites (by @alexeya-ven) + * [magento/magento2#21131](https://github.com/magento/magento2/pull/21131) -- Fix Issue #19872 - checking if image is in media directory (by @Bartlomiejsz) + * [magento/magento2#22341](https://github.com/magento/magento2/pull/22341) -- Apply coupoun and scroll top to check. applied successfully or not (by @krnshah) + * [magento/magento2#22646](https://github.com/magento/magento2/pull/22646) -- Fixed Issue #22087 (by @Surabhi-Cedcoss) + * [magento/magento2#23025](https://github.com/magento/magento2/pull/23025) -- Re-enable XML as request and response types within the SwaggerUI (by @sweikenb) + * [magento/magento2#20848](https://github.com/magento/magento2/pull/20848) -- Partial docs fixes in Newsletter module (by @SikailoISM) + * [magento/magento2#21605](https://github.com/magento/magento2/pull/21605) -- [2.3] Database Media Storage - Admin Product Edit Page handles recreates images correctly when pub/media/catalog is cleared. (by @gwharton) + * [magento/magento2#21876](https://github.com/magento/magento2/pull/21876) -- $product->getUrlInStore() does not allow to override the scope in backend context (by @Nazar65) + * [magento/magento2#23007](https://github.com/magento/magento2/pull/23007) -- [Fixed] Reset feature does not clear the date (by @niravkrish) + * [magento/magento2#23118](https://github.com/magento/magento2/pull/23118) -- #23053 : sendfriend verifies product visibility instead of status (by @Wirson) + * [magento/magento2#18748](https://github.com/magento/magento2/pull/18748) -- Add a module manager to the Magento Framework API (by @navarr) + * [magento/magento2#22637](https://github.com/magento/magento2/pull/22637) -- Fixed #22484 Customer address States are duplicated in backend (by @shikhamis11) + * [magento/magento2#23140](https://github.com/magento/magento2/pull/23140) -- magento/magento2#23138: Magento_Theme. Incorrect configuration file location (by @atwixfirster) + * [magento/magento2#23179](https://github.com/magento/magento2/pull/23179) -- Fix for translation function (by @kkdg) + * [magento/magento2#22704](https://github.com/magento/magento2/pull/22704) -- Fixed #22004 can't update attribute for all product (by @shikhamis11) + * [magento/magento2#22933](https://github.com/magento/magento2/pull/22933) -- magento/magento2#22870: ProductRepository fails to update an existing product with a changed SKU. (by @p-bystritsky) + * [magento/magento2#23005](https://github.com/magento/magento2/pull/23005) -- Improve command catalog:images:resize (by @tdgroot) + * [magento/magento2#22942](https://github.com/magento/magento2/pull/22942) -- Fixed issue #18337 (by @geet07) + * [magento/magento2#23216](https://github.com/magento/magento2/pull/23216) -- Fixed #23213 Static content deploy showing percentage symbol two times in progress bar (by @amitvishvakarma) + * [magento/magento2#23244](https://github.com/magento/magento2/pull/23244) -- Update CONTRIBUTING.md (by @diazwatson) + * [magento/magento2#23248](https://github.com/magento/magento2/pull/23248) -- fix tooltip toggle selector typo (by @Karlasa) + * [magento/magento2#23250](https://github.com/magento/magento2/pull/23250) -- Fixed #23238 Apply button act like remove button while create new order from admin (by @gauravagarwal1001) + * [magento/magento2#22211](https://github.com/magento/magento2/pull/22211) -- Show converted value for validateForRefund error message (by @kassner) + * [magento/magento2#23129](https://github.com/magento/magento2/pull/23129) -- #22934 Improved sitemap product generation logic (by @sergiy-v) + * [magento/magento2#23201](https://github.com/magento/magento2/pull/23201) -- MFTF: Use AdminLoginActionGroup for AdminLoginTest - easiest use of ActionGroup (by @lbajsarowicz) + * [magento/magento2#23100](https://github.com/magento/magento2/pull/23100) -- Resolve issue with improper EAV attribute join statement (by @udovicic) + * [magento/magento2#23267](https://github.com/magento/magento2/pull/23267) -- Add filter index for ID column in adminhtml user grid (by @JeroenVanLeusden) + * [magento/magento2#23286](https://github.com/magento/magento2/pull/23286) -- Fixed Credit memo submit button(refund) stays disable after validation fails & unable to enable button issue. (by @nishantjariwala) + * [magento/magento2#23292](https://github.com/magento/magento2/pull/23292) -- revert Properly transliterate German Umlauts (by @Nazar65) + * [magento/magento2#23307](https://github.com/magento/magento2/pull/23307) -- [Ui] Allow to define listing configuration via ui component xml (by @Den4ik) + * [magento/magento2#23335](https://github.com/magento/magento2/pull/23335) -- Correct spelling (by @ravi-chandra3197) + * [magento/magento2#22675](https://github.com/magento/magento2/pull/22675) -- Fixed #20038 loading icon disappearing before background process completes for Braintree payment in Admin (by @kunal-rtpl) + * [magento/magento2#23174](https://github.com/magento/magento2/pull/23174) -- Move Quote related Plugins to correct module (by @sankalpshekhar) + * [magento/magento2#23309](https://github.com/magento/magento2/pull/23309) -- magento/magento2#23074: update correct product URL rewrites after changing category url key (by @sta1r) + * [magento/magento2#23347](https://github.com/magento/magento2/pull/23347) -- Fixes incorrect file reference in a comment in a .htaccess file. (by @hostep) + * [magento/magento2#22650](https://github.com/magento/magento2/pull/22650) -- Fixes issue #13227 (by @atishgoswami) + * [magento/magento2#22800](https://github.com/magento/magento2/pull/22800) -- fixed issue #22638 - Asterisk(*) sign position does not consistent in admin (by @sanjaychouhan-webkul) + * [magento/magento2#22910](https://github.com/magento/magento2/pull/22910) -- Do an empty check instead of isset check on image removed (by @arnoudhgz) + * [magento/magento2#23218](https://github.com/magento/magento2/pull/23218) -- Fixed #22266: 404 message for product alerts when not logged in (by @ArjenMiedema) + * [magento/magento2#23247](https://github.com/magento/magento2/pull/23247) -- Fixed 23230 : Sticky header floating under top when there is no buttons in the toolbar (by @konarshankar07) + * [magento/magento2#23338](https://github.com/magento/magento2/pull/23338) -- Fix issue with incorrect payment translation in sales emails (by @alexeya-ven) + * [magento/magento2#23366](https://github.com/magento/magento2/pull/23366) -- Correct spelling (by @ravi-chandra3197) + * [magento/magento2#23367](https://github.com/magento/magento2/pull/23367) -- #23346: 'Test Connection' button is over-spanned (by @konarshankar07) + * [magento/magento2#22671](https://github.com/magento/magento2/pull/22671) -- Change exportButton option cvs (by @ajeetsinghcedcoss) + * [magento/magento2#23240](https://github.com/magento/magento2/pull/23240) -- Refactor: Improve mview code readability (by @lbajsarowicz) + * [magento/magento2#23280](https://github.com/magento/magento2/pull/23280) -- Ensure page is loaded after order click actions (by @fooman) + * [magento/magento2#23306](https://github.com/magento/magento2/pull/23306) -- FS/23038 Decimal qty with Increment is with specific values are not adding in cart (by @sertlab) + * [magento/magento2#23312](https://github.com/magento/magento2/pull/23312) -- Added function to check against running/pending/successful cron tasks (by @chickenland) + * [magento/magento2#22116](https://github.com/magento/magento2/pull/22116) -- Fix magento root package identification for metapackage installation (by @oleksii-lisovyi) + * [magento/magento2#23234](https://github.com/magento/magento2/pull/23234) -- [Ui] Calling the always action on opening and closing the modal. (by @eduard13) + * [magento/magento2#23353](https://github.com/magento/magento2/pull/23353) -- Get review entity id by code instead hard-coded. (by @DaniloEmpire) + * [magento/magento2#23393](https://github.com/magento/magento2/pull/23393) -- Fixed issue #21974 (by @geet07) + * [magento/magento2#23394](https://github.com/magento/magento2/pull/23394) -- Fixed issue #23377 (by @geet07) + * [magento/magento2#23403](https://github.com/magento/magento2/pull/23403) -- Remove rogue closing tag from store-switcher template (by @sta1r) + * [magento/magento2#22987](https://github.com/magento/magento2/pull/22987) -- Fixed apply discount coupons for bundle product (by @NikolasSumrak) + * [magento/magento2#23048](https://github.com/magento/magento2/pull/23048) -- #22998 : failing order creation with api when no address email is provided (by @Wirson) + * [magento/magento2#23390](https://github.com/magento/magento2/pull/23390) -- Changed logic so that _scrollToTopIfVisible is called only if element is in viewport. Previously it was called only when the element was outside it. (by @oskarolaussen) + * [magento/magento2#23425](https://github.com/magento/magento2/pull/23425) -- The best practices for SEO meta sequence. (by @vaseemishak) + * [magento/magento2#23523](https://github.com/magento/magento2/pull/23523) -- Issue #23522 UPS shipping booking and label generation gives error when shipper's street given more than 35 chars (by @ankurvr) + * [magento/magento2#23528](https://github.com/magento/magento2/pull/23528) -- move breakpoint by -1px to make nav work correctly at viewport 768 (by @bobemoe) + * [magento/magento2#23532](https://github.com/magento/magento2/pull/23532) -- Correct array type hints in Visibility model (by @pmclain) + * [magento/magento2#23535](https://github.com/magento/magento2/pull/23535) -- [2.3] Plain Text Emails are now sent with correct MIME Encoding (by @gwharton) + * [magento/magento2#23541](https://github.com/magento/magento2/pull/23541) -- fix validation class for max-words (by @sunilit42) + * [magento/magento2#21128](https://github.com/magento/magento2/pull/21128) -- Fix issue 21126 : Import design break issue resolved (by @speedy008) + * [magento/magento2#22213](https://github.com/magento/magento2/pull/22213) -- Date column ui component locale date format (by @Karlasa) + * [magento/magento2#23457](https://github.com/magento/magento2/pull/23457) -- Update CartTotalRepository.php (by @UlyanaKiklevich) + * [magento/magento2#23474](https://github.com/magento/magento2/pull/23474) -- Fixed tooltip missing at store view lable in Cms page and Cms block (by @dipeshrangani) + * [magento/magento2#23477](https://github.com/magento/magento2/pull/23477) -- Added quantity validation on Shipping Multiple Address Page (by @nirmalraval18) + * [magento/magento2#23494](https://github.com/magento/magento2/pull/23494) -- Removed editor from phone and zipcode (by @kazim-krish) + * [magento/magento2#23310](https://github.com/magento/magento2/pull/23310) -- magento/magento-2#23222: setup:upgrade should return failure when app… (by @ProcessEight) + * [magento/magento2#23360](https://github.com/magento/magento2/pull/23360) -- #23354 : Data saving problem error showing when leave blank qty and update it (by @konarshankar07) + * [magento/magento2#23427](https://github.com/magento/magento2/pull/23427) -- 23424: fixed search with 0 (by @jeysmook) + * [magento/magento2#23496](https://github.com/magento/magento2/pull/23496) -- Resolved + character issue in custom widget (by @sarfarazbheda) + * [magento/magento2#23529](https://github.com/magento/magento2/pull/23529) -- Feature/9798 updating configurable product options based on produc id and sku (by @lpouwelse) + * [magento/magento2#20918](https://github.com/magento/magento2/pull/20918) -- Enabled 'Shopping Cart' tab for customer edit interface in admin (by @rav-redchamps) + * [magento/magento2#22624](https://github.com/magento/magento2/pull/22624) -- Resolve Typo (by @prashantsharmacedcoss) + * [magento/magento2#15383](https://github.com/magento/magento2/pull/15383) -- issue fixed #8258 - assign indices for all array inputs so that validation works properly (by @jayankaghosh) + * [magento/magento2#18075](https://github.com/magento/magento2/pull/18075) -- Feature/issue 13561 2.3 (by @bnymn) + * [magento/magento2#22658](https://github.com/magento/magento2/pull/22658) -- Fixed #22545 Status downloadable product stays pending after succesfu… (by @shikhamis11) + * [magento/magento2#23500](https://github.com/magento/magento2/pull/23500) -- Fixed issue #23383 (by @manishgoswamij) + * [magento/magento2#23226](https://github.com/magento/magento2/pull/23226) -- Spacing issue for Gift message section in my account (by @amjadm61) + * [magento/magento2#23272](https://github.com/magento/magento2/pull/23272) -- hide or show the select for regions instead of enabling/disabling in customer registration (by @UB3RL33T) + * [magento/magento2#23593](https://github.com/magento/magento2/pull/23593) -- A small fix to improve format customer acl xml. (by @mrkhoa99) + * [magento/magento2#23607](https://github.com/magento/magento2/pull/23607) -- Default filter for reports set to past month (by @rogyar) + * [magento/magento2#22138](https://github.com/magento/magento2/pull/22138) -- BeanShells are changed to correct using of variables (by @AnnaShepa) + * [magento/magento2#22733](https://github.com/magento/magento2/pull/22733) -- Adds module:config:status command which checks if the module config i… (by @hostep) + * [magento/magento2#23351](https://github.com/magento/magento2/pull/23351) -- Fix some framework coding issues (by @fooman) + * [magento/magento2#23444](https://github.com/magento/magento2/pull/23444) -- Fix missing attribute_id condition from filter (by @mattijv) + * [magento/magento2#20579](https://github.com/magento/magento2/pull/20579) -- magento/magento2#12817: [Forwardport] Coupon code with canceled order. (by @p-bystritsky) + * [magento/magento2#23387](https://github.com/magento/magento2/pull/23387) -- magento/magento2#23386: Copy Service does not work properly for Entities which extends Data Object and implements ExtensibleDataInterface. (by @swnsma) + * [magento/magento2#23358](https://github.com/magento/magento2/pull/23358) -- magento/magento2#23345: Creditmemo getOrder() method loads order incorrectly. (by @p-bystritsky) + * [magento/magento2#23459](https://github.com/magento/magento2/pull/23459) -- magento/magento2#22814: Product stock alert - unsubscribe not working (by @yuriichayka) + * [magento/magento2#23598](https://github.com/magento/magento2/pull/23598) -- [2.3] magento catalog:images:resize now Database Media Storage mode aware (by @gwharton) + * [magento/magento2#23291](https://github.com/magento/magento2/pull/23291) -- Optimized dev:urn-catalog:generate for PHPStorm (by @JeroenBoersma) + * [magento/magento2#23592](https://github.com/magento/magento2/pull/23592) -- [Unit] Fix broken unit tests (by @Den4ik) + * [magento/magento2#23649](https://github.com/magento/magento2/pull/23649) -- [2.3] Transfer Encoding of emails changed to QUOTED-PRINTABLE (by @gwharton) + * [magento/magento2#23652](https://github.com/magento/magento2/pull/23652) -- Add missing getClass() to image.phtml so it is more like image_with_borders.phtml (by @woutersamaey) + * [magento/magento2#23710](https://github.com/magento/magento2/pull/23710) -- [2.3] Improve Database Media Storage Configuration settings usability (by @gwharton) + * [magento/magento2#23735](https://github.com/magento/magento2/pull/23735) -- Fixed typo in deploy module README.md (by @arnolds) + * [magento/magento2#22717](https://github.com/magento/magento2/pull/22717) -- Getting 404 url while updating quantity on multiple address cart page (by @vikalps4) + * [magento/magento2#23166](https://github.com/magento/magento2/pull/23166) -- Fix 22085 (by @geet07) + * [magento/magento2#23524](https://github.com/magento/magento2/pull/23524) -- remove html tag from option html from order page (by @sunilit42) + * [magento/magento2#22891](https://github.com/magento/magento2/pull/22891) -- Check if setting is disabled on default scope (by @kassner) + * [magento/magento2#23099](https://github.com/magento/magento2/pull/23099) -- fix customer data race condition when bundling is enabled (by @davidverholen) + * [magento/magento2#23125](https://github.com/magento/magento2/pull/23125) -- Catch throwables in mview updating (by @QuentinFarizonAfrimarket) + * [magento/magento2#23173](https://github.com/magento/magento2/pull/23173) -- Fixed issue #23135: Insert Variable popup missing template variables for new templates (by @maheshWebkul721) + * [magento/magento2#23688](https://github.com/magento/magento2/pull/23688) -- Resolve "Automatically Invoice All Items" is "Yes" but no invoice is created (Zero Subtotal Checkout) (by @edenduong) + * [magento/magento2#23718](https://github.com/magento/magento2/pull/23718) -- Resolve [Authorize.net accept.js] "Place Order" button not being disabled when editing billing address (by @edenduong) + * [magento/magento2#23753](https://github.com/magento/magento2/pull/23753) -- Add Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface to di.xml in issue23717 (by @edenduong) + * [magento/magento2#22984](https://github.com/magento/magento2/pull/22984) -- magento/magento2#14071: Not able to change a position of last two rel... (by @m-a-x-i-m) + * [magento/magento2#23656](https://github.com/magento/magento2/pull/23656) -- Fixes issue 22112 (https://github.com/magento/magento2/issues/22112) ... (by @rsimmons07) + * [magento/magento2#23666](https://github.com/magento/magento2/pull/23666) -- magento/magento2#: Fix storeId param type in the EmailNotification::newAccount, EmailNotificationInterface::newAccount methods (by @atwixfirster) + * [magento/magento2#23681](https://github.com/magento/magento2/pull/23681) -- Resolve Frontend Label For Custom Order Status not Editable in Magento Admin in Single Store Mode (by @edenduong) + * [magento/magento2#23752](https://github.com/magento/magento2/pull/23752) -- [2.3] Database Media Storage : PDF Logo file now database aware (by @gwharton) + * [magento/magento2#23679](https://github.com/magento/magento2/pull/23679) -- Moved Zero Subtotal Checkout Payment Settings (by @textarea) + * [magento/magento2#23779](https://github.com/magento/magento2/pull/23779) -- Resolve "Discount Amount" field is validated after the page load without any action from user in Create New Catalog Rule form issue23777 (by @edenduong) + * [magento/magento2#23787](https://github.com/magento/magento2/pull/23787) -- Fix for PHP_CodeSniffer error after app:config:dump (by @dng-dev) + * [magento/magento2#23790](https://github.com/magento/magento2/pull/23790) -- magento/magento2#23789: CommentLevelsSniff works incorrect with @magento_import statement. (by @p-bystritsky) + * [magento/magento2#23794](https://github.com/magento/magento2/pull/23794) -- Remove duplicate declaration (by @gfernandes410) + * [magento/magento2#23803](https://github.com/magento/magento2/pull/23803) -- Resolve Toggle icon not working in create configuration Product creation Page issue 22702 (by @edenduong) + * [magento/magento2#23782](https://github.com/magento/magento2/pull/23782) -- Cleaning some code gaps (by @Stepa4man) + * [magento/magento2#23840](https://github.com/magento/magento2/pull/23840) -- Fix regular expression comment on function isNameValid() in ImageContentValidator.php (by @nimbus2300) + * [magento/magento2#23845](https://github.com/magento/magento2/pull/23845) -- Add custom added url key to decoded directive string in WYSIWYG editor (by @JeroenVanLeusden) + * [magento/magento2#23866](https://github.com/magento/magento2/pull/23866) -- additional check for correct version of sodium (by @matei) + * [magento/magento2#23901](https://github.com/magento/magento2/pull/23901) -- Resolve Report->Product->Downloads has wrong ACL issue 23900 (by @edenduong) + * [magento/magento2#23905](https://github.com/magento/magento2/pull/23905) -- Resolve No auto-focus after validation at "Create Configurations" button => User can not see the error message issue23904 (by @edenduong) + * [magento/magento2#23917](https://github.com/magento/magento2/pull/23917) -- Resolve Missing Validation at some Payment Method Settings issue 23916 (by @edenduong) + * [magento/magento2#23919](https://github.com/magento/magento2/pull/23919) -- class ApplyAttributesUpdate should use \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE instead of fixing "bundle" (by @edenduong) + * [magento/magento2#23933](https://github.com/magento/magento2/pull/23933) -- Fix display of decimal quantities for wishlist items (by @mfickers) + 2.3.2 ============= * GitHub issues: From 5d7082f2217912839f6684cfe1c8b7639d807c92 Mon Sep 17 00:00:00 2001 From: Kieu Phan <kphan@adobe.com> Date: Mon, 26 Aug 2019 16:39:46 -0500 Subject: [PATCH 339/372] MC-18532: Update Changelog based on delivered scope Update Changelog for 2.3.3-develop --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f760535cb91b..24e445b043bfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -354,7 +354,7 @@ * [magento/magento2#23474](https://github.com/magento/magento2/pull/23474) -- Fixed tooltip missing at store view lable in Cms page and Cms block (by @dipeshrangani) * [magento/magento2#23477](https://github.com/magento/magento2/pull/23477) -- Added quantity validation on Shipping Multiple Address Page (by @nirmalraval18) * [magento/magento2#23494](https://github.com/magento/magento2/pull/23494) -- Removed editor from phone and zipcode (by @kazim-krish) - * [magento/magento2#23310](https://github.com/magento/magento2/pull/23310) -- magento/magento-2#23222: setup:upgrade should return failure when app… (by @ProcessEight) + * [magento/magento2#23310](https://github.com/magento/magento2/pull/23310) -- magento/magento-2#23222: setup:upgrade should return failure when app... (by @ProcessEight) * [magento/magento2#23360](https://github.com/magento/magento2/pull/23360) -- #23354 : Data saving problem error showing when leave blank qty and update it (by @konarshankar07) * [magento/magento2#23427](https://github.com/magento/magento2/pull/23427) -- 23424: fixed search with 0 (by @jeysmook) * [magento/magento2#23496](https://github.com/magento/magento2/pull/23496) -- Resolved + character issue in custom widget (by @sarfarazbheda) @@ -363,14 +363,14 @@ * [magento/magento2#22624](https://github.com/magento/magento2/pull/22624) -- Resolve Typo (by @prashantsharmacedcoss) * [magento/magento2#15383](https://github.com/magento/magento2/pull/15383) -- issue fixed #8258 - assign indices for all array inputs so that validation works properly (by @jayankaghosh) * [magento/magento2#18075](https://github.com/magento/magento2/pull/18075) -- Feature/issue 13561 2.3 (by @bnymn) - * [magento/magento2#22658](https://github.com/magento/magento2/pull/22658) -- Fixed #22545 Status downloadable product stays pending after succesfu… (by @shikhamis11) + * [magento/magento2#22658](https://github.com/magento/magento2/pull/22658) -- Fixed #22545 Status downloadable product stays pending after succesfu... (by @shikhamis11) * [magento/magento2#23500](https://github.com/magento/magento2/pull/23500) -- Fixed issue #23383 (by @manishgoswamij) * [magento/magento2#23226](https://github.com/magento/magento2/pull/23226) -- Spacing issue for Gift message section in my account (by @amjadm61) * [magento/magento2#23272](https://github.com/magento/magento2/pull/23272) -- hide or show the select for regions instead of enabling/disabling in customer registration (by @UB3RL33T) * [magento/magento2#23593](https://github.com/magento/magento2/pull/23593) -- A small fix to improve format customer acl xml. (by @mrkhoa99) * [magento/magento2#23607](https://github.com/magento/magento2/pull/23607) -- Default filter for reports set to past month (by @rogyar) * [magento/magento2#22138](https://github.com/magento/magento2/pull/22138) -- BeanShells are changed to correct using of variables (by @AnnaShepa) - * [magento/magento2#22733](https://github.com/magento/magento2/pull/22733) -- Adds module:config:status command which checks if the module config i… (by @hostep) + * [magento/magento2#22733](https://github.com/magento/magento2/pull/22733) -- Adds module:config:status command which checks if the module config i... (by @hostep) * [magento/magento2#23351](https://github.com/magento/magento2/pull/23351) -- Fix some framework coding issues (by @fooman) * [magento/magento2#23444](https://github.com/magento/magento2/pull/23444) -- Fix missing attribute_id condition from filter (by @mattijv) * [magento/magento2#20579](https://github.com/magento/magento2/pull/20579) -- magento/magento2#12817: [Forwardport] Coupon code with canceled order. (by @p-bystritsky) From 54d6fa00a60a03049fc2db82193addd0850f5f71 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Tue, 27 Aug 2019 09:50:54 -0500 Subject: [PATCH 340/372] MC-19633: Disabled Products Do Not Appear in Search Results of Link Attribute - update to show all products regardless of status --- .../Catalog/Model/ProductLink/Search.php | 1 - .../Adminhtml/Product/SearchTest.php | 23 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductLink/Search.php b/app/code/Magento/Catalog/Model/ProductLink/Search.php index 681c01bb1281b..ad7f3370ab3fe 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/Search.php +++ b/app/code/Magento/Catalog/Model/ProductLink/Search.php @@ -60,7 +60,6 @@ public function prepareCollection( ): \Magento\Catalog\Model\ResourceModel\Product\Collection { $productCollection = $this->productCollectionFactory->create(); $productCollection->addAttributeToSelect(ProductInterface::NAME); - $productCollection->setVisibility($this->catalogVisibility->getVisibleInCatalogIds()); $productCollection->setPage($pageNum, $limit); $this->filter->addFilter($productCollection, 'fulltext', ['fulltext' => $searchKey]); $productCollection->setPage($pageNum, $limit); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 8a33543e93439..0704d59a1431c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -38,7 +38,8 @@ public function testExecuteNonExistingSearchKey() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('{"options":[],"total":0}', $responseBody); + $jsonResponse = json_decode($responseBody, true); + $this->assertEmpty($jsonResponse['options']); } /** @@ -57,6 +58,24 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('{"options":[],"total":0}', $responseBody); + $jsonResponse = json_decode($responseBody, true); + $this->assertEquals(1, $jsonResponse['total']); + $this->assertCount(1, $jsonResponse['options']); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/multiple_mixed_products.php + */ + public function testExecuteEnabledAndDisabledProducts() : void + { + $this->getRequest() + ->setPostValue('searchKey', 'simple') + ->setPostValue('page', 1) + ->setPostValue('limit', 50); + $this->dispatch('backend/catalog/product/search'); + $responseBody = $this->getResponse()->getBody(); + $jsonResponse = json_decode($responseBody, true); + $this->assertEquals(7, $jsonResponse['total']); + $this->assertCount(7, $jsonResponse['options']); } } From 60dc36c70b9de9a03bf3554c1f01be9e11bd2818 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Tue, 27 Aug 2019 16:48:47 -0500 Subject: [PATCH 341/372] MC-19633: Disabled Products Do Not Appear in Search Results of Link Attribute - fix test --- .../Catalog/Controller/Adminhtml/Product/SearchTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 0704d59a1431c..cfa8b6022963e 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -75,7 +75,7 @@ public function testExecuteEnabledAndDisabledProducts() : void $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); $jsonResponse = json_decode($responseBody, true); - $this->assertEquals(7, $jsonResponse['total']); - $this->assertCount(7, $jsonResponse['options']); + $this->assertEquals(6, $jsonResponse['total']); + $this->assertCount(6, $jsonResponse['options']); } } From bfd31af036aa66fff3a4fcbe9c1f5ce4f66ec6f3 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 28 Aug 2019 10:45:22 -0500 Subject: [PATCH 342/372] MC-19684: Some minute values cannot be set for Analytics data collection --- .../AdminConfigurationTimeToSendDataTest.xml | 6 +-- .../Block/Agreement/Edit/AgreementsForm.xml | 2 +- .../Customer/Test/Block/Form/CustomerForm.php | 2 +- .../Block/Adminhtml/Queue/Edit/QueueForm.xml | 2 +- .../Block/Adminhtml/Sales/Coupons/Filter.xml | 2 +- .../Block/Adminhtml/Sales/TaxRule/Filter.xml | 2 +- .../Adminhtml/Rating/Edit/RatingForm.xml | 2 +- .../Block/Adminhtml/Report/Filter/Form.xml | 2 +- lib/web/mage/validation.js | 45 ------------------- lib/web/mage/validation/validation.js | 22 ++++----- 10 files changed, 18 insertions(+), 69 deletions(-) diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml index 58e62500b8203..8ebd8cb594bee 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml @@ -25,9 +25,9 @@ <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> - <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingHour}}" userInput="11" stepKey="selectAdvancedReportingHour"/> - <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingMinute}}" userInput="11" stepKey="selectAdvancedReportingMinute"/> - <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingSeconds}}" userInput="00" stepKey="selectAdvancedReportingSeconds"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingHour}}" userInput="23" stepKey="selectAdvancedReportingHour"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingMinute}}" userInput="59" stepKey="selectAdvancedReportingMinute"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingSeconds}}" userInput="59" stepKey="selectAdvancedReportingSeconds"/> <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton"/> <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess"/> </test> diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Block/Adminhtml/Block/Agreement/Edit/AgreementsForm.xml b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Block/Adminhtml/Block/Agreement/Edit/AgreementsForm.xml index 95d99f9fa76cd..f98f9ca7cfe24 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Block/Adminhtml/Block/Agreement/Edit/AgreementsForm.xml +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Block/Adminhtml/Block/Agreement/Edit/AgreementsForm.xml @@ -18,7 +18,7 @@ <input>select</input> </mode> <stores> - <selector>[name="stores[0]"]</selector> + <selector>[name="stores[]"]</selector> <input>multiselectgrouplist</input> </stores> <checkbox_text /> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php index 61166339475b7..dc1e901a3feae 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php @@ -29,7 +29,7 @@ class CustomerForm extends Form * * @var string */ - protected $customerAttribute = "[orig-name='%s[]']"; + protected $customerAttribute = "[name='%s[]']"; /** * Validation text message for a field. diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Queue/Edit/QueueForm.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Queue/Edit/QueueForm.xml index 4d2acc76c8703..c1970955013e8 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Queue/Edit/QueueForm.xml +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Queue/Edit/QueueForm.xml @@ -11,7 +11,7 @@ <selector>input[name='start_at']</selector> </queue_start_at> <stores> - <selector>select[name="stores[0]"]</selector> + <selector>select[name="stores[]"]</selector> <input>multiselectgrouplist</input> </stores> <newsletter_subject> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.xml index 51809448e4edb..d66c3b702f076 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.xml @@ -29,7 +29,7 @@ <input>select</input> </price_rule_type> <order_statuses> - <selector>[name="order_statuses[0]"]</selector> + <selector>[name="order_statuses[]"]</selector> <input>multiselect</input> </order_statuses> <rules_list> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/TaxRule/Filter.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/TaxRule/Filter.xml index 5820de6772e1c..08e783e1329a4 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/TaxRule/Filter.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/TaxRule/Filter.xml @@ -23,7 +23,7 @@ <input>select</input> </show_order_statuses> <order_statuses> - <selector>[name="order_statuses[0]"]</selector> + <selector>[name="order_statuses[]"]</selector> <input>multiselect</input> </order_statuses> <show_empty_rows> diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml index 504ce64bf2a73..3e1a1c727c668 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml +++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml @@ -12,7 +12,7 @@ <strategy>css selector</strategy> <fields> <stores> - <selector>[name="stores[0]"]</selector> + <selector>[name="stores[]"]</selector> <input>multiselectgrouplist</input> </stores> <is_active> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Report/Filter/Form.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Report/Filter/Form.xml index 294f64966bde9..d868798eba79d 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Report/Filter/Form.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Report/Filter/Form.xml @@ -26,7 +26,7 @@ <input>select</input> </show_order_statuses> <order_statuses> - <selector>[name="order_statuses[0]"]</selector> + <selector>[name="order_statuses[]"]</selector> <input>multiselect</input> </order_statuses> <show_actual_columns> diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index b284f0002bc66..55921c054e61a 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1925,7 +1925,6 @@ * @protected */ _create: function () { - this._prepareArrayInputs(); this.validate = this.element.validate(this.options); // ARIA (adding aria-required attribute) @@ -1938,50 +1937,6 @@ this._listenFormValidate(); }, - /** - * Validation creation. - * - * @protected - */ - _prepareArrayInputs: function () { - /* Store original names for array inputs */ - var originalElements = [], - originalSubmitHandler = this.options.submitHandler; - - /* For all array inputs, assign index so that validation is proper */ - this.element.find('[name$="[]"]').each(function (key, input) { - var originalName, name; - - input = $(input); - originalName = input.attr('name'); - name = originalName.replace('[]', '[' + key + ']'); - $(input).attr('name', name); - $(input).attr('orig-name', originalName); - originalElements.push({ - element: $(input), - name: originalName - }); - }); - - if (originalElements.length) { - /** - * Before submitting the actual form, remove the previously assigned indices - * @param {Object} form - */ - this.options.submitHandler = function (form) { - originalElements.forEach(function (element) { - element.element.attr('name', element.name); - element.element.removeAttr('orig-name'); - }); - - console.error(this.submit); - - /* Call the originalSubmitHandler if it's a function */ - typeof originalSubmitHandler === 'function' ? originalSubmitHandler(form) : form.submit(); - }; - } - }, - /** * Validation listening. * diff --git a/lib/web/mage/validation/validation.js b/lib/web/mage/validation/validation.js index 69cb984b0d82d..74b00e34e9160 100644 --- a/lib/web/mage/validation/validation.js +++ b/lib/web/mage/validation/validation.js @@ -49,23 +49,17 @@ 'validate-one-checkbox-required-by-name': [ function (value, element, params) { var checkedCount = 0, - selector, - container, - origNameSelector, - nameSelector; + container; if (element.type === 'checkbox') { - /* If orig-name attribute is present, use it for validation. Else use name */ - origNameSelector = '[orig-name="' + element.getAttribute('orig-name') + '"]'; - nameSelector = '[name="' + element.name + '"]'; - selector = element.getAttribute('orig-name') ? origNameSelector : nameSelector; - $(selector).each(function () { - if ($(this).is(':checked')) { - checkedCount += 1; - - return false; + $('[name="' + element.name + '"]').each( + function () { + if ($(this).is(':checked')) { + checkedCount += 1; + return false; + } } - }); + ); } container = '#' + params; From eba1d8dfff69a3c4eef6fa63e593b5f384adda27 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 28 Aug 2019 11:41:53 -0500 Subject: [PATCH 343/372] MC-19684: Some minute values cannot be set for Analytics data collection --- lib/web/mage/validation/validation.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/web/mage/validation/validation.js b/lib/web/mage/validation/validation.js index 74b00e34e9160..0f2c4c06b119b 100644 --- a/lib/web/mage/validation/validation.js +++ b/lib/web/mage/validation/validation.js @@ -56,6 +56,7 @@ function () { if ($(this).is(':checked')) { checkedCount += 1; + return false; } } From 973eb86f7b4157e2452201039416f617ae58cdb5 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Fri, 30 Aug 2019 13:26:20 -0500 Subject: [PATCH 344/372] MQE-1715: .credentials file must exist but it should not have to --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 8b2cb0b53972a..e4596256f4427 100644 --- a/composer.json +++ b/composer.json @@ -88,7 +88,7 @@ "friendsofphp/php-cs-fixer": "~2.14.0", "lusitanian/oauth": "~0.8.10", "magento/magento-coding-standard": "~3.0.0", - "magento/magento2-functional-testing-framework": "2.4.4", + "magento/magento2-functional-testing-framework": "2.4.5", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 8af9ead67d9c1..ae4219a2fd5dd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8819d140d0951fefd8e14b052ff0f61a", + "content-hash": "d6f99cc06f1aa39a903b382958676ba2", "packages": [ { "name": "braintree/braintree_php", @@ -6814,16 +6814,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.4.4", + "version": "2.4.5", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "ab347cf23d01f6bb9d158ab37d2dc56594999beb" + "reference": "d9de524babec36919b3ef73f3af03fbce99d427a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/ab347cf23d01f6bb9d158ab37d2dc56594999beb", - "reference": "ab347cf23d01f6bb9d158ab37d2dc56594999beb", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/d9de524babec36919b3ef73f3af03fbce99d427a", + "reference": "d9de524babec36919b3ef73f3af03fbce99d427a", "shasum": "" }, "require": { @@ -6885,7 +6885,7 @@ "magento", "testing" ], - "time": "2019-08-15T14:46:36+00:00" + "time": "2019-08-30T18:17:27+00:00" }, { "name": "mikey179/vfsstream", From f577a003344330ab97b606117e1f8f92d0ec1faf Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 30 Aug 2019 16:55:43 -0500 Subject: [PATCH 345/372] MC-19740: Set of InnoDB tables is converted to Memory tables after setup:upgrade --- .../Patch/Schema/ChangeTmpTablesEngine.php | 68 ----------------- app/code/Magento/Bundle/etc/db_schema.xml | 6 +- .../Patch/Schema/ChangeTmpTablesEngine.php | 74 ------------------- app/code/Magento/Catalog/etc/db_schema.xml | 38 +++++----- .../Patch/Schema/ChangeTmpTablesEngine.php | 61 --------------- .../CatalogInventory/etc/db_schema.xml | 6 +- .../Patch/Schema/ChangeTmpTablesEngine.php | 61 --------------- .../Magento/Downloadable/etc/db_schema.xml | 2 +- 8 files changed, 26 insertions(+), 290 deletions(-) delete mode 100644 app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php diff --git a/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index c6a67cc5a110c..0000000000000 --- a/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Bundle\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tables = [ - 'catalog_product_index_price_bundle_tmp', - 'catalog_product_index_price_bundle_sel_tmp', - 'catalog_product_index_price_bundle_opt_tmp', - ]; - foreach ($tables as $table) { - $tableName = $this->schemaSetup->getTable($table); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Bundle/etc/db_schema.xml b/app/code/Magento/Bundle/etc/db_schema.xml index 97e86e5c17359..ade8fbf7cf1ce 100644 --- a/app/code/Magento/Bundle/etc/db_schema.xml +++ b/app/code/Magento/Bundle/etc/db_schema.xml @@ -203,7 +203,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -265,7 +265,7 @@ <column name="selection_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_sel_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_sel_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Sel Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -320,7 +320,7 @@ <column name="option_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Opt Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> diff --git a/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index c39247f9b30df..0000000000000 --- a/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Catalog\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tables = [ - 'catalog_product_index_price_cfg_opt_agr_tmp', - 'catalog_product_index_price_cfg_opt_tmp', - 'catalog_product_index_price_final_tmp', - 'catalog_product_index_price_opt_tmp', - 'catalog_product_index_price_opt_agr_tmp', - 'catalog_product_index_eav_tmp', - 'catalog_product_index_eav_decimal_tmp', - 'catalog_product_index_price_tmp', - 'catalog_category_product_index_tmp', - ]; - foreach ($tables as $table) { - $tableName = $this->schemaSetup->getTable($table); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 6fef4ca6e9128..b5e02b1daaa01 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -1238,7 +1238,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_cfg_opt_agr_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_cfg_opt_agr_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Config Option Aggregate Temp Table"> <column xsi:type="int" name="parent_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Parent ID"/> @@ -1279,7 +1279,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_cfg_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_cfg_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Config Option Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1327,7 +1327,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_final_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_final_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Final Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1375,7 +1375,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Option Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1418,7 +1418,7 @@ <column name="option_id"/> </constraint> </table> - <table name="catalog_product_index_price_opt_agr_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_opt_agr_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Option Aggregate Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1470,7 +1470,7 @@ <column name="value"/> </index> </table> - <table name="catalog_product_index_eav_tmp" resource="default" engine="memory" + <table name="catalog_product_index_eav_tmp" resource="default" engine="innodb" comment="Catalog Product EAV Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1489,13 +1489,13 @@ <column name="value"/> <column name="source_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1528,7 +1528,7 @@ <column name="value"/> </index> </table> - <table name="catalog_product_index_eav_decimal_tmp" resource="default" engine="memory" + <table name="catalog_product_index_eav_decimal_tmp" resource="default" engine="innodb" comment="Catalog Product EAV Decimal Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1547,13 +1547,13 @@ <column name="value"/> <column name="source_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1592,7 +1592,7 @@ <column name="min_price"/> </index> </table> - <table name="catalog_product_index_price_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1617,17 +1617,17 @@ <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> </table> - <table name="catalog_category_product_index_tmp" resource="default" engine="memory" + <table name="catalog_category_product_index_tmp" resource="default" engine="innodb" comment="Catalog Category Product Indexer temporary table"> <column xsi:type="int" name="category_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Category ID"/> @@ -1646,7 +1646,7 @@ <column name="product_id"/> <column name="store_id"/> </constraint> - <index referenceId="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="hash"> + <index referenceId="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="btree"> <column name="product_id"/> <column name="category_id"/> <column name="store_id"/> diff --git a/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index 7f43cd279d4e3..0000000000000 --- a/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogInventory\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tableName = $this->schemaSetup->getTable('cataloginventory_stock_status_tmp'); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/CatalogInventory/etc/db_schema.xml b/app/code/Magento/CatalogInventory/etc/db_schema.xml index 5ac7fedc5aa18..67a200eb37125 100644 --- a/app/code/Magento/CatalogInventory/etc/db_schema.xml +++ b/app/code/Magento/CatalogInventory/etc/db_schema.xml @@ -142,7 +142,7 @@ <column name="website_id"/> </index> </table> - <table name="cataloginventory_stock_status_tmp" resource="default" engine="memory" + <table name="cataloginventory_stock_status_tmp" resource="default" engine="innodb" comment="Cataloginventory Stock Status Indexer Tmp"> <column xsi:type="int" name="product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Product Id"/> @@ -159,10 +159,10 @@ <column name="website_id"/> <column name="stock_id"/> </constraint> - <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index caf2f7745a3dd..0000000000000 --- a/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Downloadable\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tableName = $this->schemaSetup->getTable('catalog_product_index_price_downlod_tmp'); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Downloadable/etc/db_schema.xml b/app/code/Magento/Downloadable/etc/db_schema.xml index ccbefa4fb3992..ee7b3c5683ea1 100644 --- a/app/code/Magento/Downloadable/etc/db_schema.xml +++ b/app/code/Magento/Downloadable/etc/db_schema.xml @@ -233,7 +233,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_downlod_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_downlod_tmp" resource="default" engine="innodb" comment="Temporary Indexer Table for price of downloadable products"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> From 2bdab9af3c6bf0c7df63fb148ce1d396e97ab322 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 9 Sep 2019 11:56:03 -0500 Subject: [PATCH 346/372] MC-18532: Update Changelog based on delivered scope - remove reverts and fix minor issues --- CHANGELOG.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24e445b043bfa..59adb577b0cd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ * [#22527](https://github.com/magento/magento2/issues/22527) -- Wishlist and compare icon align issue in product listing page (fixed in [magento/magento2#22532](https://github.com/magento/magento2/pull/22532)) * [#628](https://github.com/magento/magento2/issues/628) -- Feature Request: Parent entities links in child entities grid. (fixed in [magento/graphql-ce#636](https://github.com/magento/graphql-ce/pull/636)) * [#640](https://github.com/magento/magento2/issues/640) -- [Insight] Files should not be executable (fixed in [magento/graphql-ce#648](https://github.com/magento/graphql-ce/pull/648)) - * [#603](https://github.com/magento/magento2/issues/603) -- 'Continue' button is disabled even though 'I've read OSL licence' is checked (fixed in [magento/graphql-ce#653](https://github.com/magento/graphql-ce/pull/653)) + * [#603](https://github.com/magento/magento2/issues/603) -- 'Continue' button is disabled even though "I've read OSL licence" is checked (fixed in [magento/graphql-ce#653](https://github.com/magento/graphql-ce/pull/653)) * [#22406](https://github.com/magento/magento2/issues/22406) -- Store view specific labels cut in left navigation menu (fixed in [magento/magento2#22423](https://github.com/magento/magento2/pull/22423)) * [#19515](https://github.com/magento/magento2/issues/19515) -- Create new order from backend saves the credit card when it is told not to (fixed in [magento/magento2#19767](https://github.com/magento/magento2/pull/19767)) * [#21473](https://github.com/magento/magento2/issues/21473) -- Form element validation is not triggered when validation rules change (fixed in [magento/magento2#21992](https://github.com/magento/magento2/pull/21992)) @@ -93,7 +93,7 @@ * [#22004](https://github.com/magento/magento2/issues/22004) -- ce231 - can't update attribute for all product (fixed in [magento/magento2#22704](https://github.com/magento/magento2/pull/22704)) * [#22870](https://github.com/magento/magento2/issues/22870) -- ProductRepository fails to update an existing product with a changed SKU (fixed in [magento/magento2#22933](https://github.com/magento/magento2/pull/22933)) * [#22808](https://github.com/magento/magento2/issues/22808) -- php bin/magento catalog:image:resize error if image is missing (fixed in [magento/magento2#23005](https://github.com/magento/magento2/pull/23005)) - * [#674](https://github.com/magento/magento2/issues/674) -- Widgets in content pages. (fixed in [magento/graphql-ce#709](https://github.com/magento/graphql-ce/pull/709)) + * [#674](https://github.com/magento/magento2/issues/674) -- Widgets in content pages. (fixed in [magento/graphql-ce#709](https://github.com/magento/graphql-ce/pull/709)) * [#683](https://github.com/magento/magento2/issues/683) -- CMS Router not routing correctly (fixed in [magento/graphql-ce#717](https://github.com/magento/graphql-ce/pull/717)) * [#9113](https://github.com/magento/magento2/issues/9113) -- [Bug or Feature?] url_path attribute value is not populated for any product (fixed in [magento/graphql-ce#721](https://github.com/magento/graphql-ce/pull/721)) * [#18337](https://github.com/magento/magento2/issues/18337) -- #search input is missing required attribute aria-expanded. (fixed in [magento/magento2#22942](https://github.com/magento/magento2/pull/22942)) @@ -137,8 +137,6 @@ * [#16234](https://github.com/magento/magento2/issues/16234) -- Unable to enter `+` character in widget content (fixed in [magento/magento2#23496](https://github.com/magento/magento2/pull/23496)) * [#9798](https://github.com/magento/magento2/issues/9798) -- Problem adding attribute options to configurable product via REST Api (fixed in [magento/magento2#23529](https://github.com/magento/magento2/pull/23529)) * [#6287](https://github.com/magento/magento2/issues/6287) -- Customer Admin Shopping Cart View Missing (fixed in [magento/magento2#20918](https://github.com/magento/magento2/pull/20918)) - * [#8258](https://github.com/magento/magento2/issues/8258) -- M2.1.3 : Form validation with identical field names does not work as expected. (fixed in [magento/magento2#15383](https://github.com/magento/magento2/pull/15383)) - * [#13561](https://github.com/magento/magento2/issues/13561) -- Magento 2 and SSL connection to MySQL (fixed in [magento/magento2#18075](https://github.com/magento/magento2/pull/18075)) * [#22545](https://github.com/magento/magento2/issues/22545) -- Status downloadable product stays pending after succesfull payment (fixed in [magento/magento2#22658](https://github.com/magento/magento2/pull/22658)) * [#23383](https://github.com/magento/magento2/issues/23383) -- Products which are not assigned to any store are automatically being force-assigned a store ID after being saved (fixed in [magento/magento2#23500](https://github.com/magento/magento2/pull/23500)) * [#22950](https://github.com/magento/magento2/issues/22950) -- Spacing issue for Gift message section in my account (fixed in [magento/magento2#23226](https://github.com/magento/magento2/pull/23226)) @@ -181,7 +179,7 @@ * [#23916](https://github.com/magento/magento2/issues/23916) -- Missing Validation at some Payment Method Settings (fixed in [magento/magento2#23917](https://github.com/magento/magento2/pull/23917)) * [#23932](https://github.com/magento/magento2/issues/23932) -- Decimal quantity is not displayed for wishlist items. (fixed in [magento/magento2#23933](https://github.com/magento/magento2/pull/23933)) * GitHub pull requests: - * [magento/magento2#20135](https://github.com/magento/magento2/pull/20135) -- issue fixed #20124 Sort By label is hidden by Shop By Menu on listing… (by @cedarvinda) + * [magento/magento2#20135](https://github.com/magento/magento2/pull/20135) -- issue fixed #20124 Sort By label is hidden by Shop By Menu on listing (by @cedarvinda) * [magento/magento2#22020](https://github.com/magento/magento2/pull/22020) -- Non existing file, when adding image to gallery with move option. Fix for #21978 (by @dudzio12) * [magento/magento2#22260](https://github.com/magento/magento2/pull/22260) -- Disabling "Display on Product Details Page" the button is shown anyway. (by @Nazar65) * [magento/magento2#22287](https://github.com/magento/magento2/pull/22287) -- #222249 configurable product images wrong sorting fix (by @Wirson) @@ -295,7 +293,6 @@ * [magento/magento2#21876](https://github.com/magento/magento2/pull/21876) -- $product->getUrlInStore() does not allow to override the scope in backend context (by @Nazar65) * [magento/magento2#23007](https://github.com/magento/magento2/pull/23007) -- [Fixed] Reset feature does not clear the date (by @niravkrish) * [magento/magento2#23118](https://github.com/magento/magento2/pull/23118) -- #23053 : sendfriend verifies product visibility instead of status (by @Wirson) - * [magento/magento2#18748](https://github.com/magento/magento2/pull/18748) -- Add a module manager to the Magento Framework API (by @navarr) * [magento/magento2#22637](https://github.com/magento/magento2/pull/22637) -- Fixed #22484 Customer address States are duplicated in backend (by @shikhamis11) * [magento/magento2#23140](https://github.com/magento/magento2/pull/23140) -- magento/magento2#23138: Magento_Theme. Incorrect configuration file location (by @atwixfirster) * [magento/magento2#23179](https://github.com/magento/magento2/pull/23179) -- Fix for translation function (by @kkdg) @@ -361,8 +358,6 @@ * [magento/magento2#23529](https://github.com/magento/magento2/pull/23529) -- Feature/9798 updating configurable product options based on produc id and sku (by @lpouwelse) * [magento/magento2#20918](https://github.com/magento/magento2/pull/20918) -- Enabled 'Shopping Cart' tab for customer edit interface in admin (by @rav-redchamps) * [magento/magento2#22624](https://github.com/magento/magento2/pull/22624) -- Resolve Typo (by @prashantsharmacedcoss) - * [magento/magento2#15383](https://github.com/magento/magento2/pull/15383) -- issue fixed #8258 - assign indices for all array inputs so that validation works properly (by @jayankaghosh) - * [magento/magento2#18075](https://github.com/magento/magento2/pull/18075) -- Feature/issue 13561 2.3 (by @bnymn) * [magento/magento2#22658](https://github.com/magento/magento2/pull/22658) -- Fixed #22545 Status downloadable product stays pending after succesfu... (by @shikhamis11) * [magento/magento2#23500](https://github.com/magento/magento2/pull/23500) -- Fixed issue #23383 (by @manishgoswamij) * [magento/magento2#23226](https://github.com/magento/magento2/pull/23226) -- Spacing issue for Gift message section in my account (by @amjadm61) From 1d284ef7a3ef63e0a68918c613b935833a8f3794 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Fri, 13 Sep 2019 22:31:47 -0700 Subject: [PATCH 347/372] MC-19873: [Sample Data Function Test] Sample data test failed with Incorrect final price --- .../Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php index e589c8595ce2c..944710773123f 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php @@ -101,7 +101,9 @@ public function execute(Rule $rule, $batchCount, $useAdditionalTable = false) $scopeTz = new \DateTimeZone( $this->localeDate->getConfigTimezone(ScopeInterface::SCOPE_WEBSITE, $websiteId) ); - $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp(); + $fromTime = $rule->getFromDate() + ? (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp() + : 0; $toTime = $rule->getToDate() ? (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp() + IndexBuilder::SECONDS_IN_DAY - 1 : 0; From 35f317b91afbe60c27c7a6a6331a3ae4ca7dcfc1 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Sat, 14 Sep 2019 06:45:26 +0000 Subject: [PATCH 348/372] MC-19873: [Sample Data Function Test] Sample data test failed with Incorrect final price --- .../Controller/Adminhtml/Promo/Catalog/Save.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 4f58293d53359..996fc4e8ef3d2 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -12,6 +12,7 @@ use Magento\Framework\Registry; use Magento\Framework\Stdlib\DateTime\Filter\Date; use Magento\Framework\App\Request\DataPersistorInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; /** * Save action for catalog rule @@ -25,19 +26,27 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog imple */ protected $dataPersistor; + /** + * @var TimezoneInterface + */ + private $localeDate; + /** * @param Context $context * @param Registry $coreRegistry * @param Date $dateFilter * @param DataPersistorInterface $dataPersistor + * @param TimezoneInterface $localeDate */ public function __construct( Context $context, Registry $coreRegistry, Date $dateFilter, - DataPersistorInterface $dataPersistor + DataPersistorInterface $dataPersistor, + TimezoneInterface $localeDate ) { $this->dataPersistor = $dataPersistor; + $this->localeDate = $localeDate; parent::__construct($context, $coreRegistry, $dateFilter); } @@ -66,6 +75,9 @@ public function execute() ); $data = $this->getRequest()->getPostValue(); + if (!$this->getRequest()->getParam('from_date')) { + $data['from_date'] = $this->localeDate->formatDate(); + } $filterValues = ['from_date' => $this->_dateFilter]; if ($this->getRequest()->getParam('to_date')) { $filterValues['to_date'] = $this->_dateFilter; From 6d7daa454c8f45669e13e17dddddc8ecbfbdd25d Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Sat, 14 Sep 2019 05:30:16 +0000 Subject: [PATCH 349/372] MC-19873: [Sample Data Function Test] Sample data test failed with Incorrect final price --- .../CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 996fc4e8ef3d2..6d499b93e411f 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -55,16 +55,15 @@ public function __construct( * * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute() { if ($this->getRequest()->getPostValue()) { - /** @var \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface $ruleRepository */ $ruleRepository = $this->_objectManager->get( \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface::class ); - /** @var \Magento\CatalogRule\Model\Rule $model */ $model = $this->_objectManager->create(\Magento\CatalogRule\Model\Rule::class); @@ -74,7 +73,6 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); - if (!$this->getRequest()->getParam('from_date')) { $data['from_date'] = $this->localeDate->formatDate(); } From 06ebc664bb2351e7128f4f8e55e1014e5d548f4e Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 18 Sep 2019 11:41:42 -0500 Subject: [PATCH 350/372] MC-20235: [2.3.3]Revert unapproved PR --- .../Adminhtml/Promo/Catalog/Save.php | 18 ++++-------------- .../Model/Indexer/ReindexRuleProduct.php | 4 +--- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 6d499b93e411f..4f58293d53359 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -12,7 +12,6 @@ use Magento\Framework\Registry; use Magento\Framework\Stdlib\DateTime\Filter\Date; use Magento\Framework\App\Request\DataPersistorInterface; -use Magento\Framework\Stdlib\DateTime\TimezoneInterface; /** * Save action for catalog rule @@ -26,27 +25,19 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog imple */ protected $dataPersistor; - /** - * @var TimezoneInterface - */ - private $localeDate; - /** * @param Context $context * @param Registry $coreRegistry * @param Date $dateFilter * @param DataPersistorInterface $dataPersistor - * @param TimezoneInterface $localeDate */ public function __construct( Context $context, Registry $coreRegistry, Date $dateFilter, - DataPersistorInterface $dataPersistor, - TimezoneInterface $localeDate + DataPersistorInterface $dataPersistor ) { $this->dataPersistor = $dataPersistor; - $this->localeDate = $localeDate; parent::__construct($context, $coreRegistry, $dateFilter); } @@ -55,15 +46,16 @@ public function __construct( * * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute() { if ($this->getRequest()->getPostValue()) { + /** @var \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface $ruleRepository */ $ruleRepository = $this->_objectManager->get( \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface::class ); + /** @var \Magento\CatalogRule\Model\Rule $model */ $model = $this->_objectManager->create(\Magento\CatalogRule\Model\Rule::class); @@ -73,9 +65,7 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); - if (!$this->getRequest()->getParam('from_date')) { - $data['from_date'] = $this->localeDate->formatDate(); - } + $filterValues = ['from_date' => $this->_dateFilter]; if ($this->getRequest()->getParam('to_date')) { $filterValues['to_date'] = $this->_dateFilter; diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php index 944710773123f..e589c8595ce2c 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php @@ -101,9 +101,7 @@ public function execute(Rule $rule, $batchCount, $useAdditionalTable = false) $scopeTz = new \DateTimeZone( $this->localeDate->getConfigTimezone(ScopeInterface::SCOPE_WEBSITE, $websiteId) ); - $fromTime = $rule->getFromDate() - ? (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp() - : 0; + $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp(); $toTime = $rule->getToDate() ? (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp() + IndexBuilder::SECONDS_IN_DAY - 1 : 0; From 37f6f6a6adc20fd2b72836116b48c8a5bfcd0cd8 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 9 Oct 2019 10:23:20 -0500 Subject: [PATCH 351/372] MC-18527: Merge release branch into 2.3-develop - fix merge conflicts and update lock file --- app/code/Magento/Catalog/Model/Product.php | 6 ++-- .../Config/Test/Mftf/Page/AdminConfigPage.xml | 3 ++ .../Form/Modifier/Data/AssociatedProducts.php | 8 ++++- app/code/Magento/Customer/Model/Customer.php | 11 +++--- app/code/Magento/Customer/Model/Session.php | 7 ++-- ...AddDefaultImageDownloadableProductTest.xml | 2 ++ app/code/Magento/Store/Model/System/Store.php | 6 ++++ composer.json | 1 + composer.lock | 34 +++++++++---------- .../Magento/Framework/App/ProductMetadata.php | 22 ++++++------ 10 files changed, 63 insertions(+), 37 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 1b7552c82276d..8092ff3eb9d4a 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -177,7 +177,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements protected $_catalogProduct = null; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -381,7 +381,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements * @param Product\Attribute\Source\Status $catalogProductStatus * @param Product\Media\Config $catalogProductMediaConfig * @param Product\Type $catalogProductType - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Helper\Product $catalogProduct * @param ResourceModel\Product $resource * @param ResourceModel\Product\Collection $resourceCollection @@ -422,7 +422,7 @@ public function __construct( \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus, \Magento\Catalog\Model\Product\Media\Config $catalogProductMediaConfig, Product\Type $catalogProductType, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Helper\Product $catalogProduct, \Magento\Catalog\Model\ResourceModel\Product $resource, \Magento\Catalog\Model\ResourceModel\Product\Collection $resourceCollection, diff --git a/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml b/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml index 8fafdc202bf09..a1ee5348d094c 100644 --- a/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml +++ b/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml @@ -24,4 +24,7 @@ <page name="AdminConfigDeveloperPage" url="admin/system_config/edit/section/dev/" area="admin" module="Magento_Config"> <section name="AdminConfigSection" /> </page> + <page name="AdminConfigAdvancedAdmin" url="admin/system_config/edit/section/admin/" area="admin" module="Magento_Config"> + <section name="AdvanceAdminSection"/> + </page> </pages> diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php index 4bde97fa8022a..ec69baeb92cb9 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php @@ -215,6 +215,7 @@ public function getConfigurableAttributesData() 'code' => $attribute['code'], 'label' => $attribute['label'], 'position' => $attribute['position'], + '__disableTmpl' => true ]; foreach ($attribute['chosen'] as $chosenOption) { @@ -234,7 +235,7 @@ public function getConfigurableAttributesData() * @return void * @throws \Zend_Currency_Exception * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * phpcs:disable Generic.Metrics.NestingLevel + * phpcs:disable Generic.Metrics.NestingLevel.TooHigh */ protected function prepareVariations() { @@ -265,6 +266,7 @@ protected function prepareVariations() 'id' => $attribute->getAttributeId(), 'position' => $configurableAttributes[$attribute->getAttributeId()]['position'], 'chosen' => [], + '__disableTmpl' => true ]; $options = $attribute->usesSource() ? $attribute->getSource()->getAllOptions() : []; foreach ($options as $option) { @@ -275,6 +277,7 @@ protected function prepareVariations() 'id' => $option['value'], 'label' => $option['label'], 'value' => $option['value'], + '__disableTmpl' => true ]; } } @@ -286,6 +289,7 @@ protected function prepareVariations() 'id' => $optionId, 'label' => $variation[$attribute->getId()]['label'], 'value' => $optionId, + '__disableTmpl' => true ]; $variationOptions[] = $variationOption; $attributes[$attribute->getAttributeId()]['chosen'][$optionId] = $variationOption; @@ -311,6 +315,7 @@ protected function prepareVariations() 'newProduct' => 0, 'attributes' => $this->getTextAttributes($variationOptions), 'thumbnail_image' => $this->imageHelper->init($product, 'product_thumbnail_image')->getUrl(), + '__disableTmpl' => true ]; $productIds[] = $product->getId(); } @@ -321,6 +326,7 @@ protected function prepareVariations() $this->productIds = $productIds; $this->productAttributes = array_values($attributes); } + //phpcs: enable /** * Get JSON string that contains attribute code and value diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index 1f8f7d90f6d0d..2692d1edf0143 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -20,6 +20,7 @@ use Magento\Framework\Reflection\DataObjectProcessor; use Magento\Store\Model\ScopeInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Math\Random; /** * Customer model @@ -180,7 +181,7 @@ class Customer extends \Magento\Framework\Model\AbstractModel protected $_encryptor; /** - * @var \Magento\Framework\Math\Random + * @var Random */ protected $mathRandom; @@ -248,6 +249,7 @@ class Customer extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data * @param AccountConfirmation|null $accountConfirmation + * @param Random|null $mathRandom * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -272,7 +274,8 @@ public function __construct( \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - AccountConfirmation $accountConfirmation = null + AccountConfirmation $accountConfirmation = null, + Random $mathRandom = null ) { $this->metadataService = $metadataService; $this->_scopeConfig = $scopeConfig; @@ -291,6 +294,7 @@ public function __construct( $this->indexerRegistry = $indexerRegistry; $this->accountConfirmation = $accountConfirmation ?: ObjectManager::getInstance() ->get(AccountConfirmation::class); + $this->mathRandom = $mathRandom ?: ObjectManager::getInstance()->get(Random::class); parent::__construct( $context, $registry, @@ -815,8 +819,7 @@ public function isConfirmationRequired() */ public function getRandomConfirmationKey() { - // phpcs:ignore Magento2.Security.InsecureFunction - return md5(uniqid()); + return $this->mathRandom->getRandomString(32); } /** diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php index 047327a0b6c29..36b8fa9764c95 100644 --- a/app/code/Magento/Customer/Model/Session.php +++ b/app/code/Magento/Customer/Model/Session.php @@ -370,7 +370,9 @@ public function setCustomerGroupId($id) } /** - * Get customer group id. If customer is not logged in system, 'not logged in' group id will be returned. + * Get customer group id. + * + * If customer is not logged in system, 'not logged in' group id will be returned. * * @return int * @throws \Magento\Framework\Exception\LocalizedException @@ -431,10 +433,10 @@ public function checkCustomerId($customerId) */ public function setCustomerAsLoggedIn($customer) { + $this->regenerateId(); $this->setCustomer($customer); $this->_eventManager->dispatch('customer_login', ['customer' => $customer]); $this->_eventManager->dispatch('customer_data_object_login', ['customer' => $this->getCustomerDataObject()]); - $this->regenerateId(); return $this; } @@ -446,6 +448,7 @@ public function setCustomerAsLoggedIn($customer) */ public function setCustomerDataAsLoggedIn($customer) { + $this->regenerateId(); $this->_httpContext->setValue(Context::CONTEXT_AUTH, true, false); $this->setCustomerData($customer); diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml index 64f33b01e668f..a7ce96ddf1fde 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml @@ -19,12 +19,14 @@ <group value="Downloadable"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteProduct"> <argument name="product" value="DownloadableProduct"/> </actionGroup> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> </after> diff --git a/app/code/Magento/Store/Model/System/Store.php b/app/code/Magento/Store/Model/System/Store.php index cf75f26aed9b7..744019b107247 100644 --- a/app/code/Magento/Store/Model/System/Store.php +++ b/app/code/Magento/Store/Model/System/Store.php @@ -152,6 +152,12 @@ public function getStoreValuesForForm($empty = false, $all = false) } } } + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); return $options; } diff --git a/composer.json b/composer.json index fdbfb664c9b1b..9197f045d8c99 100644 --- a/composer.json +++ b/composer.json @@ -100,6 +100,7 @@ }, "replace": { "magento/module-marketplace": "*", + "magento/module-admin-analytics": "*", "magento/module-admin-notification": "*", "magento/module-advanced-pricing-import-export": "*", "magento/module-amqp": "*", diff --git a/composer.lock b/composer.lock index 9d6805ac8be48..9d7d987e01eb1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "856f519091be654f930aa51de44332a7", + "content-hash": "e31f0f97dd4ce9c6b512037d6365fdf5", "packages": [ { "name": "braintree/braintree_php", @@ -1552,28 +1552,28 @@ "authors": [ { "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" + "role": "Lead Developer", + "email": "terrafrost@php.net" }, { "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" + "role": "Developer", + "email": "pm@datasphere.ch" }, { "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" + "role": "Developer", + "email": "bantu@phpbb.com" }, { "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" + "role": "Developer", + "email": "petrich@tronic-media.com" }, { "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" + "role": "Developer", + "email": "graham@alt-three.com" } ], "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", @@ -7924,20 +7924,20 @@ "authors": [ { "name": "Manuel Pichler", - "role": "Project Founder", "email": "github@manuel-pichler.de", - "homepage": "https://github.com/manuelpichler" + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" }, { "name": "Marc Würth", - "role": "Project Maintainer", "email": "ravage@bluewin.ch", - "homepage": "https://github.com/ravage84" + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" }, { "name": "Other contributors", - "role": "Contributors", - "homepage": "https://github.com/phpmd/phpmd/graphs/contributors" + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" } ], "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", diff --git a/lib/internal/Magento/Framework/App/ProductMetadata.php b/lib/internal/Magento/Framework/App/ProductMetadata.php index 631dba8273bcd..02861c8a224ad 100644 --- a/lib/internal/Magento/Framework/App/ProductMetadata.php +++ b/lib/internal/Magento/Framework/App/ProductMetadata.php @@ -30,9 +30,9 @@ class ProductMetadata implements ProductMetadataInterface const PRODUCT_NAME = 'Magento'; /** - * Cache key for Magento product version + * Magento version cache key */ - private const MAGENTO_PRODUCT_VERSION_CACHE_KEY = 'magento-product-version'; + const VERSION_CACHE_KEY = 'mage-version'; /** * Product version @@ -58,13 +58,16 @@ class ProductMetadata implements ProductMetadataInterface private $cache; /** + * ProductMetadata constructor. * @param ComposerJsonFinder $composerJsonFinder - * @param CacheInterface|null $cache + * @param \Magento\Framework\App\CacheInterface $cache */ - public function __construct(ComposerJsonFinder $composerJsonFinder, CacheInterface $cache = null) - { + public function __construct( + ComposerJsonFinder $composerJsonFinder, + CacheInterface $cache = null + ) { $this->composerJsonFinder = $composerJsonFinder; - $this->cache = $cache ?: ObjectManager::getInstance()->get(CacheInterface::class); + $this->cache = $cache ?? ObjectManager::getInstance()->get(CacheInterface::class); } /** @@ -74,9 +77,8 @@ public function __construct(ComposerJsonFinder $composerJsonFinder, CacheInterfa */ public function getVersion() { - if ($cachedVersion = $this->cache->load(self::MAGENTO_PRODUCT_VERSION_CACHE_KEY)) { - $this->version = $cachedVersion; - } + $versionFromCache = $this->cache->load(self::VERSION_CACHE_KEY); + $this->version = $this->version ?: $versionFromCache; if (!$this->version) { if (!($this->version = $this->getSystemPackageVersion())) { if ($this->getComposerInformation()->isMagentoRoot()) { @@ -84,8 +86,8 @@ public function getVersion() } else { $this->version = 'UNKNOWN'; } + $this->cache->save($this->version, self::VERSION_CACHE_KEY, [Config::CACHE_TAG]); } - $this->cache->save($this->version, self::MAGENTO_PRODUCT_VERSION_CACHE_KEY); } return $this->version; } From c3a3ceca90fec96d45048898f061aecf97e7bd13 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 9 Oct 2019 10:50:34 -0500 Subject: [PATCH 352/372] MC-18527: Merge release branch into 2.3-develop - fix merge conflict --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 9d7d987e01eb1..86c1269b0adea 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e31f0f97dd4ce9c6b512037d6365fdf5", + "content-hash": "8db6cec91148c8618af8fb7c56f2d063", "packages": [ { "name": "braintree/braintree_php", From 446c733f49d0c7d48c4d7d91ebe4054fddca4e4f Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 9 Oct 2019 11:45:41 -0500 Subject: [PATCH 353/372] MC-18527: Merge release branch into 2.3-develop - update lock file --- composer.lock | 1057 +++++++++++++++++++++---------------------------- 1 file changed, 456 insertions(+), 601 deletions(-) diff --git a/composer.lock b/composer.lock index 86c1269b0adea..906cee9da4764 100644 --- a/composer.lock +++ b/composer.lock @@ -201,16 +201,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.2.1", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "33810d865dd06a674130fceb729b2f279dc79e8c" + "reference": "10bb96592168a0f8e8f6dcde3532d9fa50b0b527" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/33810d865dd06a674130fceb729b2f279dc79e8c", - "reference": "33810d865dd06a674130fceb729b2f279dc79e8c", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/10bb96592168a0f8e8f6dcde3532d9fa50b0b527", + "reference": "10bb96592168a0f8e8f6dcde3532d9fa50b0b527", "shasum": "" }, "require": { @@ -253,20 +253,20 @@ "ssl", "tls" ], - "time": "2019-07-31T08:13:16+00:00" + "time": "2019-08-30T08:44:50+00:00" }, { "name": "composer/composer", - "version": "1.8.6", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "19b5f66a0e233eb944f134df34091fe1c5dfcc11" + "reference": "314aa57fdcfc942065996f59fb73a8b3f74f3fa5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/19b5f66a0e233eb944f134df34091fe1c5dfcc11", - "reference": "19b5f66a0e233eb944f134df34091fe1c5dfcc11", + "url": "https://api.github.com/repos/composer/composer/zipball/314aa57fdcfc942065996f59fb73a8b3f74f3fa5", + "reference": "314aa57fdcfc942065996f59fb73a8b3f74f3fa5", "shasum": "" }, "require": { @@ -302,7 +302,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -326,14 +326,14 @@ "homepage": "http://seld.be" } ], - "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", "homepage": "https://getcomposer.org/", "keywords": [ "autoload", "dependency", "package" ], - "time": "2019-06-11T13:03:06+00:00" + "time": "2019-08-02T18:55:33+00:00" }, { "name": "composer/semver", @@ -1110,16 +1110,16 @@ }, { "name": "monolog/monolog", - "version": "1.24.0", + "version": "1.25.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266" + "reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", - "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/70e65a5470a42cfec1a7da00d30edb6e617e8dcf", + "reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf", "shasum": "" }, "require": { @@ -1184,7 +1184,7 @@ "logging", "psr-3" ], - "time": "2018-11-05T09:00:11+00:00" + "time": "2019-09-06T13:49:17+00:00" }, { "name": "paragonie/random_compat", @@ -1233,16 +1233,16 @@ }, { "name": "paragonie/sodium_compat", - "version": "v1.10.1", + "version": "v1.11.1", "source": { "type": "git", "url": "https://github.com/paragonie/sodium_compat.git", - "reference": "5115fa44886d1c2785d2f135ef4626db868eac4b" + "reference": "a9f968bc99485f85f9303a8524c3485a7e87bc15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/5115fa44886d1c2785d2f135ef4626db868eac4b", - "reference": "5115fa44886d1c2785d2f135ef4626db868eac4b", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/a9f968bc99485f85f9303a8524c3485a7e87bc15", + "reference": "a9f968bc99485f85f9303a8524c3485a7e87bc15", "shasum": "" }, "require": { @@ -1311,20 +1311,20 @@ "secret-key cryptography", "side-channel resistant" ], - "time": "2019-07-12T16:36:59+00:00" + "time": "2019-09-12T12:05:58+00:00" }, { "name": "pelago/emogrifier", - "version": "v2.1.1", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/MyIntervals/emogrifier.git", - "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983" + "reference": "2472bc1c3a2dee8915ecc2256139c6100024332f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8ee7fb5ad772915451ed3415c1992bd3697d4983", - "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/2472bc1c3a2dee8915ecc2256139c6100024332f", + "reference": "2472bc1c3a2dee8915ecc2256139c6100024332f", "shasum": "" }, "require": { @@ -1342,7 +1342,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1355,16 +1355,6 @@ "MIT" ], "authors": [ - { - "name": "John Reeve", - "email": "jreeve@pelagodesign.com" - }, - { - "name": "Cameron Brooks" - }, - { - "name": "Jaime Prado" - }, { "name": "Oliver Klee", "email": "github@oliverklee.de" @@ -1373,9 +1363,19 @@ "name": "Zoli Szabó", "email": "zoli.szabo+github@gmail.com" }, + { + "name": "John Reeve", + "email": "jreeve@pelagodesign.com" + }, { "name": "Jake Hotson", "email": "jake@qzdesign.co.uk" + }, + { + "name": "Cameron Brooks" + }, + { + "name": "Jaime Prado" } ], "description": "Converts CSS styles into inline style attributes in your HTML code", @@ -1385,43 +1385,41 @@ "email", "pre-processing" ], - "time": "2018-12-10T10:36:30+00:00" + "time": "2019-09-04T16:07:59+00:00" }, { "name": "php-amqplib/php-amqplib", - "version": "v2.7.3", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/php-amqplib/php-amqplib.git", - "reference": "a8ba54bd35b973fc6861e4c2e105f71e9e95f43f" + "reference": "04e5366f032906d5f716890427e425e71307d3a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/a8ba54bd35b973fc6861e4c2e105f71e9e95f43f", - "reference": "a8ba54bd35b973fc6861e4c2e105f71e9e95f43f", + "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/04e5366f032906d5f716890427e425e71307d3a8", + "reference": "04e5366f032906d5f716890427e425e71307d3a8", "shasum": "" }, "require": { "ext-bcmath": "*", - "ext-mbstring": "*", - "php": ">=5.3.0" + "ext-sockets": "*", + "php": ">=5.6" }, "replace": { "videlalvaro/php-amqplib": "self.version" }, "require-dev": { - "phpdocumentor/phpdocumentor": "^2.9", - "phpunit/phpunit": "^4.8", - "scrutinizer/ocular": "^1.1", + "ext-curl": "*", + "nategood/httpful": "^0.2.20", + "phpdocumentor/phpdocumentor": "dev-master", + "phpunit/phpunit": "^5.7|^6.5|^7.0", "squizlabs/php_codesniffer": "^2.5" }, - "suggest": { - "ext-sockets": "Use AMQPSocketConnection" - }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.10-dev" } }, "autoload": { @@ -1447,6 +1445,11 @@ "name": "Raúl Araya", "email": "nubeiro@gmail.com", "role": "Maintainer" + }, + { + "name": "Luke Bakken", + "email": "luke@bakken.io", + "role": "Maintainer" } ], "description": "Formerly videlalvaro/php-amqplib. This library is a pure PHP implementation of the AMQP protocol. It's been tested against RabbitMQ.", @@ -1456,7 +1459,7 @@ "queue", "rabbitmq" ], - "time": "2018-04-30T03:54:54+00:00" + "time": "2019-08-08T18:28:18+00:00" }, { "name": "phpseclib/mcrypt_compat", @@ -1509,16 +1512,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.21", + "version": "2.0.23", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "9f1287e68b3f283339a9f98f67515dd619e5bf9d" + "reference": "c78eb5058d5bb1a183133c36d4ba5b6675dfa099" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/9f1287e68b3f283339a9f98f67515dd619e5bf9d", - "reference": "9f1287e68b3f283339a9f98f67515dd619e5bf9d", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c78eb5058d5bb1a183133c36d4ba5b6675dfa099", + "reference": "c78eb5058d5bb1a183133c36d4ba5b6675dfa099", "shasum": "" }, "require": { @@ -1552,28 +1555,28 @@ "authors": [ { "name": "Jim Wigginton", - "role": "Lead Developer", - "email": "terrafrost@php.net" + "email": "terrafrost@php.net", + "role": "Lead Developer" }, { "name": "Patrick Monnerat", - "role": "Developer", - "email": "pm@datasphere.ch" + "email": "pm@datasphere.ch", + "role": "Developer" }, { "name": "Andreas Fischer", - "role": "Developer", - "email": "bantu@phpbb.com" + "email": "bantu@phpbb.com", + "role": "Developer" }, { "name": "Hans-Jürgen Petrich", - "role": "Developer", - "email": "petrich@tronic-media.com" + "email": "petrich@tronic-media.com", + "role": "Developer" }, { "name": "Graham Campbell", - "role": "Developer", - "email": "graham@alt-three.com" + "email": "graham@alt-three.com", + "role": "Developer" } ], "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", @@ -1597,7 +1600,7 @@ "x.509", "x509" ], - "time": "2019-07-12T12:53:49+00:00" + "time": "2019-09-17T03:41:22+00:00" }, { "name": "psr/container", @@ -2079,16 +2082,16 @@ }, { "name": "symfony/css-selector", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "105c98bb0c5d8635bea056135304bd8edcc42b4d" + "reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/105c98bb0c5d8635bea056135304bd8edcc42b4d", - "reference": "105c98bb0c5d8635bea056135304bd8edcc42b4d", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/c6e5e2a00db768c92c3ae131532af4e1acc7bd03", + "reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03", "shasum": "" }, "require": { @@ -2128,20 +2131,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2019-01-16T21:53:39+00:00" + "time": "2019-08-20T14:07:54+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "212b020949331b6531250584531363844b34a94e" + "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/212b020949331b6531250584531363844b34a94e", - "reference": "212b020949331b6531250584531363844b34a94e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/429d0a1451d4c9c4abe1959b2986b88794b9b7d2", + "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2", "shasum": "" }, "require": { @@ -2198,7 +2201,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2019-06-27T06:42:14+00:00" + "time": "2019-08-26T08:55:16+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -2260,16 +2263,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b9896d034463ad6fd2bf17e2bf9418caecd6313d" + "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b9896d034463ad6fd2bf17e2bf9418caecd6313d", - "reference": "b9896d034463ad6fd2bf17e2bf9418caecd6313d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/9abbb7ef96a51f4d7e69627bc6f63307994e4263", + "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263", "shasum": "" }, "require": { @@ -2306,20 +2309,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-06-23T08:51:25+00:00" + "time": "2019-08-20T14:07:54+00:00" }, { "name": "symfony/finder", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9638d41e3729459860bb96f6247ccb61faaa45f2" + "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9638d41e3729459860bb96f6247ccb61faaa45f2", - "reference": "9638d41e3729459860bb96f6247ccb61faaa45f2", + "url": "https://api.github.com/repos/symfony/finder/zipball/86c1c929f0a4b24812e1eb109262fc3372c8e9f2", + "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2", "shasum": "" }, "require": { @@ -2355,20 +2358,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2019-06-28T13:16:30+00:00" + "time": "2019-08-14T12:26:46+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "82ebae02209c21113908c229e9883c419720738a" + "reference": "550ebaac289296ce228a706d0867afc34687e3f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", - "reference": "82ebae02209c21113908c229e9883c419720738a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4", "shasum": "" }, "require": { @@ -2380,7 +2383,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -2396,13 +2399,13 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - }, { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", @@ -2413,20 +2416,20 @@ "polyfill", "portable" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fe5e94c604826c35a32fa832f35bd036b6799609" + "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609", - "reference": "fe5e94c604826c35a32fa832f35bd036b6799609", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17", "shasum": "" }, "require": { @@ -2438,7 +2441,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -2472,20 +2475,20 @@ "portable", "shim" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/process", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "856d35814cf287480465bb7a6c413bb7f5f5e69c" + "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/856d35814cf287480465bb7a6c413bb7f5f5e69c", - "reference": "856d35814cf287480465bb7a6c413bb7f5f5e69c", + "url": "https://api.github.com/repos/symfony/process/zipball/e89969c00d762349f078db1128506f7f3dcc0d4a", + "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a", "shasum": "" }, "require": { @@ -2521,7 +2524,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-05-30T16:10:05+00:00" + "time": "2019-08-26T08:26:39+00:00" }, { "name": "tedivm/jshrink", @@ -2841,16 +2844,16 @@ }, { "name": "zendframework/zend-code", - "version": "3.3.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-code.git", - "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb" + "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/c21db169075c6ec4b342149f446e7b7b724f95eb", - "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/936fa7ad4d53897ea3e3eb41b5b760828246a20b", + "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b", "shasum": "" }, "require": { @@ -2858,10 +2861,10 @@ "zendframework/zend-eventmanager": "^2.6 || ^3.0" }, "require-dev": { - "doctrine/annotations": "~1.0", + "doctrine/annotations": "^1.0", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "zendframework/zend-coding-standard": "^1.0.0", + "phpunit/phpunit": "^7.5.15", + "zendframework/zend-coding-standard": "^1.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "suggest": { @@ -2884,13 +2887,13 @@ "license": [ "BSD-3-Clause" ], - "description": "provides facilities to generate arbitrary code using an object oriented interface", - "homepage": "https://github.com/zendframework/zend-code", + "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", "keywords": [ + "ZendFramework", "code", - "zf2" + "zf" ], - "time": "2018-08-13T20:36:59+00:00" + "time": "2019-08-31T14:14:34+00:00" }, { "name": "zendframework/zend-config", @@ -3158,16 +3161,16 @@ }, { "name": "zendframework/zend-diactoros", - "version": "1.8.6", + "version": "1.8.7", "source": { "type": "git", "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "20da13beba0dde8fb648be3cc19765732790f46e" + "reference": "a85e67b86e9b8520d07e6415fcbcb8391b44a75b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/20da13beba0dde8fb648be3cc19765732790f46e", - "reference": "20da13beba0dde8fb648be3cc19765732790f46e", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/a85e67b86e9b8520d07e6415fcbcb8391b44a75b", + "reference": "a85e67b86e9b8520d07e6415fcbcb8391b44a75b", "shasum": "" }, "require": { @@ -3187,9 +3190,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev", - "dev-develop": "1.9.x-dev", - "dev-release-2.0": "2.0.x-dev" + "dev-release-1.8": "1.8.x-dev" } }, "autoload": { @@ -3218,20 +3219,20 @@ "psr", "psr-7" ], - "time": "2018-09-05T19:29:37+00:00" + "time": "2019-08-06T17:53:53+00:00" }, { "name": "zendframework/zend-escaper", - "version": "2.6.0", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-escaper.git", - "reference": "31d8aafae982f9568287cb4dce987e6aff8fd074" + "reference": "3801caa21b0ca6aca57fa1c42b08d35c395ebd5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/31d8aafae982f9568287cb4dce987e6aff8fd074", - "reference": "31d8aafae982f9568287cb4dce987e6aff8fd074", + "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/3801caa21b0ca6aca57fa1c42b08d35c395ebd5f", + "reference": "3801caa21b0ca6aca57fa1c42b08d35c395ebd5f", "shasum": "" }, "require": { @@ -3263,7 +3264,7 @@ "escaper", "zf" ], - "time": "2018-04-25T15:48:53+00:00" + "time": "2019-09-05T20:03:20+00:00" }, { "name": "zendframework/zend-eventmanager", @@ -3384,16 +3385,16 @@ }, { "name": "zendframework/zend-filter", - "version": "2.9.1", + "version": "2.9.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-filter.git", - "reference": "1c3e6d02f9cd5f6c929c9859498f5efbe216e86f" + "reference": "d78f2cdde1c31975e18b2a0753381ed7b61118ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/1c3e6d02f9cd5f6c929c9859498f5efbe216e86f", - "reference": "1c3e6d02f9cd5f6c929c9859498f5efbe216e86f", + "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/d78f2cdde1c31975e18b2a0753381ed7b61118ef", + "reference": "d78f2cdde1c31975e18b2a0753381ed7b61118ef", "shasum": "" }, "require": { @@ -3439,13 +3440,13 @@ "license": [ "BSD-3-Clause" ], - "description": "provides a set of commonly needed data filters", + "description": "Programmatically filter and normalize data and files", "keywords": [ "ZendFramework", "filter", "zf" ], - "time": "2018-12-17T16:00:04+00:00" + "time": "2019-08-19T07:08:04+00:00" }, { "name": "zendframework/zend-form", @@ -3645,16 +3646,16 @@ }, { "name": "zendframework/zend-i18n", - "version": "2.9.0", + "version": "2.9.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-i18n.git", - "reference": "6d69af5a04e1a4de7250043cb1322f077a0cdb7f" + "reference": "e17a54b3aee333ab156958f570cde630acee8b07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/6d69af5a04e1a4de7250043cb1322f077a0cdb7f", - "reference": "6d69af5a04e1a4de7250043cb1322f077a0cdb7f", + "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/e17a54b3aee333ab156958f570cde630acee8b07", + "reference": "e17a54b3aee333ab156958f570cde630acee8b07", "shasum": "" }, "require": { @@ -3662,7 +3663,7 @@ "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.16", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-config": "^2.6", @@ -3709,20 +3710,20 @@ "i18n", "zf" ], - "time": "2018-05-16T16:39:13+00:00" + "time": "2019-09-30T12:04:37+00:00" }, { "name": "zendframework/zend-inputfilter", - "version": "2.10.0", + "version": "2.10.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-inputfilter.git", - "reference": "4f52b71ec9cef3a06e3bba8f5c2124e94055ec0c" + "reference": "1f44a2e9bc394a71638b43bc7024b572fa65410e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/4f52b71ec9cef3a06e3bba8f5c2124e94055ec0c", - "reference": "4f52b71ec9cef3a06e3bba8f5c2124e94055ec0c", + "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/1f44a2e9bc394a71638b43bc7024b572fa65410e", + "reference": "1f44a2e9bc394a71638b43bc7024b572fa65410e", "shasum": "" }, "require": { @@ -3733,7 +3734,7 @@ "zendframework/zend-validator": "^2.11" }, "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.15", "psr/http-message": "^1.0", "zendframework/zend-coding-standard": "~1.0.0" }, @@ -3766,7 +3767,7 @@ "inputfilter", "zf" ], - "time": "2019-01-30T16:58:51+00:00" + "time": "2019-08-28T19:45:32+00:00" }, { "name": "zendframework/zend-json", @@ -3825,16 +3826,16 @@ }, { "name": "zendframework/zend-loader", - "version": "2.6.0", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-loader.git", - "reference": "78f11749ea340f6ca316bca5958eef80b38f9b6c" + "reference": "91da574d29b58547385b2298c020b257310898c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/78f11749ea340f6ca316bca5958eef80b38f9b6c", - "reference": "78f11749ea340f6ca316bca5958eef80b38f9b6c", + "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/91da574d29b58547385b2298c020b257310898c6", + "reference": "91da574d29b58547385b2298c020b257310898c6", "shasum": "" }, "require": { @@ -3866,20 +3867,20 @@ "loader", "zf" ], - "time": "2018-04-30T15:20:54+00:00" + "time": "2019-09-04T19:38:14+00:00" }, { "name": "zendframework/zend-log", - "version": "2.10.0", + "version": "2.11.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-log.git", - "reference": "9cec3b092acb39963659c2f32441cccc56b3f430" + "reference": "cb278772afdacb1924342248a069330977625ae6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-log/zipball/9cec3b092acb39963659c2f32441cccc56b3f430", - "reference": "9cec3b092acb39963659c2f32441cccc56b3f430", + "url": "https://api.github.com/repos/zendframework/zend-log/zipball/cb278772afdacb1924342248a069330977625ae6", + "reference": "cb278772afdacb1924342248a069330977625ae6", "shasum": "" }, "require": { @@ -3892,8 +3893,8 @@ "psr/log-implementation": "1.0.0" }, "require-dev": { - "mikey179/vfsstream": "^1.6", - "phpunit/phpunit": "^5.7.15 || ^6.0.8", + "mikey179/vfsstream": "^1.6.7", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.15", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-db": "^2.6", "zendframework/zend-escaper": "^2.5", @@ -3904,7 +3905,6 @@ "suggest": { "ext-mongo": "mongo extension to use Mongo writer", "ext-mongodb": "mongodb extension to use MongoDB writer", - "zendframework/zend-console": "Zend\\Console component to use the RequestID log processor", "zendframework/zend-db": "Zend\\Db component to use the database log writer", "zendframework/zend-escaper": "Zend\\Escaper component, for use in the XML log formatter", "zendframework/zend-mail": "Zend\\Mail component to use the email log writer", @@ -3913,8 +3913,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.10.x-dev", - "dev-develop": "2.11.x-dev" + "dev-master": "2.11.x-dev", + "dev-develop": "2.12.x-dev" }, "zf": { "component": "Zend\\Log", @@ -3930,14 +3930,14 @@ "license": [ "BSD-3-Clause" ], - "description": "component for general purpose logging", - "homepage": "https://github.com/zendframework/zend-log", + "description": "Robust, composite logger with filtering, formatting, and PSR-3 support", "keywords": [ + "ZendFramework", "log", "logging", - "zf2" + "zf" ], - "time": "2018-04-09T21:59:51+00:00" + "time": "2019-08-23T21:28:18+00:00" }, { "name": "zendframework/zend-mail", @@ -4464,28 +4464,28 @@ }, { "name": "zendframework/zend-session", - "version": "2.8.5", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-session.git", - "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b" + "reference": "0a0c7ae4d8be608e30ecff714c86164ccca19ca3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-session/zipball/2cfd90e1a2f6b066b9f908599251d8f64f07021b", - "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b", + "url": "https://api.github.com/repos/zendframework/zend-session/zipball/0a0c7ae4d8be608e30ecff714c86164ccca19ca3", + "reference": "0a0c7ae4d8be608e30ecff714c86164ccca19ca3", "shasum": "" }, "require": { "php": "^5.6 || ^7.0", "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" + "zendframework/zend-stdlib": "^3.2.1" }, "require-dev": { "container-interop/container-interop": "^1.1", "mongodb/mongodb": "^1.0.1", "php-mock/php-mock-phpunit": "^1.1.2 || ^2.0", - "phpunit/phpunit": "^5.7.5 || >=6.0.13 <6.5.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.16", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-db": "^2.7", @@ -4504,8 +4504,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" + "dev-master": "2.9.x-dev", + "dev-develop": "2.10.x-dev" }, "zf": { "component": "Zend\\Session", @@ -4521,13 +4521,13 @@ "license": [ "BSD-3-Clause" ], - "description": "manage and preserve session data, a logical complement of cookie data, across multiple page requests by the same client", + "description": "Object-oriented interface to PHP sessions and storage", "keywords": [ "ZendFramework", "session", "zf" ], - "time": "2018-02-22T16:33:54+00:00" + "time": "2019-09-20T12:50:51+00:00" }, { "name": "zendframework/zend-soap", @@ -4938,25 +4938,26 @@ }, { "name": "allure-framework/allure-php-api", - "version": "1.1.4", + "version": "1.1.5", "source": { "type": "git", - "url": "https://github.com/allure-framework/allure-php-adapter-api.git", - "reference": "a462a0da121681577033e13c123b6cc4e89cdc64" + "url": "https://github.com/allure-framework/allure-php-commons.git", + "reference": "c7a675823ad75b8e02ddc364baae21668e7c4e88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/allure-framework/allure-php-adapter-api/zipball/a462a0da121681577033e13c123b6cc4e89cdc64", - "reference": "a462a0da121681577033e13c123b6cc4e89cdc64", + "url": "https://api.github.com/repos/allure-framework/allure-php-commons/zipball/c7a675823ad75b8e02ddc364baae21668e7c4e88", + "reference": "c7a675823ad75b8e02ddc364baae21668e7c4e88", "shasum": "" }, "require": { - "jms/serializer": ">=0.16.0", - "moontoast/math": ">=1.1.0", + "jms/serializer": "^0.16.0", "php": ">=5.4.0", - "phpunit/phpunit": ">=4.0.0", - "ramsey/uuid": ">=3.0.0", - "symfony/http-foundation": ">=2.0" + "ramsey/uuid": "^3.0.0", + "symfony/http-foundation": "^2.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0.0" }, "type": "library", "autoload": { @@ -4986,7 +4987,7 @@ "php", "report" ], - "time": "2016-12-07T12:15:46+00:00" + "time": "2018-05-25T14:02:11+00:00" }, { "name": "allure-framework/allure-phpunit", @@ -5283,16 +5284,16 @@ }, { "name": "codeception/phpunit-wrapper", - "version": "6.6.1", + "version": "6.7.0", "source": { "type": "git", "url": "https://github.com/Codeception/phpunit-wrapper.git", - "reference": "d0da25a98bcebeb15d97c2ad3b2de6166b6e7a0c" + "reference": "93f59e028826464eac086052fa226e58967f6907" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/d0da25a98bcebeb15d97c2ad3b2de6166b6e7a0c", - "reference": "d0da25a98bcebeb15d97c2ad3b2de6166b6e7a0c", + "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/93f59e028826464eac086052fa226e58967f6907", + "reference": "93f59e028826464eac086052fa226e58967f6907", "shasum": "" }, "require": { @@ -5325,7 +5326,7 @@ } ], "description": "PHPUnit classes used by Codeception", - "time": "2019-02-26T20:47:39+00:00" + "time": "2019-08-18T15:43:35+00:00" }, { "name": "codeception/stub", @@ -6030,16 +6031,16 @@ }, { "name": "doctrine/annotations", - "version": "v1.6.1", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "53120e0eb10355388d6ccbe462f1fea34ddadb24" + "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/53120e0eb10355388d6ccbe462f1fea34ddadb24", - "reference": "53120e0eb10355388d6ccbe462f1fea34ddadb24", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/fa4c4e861e809d6a1103bd620cce63ed91aedfeb", + "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb", "shasum": "" }, "require": { @@ -6048,12 +6049,12 @@ }, "require-dev": { "doctrine/cache": "1.*", - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "^7.5@dev" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.7.x-dev" } }, "autoload": { @@ -6066,6 +6067,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -6074,10 +6079,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -6094,7 +6095,7 @@ "docblock", "parser" ], - "time": "2019-03-25T19:12:02+00:00" + "time": "2019-08-08T18:11:40+00:00" }, { "name": "doctrine/cache", @@ -6171,76 +6172,6 @@ ], "time": "2018-08-21T18:01:43+00:00" }, - { - "name": "doctrine/collections", - "version": "v1.6.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/collections.git", - "reference": "c5e0bc17b1620e97c968ac409acbff28b8b850be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/c5e0bc17b1620e97c968ac409acbff28b8b850be", - "reference": "c5e0bc17b1620e97c968ac409acbff28b8b850be", - "shasum": "" - }, - "require": { - "php": "^7.1.3" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpstan/phpstan-shim": "^0.9.2", - "phpunit/phpunit": "^7.0", - "vimeo/psalm": "^3.2.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", - "homepage": "https://www.doctrine-project.org/projects/collections.html", - "keywords": [ - "array", - "collections", - "iterators", - "php" - ], - "time": "2019-06-09T13:48:14+00:00" - }, { "name": "doctrine/inflector", "version": "v1.1.0", @@ -6424,52 +6355,6 @@ ], "time": "2019-06-08T11:03:04+00:00" }, - { - "name": "epfremme/swagger-php", - "version": "v2.0.0", - "source": { - "type": "git", - "url": "https://github.com/epfremmer/swagger-php.git", - "reference": "eee28a442b7e6220391ec953d3c9b936354f23bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/epfremmer/swagger-php/zipball/eee28a442b7e6220391ec953d3c9b936354f23bc", - "reference": "eee28a442b7e6220391ec953d3c9b936354f23bc", - "shasum": "" - }, - "require": { - "doctrine/annotations": "^1.2", - "doctrine/collections": "^1.3", - "jms/serializer": "^1.1", - "php": ">=5.5", - "phpoption/phpoption": "^1.1", - "symfony/yaml": "^2.7|^3.1" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "~4.8|~5.0", - "satooshi/php-coveralls": "^1.0" - }, - "type": "package", - "autoload": { - "psr-4": { - "Epfremme\\Swagger\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Edward Pfremmer", - "email": "epfremme@nerdery.com" - } - ], - "description": "Library for parsing swagger documentation into PHP entities for use in testing and code generation", - "time": "2016-09-26T17:24:17+00:00" - }, { "name": "facebook/webdriver", "version": "1.7.1", @@ -6573,16 +6458,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.14.4", + "version": "v2.14.6", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "69ccf81f3c968be18d646918db94ab88ddf3594f" + "reference": "8d18a8bb180e2acde1c8031db09aefb9b73f6127" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/69ccf81f3c968be18d646918db94ab88ddf3594f", - "reference": "69ccf81f3c968be18d646918db94ab88ddf3594f", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/8d18a8bb180e2acde1c8031db09aefb9b73f6127", + "reference": "8d18a8bb180e2acde1c8031db09aefb9b73f6127", "shasum": "" }, "require": { @@ -6612,9 +6497,10 @@ "php-cs-fixer/accessible-object": "^1.0", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1", - "phpunitgoodpractices/traits": "^1.8", - "symfony/phpunit-bridge": "^4.3" + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1", + "phpunitgoodpractices/traits": "^1.5.1", + "symfony/phpunit-bridge": "^4.0", + "symfony/yaml": "^3.0 || ^4.0" }, "suggest": { "ext-mbstring": "For handling non-UTF8 characters in cache signature.", @@ -6647,17 +6533,17 @@ "MIT" ], "authors": [ - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" } ], "description": "A tool to automatically fix PHP code style", - "time": "2019-06-01T10:29:34+00:00" + "time": "2019-08-31T12:47:52+00:00" }, { "name": "fzaninotto/faker", @@ -6804,6 +6690,48 @@ "description": "Expands internal property references in a yaml file.", "time": "2017-12-16T16:06:03+00:00" }, + { + "name": "ircmaxell/password-compat", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/password_compat.git", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "files": [ + "lib/password.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@php.net", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", + "homepage": "https://github.com/ircmaxell/password_compat", + "keywords": [ + "hashing", + "password" + ], + "time": "2014-11-20T16:49:30+00:00" + }, { "name": "jms/metadata", "version": "1.7.0", @@ -6896,56 +6824,44 @@ }, { "name": "jms/serializer", - "version": "1.14.0", + "version": "0.16.0", "source": { "type": "git", "url": "https://github.com/schmittjoh/serializer.git", - "reference": "ee96d57024af9a7716d56fcbe3aa94b3d030f3ca" + "reference": "c8a171357ca92b6706e395c757f334902d430ea9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/ee96d57024af9a7716d56fcbe3aa94b3d030f3ca", - "reference": "ee96d57024af9a7716d56fcbe3aa94b3d030f3ca", + "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/c8a171357ca92b6706e395c757f334902d430ea9", + "reference": "c8a171357ca92b6706e395c757f334902d430ea9", "shasum": "" }, "require": { - "doctrine/annotations": "^1.0", - "doctrine/instantiator": "^1.0.3", - "jms/metadata": "^1.3", + "doctrine/annotations": "1.*", + "jms/metadata": "~1.1", "jms/parser-lib": "1.*", - "php": "^5.5|^7.0", - "phpcollection/phpcollection": "~0.1", - "phpoption/phpoption": "^1.1" - }, - "conflict": { - "twig/twig": "<1.12" + "php": ">=5.3.2", + "phpcollection/phpcollection": "~0.1" }, "require-dev": { "doctrine/orm": "~2.1", - "doctrine/phpcr-odm": "^1.3|^2.0", - "ext-pdo_sqlite": "*", - "jackalope/jackalope-doctrine-dbal": "^1.1.5", - "phpunit/phpunit": "^4.8|^5.0", + "doctrine/phpcr-odm": "~1.0.1", + "jackalope/jackalope-doctrine-dbal": "1.0.*", "propel/propel1": "~1.7", - "psr/container": "^1.0", - "symfony/dependency-injection": "^2.7|^3.3|^4.0", - "symfony/expression-language": "^2.6|^3.0", - "symfony/filesystem": "^2.1", - "symfony/form": "~2.1|^3.0", - "symfony/translation": "^2.1|^3.0", - "symfony/validator": "^2.2|^3.0", - "symfony/yaml": "^2.1|^3.0", - "twig/twig": "~1.12|~2.0" + "symfony/filesystem": "2.*", + "symfony/form": "~2.1", + "symfony/translation": "~2.0", + "symfony/validator": "~2.0", + "symfony/yaml": "2.*", + "twig/twig": ">=1.8,<2.0-dev" }, "suggest": { - "doctrine/cache": "Required if you like to use cache functionality.", - "doctrine/collections": "Required if you like to use doctrine collection types as ArrayCollection.", "symfony/yaml": "Required if you'd like to serialize data to YAML format." }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.14-dev" + "dev-master": "0.15-dev" } }, "autoload": { @@ -6955,16 +6871,14 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "Apache2" ], "authors": [ { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" - }, - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh", + "role": "Developer of wrapped JMSSerializerBundle" } ], "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.", @@ -6976,7 +6890,7 @@ "serialization", "xml" ], - "time": "2019-04-17T08:12:16+00:00" + "time": "2014-03-18T08:39:00+00:00" }, { "name": "league/container", @@ -7303,23 +7217,23 @@ }, { "name": "mikey179/vfsstream", - "version": "v1.6.6", + "version": "v1.6.7", "source": { "type": "git", "url": "https://github.com/bovigo/vfsStream.git", - "reference": "095238a0711c974ae5b4ebf4c4534a23f3f6c99d" + "reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/095238a0711c974ae5b4ebf4c4534a23f3f6c99d", - "reference": "095238a0711c974ae5b4ebf4c4534a23f3f6c99d", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb", + "reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb", "shasum": "" }, "require": { "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "~4.5" + "phpunit/phpunit": "^4.5|^5.0" }, "type": "library", "extra": { @@ -7345,56 +7259,7 @@ ], "description": "Virtual file system to mock the real file system in unit tests.", "homepage": "http://vfs.bovigo.org/", - "time": "2019-04-08T13:54:32+00:00" - }, - { - "name": "moontoast/math", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/ramsey/moontoast-math.git", - "reference": "c2792a25df5cad4ff3d760dd37078fc5b6fccc79" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/moontoast-math/zipball/c2792a25df5cad4ff3d760dd37078fc5b6fccc79", - "reference": "c2792a25df5cad4ff3d760dd37078fc5b6fccc79", - "shasum": "" - }, - "require": { - "ext-bcmath": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "jakub-onderka/php-parallel-lint": "^0.9.0", - "phpunit/phpunit": "^4.7|>=5.0 <5.4", - "satooshi/php-coveralls": "^0.6.1", - "squizlabs/php_codesniffer": "^2.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Moontoast\\Math\\": "src/Moontoast/Math/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" - } - ], - "description": "A mathematics library, providing functionality for large numbers", - "homepage": "https://github.com/ramsey/moontoast-math", - "keywords": [ - "bcmath", - "math" - ], - "time": "2017-02-16T16:54:46+00:00" + "time": "2019-08-01T01:38:37+00:00" }, { "name": "mustache/mustache", @@ -7444,16 +7309,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.9.1", + "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", "shasum": "" }, "require": { @@ -7488,7 +7353,7 @@ "object", "object graph" ], - "time": "2019-04-07T13:18:21+00:00" + "time": "2019-08-09T12:45:53+00:00" }, { "name": "pdepend/pdepend", @@ -7733,35 +7598,33 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "~6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -7783,30 +7646,30 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2018-08-07T13:53:10+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.1", + "version": "4.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", "shasum": "" }, "require": { "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", + "doctrine/instantiator": "^1.0.5", "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4" }, @@ -7834,41 +7697,40 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-04-30T17:48:53+00:00" + "time": "2019-09-12T14:27:41+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -7881,7 +7743,8 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpmd/phpmd", @@ -8764,16 +8627,16 @@ }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", "shasum": "" }, "require": { @@ -8800,6 +8663,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -8808,17 +8675,13 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -8827,7 +8690,7 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2019-09-14T09:02:43+00:00" }, { "name": "sebastian/finder-facade", @@ -9252,16 +9115,16 @@ }, { "name": "symfony/browser-kit", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "a29dd02a1f3f81b9a15c7730cc3226718ddb55ca" + "reference": "9e5dddb637b13db82e35695a8603fe6e118cc119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/a29dd02a1f3f81b9a15c7730cc3226718ddb55ca", - "reference": "a29dd02a1f3f81b9a15c7730cc3226718ddb55ca", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9e5dddb637b13db82e35695a8603fe6e118cc119", + "reference": "9e5dddb637b13db82e35695a8603fe6e118cc119", "shasum": "" }, "require": { @@ -9307,20 +9170,20 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2019-06-11T15:41:59+00:00" + "time": "2019-08-26T08:26:39+00:00" }, { "name": "symfony/config", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "a17a2aea43950ce83a0603ed301bac362eb86870" + "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/a17a2aea43950ce83a0603ed301bac362eb86870", - "reference": "a17a2aea43950ce83a0603ed301bac362eb86870", + "url": "https://api.github.com/repos/symfony/config/zipball/07d49c0f823e0bc367c6d84e35b61419188a5ece", + "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece", "shasum": "" }, "require": { @@ -9371,26 +9234,26 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-07-18T10:34:59+00:00" + "time": "2019-08-26T08:26:39+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "9ad1b83d474ae17156f6914cb81ffe77aeac3a9b" + "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/9ad1b83d474ae17156f6914cb81ffe77aeac3a9b", - "reference": "9ad1b83d474ae17156f6914cb81ffe77aeac3a9b", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d3ad14b66ac773ba6123622eb9b5b010165fe3d9", + "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9", "shasum": "" }, "require": { "php": "^7.1.3", "psr/container": "^1.0", - "symfony/service-contracts": "^1.1.2" + "symfony/service-contracts": "^1.1.6" }, "conflict": { "symfony/config": "<4.3", @@ -9444,20 +9307,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-07-26T07:03:43+00:00" + "time": "2019-08-26T16:27:33+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "291397232a2eefb3347eaab9170409981eaad0e2" + "reference": "cc686552948d627528c0e2e759186dff67c2610e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/291397232a2eefb3347eaab9170409981eaad0e2", - "reference": "291397232a2eefb3347eaab9170409981eaad0e2", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/cc686552948d627528c0e2e759186dff67c2610e", + "reference": "cc686552948d627528c0e2e759186dff67c2610e", "shasum": "" }, "require": { @@ -9505,35 +9368,35 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2019-06-13T11:03:18+00:00" + "time": "2019-08-26T08:26:39+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.3.3", + "version": "v2.8.50", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "8b778ee0c27731105fbf1535f51793ad1ae0ba2b" + "reference": "746f8d3638bf46ee8b202e62f2b214c3d61fb06a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8b778ee0c27731105fbf1535f51793ad1ae0ba2b", - "reference": "8b778ee0c27731105fbf1535f51793ad1ae0ba2b", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/746f8d3638bf46ee8b202e62f2b214c3d61fb06a", + "reference": "746f8d3638bf46ee8b202e62f2b214c3d61fb06a", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/mime": "^4.3", - "symfony/polyfill-mbstring": "~1.1" + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php54": "~1.0", + "symfony/polyfill-php55": "~1.0" }, "require-dev": { - "predis/predis": "~1.0", - "symfony/expression-language": "~3.4|~4.0" + "symfony/expression-language": "~2.4|~3.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -9560,30 +9423,24 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-07-23T11:21:36+00:00" + "time": "2019-04-16T10:00:53+00:00" }, { - "name": "symfony/mime", - "version": "v4.3.3", + "name": "symfony/options-resolver", + "version": "v4.3.4", "source": { "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "6b7148029b1dd5eda1502064f06d01357b7b2d8b" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "81c2e120522a42f623233968244baebd6b36cb6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/6b7148029b1dd5eda1502064f06d01357b7b2d8b", - "reference": "6b7148029b1dd5eda1502064f06d01357b7b2d8b", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/81c2e120522a42f623233968244baebd6b36cb6a", + "reference": "81c2e120522a42f623233968244baebd6b36cb6a", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0" - }, - "require-dev": { - "egulias/email-validator": "^2.0", - "symfony/dependency-injection": "~3.4|^4.1" + "php": "^7.1.3" }, "type": "library", "extra": { @@ -9593,7 +9450,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Component\\Mime\\": "" + "Symfony\\Component\\OptionsResolver\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -9613,43 +9470,47 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "A library to manipulate MIME messages", + "description": "Symfony OptionsResolver Component", "homepage": "https://symfony.com", "keywords": [ - "mime", - "mime-type" + "config", + "configuration", + "options" ], - "time": "2019-07-19T16:21:19+00:00" + "time": "2019-08-08T09:29:19+00:00" }, { - "name": "symfony/options-resolver", - "version": "v4.3.3", + "name": "symfony/polyfill-php54", + "version": "v1.12.0", "source": { "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "40762ead607c8f792ee4516881369ffa553fee6f" + "url": "https://github.com/symfony/polyfill-php54.git", + "reference": "a043bcced870214922fbb4bf22679d431ec0296a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/40762ead607c8f792ee4516881369ffa553fee6f", - "reference": "40762ead607c8f792ee4516881369ffa553fee6f", + "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/a043bcced870214922fbb4bf22679d431ec0296a", + "reference": "a043bcced870214922fbb4bf22679d431ec0296a", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=5.3.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "1.12-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" + "Symfony\\Polyfill\\Php54\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -9658,54 +9519,51 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony OptionsResolver Component", + "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ - "config", - "configuration", - "options" + "compatibility", + "polyfill", + "portable", + "shim" ], - "time": "2019-06-13T11:01:17+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { - "name": "symfony/polyfill-intl-idn", - "version": "v1.11.0", + "name": "symfony/polyfill-php55", + "version": "v1.12.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "c766e95bec706cdd89903b1eda8afab7d7a6b7af" + "url": "https://github.com/symfony/polyfill-php55.git", + "reference": "548bb39407e78e54f785b4e18c7e0d5d9e493265" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c766e95bec706cdd89903b1eda8afab7d7a6b7af", - "reference": "c766e95bec706cdd89903b1eda8afab7d7a6b7af", + "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/548bb39407e78e54f785b4e18c7e0d5d9e493265", + "reference": "548bb39407e78e54f785b4e18c7e0d5d9e493265", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.9" - }, - "suggest": { - "ext-intl": "For best performance" + "ircmaxell/password-compat": "~1.0", + "php": ">=5.3.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-master": "1.12-dev" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" + "Symfony\\Polyfill\\Php55\\": "" }, "files": [ "bootstrap.php" @@ -9717,38 +9575,36 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "idn", - "intl", "polyfill", "portable", "shim" ], - "time": "2019-03-04T13:44:35+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/polyfill-php70", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "bc4858fb611bda58719124ca079baff854149c89" + "reference": "54b4c428a0054e254223797d2713c31e08610831" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/bc4858fb611bda58719124ca079baff854149c89", - "reference": "bc4858fb611bda58719124ca079baff854149c89", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/54b4c428a0054e254223797d2713c31e08610831", + "reference": "54b4c428a0054e254223797d2713c31e08610831", "shasum": "" }, "require": { @@ -9758,7 +9614,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -9794,20 +9650,20 @@ "portable", "shim" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "ab50dcf166d5f577978419edd37aa2bb8eabce0c" + "reference": "04ce3335667451138df4307d6a9b61565560199e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/ab50dcf166d5f577978419edd37aa2bb8eabce0c", - "reference": "ab50dcf166d5f577978419edd37aa2bb8eabce0c", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e", + "reference": "04ce3335667451138df4307d6a9b61565560199e", "shasum": "" }, "require": { @@ -9816,7 +9672,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -9849,20 +9705,20 @@ "portable", "shim" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/service-contracts", - "version": "v1.1.5", + "version": "v1.1.6", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d" + "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d", - "reference": "f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3", + "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3", "shasum": "" }, "require": { @@ -9907,20 +9763,20 @@ "interoperability", "standards" ], - "time": "2019-06-13T11:15:36+00:00" + "time": "2019-08-20T14:44:19+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "6b100e9309e8979cf1978ac1778eb155c1f7d93b" + "reference": "1e4ff456bd625be5032fac9be4294e60442e9b71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6b100e9309e8979cf1978ac1778eb155c1f7d93b", - "reference": "6b100e9309e8979cf1978ac1778eb155c1f7d93b", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/1e4ff456bd625be5032fac9be4294e60442e9b71", + "reference": "1e4ff456bd625be5032fac9be4294e60442e9b71", "shasum": "" }, "require": { @@ -9957,24 +9813,24 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2019-05-27T08:16:38+00:00" + "time": "2019-08-07T11:52:19+00:00" }, { "name": "symfony/yaml", - "version": "v3.4.30", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "051d045c684148060ebfc9affb7e3f5e0899d40b" + "reference": "5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/051d045c684148060ebfc9affb7e3f5e0899d40b", - "reference": "051d045c684148060ebfc9affb7e3f5e0899d40b", + "url": "https://api.github.com/repos/symfony/yaml/zipball/5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686", + "reference": "5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { @@ -9989,7 +9845,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -10016,7 +9872,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2019-07-24T13:01:31+00:00" + "time": "2019-08-20T14:27:59+00:00" }, { "name": "theseer/fdomdocument", @@ -10151,16 +10007,16 @@ }, { "name": "webmozart/assert", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", + "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", "shasum": "" }, "require": { @@ -10168,8 +10024,7 @@ "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "extra": { @@ -10198,7 +10053,7 @@ "check", "validate" ], - "time": "2018-12-25T11:19:39+00:00" + "time": "2019-08-24T08:43:50+00:00" }, { "name": "weew/helpers-array", From 7788cb50b0db6490461e230713e16b32add15b29 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 9 Oct 2019 11:57:10 -0500 Subject: [PATCH 354/372] MC-18527: Merge release branch into 2.3-develop - fix stepKey --- .../Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml b/app/code/Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml index 9ed4e2ced99f7..c63e76d851933 100644 --- a/app/code/Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml +++ b/app/code/Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml @@ -27,7 +27,7 @@ </before> <after> - <actionGroup ref="logout" stepKey="adminLogout"/> + <actionGroup ref="logout" stepKey="logout"/> </after> <!-- Create a CMS page containing the New Products widget --> From 79748211c9c7dba320d82ed9f61d58ad4a9ea3c0 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 9 Oct 2019 12:51:47 -0500 Subject: [PATCH 355/372] MC-18527: Merge release branch into 2.3-develop - fix webapi tests --- .../_files/Magento/TestModuleUps/Model/Carrier.php | 2 +- .../product_downloadable_with_purchased_separately_links.php | 5 +++++ ...downloadable_with_purchased_separately_links_rollback.php | 5 +++++ ...oduct_downloadable_without_purchased_separately_links.php | 5 +++++ ...nloadable_without_purchased_separately_links_rollback.php | 5 +++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/_files/Magento/TestModuleUps/Model/Carrier.php b/dev/tests/api-functional/_files/Magento/TestModuleUps/Model/Carrier.php index b3c3c124cfe47..9411523db0f2e 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleUps/Model/Carrier.php +++ b/dev/tests/api-functional/_files/Magento/TestModuleUps/Model/Carrier.php @@ -7,10 +7,10 @@ namespace Magento\TestModuleUps\Model; -use Magento\Framework\Async\ProxyDeferredFactory; use Magento\Framework\HTTP\AsyncClientInterface; use Magento\Framework\HTTP\ClientFactory; use Magento\Framework\Xml\Security; +use Magento\Shipping\Model\Rate\Result\ProxyDeferredFactory; use Magento\Ups\Helper\Config; /** diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php index 6ceb4d90787e1..bdb121d86154d 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php @@ -9,6 +9,11 @@ use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Downloadable\Model\Product\Type as ProductType; use Magento\Catalog\Model\Product\Visibility as ProductVisibility; +use Magento\Downloadable\Api\DomainManagerInterface; + +/** @var DomainManagerInterface $domainManager */ +$domainManager = Bootstrap::getObjectManager()->get(DomainManagerInterface::class); +$domainManager->addDomains(['example.com']); /** * @var \Magento\Catalog\Model\Product $product diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links_rollback.php index 308a48c144e22..5fcab9af5eb77 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links_rollback.php @@ -7,6 +7,11 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Downloadable\Api\DomainManagerInterface; + +/** @var DomainManagerInterface $domainManager */ +$domainManager = Bootstrap::getObjectManager()->get(DomainManagerInterface::class); +$domainManager->removeDomains(['example.com']); /** @var \Magento\Framework\Registry $registry */ $registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links.php index f55261be04ce6..28a086848b0b0 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links.php @@ -9,6 +9,11 @@ use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Downloadable\Model\Product\Type as ProductType; use Magento\Catalog\Model\Product\Visibility as ProductVisibility; +use Magento\Downloadable\Api\DomainManagerInterface; + +/** @var DomainManagerInterface $domainManager */ +$domainManager = Bootstrap::getObjectManager()->get(DomainManagerInterface::class); +$domainManager->addDomains(['example.com']); /** * @var \Magento\Catalog\Model\Product $product diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links_rollback.php index 4569460b10181..498fab815cdb7 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links_rollback.php @@ -7,6 +7,11 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Downloadable\Api\DomainManagerInterface; + +/** @var DomainManagerInterface $domainManager */ +$domainManager = Bootstrap::getObjectManager()->get(DomainManagerInterface::class); +$domainManager->removeDomains(['example.com']); /** @var \Magento\Framework\Registry $registry */ $registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); From 0097469cc66b42489ba56ce3940453c78a3d2888 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 9 Oct 2019 13:51:13 -0500 Subject: [PATCH 356/372] MC-18527: Merge release branch into 2.3-develop - fix static test failures --- .../Model/ResourceModel/Viewer/Logger.php | 3 --- .../Model/Product/Compare/ListCompare.php | 1 + .../Unit/Ui/Component/ColumnFactoryTest.php | 7 ++++--- .../Ui/Component/Product/MassAction.php | 1 + app/code/Magento/Customer/Model/Visitor.php | 4 ++-- .../Import/Product/Type/Downloadable.php | 20 ++----------------- .../Magento/ImportExport/Model/Import.php | 3 --- 7 files changed, 10 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 5c225ebfeceb5..1ade6e9d54fee 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -18,9 +18,6 @@ */ class Logger { - /** - * Log table name - */ const LOG_TABLE_NAME = 'admin_analytics_usage_version_log'; /** diff --git a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php index bfd36360ee559..9ccb86441812c 100644 --- a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php +++ b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php @@ -15,6 +15,7 @@ * * @api * @SuppressWarnings(PHPMD.LongVariable) + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @since 100.0.2 */ class ListCompare extends \Magento\Framework\DataObject diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php index 45d911f7e94e5..55acfff6d87d3 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php @@ -67,9 +67,10 @@ protected function setUp(): void $this->uiComponentFactory->method('create') ->willReturn($this->column); - $this->columnFactory = $this->objectManager->getObject(ColumnFactory::class, [ - 'componentFactory' => $this->uiComponentFactory - ]); + $this->columnFactory = $this->objectManager->getObject( + ColumnFactory::class, + ['componentFactory' => $this->uiComponentFactory] + ); } /** diff --git a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php index 8db1bf8268b66..f770f6b9c497f 100644 --- a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php +++ b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php @@ -52,6 +52,7 @@ public function prepare() : void foreach ($this->getChildComponents() as $actionComponent) { $actionType = $actionComponent->getConfiguration()['type']; if ($this->isActionAllowed($actionType)) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $config['actions'][] = array_merge($actionComponent->getConfiguration(), ['__disableTmpl' => true]); } } diff --git a/app/code/Magento/Customer/Model/Visitor.php b/app/code/Magento/Customer/Model/Visitor.php index 17394c4d94129..6935b9dca7f28 100644 --- a/app/code/Magento/Customer/Model/Visitor.php +++ b/app/code/Magento/Customer/Model/Visitor.php @@ -265,7 +265,7 @@ public function bindCustomerLogout($observer) * Create binding of checkout quote * * @param \Magento\Framework\Event\Observer $observer - * @return \Magento\Customer\Model\Visitor + * @return \Magento\Customer\Model\Visitor */ public function bindQuoteCreate($observer) { @@ -283,7 +283,7 @@ public function bindQuoteCreate($observer) * Destroy binding of checkout quote * * @param \Magento\Framework\Event\Observer $observer - * @return \Magento\Customer\Model\Visitor + * @return \Magento\Customer\Model\Visitor */ public function bindQuoteDestroy($observer) { diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index fbee9c093b04f..1cfef359ca81a 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -19,29 +19,14 @@ */ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType { - /** - * Pair value separator. - */ const PAIR_VALUE_SEPARATOR = '='; - /** - * Default sort order - */ const DEFAULT_SORT_ORDER = 0; - /** - * Default number of downloads - */ const DEFAULT_NUMBER_OF_DOWNLOADS = 0; - /** - * Default is shareable - */ const DEFAULT_IS_SHAREABLE = 2; - /** - * Default website id - */ const DEFAULT_WEBSITE_ID = 0; /** @@ -79,9 +64,6 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ */ const COL_DOWNLOADABLE_LINKS = 'downloadable_links'; - /** - * Default group title - */ const DEFAULT_GROUP_TITLE = ''; /** @@ -786,6 +768,7 @@ protected function prepareSampleData($rowCol, $entityId = null) $rowCol ); foreach ($options as $option) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $result[] = array_merge( $this->dataSample, ['product_id' => $entityId], @@ -810,6 +793,7 @@ protected function prepareLinkData($rowCol, $entityId = null) $rowCol ); foreach ($options as $option) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $result[] = array_merge( $this->dataLink, ['product_id' => $entityId], diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index d29bf29dd50af..f3ed7e104bca7 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -107,9 +107,6 @@ class Import extends AbstractModel */ const DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR = ','; - /** - * default empty attribute value constant - */ const DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT = '__EMPTY__VALUE__'; const DEFAULT_SIZE = 50; const MAX_IMPORT_CHUNKS = 4; From d5605e827c6b0be404364875646e9eeb321e3366 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 9 Oct 2019 15:22:47 -0500 Subject: [PATCH 357/372] MC-18527: Merge release branch into 2.3-develop - fix integration tests --- .../integration/testsuite/Magento/Sales/_files/quotes.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php index b916fc0240417..53c429ee5f20e 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php @@ -19,12 +19,17 @@ /** @var QuoteRepository $quoteRepository */ $quoteRepository = $objectManager->get(QuoteRepository::class); +/** @var Magento\Store\Model\Store $store */ +$store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); +$store->load('fixture_second_store'); +$storeId = $store->getId(); + $quotes = [ 'quote for first store' => [ 'store' => 1, ], 'quote for second store' => [ - 'store' => 2, + 'store' => $storeId, ], ]; From 41a2e82eb2c40ae12a33a07f86e4500bece5f9c0 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 9 Oct 2019 19:07:23 -0500 Subject: [PATCH 358/372] MC-18527: Merge release branch into 2.3-develop - fix MFTF and integration tests --- .../Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml | 4 ++++ .../AdminExportImportConfigurableProductWithImagesTest.xml | 6 ++++++ .../Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml | 4 ++++ ...EditDownloadableProductWithSeparateLinksFromCartTest.xml | 6 ++++++ .../SelectAllDownloadableLinksDownloadableProductTest.xml | 6 ++++++ ...isableDownloadableProductSamplesAreNotAccessibleTest.xml | 6 ++++++ .../AdminOpenAndFillCreditMemoRefundActionGroup.xml | 1 - .../integration/testsuite/Magento/Sales/_files/quotes.php | 5 ----- .../testsuite/Magento/Store/_files/second_store.php | 5 ++++- 9 files changed, 36 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml index a11646cc46875..de065d2d930cb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml @@ -20,12 +20,16 @@ <group value="catalog"/> </annotations> <before> + <!-- Add downloadable domains --> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--Create product--> <comment userInput="Create product" stepKey="commentCreateProduct"/> <createData entity="VirtualProduct" stepKey="createProduct"/> </before> <after> + <!-- Remove downloadable domains --> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <!--Delete product--> <comment userInput="Delete product" stepKey="commentDeleteProduct"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> diff --git a/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportImportConfigurableProductWithImagesTest.xml b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportImportConfigurableProductWithImagesTest.xml index 88f6e6c9f9039..f0ec7dbd0706b 100644 --- a/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportImportConfigurableProductWithImagesTest.xml +++ b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportImportConfigurableProductWithImagesTest.xml @@ -19,6 +19,9 @@ <group value="configurable_product"/> </annotations> <before> + <!-- Add downloadable domains --> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> + <!-- Create sample data: 1. Create simple products --> <createData entity="ApiCategory" stepKey="createCategory"/> @@ -128,6 +131,9 @@ <actionGroup ref="deleteAllExportedFiles" stepKey="clearExportedFilesList"/> </before> <after> + <!-- Remove downloadable domains --> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> + <!-- Delete created data --> <deleteData createDataKey="createFirstSimpleProduct" stepKey="deleteFisrtSimpleProduct"/> <deleteData createDataKey="createSecondSimpleProduct" stepKey="deleteSecondSimpleProduct"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml index 8cb0d5fde9863..20c1acaf8d612 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest.xml @@ -37,12 +37,16 @@ <group value="catalog"/> </annotations> <before> + <!-- Add downloadable domains --> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--Create product--> <comment userInput="Create product" stepKey="commentCreateProduct"/> <createData entity="SimpleProduct2" stepKey="createProduct"/> </before> <after> + <!-- Remove downloadable domains --> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <!--Delete product--> <comment userInput="Delete product" stepKey="commentDeleteProduct"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/EditDownloadableProductWithSeparateLinksFromCartTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/EditDownloadableProductWithSeparateLinksFromCartTest.xml index 0b905964fd2d9..274dd39468a2b 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/EditDownloadableProductWithSeparateLinksFromCartTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/EditDownloadableProductWithSeparateLinksFromCartTest.xml @@ -18,6 +18,9 @@ <group value="Downloadable"/> </annotations> <before> + <!-- Add downloadable domains --> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> + <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -61,6 +64,9 @@ <actionGroup ref="saveProductForm" stepKey="saveProduct"/> </before> <after> + <!-- Remove downloadable domains --> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> + <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/SelectAllDownloadableLinksDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/SelectAllDownloadableLinksDownloadableProductTest.xml index 94940f0e08195..f9ca6fea09cf0 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/SelectAllDownloadableLinksDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/SelectAllDownloadableLinksDownloadableProductTest.xml @@ -18,6 +18,9 @@ <group value="Downloadable"/> </annotations> <before> + <!-- Add downloadable domains --> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> + <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -61,6 +64,9 @@ <actionGroup ref="saveProductForm" stepKey="saveProduct"/> </before> <after> + <!-- Remove downloadable domains --> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> + <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyDisableDownloadableProductSamplesAreNotAccessibleTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyDisableDownloadableProductSamplesAreNotAccessibleTest.xml index f29bbcf925e26..ba2e3453a6d99 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyDisableDownloadableProductSamplesAreNotAccessibleTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyDisableDownloadableProductSamplesAreNotAccessibleTest.xml @@ -21,6 +21,9 @@ <group value="catalog"/> </annotations> <before> + <!-- Add downloadable domains --> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> + <!-- Create category --> <createData entity="_defaultCategory" stepKey="createCategory"/> @@ -40,6 +43,9 @@ </createData> </before> <after> + <!-- Remove downloadable domains --> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> + <!-- Delete product --> <deleteData createDataKey="createProduct" stepKey="deleteDownloadableProduct"/> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOpenAndFillCreditMemoRefundActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOpenAndFillCreditMemoRefundActionGroup.xml index 60134ee7e039c..78717e9c2f963 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOpenAndFillCreditMemoRefundActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOpenAndFillCreditMemoRefundActionGroup.xml @@ -35,7 +35,6 @@ <fillField userInput="{{adjustmentRefund}}" selector="{{AdminCreditMemoTotalSection.adjustmentRefund}}" stepKey="fillAdjustmentRefund"/> <fillField userInput="{{adjustmentFee}}" selector="{{AdminCreditMemoTotalSection.adjustmentFee}}" stepKey="fillAdjustmentFee"/> <checkOption selector="{{AdminCreditMemoTotalSection.emailCopy}}" stepKey="checkSendEmailCopy"/> - <conditionalClick selector="{{AdminCreditMemoTotalSection.updateTotals}}" dependentSelector="{{AdminCreditMemoTotalSection.disabledUpdateTotals}}" visible="false" stepKey="clickUpdateTotalsButton"/> </actionGroup> <!-- Open and fill CreditMemo refund with back to stock --> diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php index 53c429ee5f20e..e4ad1fcc3c5fa 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php @@ -19,11 +19,6 @@ /** @var QuoteRepository $quoteRepository */ $quoteRepository = $objectManager->get(QuoteRepository::class); -/** @var Magento\Store\Model\Store $store */ -$store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); -$store->load('fixture_second_store'); -$storeId = $store->getId(); - $quotes = [ 'quote for first store' => [ 'store' => 1, diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php index af008a28d611b..39cd8954df160 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php @@ -8,7 +8,8 @@ /** @var \Magento\Store\Model\Store $store */ $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); -if (!$store->load('fixture_second_store', 'code')->getId()) { +$storeId = $store->load('fixture_second_store', 'code')->getId(); +if (!$storeId) { $websiteId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Store\Model\StoreManagerInterface::class )->getWebsite() @@ -30,4 +31,6 @@ 1 ); $store->save(); + + $storeId = $store->getId(); } From f3ec9ddcf88f763f92a6583209c74b899033dea5 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 14 Oct 2019 07:53:17 -0500 Subject: [PATCH 359/372] MC-18527: Merge release branch into 2.3-develop - skip MFTF test --- .../AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml index ec0d86ac066fd..41d3ca3020c98 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml @@ -18,6 +18,9 @@ <testCaseId value="MC-11146"/> <group value="catalog"/> <group value="indexer"/> + <skip> + <issueId value="MC-20392"/> + </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> From 8d406c70120a8972806e07388a183d095197508e Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 14 Oct 2019 09:11:25 -0500 Subject: [PATCH 360/372] MC-18527: Merge release branch into 2.3-develop - fix merge conflict --- ...ceCatalogSearchDownloadableProductTest.xml | 2 +- .../Api/ProductRepositoryInterfaceTest.php | 113 ++++++++++++++++-- 2 files changed, 101 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml index 2a320fa674e74..b5f437996d69b 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml @@ -44,7 +44,7 @@ </annotations> <before> <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> - <createData entity="ApiDownloadableProduct" stepKey="product"/> + <createData entity="ApiDownloadableProductUnderscoredSku" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> </createData> diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 2772e80490278..a0a620ade50c3 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -25,6 +25,8 @@ use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; /** + * Test for \Magento\Catalog\Api\ProductRepositoryInterface + * * @magentoAppIsolation enabled * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -83,6 +85,8 @@ protected function tearDown() } /** + * Test get() method + * * @magentoApiDataFixture Magento/Catalog/_files/products_related.php */ public function testGet() @@ -96,6 +100,8 @@ public function testGet() } /** + * Get product + * * @param string $sku * @param string|null $storeCode * @return array|bool|float|int|string @@ -113,11 +119,14 @@ protected function getProduct($sku, $storeCode = null) 'operation' => self::SERVICE_NAME . 'Get', ], ]; - $response = $this->_webApiCall($serviceInfo, ['sku' => $sku], null, $storeCode); + return $response; } + /** + * Test get() method with invalid sku + */ public function testGetNoSuchEntityException() { $invalidSku = '(nonExistingSku)'; @@ -152,6 +161,8 @@ public function testGetNoSuchEntityException() } /** + * Product creation provider + * * @return array */ public function productCreationProvider() @@ -162,6 +173,7 @@ public function productCreationProvider() $data ); }; + return [ [$productBuilder([ProductInterface::TYPE_ID => 'simple', ProductInterface::SKU => 'psku-test-1'])], [$productBuilder([ProductInterface::TYPE_ID => 'virtual', ProductInterface::SKU => 'psku-test-2'])], @@ -188,6 +200,7 @@ private function loadWebsiteByCode($websiteCode) /** * Test removing association between product and website 1 + * * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php */ public function testUpdateWithDeleteWebsites() @@ -211,6 +224,7 @@ public function testUpdateWithDeleteWebsites() /** * Test removing all website associations + * * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php */ public function testDeleteAllWebsiteAssociations() @@ -229,6 +243,8 @@ public function testDeleteAllWebsiteAssociations() } /** + * Test create() method with multiple websites + * * @magentoApiDataFixture Magento/Catalog/_files/second_website.php */ public function testCreateWithMultipleWebsites() @@ -332,6 +348,8 @@ public function testUpdateWithoutWebsiteIds() } /** + * Test create() method + * * @dataProvider productCreationProvider */ public function testCreate($product) @@ -399,6 +417,9 @@ public function testCreateAllStoreCodeForSingleWebsite($fixtureProduct) $this->deleteProduct($fixtureProduct[ProductInterface::SKU]); } + /** + * Test create() method with invalid price format + */ public function testCreateInvalidPriceFormat() { $this->_markTestAsRestOnly("In case of SOAP type casting is handled by PHP SoapServer, no need to test it"); @@ -435,6 +456,9 @@ public function testDeleteAllStoreCode($fixtureProduct) $this->getProduct($sku); } + /** + * Test product links + */ public function testProductLinks() { // Create simple product @@ -468,7 +492,6 @@ public function testProductLinks() ProductInterface::TYPE_ID => 'simple', ProductInterface::PRICE => 100, ProductInterface::STATUS => 1, - ProductInterface::TYPE_ID => 'simple', ProductInterface::ATTRIBUTE_SET_ID => 4, "product_links" => [$productLinkData] ]; @@ -531,6 +554,8 @@ public function testProductLinks() } /** + * Get options data + * * @param string $productSku * @return array */ @@ -570,6 +595,9 @@ protected function getOptionsData($productSku) ]; } + /** + * Test product options + */ public function testProductOptions() { //Create product with options @@ -631,6 +659,9 @@ public function testProductOptions() $this->deleteProduct($productData[ProductInterface::SKU]); } + /** + * Test product with media gallery + */ public function testProductWithMediaGallery() { $testImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg'; @@ -663,7 +694,7 @@ public function testProductWithMediaGallery() 'position' => 2, 'media_type' => 'image', 'disabled' => false, - 'types' => ['image', 'small_image'], + 'types' => [], 'file' => '/t/i/' . $filename2, ], ]; @@ -676,7 +707,7 @@ public function testProductWithMediaGallery() 'label' => 'tiny1_new_label', 'position' => 1, 'disabled' => false, - 'types' => ['image', 'small_image'], + 'types' => [], 'file' => '/t/i/' . $filename1, ], ]; @@ -690,7 +721,7 @@ public function testProductWithMediaGallery() 'media_type' => 'image', 'position' => 1, 'disabled' => false, - 'types' => ['image', 'small_image'], + 'types' => [], 'file' => '/t/i/' . $filename1, ] ]; @@ -710,6 +741,8 @@ public function testProductWithMediaGallery() } /** + * Test update() method + * * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php */ public function testUpdate() @@ -753,15 +786,18 @@ public function testUpdateWithExtensionAttributes(): void } /** + * Update product + * * @param array $product * @return array|bool|float|int|string */ protected function updateProduct($product) { if (isset($product['custom_attributes'])) { - foreach ($product['custom_attributes'] as &$customAttribute) { - if ($customAttribute['attribute_code'] == 'category_ids' - && !is_array($customAttribute['value']) + $countOfProductCustomAttributes = sizeof($product['custom_attributes']); + for ($i = 0; $i < $countOfProductCustomAttributes; $i++) { + if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids' + && !is_array($product['custom_attributes'][$i]['value']) ) { $customAttribute['value'] = [""]; } @@ -789,6 +825,8 @@ protected function updateProduct($product) } /** + * Test delete() method + * * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php */ public function testDelete() @@ -798,6 +836,8 @@ public function testDelete() } /** + * Test getList() method + * * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php */ public function testGetList() @@ -860,6 +900,8 @@ public function testGetList() } /** + * Test getList() method with additional params + * * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php */ public function testGetListWithAdditionalParams() @@ -899,6 +941,8 @@ public function testGetListWithAdditionalParams() } /** + * Test getList() method with filtering by website + * * @magentoApiDataFixture Magento/Catalog/_files/products_with_websites_and_stores.php * @return void */ @@ -986,6 +1030,11 @@ public function testGetListWithFilteringByStore(array $searchCriteria, array $sk } } + /** + * Test getList() method with filtering by store data provider + * + * @return array + */ public function testGetListWithFilteringByStoreDataProvider() { return [ @@ -1025,6 +1074,8 @@ public function testGetListWithFilteringByStoreDataProvider() } /** + * Test getList() method with multiple filter groups and sorting and pagination + * * @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php */ public function testGetListWithMultipleFilterGroupsAndSortingAndPagination() @@ -1094,6 +1145,8 @@ public function testGetListWithMultipleFilterGroupsAndSortingAndPagination() } /** + * Convert custom attributes to associative array + * * @param $customAttributes * @return array */ @@ -1103,10 +1156,13 @@ protected function convertCustomAttributesToAssociativeArray($customAttributes) foreach ($customAttributes as $customAttribute) { $converted[$customAttribute['attribute_code']] = $customAttribute['value']; } + return $converted; } /** + * Convert associative array to custom attributes + * * @param $data * @return array */ @@ -1116,10 +1172,13 @@ protected function convertAssociativeArrayToCustomAttributes($data) foreach ($data as $attributeCode => $attributeValue) { $customAttributes[] = ['attribute_code' => $attributeCode, 'value' => $attributeValue]; } + return $customAttributes; } /** + * Test eav attributes + * * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php */ public function testEavAttributes() @@ -1163,7 +1222,6 @@ protected function getSimpleProductData($productData = []) ProductInterface::TYPE_ID => 'simple', ProductInterface::PRICE => 3.62, ProductInterface::STATUS => 1, - ProductInterface::TYPE_ID => 'simple', ProductInterface::ATTRIBUTE_SET_ID => 4, 'custom_attributes' => [ ['attribute_code' => 'cost', 'value' => ''], @@ -1173,6 +1231,8 @@ protected function getSimpleProductData($productData = []) } /** + * Save Product + * * @param $product * @param string|null $storeCode * @return mixed @@ -1180,9 +1240,10 @@ protected function getSimpleProductData($productData = []) protected function saveProduct($product, $storeCode = null) { if (isset($product['custom_attributes'])) { - foreach ($product['custom_attributes'] as &$customAttribute) { - if ($customAttribute['attribute_code'] == 'category_ids' - && !is_array($customAttribute['value']) + $countOfProductCustomAttributes = sizeof($product['custom_attributes']); + for ($i = 0; $i < $countOfProductCustomAttributes; $i++) { + if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids' + && !is_array($product['custom_attributes'][$i]['value']) ) { $customAttribute['value'] = [""]; } @@ -1200,6 +1261,7 @@ protected function saveProduct($product, $storeCode = null) ], ]; $requestData = ['product' => $product]; + return $this->_webApiCall($serviceInfo, $requestData, null, $storeCode); } @@ -1227,6 +1289,9 @@ protected function deleteProduct($sku) $this->_webApiCall($serviceInfo, ['sku' => $sku]) : $this->_webApiCall($serviceInfo); } + /** + * Test tier prices + */ public function testTierPrices() { // create a product with tier prices @@ -1311,6 +1376,8 @@ public function testTierPrices() } /** + * Get stock item data + * * @return array */ private function getStockItemData() @@ -1343,6 +1410,8 @@ private function getStockItemData() } /** + * Test product category links + * * @magentoApiDataFixture Magento/Catalog/_files/category_product.php */ public function testProductCategoryLinks() @@ -1365,6 +1434,8 @@ public function testProductCategoryLinks() } /** + * Test update product category without categories + * * @magentoApiDataFixture Magento/Catalog/_files/category_product.php */ public function testUpdateProductCategoryLinksNullOrNotExists() @@ -1386,6 +1457,8 @@ public function testUpdateProductCategoryLinksNullOrNotExists() } /** + * Test update product category links position + * * @magentoApiDataFixture Magento/Catalog/_files/category_product.php */ public function testUpdateProductCategoryLinksPosistion() @@ -1403,6 +1476,8 @@ public function testUpdateProductCategoryLinksPosistion() } /** + * Test update product category links unassing + * * @magentoApiDataFixture Magento/Catalog/_files/category_product.php */ public function testUpdateProductCategoryLinksUnassign() @@ -1415,6 +1490,8 @@ public function testUpdateProductCategoryLinksUnassign() } /** + * Get media gallery data + * * @param $filename1 * @param $encodedImage * @param $filename2 @@ -1440,7 +1517,7 @@ private function getMediaGalleryData($filename1, $encodedImage, $filename2) 'media_type' => 'image', 'disabled' => false, 'label' => 'tiny2', - 'types' => ['image', 'small_image'], + 'types' => [], 'content' => [ 'type' => 'image/jpeg', 'name' => $filename2, @@ -1450,6 +1527,9 @@ private function getMediaGalleryData($filename1, $encodedImage, $filename2) ]; } + /** + * Test special price + */ public function testSpecialPrice() { $productData = $this->getSimpleProductData(); @@ -1499,6 +1579,9 @@ public function testResetSpecialPrice() $this->assertFalse(array_key_exists(self::KEY_SPECIAL_PRICE, $customAttributes)); } + /** + * Test update status + */ public function testUpdateStatus() { // Create simple product @@ -1571,6 +1654,8 @@ public function testUpdateMultiselectAttributes() } /** + * Get attribute options + * * @param string $attributeCode * @return array|bool|float|int|string */ @@ -1592,6 +1677,8 @@ private function getAttributeOptions($attributeCode) } /** + * Assert multiselect value + * * @param string $productSku * @param string $multiselectAttributeCode * @param string $expectedMultiselectValue From b559f56722173875263f12bc0bc47e5e0fc74c90 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 14 Oct 2019 12:26:47 -0500 Subject: [PATCH 361/372] MC-18527: Merge release branch into 2.3-develop - fix failing tests --- ...atalogSearchDownloadableBySkuWithHyphenTest.xml | 4 ++++ .../Catalog/Api/ProductRepositoryInterfaceTest.php | 14 ++++++-------- .../product_downloadable_with_download_limit.php | 5 +++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest.xml index 7174122760576..7c415a8edccc4 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest.xml @@ -20,6 +20,7 @@ <group value="SearchEngineMysql"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -28,5 +29,8 @@ <requiredEntity createDataKey="product"/> </createData> </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> + </after> </test> </tests> diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index a0a620ade50c3..ed67f41a78234 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -794,10 +794,9 @@ public function testUpdateWithExtensionAttributes(): void protected function updateProduct($product) { if (isset($product['custom_attributes'])) { - $countOfProductCustomAttributes = sizeof($product['custom_attributes']); - for ($i = 0; $i < $countOfProductCustomAttributes; $i++) { - if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids' - && !is_array($product['custom_attributes'][$i]['value']) + foreach ($product['custom_attributes'] as &$customAttribute) { + if ($customAttribute['attribute_code'] == 'category_ids' + && !is_array($customAttribute['value']) ) { $customAttribute['value'] = [""]; } @@ -1240,10 +1239,9 @@ protected function getSimpleProductData($productData = []) protected function saveProduct($product, $storeCode = null) { if (isset($product['custom_attributes'])) { - $countOfProductCustomAttributes = sizeof($product['custom_attributes']); - for ($i = 0; $i < $countOfProductCustomAttributes; $i++) { - if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids' - && !is_array($product['custom_attributes'][$i]['value']) + foreach ($product['custom_attributes'] as &$customAttribute) { + if ($customAttribute['attribute_code'] == 'category_ids' + && !is_array($customAttribute['value']) ) { $customAttribute['value'] = [""]; } diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_download_limit.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_download_limit.php index 7f1701d4ca6ac..f0c6e013a9d95 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_download_limit.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_download_limit.php @@ -15,6 +15,11 @@ use Magento\Downloadable\Model\Link; use Magento\Downloadable\Model\Product\Type; use Magento\TestFramework\Helper\Bootstrap; +use Magento\Downloadable\Api\DomainManagerInterface; + +/** @var DomainManagerInterface $domainManager */ +$domainManager = Bootstrap::getObjectManager()->get(DomainManagerInterface::class); +$domainManager->addDomains(['example.com']); /** @var ProductRepositoryInterface $productRepository */ $productRepository = Bootstrap::getObjectManager() From 6b9339ee46e58b32f03148f37a3a386a671c2bbb Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 15 Oct 2019 09:08:23 -0500 Subject: [PATCH 362/372] MC-18527: Merge release branch into 2.3-develop - update lock file --- composer.lock | 228 +++++++++++++++++++++++++------------------------- 1 file changed, 112 insertions(+), 116 deletions(-) diff --git a/composer.lock b/composer.lock index 906cee9da4764..6838734cc0610 100644 --- a/composer.lock +++ b/composer.lock @@ -1389,16 +1389,16 @@ }, { "name": "php-amqplib/php-amqplib", - "version": "v2.10.0", + "version": "v2.10.1", "source": { "type": "git", "url": "https://github.com/php-amqplib/php-amqplib.git", - "reference": "04e5366f032906d5f716890427e425e71307d3a8" + "reference": "6e2b2501e021e994fb64429e5a78118f83b5c200" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/04e5366f032906d5f716890427e425e71307d3a8", - "reference": "04e5366f032906d5f716890427e425e71307d3a8", + "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/6e2b2501e021e994fb64429e5a78118f83b5c200", + "reference": "6e2b2501e021e994fb64429e5a78118f83b5c200", "shasum": "" }, "require": { @@ -1412,7 +1412,6 @@ "require-dev": { "ext-curl": "*", "nategood/httpful": "^0.2.20", - "phpdocumentor/phpdocumentor": "dev-master", "phpunit/phpunit": "^5.7|^6.5|^7.0", "squizlabs/php_codesniffer": "^2.5" }, @@ -1459,7 +1458,7 @@ "queue", "rabbitmq" ], - "time": "2019-08-08T18:28:18+00:00" + "time": "2019-10-10T13:23:40+00:00" }, { "name": "phpseclib/mcrypt_compat", @@ -2082,16 +2081,16 @@ }, { "name": "symfony/css-selector", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03" + "reference": "f4b3ff6a549d9ed28b2b0ecd1781bf67cf220ee9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/c6e5e2a00db768c92c3ae131532af4e1acc7bd03", - "reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/f4b3ff6a549d9ed28b2b0ecd1781bf67cf220ee9", + "reference": "f4b3ff6a549d9ed28b2b0ecd1781bf67cf220ee9", "shasum": "" }, "require": { @@ -2131,20 +2130,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2019-08-20T14:07:54+00:00" + "time": "2019-10-02T08:36:26+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2" + "reference": "6229f58993e5a157f6096fc7145c0717d0be8807" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/429d0a1451d4c9c4abe1959b2986b88794b9b7d2", - "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6229f58993e5a157f6096fc7145c0717d0be8807", + "reference": "6229f58993e5a157f6096fc7145c0717d0be8807", "shasum": "" }, "require": { @@ -2201,20 +2200,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-10-01T16:40:32+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.5", + "version": "v1.1.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "c61766f4440ca687de1084a5c00b08e167a2575c" + "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c61766f4440ca687de1084a5c00b08e167a2575c", - "reference": "c61766f4440ca687de1084a5c00b08e167a2575c", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c43ab685673fb6c8d84220c77897b1d6cdbe1d18", + "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18", "shasum": "" }, "require": { @@ -2259,11 +2258,11 @@ "interoperability", "standards" ], - "time": "2019-06-20T06:46:26+00:00" + "time": "2019-09-17T09:54:03+00:00" }, { "name": "symfony/filesystem", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", @@ -2313,16 +2312,16 @@ }, { "name": "symfony/finder", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2" + "reference": "5e575faa95548d0586f6bedaeabec259714e44d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/86c1c929f0a4b24812e1eb109262fc3372c8e9f2", - "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2", + "url": "https://api.github.com/repos/symfony/finder/zipball/5e575faa95548d0586f6bedaeabec259714e44d1", + "reference": "5e575faa95548d0586f6bedaeabec259714e44d1", "shasum": "" }, "require": { @@ -2358,7 +2357,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2019-08-14T12:26:46+00:00" + "time": "2019-09-16T11:29:48+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2479,16 +2478,16 @@ }, { "name": "symfony/process", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a" + "reference": "50556892f3cc47d4200bfd1075314139c4c9ff4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e89969c00d762349f078db1128506f7f3dcc0d4a", - "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a", + "url": "https://api.github.com/repos/symfony/process/zipball/50556892f3cc47d4200bfd1075314139c4c9ff4b", + "reference": "50556892f3cc47d4200bfd1075314139c4c9ff4b", "shasum": "" }, "require": { @@ -2524,7 +2523,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-09-26T21:17:10+00:00" }, { "name": "tedivm/jshrink", @@ -3450,16 +3449,16 @@ }, { "name": "zendframework/zend-form", - "version": "2.14.1", + "version": "2.14.3", "source": { "type": "git", "url": "https://github.com/zendframework/zend-form.git", - "reference": "ff9385b7d0d93d9bdbc2aa4af82ab616dbc7d4be" + "reference": "0b1616c59b1f3df194284e26f98c81ad0c377871" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-form/zipball/ff9385b7d0d93d9bdbc2aa4af82ab616dbc7d4be", - "reference": "ff9385b7d0d93d9bdbc2aa4af82ab616dbc7d4be", + "url": "https://api.github.com/repos/zendframework/zend-form/zipball/0b1616c59b1f3df194284e26f98c81ad0c377871", + "reference": "0b1616c59b1f3df194284e26f98c81ad0c377871", "shasum": "" }, "require": { @@ -3524,7 +3523,7 @@ "form", "zf" ], - "time": "2019-02-26T18:13:31+00:00" + "time": "2019-10-04T10:46:36+00:00" }, { "name": "zendframework/zend-http", @@ -3583,16 +3582,16 @@ }, { "name": "zendframework/zend-hydrator", - "version": "2.4.1", + "version": "2.4.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-hydrator.git", - "reference": "70b02f4d8676e64af932625751750b5ca72fff3a" + "reference": "2bfc6845019e7b6d38b0ab5e55190244dc510285" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-hydrator/zipball/70b02f4d8676e64af932625751750b5ca72fff3a", - "reference": "70b02f4d8676e64af932625751750b5ca72fff3a", + "url": "https://api.github.com/repos/zendframework/zend-hydrator/zipball/2bfc6845019e7b6d38b0ab5e55190244dc510285", + "reference": "2bfc6845019e7b6d38b0ab5e55190244dc510285", "shasum": "" }, "require": { @@ -3617,10 +3616,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-release-1.0": "1.0.x-dev", - "dev-release-1.1": "1.1.x-dev", - "dev-master": "2.4.x-dev", - "dev-develop": "2.5.x-dev" + "dev-release-2.4": "2.4.x-dev" }, "zf": { "component": "Zend\\Hydrator", @@ -3642,7 +3638,7 @@ "hydrator", "zf" ], - "time": "2018-11-19T19:16:10+00:00" + "time": "2019-10-04T11:17:36+00:00" }, { "name": "zendframework/zend-i18n", @@ -4678,16 +4674,16 @@ }, { "name": "zendframework/zend-uri", - "version": "2.7.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-uri.git", - "reference": "b2785cd38fe379a784645449db86f21b7739b1ee" + "reference": "bfc4a5b9a309711e968d7c72afae4ac50c650083" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/b2785cd38fe379a784645449db86f21b7739b1ee", - "reference": "b2785cd38fe379a784645449db86f21b7739b1ee", + "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/bfc4a5b9a309711e968d7c72afae4ac50c650083", + "reference": "bfc4a5b9a309711e968d7c72afae4ac50c650083", "shasum": "" }, "require": { @@ -4721,20 +4717,20 @@ "uri", "zf" ], - "time": "2019-02-27T21:39:04+00:00" + "time": "2019-10-07T13:35:33+00:00" }, { "name": "zendframework/zend-validator", - "version": "2.12.0", + "version": "2.12.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-validator.git", - "reference": "64c33668e5fa2d39c6289a878f927ea2b0850c30" + "reference": "7b870a7515f3a35afbecc39d63f34a861f40f58b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/64c33668e5fa2d39c6289a878f927ea2b0850c30", - "reference": "64c33668e5fa2d39c6289a878f927ea2b0850c30", + "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/7b870a7515f3a35afbecc39d63f34a861f40f58b", + "reference": "7b870a7515f3a35afbecc39d63f34a861f40f58b", "shasum": "" }, "require": { @@ -4788,26 +4784,26 @@ "license": [ "BSD-3-Clause" ], - "description": "provides a set of commonly needed validators", - "homepage": "https://github.com/zendframework/zend-validator", + "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", "keywords": [ + "ZendFramework", "validator", - "zf2" + "zf" ], - "time": "2019-01-30T14:26:10+00:00" + "time": "2019-10-12T12:17:57+00:00" }, { "name": "zendframework/zend-view", - "version": "2.11.2", + "version": "2.11.3", "source": { "type": "git", "url": "https://github.com/zendframework/zend-view.git", - "reference": "4f5cb653ed4c64bb8d9bf05b294300feb00c67f2" + "reference": "e766457bd6ce13c5354e443bb949511b6904d7f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-view/zipball/4f5cb653ed4c64bb8d9bf05b294300feb00c67f2", - "reference": "4f5cb653ed4c64bb8d9bf05b294300feb00c67f2", + "url": "https://api.github.com/repos/zendframework/zend-view/zipball/e766457bd6ce13c5354e443bb949511b6904d7f5", + "reference": "e766457bd6ce13c5354e443bb949511b6904d7f5", "shasum": "" }, "require": { @@ -4875,13 +4871,13 @@ "license": [ "BSD-3-Clause" ], - "description": "provides a system of helpers, output filters, and variable escaping", - "homepage": "https://github.com/zendframework/zend-view", + "description": "Flexible view layer supporting and providing multiple view layers, helpers, and more", "keywords": [ + "ZendFramework", "view", - "zf2" + "zf" ], - "time": "2019-02-19T17:40:15+00:00" + "time": "2019-10-11T21:10:04+00:00" } ], "packages-dev": [ @@ -6031,16 +6027,16 @@ }, { "name": "doctrine/annotations", - "version": "v1.7.0", + "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb" + "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/fa4c4e861e809d6a1103bd620cce63ed91aedfeb", - "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/904dca4eb10715b92569fbcd79e201d5c349b6bc", + "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc", "shasum": "" }, "require": { @@ -6049,7 +6045,7 @@ }, "require-dev": { "doctrine/cache": "1.*", - "phpunit/phpunit": "^7.5@dev" + "phpunit/phpunit": "^7.5" }, "type": "library", "extra": { @@ -6095,7 +6091,7 @@ "docblock", "parser" ], - "time": "2019-08-08T18:11:40+00:00" + "time": "2019-10-01T18:55:10+00:00" }, { "name": "doctrine/cache", @@ -6959,16 +6955,16 @@ }, { "name": "league/flysystem", - "version": "1.0.55", + "version": "1.0.56", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "33c91155537c6dc899eacdc54a13ac6303f156e6" + "reference": "90e3f83cb10ef6b058d70f95267030e7a6236518" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/33c91155537c6dc899eacdc54a13ac6303f156e6", - "reference": "33c91155537c6dc899eacdc54a13ac6303f156e6", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/90e3f83cb10ef6b058d70f95267030e7a6236518", + "reference": "90e3f83cb10ef6b058d70f95267030e7a6236518", "shasum": "" }, "require": { @@ -7039,7 +7035,7 @@ "sftp", "storage" ], - "time": "2019-08-24T11:17:19+00:00" + "time": "2019-10-12T13:05:59+00:00" }, { "name": "lusitanian/oauth", @@ -7866,22 +7862,22 @@ }, { "name": "phpspec/prophecy", - "version": "1.8.1", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76" + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76", - "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, @@ -7925,7 +7921,7 @@ "spy", "stub" ], - "time": "2019-06-13T12:50:23+00:00" + "time": "2019-10-03T11:07:50+00:00" }, { "name": "phpunit/php-code-coverage", @@ -9115,16 +9111,16 @@ }, { "name": "symfony/browser-kit", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "9e5dddb637b13db82e35695a8603fe6e118cc119" + "reference": "78b7611c45039e8ce81698be319851529bf040b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9e5dddb637b13db82e35695a8603fe6e118cc119", - "reference": "9e5dddb637b13db82e35695a8603fe6e118cc119", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/78b7611c45039e8ce81698be319851529bf040b1", + "reference": "78b7611c45039e8ce81698be319851529bf040b1", "shasum": "" }, "require": { @@ -9170,20 +9166,20 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-09-10T11:25:17+00:00" }, { "name": "symfony/config", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece" + "reference": "0acb26407a9e1a64a275142f0ae5e36436342720" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/07d49c0f823e0bc367c6d84e35b61419188a5ece", - "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece", + "url": "https://api.github.com/repos/symfony/config/zipball/0acb26407a9e1a64a275142f0ae5e36436342720", + "reference": "0acb26407a9e1a64a275142f0ae5e36436342720", "shasum": "" }, "require": { @@ -9234,20 +9230,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-09-19T15:51:53+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9" + "reference": "e1e0762a814b957a1092bff75a550db49724d05b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d3ad14b66ac773ba6123622eb9b5b010165fe3d9", - "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e1e0762a814b957a1092bff75a550db49724d05b", + "reference": "e1e0762a814b957a1092bff75a550db49724d05b", "shasum": "" }, "require": { @@ -9307,20 +9303,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-08-26T16:27:33+00:00" + "time": "2019-10-02T12:58:58+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "cc686552948d627528c0e2e759186dff67c2610e" + "reference": "e9f7b4d19d69b133bd638eeddcdc757723b4211f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/cc686552948d627528c0e2e759186dff67c2610e", - "reference": "cc686552948d627528c0e2e759186dff67c2610e", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/e9f7b4d19d69b133bd638eeddcdc757723b4211f", + "reference": "e9f7b4d19d69b133bd638eeddcdc757723b4211f", "shasum": "" }, "require": { @@ -9368,7 +9364,7 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-09-28T21:25:05+00:00" }, { "name": "symfony/http-foundation", @@ -9427,7 +9423,7 @@ }, { "name": "symfony/options-resolver", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", @@ -9709,16 +9705,16 @@ }, { "name": "symfony/service-contracts", - "version": "v1.1.6", + "version": "v1.1.7", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3" + "reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3", - "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffcde9615dc5bb4825b9f6aed07716f1f57faae0", + "reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0", "shasum": "" }, "require": { @@ -9763,11 +9759,11 @@ "interoperability", "standards" ], - "time": "2019-08-20T14:44:19+00:00" + "time": "2019-09-17T11:12:18+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -9817,16 +9813,16 @@ }, { "name": "symfony/yaml", - "version": "v4.3.4", + "version": "v4.3.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686" + "reference": "41e16350a2a1c7383c4735aa2f9fce74cf3d1178" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686", - "reference": "5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686", + "url": "https://api.github.com/repos/symfony/yaml/zipball/41e16350a2a1c7383c4735aa2f9fce74cf3d1178", + "reference": "41e16350a2a1c7383c4735aa2f9fce74cf3d1178", "shasum": "" }, "require": { @@ -9872,7 +9868,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2019-08-20T14:27:59+00:00" + "time": "2019-09-11T15:41:19+00:00" }, { "name": "theseer/fdomdocument", From e96697c94491ad905dafec88cb86a029329a4759 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 16 Oct 2019 08:30:14 -0500 Subject: [PATCH 363/372] MC-18527: Merge release branch into 2.3-develop - minor code changes --- .../Model/ResourceModel/Viewer/Logger.php | 3 +++ .../Adminhtml/Promo/Catalog/Save.php | 18 ++++-------------- .../Model/Indexer/ReindexRuleProduct.php | 4 +--- app/code/Magento/Customer/Model/Session.php | 4 ++-- .../Import/Product/Type/Downloadable.php | 19 +++++++++++++++++++ .../Magento/ImportExport/Model/Import.php | 3 +++ .../testsuite/Magento/Sales/_files/quotes.php | 7 +++++-- .../Magento/Store/_files/second_store.php | 5 +---- .../Magento/Framework/App/ProductMetadata.php | 5 ++--- 9 files changed, 40 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 1ade6e9d54fee..c66f31e3d3bcb 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -18,6 +18,9 @@ */ class Logger { + /** + * Admin Analytics usage version log table name + */ const LOG_TABLE_NAME = 'admin_analytics_usage_version_log'; /** diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 6d499b93e411f..4f58293d53359 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -12,7 +12,6 @@ use Magento\Framework\Registry; use Magento\Framework\Stdlib\DateTime\Filter\Date; use Magento\Framework\App\Request\DataPersistorInterface; -use Magento\Framework\Stdlib\DateTime\TimezoneInterface; /** * Save action for catalog rule @@ -26,27 +25,19 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog imple */ protected $dataPersistor; - /** - * @var TimezoneInterface - */ - private $localeDate; - /** * @param Context $context * @param Registry $coreRegistry * @param Date $dateFilter * @param DataPersistorInterface $dataPersistor - * @param TimezoneInterface $localeDate */ public function __construct( Context $context, Registry $coreRegistry, Date $dateFilter, - DataPersistorInterface $dataPersistor, - TimezoneInterface $localeDate + DataPersistorInterface $dataPersistor ) { $this->dataPersistor = $dataPersistor; - $this->localeDate = $localeDate; parent::__construct($context, $coreRegistry, $dateFilter); } @@ -55,15 +46,16 @@ public function __construct( * * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute() { if ($this->getRequest()->getPostValue()) { + /** @var \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface $ruleRepository */ $ruleRepository = $this->_objectManager->get( \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface::class ); + /** @var \Magento\CatalogRule\Model\Rule $model */ $model = $this->_objectManager->create(\Magento\CatalogRule\Model\Rule::class); @@ -73,9 +65,7 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); - if (!$this->getRequest()->getParam('from_date')) { - $data['from_date'] = $this->localeDate->formatDate(); - } + $filterValues = ['from_date' => $this->_dateFilter]; if ($this->getRequest()->getParam('to_date')) { $filterValues['to_date'] = $this->_dateFilter; diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php index 944710773123f..e589c8595ce2c 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php @@ -101,9 +101,7 @@ public function execute(Rule $rule, $batchCount, $useAdditionalTable = false) $scopeTz = new \DateTimeZone( $this->localeDate->getConfigTimezone(ScopeInterface::SCOPE_WEBSITE, $websiteId) ); - $fromTime = $rule->getFromDate() - ? (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp() - : 0; + $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp(); $toTime = $rule->getToDate() ? (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp() + IndexBuilder::SECONDS_IN_DAY - 1 : 0; diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php index 36b8fa9764c95..e9dc7700ec090 100644 --- a/app/code/Magento/Customer/Model/Session.php +++ b/app/code/Magento/Customer/Model/Session.php @@ -441,7 +441,7 @@ public function setCustomerAsLoggedIn($customer) } /** - * Sets customer data as logged in + * Sets customer as logged in * * @param CustomerData $customer * @return $this @@ -593,7 +593,7 @@ public function regenerateId() } /** - * Creates URL factory + * Creates URL object * * @return \Magento\Framework\UrlInterface */ diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index 1cfef359ca81a..c9cdf52f55dd1 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -15,18 +15,34 @@ /** * Class Downloadable * + * phpcs:disable Magento2.Commenting.ConstantsPHPDocFormatting * @SuppressWarnings(PHPMD.TooManyFields) */ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType { + /** + * Pair value separator. + */ const PAIR_VALUE_SEPARATOR = '='; + /** + * Default sort order + */ const DEFAULT_SORT_ORDER = 0; + /** + * Default number of downloads + */ const DEFAULT_NUMBER_OF_DOWNLOADS = 0; + /** + * Default is shareable + */ const DEFAULT_IS_SHAREABLE = 2; + /** + * Default website id + */ const DEFAULT_WEBSITE_ID = 0; /** @@ -64,6 +80,9 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ */ const COL_DOWNLOADABLE_LINKS = 'downloadable_links'; + /** + * Default group title + */ const DEFAULT_GROUP_TITLE = ''; /** diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index f3ed7e104bca7..cf20001882c0d 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -107,6 +107,9 @@ class Import extends AbstractModel */ const DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR = ','; + /** + * Import empty attribute default value + */ const DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT = '__EMPTY__VALUE__'; const DEFAULT_SIZE = 50; const MAX_IMPORT_CHUNKS = 4; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php index e4ad1fcc3c5fa..d1642239c70ca 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php @@ -7,6 +7,7 @@ use Magento\Quote\Model\QuoteFactory; use Magento\Quote\Model\QuoteRepository; +use Magento\Store\Model\Store; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\ObjectManager; @@ -18,13 +19,15 @@ $quoteFactory = $objectManager->get(QuoteFactory::class); /** @var QuoteRepository $quoteRepository */ $quoteRepository = $objectManager->get(QuoteRepository::class); +/** @var Store $store */ +$store = $objectManager->get(Store::class); $quotes = [ 'quote for first store' => [ - 'store' => 1, + 'store' => $store->load('default', 'code')->getId(), ], 'quote for second store' => [ - 'store' => $storeId, + 'store' => $store->load('test_second_store', 'code')->getId(), ], ]; diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php index 39cd8954df160..af008a28d611b 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store.php @@ -8,8 +8,7 @@ /** @var \Magento\Store\Model\Store $store */ $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); -$storeId = $store->load('fixture_second_store', 'code')->getId(); -if (!$storeId) { +if (!$store->load('fixture_second_store', 'code')->getId()) { $websiteId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Store\Model\StoreManagerInterface::class )->getWebsite() @@ -31,6 +30,4 @@ 1 ); $store->save(); - - $storeId = $store->getId(); } diff --git a/lib/internal/Magento/Framework/App/ProductMetadata.php b/lib/internal/Magento/Framework/App/ProductMetadata.php index 02861c8a224ad..052119713294b 100644 --- a/lib/internal/Magento/Framework/App/ProductMetadata.php +++ b/lib/internal/Magento/Framework/App/ProductMetadata.php @@ -67,7 +67,7 @@ public function __construct( CacheInterface $cache = null ) { $this->composerJsonFinder = $composerJsonFinder; - $this->cache = $cache ?? ObjectManager::getInstance()->get(CacheInterface::class); + $this->cache = $cache ?: ObjectManager::getInstance()->get(CacheInterface::class); } /** @@ -77,8 +77,7 @@ public function __construct( */ public function getVersion() { - $versionFromCache = $this->cache->load(self::VERSION_CACHE_KEY); - $this->version = $this->version ?: $versionFromCache; + $this->version = $this->version ?: $this->cache->load(self::VERSION_CACHE_KEY); if (!$this->version) { if (!($this->version = $this->getSystemPackageVersion())) { if ($this->getComposerInformation()->isMagentoRoot()) { From a1275c9bba90633b22c335a4eefc0188386050a2 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 16 Oct 2019 08:47:06 -0500 Subject: [PATCH 364/372] MC-18527: Merge release branch into 2.3-develop - fix merge conflict --- .../testsuite/Magento/Sales/_files/quotes.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php index d1642239c70ca..d59c615d7b2e6 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php @@ -5,6 +5,7 @@ */ declare(strict_types=1); +use Magento\Store\Model\StoreRepository; use Magento\Quote\Model\QuoteFactory; use Magento\Quote\Model\QuoteRepository; use Magento\Store\Model\Store; @@ -19,15 +20,18 @@ $quoteFactory = $objectManager->get(QuoteFactory::class); /** @var QuoteRepository $quoteRepository */ $quoteRepository = $objectManager->get(QuoteRepository::class); -/** @var Store $store */ -$store = $objectManager->get(Store::class); +/** @var StoreRepository $storeRepository */ +$storeRepository = $objectManager->get(StoreRepository::class); + +$defaultStore = $storeRepository->getActiveStoreByCode('default'); +$secondStore = $storeRepository->getActiveStoreByCode('fixture_second_store'); $quotes = [ 'quote for first store' => [ - 'store' => $store->load('default', 'code')->getId(), + 'store' => $defaultStore->getId(), ], 'quote for second store' => [ - 'store' => $store->load('test_second_store', 'code')->getId(), + 'store' => $secondStore->getId(), ], ]; From ab5f999775c7de95f56c8b809477f8e399c9ebe8 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 16 Oct 2019 08:48:30 -0500 Subject: [PATCH 365/372] MC-18527: Merge release branch into 2.3-develop - fix merge conflict --- dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php index d59c615d7b2e6..3c4c164f0a01f 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php @@ -8,7 +8,6 @@ use Magento\Store\Model\StoreRepository; use Magento\Quote\Model\QuoteFactory; use Magento\Quote\Model\QuoteRepository; -use Magento\Store\Model\Store; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\ObjectManager; From 2f84cb380e375ff02c116388002ea21f9d25d1d6 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Wed, 16 Oct 2019 10:20:59 -0500 Subject: [PATCH 366/372] MC-18527: Merge release branch into 2.3-develop - fix mftf test --- ...ualSelectAllDownloadableLinksDownloadableProductTest.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/ManualSelectAllDownloadableLinksDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/ManualSelectAllDownloadableLinksDownloadableProductTest.xml index b0424b1976c1c..a86fd544d24d6 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/ManualSelectAllDownloadableLinksDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/ManualSelectAllDownloadableLinksDownloadableProductTest.xml @@ -18,6 +18,9 @@ <group value="Downloadable"/> </annotations> <before> + <!-- Add downloadable domains --> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> + <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -61,6 +64,9 @@ <actionGroup ref="saveProductForm" stepKey="saveProduct"/> </before> <after> + <!-- Remove downloadable domains --> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> + <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> From 03aa99c8acc325edb236ea6ff72edab4cbe315dc Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 18 Oct 2019 16:22:05 -0500 Subject: [PATCH 367/372] MC-18527: Merge release branch into 2.3-develop - fix merge conflict --- composer.lock | 70 +++++---- .../MysqlMq/Model/QueueManagementTest.php | 140 +++++++++++++++--- 2 files changed, 151 insertions(+), 59 deletions(-) diff --git a/composer.lock b/composer.lock index 6838734cc0610..f8842a3f92c18 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8db6cec91148c8618af8fb7c56f2d063", + "content-hash": "be7c5337c409a82db70a53af87b1c521", "packages": [ { "name": "braintree/braintree_php", @@ -882,23 +882,23 @@ }, { "name": "justinrainbow/json-schema", - "version": "5.2.8", + "version": "5.2.9", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "dcb6e1006bb5fd1e392b4daa68932880f37550d4" + "reference": "44c6787311242a979fa15c704327c20e7221a0e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/dcb6e1006bb5fd1e392b4daa68932880f37550d4", - "reference": "dcb6e1006bb5fd1e392b4daa68932880f37550d4", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4", + "reference": "44c6787311242a979fa15c704327c20e7221a0e4", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20", + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", "json-schema/json-schema-test-suite": "1.2.0", "phpunit/phpunit": "^4.8.35" }, @@ -944,7 +944,7 @@ "json", "schema" ], - "time": "2019-01-14T23:55:14+00:00" + "time": "2019-09-25T14:49:45+00:00" }, { "name": "magento/composer", @@ -1233,16 +1233,16 @@ }, { "name": "paragonie/sodium_compat", - "version": "v1.11.1", + "version": "v1.11.4", "source": { "type": "git", "url": "https://github.com/paragonie/sodium_compat.git", - "reference": "a9f968bc99485f85f9303a8524c3485a7e87bc15" + "reference": "b7115d0a80d5f9e8ae4cbfdee59d1d39dcfc90ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/a9f968bc99485f85f9303a8524c3485a7e87bc15", - "reference": "a9f968bc99485f85f9303a8524c3485a7e87bc15", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/b7115d0a80d5f9e8ae4cbfdee59d1d39dcfc90ea", + "reference": "b7115d0a80d5f9e8ae4cbfdee59d1d39dcfc90ea", "shasum": "" }, "require": { @@ -1311,7 +1311,7 @@ "secret-key cryptography", "side-channel resistant" ], - "time": "2019-09-12T12:05:58+00:00" + "time": "2019-10-18T15:04:07+00:00" }, { "name": "pelago/emogrifier", @@ -4049,16 +4049,16 @@ }, { "name": "zendframework/zend-mime", - "version": "2.7.1", + "version": "2.7.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-mime.git", - "reference": "52ae5fa9f12845cae749271034a2d594f0e4c6f2" + "reference": "c91e0350be53cc9d29be15563445eec3b269d7c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-mime/zipball/52ae5fa9f12845cae749271034a2d594f0e4c6f2", - "reference": "52ae5fa9f12845cae749271034a2d594f0e4c6f2", + "url": "https://api.github.com/repos/zendframework/zend-mime/zipball/c91e0350be53cc9d29be15563445eec3b269d7c1", + "reference": "c91e0350be53cc9d29be15563445eec3b269d7c1", "shasum": "" }, "require": { @@ -4076,8 +4076,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" + "dev-master": "2.7.x-dev", + "dev-develop": "2.8.x-dev" } }, "autoload": { @@ -4090,13 +4090,12 @@ "BSD-3-Clause" ], "description": "Create and parse MIME messages and parts", - "homepage": "https://github.com/zendframework/zend-mime", "keywords": [ "ZendFramework", "mime", "zf" ], - "time": "2018-05-14T19:02:50+00:00" + "time": "2019-10-16T19:30:37+00:00" }, { "name": "zendframework/zend-modulemanager", @@ -4361,16 +4360,16 @@ }, { "name": "zendframework/zend-server", - "version": "2.8.0", + "version": "2.8.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-server.git", - "reference": "23a2e9a5599c83c05da831cb7c649e8a7809595e" + "reference": "d80c44700ebb92191dd9a3005316a6ab6637c0d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-server/zipball/23a2e9a5599c83c05da831cb7c649e8a7809595e", - "reference": "23a2e9a5599c83c05da831cb7c649e8a7809595e", + "url": "https://api.github.com/repos/zendframework/zend-server/zipball/d80c44700ebb92191dd9a3005316a6ab6637c0d1", + "reference": "d80c44700ebb92191dd9a3005316a6ab6637c0d1", "shasum": "" }, "require": { @@ -4404,7 +4403,7 @@ "server", "zf" ], - "time": "2018-04-30T22:21:28+00:00" + "time": "2019-10-16T18:27:05+00:00" }, { "name": "zendframework/zend-servicemanager", @@ -4626,16 +4625,16 @@ }, { "name": "zendframework/zend-text", - "version": "2.7.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-text.git", - "reference": "ca987dd4594f5f9508771fccd82c89bc7fbb39ac" + "reference": "41e32dafa4015e160e2f95a7039554385c71624d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-text/zipball/ca987dd4594f5f9508771fccd82c89bc7fbb39ac", - "reference": "ca987dd4594f5f9508771fccd82c89bc7fbb39ac", + "url": "https://api.github.com/repos/zendframework/zend-text/zipball/41e32dafa4015e160e2f95a7039554385c71624d", + "reference": "41e32dafa4015e160e2f95a7039554385c71624d", "shasum": "" }, "require": { @@ -4670,7 +4669,7 @@ "text", "zf" ], - "time": "2018-04-30T14:55:10+00:00" + "time": "2019-10-16T20:36:27+00:00" }, { "name": "zendframework/zend-uri", @@ -6955,16 +6954,16 @@ }, { "name": "league/flysystem", - "version": "1.0.56", + "version": "1.0.57", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "90e3f83cb10ef6b058d70f95267030e7a6236518" + "reference": "0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/90e3f83cb10ef6b058d70f95267030e7a6236518", - "reference": "90e3f83cb10ef6b058d70f95267030e7a6236518", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a", + "reference": "0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a", "shasum": "" }, "require": { @@ -7035,7 +7034,7 @@ "sftp", "storage" ], - "time": "2019-10-12T13:05:59+00:00" + "time": "2019-10-16T21:01:05+00:00" }, { "name": "lusitanian/oauth", @@ -10111,7 +10110,6 @@ "ext-pdo_mysql": "*", "ext-simplexml": "*", "ext-soap": "*", - "ext-spl": "*", "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*" diff --git a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php index 8fbbe800d6735..d3228bd514400 100644 --- a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\MysqlMq\Model; /** @@ -23,27 +25,26 @@ class QueueManagementTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->queueManagement = $this->objectManager->create(\Magento\MysqlMq\Model\QueueManagement::class); + $this->queueManagement = $this->objectManager->create(QueueManagement::class); } /** * @magentoDataFixture Magento/MysqlMq/_files/queues.php */ - public function testAllFlows() + public function testMessageReading() { - $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1', 'queue2']); - $this->queueManagement->addMessageToQueues('topic2', 'messageBody2', ['queue2', 'queue3']); - $this->queueManagement->addMessageToQueues('topic3', 'messageBody3', ['queue1', 'queue3']); - $this->queueManagement->addMessageToQueues('topic4', 'messageBody4', ['queue1', 'queue2', 'queue3']); + $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1']); + $this->queueManagement->addMessageToQueues('topic2', 'messageBody2', ['queue1']); + $this->queueManagement->addMessageToQueues('topic3', 'messageBody3', ['queue1']); $maxMessagesNumber = 2; - $messages = $this->queueManagement->readMessages('queue3', $maxMessagesNumber); + $messages = $this->queueManagement->readMessages('queue1', $maxMessagesNumber); $this->assertCount($maxMessagesNumber, $messages); $firstMessage = array_shift($messages); - $this->assertEquals('topic2', $firstMessage[QueueManagement::MESSAGE_TOPIC]); - $this->assertEquals('messageBody2', $firstMessage[QueueManagement::MESSAGE_BODY]); - $this->assertEquals('queue3', $firstMessage[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals('topic1', $firstMessage[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody1', $firstMessage[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue1', $firstMessage[QueueManagement::MESSAGE_QUEUE_NAME]); $this->assertEquals( QueueManagement::MESSAGE_STATUS_IN_PROGRESS, $firstMessage[QueueManagement::MESSAGE_STATUS] @@ -55,9 +56,9 @@ public function testAllFlows() $this->assertCount(12, date_parse($firstMessage[QueueManagement::MESSAGE_UPDATED_AT])); $secondMessage = array_shift($messages); - $this->assertEquals('topic3', $secondMessage[QueueManagement::MESSAGE_TOPIC]); - $this->assertEquals('messageBody3', $secondMessage[QueueManagement::MESSAGE_BODY]); - $this->assertEquals('queue3', $secondMessage[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals('topic2', $secondMessage[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody2', $secondMessage[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue1', $secondMessage[QueueManagement::MESSAGE_QUEUE_NAME]); $this->assertEquals( QueueManagement::MESSAGE_STATUS_IN_PROGRESS, $secondMessage[QueueManagement::MESSAGE_STATUS] @@ -67,35 +68,128 @@ public function testAllFlows() $this->assertTrue(is_numeric($secondMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID])); $this->assertEquals(0, $secondMessage[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); $this->assertCount(12, date_parse($secondMessage[QueueManagement::MESSAGE_UPDATED_AT])); + } + + /** + * @magentoDataFixture Magento/MysqlMq/_files/queues.php + */ + public function testMessageReadingMultipleQueues() + { + $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1']); + $this->queueManagement->addMessageToQueues('topic2', 'messageBody2', ['queue1', 'queue2']); + $this->queueManagement->addMessageToQueues('topic3', 'messageBody3', ['queue2']); + + $maxMessagesNumber = 2; + $messages = $this->queueManagement->readMessages('queue1', $maxMessagesNumber); + $this->assertCount($maxMessagesNumber, $messages); + + $message = array_shift($messages); + $this->assertEquals('topic1', $message[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody1', $message[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue1', $message[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals( + QueueManagement::MESSAGE_STATUS_IN_PROGRESS, + $message[QueueManagement::MESSAGE_STATUS] + ); + + $message= array_shift($messages); + $this->assertEquals('topic2', $message[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody2', $message[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue1', $message[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals( + QueueManagement::MESSAGE_STATUS_IN_PROGRESS, + $message[QueueManagement::MESSAGE_STATUS] + ); + + $maxMessagesNumber = 2; + $messages = $this->queueManagement->readMessages('queue2', $maxMessagesNumber); + $this->assertCount($maxMessagesNumber, $messages); + + $message= array_shift($messages); + $this->assertEquals('topic2', $message[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody2', $message[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue2', $message[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals( + QueueManagement::MESSAGE_STATUS_IN_PROGRESS, + $message[QueueManagement::MESSAGE_STATUS] + ); + + $message = array_shift($messages); + $this->assertEquals('topic3', $message[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody3', $message[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue2', $message[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals( + QueueManagement::MESSAGE_STATUS_IN_PROGRESS, + $message[QueueManagement::MESSAGE_STATUS] + ); + } + + /** + * @magentoDataFixture Magento/MysqlMq/_files/queues.php + */ + public function testChangingMessageStatus() + { + $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1']); + $this->queueManagement->addMessageToQueues('topic2', 'messageBody2', ['queue1']); + $this->queueManagement->addMessageToQueues('topic3', 'messageBody3', ['queue1']); + $this->queueManagement->addMessageToQueues('topic4', 'messageBody4', ['queue1']); + + $maxMessagesNumber = 4; + $messages = $this->queueManagement->readMessages('queue1', $maxMessagesNumber); + $this->assertCount($maxMessagesNumber, $messages); + + $firstMessage = array_shift($messages); + $secondMessage = array_shift($messages); + $thirdMessage = array_shift($messages); + $fourthMessage = array_shift($messages); + + $this->queueManagement->changeStatus( + [ + $firstMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] + ], + QueueManagement::MESSAGE_STATUS_ERROR + ); - /** Mark one message as complete or failed and make sure it is not displayed in the list of read messages */ $this->queueManagement->changeStatus( [ $secondMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] ], QueueManagement::MESSAGE_STATUS_COMPLETE ); - $messages = $this->queueManagement->readMessages('queue3', $maxMessagesNumber); - $this->assertCount(1, $messages); $this->queueManagement->changeStatus( [ - $firstMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] + $thirdMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] ], - QueueManagement::MESSAGE_STATUS_ERROR + QueueManagement::MESSAGE_STATUS_NEW + ); + + $this->queueManagement->changeStatus( + [ + $fourthMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] + ], + QueueManagement::MESSAGE_STATUS_RETRY_REQUIRED ); - $messages = $this->queueManagement->readMessages('queue3', $maxMessagesNumber); - $this->assertCount(0, $messages); - /** Ensure that message for retry is still accessible when reading messages from the queue */ - $messages = $this->queueManagement->readMessages('queue2', 1); + $messages = $this->queueManagement->readMessages('queue1'); + $this->assertCount(2, $messages); + } + + /** + * @magentoDataFixture Magento/MysqlMq/_files/queues.php + */ + public function testMessageRetry() + { + $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1']); + + $messages = $this->queueManagement->readMessages('queue1', 1); $message = array_shift($messages); $messageRelationId = $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]; $this->queueManagement->pushToQueueForRetry($messageRelationId); $retryMessage = null; for ($i = 1; $i <= 3; $i++) { - $messages = $this->queueManagement->readMessages('queue2', 1); + $messages = $this->queueManagement->readMessages('queue1', 1); $message = array_shift($messages); if ($message[QueueManagement::MESSAGE_QUEUE_RELATION_ID] == $messageRelationId) { $retryMessage = $message; From eb3ead9e276ad55fd33c99602e4d75666f9d145a Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 21 Oct 2019 07:44:40 -0500 Subject: [PATCH 368/372] MC-18527: Merge release branch into 2.3-develop - fix integration test --- .../Magento/MysqlMq/Model/QueueManagementTest.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php index d3228bd514400..cba3334f1b7f3 100644 --- a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php @@ -185,17 +185,13 @@ public function testMessageRetry() $messages = $this->queueManagement->readMessages('queue1', 1); $message = array_shift($messages); $messageRelationId = $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]; - $this->queueManagement->pushToQueueForRetry($messageRelationId); - $retryMessage = null; - for ($i = 1; $i <= 3; $i++) { + for ($i = 0; $i < 2; $i++) { + $this->assertEquals($i, $message[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); + $this->queueManagement->pushToQueueForRetry($message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]); $messages = $this->queueManagement->readMessages('queue1', 1); $message = array_shift($messages); - if ($message[QueueManagement::MESSAGE_QUEUE_RELATION_ID] == $messageRelationId) { - $retryMessage = $message; - } + $this->assertEquals($messageRelationId, $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]); } - $this->assertNotNull($retryMessage, 'Made retry message not found in queue'); - $this->assertEquals(1, $retryMessage[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); } -} +} \ No newline at end of file From 7b25cc4c5c33f9d31a494e317f92f6472624d85b Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 21 Oct 2019 10:51:59 -0500 Subject: [PATCH 369/372] MC-18527: Merge release branch into 2.3-develop fix integration test --- .../Controller/Adminhtml/Product/Gallery/UploadTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Gallery/UploadTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Gallery/UploadTest.php index 6fb74d54d827f..5a1b69648f864 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Gallery/UploadTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Gallery/UploadTest.php @@ -185,7 +185,7 @@ public function uploadActionWithErrorsDataProvider(): array 'name' => 'invalid_file.txt', ], 'expectation' => [ - 'message' => 'Disallowed file type.', + 'message' => 'Disallowed File Type.', 'errorcode' => 0, 'tmp_media_path' => '/i/n/invalid_file.txt', ], @@ -198,7 +198,7 @@ public function uploadActionWithErrorsDataProvider(): array 'current_path' => '/../../../../_files', ], 'expectation' => [ - 'message' => 'Wrong file size.', + 'message' => 'Disallowed File Type.', 'errorcode' => 0, 'tmp_media_path' => '/m/a/magento_empty.jpg', ], From fdbe2549477a694643be3aa1dc031a3a020bb542 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 21 Oct 2019 16:42:30 -0500 Subject: [PATCH 370/372] MC-18527: Merge release branch into 2.3-develop --- .../Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml index 1b72458747067..47e206768527b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml @@ -16,6 +16,9 @@ <severity value="CRITICAL"/> <group value="mtf_migrated"/> <group value="Catalog"/> + <skip> + <issueId value="MC-21962"/> + </skip> </annotations> <before> <magentoCLI stepKey="setFlatCatalogCategory" command="config:set catalog/frontend/flat_catalog_category 1 "/> From 59606fb66426b70eefc1bb1511421a1aa14f92bf Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 22 Oct 2019 11:07:17 -0500 Subject: [PATCH 371/372] MC-18527: Merge release branch into 2.3-develop --- .../CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml index 4cf59409a5a95..90b13bd1b6b4f 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml @@ -283,6 +283,9 @@ <testCaseId value="MC-14784"/> <group value="CatalogSearch"/> <group value="mtf_migrated"/> + <skip> + <issueId value="MC-21717"/> + </skip> </annotations> <before> <createData entity="_defaultCategory" stepKey="createCategory"/> From 30072e2881b37dd5789e3d627e87b097b22e662a Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 22 Oct 2019 15:12:37 -0500 Subject: [PATCH 372/372] MC-18527: Merge release branch into 2.3-develop - skip integration test --- .../Controller/Adminhtml/Product/Gallery/UploadTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Gallery/UploadTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Gallery/UploadTest.php index 5a1b69648f864..a786e7fa821b6 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Gallery/UploadTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Gallery/UploadTest.php @@ -154,6 +154,8 @@ public function uploadActionDataProvider(): array */ public function testUploadActionWithErrors(array $file, array $expectation): void { + $this->markTestSkipped('MC-21994'); + if (!empty($file['create_file'])) { $this->createFileInSysTmpDir($file['name']); } elseif (!empty($file['copy_file'])) { @@ -185,7 +187,7 @@ public function uploadActionWithErrorsDataProvider(): array 'name' => 'invalid_file.txt', ], 'expectation' => [ - 'message' => 'Disallowed File Type.', + 'message' => 'Disallowed file type.', 'errorcode' => 0, 'tmp_media_path' => '/i/n/invalid_file.txt', ], @@ -198,7 +200,7 @@ public function uploadActionWithErrorsDataProvider(): array 'current_path' => '/../../../../_files', ], 'expectation' => [ - 'message' => 'Disallowed File Type.', + 'message' => 'Wrong file size.', 'errorcode' => 0, 'tmp_media_path' => '/m/a/magento_empty.jpg', ],