From 96687ac49b311ababf2d3eb7054b07cf9627883d Mon Sep 17 00:00:00 2001 From: Ihor Sviziev Date: Wed, 10 Oct 2018 10:39:59 +0300 Subject: [PATCH 01/75] Checkout - Fix JS error Cannot read property 'quoteData' of undefined --- app/code/Magento/Checkout/view/frontend/web/js/model/quote.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js b/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js index 2510d1aced3d3..3486a92736617 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js @@ -7,7 +7,8 @@ */ define([ 'ko', - 'underscore' + 'underscore', + 'domReady!' ], function (ko, _) { 'use strict'; From ea9f3598a400878d8e1daeb7ef5a07410ebd242a Mon Sep 17 00:00:00 2001 From: Nikita Tychuk Date: Sat, 24 Nov 2018 16:28:08 +0200 Subject: [PATCH 02/75] store_view_code-column-has-empty-values-in-csv-17784. Moved ->clear(); --- app/code/Magento/CatalogImportExport/Model/Export/Product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 345d323e6e129..236b7caef1570 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -948,8 +948,8 @@ protected function loadCollection(): array foreach ($collection as $itemId => $item) { $data[$itemId][$storeId] = $item; } + $collection->clear(); } - $collection->clear(); return $data; } From 6d5ee6380cd9038fc1ef3403031e550f44440524 Mon Sep 17 00:00:00 2001 From: NazarKlovanych Date: Thu, 27 Dec 2018 11:31:38 +0200 Subject: [PATCH 03/75] Fix for issue 19983 --- .../Magento/Ui/view/base/web/js/form/element/file-uploader.js | 3 ++- 1 file changed, 2 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 357571350a268..c6bf36f5cc867 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 @@ -16,7 +16,8 @@ define([ 'Magento_Ui/js/form/element/abstract', 'mage/backend/notification', 'mage/translate', - 'jquery/file-uploader' + 'jquery/file-uploader', + 'mage/adminhtml/tools' ], function ($, _, utils, uiAlert, validator, Element, notification, $t) { 'use strict'; From 188a3e66e7d9604942d7c36cfaec7dc5bae32710 Mon Sep 17 00:00:00 2001 From: NazarKlovanych Date: Thu, 27 Dec 2018 12:53:39 +0200 Subject: [PATCH 04/75] Fix save customer attribute image --- app/code/Magento/Eav/Model/Attribute/Data/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php index 1b2cac32598e1..b8ca34986111b 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/File.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php @@ -146,7 +146,7 @@ protected function _validateByRules($value) return $this->_fileValidator->getMessages(); } - if (!empty($value['tmp_name']) && !is_uploaded_file($value['tmp_name'])) { + if (empty($value['tmp_name']) && !is_uploaded_file($value['tmp_name'])) { return [__('"%1" is not a valid file.', $label)]; } From a042993b2d608df6e050a5e9b62509ef08be985b Mon Sep 17 00:00:00 2001 From: Anton Evers Date: Wed, 2 Jan 2019 14:02:29 +0100 Subject: [PATCH 05/75] Make it possible to generate sales PDF's using the API --- .../base/templates/info/pdf/default.phtml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 app/code/Magento/Payment/view/base/templates/info/pdf/default.phtml diff --git a/app/code/Magento/Payment/view/base/templates/info/pdf/default.phtml b/app/code/Magento/Payment/view/base/templates/info/pdf/default.phtml new file mode 100644 index 0000000000000..7acac62f65d38 --- /dev/null +++ b/app/code/Magento/Payment/view/base/templates/info/pdf/default.phtml @@ -0,0 +1,23 @@ + +escapeHtml($block->getMethod()->getTitle()) ?>{{pdf_row_separator}} + +getSpecificInformation()):?> + $value):?> + escapeHtml($label) ?>: + escapeHtml(implode(' ', $block->getValueAsArray($value))) ?> + {{pdf_row_separator}} + + + +escapeHtml(implode('{{pdf_row_separator}}', $block->getChildPdfAsArray())) ?> From c3fdba54dfc023bd92c5823682dc370235a59262 Mon Sep 17 00:00:00 2001 From: Anton Evers Date: Thu, 3 Jan 2019 13:54:57 +0100 Subject: [PATCH 06/75] Make it possible to generate sales PDF's using the API --- .../base/templates/info/pdf/checkmo.phtml | 26 +++++++++++++++++++ .../templates/info/pdf/purchaseorder.phtml | 11 ++++++++ 2 files changed, 37 insertions(+) create mode 100644 app/code/Magento/OfflinePayments/view/base/templates/info/pdf/checkmo.phtml create mode 100644 app/code/Magento/OfflinePayments/view/base/templates/info/pdf/purchaseorder.phtml diff --git a/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/checkmo.phtml b/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/checkmo.phtml new file mode 100644 index 0000000000000..4d63577319d5b --- /dev/null +++ b/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/checkmo.phtml @@ -0,0 +1,26 @@ + +escapeHtml($block->getMethod()->getTitle()) ?> + {{pdf_row_separator}} +getInfo()->getAdditionalInformation()): ?> + {{pdf_row_separator}} + getPayableTo()): ?> + escapeHtml(__('Make Check payable to: %1', $block->getPayableTo())) ?> + {{pdf_row_separator}} + + getMailingAddress()): ?> + escapeHtml(__('Send Check to:')) ?> + {{pdf_row_separator}} + escapeHtml($block->getMailingAddress())) ?> + {{pdf_row_separator}} + + diff --git a/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/purchaseorder.phtml b/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/purchaseorder.phtml new file mode 100644 index 0000000000000..4a6ea1c00b21c --- /dev/null +++ b/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/purchaseorder.phtml @@ -0,0 +1,11 @@ + +escapeHtml(__('Purchase Order Number: %1', $block->getInfo()->getPoNumber())) ?> + {{pdf_row_separator}} From 825fa30f043cdee014dcb6602eed50616a2f601c Mon Sep 17 00:00:00 2001 From: shikhamis11 Date: Thu, 1 Nov 2018 17:59:28 +0530 Subject: [PATCH 07/75] fixed store wise product filter issue Fixed issue - #18374 Unable to get product attribute value for store-view scope type in product collection loaded for a specific store. --- .../Magento/Eav/Model/Entity/Collection/AbstractCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php index 0eb87374f3ba3..eba9976260bed 100644 --- a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php +++ b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php @@ -399,7 +399,7 @@ public function addAttributeToFilter($attribute, $condition = null, $joinType = */ public function addFieldToFilter($attribute, $condition = null) { - return $this->addAttributeToFilter($attribute, $condition); + return $this->addAttributeToFilter($attribute, $condition,'left'); } /** From fd52e94b69f2ec44552fb1ff21a3897d114f620a Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Fri, 21 Dec 2018 16:15:37 -0600 Subject: [PATCH 08/75] Fixed code style issue --- .../Magento/Eav/Model/Entity/Collection/AbstractCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php index eba9976260bed..6d9e5e88cdfe5 100644 --- a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php +++ b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php @@ -399,7 +399,7 @@ public function addAttributeToFilter($attribute, $condition = null, $joinType = */ public function addFieldToFilter($attribute, $condition = null) { - return $this->addAttributeToFilter($attribute, $condition,'left'); + return $this->addAttributeToFilter($attribute, $condition, 'left'); } /** From 99d6e43098dbc33dcfbd922521e685eaa791837f Mon Sep 17 00:00:00 2001 From: Govind Sharma Date: Tue, 15 Jan 2019 17:27:03 +0530 Subject: [PATCH 09/75] Updated _payment.less file to fix update button issue Updated _payment.less file to fix update button issue --- .../web/css/source/module/checkout/_payments.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less index dd9db0e715308..d7e3de57f4657 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less @@ -118,6 +118,7 @@ .primary { .action-update { margin-right: 0; + margin-bottom:20px; } } From da46b6ac353d1cbd9e58686516d31a9025110db1 Mon Sep 17 00:00:00 2001 From: Govind Sharma Date: Wed, 16 Jan 2019 08:50:36 +0530 Subject: [PATCH 10/75] fix indent --- .../web/css/source/module/checkout/_payments.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less index d7e3de57f4657..7428b1a108b25 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less @@ -118,7 +118,7 @@ .primary { .action-update { margin-right: 0; - margin-bottom:20px; + margin-bottom: 20px; } } From 20fd58914382220cb4b5050d0540ec8f62c63814 Mon Sep 17 00:00:00 2001 From: Nazar Klovanych Date: Fri, 18 Jan 2019 00:00:55 +0200 Subject: [PATCH 11/75] add mage/adminhtml/tools for Base64 --- app/code/Magento/Variable/view/adminhtml/web/variables.js | 3 ++- .../wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Variable/view/adminhtml/web/variables.js b/app/code/Magento/Variable/view/adminhtml/web/variables.js index 47f027f27102d..bf8bfbc570ce2 100644 --- a/app/code/Magento/Variable/view/adminhtml/web/variables.js +++ b/app/code/Magento/Variable/view/adminhtml/web/variables.js @@ -16,7 +16,8 @@ define([ 'Magento_Variable/js/custom-directive-generator', 'Magento_Ui/js/lib/spinner', 'jquery/ui', - 'prototype' + 'prototype', + 'mage/adminhtml/tools' ], function (jQuery, notification, $t, wysiwyg, registry, mageApply, utils, configGenerator, customGenerator, loader) { 'use strict'; diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js index e6f12a2e51acf..96091e4099676 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js @@ -9,7 +9,8 @@ define([ 'Magento_Variable/js/config-directive-generator', 'Magento_Variable/js/custom-directive-generator', 'wysiwygAdapter', - 'jquery' + 'jquery', + 'mage/adminhtml/tools' ], function (configDirectiveGenerator, customDirectiveGenerator, wysiwyg, jQuery) { return function (config) { tinymce.create('tinymce.plugins.magentovariable', { From ddb1137b96ff0ae93c2e78dff62e02da31f9a02a Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Thu, 17 Jan 2019 17:53:04 +0530 Subject: [PATCH 12/75] Issue Fixed: #8086: Multiline admin field is broken --- app/code/Magento/Config/Model/Config.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Config/Model/Config.php b/app/code/Magento/Config/Model/Config.php index b1074e92cc949..bec44e9d55757 100644 --- a/app/code/Magento/Config/Model/Config.php +++ b/app/code/Magento/Config/Model/Config.php @@ -424,6 +424,11 @@ protected function _processGroup( if (!isset($fieldData['value'])) { $fieldData['value'] = null; } + + if ($field->getType() == 'multiline' && is_array($fieldData['value'])) { + $fieldData['value'] = trim(implode(PHP_EOL, $fieldData['value'])); + } + $data = [ 'field' => $fieldId, 'groups' => $groups, From 9ca8077242bd6bb7a09c8bb77f4495b39787fcb0 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Fri, 18 Jan 2019 14:07:02 +0200 Subject: [PATCH 13/75] Update app/code/Magento/Eav/Model/Attribute/Data/File.php Co-Authored-By: Nazar65 --- app/code/Magento/Eav/Model/Attribute/Data/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php index b8ca34986111b..8a29c1f2326cf 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/File.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php @@ -146,7 +146,7 @@ protected function _validateByRules($value) return $this->_fileValidator->getMessages(); } - if (empty($value['tmp_name']) && !is_uploaded_file($value['tmp_name'])) { + if (empty($value['tmp_name']) || !is_uploaded_file($value['tmp_name'])) { return [__('"%1" is not a valid file.', $label)]; } From f669a4d2982579d768cb9c09fecceb720e3582e4 Mon Sep 17 00:00:00 2001 From: Nainesh Date: Thu, 17 Jan 2019 16:54:48 +0530 Subject: [PATCH 14/75] 'Fixes-for-customer-login-page-input-field' :: On customer login page input field are short width on tablet view --- .../Magento/blank/Magento_Customer/web/css/source/_module.less | 2 +- .../Magento/luma/Magento_Customer/web/css/source/_module.less | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less index 9df59ca5dac92..a94fedbcbbd14 100644 --- a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less @@ -421,7 +421,7 @@ > .field { > .control { - width: 55%; + width: 80%; } } } diff --git a/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less index 2e7856d390bd0..61fc2610fc2e5 100755 --- a/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less @@ -375,7 +375,7 @@ .fieldset { > .field { > .control { - width: 55%; + width: 80%; } } } From 40a62741285b064fd9e4850244605e2dfed44a16 Mon Sep 17 00:00:00 2001 From: Nainesh Date: Thu, 17 Jan 2019 16:54:48 +0530 Subject: [PATCH 15/75] 'Fixes-for-customer-login-page-input-field' :: On customer login page input field are short width on tablet view --- .../Magento/blank/Magento_Customer/web/css/source/_module.less | 2 +- .../Magento/luma/Magento_Customer/web/css/source/_module.less | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less index 9df59ca5dac92..a94fedbcbbd14 100644 --- a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less @@ -421,7 +421,7 @@ > .field { > .control { - width: 55%; + width: 80%; } } } diff --git a/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less index 2e7856d390bd0..61fc2610fc2e5 100755 --- a/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less @@ -375,7 +375,7 @@ .fieldset { > .field { > .control { - width: 55%; + width: 80%; } } } From 122e5c2f61bd29fa6a329af2f23f4441a64b1ea9 Mon Sep 17 00:00:00 2001 From: LisovyiEvhenii Date: Thu, 24 Jan 2019 15:34:04 +0200 Subject: [PATCH 16/75] #13982: Customer Login Block sets the title for the page when rendered. Move setPageTitle from Block to layout configs --- app/code/Magento/Customer/Block/Form/Login.php | 9 --------- .../view/frontend/layout/customer_account_login.xml | 5 +++++ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Customer/Block/Form/Login.php b/app/code/Magento/Customer/Block/Form/Login.php index 7b265ae1f0f32..d3d3306a49b44 100644 --- a/app/code/Magento/Customer/Block/Form/Login.php +++ b/app/code/Magento/Customer/Block/Form/Login.php @@ -47,15 +47,6 @@ public function __construct( $this->_customerSession = $customerSession; } - /** - * @return $this - */ - protected function _prepareLayout() - { - $this->pageConfig->getTitle()->set(__('Customer Login')); - return parent::_prepareLayout(); - } - /** * Retrieve form posting url * diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml index d49dae6dee58f..00f9c4ed84d24 100644 --- a/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml +++ b/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml @@ -7,6 +7,11 @@ --> + + + Customer Login + + From 40d9c7e452eaae742f35ea587bbc6f8a2d3fc8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bajsarowicz?= Date: Thu, 24 Jan 2019 20:21:00 +0100 Subject: [PATCH 17/75] Optimize snail_case replacement to PascalCase --- .../Magento/Catalog/Controller/Adminhtml/Product/GridOnly.php | 2 +- .../Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php | 2 +- .../Unit/Model/Product/CurrentUrlRewritesRegeneratorTest.php | 2 +- .../Test/Unit/Observer/AfterImportDataObserverTest.php | 2 +- .../Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php | 2 +- .../Tax/Test/Unit/Model/Sales/Total/Quote/ShippingTest.php | 2 +- .../Test/Fixture/CatalogSearchQuery/QueryText.php | 2 +- .../tests/app/Magento/Widget/Test/Handler/Widget/Curl.php | 2 +- .../Magento/Framework/Api/SimpleDataObjectConverter.php | 4 ++-- lib/internal/Magento/Framework/Code/NameBuilder.php | 2 +- lib/internal/Magento/Framework/DataObject.php | 4 ++-- lib/internal/Magento/Framework/DataObject/Copy.php | 4 ++-- lib/internal/Magento/Framework/Module/PackageInfo.php | 3 +-- 13 files changed, 16 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/GridOnly.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/GridOnly.php index 40e62895caffc..2ddd16b00dfd0 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/GridOnly.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/GridOnly.php @@ -47,7 +47,7 @@ public function execute() $this->productBuilder->build($this->getRequest()); $block = $this->getRequest()->getParam('gridOnlyBlock'); - $blockClassSuffix = str_replace(' ', '_', ucwords(str_replace('_', ' ', $block))); + $blockClassSuffix = ucwords($block, '_'); /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */ $resultRaw = $this->resultRawFactory->create(); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php index fbc620a6d741a..294cf8562906d 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php @@ -252,7 +252,7 @@ protected function getCurrentRewritesMocks($currentRewrites) ->disableOriginalConstructor()->getMock(); foreach ($urlRewrite as $key => $value) { $url->expects($this->any()) - ->method('get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)))) + ->method('get' . str_replace('_', '', ucwords($key, '_'))) ->will($this->returnValue($value)); } $rewrites[] = $url; diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Product/CurrentUrlRewritesRegeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Product/CurrentUrlRewritesRegeneratorTest.php index 4855478b8488a..c431743fc0b51 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Product/CurrentUrlRewritesRegeneratorTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Product/CurrentUrlRewritesRegeneratorTest.php @@ -294,7 +294,7 @@ protected function getCurrentRewritesMocks($currentRewrites) ->disableOriginalConstructor()->getMock(); foreach ($urlRewrite as $key => $value) { $url->expects($this->any()) - ->method('get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)))) + ->method('get' . str_replace('_', '', ucwords($key, '_'))) ->will($this->returnValue($value)); } $rewrites[] = $url; diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/AfterImportDataObserverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/AfterImportDataObserverTest.php index fd9ab10537f1c..3984d949332d3 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/AfterImportDataObserverTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/AfterImportDataObserverTest.php @@ -694,7 +694,7 @@ protected function currentUrlRewritesRegeneratorGetCurrentRewritesMocks($current ->disableOriginalConstructor()->getMock(); foreach ($urlRewrite as $key => $value) { $url->expects($this->any()) - ->method('get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)))) + ->method('get' . str_replace('_', '', ucwords($key, '_'))) ->will($this->returnValue($value)); } $rewrites[] = $url; diff --git a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php index bf49f3d479132..77da6950fecf7 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php @@ -252,7 +252,7 @@ private function getTaxRateMock(array $taxRateData) foreach ($taxRateData as $key => $value) { // convert key from snake case to upper case $taxRateMock->expects($this->any()) - ->method('get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)))) + ->method('get' . str_replace('_', '', ucwords($key, '_'))) ->will($this->returnValue($value)); } diff --git a/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/ShippingTest.php b/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/ShippingTest.php index 77e25d6f14574..2bfebc984bb81 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/ShippingTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/Sales/Total/Quote/ShippingTest.php @@ -133,7 +133,7 @@ private function getMockObject($className, array $objectState) $getterValueMap = []; $methods = ['__wakeup']; foreach ($objectState as $key => $value) { - $getterName = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); + $getterName = 'get' . str_replace('_', '', ucwords($key, '_')); $getterValueMap[$getterName] = $value; $methods[] = $getterName; } diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php index e2193b799c3be..11a8693723f25 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php @@ -61,7 +61,7 @@ private function createProducts(FixtureFactory $fixtureFactory, $productsData) $searchValue = isset($productData[2]) ? $productData[2] : $productData[1]; if ($this->data === null) { if ($product->hasData($searchValue)) { - $getProperty = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $searchValue))); + $getProperty = 'get' . str_replace('_', '', ucwords($searchValue, '_')); $this->data = $product->$getProperty(); } else { $this->data = $searchValue; diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php index 1a024eefe162d..13c16c888fbb0 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Handler/Widget/Curl.php @@ -172,7 +172,7 @@ protected function prepareWidgetInstance(array $data) $widgetInstances = []; foreach ($data['widget_instance'] as $key => $widgetInstance) { $pageGroup = $widgetInstance['page_group']; - $method = 'prepare' . str_replace(' ', '', ucwords(str_replace('_', ' ', $pageGroup))) . 'Group'; + $method = 'prepare' . str_replace('_', '', ucwords($pageGroup, '_')) . 'Group'; if (!method_exists(__CLASS__, $method)) { throw new \Exception('Method for prepare page group "' . $method . '" is not exist.'); } diff --git a/lib/internal/Magento/Framework/Api/SimpleDataObjectConverter.php b/lib/internal/Magento/Framework/Api/SimpleDataObjectConverter.php index 49d824a4f2e5a..4dbf4680f8988 100644 --- a/lib/internal/Magento/Framework/Api/SimpleDataObjectConverter.php +++ b/lib/internal/Magento/Framework/Api/SimpleDataObjectConverter.php @@ -58,7 +58,7 @@ public function convertKeysToCamelCase(array $dataArray) if (is_array($fieldValue) && !$this->_isSimpleSequentialArray($fieldValue)) { $fieldValue = $this->convertKeysToCamelCase($fieldValue); } - $fieldName = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $fieldName)))); + $fieldName = lcfirst(str_replace('_', '', ucwords($fieldName, '_'))); $response[$fieldName] = $fieldValue; } return $response; @@ -148,7 +148,7 @@ protected function _unpackAssociativeArray($data) */ public static function snakeCaseToUpperCamelCase($input) { - return str_replace(' ', '', ucwords(str_replace('_', ' ', $input))); + return str_replace('_', '', ucwords($input, '_')); } /** diff --git a/lib/internal/Magento/Framework/Code/NameBuilder.php b/lib/internal/Magento/Framework/Code/NameBuilder.php index c27a896b65f04..13a17d7c13b0f 100644 --- a/lib/internal/Magento/Framework/Code/NameBuilder.php +++ b/lib/internal/Magento/Framework/Code/NameBuilder.php @@ -23,7 +23,7 @@ public function buildClassName($parts) $separator = '\\'; $string = join($separator, $parts); $string = str_replace('_', $separator, $string); - $className = str_replace(' ', $separator, ucwords(str_replace($separator, ' ', $string))); + $className = ucwords($string, $separator); return $className; } } diff --git a/lib/internal/Magento/Framework/DataObject.php b/lib/internal/Magento/Framework/DataObject.php index 9ff004c53bb9b..7f056d38c8fd7 100644 --- a/lib/internal/Magento/Framework/DataObject.php +++ b/lib/internal/Magento/Framework/DataObject.php @@ -202,7 +202,7 @@ protected function _getData($key) */ public function setDataUsingMethod($key, $args = []) { - $method = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); + $method = 'set' . str_replace('_', '', ucwords($key, '_')); $this->{$method}($args); return $this; } @@ -216,7 +216,7 @@ public function setDataUsingMethod($key, $args = []) */ public function getDataUsingMethod($key, $args = null) { - $method = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); + $method = 'get' . str_replace('_', '', ucwords($key, '_')); return $this->{$method}($args); } diff --git a/lib/internal/Magento/Framework/DataObject/Copy.php b/lib/internal/Magento/Framework/DataObject/Copy.php index 8d8896c6cb62a..6a908ae78a343 100644 --- a/lib/internal/Magento/Framework/DataObject/Copy.php +++ b/lib/internal/Magento/Framework/DataObject/Copy.php @@ -239,7 +239,7 @@ protected function _setFieldsetFieldValue($target, $targetCode, $value) */ protected function getAttributeValueFromExtensibleDataObject($source, $code) { - $method = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $code))); + $method = 'get' . str_replace('_', '', ucwords($code, '_')); $methodExists = method_exists($source, $method); if ($methodExists == true) { @@ -273,7 +273,7 @@ protected function getAttributeValueFromExtensibleDataObject($source, $code) */ protected function setAttributeValueFromExtensibleDataObject($target, $code, $value) { - $method = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $code))); + $method = 'set' . str_replace('_', '', ucwords($code, '_')); $methodExists = method_exists($target, $method); if ($methodExists == true) { diff --git a/lib/internal/Magento/Framework/Module/PackageInfo.php b/lib/internal/Magento/Framework/Module/PackageInfo.php index 0dce507ba26f4..848ad4495f39e 100644 --- a/lib/internal/Magento/Framework/Module/PackageInfo.php +++ b/lib/internal/Magento/Framework/Module/PackageInfo.php @@ -176,8 +176,7 @@ public function getNonExistingDependencies() protected function convertPackageNameToModuleName($packageName) { $moduleName = str_replace('magento/module-', '', $packageName); - $moduleName = str_replace('-', ' ', $moduleName); - $moduleName = str_replace(' ', '', ucwords($moduleName)); + $moduleName = str_replace('-', '', ucwords($moduleName, '-')); return 'Magento_' . $moduleName; } From 93f1caa3623e711b6699107bb3dcb24e982eb750 Mon Sep 17 00:00:00 2001 From: LisovyiEvhenii Date: Fri, 25 Jan 2019 10:32:37 +0200 Subject: [PATCH 18/75] #13982: fix page title to be displayed both in head's and page's title --- .../view/frontend/layout/customer_account_login.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml index 00f9c4ed84d24..3518df736c4ac 100644 --- a/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml +++ b/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml @@ -6,12 +6,10 @@ */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <head> + <title>Customer Login + - - - Customer Login - - From 5c7d8994776ce6d902b7ef793afd8fafd21722f1 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Fri, 25 Jan 2019 13:22:21 +0000 Subject: [PATCH 19/75] Changed references to "Store" to "Scope" in framework components. --- .../Sales/Model/Order/Email/SenderBuilder.php | 2 +- .../Model/Order/Email/SenderBuilderTest.php | 8 +++--- .../Mail/Template/TransportBuilder.php | 26 ++++++++++++++----- .../Unit/Template/TransportBuilderTest.php | 8 +++--- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index a7d749ec04c7d..ed9e38822245f 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -106,7 +106,7 @@ protected function configureEmailTemplate() $this->transportBuilder->setTemplateIdentifier($this->templateContainer->getTemplateId()); $this->transportBuilder->setTemplateOptions($this->templateContainer->getTemplateOptions()); $this->transportBuilder->setTemplateVars($this->templateContainer->getTemplateVars()); - $this->transportBuilder->setFromByStore( + $this->transportBuilder->setFromByScope( $this->identityContainer->getEmailIdentity(), $this->identityContainer->getStore()->getId() ); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php index 759d60d9e6613..24cd54e3a46b3 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php @@ -76,7 +76,7 @@ protected function setUp() 'setTemplateIdentifier', 'setTemplateOptions', 'setTemplateVars', - 'setFromByStore', + 'setFromByScope', ] ); @@ -103,7 +103,7 @@ protected function setUp() ->method('getEmailIdentity') ->will($this->returnValue($emailIdentity)); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($this->equalTo($emailIdentity), 1); $this->identityContainerMock->expects($this->once()) @@ -146,7 +146,7 @@ public function testSend() ->method('getId') ->willReturn(1); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($identity, 1); $this->transportBuilder->expects($this->once()) ->method('addTo') @@ -176,7 +176,7 @@ public function testSendCopyTo() ->method('addTo') ->with($this->equalTo('example@mail.com')); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($identity, 1); $this->identityContainerMock->expects($this->once()) ->method('getStore') diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index a7bb96122a84d..0d69b3d96cebf 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -177,29 +177,43 @@ public function setReplyTo($email, $name = null) /** * Set mail from address * - * @deprecated This function sets the from address for the first store only. - * new function setFromByStore introduced to allow setting of from address - * based on store. - * @see setFromByStore() + * @deprecated This function sets the from address but does not provide + * a way of setting the correct from addresses based on the scope. + * @see setFromByScope() * * @param string|array $from * @return $this */ public function setFrom($from) { - return $this->setFromByStore($from, null); + return $this->setFromByScope($from, null); } /** * Set mail from address by store * + * @deprecated Use setFromByScope + * @see setFromByScope() + * * @param string|array $from * @param string|int $store * @return $this */ public function setFromByStore($from, $store = null) { - $result = $this->_senderResolver->resolve($from, $store); + return $this->setFromByScope($from, $store); + } + + /** + * Set mail from address by scopeId + * + * @param string|array $from + * @param string|int $scopeId + * @return $this + */ + public function setFromByScope($from, $scopeId = null) + { + $result = $this->_senderResolver->resolve($from, $scopeId); $this->message->setFromAddress($result['email'], $result['name']); return $this; } diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php index b476eecd7f59f..5e3309af6497b 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php @@ -167,20 +167,20 @@ public function getTransportDataProvider() /** * @return void */ - public function testSetFromByStore() + public function testSetFromByScope() { $sender = ['email' => 'from@example.com', 'name' => 'name']; - $store = 1; + $scopeId = 1; $this->senderResolverMock->expects($this->once()) ->method('resolve') - ->with($sender, $store) + ->with($sender, $scopeId) ->willReturn($sender); $this->messageMock->expects($this->once()) ->method('setFromAddress') ->with($sender['email'], $sender['name']) ->willReturnSelf(); - $this->builder->setFromByStore($sender, $store); + $this->builder->setFromByScope($sender, $scopeId); } /** From a0516563c682a9d3b51ffd0f0aa7040591dedf0a Mon Sep 17 00:00:00 2001 From: Nazar Klovanych Date: Sat, 26 Jan 2019 21:44:12 +0200 Subject: [PATCH 20/75] Update File.php to resolve issue 19983 --- app/code/Magento/Eav/Model/Attribute/Data/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php index 8a29c1f2326cf..32283d38a065f 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/File.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php @@ -146,7 +146,7 @@ protected function _validateByRules($value) return $this->_fileValidator->getMessages(); } - if (empty($value['tmp_name']) || !is_uploaded_file($value['tmp_name'])) { + if (!empty($value['tmp_name']) || !file_exists($value['tmp_name'])) { return [__('"%1" is not a valid file.', $label)]; } From 13722031d11aeb6ce92f0272db06714bce7840e0 Mon Sep 17 00:00:00 2001 From: Nazar Date: Sat, 26 Jan 2019 21:45:56 +0200 Subject: [PATCH 21/75] Update File.php --- app/code/Magento/Eav/Model/Attribute/Data/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php index 32283d38a065f..a52c88261166e 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/File.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php @@ -146,7 +146,7 @@ protected function _validateByRules($value) return $this->_fileValidator->getMessages(); } - if (!empty($value['tmp_name']) || !file_exists($value['tmp_name'])) { + if (!empty($value['tmp_name']) && !file_exists($value['tmp_name'])) { return [__('"%1" is not a valid file.', $label)]; } From 4bb06ef6bccb10c881d7803350060a177bfd60b9 Mon Sep 17 00:00:00 2001 From: Dipti 2Jcommerce Date: Thu, 31 Jan 2019 19:00:59 +0530 Subject: [PATCH 22/75] ipad-view-order-summary-block --- .../web/css/source/module/checkout/_order-summary.less | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less index 9bad9518f5724..85a960e8bc05a 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less @@ -148,14 +148,14 @@ } .product-item-name-block { - display: table-cell; + display: block; padding-right: @indent__xs; text-align: left; } .subtotal { - display: table-cell; - text-align: right; + display: block; + text-align: left; } .price { From d4027d61b968999d77c194c5517b19465af8ba55 Mon Sep 17 00:00:00 2001 From: Ravi Chandra Date: Fri, 1 Feb 2019 18:05:35 +0530 Subject: [PATCH 23/75] Correct spelling --- app/code/Magento/Ui/view/base/web/js/grid/data-storage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/data-storage.js b/app/code/Magento/Ui/view/base/web/js/grid/data-storage.js index dad67da3ea8ad..547cdab16cdf1 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/data-storage.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/data-storage.js @@ -199,7 +199,7 @@ define([ }, /** - * Caches requests object with provdided parameters + * Caches requests object with provided parameters * and data object associated with it. * * @param {Object} data - Data associated with request. From 92d4ffadeb479344c01ad35d8fb5149cb545d7c0 Mon Sep 17 00:00:00 2001 From: Dipti 2Jcommerce Date: Mon, 4 Feb 2019 15:21:34 +0530 Subject: [PATCH 24/75] ipad-view-order-summary-block --- .../module/checkout/_order-summary.less | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less index 85a960e8bc05a..ae21a3877c350 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less @@ -227,3 +227,27 @@ } } } + +// +// Tablet +// _____________________________________________ + +@media only screen and (max-width: @screen__m) { + .opc-block-summary { + .product-item { + .product-item-inner { + display: block; + } + + .product-item-name-block { + display: block; + text-align: left; + } + + .subtotal { + display: block; + text-align: left; + } + } + } +} \ No newline at end of file From 7b9c6058e8462165dd975ab9d005f671d29a5492 Mon Sep 17 00:00:00 2001 From: Alexandre Jardin Date: Tue, 5 Feb 2019 15:11:29 +0100 Subject: [PATCH 25/75] Make the module list more deterministic --- .../Framework/Module/ModuleList/Loader.php | 36 +++++++++++-- .../Test/Unit/ModuleList/LoaderTest.php | 51 +++++++++++++++++++ 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/lib/internal/Magento/Framework/Module/ModuleList/Loader.php b/lib/internal/Magento/Framework/Module/ModuleList/Loader.php index bdfb77762b41c..80958f65e110e 100644 --- a/lib/internal/Magento/Framework/Module/ModuleList/Loader.php +++ b/lib/internal/Magento/Framework/Module/ModuleList/Loader.php @@ -126,16 +126,21 @@ private function getModuleConfigs() * * @param array $origList * @return array - * @SuppressWarnings(PHPMD.UnusedLocalVariable) + * @throws \Exception */ - private function sortBySequence($origList) + private function sortBySequence(array $origList): array { ksort($origList); + $modules = $this->prearrangeModules($origList); + $expanded = []; - foreach ($origList as $moduleName => $value) { + foreach ($modules as $moduleName => $value) { + $sequence = $this->expandSequence($origList, $moduleName); + asort($sequence); + $expanded[] = [ 'name' => $moduleName, - 'sequence' => $this->expandSequence($origList, $moduleName), + 'sequence' => $sequence, ]; } @@ -143,7 +148,7 @@ private function sortBySequence($origList) $total = count($expanded); for ($i = 0; $i < $total - 1; $i++) { for ($j = $i; $j < $total; $j++) { - if (in_array($expanded[$j]['name'], $expanded[$i]['sequence'])) { + if (in_array($expanded[$j]['name'], $expanded[$i]['sequence'], true)) { $temp = $expanded[$i]; $expanded[$i] = $expanded[$j]; $expanded[$j] = $temp; @@ -159,6 +164,27 @@ private function sortBySequence($origList) return $result; } + /** + * Prearrange all modules by putting those from Magento before the others + * + * @param array $modules + * @return array + */ + private function prearrangeModules(array $modules): array + { + $breakdown = ['magento' => [], 'others' => []]; + + foreach ($modules as $moduleName => $moduleDetails) { + if (strpos($moduleName, 'Magento_') !== false) { + $breakdown['magento'][$moduleName] = $moduleDetails; + } else { + $breakdown['others'][$moduleName] = $moduleDetails; + } + } + + return array_merge($breakdown['magento'], $breakdown['others']); + } + /** * Accumulate information about all transitive "sequence" references * diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php index fe613450fd485..a62bb5fa70f97 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php @@ -160,4 +160,55 @@ public function testLoadCircular() ])); $this->loader->load(); } + + /** + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testLoadPrearranged(): void + { + $fixtures = [ + 'Foo_Bar' => ['name' => 'Foo_Bar', 'sequence' => ['Magento_Store']], + 'Magento_Directory' => ['name' => 'Magento_Directory', 'sequence' => ['Magento_Store']], + 'Magento_Store' => ['name' => 'Magento_Store', 'sequence' => []], + 'Magento_Theme' => ['name' => 'Magento_Theme', 'sequence' => ['Magento_Store', 'Magento_Directory']], + 'Test_HelloWorld' => ['name' => 'Test_HelloWorld', 'sequence' => ['Magento_Theme']] + ]; + + $index = 0; + foreach ($fixtures as $name => $fixture) { + $this->converter->expects($this->at($index++))->method('convert')->willReturn([$name => $fixture]); + } + + $this->registry->expects($this->once()) + ->method('getPaths') + ->willReturn([ + '/path/to/Foo_Bar', + '/path/to/Magento_Directory', + '/path/to/Magento_Store', + '/path/to/Magento_Theme', + '/path/to/Test_HelloWorld' + ]); + + $this->driver->expects($this->exactly(5)) + ->method('fileGetContents') + ->will($this->returnValueMap([ + ['/path/to/Foo_Bar/etc/module.xml', null, null, self::$sampleXml], + ['/path/to/Magento_Directory/etc/module.xml', null, null, self::$sampleXml], + ['/path/to/Magento_Store/etc/module.xml', null, null, self::$sampleXml], + ['/path/to/Magento_Theme/etc/module.xml', null, null, self::$sampleXml], + ['/path/to/Test_HelloWorld/etc/module.xml', null, null, self::$sampleXml], + ])); + + // Load the full module list information + $result = $this->loader->load(); + + $this->assertSame( + ['Magento_Store', 'Magento_Directory', 'Magento_Theme', 'Foo_Bar', 'Test_HelloWorld'], + array_keys($result) + ); + + foreach ($fixtures as $name => $fixture) { + $this->assertSame($fixture, $result[$name]); + } + } } From e95c678c4db2b29fad6bf7f319dcb1f16dd4c15f Mon Sep 17 00:00:00 2001 From: Patrick McLain Date: Tue, 29 Jan 2019 14:03:10 -0500 Subject: [PATCH 26/75] Proposal For setPaymentMethodOnCart Ref #293 --- app/code/Magento/BraintreeGraphQl/README.md | 4 + .../Magento/BraintreeGraphQl/composer.json | 24 ++ .../BraintreeGraphQl/etc/graphql/di.xml | 27 ++ .../Magento/BraintreeGraphQl/etc/module.xml | 10 + .../BraintreeGraphQl/etc/schema.graphqls | 18 + .../Magento/BraintreeGraphQl/registration.php | 10 + .../AdditionalDataBuilderInterface.php | 13 + .../Payment/AdditionalDataBuilderPool.php | 32 ++ .../Payment/DefaultAdditionalDataBuilder.php | 43 +++ .../Model/Cart/Payment/MethodBuilder.php | 62 ++++ .../Cart/Payment/PaymentDataProvider.php | 35 ++ .../Model/Resolver/CartPaymentMethod.php | 58 +++ .../Model/Resolver/SetPaymentMethodOnCart.php | 102 ++++++ .../Magento/QuoteGraphQl/etc/schema.graphqls | 21 ++ composer.json | 1 + composer.lock | 4 +- .../Quote/SetPaymentMethodOnCartTest.php | 335 ++++++++++++++++++ 17 files changed, 797 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/BraintreeGraphQl/README.md create mode 100644 app/code/Magento/BraintreeGraphQl/composer.json create mode 100644 app/code/Magento/BraintreeGraphQl/etc/graphql/di.xml create mode 100644 app/code/Magento/BraintreeGraphQl/etc/module.xml create mode 100644 app/code/Magento/BraintreeGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/BraintreeGraphQl/registration.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Payment/AdditionalDataBuilderInterface.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Payment/AdditionalDataBuilderPool.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Payment/DefaultAdditionalDataBuilder.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Payment/MethodBuilder.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Payment/PaymentDataProvider.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/CartPaymentMethod.php create mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetPaymentMethodOnCartTest.php diff --git a/app/code/Magento/BraintreeGraphQl/README.md b/app/code/Magento/BraintreeGraphQl/README.md new file mode 100644 index 0000000000000..f6740e4d250e9 --- /dev/null +++ b/app/code/Magento/BraintreeGraphQl/README.md @@ -0,0 +1,4 @@ +# BraintreeGraphQl + +**BraintreeGraphQl** provides type and resolver for method additional +information. \ No newline at end of file diff --git a/app/code/Magento/BraintreeGraphQl/composer.json b/app/code/Magento/BraintreeGraphQl/composer.json new file mode 100644 index 0000000000000..a322db9d257dc --- /dev/null +++ b/app/code/Magento/BraintreeGraphQl/composer.json @@ -0,0 +1,24 @@ +{ + "name": "magento/module-braintree-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*" + }, + "suggest": { + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\BraintreeGraphQl\\": "" + } + } +} diff --git a/app/code/Magento/BraintreeGraphQl/etc/graphql/di.xml b/app/code/Magento/BraintreeGraphQl/etc/graphql/di.xml new file mode 100644 index 0000000000000..3788a0c2f1325 --- /dev/null +++ b/app/code/Magento/BraintreeGraphQl/etc/graphql/di.xml @@ -0,0 +1,27 @@ + + + + + + + BraintreeAdditionalDataBuilder + BraintreeVaultAdditionalDataBuilder + + + + + + Magento\Braintree\Model\Ui\ConfigProvider::CODE + + + + + Magento\Braintree\Model\Ui\ConfigProvider::CC_VAULT_CODE + + + diff --git a/app/code/Magento/BraintreeGraphQl/etc/module.xml b/app/code/Magento/BraintreeGraphQl/etc/module.xml new file mode 100644 index 0000000000000..2133e95a69104 --- /dev/null +++ b/app/code/Magento/BraintreeGraphQl/etc/module.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/app/code/Magento/BraintreeGraphQl/etc/schema.graphqls b/app/code/Magento/BraintreeGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..83c98a68d85ee --- /dev/null +++ b/app/code/Magento/BraintreeGraphQl/etc/schema.graphqls @@ -0,0 +1,18 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +input PaymentMethodInput { + braintree: BraintreeInput + braintree_vault: BraintreeVaultInput +} + +input BraintreeInput { + payment_method_nonce: String! + is_active_payment_token_enabler: Boolean! +} + +input BraintreeVaultInput { + payment_method_nonce: String! + public_hash: String! + is_active_payment_token_enabler: Boolean! +} diff --git a/app/code/Magento/BraintreeGraphQl/registration.php b/app/code/Magento/BraintreeGraphQl/registration.php new file mode 100644 index 0000000000000..37f7ef30864cb --- /dev/null +++ b/app/code/Magento/BraintreeGraphQl/registration.php @@ -0,0 +1,10 @@ +builders = $builders; + } + + public function buildForMethod(string $methodCode, array $args): array + { + $additionalData = []; + if (isset($this->builders[$methodCode])) { + $additionalData = $this->builders[$methodCode]->build($args); + } + + return $additionalData; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/DefaultAdditionalDataBuilder.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/DefaultAdditionalDataBuilder.php new file mode 100644 index 0000000000000..5a032ccc6386d --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/DefaultAdditionalDataBuilder.php @@ -0,0 +1,43 @@ +arrayManager = $arrayManager; + $this->methodCode = $methodCode; + } + + public function build(array $args): array + { + return $this->arrayManager->get($this->getAdditionalDataPath(), $args) ?? []; + } + + private function getAdditionalDataPath(): string + { + return sprintf(static::INPUT_PATH_ADDITIONAL_DATA, $this->methodCode); + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/MethodBuilder.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/MethodBuilder.php new file mode 100644 index 0000000000000..110e24d7d0fe5 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/MethodBuilder.php @@ -0,0 +1,62 @@ +paymentFactory = $paymentFactory; + $this->additionalDataBuilderPool = $additionalDataBuilderPool; + $this->arrayManager = $arrayManager; + } + + public function build(array $args): PaymentInterface + { + $method = (string) $this->arrayManager->get('input/payment_method/method', $args); + + return $this->paymentFactory->create([ + 'data' => [ + PaymentInterface::KEY_METHOD => $method, + PaymentInterface::KEY_PO_NUMBER => $this->arrayManager->get('input/payment_method/po_number', $args), + PaymentInterface::KEY_ADDITIONAL_DATA => $this->additionalDataBuilderPool->buildForMethod( + $method, + $args + ), + ] + ]); + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/PaymentDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/PaymentDataProvider.php new file mode 100644 index 0000000000000..22adc69d1cc58 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/Payment/PaymentDataProvider.php @@ -0,0 +1,35 @@ +getPayment(); + if (!$payment) { + return []; + } + + return [ + 'method' => $payment->getMethod(), + 'po_number' => $payment->getPoNumber(), + ]; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartPaymentMethod.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartPaymentMethod.php new file mode 100644 index 0000000000000..9e75256cd9b2b --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartPaymentMethod.php @@ -0,0 +1,58 @@ +paymentDataProvider = $paymentDataProvider; + $this->getCartForUser = $getCartForUser; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (!isset($value['cart_id'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + $maskedCartId = $value['cart_id']; + $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); + + return $this->paymentDataProvider->getCartPayment($cart); + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php new file mode 100644 index 0000000000000..5e48b3413f7ce --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentMethodOnCart.php @@ -0,0 +1,102 @@ +maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; + $this->getCartForUser = $getCartForUser; + $this->arrayManager = $arrayManager; + $this->paymentMethodManagement = $paymentMethodManagement; + $this->methodBuilder = $methodBuilder; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + $paymentMethod = $this->arrayManager->get('input/payment_method', $args); + $maskedCartId = $this->arrayManager->get('input/cart_id', $args); + + if (!$maskedCartId) { + throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); + } + if (!$paymentMethod) { + throw new GraphQlInputException(__('Required parameter "payment_method" is missing')); + } + + $maskedCartId = $args['input']['cart_id']; + $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); + + try { + $this->paymentMethodManagement->set($cart->getId(), $this->methodBuilder->build($args)); + } catch (LocalizedException $e) { + throw new GraphQlInputException(__($e->getMessage())); + } + + return [ + 'cart' => [ + 'cart_id' => $maskedCartId, + ], + ]; + } +} diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 4c1101a5f90a8..e1dd06f64cf88 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -15,6 +15,17 @@ type Mutation { setBillingAddressOnCart(input: SetBillingAddressOnCartInput): SetBillingAddressOnCartOutput setShippingMethodsOnCart(input: SetShippingMethodsOnCartInput): SetShippingMethodsOnCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SetShippingMethodsOnCart") addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart") + setPaymentMethodOnCart(input: SetPaymentMethodOnCartInput): SetPaymentMethodOnCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\SetPaymentMethodOnCart") +} + +input SetPaymentMethodOnCartInput { + cart_id: String! + payment_method: PaymentMethodInput! +} + +input PaymentMethodInput { + method: String! + po_number: String } input SetShippingAddressesOnCartInput { @@ -64,6 +75,10 @@ input ShippingMethodForAddressInput { shipping_method_code: String! } +type SetPaymentMethodOnCartOutput { + cart: Cart! +} + type SetBillingAddressOnCartOutput { cart: Cart! } @@ -98,6 +113,7 @@ type Cart { items: [CartItemInterface] applied_coupon: AppliedCoupon addresses: [CartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartAddresses") + payment_method: CartPaymentMethod @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartPaymentMethod") } type CartAddress { @@ -118,6 +134,11 @@ type CartAddress { cart_items: [CartItemQuantity] } +type CartPaymentMethod { + method: String + po_number: String +} + type CartItemQuantity { cart_item_id: String! quantity: Float! diff --git a/composer.json b/composer.json index 3222de2d1fe0f..69924d836b9e7 100644 --- a/composer.json +++ b/composer.json @@ -108,6 +108,7 @@ "magento/module-backend": "*", "magento/module-backup": "*", "magento/module-braintree": "*", + "magento/module-braintree-graph-ql": "*", "magento/module-bundle": "*", "magento/module-bundle-graph-ql": "*", "magento/module-bundle-import-export": "*", diff --git a/composer.lock b/composer.lock index 697e7df3e19aa..172866d59f4ff 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "3f58ddc5609e6a934ee3706006357646", + "content-hash": "bee21a1a1fa89a8a2dc5aedcd087d1e7", "packages": [ { "name": "braintree/braintree_php", diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetPaymentMethodOnCartTest.php new file mode 100644 index 0000000000000..cd16123d428b0 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetPaymentMethodOnCartTest.php @@ -0,0 +1,335 @@ +quoteResource = $objectManager->create(QuoteResource::class); + $this->quote = $objectManager->create(Quote::class); + $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class); + $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + $this->config = $objectManager->get(Config::class); + $this->cacheList = $objectManager->get(TypeListInterface::class); + + foreach (static::OFFLINE_METHOD_CODES as $offlineMethodCode) { + $this->config->saveConfig( + 'payment/' . $offlineMethodCode . '/active', + '1', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + } + $this->cacheList->cleanType('config'); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + foreach (static::OFFLINE_METHOD_CODES as $offlineMethodCode) { + //Never no disable checkmo method + if ($offlineMethodCode === Checkmo::PAYMENT_METHOD_CHECKMO_CODE) { + continue; + } + $this->config->saveConfig( + 'payment/' . $offlineMethodCode . '/active', + '0', + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + } + $this->cacheList->cleanType('config'); + } + + /** + * @param string $methodCode + * @dataProvider dataProviderOfflinePaymentMethods + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetPaymentMethodOnCart(string $methodCode) + { + /** @var \Magento\Config\Model\ResourceModel\Config $config */ + $config = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class); + $config->saveConfig( + 'payment/' . $methodCode . '/active', + 1, + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $methodCode + ); + + $response = $this->sendRequestWithToken($query); + + $this->assertArrayHasKey('setPaymentMethodOnCart', $response); + $this->assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); + $this->assertEquals($maskedQuoteId, $response['setPaymentMethodOnCart']['cart']['cart_id']); + $this->assertArrayHasKey('payment_method', $response['setPaymentMethodOnCart']['cart']); + $this->assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['payment_method']['method']); + } + + public function dataProviderOfflinePaymentMethods(): array + { + $methods = []; + foreach (static::OFFLINE_METHOD_CODES as $offlineMethodCode) { + //Purchase order requires additional input and is tested separately + if ($offlineMethodCode === Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE) { + continue; + } + $methods[] = [$offlineMethodCode]; + } + + return $methods; + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetNonExistingPaymentMethod() + { + $paymentMethod = 'noway'; + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $paymentMethod + ); + + $this->expectExceptionMessage('The requested Payment Method is not available.'); + $this->sendRequestWithToken($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetPaymentMethodByGuestToCustomerCart() + { + $paymentMethod = 'checkmo'; + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + $paymentMethod + ); + + $this->expectExceptionMessage( + "The current user cannot perform operations on cart \"$maskedQuoteId\"" + ); + + $this->graphQlQuery($query); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testSetPaymentMethodPurchaseOrderOnCart() + { + $methodCode = \Magento\OfflinePayments\Model\Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE; + $poNumber = 'GQL-19002'; + + /** @var \Magento\Config\Model\ResourceModel\Config $config */ + $config = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class); + $config->saveConfig( + 'payment/' . $methodCode . '/active', + 1, + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<sendRequestWithToken($query); + + $this->assertArrayHasKey('setPaymentMethodOnCart', $response); + $this->assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); + $this->assertEquals($maskedQuoteId, $response['setPaymentMethodOnCart']['cart']['cart_id']); + $this->assertArrayHasKey('payment_method', $response['setPaymentMethodOnCart']['cart']); + $this->assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['payment_method']['method']); + $this->assertEquals($poNumber, $response['setPaymentMethodOnCart']['cart']['payment_method']['po_number']); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + */ + public function testPurchaseOrderPaymentMethodFailingValidation() + { + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = $this->prepareMutationQuery( + $maskedQuoteId, + Purchaseorder::PAYMENT_METHOD_PURCHASEORDER_CODE + ); + + $this->expectExceptionMessage('Purchase order number is a required field.'); + $this->sendRequestWithToken($query); + } + + /** + * Generates query for setting the specified shipping method on cart + * + * @param string $maskedQuoteId + * @param string $methodCode + * @return string + */ + private function prepareMutationQuery( + string $maskedQuoteId, + string $methodCode + ) : string { + return <<customerTokenService->createCustomerAccessToken('customer@example.com', 'password'); + $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; + + return $this->graphQlQuery($query, [], '', $headerMap); + } +} From 8ec9a3ab8bfe02aa7bb4da56249dfe493c7fb049 Mon Sep 17 00:00:00 2001 From: jaideepghosh Date: Thu, 7 Feb 2019 19:44:41 +0530 Subject: [PATCH 27/75] Update static block in nginx.conf Update the 'nginx.conf.sample' to allow the browsers for accessing the static contents even in multisite mode also. --- nginx.conf.sample | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nginx.conf.sample b/nginx.conf.sample index 90604808f6ec0..eec85c74cec69 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -99,16 +99,16 @@ location /static/ { # Remove signature of the static files that is used to overcome the browser cache location ~ ^/static/version { - rewrite ^/static/(version[^/]+/)?(.*)$ /static/$2 last; + rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last; } - location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ { + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { add_header Cache-Control "public"; add_header X-Frame-Options "SAMEORIGIN"; expires +1y; if (!-f $request_filename) { - rewrite ^/static/?(.*)$ /static.php?resource=$1 last; + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; } } location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { @@ -117,11 +117,11 @@ location /static/ { expires off; if (!-f $request_filename) { - rewrite ^/static/?(.*)$ /static.php?resource=$1 last; + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; } } if (!-f $request_filename) { - rewrite ^/static/?(.*)$ /static.php?resource=$1 last; + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; } add_header X-Frame-Options "SAMEORIGIN"; } From e5603018be8113f3acd124b896da4666c538dcea Mon Sep 17 00:00:00 2001 From: jaideepghosh Date: Thu, 7 Feb 2019 19:49:47 +0530 Subject: [PATCH 28/75] update nginx.conf.sample to serve json also. --- nginx.conf.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx.conf.sample b/nginx.conf.sample index eec85c74cec69..ce3891627bc8c 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -102,7 +102,7 @@ location /static/ { rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last; } - location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ { add_header Cache-Control "public"; add_header X-Frame-Options "SAMEORIGIN"; expires +1y; From cab38a21087525b72add16910b6eccf7eb7e1b63 Mon Sep 17 00:00:00 2001 From: Vinai Kopp Date: Sun, 3 Feb 2019 17:46:26 +0530 Subject: [PATCH 29/75] magento/magento2#20773: Make autoloader PSR-4 compliant --- .../Code/Generator/AutoloaderTest.php | 85 +++++++++++++++++++ .../Framework/Code/Generator/Autoloader.php | 70 +++++++++++++-- 2 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php new file mode 100644 index 0000000000000..0e1b51b3ae273 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php @@ -0,0 +1,85 @@ +createMock(LoggerInterface::class); + $this->getTestFrameworkObjectManager()->addSharedInstance($loggerTestDouble, MagentoMonologLogger::class); + } + + /** + * @after + */ + public function removeLoggerTestDouble(): void + { + $this->getTestFrameworkObjectManager()->removeSharedInstance(MagentoMonologLogger::class); + } + + /** + * @param \RuntimeException $testException + * @return Generator|MockObject + */ + private function createExceptionThrowingGeneratorTestDouble(\RuntimeException $testException) + { + /** @var Generator|MockObject $generatorStub */ + $generatorStub = $this->createMock(Generator::class); + $generatorStub->method('generateClass')->willThrowException($testException); + + return $generatorStub; + } + + public function testLogsExceptionDuringGeneration(): void + { + $exceptionMessage = 'Test exception thrown during generation'; + $testException = new \RuntimeException($exceptionMessage); + + $loggerMock = ObjectManager::getInstance()->get(LoggerInterface::class); + $loggerMock->expects($this->once())->method('debug')->with($exceptionMessage, ['exception' => $testException]); + + $autoloader = new Autoloader($this->createExceptionThrowingGeneratorTestDouble($testException)); + $this->assertNull($autoloader->load(NonExistingClassName::class)); + } + + public function testFiltersDuplicateExceptionMessages(): void + { + $exceptionMessage = 'Test exception thrown during generation'; + $testException = new \RuntimeException($exceptionMessage); + + $loggerMock = ObjectManager::getInstance()->get(LoggerInterface::class); + $loggerMock->expects($this->once())->method('debug')->with($exceptionMessage, ['exception' => $testException]); + + $autoloader = new Autoloader($this->createExceptionThrowingGeneratorTestDouble($testException)); + $autoloader->load(OneNonExistingClassName::class); + $autoloader->load(AnotherNonExistingClassName::class); + } +} diff --git a/lib/internal/Magento/Framework/Code/Generator/Autoloader.php b/lib/internal/Magento/Framework/Code/Generator/Autoloader.php index c214008393609..1afa97729b158 100644 --- a/lib/internal/Magento/Framework/Code/Generator/Autoloader.php +++ b/lib/internal/Magento/Framework/Code/Generator/Autoloader.php @@ -3,37 +3,89 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Framework\Code\Generator; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Code\Generator; +use Psr\Log\LoggerInterface; class Autoloader { /** - * @var \Magento\Framework\Code\Generator + * @var Generator */ protected $_generator; /** - * @param \Magento\Framework\Code\Generator $generator + * Enables guarding against spamming the debug log with duplicate messages, as + * the generation exception will be thrown multiple times within a single request. + * + * @var string + */ + private $lastGenerationErrorMessage; + + /** + * @param Generator $generator */ - public function __construct( - \Magento\Framework\Code\Generator $generator - ) { + public function __construct(Generator $generator) + { $this->_generator = $generator; } /** * Load specified class name and generate it if necessary * + * According to PSR-4 section 2.4 an autoloader MUST NOT throw an exception and SHOULD NOT return a value. + * + * @see https://www.php-fig.org/psr/psr-4/ + * * @param string $className - * @return bool True if class was loaded + * @return void */ public function load($className) { - if (!class_exists($className)) { - return Generator::GENERATION_ERROR != $this->_generator->generateClass($className); + if (! class_exists($className)) { + try { + $this->_generator->generateClass($className); + } catch (\Exception $exception) { + $this->tryToLogExceptionMessageIfNotDuplicate($exception); + } + } + } + + /** + * @param \Exception $exception + */ + private function tryToLogExceptionMessageIfNotDuplicate(\Exception $exception): void + { + if ($this->lastGenerationErrorMessage !== $exception->getMessage()) { + $this->lastGenerationErrorMessage = $exception->getMessage(); + $this->tryToLogException($exception); + } + } + + /** + * Try to capture the exception message. + * + * The Autoloader is instantiated before the ObjectManager, so the LoggerInterface can not be injected. + * The Logger is instantiated in the try/catch block because ObjectManager might still not be initialized. + * In that case the exception message can not be captured. + * + * The debug level is used for logging in case class generation fails for a common class, but a custom + * autoloader is used later in the stack. A more severe log level would fill the logs with messages on production. + * The exception message now can be accessed in developer mode if debug logging is enabled. + * + * @param \Exception $exception + * @return void + */ + private function tryToLogException(\Exception $exception): void + { + try { + $logger = ObjectManager::getInstance()->get(LoggerInterface::class); + $logger->debug($exception->getMessage(), ['exception' => $exception]); + } catch (\Exception $ignoreThisException) { + // Do not take an action here, since the original exception might have been caused by logger } - return true; } } From b46c740c6f2a2ccc940f4040b45314b0301d644b Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Wed, 13 Feb 2019 09:01:48 -0600 Subject: [PATCH 30/75] MAGETWO-98225: AuthorizenetAcceptjs broken for multi-shipping checkout - Fixed option - Added config test coverage --- app/code/Magento/AuthorizenetAcceptjs/etc/payment.xml | 2 +- .../Magento/AuthorizenetAcceptjs/Gateway/ConfigTest.php | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/payment.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/payment.xml index b8292839c3bd1..b9f8d40b03006 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/payment.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/etc/payment.xml @@ -9,7 +9,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Payment:etc/payment.xsd"> - 1 + 0 diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/ConfigTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/ConfigTest.php index 7e6aeda5a7a6d..a37f927274242 100644 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/ConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/ConfigTest.php @@ -8,6 +8,7 @@ namespace Magento\AuthorizenetAcceptjs\Gateway; +use Magento\Framework\Config\Data; use Magento\Payment\Model\Method\Adapter; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\ObjectManager; @@ -40,5 +41,11 @@ public function testVerifyConfiguration() $this->assertTrue($paymentAdapter->canUseInternal()); $this->assertTrue($paymentAdapter->canEdit()); $this->assertTrue($paymentAdapter->canFetchTransactionInfo()); + + /** @var Data $configReader */ + $configReader = $this->objectManager->get('Magento\Payment\Model\Config\Data'); + $value = $configReader->get('methods/authorizenet_acceptjs/allow_multiple_address'); + + $this->assertSame('0', $value); } } From 111dd2ceafbfc7aae5d8e6bd553117c3936515bb Mon Sep 17 00:00:00 2001 From: Dave Macaulay Date: Fri, 15 Feb 2019 17:13:56 +0100 Subject: [PATCH 31/75] MC-14858: Failing MFTF Test: CheckMessageDisplayedForUsedCompanyTest - Ensure filters are cleared after executing test --- .../Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilter.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilter.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilter.xml index 7c24a8aba27bd..79eec02a828f6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilter.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilter.xml @@ -28,6 +28,7 @@ + From 80cd335e35ad9827954492427db81db14b1c510f Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Fri, 15 Feb 2019 16:30:13 -0600 Subject: [PATCH 32/75] MAGETWO-98258: Fix elacticsearch search perfomance - reverting back fix --- .../Product/FieldProvider/DynamicField.php | 2 +- .../Aggregation/Builder/Term.php | 9 +-- .../SearchAdapter/Query/Builder/Match.php | 52 ++++--------- .../ValueTransformer/DateTransformer.php | 44 ----------- .../ValueTransformer/FloatTransformer.php | 24 ------ .../ValueTransformer/IntegerTransformer.php | 24 ------ .../ValueTransformer/TextTransformer.php | 65 ---------------- .../Query/ValueTransformerInterface.php | 22 ------ .../Query/ValueTransformerPool.php | 46 ----------- .../SearchAdapter/Query/Builder/MatchTest.php | 76 ++++++++++++------- app/code/Magento/Elasticsearch/etc/di.xml | 18 ----- .../Model/ResourceModel/SynonymReader.php | 14 +--- ...llback.php => text_attribute_rollback.php} | 6 +- .../_files/product_export_data_rollback.php | 8 +- ...uct_export_data_special_chars_rollback.php | 8 +- .../SearchAdapter/AdapterTest.php | 14 ---- .../Search/_files/filterable_attributes.php | 33 +------- .../_files/filterable_attributes_rollback.php | 12 +-- .../Search/Model/SynonymReaderTest.php | 17 +---- 19 files changed, 81 insertions(+), 413 deletions(-) delete mode 100644 app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/DateTransformer.php delete mode 100644 app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/FloatTransformer.php delete mode 100644 app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/IntegerTransformer.php delete mode 100644 app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/TextTransformer.php delete mode 100644 app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformerInterface.php delete mode 100644 app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformerPool.php rename dev/tests/integration/testsuite/Magento/Catalog/_files/{product_text_attribute_rollback.php => text_attribute_rollback.php} (84%) diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php index 9e2659a757924..c7e2a4beabb5c 100644 --- a/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php +++ b/app/code/Magento/Elasticsearch/Model/Adapter/FieldMapper/Product/FieldProvider/DynamicField.php @@ -126,7 +126,7 @@ public function getFields(array $context = []): array foreach ($groups as $group) { $groupPriceKey = $this->fieldNameResolver->getFieldName( $priceAttribute, - array_merge($context, ['customerGroupId' => $group->getId()]) + ['customerGroupId' => $group->getId(), 'websiteId' => $context['websiteId']] ); $allAttributes[$groupPriceKey] = [ 'type' => $this->fieldTypeConverter->convert(FieldTypeConverterInterface::INTERNAL_DATA_TYPE_FLOAT), diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php b/app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php index eeb48f805bccf..bcfb7f5565b86 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php @@ -8,13 +8,10 @@ use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; use Magento\Framework\Search\Dynamic\DataProviderInterface; -/** - * Builder for term buckets. - */ class Term implements BucketBuilderInterface { /** - * @inheritdoc + * {@inheritdoc} */ public function build( RequestBucketInterface $bucket, @@ -22,15 +19,13 @@ public function build( array $queryResult, DataProviderInterface $dataProvider ) { - $buckets = $queryResult['aggregations'][$bucket->getName()]['buckets'] ?? []; $values = []; - foreach ($buckets as $resultBucket) { + foreach ($queryResult['aggregations'][$bucket->getName()]['buckets'] as $resultBucket) { $values[$resultBucket['key']] = [ 'value' => $resultBucket['key'], 'count' => $resultBucket['doc_count'], ]; } - return $values; } } diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php index e83c49941bcc2..f1c3451482bab 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php @@ -5,16 +5,11 @@ */ namespace Magento\Elasticsearch\SearchAdapter\Query\Builder; -use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerPool; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Search\Request\Query\BoolExpression; use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface; -/** - * Builder for match query. - */ class Match implements QueryInterface { /** @@ -28,35 +23,24 @@ class Match implements QueryInterface private $fieldMapper; /** - * @deprecated - * @see \Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer\TextTransformer * @var PreprocessorInterface[] */ protected $preprocessorContainer; - /** - * @var ValueTransformerPool - */ - private $valueTransformerPool; - /** * @param FieldMapperInterface $fieldMapper * @param PreprocessorInterface[] $preprocessorContainer - * @param ValueTransformerPool|null $valueTransformerPool */ public function __construct( FieldMapperInterface $fieldMapper, - array $preprocessorContainer, - ValueTransformerPool $valueTransformerPool = null + array $preprocessorContainer ) { $this->fieldMapper = $fieldMapper; $this->preprocessorContainer = $preprocessorContainer; - $this->valueTransformerPool = $valueTransformerPool ?? ObjectManager::getInstance() - ->get(ValueTransformerPool::class); } /** - * @inheritdoc + * {@inheritdoc} */ public function build(array $selectQuery, RequestQueryInterface $requestQuery, $conditionType) { @@ -77,14 +61,16 @@ public function build(array $selectQuery, RequestQueryInterface $requestQuery, $ } /** - * Prepare query. - * * @param string $queryValue * @param string $conditionType * @return array */ protected function prepareQuery($queryValue, $conditionType) { + $queryValue = $this->escape($queryValue); + foreach ($this->preprocessorContainer as $preprocessor) { + $queryValue = $preprocessor->process($queryValue); + } $condition = $conditionType === BoolExpression::QUERY_CONDITION_NOT ? self::QUERY_CONDITION_MUST_NOT : $conditionType; return [ @@ -113,34 +99,21 @@ protected function buildQueries(array $matches, array $queryValue) // Checking for quoted phrase \"phrase test\", trim escaped surrounding quotes if found $count = 0; - $value = preg_replace('#^"(.*)"$#m', '$1', $queryValue['value'], -1, $count); + $value = preg_replace('#^\\\\"(.*)\\\\"$#m', '$1', $queryValue['value'], -1, $count); $condition = ($count) ? 'match_phrase' : 'match'; - $attributesTypes = $this->fieldMapper->getAllAttributesTypes(); - $transformedTypes = []; foreach ($matches as $match) { $resolvedField = $this->fieldMapper->getFieldName( $match['field'], ['type' => FieldMapperInterface::TYPE_QUERY] ); - $valueTransformer = $this->valueTransformerPool->get($attributesTypes[$resolvedField]['type'] ?? 'text'); - $valueTransformerHash = \spl_object_hash($valueTransformer); - if (!isset($transformedTypes[$valueTransformerHash])) { - $transformedTypes[$valueTransformerHash] = $valueTransformer->transform($value); - } - $transformedValue = $transformedTypes[$valueTransformerHash]; - if (null === $transformedValue) { - //Value is incompatible with this field type. - continue; - } - $conditions[] = [ 'condition' => $queryValue['condition'], 'body' => [ $condition => [ $resolvedField => [ - 'query' => $transformedValue, - 'boost' => $match['boost'] ?? 1, + 'query' => $value, + 'boost' => isset($match['boost']) ? $match['boost'] : 1, ], ], ], @@ -151,15 +124,18 @@ protected function buildQueries(array $matches, array $queryValue) } /** + * Cut trailing plus or minus sign, and @ symbol, using of which causes InnoDB to report a syntax error. + * @link https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html Fulltext-boolean search docs. + * * Escape a value for special query characters such as ':', '(', ')', '*', '?', etc. * - * @deprecated - * @see \Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer\TextTransformer * @param string $value * @return string */ protected function escape($value) { + $value = preg_replace('/@+|[@+-]+$/', '', $value); + $pattern = '/(\+|-|&&|\|\||!|\(|\)|\{|}|\[|]|\^|"|~|\*|\?|:|\\\)/'; $replace = '\\\$1'; diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/DateTransformer.php b/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/DateTransformer.php deleted file mode 100644 index 49eca6e9d82a6..0000000000000 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/DateTransformer.php +++ /dev/null @@ -1,44 +0,0 @@ -dateFieldType = $dateFieldType; - } - - /** - * @inheritdoc - */ - public function transform(string $value): ?string - { - try { - $formattedDate = $this->dateFieldType->formatDate(null, $value); - } catch (\Exception $e) { - $formattedDate = null; - } - - return $formattedDate; - } -} diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/FloatTransformer.php b/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/FloatTransformer.php deleted file mode 100644 index 5e330076d3df7..0000000000000 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformer/FloatTransformer.php +++ /dev/null @@ -1,24 +0,0 @@ -preprocessors = $preprocessors; - } - - /** - * @inheritdoc - */ - public function transform(string $value): string - { - $value = $this->escape($value); - foreach ($this->preprocessors as $preprocessor) { - $value = $preprocessor->process($value); - } - - return $value; - } - - /** - * Escape a value for special query characters such as ':', '(', ')', '*', '?', etc. - * - * @param string $value - * @return string - */ - private function escape(string $value): string - { - $pattern = '/(\+|-|&&|\|\||!|\(|\)|\{|}|\[|]|\^|"|~|\*|\?|:|\\\)/'; - $replace = '\\\$1'; - - return preg_replace($pattern, $replace, $value); - } -} diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformerInterface.php b/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformerInterface.php deleted file mode 100644 index c84ddc69cc7a8..0000000000000 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Query/ValueTransformerInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -transformers = $valueTransformers; - } - - /** - * Get value transformer related to field type. - * - * @param string $fieldType - * @return ValueTransformerInterface - */ - public function get(string $fieldType): ValueTransformerInterface - { - return $this->transformers[$fieldType] ?? $this->transformers['default']; - } -} diff --git a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Query/Builder/MatchTest.php b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Query/Builder/MatchTest.php index c8aa3db39bd5e..8114feb09d35d 100644 --- a/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Query/Builder/MatchTest.php +++ b/app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Query/Builder/MatchTest.php @@ -7,8 +7,6 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Elasticsearch\SearchAdapter\Query\Builder\Match as MatchQueryBuilder; -use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerInterface; -use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerPool; use Magento\Framework\Search\Request\Query\Match as MatchRequestQuery; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit_Framework_MockObject_MockObject as MockObject; @@ -25,48 +23,46 @@ class MatchTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $valueTransformerPoolMock = $this->createMock(ValueTransformerPool::class); - $valueTransformerMock = $this->createMock(ValueTransformerInterface::class); - $valueTransformerPoolMock->method('get') - ->willReturn($valueTransformerMock); - $valueTransformerMock->method('transform') - ->willReturnArgument(0); - $this->matchQueryBuilder = (new ObjectManager($this))->getObject( MatchQueryBuilder::class, [ 'fieldMapper' => $this->getFieldMapper(), 'preprocessorContainer' => [], - 'valueTransformerPool' => $valueTransformerPoolMock, ] ); } /** * Tests that method constructs a correct select query. - * * @see MatchQueryBuilder::build + * + * @dataProvider queryValuesInvariantsProvider + * + * @param string $rawQueryValue + * @param string $errorMessage */ - public function testBuild() + public function testBuild($rawQueryValue, $errorMessage) { - $rawQueryValue = 'query_value'; - $selectQuery = $this->matchQueryBuilder->build([], $this->getMatchRequestQuery($rawQueryValue), 'not'); + $this->assertSelectQuery( + $this->matchQueryBuilder->build([], $this->getMatchRequestQuery($rawQueryValue), 'not'), + $errorMessage + ); + } - $expectedSelectQuery = [ - 'bool' => [ - 'must_not' => [ - [ - 'match' => [ - 'some_field' => [ - 'query' => $rawQueryValue, - 'boost' => 43, - ], - ], - ], - ], - ], + /** + * @link https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html Fulltext-boolean search docs. + * + * @return array + */ + public function queryValuesInvariantsProvider() + { + return [ + ['query_value', 'Select query field must match simple raw query value.'], + ['query_value+', 'Specifying a trailing plus sign causes InnoDB to report a syntax error.'], + ['query_value-', 'Specifying a trailing minus sign causes InnoDB to report a syntax error.'], + ['query_@value', 'The @ symbol is reserved for use by the @distance proximity search operator.'], + ['query_value+@', 'The @ symbol is reserved for use by the @distance proximity search operator.'], ]; - $this->assertEquals($expectedSelectQuery, $selectQuery); } /** @@ -115,6 +111,30 @@ public function matchProvider() ]; } + /** + * @param array $selectQuery + * @param string $errorMessage + */ + private function assertSelectQuery($selectQuery, $errorMessage) + { + $expectedSelectQuery = [ + 'bool' => [ + 'must_not' => [ + [ + 'match' => [ + 'some_field' => [ + 'query' => 'query_value', + 'boost' => 43, + ], + ], + ], + ], + ], + ]; + + $this->assertEquals($expectedSelectQuery, $selectQuery, $errorMessage); + } + /** * Gets fieldMapper mock object. * diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 05a67605ba0e6..7e219bb2f918f 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -421,22 +421,4 @@ - - - - Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer\TextTransformer - Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer\DateTransformer - Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer\FloatTransformer - Magento\Elasticsearch\SearchAdapter\Query\ValueTransformer\IntegerTransformer - - - - - - - Magento\Elasticsearch\SearchAdapter\Query\Preprocessor\Stopwords - Magento\Search\Adapter\Query\Preprocessor\Synonyms - - - diff --git a/app/code/Magento/Search/Model/ResourceModel/SynonymReader.php b/app/code/Magento/Search/Model/ResourceModel/SynonymReader.php index 45eee0a4001d1..46e794a1954cf 100644 --- a/app/code/Magento/Search/Model/ResourceModel/SynonymReader.php +++ b/app/code/Magento/Search/Model/ResourceModel/SynonymReader.php @@ -87,7 +87,7 @@ private function queryByPhrase($phrase) { $matchQuery = $this->fullTextSelect->getMatchQuery( ['synonyms' => 'synonyms'], - $this->escapePhrase($phrase), + $phrase, Fulltext::FULLTEXT_MODE_BOOLEAN ); $query = $this->getConnection()->select()->from( @@ -97,18 +97,6 @@ private function queryByPhrase($phrase) return $this->getConnection()->fetchAll($query); } - /** - * Cut trailing plus or minus sign, and @ symbol, using of which causes InnoDB to report a syntax error. - * - * @see https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html - * @param string $phrase - * @return string - */ - private function escapePhrase(string $phrase): string - { - return preg_replace('/@+|[@+-]+$/', '', $phrase); - } - /** * A private helper function to retrieve matching synonym groups per scope * diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_text_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/text_attribute_rollback.php similarity index 84% rename from dev/tests/integration/testsuite/Magento/Catalog/_files/product_text_attribute_rollback.php rename to dev/tests/integration/testsuite/Magento/Catalog/_files/text_attribute_rollback.php index a9ab0e11312b2..cbc0476efd1b5 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_text_attribute_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/text_attribute_rollback.php @@ -3,15 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - /* Delete attribute with text_attribute code */ -$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); $registry->unregister('isSecureArea'); $registry->register('isSecureArea', true); - /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ $attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class + 'Magento\Catalog\Model\ResourceModel\Eav\Attribute' ); $attribute->load('text_attribute', 'attribute_code'); $attribute->delete(); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_rollback.php index c57c7c3fd6a92..168073bc6ab74 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_rollback.php @@ -5,10 +5,10 @@ */ /** Delete all products */ -include dirname(dirname(__DIR__)) . '/Catalog/_files/products_with_multiselect_attribute_rollback.php'; +require dirname(dirname(__DIR__)) . '/Catalog/_files/products_with_multiselect_attribute_rollback.php'; /** Delete text attribute */ -include dirname(dirname(__DIR__)) . '/Catalog/_files/product_text_attribute_rollback.php'; +require dirname(dirname(__DIR__)) . '/Catalog/_files/text_attribute_rollback.php'; -include dirname(dirname(__DIR__)) . '/Store/_files/second_store_rollback.php'; +require dirname(dirname(__DIR__)) . '/Store/_files/second_store_rollback.php'; -include dirname(dirname(__DIR__)) . '/Catalog/_files/category_rollback.php'; +require dirname(dirname(__DIR__)) . '/Catalog/_files/category_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars_rollback.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars_rollback.php index c57c7c3fd6a92..168073bc6ab74 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars_rollback.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data_special_chars_rollback.php @@ -5,10 +5,10 @@ */ /** Delete all products */ -include dirname(dirname(__DIR__)) . '/Catalog/_files/products_with_multiselect_attribute_rollback.php'; +require dirname(dirname(__DIR__)) . '/Catalog/_files/products_with_multiselect_attribute_rollback.php'; /** Delete text attribute */ -include dirname(dirname(__DIR__)) . '/Catalog/_files/product_text_attribute_rollback.php'; +require dirname(dirname(__DIR__)) . '/Catalog/_files/text_attribute_rollback.php'; -include dirname(dirname(__DIR__)) . '/Store/_files/second_store_rollback.php'; +require dirname(dirname(__DIR__)) . '/Store/_files/second_store_rollback.php'; -include dirname(dirname(__DIR__)) . '/Catalog/_files/category_rollback.php'; +require dirname(dirname(__DIR__)) . '/Catalog/_files/category_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php index 8d80fd8533d6f..dc288a18fadb7 100644 --- a/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/SearchAdapter/AdapterTest.php @@ -369,18 +369,4 @@ public function dateDataProvider() [['from' => '2000-02-01T00:00:00Z', 'to' => ''], 0], ]; } - - public function filterByAttributeValuesDataProvider() - { - $variations = parent::filterByAttributeValuesDataProvider(); - - $variations['quick search by date'] = [ - 'quick_search_container', - [ - 'search_term' => '2000-10-30', - ], - ]; - - return $variations; - } } 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..b09af48b5f943 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 @@ -20,10 +20,6 @@ CategorySetup::class, ['resourceName' => 'catalog_setup'] ); -$productEntityTypeId = $installer->getEntityTypeId( - \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE -); - $selectOptions = []; $selectAttributes = []; foreach (range(1, 2) as $index) { @@ -34,7 +30,7 @@ $selectAttribute->setData( [ 'attribute_code' => 'select_attribute_' . $index, - 'entity_type_id' => $productEntityTypeId, + 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), 'is_global' => 1, 'is_user_defined' => 1, 'frontend_input' => 'select', @@ -60,8 +56,7 @@ ); $selectAttribute->save(); /* Assign attribute to attribute set */ - $installer->addAttributeToGroup($productEntityTypeId, 'Default', 'General', $selectAttribute->getId()); - + $installer->addAttributeToGroup('catalog_product', 'Default', 'General', $selectAttribute->getId()); /** @var $selectOptions Collection */ $selectOption = Bootstrap::getObjectManager()->create( Collection::class @@ -70,26 +65,6 @@ $selectAttributes[$index] = $selectAttribute; $selectOptions[$index] = $selectOption; } - -$dateAttribute = Bootstrap::getObjectManager()->create(Attribute::class); -$dateAttribute->setData( - [ - 'attribute_code' => 'date_attribute', - 'entity_type_id' => $productEntityTypeId, - 'is_global' => 1, - 'is_filterable' => 1, - 'backend_type' => 'datetime', - 'frontend_input' => 'date', - 'frontend_label' => 'Test Date', - 'is_searchable' => 1, - 'is_filterable_in_search' => 1, - ] -); -$dateAttribute->save(); -/* Assign attribute to attribute set */ -$installer->addAttributeToGroup($productEntityTypeId, 'Default', 'General', $dateAttribute->getId()); - -$productAttributeSetId = $installer->getAttributeSetId($productEntityTypeId, 'Default'); /* Create simple products per each first attribute option */ foreach ($selectOptions[1] as $option) { /** @var $product Product */ @@ -99,7 +74,7 @@ $product->setTypeId( Type::TYPE_SIMPLE )->setAttributeSetId( - $productAttributeSetId + $installer->getAttributeSetId('catalog_product', 'Default') )->setWebsiteIds( [1] )->setName( @@ -117,7 +92,6 @@ )->setStockData( ['use_config_manage_stock' => 1, 'qty' => 5, 'is_in_stock' => 1] )->save(); - Bootstrap::getObjectManager()->get( Action::class )->updateAttributes( @@ -125,7 +99,6 @@ [ $selectAttributes[1]->getAttributeCode() => $option->getId(), $selectAttributes[2]->getAttributeCode() => $selectOptions[2]->getLastItem()->getId(), - $dateAttribute->getAttributeCode() => '10/30/2000', ], $product->getStoreId() ); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes_rollback.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes_rollback.php index fd413726b2637..18a5372d06d98 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes_rollback.php @@ -13,7 +13,6 @@ $registry = Bootstrap::getObjectManager()->get(Registry::class); $registry->unregister('isSecureArea'); $registry->register('isSecureArea', true); - /** @var $productCollection \Magento\Catalog\Model\ResourceModel\Product\Collection */ $productCollection = Bootstrap::getObjectManager() ->create(Product::class) @@ -21,26 +20,17 @@ foreach ($productCollection as $product) { $product->delete(); } - /** @var $attribute Attribute */ $attribute = Bootstrap::getObjectManager()->create( Attribute::class ); /** @var $installer CategorySetup */ $installer = Bootstrap::getObjectManager()->create(CategorySetup::class); -$productEntityTypeId = $installer->getEntityTypeId( - \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE -); foreach (range(1, 2) as $index) { - $attribute->loadByCode($productEntityTypeId, 'select_attribute_' . $index); + $attribute->loadByCode($installer->getEntityTypeId('catalog_product'), 'select_attribute_' . $index); if ($attribute->getId()) { $attribute->delete(); } } -$attribute->loadByCode($productEntityTypeId, 'date_attribute'); -if ($attribute->getId()) { - $attribute->delete(); -} - $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Search/Model/SynonymReaderTest.php b/dev/tests/integration/testsuite/Magento/Search/Model/SynonymReaderTest.php index 2d0020ba22680..b9ba89ba53144 100644 --- a/dev/tests/integration/testsuite/Magento/Search/Model/SynonymReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Search/Model/SynonymReaderTest.php @@ -48,22 +48,7 @@ public static function loadByPhraseDataProvider() ['synonyms' => 'queen,monarch', 'store_id' => 1, 'website_id' => 0], ['synonyms' => 'british,english', 'store_id' => 1, 'website_id' => 0] ] - ], - [ - 'query_value', [] - ], - [ - 'query_value+', [] - ], - [ - 'query_value-', [] - ], - [ - 'query_@value', [] - ], - [ - 'query_value+@', [] - ], + ] ]; } From e7e2f96b74675b0440bf1ee8d70160acb818f520 Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Fri, 15 Feb 2019 16:40:00 -0600 Subject: [PATCH 33/75] ENGCOM-4289: GraphQL 2.3.1 release fixes --- .../Model/Cart/AddSimpleProductToCart.php | 11 +- .../Cart/Address/AddressDataProvider.php | 94 ----- .../Address/BillingAddressDataProvider.php | 72 ---- .../Address/ShippingAddressesDataProvider.php | 76 ---- ...Address.php => ExtractDataFromAddress.php} | 32 +- .../Model/Cart/ExtractDataFromCart.php | 18 + .../Model/Cart/GetCustomerAddress.php | 65 ++++ .../Model/Cart/SetBillingAddressOnCart.php | 28 +- .../Model/Cart/SetShippingAddressOnCart.php | 29 +- .../Model/Resolver/BillingAddress.php | 24 +- .../Model/Resolver/CartAddresses.php | 48 --- .../Resolver/SetShippingAddressesOnCart.php | 13 +- .../Model/Resolver/ShippingAddresses.php | 26 +- .../Magento/QuoteGraphQl/etc/schema.graphqls | 31 +- .../Quote/AddSimpleProductToCartTest.php | 86 +++++ .../Magento/GraphQl/Quote/GetCartTest.php | 10 +- .../Quote/SetBillingAddressOnCartTest.php | 244 ++++++++---- .../Quote/SetShippingAddressOnCartTest.php | 357 ++++++++++-------- .../Quote/SetShippingMethodOnCartTest.php | 252 ------------- 19 files changed, 662 insertions(+), 854 deletions(-) delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Address/BillingAddressDataProvider.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Address/ShippingAddressesDataProvider.php rename app/code/Magento/QuoteGraphQl/Model/Cart/{Address/Mapper/Address.php => ExtractDataFromAddress.php} (64%) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/GetCustomerAddress.php delete mode 100644 app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductToCartTest.php delete mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php index 2303d2aa14f03..1b32866ed883c 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php @@ -75,7 +75,16 @@ public function execute(Quote $cart, array $cartItemData): void throw new GraphQlNoSuchEntityException(__('Could not find a product with SKU "%sku"', ['sku' => $sku])); } - $result = $cart->addProduct($product, $this->createBuyRequest($qty, $customizableOptions)); + try { + $result = $cart->addProduct($product, $this->createBuyRequest($qty, $customizableOptions)); + } catch (\Exception $e) { + throw new GraphQlInputException( + __( + 'Could not add the product with SKU %sku to the shopping cart: %message', + ['sku' => $sku, 'message' => $e->getMessage()] + ) + ); + } if (is_string($result)) { throw new GraphQlInputException(__($result)); diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php deleted file mode 100644 index fb742477ec99b..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/AddressDataProvider.php +++ /dev/null @@ -1,94 +0,0 @@ -dataObjectConverter = $dataObjectConverter; - } - - /** - * Collect and return information about shipping and billing addresses - * - * @param CartInterface $cart - * @return array - */ - public function getCartAddresses(CartInterface $cart): array - { - $addressData = []; - $shippingAddress = $cart->getShippingAddress(); - $billingAddress = $cart->getBillingAddress(); - - if ($shippingAddress) { - $shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], AddressInterface::class); - $shippingData['address_type'] = 'SHIPPING'; - $addressData[] = array_merge($shippingData, $this->extractAddressData($shippingAddress)); - } - - if ($billingAddress) { - $billingData = $this->dataObjectConverter->toFlatArray($billingAddress, [], AddressInterface::class); - $billingData['address_type'] = 'BILLING'; - $addressData[] = array_merge($billingData, $this->extractAddressData($billingAddress)); - } - - return $addressData; - } - - /** - * Extract the necessary address fields from address model - * - * @param QuoteAddress $address - * @return array - */ - private function extractAddressData(QuoteAddress $address): array - { - $addressData = [ - 'country' => [ - 'code' => $address->getCountryId(), - 'label' => $address->getCountry() - ], - 'region' => [ - 'code' => $address->getRegionCode(), - 'label' => $address->getRegion() - ], - 'street' => $address->getStreet(), - 'selected_shipping_method' => [ - 'code' => $address->getShippingMethod(), - 'label' => $address->getShippingDescription(), - 'free_shipping' => $address->getFreeShipping(), - ], - 'items_weight' => $address->getWeight(), - 'customer_notes' => $address->getCustomerNotes() - ]; - - return $addressData; - } -} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/BillingAddressDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/BillingAddressDataProvider.php deleted file mode 100644 index bcd781025a6d6..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/BillingAddressDataProvider.php +++ /dev/null @@ -1,72 +0,0 @@ -cartRepository = $cartRepository; - $this->addressMapper = $addressMapper; - $this->dataObjectConverter = $dataObjectConverter; - } - - /** - * Collect and return information about a billing addresses - * - * @param CartInterface $cart - * @return null|array - */ - public function getCartAddresses(CartInterface $cart): ?array - { - $cart = $this->cartRepository->get($cart->getId()); - $billingAddress = $cart->getBillingAddress(); - - if (!$billingAddress) { - return null; - } - $billingData = $this->dataObjectConverter->toFlatArray($billingAddress, [], AddressInterface::class); - $addressData = array_merge($billingData, $this->addressMapper->toNestedArray($billingAddress)); - - return $addressData; - } -} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/ShippingAddressesDataProvider.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/ShippingAddressesDataProvider.php deleted file mode 100644 index eb9d760809594..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/ShippingAddressesDataProvider.php +++ /dev/null @@ -1,76 +0,0 @@ -dataObjectConverter = $dataObjectConverter; - $this->cartRepository = $cartRepository; - $this->addressMapper = $addressMapper; - } - - /** - * Collect and return information about shipping addresses - * - * @param CartInterface $cart - * @return array - */ - public function getCartAddresses(CartInterface $cart): array - { - $cart = $this->cartRepository->get($cart->getId()); - $addressData = []; - $shippingAddresses = $cart->getAllShippingAddresses(); - - if ($shippingAddresses) { - foreach ($shippingAddresses as $shippingAddress) { - $shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], AddressInterface::class); - $addressData[] = array_merge($shippingData, $this->addressMapper->toNestedArray($shippingAddress)); - } - } - - return $addressData; - } -} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/Mapper/Address.php b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromAddress.php similarity index 64% rename from app/code/Magento/QuoteGraphQl/Model/Cart/Address/Mapper/Address.php rename to app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromAddress.php index 64ac407e2692a..b0e5070315d87 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/Mapper/Address.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromAddress.php @@ -5,26 +5,42 @@ */ declare(strict_types=1); -namespace Magento\QuoteGraphQl\Model\Cart\Address\Mapper; +namespace Magento\QuoteGraphQl\Model\Cart; +use Magento\Framework\Api\ExtensibleDataObjectConverter; +use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Model\Quote\Address as QuoteAddress; /** - * Class Address - * * Extract the necessary address fields from an Address model */ -class Address +class ExtractDataFromAddress { /** - * Converts Address model data to nested array + * @var ExtensibleDataObjectConverter + */ + private $dataObjectConverter; + + /** + * @param ExtensibleDataObjectConverter $dataObjectConverter + */ + public function __construct(ExtensibleDataObjectConverter $dataObjectConverter) + { + $this->dataObjectConverter = $dataObjectConverter; + } + + /** + * Converts Address model to flat array * * @param QuoteAddress $address * @return array */ - public function toNestedArray(QuoteAddress $address): array + public function execute(QuoteAddress $address): array { - $addressData = [ + $addressData = $this->dataObjectConverter->toFlatArray($address, [], AddressInterface::class); + $addressData['model'] = $address; + + $addressData = array_merge($addressData, [ 'country' => [ 'code' => $address->getCountryId(), 'label' => $address->getCountry() @@ -41,7 +57,7 @@ public function toNestedArray(QuoteAddress $address): array ], 'items_weight' => $address->getWeight(), 'customer_notes' => $address->getCustomerNotes() - ]; + ]); if (!$address->hasItems()) { return $addressData; diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromCart.php index 438f28980918d..62ffdbd4b194f 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromCart.php @@ -7,19 +7,36 @@ namespace Magento\QuoteGraphQl\Model\Cart; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Quote\Model\Quote; use Magento\Quote\Model\Quote\Item as QuoteItem; +use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; /** * Extract data from cart */ class ExtractDataFromCart { + /** + * @var QuoteIdToMaskedQuoteIdInterface + */ + private $quoteIdToMaskedQuoteId; + + /** + * @param QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedQuoteId + */ + public function __construct( + QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedQuoteId + ) { + $this->quoteIdToMaskedQuoteId = $quoteIdToMaskedQuoteId; + } + /** * Extract data from cart * * @param Quote $cart * @return array + * @throws NoSuchEntityException */ public function execute(Quote $cart): array { @@ -43,6 +60,7 @@ public function execute(Quote $cart): array $appliedCoupon = $cart->getCouponCode(); return [ + 'cart_id' => $this->quoteIdToMaskedQuoteId->execute((int)$cart->getId()), 'items' => $items, 'applied_coupon' => $appliedCoupon ? ['code' => $appliedCoupon] : null ]; diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/GetCustomerAddress.php b/app/code/Magento/QuoteGraphQl/Model/Cart/GetCustomerAddress.php new file mode 100644 index 0000000000000..d3de86702b96c --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/GetCustomerAddress.php @@ -0,0 +1,65 @@ +addressRepository = $addressRepository; + } + + /** + * Get customer address. Throws exception if customer is not owner of address + * + * @param int $addressId + * @param int $customerId + * @return AddressInterface + * @throws GraphQlAuthorizationException + * @throws GraphQlNoSuchEntityException + * @throws LocalizedException + */ + public function execute(int $addressId, int $customerId): AddressInterface + { + try { + $customerAddress = $this->addressRepository->getById($addressId); + } catch (NoSuchEntityException $e) { + throw new GraphQlNoSuchEntityException( + __('Could not find a address with ID "%address_id"', ['address_id' => $addressId]) + ); + } + + if ((int)$customerAddress->getCustomerId() !== $customerId) { + throw new GraphQlAuthorizationException( + __( + 'The current user cannot use address with ID "%address_id"', + ['address_id' => $addressId] + ) + ); + } + return $customerAddress; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php index 97b1ed09decc4..5d3125ae13ef8 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php @@ -7,7 +7,6 @@ namespace Magento\QuoteGraphQl\Model\Cart; -use Magento\Customer\Api\Data\AddressInterface; use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; @@ -26,11 +25,6 @@ class SetBillingAddressOnCart */ private $billingAddressManagement; - /** - * @var AddressRepositoryInterface - */ - private $addressRepository; - /** * @var Address */ @@ -41,26 +35,40 @@ class SetBillingAddressOnCart */ private $checkCustomerAccount; + /** + * @var GetCustomerAddress + */ + private $getCustomerAddress; + /** * @param BillingAddressManagementInterface $billingAddressManagement * @param AddressRepositoryInterface $addressRepository * @param Address $addressModel * @param CheckCustomerAccount $checkCustomerAccount + * @param GetCustomerAddress $getCustomerAddress */ public function __construct( BillingAddressManagementInterface $billingAddressManagement, AddressRepositoryInterface $addressRepository, Address $addressModel, - CheckCustomerAccount $checkCustomerAccount + CheckCustomerAccount $checkCustomerAccount, + GetCustomerAddress $getCustomerAddress ) { $this->billingAddressManagement = $billingAddressManagement; $this->addressRepository = $addressRepository; $this->addressModel = $addressModel; $this->checkCustomerAccount = $checkCustomerAccount; + $this->getCustomerAddress = $getCustomerAddress; } /** - * @inheritdoc + * Set billing address for a specified shopping cart + * + * @param ContextInterface $context + * @param CartInterface $cart + * @param array $billingAddress + * @return void + * @throws GraphQlInputException */ public function execute(ContextInterface $context, CartInterface $cart, array $billingAddress): void { @@ -88,9 +96,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $b $billingAddress = $this->addressModel->addData($addressInput); } else { $this->checkCustomerAccount->execute($context->getUserId(), $context->getUserType()); - - /** @var AddressInterface $customerAddress */ - $customerAddress = $this->addressRepository->getById($customerAddressId); + $customerAddress = $this->getCustomerAddress->execute((int)$customerAddressId, (int)$context->getUserId()); $billingAddress = $this->addressModel->importCustomerAddressData($customerAddress); } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php index b9fd5c7807d2f..e6b18fc88a27a 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressOnCart.php @@ -7,14 +7,12 @@ namespace Magento\QuoteGraphQl\Model\Cart; -use Magento\Customer\Api\Data\AddressInterface; use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ShippingAddressManagementInterface; -use Magento\Customer\Api\AddressRepositoryInterface; /** * Set single shipping address for a specified shopping cart @@ -26,11 +24,6 @@ class SetShippingAddressOnCart implements SetShippingAddressesOnCartInterface */ private $shippingAddressManagement; - /** - * @var AddressRepositoryInterface - */ - private $addressRepository; - /** * @var Address */ @@ -41,26 +34,36 @@ class SetShippingAddressOnCart implements SetShippingAddressesOnCartInterface */ private $checkCustomerAccount; + /** + * @var GetCustomerAddress + */ + private $getCustomerAddress; + /** * @param ShippingAddressManagementInterface $shippingAddressManagement - * @param AddressRepositoryInterface $addressRepository * @param Address $addressModel * @param CheckCustomerAccount $checkCustomerAccount + * @param GetCustomerAddress $getCustomerAddress */ public function __construct( ShippingAddressManagementInterface $shippingAddressManagement, - AddressRepositoryInterface $addressRepository, Address $addressModel, - CheckCustomerAccount $checkCustomerAccount + CheckCustomerAccount $checkCustomerAccount, + GetCustomerAddress $getCustomerAddress ) { $this->shippingAddressManagement = $shippingAddressManagement; - $this->addressRepository = $addressRepository; $this->addressModel = $addressModel; $this->checkCustomerAccount = $checkCustomerAccount; + $this->getCustomerAddress = $getCustomerAddress; } /** * @inheritdoc + * + * @param ContextInterface $context + * @param CartInterface $cart + * @param array $shippingAddresses + * @throws GraphQlInputException */ public function execute(ContextInterface $context, CartInterface $cart, array $shippingAddresses): void { @@ -87,9 +90,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s $shippingAddress = $this->addressModel->addData($addressInput); } else { $this->checkCustomerAccount->execute($context->getUserId(), $context->getUserType()); - - /** @var AddressInterface $customerAddress */ - $customerAddress = $this->addressRepository->getById($customerAddressId); + $customerAddress = $this->getCustomerAddress->execute((int)$customerAddressId, (int)$context->getUserId()); $shippingAddress = $this->addressModel->importCustomerAddressData($customerAddress); } diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/BillingAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/BillingAddress.php index 7de5a4ac05c24..a03533ecefffa 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/BillingAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/BillingAddress.php @@ -11,7 +11,7 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\QuoteGraphQl\Model\Cart\Address\BillingAddressDataProvider; +use Magento\QuoteGraphQl\Model\Cart\ExtractDataFromAddress; /** * @inheritdoc @@ -19,17 +19,16 @@ class BillingAddress implements ResolverInterface { /** - * @var BillingAddressDataProvider + * @var ExtractDataFromAddress */ - private $addressDataProvider; + private $extractDataFromAddress; /** - * @param BillingAddressDataProvider $addressDataProvider + * @param ExtractDataFromAddress $extractDataFromAddress */ - public function __construct( - BillingAddressDataProvider $addressDataProvider - ) { - $this->addressDataProvider = $addressDataProvider; + public function __construct(ExtractDataFromAddress $extractDataFromAddress) + { + $this->extractDataFromAddress = $extractDataFromAddress; } /** @@ -40,9 +39,14 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (!isset($value['model'])) { throw new LocalizedException(__('"model" value should be specified')); } - $cart = $value['model']; - return $this->addressDataProvider->getCartAddresses($cart); + $billingAddress = $cart->getBillingAddress(); + if (null === $billingAddress) { + return null; + } + + $addressData = $this->extractDataFromAddress->execute($billingAddress); + return $addressData; } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php deleted file mode 100644 index 69544672bf12e..0000000000000 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartAddresses.php +++ /dev/null @@ -1,48 +0,0 @@ -addressDataProvider = $addressDataProvider; - } - - /** - * @inheritdoc - */ - public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) - { - if (!isset($value['model'])) { - throw new LocalizedException(__('"model" value should be specified')); - } - - $cart = $value['model']; - - return $this->addressDataProvider->getCartAddresses($cart); - } -} diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php index b024e7b77af40..ec50bd6ab6ea4 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetShippingAddressesOnCart.php @@ -12,7 +12,6 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface; use Magento\Quote\Model\ShippingAddressManagementInterface; use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; use Magento\QuoteGraphQl\Model\Cart\SetShippingAddressesOnCartInterface; @@ -24,11 +23,6 @@ */ class SetShippingAddressesOnCart implements ResolverInterface { - /** - * @var MaskedQuoteIdToQuoteIdInterface - */ - private $maskedQuoteIdToQuoteId; - /** * @var ShippingAddressManagementInterface */ @@ -50,20 +44,17 @@ class SetShippingAddressesOnCart implements ResolverInterface private $setShippingAddressesOnCart; /** - * @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId * @param ShippingAddressManagementInterface $shippingAddressManagement * @param GetCartForUser $getCartForUser * @param ArrayManager $arrayManager * @param SetShippingAddressesOnCartInterface $setShippingAddressesOnCart */ public function __construct( - MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId, ShippingAddressManagementInterface $shippingAddressManagement, GetCartForUser $getCartForUser, ArrayManager $arrayManager, SetShippingAddressesOnCartInterface $setShippingAddressesOnCart ) { - $this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId; $this->shippingAddressManagement = $shippingAddressManagement; $this->getCartForUser = $getCartForUser; $this->arrayManager = $arrayManager; @@ -76,16 +67,16 @@ public function __construct( public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { $shippingAddresses = $this->arrayManager->get('input/shipping_addresses', $args); - $maskedCartId = $this->arrayManager->get('input/cart_id', $args); + $maskedCartId = (string) $this->arrayManager->get('input/cart_id', $args); if (!$maskedCartId) { throw new GraphQlInputException(__('Required parameter "cart_id" is missing')); } + if (!$shippingAddresses) { throw new GraphQlInputException(__('Required parameter "shipping_addresses" is missing')); } - $maskedCartId = $args['input']['cart_id']; $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId()); $this->setShippingAddressesOnCart->execute($context, $cart, $shippingAddresses); diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddresses.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddresses.php index caa0eee22d702..3a55ef9ae25a8 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddresses.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddresses.php @@ -11,7 +11,7 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\QuoteGraphQl\Model\Cart\Address\ShippingAddressesDataProvider; +use Magento\QuoteGraphQl\Model\Cart\ExtractDataFromAddress; /** * @inheritdoc @@ -19,17 +19,16 @@ class ShippingAddresses implements ResolverInterface { /** - * @var ShippingAddressesDataProvider + * @var ExtractDataFromAddress */ - private $addressDataProvider; + private $extractDataFromAddress; /** - * @param ShippingAddressesDataProvider $addressDataProvider + * @param ExtractDataFromAddress $extractDataFromAddress */ - public function __construct( - ShippingAddressesDataProvider $addressDataProvider - ) { - $this->addressDataProvider = $addressDataProvider; + public function __construct(ExtractDataFromAddress $extractDataFromAddress) + { + $this->extractDataFromAddress = $extractDataFromAddress; } /** @@ -40,9 +39,16 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (!isset($value['model'])) { throw new LocalizedException(__('"model" value should be specified')); } - $cart = $value['model']; - return $this->addressDataProvider->getCartAddresses($cart); + $addressesData = []; + $shippingAddresses = $cart->getAllShippingAddresses(); + + if (count($shippingAddresses)) { + foreach ($shippingAddresses as $shippingAddress) { + $addressesData[] = $this->extractDataFromAddress->execute($shippingAddress); + } + } + return $addressesData; } } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 3448d640618d4..17dd1141a0368 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Query { - Cart(cart_id: String!): Cart @resolver (class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart") @doc(description:"Returns information about shopping cart") + cart(cart_id: String!): Cart @resolver (class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart") @doc(description:"Returns information about shopping cart") } type Mutation { @@ -64,8 +64,8 @@ input SetShippingMethodsOnCartInput { input ShippingMethodForAddressInput { cart_address_id: Int! - shipping_carrier_code: String! - shipping_method_code: String! + carrier_code: String! + method_code: String! } type SetBillingAddressOnCartOutput { @@ -116,8 +116,6 @@ type CartAddress { country: CartAddressCountry telephone: String address_type: AdressTypeEnum - selected_shipping_method: CheckoutShippingMethod - available_shipping_methods: [CheckoutShippingMethod] items_weight: Float customer_notes: String cart_items: [CartItemQuantity] @@ -138,12 +136,20 @@ type CartAddressCountry { label: String } -type CheckoutShippingMethod { - code: String - label: String - free_shipping: Boolean! +type SelectedShippingMethod { + amount: Float! +} + +type AvailableShippingMethod { + carrier_code: String! + carrier_title: String! + method_code: String! + method_title: String! error_message: String - # TODO: Add more complex structure for shipping rates + amount: Float! + base_amount: Float! + price_excl_tax: Float! + price_incl_tax: Float! } enum AdressTypeEnum { @@ -219,8 +225,3 @@ type CartItemSelectedOptionValuePrice { units: String! type: PriceTypeEnum! } - -input CartItemDetailsInput { - sku: String! - qty: Float! -} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductToCartTest.php new file mode 100644 index 0000000000000..4cbc614e1b8dc --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductToCartTest.php @@ -0,0 +1,86 @@ +quoteResource = $objectManager->get(QuoteResource::class); + $this->quote = $objectManager->create(Quote::class); + $this->quoteIdToMaskedId = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products.php + * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php + * @expectedException \Exception + * @expectedExceptionMessage The requested qty is not available + */ + public function testAddProductIfQuantityIsNotAvailable() + { + $sku = 'simple'; + $qty = 200; + + $this->quoteResource->load( + $this->quote, + 'test_order_1', + 'reserved_order_id' + ); + $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + + $query = <<graphQlQuery($query); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCartTest.php index f0038351bcdcf..44cd2ef526bd5 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCartTest.php @@ -68,9 +68,9 @@ public function testGetOwnCartForRegisteredCustomer() $response = $this->sendRequestWithToken($query); - self::assertArrayHasKey('Cart', $response); - self::assertNotEmpty($response['Cart']['items']); - self::assertNotEmpty($response['Cart']['shipping_addresses']); + self::assertArrayHasKey('cart', $response); + self::assertNotEmpty($response['cart']['items']); + self::assertNotEmpty($response['cart']['shipping_addresses']); } /** @@ -110,7 +110,7 @@ public function testGetCartForGuest() $response = $this->graphQlQuery($query); - self::assertArrayHasKey('Cart', $response); + self::assertArrayHasKey('cart', $response); } public function testGetNonExistentCart() @@ -134,7 +134,7 @@ private function prepareGetCartQuery( ) : string { return <<quoteResource = $objectManager->create(QuoteResource::class); - $this->quote = $objectManager->create(Quote::class); - $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class); + $this->quoteResource = $objectManager->get(QuoteResource::class); + $this->quoteFactory = $objectManager->get(QuoteFactory::class); + $this->quoteIdToMaskedId = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class); + $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); } /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php */ - public function testSetNewGuestBillingAddressOnCart() + public function testSetNewBillingAddressByGuest() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); $query = <<quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); $query = <<quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); $query = <<graphQlQuery($query); } @@ -214,23 +200,9 @@ public function testSetSavedBillingAddressOnCartByGuest() * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php * @magentoApiDataFixture Magento/Customer/_files/customer.php */ - public function testSetNewRegisteredCustomerBillingAddressOnCart() + public function testSetNewBillingAddressByRegisteredCustomer() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $this->quote->setCustomerId(1); - $this->quoteResource->save($this->quote); - - $headerMap = $this->getHeaderMap(); + $maskedQuoteId = $this->assignQuoteToCustomer(); $query = <<graphQlQuery($query, [], '', $headerMap); + $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); self::assertArrayHasKey('cart', $response['setBillingAddressOnCart']); $cartResponse = $response['setBillingAddressOnCart']['cart']; @@ -281,23 +253,9 @@ public function testSetNewRegisteredCustomerBillingAddressOnCart() * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php */ - public function testSetSavedRegisteredCustomerBillingAddressOnCart() + public function testSetBillingAddressFromAddressBookByRegisteredCustomer() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $this->quote->setCustomerId(1); - $this->quoteResource->save($this->quote); - - $headerMap = $this->getHeaderMap(); + $maskedQuoteId = $this->assignQuoteToCustomer(); $query = <<graphQlQuery($query, [], '', $headerMap); + $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); self::assertArrayHasKey('cart', $response['setBillingAddressOnCart']); $cartResponse = $response['setBillingAddressOnCart']['cart']; @@ -332,6 +290,115 @@ public function testSetSavedRegisteredCustomerBillingAddressOnCart() $this->assertSavedBillingAddressFields($billingAddressResponse); } + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @expectedException \Exception + * @expectedExceptionMessage Could not find a address with ID "100" + */ + public function testSetNotExistedBillingAddressFromAddressBook() + { + $maskedQuoteId = $this->assignQuoteToCustomer(); + + $query = <<graphQlQuery($query, [], '', $this->getHeaderMap()); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php + */ + public function testSetNewBillingAddressAndFromAddressBookAtSameTime() + { + $maskedQuoteId = $this->assignQuoteToCustomer(); + + $query = <<graphQlQuery($query, [], '', $this->getHeaderMap()); + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/three_customers.php + * @magentoApiDataFixture Magento/Customer/_files/customer_address.php + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @expectedException \Exception + * @expectedExceptionMessage The current user cannot use address with ID "1" + */ + public function testSetBillingAddressIfCustomerIsNotOwnerOfAddress() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); + + $query = <<graphQlQuery($query, [], '', $this->getHeaderMap('customer2@search.example.com')); + } + /** * Verify the all the whitelisted fields for a New Address Object * @@ -374,19 +441,48 @@ private function assertSavedBillingAddressFields(array $billingAddressResponse): /** * @param string $username + * @param string $password * @return array + * @throws \Magento\Framework\Exception\AuthenticationException */ - private function getHeaderMap(string $username = 'customer@example.com'): array + private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array { - $password = 'password'; - /** @var CustomerTokenServiceInterface $customerTokenService */ - $customerTokenService = ObjectManager::getInstance() - ->get(CustomerTokenServiceInterface::class); - $customerToken = $customerTokenService->createCustomerAccessToken($username, $password); + $customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password); $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; return $headerMap; } + /** + * @param string $reversedQuoteId + * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + private function getMaskedQuoteIdByReversedQuoteId(string $reversedQuoteId): string + { + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, $reversedQuoteId, 'reserved_order_id'); + + return $this->quoteIdToMaskedId->execute((int)$quote->getId()); + } + + /** + * @param string $reversedQuoteId + * @param int $customerId + * @return string + * @throws \Magento\Framework\Exception\AlreadyExistsException + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + private function assignQuoteToCustomer( + string $reversedQuoteId = 'test_order_with_simple_product_without_address', + int $customerId = 1 + ): string { + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, $reversedQuoteId, 'reserved_order_id'); + $quote->setCustomerId($customerId); + $this->quoteResource->save($quote); + return $this->quoteIdToMaskedId->execute((int)$quote->getId()); + } + public function tearDown() { /** @var \Magento\Config\Model\ResourceModel\Config $config */ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php index d60876e7c0be4..11fd37b94d535 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -10,7 +10,7 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\Multishipping\Helper\Data; -use Magento\Quote\Model\Quote; +use Magento\Quote\Model\QuoteFactory; use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface; use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; use Magento\TestFramework\Helper\Bootstrap; @@ -28,34 +28,35 @@ class SetShippingAddressOnCartTest extends GraphQlAbstract private $quoteResource; /** - * @var Quote + * @var QuoteFactory */ - private $quote; + private $quoteFactory; /** * @var QuoteIdToMaskedQuoteIdInterface */ private $quoteIdToMaskedId; + /** + * @var CustomerTokenServiceInterface + */ + private $customerTokenService; + protected function setUp() { $objectManager = Bootstrap::getObjectManager(); - $this->quoteResource = $objectManager->create(QuoteResource::class); - $this->quote = $objectManager->create(Quote::class); - $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class); + $this->quoteResource = $objectManager->get(QuoteResource::class); + $this->quoteFactory = $objectManager->get(QuoteFactory::class); + $this->quoteIdToMaskedId = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class); + $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); } /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php */ - public function testSetNewGuestShippingAddressOnCart() + public function testSetNewShippingAddressByGuest() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); $query = <<quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); $query = <<graphQlQuery($query); } /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php */ - public function testSetMultipleShippingAddressesOnCartByGuest() + public function testSetNewShippingAddressByRegisteredCustomer() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $maskedQuoteId = $this->assignQuoteToCustomer(); $query = <<get(\Magento\Config\Model\ResourceModel\Config::class); - $config->saveConfig( - Data::XML_PATH_CHECKOUT_MULTIPLE_AVAILABLE, - null, - ScopeConfigInterface::SCOPE_TYPE_DEFAULT, - 0 - ); - /** @var \Magento\Framework\App\Config\ReinitableConfigInterface $config */ - $config = ObjectManager::getInstance()->get(\Magento\Framework\App\Config\ReinitableConfigInterface::class); - $config->reinit(); + $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); - self::expectExceptionMessage('You cannot specify multiple shipping addresses.'); - $this->graphQlQuery($query); + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('shipping_addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['shipping_addresses']); + $this->assertNewShippingAddressFields($shippingAddressResponse); } /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php */ - public function testSetSavedAndNewShippingAddressOnCartAtTheSameTime() + public function testSetShippingAddressFromAddressBookByRegisteredCustomer() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $maskedQuoteId = $this->assignQuoteToCustomer(); $query = <<graphQlQuery($query); + $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('shipping_addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['shipping_addresses']); + $this->assertSavedShippingAddressFields($shippingAddressResponse); } /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @expectedException \Exception + * @expectedExceptionMessage Could not find a address with ID "100" */ - public function testSetShippingAddressOnCartWithNoAddresses() + public function testSetNotExistedShippingAddressFromAddressBook() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); + $maskedQuoteId = $this->assignQuoteToCustomer(); + + $query = <<graphQlQuery($query, [], '', $this->getHeaderMap()); + } + + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @expectedException \Exception + * @expectedExceptionMessage The shipping address must contain either "customer_address_id" or "address". + */ + public function testSetShippingAddressWithoutAddresses() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); $query = <<graphQlQuery($query); } /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php */ - public function testSetNewRegisteredCustomerShippingAddressOnCart() + public function testSetNewShippingAddressAndFromAddressBookAtSameTime() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' + $maskedQuoteId = $this->assignQuoteToCustomer(); + + $query = <<quote->setCustomerId(1); - $this->quoteResource->save($this->quote); + $this->graphQlQuery($query, [], '', $this->getHeaderMap()); + } - $headerMap = $this->getHeaderMap(); + /** + * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php + * @expectedException \Exception + * @expectedExceptionMessage You cannot specify multiple shipping addresses. + */ + public function testSetMultipleNewShippingAddresses() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); $query = <<graphQlQuery($query, [], '', $headerMap); + /** @var \Magento\Config\Model\ResourceModel\Config $config */ + $config = ObjectManager::getInstance()->get(\Magento\Config\Model\ResourceModel\Config::class); + $config->saveConfig( + Data::XML_PATH_CHECKOUT_MULTIPLE_AVAILABLE, + null, + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + /** @var \Magento\Framework\App\Config\ReinitableConfigInterface $config */ + $config = ObjectManager::getInstance()->get(\Magento\Framework\App\Config\ReinitableConfigInterface::class); + $config->reinit(); - self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); - $cartResponse = $response['setShippingAddressesOnCart']['cart']; - self::assertArrayHasKey('shipping_addresses', $cartResponse); - $shippingAddressResponse = current($cartResponse['shipping_addresses']); - $this->assertNewShippingAddressFields($shippingAddressResponse); + $this->graphQlQuery($query); } /** + * @magentoApiDataFixture Magento/Customer/_files/three_customers.php + * @magentoApiDataFixture Magento/Customer/_files/customer_address.php * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php - * @magentoApiDataFixture Magento/Customer/_files/customer.php - * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php + * @expectedException \Exception + * @expectedExceptionMessage The current user cannot use address with ID "1" */ - public function testSetSavedRegisteredCustomerShippingAddressOnCart() + public function testSetShippingAddressIfCustomerIsNotOwnerOfAddress() { - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - $this->quoteResource->load( - $this->quote, - 'test_order_with_simple_product_without_address', - 'reserved_order_id' - ); - $this->quote->setCustomerId(1); - $this->quoteResource->save($this->quote); - - $headerMap = $this->getHeaderMap(); + $maskedQuoteId = $this->getMaskedQuoteIdByReversedQuoteId('test_order_with_simple_product_without_address'); $query = <<graphQlQuery($query, [], '', $headerMap); - self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); - $cartResponse = $response['setShippingAddressesOnCart']['cart']; - self::assertArrayHasKey('shipping_addresses', $cartResponse); - $shippingAddressResponse = current($cartResponse['shipping_addresses']); - $this->assertSavedShippingAddressFields($shippingAddressResponse); + $this->graphQlQuery($query, [], '', $this->getHeaderMap('customer2@search.example.com')); } /** @@ -468,19 +490,48 @@ private function assertSavedShippingAddressFields(array $shippingAddressResponse /** * @param string $username + * @param string $password * @return array + * @throws \Magento\Framework\Exception\AuthenticationException */ - private function getHeaderMap(string $username = 'customer@example.com'): array + private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array { - $password = 'password'; - /** @var CustomerTokenServiceInterface $customerTokenService */ - $customerTokenService = ObjectManager::getInstance() - ->get(CustomerTokenServiceInterface::class); - $customerToken = $customerTokenService->createCustomerAccessToken($username, $password); + $customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password); $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; return $headerMap; } + /** + * @param string $reversedQuoteId + * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + private function getMaskedQuoteIdByReversedQuoteId(string $reversedQuoteId): string + { + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, $reversedQuoteId, 'reserved_order_id'); + + return $this->quoteIdToMaskedId->execute((int)$quote->getId()); + } + + /** + * @param string $reversedQuoteId + * @param int $customerId + * @return string + * @throws \Magento\Framework\Exception\AlreadyExistsException + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + private function assignQuoteToCustomer( + string $reversedQuoteId = 'test_order_with_simple_product_without_address', + int $customerId = 1 + ): string { + $quote = $this->quoteFactory->create(); + $this->quoteResource->load($quote, $reversedQuoteId, 'reserved_order_id'); + $quote->setCustomerId($customerId); + $this->quoteResource->save($quote); + return $this->quoteIdToMaskedId->execute((int)$quote->getId()); + } + public function tearDown() { /** @var \Magento\Config\Model\ResourceModel\Config $config */ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php deleted file mode 100644 index 1c6679ee30f29..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingMethodOnCartTest.php +++ /dev/null @@ -1,252 +0,0 @@ -quoteResource = $objectManager->create(QuoteResource::class); - $this->quote = $objectManager->create(Quote::class); - $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class); - $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); - } - - /** - * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php - */ - public function testSetShippingMethodOnCart() - { - $shippingCarrierCode = 'flatrate'; - $shippingMethodCode = 'flatrate'; - $this->quoteResource->load( - $this->quote, - 'test_order_1', - 'reserved_order_id' - ); - $shippingAddress = $this->quote->getShippingAddress(); - $shippingAddressId = $shippingAddress->getId(); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - - $query = $this->prepareMutationQuery( - $maskedQuoteId, - $shippingMethodCode, - $shippingCarrierCode, - $shippingAddressId - ); - - $response = $this->sendRequestWithToken($query); - - self::assertArrayHasKey('setShippingMethodsOnCart', $response); - self::assertArrayHasKey('cart', $response['setShippingMethodsOnCart']); - self::assertEquals($maskedQuoteId, $response['setShippingMethodsOnCart']['cart']['cart_id']); - $addressesInformation = $response['setShippingMethodsOnCart']['cart']['shipping_addresses']; - self::assertCount(1, $addressesInformation); - self::assertEquals( - $addressesInformation[0]['selected_shipping_method']['code'], - $shippingCarrierCode . '_' . $shippingMethodCode - ); - } - - /** - * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php - */ - public function testSetShippingMethodWithWrongCartId() - { - $shippingCarrierCode = 'flatrate'; - $shippingMethodCode = 'flatrate'; - $shippingAddressId = '1'; - $maskedQuoteId = 'invalid'; - - $query = $this->prepareMutationQuery( - $maskedQuoteId, - $shippingMethodCode, - $shippingCarrierCode, - $shippingAddressId - ); - - self::expectExceptionMessage("Could not find a cart with ID \"$maskedQuoteId\""); - $this->sendRequestWithToken($query); - } - - /** - * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php - */ - public function testSetNonExistingShippingMethod() - { - $shippingCarrierCode = 'non'; - $shippingMethodCode = 'existing'; - $this->quoteResource->load( - $this->quote, - 'test_order_1', - 'reserved_order_id' - ); - $shippingAddress = $this->quote->getShippingAddress(); - $shippingAddressId = $shippingAddress->getId(); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - - $query = $this->prepareMutationQuery( - $maskedQuoteId, - $shippingMethodCode, - $shippingCarrierCode, - $shippingAddressId - ); - - self::expectExceptionMessage("Carrier with such method not found: $shippingCarrierCode, $shippingMethodCode"); - $this->sendRequestWithToken($query); - } - - /** - * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php - */ - public function testSetShippingMethodWithNonExistingAddress() - { - $shippingCarrierCode = 'flatrate'; - $shippingMethodCode = 'flatrate'; - $this->quoteResource->load( - $this->quote, - 'test_order_1', - 'reserved_order_id' - ); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - $shippingAddressId = '-20'; - - $query = $this->prepareMutationQuery( - $maskedQuoteId, - $shippingMethodCode, - $shippingCarrierCode, - $shippingAddressId - ); - - self::expectExceptionMessage('The shipping address is missing. Set the address and try again.'); - $this->sendRequestWithToken($query); - } - - /** - * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php - */ - public function testSetShippingMethodByGuestToCustomerCart() - { - $shippingCarrierCode = 'flatrate'; - $shippingMethodCode = 'flatrate'; - $this->quoteResource->load( - $this->quote, - 'test_order_1', - 'reserved_order_id' - ); - $shippingAddress = $this->quote->getShippingAddress(); - $shippingAddressId = $shippingAddress->getId(); - $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId()); - - $query = $this->prepareMutationQuery( - $maskedQuoteId, - $shippingMethodCode, - $shippingCarrierCode, - $shippingAddressId - ); - - self::expectExceptionMessage( - "The current user cannot perform operations on cart \"$maskedQuoteId\"" - ); - - $this->graphQlQuery($query); - } - - /** - * Generates query for setting the specified shipping method on cart - * - * @param string $maskedQuoteId - * @param string $shippingMethodCode - * @param string $shippingCarrierCode - * @param string $shippingAddressId - * @return string - */ - private function prepareMutationQuery( - string $maskedQuoteId, - string $shippingMethodCode, - string $shippingCarrierCode, - string $shippingAddressId - ) : string { - return <<customerTokenService->createCustomerAccessToken('customer@example.com', 'password'); - $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; - - return $this->graphQlQuery($query, [], '', $headerMap); - } -} From 6478f84571442e0509de48b8599b52a6efcb3fa7 Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Fri, 15 Feb 2019 18:49:26 -0600 Subject: [PATCH 34/75] ENGCOM-4289: GraphQL 2.3.1 release fixes --- app/code/Magento/QuoteGraphQl/etc/schema.graphqls | 5 +++++ .../Magento/GraphQl/Quote/SetBillingAddressOnCartTest.php | 4 ---- .../Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php | 4 ---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 17dd1141a0368..a76f7d59c3f77 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -225,3 +225,8 @@ type CartItemSelectedOptionValuePrice { units: String! type: PriceTypeEnum! } + +input CartItemDetailsInput { + sku: String! + qty: Float! +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetBillingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetBillingAddressOnCartTest.php index 74f53d4241496..bfe57109d107d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetBillingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetBillingAddressOnCartTest.php @@ -443,7 +443,6 @@ private function assertSavedBillingAddressFields(array $billingAddressResponse): * @param string $username * @param string $password * @return array - * @throws \Magento\Framework\Exception\AuthenticationException */ private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array { @@ -455,7 +454,6 @@ private function getHeaderMap(string $username = 'customer@example.com', string /** * @param string $reversedQuoteId * @return string - * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function getMaskedQuoteIdByReversedQuoteId(string $reversedQuoteId): string { @@ -469,8 +467,6 @@ private function getMaskedQuoteIdByReversedQuoteId(string $reversedQuoteId): str * @param string $reversedQuoteId * @param int $customerId * @return string - * @throws \Magento\Framework\Exception\AlreadyExistsException - * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function assignQuoteToCustomer( string $reversedQuoteId = 'test_order_with_simple_product_without_address', diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php index 11fd37b94d535..c3685c88ae487 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/SetShippingAddressOnCartTest.php @@ -492,7 +492,6 @@ private function assertSavedShippingAddressFields(array $shippingAddressResponse * @param string $username * @param string $password * @return array - * @throws \Magento\Framework\Exception\AuthenticationException */ private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array { @@ -504,7 +503,6 @@ private function getHeaderMap(string $username = 'customer@example.com', string /** * @param string $reversedQuoteId * @return string - * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function getMaskedQuoteIdByReversedQuoteId(string $reversedQuoteId): string { @@ -518,8 +516,6 @@ private function getMaskedQuoteIdByReversedQuoteId(string $reversedQuoteId): str * @param string $reversedQuoteId * @param int $customerId * @return string - * @throws \Magento\Framework\Exception\AlreadyExistsException - * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function assignQuoteToCustomer( string $reversedQuoteId = 'test_order_with_simple_product_without_address', From 9d4f13cc80d711fd9ac279f18cc6aa5b3576b178 Mon Sep 17 00:00:00 2001 From: Pratik Oza Date: Mon, 18 Feb 2019 18:27:14 +0530 Subject: [PATCH 35/75] Fixed pagination drop-down size --- .../backend/web/css/source/actions/_actions-dropdown.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less index cd089232412dc..d1fe33c4fe77d 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-dropdown.less @@ -234,6 +234,7 @@ border: 0; display: inline; margin: 0; + width: 6rem; body._keyfocus &:focus { box-shadow: none; From b179e544a9c05eb0d5347028d4095755d019e304 Mon Sep 17 00:00:00 2001 From: Milind Singh Date: Tue, 19 Feb 2019 15:53:22 +0530 Subject: [PATCH 36/75] Issue Fixed #21322 : Declarative schema: Omitting indexType throws exception --- .../Framework/Setup/Declaration/Schema/Dto/Factories/Index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php index 715f98c4177c0..211d3885297ba 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Index.php @@ -19,7 +19,7 @@ class Index implements FactoryInterface /** * Default index type. */ - const DEFAULT_INDEX_TYPE = "BTREE"; + const DEFAULT_INDEX_TYPE = "btree"; /** * @var ObjectManagerInterface From 5c67e67a796861e37d6abe07dc42ca1ea8763202 Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Tue, 19 Feb 2019 13:46:50 +0200 Subject: [PATCH 37/75] Fix static test. --- .../module/checkout/_order-summary.less | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less index ae21a3877c350..beb8fc8d4c3b9 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less @@ -233,21 +233,21 @@ // _____________________________________________ @media only screen and (max-width: @screen__m) { - .opc-block-summary { - .product-item { - .product-item-inner { - display: block; - } - - .product-item-name-block { - display: block; - text-align: left; - } - - .subtotal { - display: block; - text-align: left; - } + .opc-block-summary { + .product-item { + .product-item-inner { + display: block; + } + + .product-item-name-block { + display: block; + text-align: left; + } + + .subtotal { + display: block; + text-align: left; + } + } } - } -} \ No newline at end of file +} From 7b9e807c8966308d173216d62f7ab40b11725353 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Fri, 25 Jan 2019 13:22:21 +0000 Subject: [PATCH 38/75] Changed references to "Store" to "Scope" in framework components. --- .../Sales/Model/Order/Email/SenderBuilder.php | 2 +- .../Model/Order/Email/SenderBuilderTest.php | 8 +++--- .../Mail/Template/TransportBuilder.php | 26 ++++++++++++++----- .../Unit/Template/TransportBuilderTest.php | 8 +++--- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index a7d749ec04c7d..ed9e38822245f 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -106,7 +106,7 @@ protected function configureEmailTemplate() $this->transportBuilder->setTemplateIdentifier($this->templateContainer->getTemplateId()); $this->transportBuilder->setTemplateOptions($this->templateContainer->getTemplateOptions()); $this->transportBuilder->setTemplateVars($this->templateContainer->getTemplateVars()); - $this->transportBuilder->setFromByStore( + $this->transportBuilder->setFromByScope( $this->identityContainer->getEmailIdentity(), $this->identityContainer->getStore()->getId() ); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php index 759d60d9e6613..24cd54e3a46b3 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php @@ -76,7 +76,7 @@ protected function setUp() 'setTemplateIdentifier', 'setTemplateOptions', 'setTemplateVars', - 'setFromByStore', + 'setFromByScope', ] ); @@ -103,7 +103,7 @@ protected function setUp() ->method('getEmailIdentity') ->will($this->returnValue($emailIdentity)); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($this->equalTo($emailIdentity), 1); $this->identityContainerMock->expects($this->once()) @@ -146,7 +146,7 @@ public function testSend() ->method('getId') ->willReturn(1); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($identity, 1); $this->transportBuilder->expects($this->once()) ->method('addTo') @@ -176,7 +176,7 @@ public function testSendCopyTo() ->method('addTo') ->with($this->equalTo('example@mail.com')); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($identity, 1); $this->identityContainerMock->expects($this->once()) ->method('getStore') diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index a7bb96122a84d..0d69b3d96cebf 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -177,29 +177,43 @@ public function setReplyTo($email, $name = null) /** * Set mail from address * - * @deprecated This function sets the from address for the first store only. - * new function setFromByStore introduced to allow setting of from address - * based on store. - * @see setFromByStore() + * @deprecated This function sets the from address but does not provide + * a way of setting the correct from addresses based on the scope. + * @see setFromByScope() * * @param string|array $from * @return $this */ public function setFrom($from) { - return $this->setFromByStore($from, null); + return $this->setFromByScope($from, null); } /** * Set mail from address by store * + * @deprecated Use setFromByScope + * @see setFromByScope() + * * @param string|array $from * @param string|int $store * @return $this */ public function setFromByStore($from, $store = null) { - $result = $this->_senderResolver->resolve($from, $store); + return $this->setFromByScope($from, $store); + } + + /** + * Set mail from address by scopeId + * + * @param string|array $from + * @param string|int $scopeId + * @return $this + */ + public function setFromByScope($from, $scopeId = null) + { + $result = $this->_senderResolver->resolve($from, $scopeId); $this->message->setFromAddress($result['email'], $result['name']); return $this; } diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php index b476eecd7f59f..5e3309af6497b 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php @@ -167,20 +167,20 @@ public function getTransportDataProvider() /** * @return void */ - public function testSetFromByStore() + public function testSetFromByScope() { $sender = ['email' => 'from@example.com', 'name' => 'name']; - $store = 1; + $scopeId = 1; $this->senderResolverMock->expects($this->once()) ->method('resolve') - ->with($sender, $store) + ->with($sender, $scopeId) ->willReturn($sender); $this->messageMock->expects($this->once()) ->method('setFromAddress') ->with($sender['email'], $sender['name']) ->willReturnSelf(); - $this->builder->setFromByStore($sender, $store); + $this->builder->setFromByScope($sender, $scopeId); } /** From 3e832846dac8640fed86f8e0f0984f027c2f8b04 Mon Sep 17 00:00:00 2001 From: Shikha Mishra Date: Tue, 19 Feb 2019 20:00:48 +0530 Subject: [PATCH 39/75] Fixed #15059 Cannot reorder from the first try --- app/code/Magento/Sales/Model/AdminOrder/Create.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index 088ad5a61f6c3..1ba5984799414 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -582,6 +582,7 @@ public function initFromOrder(\Magento\Sales\Model\Order $order) } $quote->getShippingAddress()->unsCachedItemsAll(); + $quote->getBillingAddress()->unsCachedItemsAll(); $quote->setTotalsCollectedFlag(false); $this->quoteRepository->save($quote); From 2d4f079ecfefc9e1775239539ad5d9408bc9868e Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 19 Feb 2019 10:38:25 -0600 Subject: [PATCH 40/75] MAGETWO-98258: Fix elacticsearch search perfomance - fix static --- .../SearchAdapter/Aggregation/Builder/Term.php | 5 ++++- .../SearchAdapter/Query/Builder/Match.php | 11 ++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php b/app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php index bcfb7f5565b86..0c03a9df18dc8 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Aggregation/Builder/Term.php @@ -8,10 +8,13 @@ use Magento\Framework\Search\Request\BucketInterface as RequestBucketInterface; use Magento\Framework\Search\Dynamic\DataProviderInterface; +/** + * Builder for term buckets. + */ class Term implements BucketBuilderInterface { /** - * {@inheritdoc} + * @inheritdoc */ public function build( RequestBucketInterface $bucket, diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php index f1c3451482bab..149405aff3e78 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php @@ -10,6 +10,9 @@ use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface; +/** + * Builder for match query. + */ class Match implements QueryInterface { /** @@ -40,7 +43,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function build(array $selectQuery, RequestQueryInterface $requestQuery, $conditionType) { @@ -61,6 +64,8 @@ public function build(array $selectQuery, RequestQueryInterface $requestQuery, $ } /** + * Prepare query. + * * @param string $queryValue * @param string $conditionType * @return array @@ -124,11 +129,11 @@ protected function buildQueries(array $matches, array $queryValue) } /** + * Escape a value for special query characters such as ':', '(', ')', '*', '?', etc. + * * Cut trailing plus or minus sign, and @ symbol, using of which causes InnoDB to report a syntax error. * @link https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html Fulltext-boolean search docs. * - * Escape a value for special query characters such as ':', '(', ')', '*', '?', etc. - * * @param string $value * @return string */ From 2a884e574241b4ab1d8093e1421cf980283383c7 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Tue, 19 Feb 2019 16:44:12 +0000 Subject: [PATCH 41/75] magento/magento2#20621: Removed deprecated method --- .../Mail/Template/TransportBuilder.php | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 0d69b3d96cebf..b9271c0209fd3 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -183,33 +183,20 @@ public function setReplyTo($email, $name = null) * * @param string|array $from * @return $this + * @throws \Magento\Framework\Exception\MailException */ public function setFrom($from) { return $this->setFromByScope($from, null); } - /** - * Set mail from address by store - * - * @deprecated Use setFromByScope - * @see setFromByScope() - * - * @param string|array $from - * @param string|int $store - * @return $this - */ - public function setFromByStore($from, $store = null) - { - return $this->setFromByScope($from, $store); - } - /** * Set mail from address by scopeId * * @param string|array $from * @param string|int $scopeId * @return $this + * @throws \Magento\Framework\Exception\MailException */ public function setFromByScope($from, $scopeId = null) { @@ -270,6 +257,7 @@ public function setTemplateOptions($templateOptions) * Get mail transport * * @return \Magento\Framework\Mail\TransportInterface + * @throws LocalizedException */ public function getTransport() { From 168f916d35011d5147a1b7c7218cd122724b91f4 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Tue, 19 Feb 2019 11:30:20 -0600 Subject: [PATCH 42/75] MAGETWO-98258: Fix elacticsearch search perfomance - fix static --- .../Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php index 149405aff3e78..aaa9d8a88382f 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php @@ -132,7 +132,7 @@ protected function buildQueries(array $matches, array $queryValue) * Escape a value for special query characters such as ':', '(', ')', '*', '?', etc. * * Cut trailing plus or minus sign, and @ symbol, using of which causes InnoDB to report a syntax error. - * @link https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html Fulltext-boolean search docs. + * https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html Fulltext-boolean search docs. * * @param string $value * @return string From 6b0fc4791e49014386b2ea69f152cfe9cf93ec70 Mon Sep 17 00:00:00 2001 From: Joan He Date: Tue, 19 Feb 2019 12:48:28 -0600 Subject: [PATCH 43/75] MC-14951: Create backup not working --- app/code/Magento/Backup/Controller/Adminhtml/Index.php | 3 +-- .../Magento/Backup/Controller/Adminhtml/Index/Create.php | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php index 0edeb5565f288..b62963947d7bf 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php @@ -6,7 +6,6 @@ namespace Magento\Backup\Controller\Adminhtml; use Magento\Backend\App\Action; -use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Backup\Helper\Data as Helper; use Magento\Framework\App\ObjectManager; @@ -18,7 +17,7 @@ * @since 100.0.2 * @SuppressWarnings(PHPMD.AllPurposeAction) */ -abstract class Index extends Action implements HttpGetActionInterface +abstract class Index extends Action { /** * Authorization level of a basic admin session diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php index 53f45aff50cbc..99c48b727521a 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php @@ -1,15 +1,18 @@ Date: Tue, 19 Feb 2019 14:15:24 -0600 Subject: [PATCH 44/75] MC-14957: Authorize.net trying to load non-existent Accept.min.js in production configurations - Changed how require loads accept.js library to work within all constraints --- .../view/base/requirejs-config.js | 14 ++++---------- .../base/web/js/view/payment/acceptjs-factory.js | 13 +++++++++++-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/base/requirejs-config.js b/app/code/Magento/AuthorizenetAcceptjs/view/base/requirejs-config.js index 83ddd1094ea1a..cbe0a6c30e699 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/view/base/requirejs-config.js +++ b/app/code/Magento/AuthorizenetAcceptjs/view/base/requirejs-config.js @@ -4,16 +4,10 @@ */ var config = { - shim: { - acceptjs: { - exports: 'Accept' - }, - acceptjssandbox: { - exports: 'Accept' + map: { + '*': { + acceptjssandbox: 'https://jstest.authorize.net/v1/Accept.js', + acceptjs: 'https://js.authorize.net/v1/Accept.js' } - }, - paths: { - acceptjssandbox: 'https://jstest.authorize.net/v1/Accept', - acceptjs: 'https://js.authorize.net/v1/Accept' } }; diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-factory.js b/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-factory.js index e98a204e36cee..c8813c17c70c7 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-factory.js +++ b/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-factory.js @@ -16,7 +16,7 @@ define([ dependency = 'acceptjssandbox'; } - require([dependency], function (accept) { + require([dependency], function () { var $body = $('body'); /* @@ -26,7 +26,16 @@ define([ * Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/td-p/63283 */ $body.on('handshake.acceptjs', function () { - deferred.resolve(accept); + /* + * Accept.js doesn't return the library when loading + * and requirejs "shim" can't be used because it only works with the "paths" config option + * and we can't use "paths" because require will try to load ".min.js" in production + * and that doesn't work because it doesn't exist + * and we can't add a query string to force a URL because accept.js will reject it + * and we can't include it locally because they check in the script before loading more scripts + * So, we use the global version as "shim" would + */ + deferred.resolve(window.Accept); $body.off('handshake.acceptjs'); }); }, From 55b8bf813f4e398a6c81e0725a8c16302612f745 Mon Sep 17 00:00:00 2001 From: Iryna Lagno Date: Wed, 13 Feb 2019 14:41:53 -0600 Subject: [PATCH 45/75] MC-14849: \Magento\Paypal\Model\Api\Nvp::callSetExpressCheckout returns empty response --- lib/internal/Magento/Framework/HTTP/Adapter/Curl.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php index 0e51c64661a4b..bc833bf3bb2d4 100644 --- a/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php @@ -170,7 +170,6 @@ public function write($method, $url, $http_ver = '1.1', $headers = [], $body = ' // set url to post to curl_setopt($this->_getResource(), CURLOPT_URL, $url); - curl_setopt($this->_getResource(), CURLOPT_HTTP_VERSION, $http_ver); curl_setopt($this->_getResource(), CURLOPT_RETURNTRANSFER, true); if ($method == \Zend_Http_Client::POST) { curl_setopt($this->_getResource(), CURLOPT_POST, true); From 8b09a6ff2e3b681cb92af8558ebbfdf6718bc576 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov Date: Tue, 19 Feb 2019 15:41:29 -0600 Subject: [PATCH 46/75] MAGETWO-98328: Update FedEx Shipping Dates behavior in Tracking Popup --- .../DataProviders/Tracking/ChangeTitle.php | 32 +++++++++++ .../Block/Tracking/PopupDeliveryDate.php | 55 +++++++++++++++++++ app/code/Magento/Fedex/etc/di.xml | 6 ++ .../Tracking/DeliveryDateTitle.php | 25 +++++++++ .../layout/shipping_tracking_popup.xml | 6 +- .../frontend/templates/tracking/details.phtml | 2 +- 6 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php create mode 100644 app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php create mode 100644 app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php diff --git a/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php new file mode 100644 index 0000000000000..d148b91aa3e7a --- /dev/null +++ b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php @@ -0,0 +1,32 @@ +getCarrier() === Carrier::CODE) { + $result = __('Expected Delivery:'); + } + return $result; + } +} diff --git a/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php b/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php new file mode 100644 index 0000000000000..942d21dfa5e47 --- /dev/null +++ b/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php @@ -0,0 +1,55 @@ +getCarrier($subject) === Carrier::CODE) { + $result = $subject->formatDeliveryDate($date); + } + return $result; + } + + /** + * Retrieve carrier name from tracking info + * + * @param Popup $subject + * @return string + */ + private function getCarrier(Popup $subject): string + { + foreach ($subject->getTrackingInfo() as $trackingData) { + foreach ($trackingData as $trackingInfo) { + if ($trackingInfo instanceof Status) { + $carrier = $trackingInfo->getCarrier(); + return $carrier; + } + } + } + return ''; + } +} diff --git a/app/code/Magento/Fedex/etc/di.xml b/app/code/Magento/Fedex/etc/di.xml index f17f8f2afe663..c542b1f04d1eb 100644 --- a/app/code/Magento/Fedex/etc/di.xml +++ b/app/code/Magento/Fedex/etc/di.xml @@ -22,4 +22,10 @@ + + + + + + diff --git a/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php new file mode 100644 index 0000000000000..dc66c4f0bd018 --- /dev/null +++ b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php @@ -0,0 +1,25 @@ +getCarrier() ? __('Delivered on:') : ''; + } +} diff --git a/app/code/Magento/Shipping/view/frontend/layout/shipping_tracking_popup.xml b/app/code/Magento/Shipping/view/frontend/layout/shipping_tracking_popup.xml index 1f5b0ae4630ad..67d03da2599bf 100644 --- a/app/code/Magento/Shipping/view/frontend/layout/shipping_tracking_popup.xml +++ b/app/code/Magento/Shipping/view/frontend/layout/shipping_tracking_popup.xml @@ -8,7 +8,11 @@ - + + + Magento\Shipping\Block\DataProviders\Tracking\DeliveryDateTitle + + diff --git a/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml b/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml index 9253b47f82f5d..e8584d8f6ad51 100644 --- a/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml +++ b/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml @@ -77,7 +77,7 @@ $number = is_object($track) ? $track->getTracking() : $track['number']; getDeliverydate()): ?> - escapeHtml(__('Delivered on:')) ?> + escapeHtml($parentBlock->getDeliveryDateTitle()->getTitle($track)) ?> formatDeliveryDateTime($track->getDeliverydate(), $track->getDeliverytime()) ?> From 40890490c1a2430c3882ed9c721e4cd1e55a3879 Mon Sep 17 00:00:00 2001 From: Iryna Lagno Date: Tue, 19 Feb 2019 10:42:11 -0600 Subject: [PATCH 47/75] MC-14953: Not clickable link --- .../Magento_Rma/web/css/source/_module.less | 14 +++++++++++--- .../Magento/Test/Legacy/_files/words_ce.xml | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Rma/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Rma/web/css/source/_module.less index c405707ee7bbe..16c84047b529d 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Rma/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_Rma/web/css/source/_module.less @@ -7,13 +7,21 @@ .rma-request-details, .rma-wrapper .order-shipping-address { float: left; - #mix-grid .width(6,12); + /** + * @codingStandardsIgnoreStart + */ + #mix-grid .width(6, 12); + //@codingStandardsIgnoreEnd } .rma-confirmation, - .rma-wrapper .order-return-address { + .rma-wrapper .order-return-address, .rma-wrapper .order-shipping-method { float: right; - #mix-grid .width(6,12); + /** + * @codingStandardsIgnoreStart + */ + #mix-grid .width(6, 12); + //@codingStandardsIgnoreEnd } } diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/words_ce.xml b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/words_ce.xml index 9bb00533a5da5..92e7b15efed29 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/words_ce.xml +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/words_ce.xml @@ -69,5 +69,9 @@ dev/build/publication/sanity/ce.xml + + app/design/adminhtml/Magento/backend/Magento_Rma/web/css/source/_module.less + rma + From 974152f8ab4a7b7f381e9c28e37ac3c7adaf08c5 Mon Sep 17 00:00:00 2001 From: Yogesh Suhagiya Date: Wed, 20 Feb 2019 10:34:11 +0530 Subject: [PATCH 48/75] Applied some code format rules --- app/code/Magento/Marketplace/Block/Partners.php | 2 +- app/code/Magento/PageCache/Model/Cache/Server.php | 3 +-- .../PageCache/Model/System/Config/Backend/AccessList.php | 2 +- app/code/Magento/PageCache/Model/Varnish/VclGenerator.php | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Marketplace/Block/Partners.php b/app/code/Magento/Marketplace/Block/Partners.php index 4f8ca798f1756..a3ed88f4fc3b4 100644 --- a/app/code/Magento/Marketplace/Block/Partners.php +++ b/app/code/Magento/Marketplace/Block/Partners.php @@ -39,7 +39,7 @@ public function __construct( /** * Gets partners * - * @return bool|string + * @return array */ public function getPartners() { diff --git a/app/code/Magento/PageCache/Model/Cache/Server.php b/app/code/Magento/PageCache/Model/Cache/Server.php index 349e9faffa673..06118446c21bc 100644 --- a/app/code/Magento/PageCache/Model/Cache/Server.php +++ b/app/code/Magento/PageCache/Model/Cache/Server.php @@ -62,8 +62,7 @@ public function getUris() foreach ($configuredHosts as $host) { $servers[] = UriFactory::factory('') ->setHost($host['host']) - ->setPort(isset($host['port']) ? $host['port'] : self::DEFAULT_PORT) - ; + ->setPort(isset($host['port']) ? $host['port'] : self::DEFAULT_PORT); } } elseif ($this->request->getHttpHost()) { $servers[] = UriFactory::factory('')->setHost($this->request->getHttpHost())->setPort(self::DEFAULT_PORT); diff --git a/app/code/Magento/PageCache/Model/System/Config/Backend/AccessList.php b/app/code/Magento/PageCache/Model/System/Config/Backend/AccessList.php index e16584b0b17f8..7c9391ba22182 100644 --- a/app/code/Magento/PageCache/Model/System/Config/Backend/AccessList.php +++ b/app/code/Magento/PageCache/Model/System/Config/Backend/AccessList.php @@ -28,7 +28,7 @@ public function beforeSave() throw new LocalizedException( new Phrase( 'Access List value "%1" is not valid. ' - .'Please use only IP addresses and host names.', + . 'Please use only IP addresses and host names.', [$value] ) ); diff --git a/app/code/Magento/PageCache/Model/Varnish/VclGenerator.php b/app/code/Magento/PageCache/Model/Varnish/VclGenerator.php index cf5a703142c84..5a7c3a2d2f6d1 100644 --- a/app/code/Magento/PageCache/Model/Varnish/VclGenerator.php +++ b/app/code/Magento/PageCache/Model/Varnish/VclGenerator.php @@ -119,7 +119,7 @@ private function getReplacements() private function getRegexForDesignExceptions() { $result = ''; - $tpl = "%s (req.http.user-agent ~ \"%s\") {\n"." hash_data(\"%s\");\n"." }"; + $tpl = "%s (req.http.user-agent ~ \"%s\") {\n" . " hash_data(\"%s\");\n" . " }"; $expressions = $this->getDesignExceptions(); @@ -157,7 +157,7 @@ private function getTransformedAccessList() $result = array_reduce( $this->getAccessList(), function ($ips, $ip) use ($tpl) { - return $ips.sprintf($tpl, trim($ip)) . "\n"; + return $ips . sprintf($tpl, trim($ip)) . "\n"; }, '' ); From 78916b3f987d47febbdf443b8839baca780e9c02 Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Wed, 20 Feb 2019 13:30:27 +0200 Subject: [PATCH 49/75] Fix static tests. --- lib/internal/Magento/Framework/Module/ModuleList/Loader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Module/ModuleList/Loader.php b/lib/internal/Magento/Framework/Module/ModuleList/Loader.php index 80958f65e110e..72421f793f131 100644 --- a/lib/internal/Magento/Framework/Module/ModuleList/Loader.php +++ b/lib/internal/Magento/Framework/Module/ModuleList/Loader.php @@ -134,7 +134,7 @@ private function sortBySequence(array $origList): array $modules = $this->prearrangeModules($origList); $expanded = []; - foreach ($modules as $moduleName => $value) { + foreach (array_keys($modules) as $moduleName) { $sequence = $this->expandSequence($origList, $moduleName); asort($sequence); From b63123e693fe7f950318ed6550d71494661fea89 Mon Sep 17 00:00:00 2001 From: mageprince Date: Wed, 20 Feb 2019 17:12:37 +0530 Subject: [PATCH 50/75] Solve page break on long string search --- .../Magento/luma/Magento_Theme/web/css/source/_module.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less index 99da7716f9274..9f0997ed2ba85 100644 --- a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less @@ -503,6 +503,7 @@ > .page-title-wrapper { .page-title { display: inline-block; + word-break: break-all; } .page-title + .action { From 1236770b10b14969a69ac81725a6bab781011ffd Mon Sep 17 00:00:00 2001 From: mageprince Date: Wed, 20 Feb 2019 17:30:37 +0530 Subject: [PATCH 51/75] Move css to general for all devices --- .../luma/Magento_Theme/web/css/source/_module.less | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less index 9f0997ed2ba85..4d990a82cb7e4 100644 --- a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less @@ -77,6 +77,14 @@ .lib-vendor-prefix-flex-grow(1); } + .page-main { + > .page-title-wrapper { + .page-title { + word-break: break-all; + } + } + } + // // Header // --------------------------------------------- @@ -503,7 +511,6 @@ > .page-title-wrapper { .page-title { display: inline-block; - word-break: break-all; } .page-title + .action { From 01bfe90b33206d352b14a80a2a2bdafafd90a7f9 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov Date: Wed, 20 Feb 2019 10:48:15 -0600 Subject: [PATCH 52/75] MAGETWO-98328: Update FedEx Shipping Dates behavior in Tracking Popup --- .../Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php index d148b91aa3e7a..86a576f2db650 100644 --- a/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php +++ b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php @@ -16,13 +16,15 @@ class ChangeTitle { /** + * Title modification in case if FedEx used as carrier + * * @param Subject $subject * @param \Magento\Framework\Phrase|string $result * @param Status $trackingStatus * @return \Magento\Framework\Phrase|string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetTitle(Subject $subject, $result, Status $trackingStatus): string + public function afterGetTitle(Subject $subject, $result, Status $trackingStatus) { if ($trackingStatus->getCarrier() === Carrier::CODE) { $result = __('Expected Delivery:'); From 0a56988e31ba69f2fb48500f98ee393fce0bf8d7 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov Date: Wed, 20 Feb 2019 11:07:31 -0600 Subject: [PATCH 53/75] MAGETWO-98328: Update FedEx Shipping Dates behavior in Tracking Popup --- .../Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php index dc66c4f0bd018..ec1ee277a5a51 100644 --- a/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php +++ b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php @@ -15,6 +15,8 @@ class DeliveryDateTitle implements ArgumentInterface { /** + * Returns Title in case if carrier defined + * * @param Status $trackingStatus * @return \Magento\Framework\Phrase|string */ From 9a0c504199f414bf8dfc9d286d6fda48f5fd208b Mon Sep 17 00:00:00 2001 From: Amol2jcommerce Date: Wed, 20 Feb 2019 23:27:53 +0530 Subject: [PATCH 54/75] CSS-Property-name-issue --- .../Magento/blank/Magento_Swatches/web/css/source/_module.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less index 28aa3f187e95c..8824624d1c63a 100644 --- a/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Swatches/web/css/source/_module.less @@ -110,7 +110,7 @@ .lib-css(color, @attr-swatch-option__color); &.selected { - .lib-css(blackground, @attr-swatch-option__selected__background); + .lib-css(background, @attr-swatch-option__selected__background); .lib-css(border, @attr-swatch-option__selected__border); .lib-css(color, @attr-swatch-option__selected__color); } From a68e81575c158b92505cc5e3c300ca551fae5cf7 Mon Sep 17 00:00:00 2001 From: Amol2jcommerce Date: Wed, 20 Feb 2019 23:33:33 +0530 Subject: [PATCH 55/75] unwanted changes reverted CSS-Property-name-issue --- .../Magento/blank/Magento_Customer/web/css/source/_module.less | 2 +- .../Magento/luma/Magento_Customer/web/css/source/_module.less | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less index a94fedbcbbd14..9df59ca5dac92 100644 --- a/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Customer/web/css/source/_module.less @@ -421,7 +421,7 @@ > .field { > .control { - width: 80%; + width: 55%; } } } diff --git a/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less index 61fc2610fc2e5..2e7856d390bd0 100755 --- a/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Customer/web/css/source/_module.less @@ -375,7 +375,7 @@ .fieldset { > .field { > .control { - width: 80%; + width: 55%; } } } From ecf6ddd231dff70ad5e2011b71ef9f8a2d3c0e94 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov Date: Wed, 20 Feb 2019 13:21:14 -0600 Subject: [PATCH 56/75] MAGETWO-98328: Update FedEx Shipping Dates behavior in Tracking Popup --- .../Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php b/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php index 942d21dfa5e47..e1597707f9d02 100644 --- a/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php +++ b/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); namespace Magento\Fedex\Plugin\Block\Tracking; @@ -26,7 +25,7 @@ class PopupDeliveryDate * @return string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterFormatDeliveryDateTime(Popup $subject, string $result, string $date, string $time): string + public function afterFormatDeliveryDateTime(Popup $subject, $result, $date, $time) { if ($this->getCarrier($subject) === Carrier::CODE) { $result = $subject->formatDeliveryDate($date); From b392c7cf48c78ad499ede0d80a67b6471908d703 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 20 Feb 2019 17:34:37 -0600 Subject: [PATCH 57/75] MC-15000: Add New Attribute on the admin product page with JS error - validation has be called as a function inside the component --- .../view/adminhtml/web/catalog/product/edit/attribute.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/edit/attribute.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/edit/attribute.js index 407fd1fe28e39..e1923dc46d68e 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/edit/attribute.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/edit/attribute.js @@ -5,13 +5,13 @@ define([ 'jquery', - 'mage/mage' + 'mage/mage', + 'validation' ], function ($) { 'use strict'; return function (config, element) { - - $(element).mage('form').mage('validation', { + $(element).mage('form').validation({ validationUrl: config.validationUrl }); }; From c67c3fc8bf3d50bb25047b6be835ae99bd167914 Mon Sep 17 00:00:00 2001 From: Cristian Partica Date: Wed, 20 Feb 2019 17:45:02 -0600 Subject: [PATCH 58/75] MC-15000: Add New Attribute on the admin product page with JS error - remove unused phtml file --- .../adminhtml/templates/class/page/edit.phtml | 20 ------------------- .../view/adminhtml/web/js/page/validate.js | 15 -------------- 2 files changed, 35 deletions(-) delete mode 100644 app/code/Magento/Tax/view/adminhtml/templates/class/page/edit.phtml delete mode 100644 app/code/Magento/Tax/view/adminhtml/web/js/page/validate.js diff --git a/app/code/Magento/Tax/view/adminhtml/templates/class/page/edit.phtml b/app/code/Magento/Tax/view/adminhtml/templates/class/page/edit.phtml deleted file mode 100644 index 18e86549a1ff9..0000000000000 --- a/app/code/Magento/Tax/view/adminhtml/templates/class/page/edit.phtml +++ /dev/null @@ -1,20 +0,0 @@ - -
- getBackButtonHtml() ?> - getResetButtonHtml() ?> - getDeleteButtonHtml() ?> - getSaveButtonHtml() ?> -
-getRenameFormHtml() ?> - diff --git a/app/code/Magento/Tax/view/adminhtml/web/js/page/validate.js b/app/code/Magento/Tax/view/adminhtml/web/js/page/validate.js deleted file mode 100644 index a49f199ba56b6..0000000000000 --- a/app/code/Magento/Tax/view/adminhtml/web/js/page/validate.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'jquery', - 'mage/mage' -], function (jQuery) { - 'use strict'; - - return function (data, element) { - jQuery(element).mage('form').mage('validation'); - }; -}); From 124b0e03bd3004b04f2efe3ecac4d758fc4891c5 Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Thu, 21 Feb 2019 10:49:29 +0200 Subject: [PATCH 59/75] Fix static tests. --- app/code/Magento/Sales/Model/AdminOrder/Create.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index 1ba5984799414..063433140566a 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -23,6 +23,7 @@ * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @since 100.0.2 */ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\Model\Cart\CartInterface From 5d3870a57594d91884dd80d312983c840780849b Mon Sep 17 00:00:00 2001 From: Iryna Lagno Date: Thu, 21 Feb 2019 14:03:56 -0600 Subject: [PATCH 60/75] MC-15011: Text is not displayed correctly --- .../Cms/Test/Mftf/Page/CmsPageEditPage.xml | 2 +- .../AdminProductFormConfigurationsSection.xml | 1 + .../AdminConfigurableProductCreateTest.xml | 1 + .../Product/Form/Modifier/Links.php | 26 +++++++++++++++++-- .../Product/Form/Modifier/Samples.php | 15 +++++++++-- .../form/element/uploader/uploader.html | 2 +- .../backend/web/css/source/forms/_fields.less | 1 + 7 files changed, 42 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/Page/CmsPageEditPage.xml b/app/code/Magento/Cms/Test/Mftf/Page/CmsPageEditPage.xml index 885310d9399ae..73db6b61343b1 100644 --- a/app/code/Magento/Cms/Test/Mftf/Page/CmsPageEditPage.xml +++ b/app/code/Magento/Cms/Test/Mftf/Page/CmsPageEditPage.xml @@ -7,7 +7,7 @@ --> - +
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection.xml index c5d6abd89edbf..73ae71adfaaf0 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection.xml @@ -27,6 +27,7 @@ +
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest.xml index 24af7d44e8261..2af85e1bac048 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest.xml @@ -36,6 +36,7 @@ + diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php index a352c4bdf7bc3..2188a671a5aa0 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php @@ -86,7 +86,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -101,7 +101,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function modifyMeta(array $meta) @@ -160,6 +160,8 @@ public function modifyMeta(array $meta) } /** + * Returns configuration for dynamic rows + * * @return array */ protected function getDynamicRows() @@ -180,6 +182,8 @@ protected function getDynamicRows() } /** + * Returns Record column configuration + * * @return array */ protected function getRecord() @@ -221,6 +225,8 @@ protected function getRecord() } /** + * Returns Title column configuration + * * @return array */ protected function getTitleColumn() @@ -238,6 +244,7 @@ protected function getTitleColumn() 'componentType' => Form\Field::NAME, 'dataType' => Form\Element\DataType\Text::NAME, 'dataScope' => 'title', + 'labelVisible' => false, 'validation' => [ 'required-entry' => true, ], @@ -247,6 +254,8 @@ protected function getTitleColumn() } /** + * Returns Price column configuration + * * @return array */ protected function getPriceColumn() @@ -265,6 +274,7 @@ protected function getPriceColumn() 'dataType' => Form\Element\DataType\Number::NAME, 'component' => 'Magento_Downloadable/js/components/price-handler', 'dataScope' => 'price', + 'labelVisible' => false, 'addbefore' => $this->locator->getStore()->getBaseCurrency() ->getCurrencySymbol(), 'validation' => [ @@ -281,6 +291,8 @@ protected function getPriceColumn() } /** + * Returns File column configuration + * * @return array */ protected function getFileColumn() @@ -302,6 +314,7 @@ protected function getFileColumn() 'options' => $this->typeUpload->toOptionArray(), 'typeFile' => 'links_file', 'typeUrl' => 'link_url', + 'labelVisible' => false, ]; $fileLinkUrl['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, @@ -344,6 +357,8 @@ protected function getFileColumn() } /** + * Returns Sample column configuration + * * @return array */ protected function getSampleColumn() @@ -363,6 +378,7 @@ protected function getSampleColumn() 'dataType' => Form\Element\DataType\Text::NAME, 'dataScope' => 'sample.type', 'options' => $this->typeUpload->toOptionArray(), + 'labelVisible' => false, 'typeFile' => 'sample_file', 'typeUrl' => 'sample_url', ]; @@ -382,6 +398,7 @@ protected function getSampleColumn() 'component' => 'Magento_Downloadable/js/components/file-uploader', 'elementTmpl' => 'Magento_Downloadable/components/file-uploader', 'fileInputName' => 'link_samples', + 'labelVisible' => false, 'uploaderConfig' => [ 'url' => $this->urlBuilder->addSessionParam()->getUrl( 'adminhtml/downloadable_file/upload', @@ -403,6 +420,8 @@ protected function getSampleColumn() } /** + * Returns Sharable columns configuration + * * @return array */ protected function getShareableColumn() @@ -420,6 +439,8 @@ protected function getShareableColumn() } /** + * Returns max downloads column configuration + * * @return array */ protected function getMaxDownloadsColumn() @@ -437,6 +458,7 @@ protected function getMaxDownloadsColumn() 'componentType' => Form\Field::NAME, 'dataType' => Form\Element\DataType\Number::NAME, 'dataScope' => 'number_of_downloads', + 'labelVisible' => false, 'value' => 0, 'validation' => [ 'validate-zero-or-greater' => true, diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php index 1587163ba8121..197bf1338f945 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php @@ -77,7 +77,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -90,7 +90,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function modifyMeta(array $meta) @@ -135,6 +135,8 @@ public function modifyMeta(array $meta) } /** + * Returns configuration for dynamic rows + * * @return array */ protected function getDynamicRows() @@ -155,6 +157,8 @@ protected function getDynamicRows() } /** + * Returns Record column configuration + * * @return array */ protected function getRecord() @@ -192,6 +196,8 @@ protected function getRecord() } /** + * Returns Title column configuration + * * @return array */ protected function getTitleColumn() @@ -209,6 +215,7 @@ protected function getTitleColumn() 'componentType' => Form\Field::NAME, 'dataType' => Form\Element\DataType\Text::NAME, 'dataScope' => 'title', + 'labelVisible' => false, 'validation' => [ 'required-entry' => true, ], @@ -218,6 +225,8 @@ protected function getTitleColumn() } /** + * Returns Sample column configuration + * * @return array */ protected function getSampleColumn() @@ -236,6 +245,7 @@ protected function getSampleColumn() 'component' => 'Magento_Downloadable/js/components/upload-type-handler', 'dataType' => Form\Element\DataType\Text::NAME, 'dataScope' => 'type', + 'labelVisible' => false, 'options' => $this->typeUpload->toOptionArray(), 'typeFile' => 'sample_file', 'typeUrl' => 'sample_url', @@ -246,6 +256,7 @@ protected function getSampleColumn() 'dataType' => Form\Element\DataType\Text::NAME, 'dataScope' => 'sample_url', 'placeholder' => 'URL', + 'labelVisible' => false, 'validation' => [ 'required-entry' => true, 'validate-url' => true, diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html b/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html index a92b85cb47401..cf4e2243b5886 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html @@ -6,7 +6,7 @@ -->
-