diff --git a/app/code/Magento/AdminNotification/view/adminhtml/templates/system/messages/popup.phtml b/app/code/Magento/AdminNotification/view/adminhtml/templates/system/messages/popup.phtml index a97293547e132..d654504a41e5c 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/templates/system/messages/popup.phtml +++ b/app/code/Magento/AdminNotification/view/adminhtml/templates/system/messages/popup.phtml @@ -19,20 +19,12 @@ - + \ No newline at end of file diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/system/messages/popup.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/system/messages/popup.js new file mode 100644 index 0000000000000..f3f6a5fb1a123 --- /dev/null +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/system/messages/popup.js @@ -0,0 +1,24 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. +*/ + +define([ + 'jquery', + 'Magento_Ui/js/modal/modal' +], function ($) { + 'use strict'; + + return function (data, element) { + if (this.modal) { + this.modal.html($(element).html()); + } else { + this.modal = $(element).modal({ + modalClass: data.class, + type: 'popup', + buttons: [] + }); + } + this.modal.modal('openModal'); + }; +}); diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 03ddab3d44547..4c0122694285d 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -334,9 +334,7 @@ protected function initializeProductData(array $productData, $createNew) unset($productData['media_gallery']); if ($createNew) { $product = $this->productFactory->create(); - if ($this->storeManager->hasSingleStore()) { - $product->setWebsiteIds([$this->storeManager->getStore(true)->getWebsiteId()]); - } + $this->assignProductToWebsites($product); } else { $this->removeProductFromLocalCache($productData['sku']); $product = $this->get($productData['sku']); @@ -345,31 +343,20 @@ protected function initializeProductData(array $productData, $createNew) foreach ($productData as $key => $value) { $product->setData($key, $value); } - $this->assignProductToWebsites($product, $createNew); return $product; } /** * @param \Magento\Catalog\Model\Product $product - * @param bool $createNew * @return void */ - private function assignProductToWebsites(\Magento\Catalog\Model\Product $product, $createNew) + private function assignProductToWebsites(\Magento\Catalog\Model\Product $product) { - $websiteIds = $product->getWebsiteIds(); - - if (!$this->storeManager->hasSingleStore()) { - $websiteIds = array_unique( - array_merge( - $websiteIds, - [$this->storeManager->getStore()->getWebsiteId()] - ) - ); - } - - if ($createNew && $this->storeManager->getStore(true)->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) { + if ($this->storeManager->getStore(true)->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) { $websiteIds = array_keys($this->storeManager->getWebsites()); + } else { + $websiteIds = [$this->storeManager->getStore()->getWebsiteId()]; } $product->setWebsiteIds($websiteIds); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index bf5c3d8276295..a1cf6662d78f0 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -553,7 +553,6 @@ public function testGetBySkuFromCacheInitializedInGetById() public function testSaveExisting() { - $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']); $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100)); $this->productFactoryMock->expects($this->any()) ->method('create') @@ -566,7 +565,6 @@ public function testSaveExisting() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($this->productData['sku']); $this->assertEquals($this->productMock, $this->model->save($this->productMock)); @@ -588,7 +586,6 @@ public function testSaveNew() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->method('getWebsiteIds')->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->assertEquals($this->productMock, $this->model->save($this->productMock)); @@ -615,7 +612,6 @@ public function testSaveUnableToSaveException() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->method('getWebsiteIds')->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->model->save($this->productMock); @@ -642,7 +638,6 @@ public function testSaveException() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->model->save($this->productMock); @@ -667,7 +662,6 @@ public function testSaveInvalidProductException() ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->model->save($this->productMock); @@ -697,9 +691,6 @@ public function testSaveThrowsTemporaryStateExceptionIfDatabaseConnectionErrorOc ->expects($this->once()) ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->productMock->expects($this->once()) - ->method('getWebsiteIds') - ->willReturn([]); $this->productMock->method('getSku')->willReturn('simple'); $this->model->save($this->productMock); @@ -847,7 +838,6 @@ public function testSaveExistingWithOptions(array $newOptions, array $existingOp ->method('toNestedArray') ->will($this->returnValue($this->productData)); - $this->initializedProductMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->initializedProductMock->expects($this->atLeastOnce()) ->method('getSku')->willReturn($this->productData['sku']); $this->productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($this->productData['sku']); @@ -1083,7 +1073,6 @@ public function testSaveWithLinks(array $newLinks, array $existingLinks, array $ $outputLinks[] = $outputLink; } } - $this->initializedProductMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); if (!empty($outputLinks)) { $this->initializedProductMock->expects($this->once()) @@ -1264,7 +1253,6 @@ public function testSaveExistingWithNewMediaGalleryEntries() 'media_type' => 'media_type', ] ); - $this->initializedProductMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->initializedProductMock->expects($this->atLeastOnce()) ->method('getSku')->willReturn($this->productData['sku']); $this->productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($this->productData['sku']); @@ -1305,7 +1293,6 @@ public function testSaveWithDifferentWebsites() 2 => ['second'], 3 => ['third'] ]); - $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([1,2,3]); $this->productMock->expects($this->once())->method('setWebsiteIds')->willReturn([2,3]); $this->productMock->method('getSku')->willReturn('simple'); @@ -1377,7 +1364,6 @@ public function testSaveExistingWithMediaGalleryEntries() $this->mediaGalleryProcessor->expects($this->once()) ->method('setMediaAttribute') ->with($this->initializedProductMock, ['image', 'small_image'], 'filename1'); - $this->initializedProductMock->expects($this->once())->method('getWebsiteIds')->willReturn([]); $this->initializedProductMock->expects($this->atLeastOnce()) ->method('getSku')->willReturn($this->productData['sku']); $this->productMock->expects($this->atLeastOnce())->method('getSku')->willReturn($this->productData['sku']); diff --git a/app/code/Magento/Catalog/etc/adminhtml/menu.xml b/app/code/Magento/Catalog/etc/adminhtml/menu.xml index aa910e6d5ade4..cfcce3a26cbec 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/menu.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/menu.xml @@ -12,7 +12,6 @@ - diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 6efd2d1c1eafe..60789c016ff0f 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -1809,7 +1809,7 @@ - diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json index b38817331bee5..1c2c660ca9b00 100644 --- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json +++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json @@ -1096,7 +1096,8 @@ "index": { "CAT_CTGR_PRD_IDX_REPLICA_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY": true, "IDX_87EB2E3059853CF89A75B4C55074810B": true, - "CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY": true + "CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY": true, + "CAT_CTGR_PRD_IDX_STORE_ID_CTGR_ID_VISIBILITY_IS_PARENT_POSITION": true }, "constraint": { "PRIMARY": true @@ -1114,8 +1115,9 @@ "constraint": { "PRIMARY": true, "CAT_PRD_FRONTEND_ACTION_CSTR_ID_CSTR_ENTT_ENTT_ID": true, + "CAT_PRD_FRONTEND_ACTION_PRD_ID_CAT_PRD_ENTT_ENTT_ID": true, "CATALOG_PRODUCT_FRONTEND_ACTION_VISITOR_ID_PRODUCT_ID_TYPE_ID": true, "CATALOG_PRODUCT_FRONTEND_ACTION_CUSTOMER_ID_PRODUCT_ID_TYPE_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 4d42330cd00bf..59009cc2d5637 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -10,6 +10,7 @@ use Magento\CatalogImportExport\Model\Import\Product\MediaGalleryProcessor; use Magento\CatalogImportExport\Model\Import\Product\ImageTypeProcessor; use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface as ValidatorInterface; +use Magento\CatalogInventory\Api\Data\StockItemInterface; use Magento\CatalogImportExport\Model\StockItemImporterInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; @@ -2618,7 +2619,10 @@ private function _setStockUseConfigFieldsValues($rowData) { $useConfigFields = []; foreach ($rowData as $key => $value) { - $useConfigName = self::INVENTORY_USE_CONFIG_PREFIX . $key; + $useConfigName = $key === StockItemInterface::ENABLE_QTY_INCREMENTS + ? StockItemInterface::USE_CONFIG_ENABLE_QTY_INC + : self::INVENTORY_USE_CONFIG_PREFIX . $key; + if (isset($this->defaultStockData[$key]) && isset($this->defaultStockData[$useConfigName]) && !empty($value) @@ -2715,7 +2719,12 @@ protected function checkUrlKeyDuplicates() ); foreach ($urlKeyDuplicates as $entityData) { $rowNum = $this->rowNumbers[$entityData['store_id']][$entityData['request_path']]; - $this->addRowError(ValidatorInterface::ERROR_DUPLICATE_URL_KEY, $rowNum); + $message = sprintf( + $this->retrieveMessageTemplate(ValidatorInterface::ERROR_DUPLICATE_URL_KEY), + $entityData['request_path'], + $entityData['sku'] + ); + $this->addRowError(ValidatorInterface::ERROR_DUPLICATE_URL_KEY, $rowNum, 'url_key', $message); } } } diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php index 3d9dcd05f8fac..d049d74bd2601 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php @@ -32,7 +32,7 @@ public function __construct(Context $context, Registry $coreRegistry) /** * Initialize category object in registry * - * @return Category + * @return Category|bool */ protected function _initCategory() { diff --git a/app/code/Magento/CatalogRule/etc/db_schema.xml b/app/code/Magento/CatalogRule/etc/db_schema.xml index 883a992d8c730..f4c40a6930cc0 100644 --- a/app/code/Magento/CatalogRule/etc/db_schema.xml +++ b/app/code/Magento/CatalogRule/etc/db_schema.xml @@ -60,7 +60,7 @@ - + @@ -198,7 +198,7 @@ - + diff --git a/app/code/Magento/CatalogRule/etc/db_schema_whitelist.json b/app/code/Magento/CatalogRule/etc/db_schema_whitelist.json index a41d31a08ee29..f5aaece43f179 100644 --- a/app/code/Magento/CatalogRule/etc/db_schema_whitelist.json +++ b/app/code/Magento/CatalogRule/etc/db_schema_whitelist.json @@ -49,7 +49,8 @@ }, "constraint": { "PRIMARY": true, - "IDX_EAA51B56FF092A0DCB795D1CEF812B7B": true + "IDX_EAA51B56FF092A0DCB795D1CEF812B7B": true, + "UNQ_EAA51B56FF092A0DCB795D1CEF812B7B": true } }, "catalogrule_product_price": { @@ -146,7 +147,8 @@ }, "constraint": { "PRIMARY": true, - "UNQ_BDF2B92A4F0B28D7896648B3B8A26089": true + "IDX_EAA51B56FF092A0DCB795D1CEF812B7B": true, + "UNQ_EAA51B56FF092A0DCB795D1CEF812B7B": true } }, "catalogrule_product_price_replica": { @@ -190,4 +192,4 @@ "PRIMARY": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index cd419902831b8..5ad2635576857 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -221,7 +221,7 @@ private function getSelectForSearchableProducts( $lastProductId, $batch ) { - $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId(); + $websiteId = (int)$this->storeManager->getStore($storeId)->getWebsiteId(); $lastProductId = (int) $lastProductId; $select = $this->connection->select() diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php index ffba417eb3ac7..fac8c4d2a47f6 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Engine.php @@ -120,7 +120,7 @@ public function processAttributeValue($attribute, $value) * * @param array $index * @param string $separator - * @return string + * @return array */ public function prepareEntityIndex($index, $separator = ' ') { diff --git a/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php b/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php index d93475a4744ca..de996bed02439 100644 --- a/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php +++ b/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php @@ -394,9 +394,9 @@ protected function orderCountryOptions(array $countryOptions) ]]; foreach ($countryOptions as $countryOption) { if (empty($countryOption['value']) || in_array($countryOption['value'], $this->topCountryCodes)) { - array_push($headOptions, $countryOption); + $headOptions[] = $countryOption; } else { - array_push($tailOptions, $countryOption); + $tailOptions[] = $countryOption; } } return array_merge($headOptions, $tailOptions); diff --git a/app/code/Magento/Checkout/Block/Checkout/DirectoryDataProcessor.php b/app/code/Magento/Checkout/Block/Checkout/DirectoryDataProcessor.php index 1d5bb5bb07d81..587dd06d89106 100644 --- a/app/code/Magento/Checkout/Block/Checkout/DirectoryDataProcessor.php +++ b/app/code/Magento/Checkout/Block/Checkout/DirectoryDataProcessor.php @@ -141,9 +141,9 @@ private function orderCountryOptions(array $countryOptions) ]]; foreach ($countryOptions as $countryOption) { if (empty($countryOption['value']) || in_array($countryOption['value'], $topCountryCodes)) { - array_push($headOptions, $countryOption); + $headOptions[] = $countryOption; } else { - array_push($tailOptions, $countryOption); + $tailOptions[] = $countryOption; } } return array_merge($headOptions, $tailOptions); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js index a0bdf0a17d7fe..aba0c31b998d1 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js @@ -14,20 +14,17 @@ define([ 'use strict'; var quoteItems = ko.observable(quote.totals().items), - cartData = customerData.get('cart'); + cartData = customerData.get('cart'), + quoteSubtotal = parseFloat(quote.totals().subtotal), + subtotalAmount = parseFloat(cartData().subtotalAmount); quote.totals.subscribe(function (newValue) { quoteItems(newValue.items); }); - cartData.subscribe(function () { - var quoteSubtotal = parseFloat(quote.totals().subtotal), - subtotalAmount = parseFloat(cartData().subtotalAmount); - - if (quoteSubtotal !== subtotalAmount) { - customerData.reload(['cart'], false); - } - }, this); + if (quoteSubtotal !== subtotalAmount) { + customerData.reload(['cart'], false); + } return { totals: quote.totals, diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index 33223e9ae3c24..a2f8c8c56ff33 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -94,10 +94,6 @@ define([ this.isLoading(addToCartCalls > 0); sidebarInitialized = false; this.update(updatedCart); - - if (cartData()['website_id'] !== window.checkout.websiteId) { - customerData.reload(['cart'], false); - } initSidebar(); }, this); $('[data-block="minicart"]').on('contentLoading', function () { @@ -105,6 +101,10 @@ define([ self.isLoading(true); }); + if (cartData()['website_id'] !== window.checkout.websiteId) { + customerData.reload(['cart'], false); + } + return this._super(); }, isLoading: ko.observable(false), diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js index 37b7c7c41b216..558a1fdf31085 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js @@ -26,7 +26,7 @@ define([ if (!(data && data.items && data.items.length && productId)) { return false; } - changedProductOptions = data.items.find(function (item) { + changedProductOptions = _.find(data.items, function (item) { if (item['item_id'] === itemId) { return item['product_id'] === productId; } diff --git a/app/code/Magento/Customer/Block/Widget/Dob.php b/app/code/Magento/Customer/Block/Widget/Dob.php index e456efbc605fa..1a1d5d81bf13d 100644 --- a/app/code/Magento/Customer/Block/Widget/Dob.php +++ b/app/code/Magento/Customer/Block/Widget/Dob.php @@ -127,7 +127,8 @@ protected function getFormFilter() protected function applyOutputFilter($value) { $filter = $this->getFormFilter(); - if ($filter) { + if ($filter && $value) { + $value = date('Y-m-d', $this->getTime()); $value = $filter->outputFilter($value); } return $value; diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 4fc74fa695829..63eb1efa64be6 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -624,6 +624,7 @@ public function resetPassword($email, $resetToken, $newPassword) $customerSecure->setRpToken(null); $customerSecure->setRpTokenCreatedAt(null); $customerSecure->setPasswordHash($this->createPasswordHash($newPassword)); + $this->getAuthentication()->unlock($customer->getId()); $this->sessionManager->destroy(); $this->destroyCustomerSessions($customer->getId()); $this->customerRepository->save($customer); diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index 0d99c1145e81b..86ed633790491 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -353,9 +353,9 @@ - customer_group_code - customer_group_id - class_name + main_table.customer_group_code + main_table.customer_group_id + tax_class_table.class_name @@ -363,9 +363,9 @@ - customer_group_code - customer_group_id - class_name + main_table.customer_group_code + main_table.customer_group_id + tax_class_table.class_name ASC diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index 77e250c5de923..2d44dde215139 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -24,7 +24,7 @@
@@ -43,12 +43,3 @@
- diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index 43e4e92fd0904..6cdb8fc44f665 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -131,7 +131,7 @@
- +
diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index 15df80f360bf7..c4672c48e1f4a 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -232,11 +232,9 @@ define([ if (!_.isEmpty(privateContent)) { countryData = this.get('directory-data'); - countryData.subscribe(function () { - if (_.isEmpty(countryData())) { - customerData.reload(['directory-data'], false); - } - }, this); + if (_.isEmpty(countryData())) { + customerData.reload(['directory-data'], false); + } } }, diff --git a/app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js b/app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js index 3fc65c266e895..c1ca395e46cbb 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js +++ b/app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js @@ -34,7 +34,7 @@ define([ /** Show login popup window */ showModal: function () { - $(this.modalWindow).modal('openModal'); + $(this.modalWindow).modal('openModal').trigger('contentUpdated'); } }; }); diff --git a/app/code/Magento/Customer/view/frontend/web/js/trim-username.js b/app/code/Magento/Customer/view/frontend/web/js/trim-username.js deleted file mode 100644 index 1b6aab6086853..0000000000000 --- a/app/code/Magento/Customer/view/frontend/web/js/trim-username.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'jquery' -], function ($) { - 'use strict'; - - $.widget('mage.trimUsername', { - options: { - cache: {}, - formSelector: 'form', - emailSelector: 'input[type="email"]' - }, - - /** - * Widget initialization - * @private - */ - _create: function () { - // We need to look outside the module for backward compatibility, since someone can already use the module. - // @todo Narrow this selector in 2.3 so it doesn't accidentally finds the email field from the - // newsletter email field or any other "email" field. - this.options.cache.email = $(this.options.formSelector).find(this.options.emailSelector); - this._bind(); - }, - - /** - * Event binding, will monitor change, keyup and paste events. - * @private - */ - _bind: function () { - if (this.options.cache.email.length) { - this._on(this.options.cache.email, { - 'change': this._trimUsername, - 'keyup': this._trimUsername, - 'paste': this._trimUsername - }); - } - }, - - /** - * Trim username - * @private - */ - _trimUsername: function () { - var username = this._getUsername().trim(); - - this.options.cache.email.val(username); - }, - - /** - * Get username value - * @returns {*} - * @private - */ - _getUsername: function () { - return this.options.cache.email.val(); - } - }); - - return $.mage.trimUsername; -}); diff --git a/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html b/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html index 6b3a232cd3e39..ca4f8b4f03b13 100644 --- a/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html +++ b/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html @@ -60,6 +60,7 @@ id="customer-email" type="email" class="input-text" + data-mage-init='{"mage/trim-input":{}}' data-bind="attr: {autocomplete: autocomplete}" data-validate="{required:true, 'validate-email':true}">
diff --git a/app/code/Magento/Deploy/Package/Processor/PreProcessor/Less.php b/app/code/Magento/Deploy/Package/Processor/PreProcessor/Less.php index 8a464ca4bc627..b5fe0c78640e5 100644 --- a/app/code/Magento/Deploy/Package/Processor/PreProcessor/Less.php +++ b/app/code/Magento/Deploy/Package/Processor/PreProcessor/Less.php @@ -188,7 +188,7 @@ private function buildMap($filePath, $packagePath, $contentType) if (!isset($this->map[$filePath])) { $this->map[$filePath] = []; } - array_push($this->map[$filePath], $resolvedMapPath); + $this->map[$filePath][] = $resolvedMapPath; $this->buildMap($resolvedMapPath, $packagePath, $contentType); }; if ($content) { diff --git a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php index 6715ecd681efe..776bef99e7960 100644 --- a/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php +++ b/app/code/Magento/Developer/Console/Command/TablesWhitelistGenerateCommand.php @@ -22,11 +22,6 @@ */ class TablesWhitelistGenerateCommand extends Command { - /** - * Whitelist file name. - */ - const GENERATED_FILE_NAME = 'db_schema_whitelist.json'; - /** * Module name key, that will be used in whitelist generate command. */ diff --git a/app/code/Magento/Developer/Model/Logger/Handler/Syslog.php b/app/code/Magento/Developer/Model/Logger/Handler/Syslog.php new file mode 100644 index 0000000000000..6dc276a696f6f --- /dev/null +++ b/app/code/Magento/Developer/Model/Logger/Handler/Syslog.php @@ -0,0 +1,59 @@ +scopeConfig = $scopeConfig; + $this->deploymentConfig = $deploymentConfig; + } + + /** + * @inheritdoc + */ + public function isHandling(array $record): bool + { + return parent::isHandling($record) + && $this->deploymentConfig->isAvailable() + && $this->scopeConfig->getValue(self::CONFIG_PATH); + } +} diff --git a/app/code/Magento/Developer/Test/Unit/Model/Logger/Handler/SyslogTest.php b/app/code/Magento/Developer/Test/Unit/Model/Logger/Handler/SyslogTest.php new file mode 100644 index 0000000000000..c744645b670b4 --- /dev/null +++ b/app/code/Magento/Developer/Test/Unit/Model/Logger/Handler/SyslogTest.php @@ -0,0 +1,103 @@ +scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class); + $this->deploymentConfigMock = $this->createMock(DeploymentConfig::class); + + $this->model = new Syslog( + $this->scopeConfigMock, + $this->deploymentConfigMock, + 'Magento' + ); + } + + public function testIsHandling(): void + { + $record = [ + 'level' => Monolog::DEBUG, + ]; + + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with(Syslog::CONFIG_PATH) + ->willReturn('1'); + $this->deploymentConfigMock->expects($this->once()) + ->method('isAvailable') + ->willReturn(true); + + $this->assertTrue( + $this->model->isHandling($record) + ); + } + + public function testIsHandlingNotInstalled(): void + { + $record = [ + 'level' => Monolog::DEBUG, + ]; + + $this->scopeConfigMock->expects($this->never()) + ->method('getValue'); + $this->deploymentConfigMock->expects($this->once()) + ->method('isAvailable') + ->willReturn(false); + + $this->assertFalse( + $this->model->isHandling($record) + ); + } + + public function testIsHandlingDisabled(): void + { + $record = [ + 'level' => Monolog::DEBUG, + ]; + + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with(Syslog::CONFIG_PATH) + ->willReturn('0'); + $this->deploymentConfigMock->expects($this->once()) + ->method('isAvailable') + ->willReturn(true); + + $this->assertFalse( + $this->model->isHandling($record) + ); + } +} diff --git a/app/code/Magento/Developer/etc/adminhtml/system.xml b/app/code/Magento/Developer/etc/adminhtml/system.xml index 9663cff72bc9d..aae9913009837 100644 --- a/app/code/Magento/Developer/etc/adminhtml/system.xml +++ b/app/code/Magento/Developer/etc/adminhtml/system.xml @@ -32,6 +32,13 @@ Magento\Config\Model\Config\Source\Yesno + + + + + Magento\Config\Model\Config\Source\Yesno + + diff --git a/app/code/Magento/Developer/etc/di.xml b/app/code/Magento/Developer/etc/di.xml index 2254c94a8a913..21ecf10c1b1e7 100644 --- a/app/code/Magento/Developer/etc/di.xml +++ b/app/code/Magento/Developer/etc/di.xml @@ -7,6 +7,7 @@ --> + diff --git a/app/code/Magento/Eav/etc/db_schema.xml b/app/code/Magento/Eav/etc/db_schema.xml index 24a9d405dd7a5..f930321e5259b 100644 --- a/app/code/Magento/Eav/etc/db_schema.xml +++ b/app/code/Magento/Eav/etc/db_schema.xml @@ -377,7 +377,7 @@
- + diff --git a/app/code/Magento/Eav/etc/db_schema_whitelist.json b/app/code/Magento/Eav/etc/db_schema_whitelist.json index 9c015e0e3b8c5..cf06b06d833d5 100644 --- a/app/code/Magento/Eav/etc/db_schema_whitelist.json +++ b/app/code/Magento/Eav/etc/db_schema_whitelist.json @@ -234,6 +234,7 @@ "PRIMARY": true, "EAV_ATTR_GROUP_ATTR_SET_ID_EAV_ATTR_SET_ATTR_SET_ID": true, "EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_NAME": true, + "EAV_ATTRIBUTE_GROUP_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_CODE": true, "CATALOG_CATEGORY_PRODUCT_ATTRIBUTE_SET_ID_ATTRIBUTE_GROUP_CODE": true } }, @@ -386,4 +387,4 @@ "EAV_FORM_ELEMENT_TYPE_ID_ATTRIBUTE_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/ImportExport/Model/Report/Csv.php b/app/code/Magento/ImportExport/Model/Report/Csv.php index 86c68d7c4df77..7279092265cbb 100644 --- a/app/code/Magento/ImportExport/Model/Report/Csv.php +++ b/app/code/Magento/ImportExport/Model/Report/Csv.php @@ -77,7 +77,7 @@ public function createReport( $outputCsv = $this->createOutputCsvModel($outputFileName); $columnsName = $sourceCsv->getColNames(); - array_push($columnsName, self::REPORT_ERROR_COLUMN_NAME); + $columnsName[] = self::REPORT_ERROR_COLUMN_NAME; $outputCsv->setHeaderCols($columnsName); foreach ($sourceCsv as $rowNum => $rowData) { diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index 70d480a448638..9412b13895599 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -170,6 +170,11 @@ class Multishipping extends \Magento\Framework\DataObject */ private $logger; + /** + * @var \Magento\Framework\Api\DataObjectHelper + */ + private $dataObjectHelper; + /** * Constructor * @@ -227,7 +232,8 @@ public function __construct( \Magento\Quote\Api\Data\CartExtensionFactory $cartExtensionFactory = null, AllowedCountries $allowedCountryReader = null, Multishipping\PlaceOrderFactory $placeOrderFactory = null, - LoggerInterface $logger = null + LoggerInterface $logger = null, + \Magento\Framework\Api\DataObjectHelper $dataObjectHelper = null ) { $this->_eventManager = $eventManager; $this->_scopeConfig = $scopeConfig; @@ -258,6 +264,8 @@ public function __construct( ->get(Multishipping\PlaceOrderFactory::class); $this->logger = $logger ?: ObjectManager::getInstance() ->get(LoggerInterface::class); + $this->dataObjectHelper = $dataObjectHelper ?: ObjectManager::getInstance() + ->get(\Magento\Framework\Api\DataObjectHelper::class); parent::__construct($data); $this->_init(); } @@ -670,7 +678,14 @@ protected function _prepareOrder(\Magento\Quote\Model\Quote\Address $address) $quote->reserveOrderId(); $quote->collectTotals(); - $order = $this->quoteAddressToOrder->convert($address); + $order = $this->_orderFactory->create(); + + $this->dataObjectHelper->mergeDataObjects( + \Magento\Sales\Api\Data\OrderInterface::class, + $order, + $this->quoteAddressToOrder->convert($address) + ); + $order->setQuote($quote); $order->setBillingAddress($this->quoteAddressToOrderAddress->convert($quote->getBillingAddress())); diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php index b2e484e148f43..94c11bef1d311 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php @@ -11,7 +11,9 @@ use Magento\Customer\Api\Data\AddressInterface; use Magento\Customer\Api\Data\AddressSearchResultsInterface; use Magento\Customer\Api\Data\CustomerInterface; -use Magento\Customer\Model\Data\Address; +use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderDefault; +use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderFactory; +use Magento\Quote\Model\Quote\Address; use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteria; @@ -51,6 +53,7 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class MultishippingTest extends \PHPUnit\Framework\TestCase { @@ -119,24 +122,69 @@ class MultishippingTest extends \PHPUnit\Framework\TestCase */ private $quoteRepositoryMock; + /** + * @var OrderFactory|PHPUnit_Framework_MockObject_MockObject + */ + private $orderFactoryMock; + + /** + * @var \Magento\Framework\Api\DataObjectHelper|PHPUnit_Framework_MockObject_MockObject + */ + private $dataObjectHelperMock; + + /** + * @var ToOrder|PHPUnit_Framework_MockObject_MockObject + */ + private $toOrderMock; + + /** + * @var ToOrderAddress|PHPUnit_Framework_MockObject_MockObject + */ + private $toOrderAddressMock; + + /** + * @var ToOrderPayment|PHPUnit_Framework_MockObject_MockObject + */ + private $toOrderPaymentMock; + + /** + * @var PriceCurrencyInterface|PHPUnit_Framework_MockObject_MockObject + */ + private $priceMock; + + /** + * @var ToOrderItem|PHPUnit_Framework_MockObject_MockObject + */ + private $toOrderItemMock; + + /** + * @var PlaceOrderFactory|PHPUnit_Framework_MockObject_MockObject + */ + private $placeOrderFactoryMock; + + /** + * @var Generic|PHPUnit_Framework_MockObject_MockObject + */ + private $sessionMock; + protected function setUp() { $this->checkoutSessionMock = $this->createSimpleMock(Session::class); $this->customerSessionMock = $this->createSimpleMock(CustomerSession::class); - $orderFactoryMock = $this->createSimpleMock(OrderFactory::class); + $this->orderFactoryMock = $this->createSimpleMock(OrderFactory::class); $eventManagerMock = $this->createSimpleMock(ManagerInterface::class); $scopeConfigMock = $this->createSimpleMock(ScopeConfigInterface::class); - $sessionMock = $this->createSimpleMock(Generic::class); + $this->sessionMock = $this->createSimpleMock(Generic::class); $addressFactoryMock = $this->createSimpleMock(AddressFactory::class); - $toOrderMock = $this->createSimpleMock(ToOrder::class); - $toOrderAddressMock = $this->createSimpleMock(ToOrderAddress::class); - $toOrderPaymentMock = $this->createSimpleMock(ToOrderPayment::class); - $toOrderItemMock = $this->createSimpleMock(ToOrderItem::class); + $this->toOrderMock = $this->createSimpleMock(ToOrder::class); + $this->toOrderAddressMock = $this->createSimpleMock(ToOrderAddress::class); + $this->toOrderPaymentMock = $this->createSimpleMock(ToOrderPayment::class); + $this->toOrderItemMock = $this->createSimpleMock(ToOrderItem::class); $storeManagerMock = $this->createSimpleMock(StoreManagerInterface::class); $paymentSpecMock = $this->createSimpleMock(SpecificationInterface::class); $this->helperMock = $this->createSimpleMock(Data::class); $orderSenderMock = $this->createSimpleMock(OrderSender::class); - $priceMock = $this->createSimpleMock(PriceCurrencyInterface::class); + $this->priceMock = $this->createSimpleMock(PriceCurrencyInterface::class); $this->quoteRepositoryMock = $this->createSimpleMock(CartRepositoryInterface::class); $this->filterBuilderMock = $this->createSimpleMock(FilterBuilder::class); $this->searchCriteriaBuilderMock = $this->createSimpleMock(SearchCriteriaBuilder::class); @@ -160,32 +208,44 @@ protected function setUp() ->getMock(); $allowedCountryReaderMock->method('getAllowedCountries') ->willReturn(['EN'=>'EN']); + $this->dataObjectHelperMock = $this->getMockBuilder(\Magento\Framework\Api\DataObjectHelper::class) + ->disableOriginalConstructor() + ->setMethods(['mergeDataObjects']) + ->getMock(); + $this->placeOrderFactoryMock = $this->getMockBuilder(PlaceOrderFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $logger = $this->createSimpleMock(\Psr\Log\LoggerInterface::class); $this->model = new Multishipping( $this->checkoutSessionMock, $this->customerSessionMock, - $orderFactoryMock, + $this->orderFactoryMock, $this->addressRepositoryMock, $eventManagerMock, $scopeConfigMock, - $sessionMock, + $this->sessionMock, $addressFactoryMock, - $toOrderMock, - $toOrderAddressMock, - $toOrderPaymentMock, - $toOrderItemMock, + $this->toOrderMock, + $this->toOrderAddressMock, + $this->toOrderPaymentMock, + $this->toOrderItemMock, $storeManagerMock, $paymentSpecMock, $this->helperMock, $orderSenderMock, - $priceMock, + $this->priceMock, $this->quoteRepositoryMock, $this->searchCriteriaBuilderMock, $this->filterBuilderMock, $this->totalsCollectorMock, $data, $this->cartExtensionFactoryMock, - $allowedCountryReaderMock + $allowedCountryReaderMock, + $this->placeOrderFactoryMock, + $logger, + $this->dataObjectHelperMock ); $this->shippingAssignmentProcessorMock = $this->createSimpleMock(ShippingAssignmentProcessor::class); @@ -365,6 +425,255 @@ public function testSetShippingMethods() $this->model->setShippingMethods($methodsArray); } + /** + * @return void + */ + public function testCreateOrders(): void + { + $addressTotal = 5; + $productType = \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE; + $infoBuyRequest = [ + 'info_buyRequest' => [ + 'product' => '1', + 'qty' => 1, + ], + ]; + $quoteItemId = 1; + $paymentProviderCode = 'checkmo'; + + $simpleProductTypeMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Type\Simple::class) + ->disableOriginalConstructor() + ->setMethods(['getOrderOptions']) + ->getMock(); + $productMock = $this->getProductMock($simpleProductTypeMock); + $simpleProductTypeMock->method('getOrderOptions')->with($productMock)->willReturn($infoBuyRequest); + + $quoteItemMock = $this->getQuoteItemMock($productType, $productMock); + $quoteAddressItemMock = $this->getQuoteAddressItemMock($quoteItemMock, $productType, $infoBuyRequest); + list($shippingAddressMock, $billingAddressMock) = + $this->getQuoteAddressesMock($quoteAddressItemMock, $addressTotal); + $this->setQuoteMockData($paymentProviderCode, $shippingAddressMock, $billingAddressMock); + + $orderAddressMock = $this->createSimpleMock(\Magento\Sales\Api\Data\OrderAddressInterface::class); + $orderPaymentMock = $this->createSimpleMock(\Magento\Sales\Api\Data\OrderPaymentInterface::class); + $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getQuoteItemId']) + ->getMock(); + $orderItemMock->method('getQuoteItemId')->willReturn($quoteItemId); + $orderMock = $this->getOrderMock($orderAddressMock, $orderPaymentMock, $orderItemMock); + + $this->orderFactoryMock->expects($this->once())->method('create')->willReturn($orderMock); + $this->dataObjectHelperMock->expects($this->once())->method('mergeDataObjects') + ->with( + \Magento\Sales\Api\Data\OrderInterface::class, + $orderMock, + $orderMock + )->willReturnSelf(); + $this->priceMock->expects($this->once())->method('round')->with($addressTotal)->willReturn($addressTotal); + + $this->toOrderMock + ->expects($this->once()) + ->method('convert') + ->with($shippingAddressMock) + ->willReturn($orderMock); + $this->toOrderAddressMock->expects($this->exactly(2))->method('convert') + ->withConsecutive( + [$billingAddressMock, []], + [$shippingAddressMock, []] + )->willReturn($orderAddressMock); + $this->toOrderPaymentMock->method('convert')->willReturn($orderPaymentMock); + $this->toOrderItemMock->method('convert')->with($quoteAddressItemMock)->willReturn($orderItemMock); + + $placeOrderServiceMock = $this->getMockBuilder(PlaceOrderDefault::class) + ->disableOriginalConstructor() + ->setMethods(['place']) + ->getMock(); + $placeOrderServiceMock->method('place')->with([$orderMock])->willReturn([]); + $this->placeOrderFactoryMock->method('create')->with($paymentProviderCode)->willReturn($placeOrderServiceMock); + $this->quoteRepositoryMock->method('save')->with($this->quoteMock); + + $this->model->createOrders(); + } + + /** + * @param string $paymentProviderCode + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getPaymentMock(string $paymentProviderCode): PHPUnit_Framework_MockObject_MockObject + { + $abstractMethod = $this->getMockBuilder(AbstractMethod::class) + ->disableOriginalConstructor() + ->setMethods(['isAvailable']) + ->getMockForAbstractClass(); + $abstractMethod->method('isAvailable')->willReturn(true); + + $paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->setMethods(['getMethodInstance', 'getMethod']) + ->getMock(); + $paymentMock->method('getMethodInstance')->willReturn($abstractMethod); + $paymentMock->method('getMethod')->willReturn($paymentProviderCode); + + return $paymentMock; + } + + /** + * @param \Magento\Catalog\Model\Product\Type\Simple|PHPUnit_Framework_MockObject_MockObject $simpleProductTypeMock + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getProductMock($simpleProductTypeMock): PHPUnit_Framework_MockObject_MockObject + { + $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->setMethods(['getTypeInstance']) + ->getMock(); + $productMock->method('getTypeInstance')->willReturn($simpleProductTypeMock); + + return $productMock; + } + + /** + * @param string $productType + * @param \Magento\Catalog\Model\Product|PHPUnit_Framework_MockObject_MockObject $productMock + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getQuoteItemMock($productType, $productMock): PHPUnit_Framework_MockObject_MockObject + { + $quoteItemMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getProductType', 'getProduct']) + ->getMock(); + $quoteItemMock->method('getProductType')->willReturn($productType); + $quoteItemMock->method('getProduct')->willReturn($productMock); + + return $quoteItemMock; + } + + /** + * @param \Magento\Quote\Model\Quote\Item|PHPUnit_Framework_MockObject_MockObject $quoteItemMock + * @param string $productType + * @param array $infoBuyRequest + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getQuoteAddressItemMock( + $quoteItemMock, + string $productType, + array $infoBuyRequest + ): PHPUnit_Framework_MockObject_MockObject { + $quoteAddressItemMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getQuoteItem', 'setProductType', 'setProductOptions', 'getParentItem']) + ->getMock(); + $quoteAddressItemMock->method('getQuoteItem')->willReturn($quoteItemMock); + $quoteAddressItemMock->method('setProductType')->with($productType)->willReturnSelf(); + $quoteAddressItemMock->method('setProductOptions')->willReturn($infoBuyRequest); + $quoteAddressItemMock->method('getParentItem')->willReturn(false); + + return $quoteAddressItemMock; + } + + /** + * @param \Magento\Quote\Model\Quote\Address\Item|PHPUnit_Framework_MockObject_MockObject $quoteAddressItemMock + * @param int $addressTotal + * @return array + */ + private function getQuoteAddressesMock($quoteAddressItemMock, int $addressTotal): array + { + $shippingAddressMock = $this->getMockBuilder(Address::class) + ->disableOriginalConstructor() + ->setMethods( + [ + 'validate', + 'getShippingMethod', + 'getShippingRateByCode', + 'getCountryId', + 'getAddressType', + 'getGrandTotal', + 'getAllItems', + ] + )->getMock(); + $shippingAddressMock->method('validate')->willReturn(true); + $shippingAddressMock->method('getShippingMethod')->willReturn('carrier'); + $shippingAddressMock->method('getShippingRateByCode')->willReturn('code'); + $shippingAddressMock->method('getCountryId')->willReturn('EN'); + $shippingAddressMock->method('getAllItems')->willReturn([$quoteAddressItemMock]); + $shippingAddressMock->method('getAddressType')->willReturn('shipping'); + $shippingAddressMock->method('getGrandTotal')->willReturn($addressTotal); + + $billingAddressMock = $this->getMockBuilder(Address::class) + ->disableOriginalConstructor() + ->setMethods(['validate']) + ->getMock(); + $billingAddressMock->method('validate')->willReturn(true); + + return [$shippingAddressMock, $billingAddressMock]; + } + + /** + * @param string $paymentProviderCode + * @param Address|PHPUnit_Framework_MockObject_MockObject $shippingAddressMock + * @param Address|PHPUnit_Framework_MockObject_MockObject $billingAddressMock + * + * @return void + */ + private function setQuoteMockData(string $paymentProviderCode, $shippingAddressMock, $billingAddressMock): void + { + $quoteId = 1; + $paymentMock = $this->getPaymentMock($paymentProviderCode); + $this->quoteMock->method('getPayment') + ->willReturn($paymentMock); + $this->quoteMock->method('getAllShippingAddresses') + ->willReturn([$shippingAddressMock]); + $this->quoteMock->method('getBillingAddress') + ->willReturn($billingAddressMock); + $this->quoteMock->method('hasVirtualItems') + ->willReturn(false); + $this->quoteMock->expects($this->once())->method('reserveOrderId')->willReturnSelf(); + $this->quoteMock->expects($this->once())->method('collectTotals')->willReturnSelf(); + $this->quoteMock->method('getId')->willReturn($quoteId); + $this->quoteMock->method('setIsActive')->with(false)->willReturnSelf(); + } + + /** + * @param \Magento\Sales\Api\Data\OrderAddressInterface|PHPUnit_Framework_MockObject_MockObject $orderAddressMock + * @param \Magento\Sales\Api\Data\OrderPaymentInterface|PHPUnit_Framework_MockObject_MockObject $orderPaymentMock + * @param \Magento\Sales\Model\Order\Item|PHPUnit_Framework_MockObject_MockObject $orderItemMock + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getOrderMock( + $orderAddressMock, + $orderPaymentMock, + $orderItemMock + ): PHPUnit_Framework_MockObject_MockObject { + $orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class) + ->disableOriginalConstructor() + ->setMethods( + [ + 'setQuote', + 'setBillingAddress', + 'setShippingAddress', + 'setPayment', + 'addItem', + 'getIncrementId', + 'getId', + 'getCanSendNewEmailFlag', + 'getItems', + ] + )->getMock(); + $orderMock->method('setQuote')->with($this->quoteMock); + $orderMock->method('setBillingAddress')->with($orderAddressMock)->willReturnSelf(); + $orderMock->method('setShippingAddress')->with($orderAddressMock)->willReturnSelf(); + $orderMock->method('setPayment')->with($orderPaymentMock)->willReturnSelf(); + $orderMock->method('addItem')->with($orderItemMock)->willReturnSelf(); + $orderMock->method('getIncrementId')->willReturn('1'); + $orderMock->method('getId')->willReturn('1'); + $orderMock->method('getCanSendNewEmailFlag')->willReturn(false); + $orderMock->method('getItems')->willReturn([$orderItemMock]); + + return $orderMock; + } + /** * Tests exception for addresses with country id not in the allowed countries list. * diff --git a/app/code/Magento/MysqlMq/etc/db_schema.xml b/app/code/Magento/MysqlMq/etc/db_schema.xml index 9ef1fc15f1fb5..02757afa53fcd 100644 --- a/app/code/Magento/MysqlMq/etc/db_schema.xml +++ b/app/code/Magento/MysqlMq/etc/db_schema.xml @@ -44,10 +44,10 @@ - - diff --git a/app/code/Magento/MysqlMq/etc/db_schema_whitelist.json b/app/code/Magento/MysqlMq/etc/db_schema_whitelist.json index 9d224cd8cb724..4d5a919320fe9 100644 --- a/app/code/Magento/MysqlMq/etc/db_schema_whitelist.json +++ b/app/code/Magento/MysqlMq/etc/db_schema_whitelist.json @@ -33,9 +33,11 @@ }, "constraint": { "PRIMARY": true, + "QUEUE_MESSAGE_STATUS_MESSAGE_ID_QUEUE_MESSAGE_ID": true, "QUEUE_MESSAGE_ID_QUEUE_MESSAGE_STATUS_MESSAGE_ID": true, + "QUEUE_MESSAGE_STATUS_QUEUE_ID_QUEUE_ID": true, "QUEUE_ID_QUEUE_MESSAGE_STATUS_QUEUE_ID": true, "QUEUE_MESSAGE_STATUS_QUEUE_ID_MESSAGE_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Newsletter/etc/db_schema_whitelist.json b/app/code/Magento/Newsletter/etc/db_schema_whitelist.json index 237c675f5fcca..27a42a55a174c 100644 --- a/app/code/Magento/Newsletter/etc/db_schema_whitelist.json +++ b/app/code/Magento/Newsletter/etc/db_schema_whitelist.json @@ -11,7 +11,8 @@ }, "index": { "NEWSLETTER_SUBSCRIBER_CUSTOMER_ID": true, - "NEWSLETTER_SUBSCRIBER_STORE_ID": true + "NEWSLETTER_SUBSCRIBER_STORE_ID": true, + "NEWSLETTER_SUBSCRIBER_SUBSCRIBER_EMAIL": true }, "constraint": { "PRIMARY": true, @@ -112,4 +113,4 @@ "NLTTR_PROBLEM_SUBSCRIBER_ID_NLTTR_SUBSCRIBER_SUBSCRIBER_ID": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Paypal/view/frontend/web/order-review.js b/app/code/Magento/Paypal/view/frontend/web/order-review.js index 566c9c8da06dc..2155b52f4081b 100644 --- a/app/code/Magento/Paypal/view/frontend/web/order-review.js +++ b/app/code/Magento/Paypal/view/frontend/web/order-review.js @@ -108,7 +108,7 @@ define([ }, /** - * trigger change for the update of shippping methods from server + * trigger change for the update of shipping methods from server */ _updateOrderHandler: function () { $(this.options.shippingSelector).trigger('change'); @@ -297,7 +297,7 @@ define([ this._updateOrderSubmit(true); this._toggleButton(this.options.updateOrderSelector, true); - // form data and callBack updated based on the shippping Form element + // form data and callBack updated based on the shipping Form element if (this.isShippingSubmitForm) { formData = $(this.options.shippingSubmitFormSelector).serialize() + '&isAjax=true'; diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index ad90b75cbb0d5..3b19c6495dd99 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -2021,7 +2021,7 @@ public function getErrors() foreach ($this->getMessages() as $message) { /* @var $error \Magento\Framework\Message\AbstractMessage */ if ($message->getType() == \Magento\Framework\Message\MessageInterface::TYPE_ERROR) { - array_push($errors, $message); + $errors[] = $message; } } return $errors; diff --git a/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php b/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php index 0ad2245a6287e..d3e13334bb3f9 100644 --- a/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php +++ b/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php @@ -93,27 +93,27 @@ public function apply() public function fillQuoteAddressIdInSalesOrderAddress() { $addressCollection = $this->addressCollectionFactory->create(); + $addressCollection->addFieldToFilter('quote_address_id', ['null' => true]); + /** @var \Magento\Sales\Model\Order\Address $orderAddress */ foreach ($addressCollection as $orderAddress) { - if (!$orderAddress->getData('quote_address_id')) { - $orderId = $orderAddress->getParentId(); - $addressType = $orderAddress->getAddressType(); - - /** @var \Magento\Sales\Model\Order $order */ - $order = $this->orderFactory->create()->load($orderId); - $quoteId = $order->getQuoteId(); - $quote = $this->quoteFactory->create()->load($quoteId); - - if ($addressType == \Magento\Sales\Model\Order\Address::TYPE_SHIPPING) { - $quoteAddressId = $quote->getShippingAddress()->getId(); - $orderAddress->setData('quote_address_id', $quoteAddressId); - } elseif ($addressType == \Magento\Sales\Model\Order\Address::TYPE_BILLING) { - $quoteAddressId = $quote->getBillingAddress()->getId(); - $orderAddress->setData('quote_address_id', $quoteAddressId); - } - - $orderAddress->save(); + $orderId = $orderAddress->getParentId(); + $addressType = $orderAddress->getAddressType(); + + /** @var \Magento\Sales\Model\Order $order */ + $order = $this->orderFactory->create()->load($orderId); + $quoteId = $order->getQuoteId(); + $quote = $this->quoteFactory->create()->load($quoteId); + + if ($addressType == \Magento\Sales\Model\Order\Address::TYPE_SHIPPING) { + $quoteAddressId = $quote->getShippingAddress()->getId(); + $orderAddress->setData('quote_address_id', $quoteAddressId); + } elseif ($addressType == \Magento\Sales\Model\Order\Address::TYPE_BILLING) { + $quoteAddressId = $quote->getBillingAddress()->getId(); + $orderAddress->setData('quote_address_id', $quoteAddressId); } + + $orderAddress->save(); } } diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index ac25cdab22f56..35fc8684d9e46 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -120,6 +120,7 @@ Magento\Sales\Model\ResourceModel\Provider\UpdatedIdListProvider + Magento\Sales\Model\ResourceModel\Provider\UpdatedAtListProvider diff --git a/app/code/Magento/SalesRule/Model/Validator.php b/app/code/Magento/SalesRule/Model/Validator.php index 5c76c534ed03b..5c0f97ae0b08b 100644 --- a/app/code/Magento/SalesRule/Model/Validator.php +++ b/app/code/Magento/SalesRule/Model/Validator.php @@ -506,7 +506,7 @@ public function sortItemsByPriority($items, Address $address = null) foreach ($items as $itemKey => $itemValue) { if ($rule->getActions()->validate($itemValue)) { unset($items[$itemKey]); - array_push($itemsSorted, $itemValue); + $itemsSorted[] = $itemValue; } } } diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/Formatter.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/Formatter.js index 0cbca75ec504b..5f05d3f3015ad 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/Formatter.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/Formatter.js @@ -445,7 +445,7 @@ childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block - // elements so never remove single

since that would remove the currrent empty block element where the caret is at + // elements so never remove single

since that would remove the current empty block element where the caret is at if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/dom/DOMUtils.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/dom/DOMUtils.js index 783dbea1cacb9..eb8b4b7ab5d78 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/dom/DOMUtils.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/classes/dom/DOMUtils.js @@ -1106,7 +1106,7 @@ /** * Returns a unique id. This can be useful when generating elements on the fly. - * This method will not check if the element allready exists. + * This method will not check if the element already exists. * * @method uniqueId * @param {String} p Optional prefix to add infront of all ids defaults to "mce_". diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_jquery_src.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_jquery_src.js index b16d0e3ffdbb4..2daf1620a918e 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_jquery_src.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_jquery_src.js @@ -14451,7 +14451,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block - // elements so never remove single

since that would remove the currrent empty block element where the caret is at + // elements so never remove single

since that would remove the current empty block element where the caret is at if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_prototype_src.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_prototype_src.js index 1c7b76cf75c8b..44b3010b0adfd 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_prototype_src.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_prototype_src.js @@ -15301,7 +15301,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block - // elements so never remove single

since that would remove the currrent empty block element where the caret is at + // elements so never remove single

since that would remove the current empty block element where the caret is at if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; diff --git a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_src.js b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_src.js index a1ce5c5d8c32f..46ba27e60f419 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_src.js +++ b/app/code/Magento/Tinymce3/view/base/web/tiny_mce/tiny_mce_src.js @@ -15275,7 +15275,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block - // elements so never remove single

since that would remove the currrent empty block element where the caret is at + // elements so never remove single

since that would remove the current empty block element where the caret is at if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; diff --git a/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php index 195c0fc10dc07..38025f21cdab1 100644 --- a/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php +++ b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php @@ -79,7 +79,7 @@ public function getUrlRewriteId() /** * @param int $urlRewriteId - * @return int + * @return $this */ public function setUrlRewriteId($urlRewriteId) { diff --git a/app/code/Magento/User/Model/Backend/Config/ObserverConfig.php b/app/code/Magento/User/Model/Backend/Config/ObserverConfig.php index c1b7e6a1110f7..6d921dfdcdd65 100644 --- a/app/code/Magento/User/Model/Backend/Config/ObserverConfig.php +++ b/app/code/Magento/User/Model/Backend/Config/ObserverConfig.php @@ -72,7 +72,7 @@ public function getAdminPasswordLifetime() } /** - * Get admin maxiumum security failures from config + * Get admin maximum security failures from config * * @return int */ diff --git a/app/code/Magento/Vault/etc/db_schema.xml b/app/code/Magento/Vault/etc/db_schema.xml index 6975369145776..ed1f2adba2142 100644 --- a/app/code/Magento/Vault/etc/db_schema.xml +++ b/app/code/Magento/Vault/etc/db_schema.xml @@ -30,12 +30,12 @@ - + - + diff --git a/app/code/Magento/Vault/etc/db_schema_whitelist.json b/app/code/Magento/Vault/etc/db_schema_whitelist.json index 256bfcb458c7e..9b5e740fd16e8 100644 --- a/app/code/Magento/Vault/etc/db_schema_whitelist.json +++ b/app/code/Magento/Vault/etc/db_schema_whitelist.json @@ -16,7 +16,9 @@ "constraint": { "PRIMARY": true, "VAULT_PAYMENT_TOKEN_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID": true, + "VAULT_PAYMENT_TOKEN_PAYMENT_METHOD_CODE_CSTR_ID_GATEWAY_TOKEN": true, "UNQ_54DCE14AEAEA03B587F9EF723EB10A10": true, + "VAULT_PAYMENT_TOKEN_PUBLIC_HASH": true, "VAULT_PAYMENT_TOKEN_HASH_UNIQUE_INDEX_PUBLIC_HASH": true } }, @@ -31,4 +33,4 @@ "FK_4ED894655446D385894580BECA993862": true } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php index 94196c9b86534..d89513b50c9c5 100644 --- a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php +++ b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php @@ -132,6 +132,11 @@ private function isTokenExpired(Token $token): bool // other user-type tokens are considered always valid return false; } + + if (empty($tokenTtl)) { + return false; + } + if ($this->dateTime->strToTime($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) { return true; } diff --git a/app/code/Magento/Wishlist/CustomerData/Wishlist.php b/app/code/Magento/Wishlist/CustomerData/Wishlist.php index 85aff60ac6370..eeae07861e22d 100644 --- a/app/code/Magento/Wishlist/CustomerData/Wishlist.php +++ b/app/code/Magento/Wishlist/CustomerData/Wishlist.php @@ -149,6 +149,14 @@ protected function getItemData(\Magento\Wishlist\Model\Item $wishlistItem) */ protected function getImageData($product) { + /*Set variant product if it is configurable product. + It will show variant product image in sidebar instead of configurable product image.*/ + $simpleOption = $product->getCustomOption('simple_product'); + if ($simpleOption !== null) { + $optionProduct = $simpleOption->getProduct(); + $product = $optionProduct; + } + /** @var \Magento\Catalog\Helper\Image $helper */ $helper = $this->imageHelperFactory->create() ->init($product, 'wishlist_sidebar_block'); diff --git a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/lib/forms/_checkbox-radio.less b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/lib/forms/_checkbox-radio.less index 44b6a1568ef9b..82a6f7b2f19bd 100644 --- a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/lib/forms/_checkbox-radio.less +++ b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/lib/forms/_checkbox-radio.less @@ -87,7 +87,7 @@ .form-el-checkbox { &:checked { + .form-label { - &::before { + &:before { content: @checkbox-icon__content; font-family: @icons__font-family; } diff --git a/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less b/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less index 2e8f06c091265..283054e015fc5 100644 --- a/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less +++ b/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less @@ -22,8 +22,8 @@ vertical-align: middle; width: @component-indicator__size; - &::before, - &::after { + &:before, + &:after { background: @color-white; display: block; opacity: 0; @@ -32,7 +32,7 @@ visibility: hidden; } - &::before { + &:before { border: 1px solid @color-gray68; border-radius: 1px; box-shadow: 0 0 2px rgba(0,0,0,.4); @@ -43,7 +43,7 @@ padding: 4px 5px; } - &::after { + &:after { border-color: darken(@color-gray68, 8); border-style: solid; border-width: 1px 0 0 1px; @@ -56,8 +56,8 @@ } &:hover { - &::before, - &::after { + &:before, + &:after { opacity: 1; transition: opacity .2s linear; visibility: visible; @@ -115,7 +115,7 @@ &._tooltip { background: transparent; - margin: 0px 0px 8px 5px; + margin: 0 0 8px 5px; a { width: 21px; diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less index 2dd8463308a2c..08a9b61977922 100644 --- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less @@ -507,6 +507,16 @@ } } + // + // Category page 1 column layout + // --------------------------------------------- + + .catalog-category-view.page-layout-1column { + .column.main { + min-height: inherit; + } + } + } // diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less index e1e23a9ffbb15..3fdd20e34e09a 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less @@ -25,6 +25,7 @@ padding: @block-auth__dropdown__padding; } } + .authentication-wrapper { float: right; margin-top: -1.5*@indent__xl; @@ -94,7 +95,7 @@ padding-top: @indent__xl; position: relative; - &::before { + &:before { .lib-css(height, @block-auth__or-label__size); .lib-css(line-height, @block-auth__or-label__size - 2px); .lib-css(margin, -(@block-auth__or-label__size/2 + 1px) 0 0 -(@block-auth__or-label__size / 2)); @@ -212,7 +213,7 @@ margin: 0; padding: @indent__s 0 0 @indent__xl; - &::before { + &:before { left: 0; top: 50%; } diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less index 4e1156949de3a..3ce46a73a11c4 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less @@ -198,6 +198,7 @@ .payment-option-title { .lib-css(padding-left, @checkout-payment-option-content__padding__xl); } + .payment-option-content { .payment-option-inner { + .actions-toolbar { diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less index e7f0259fc9ce3..0a463a95e3182 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less @@ -188,6 +188,7 @@ } } } + .row-error { td { border-top: none; @@ -285,6 +286,7 @@ .lib-css(max-width, @checkout-shipping-address__max-width); } } + .table-checkout-shipping-method { width: auto; } @@ -324,6 +326,7 @@ } } } + .table-checkout-shipping-method { min-width: 500px; } diff --git a/app/design/frontend/Magento/blank/Magento_GiftRegistry/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_GiftRegistry/web/css/source/_module.less index d05bcec38cbed..03a474012cb0c 100644 --- a/app/design/frontend/Magento/blank/Magento_GiftRegistry/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_GiftRegistry/web/css/source/_module.less @@ -15,6 +15,7 @@ .actions-toolbar:not(:last-child) { margin-bottom: @indent__xl; } + .fieldset { .nested { .field:not(.choice) { diff --git a/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/_module.less index 1e5769f3d7396..66dbb30cb6712 100644 --- a/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Multishipping/web/css/source/_module.less @@ -9,7 +9,8 @@ & when (@media-common = true) { .multicheckout { - &.results, &.success { + &.results, + &.success { h3 { font-size: 1.6rem; margin-bottom: @indent__base; @@ -33,15 +34,18 @@ .shipping-list { .shipping-item { - margin-left:84px; + margin-left: 84px; } + .shipping-label { font-weight: @font-weight__bold; margin-right: @indent__s; } + .shipping-address { font-weight: @font-weight__regular; } + .error-block { color: @color-red10; @@ -49,6 +53,7 @@ font-weight: @font-weight__bold; margin-right: @indent__s; } + .error-description { font-weight: @font-weight__regular; } @@ -62,10 +67,11 @@ .shipping-list { .order-id { - float:left; + float: left; } + .shipping-item { - margin-left:100px; + margin-left: 100px; } } } diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less index 228c6947c938b..501a1d2918d6a 100644 --- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less @@ -747,6 +747,16 @@ } } } + + // + // Category page 1 column layout + // --------------------------------------------- + + .catalog-category-view.page-layout-1column { + .column.main { + min-height: inherit; + } + } } // diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less index 512751df1cb35..d0ce87beb6ad3 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less @@ -296,6 +296,7 @@ } } } + .opc-wrapper { .form-login, .form-shipping-address { @@ -307,6 +308,7 @@ padding-bottom: @indent__base; } } + .table-checkout-shipping-method { width: auto; } @@ -346,6 +348,7 @@ } } } + .table-checkout-shipping-method { min-width: 500px; } diff --git a/app/design/frontend/Magento/luma/Magento_InstantPurchase/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_InstantPurchase/web/css/source/_module.less index 9877f6bbcea23..9ab5148a87264 100644 --- a/app/design/frontend/Magento/luma/Magento_InstantPurchase/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_InstantPurchase/web/css/source/_module.less @@ -1,16 +1,21 @@ +// /** +// * Copyright © Magento, Inc. All rights reserved. +// * See COPYING.txt for license details. +// */ + & when (@media-common = true) { - .box-tocart { - .action.instant-purchase { - &:extend(.abs-button-l all); - &:extend(.abs-button-responsive all); + .box-tocart { + .action.instant-purchase { + &:extend(.abs-button-l all); + &:extend(.abs-button-responsive all); - &:not(:last-child) { - margin-bottom: 15px; - } + &:not(:last-child) { + margin-bottom: 15px; + } - vertical-align: top; + vertical-align: top; + } } - } } // @@ -18,11 +23,11 @@ // _____________________________________________ .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) { - .box-tocart { - .action.instant-purchase { - margin-bottom: 0; - margin-right: 1%; - width: 49%; + .box-tocart { + .action.instant-purchase { + margin-bottom: 0; + margin-right: 1%; + width: 49%; + } } - } } diff --git a/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less index 03ff1fb09a3e4..7662c60734a1b 100644 --- a/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less @@ -8,285 +8,291 @@ // _____________________________________________ & when (@media-common = true) { - .multicheckout { - &.results, &.success { - h3 { - font-size: 1.6rem; - margin-bottom: @indent__base; - margin-top: @indent__l; - a { - color: @text__color; - &:hover { - text-decoration: none; - } - } - } - - ul.orders-list { - list-style: none; - padding-left: 0; - } - - .orders-list { - margin-top: @indent__m; - padding-left: @indent__base - 4px; - - .shipping-list { - .shipping-item { - margin-left:84px; - } - .shipping-label { - font-weight: @font-weight__bold; - margin-right: @indent__s; - } - .shipping-address { - font-weight: @font-weight__regular; - } - .error-block { - color: @color-red10; - .error-label { - font-weight: @font-weight__bold; - margin-right: @indent__s; + .multicheckout { + &.results, + &.success { + h3 { + font-size: 1.6rem; + margin-bottom: @indent__base; + margin-top: @indent__l; + a { + color: @text__color; + &:hover { + text-decoration: none; + } } - .error-description { - font-weight: @font-weight__regular; + } + + ul.orders-list { + list-style: none; + padding-left: 0; + } + + .orders-list { + margin-top: @indent__m; + padding-left: @indent__base - 4px; + + .shipping-list { + .shipping-item { + margin-left: 84px; + } + + .shipping-label { + font-weight: @font-weight__bold; + margin-right: @indent__s; + } + + .shipping-address { + font-weight: @font-weight__regular; + } + + .error-block { + color: @color-red10; + + .error-label { + font-weight: @font-weight__bold; + margin-right: @indent__s; + } + + .error-description { + font-weight: @font-weight__regular; + } + } } - } } - } - .orders-succeed { - .orders-list { - margin-top: 0; + .orders-succeed { + .orders-list { + margin-top: 0; + + .shipping-list { + .order-id { + float: left; + } + .shipping-item { + margin-left: 100px; + } + } + } + } + } - .shipping-list { - .order-id { - float:left; - } - .shipping-item { - margin-left:100px; - } + .title { + margin-bottom: @indent__l; + + strong { + font-weight: @font-weight__regular; } - } } - } - .title { - margin-bottom: @indent__l; + .table-wrapper { + margin-bottom: 0; - strong { - font-weight: @font-weight__regular; - } - } + .action.delete { + display: inline-block; + } + + .col { + .qty { + display: inline-block; + + .input-text { + &:extend(.abs-input-qty all); + } + } - .table-wrapper { - margin-bottom: 0; + .label { + &:extend(.abs-visually-hidden all); + } - .action.delete { - display: inline-block; - } + &.item { + .action.edit { + font-weight: @font-weight__regular; + margin-left: @indent__s; + } + } + } - .col { - .qty { - display: inline-block; + .cart-price { + &:extend(.abs-checkout-cart-price all); + } - .input-text { - &:extend(.abs-input-qty all); - } + .product-item-name { + &:extend(.abs-checkout-product-name all); + } } - .label { - &:extend(.abs-visually-hidden all); + &:not(.address) { + .table-wrapper { + .product-item-name { + margin: 0; + } + } } - &.item { - .action.edit { - font-weight: @font-weight__regular; - margin-left: @indent__s; - } + > .actions-toolbar { + margin-top: @indent__xl; } - } - .cart-price { - &:extend(.abs-checkout-cart-price all); - } + .actions-toolbar { + > .secondary { + display: block; - .product-item-name { - &:extend(.abs-checkout-product-name all); - } - } + .action { + margin-bottom: @indent__m; - &:not(.address) { - .table-wrapper { - .product-item-name { - margin: 0; - } - } - } + &.back { + display: block; + margin-left: 0; + } + } + } - > .actions-toolbar { - margin-top: @indent__xl; - } + > .primary { + margin-right: @indent__s; + } + } - .actions-toolbar { - > .secondary { - display: block; + .action.primary { + &:extend(.abs-button-l all); + } - .action { - margin-bottom: @indent__m; + .item-options { + margin: @indent__s 0 0; - &.back { - display: block; - margin-left: 0; - } + &:extend(.abs-product-options-list all); + &:extend(.abs-add-clearfix all); } - } - > .primary { - margin-right: @indent__s; - } - } + &:extend(.abs-account-blocks all); - .action.primary { - &:extend(.abs-button-l all); - } + .block { + &:extend(.abs-add-clearfix all); - .item-options { - margin: @indent__s 0 0; - - &:extend(.abs-product-options-list all); - &:extend(.abs-add-clearfix all); - } + .methods-shipping { + .item-content { + .fieldset { + > .legend { + &:extend(.abs-visually-hidden all); + } - &:extend(.abs-account-blocks all); + > .legend + br { + &:extend(.abs-no-display all); + } - .block { - &:extend(.abs-add-clearfix all); + > .field { + &:before { + display: none; + } - .methods-shipping { - .item-content { - .fieldset { - > .legend { - &:extend(.abs-visually-hidden all); + .control { + display: inline-block; + } + } + } + } } + } - > .legend + br { - &:extend(.abs-no-display all); - } + .block-title, + .block-content .title { + &:extend(.abs-account-title all); + border-bottom: @border-width__base solid @border-color__base; + padding-bottom: @indent__s; - > .field { - &:before { - display: none; - } + strong { + font-weight: @font-weight__regular; - .control { - display: inline-block; - } + span { + .lib-css(color, @primary__color__light); + } } - } } - } - } - - .block-title, - .block-content .title { - &:extend(.abs-account-title all); - border-bottom: @border-width__base solid @border-color__base; - padding-bottom: @indent__s; - - strong { - font-weight: @font-weight__regular; - span { - .lib-css(color, @primary__color__light); + .block-content { + &:extend(.abs-add-clearfix all); + .title { + border-bottom: none; + padding-bottom: 0; + } } - } - } - .block-content { - &:extend(.abs-add-clearfix all); - .title { - border-bottom: none; - padding-bottom: 0; - } - } + &.order-review { + .block-title > strong { + .lib-font-size(24); + } - &.order-review { - .block-title > strong { - .lib-font-size(24); - } + .block-shipping { + .block-content:not(:last-child) { + margin-bottom: @indent__xl; + } + } - .block-shipping { - .block-content:not(:last-child) { - margin-bottom: @indent__xl; + .error-description { + color: @color-red10; + font-weight: @font-weight__regular; + margin-bottom: @indent__s; + margin-top: -@indent__s; + } } - } - .error-description { - color: @color-red10; - font-weight: @font-weight__regular; - margin-bottom: @indent__s; - margin-top: -@indent__s; - } - } - - .box-title { - span { - margin-right: @indent__s; - } + .box-title { + span { + margin-right: @indent__s; + } - > .action { - margin: 0; - } - } + > .action { + margin: 0; + } + } - .box-shipping-method { - .price { - font-weight: @font-weight__bold; - } - } + .box-shipping-method { + .price { + font-weight: @font-weight__bold; + } + } - .box-billing-method { - .fieldset { - margin: 0; + .box-billing-method { + .fieldset { + margin: 0; - .legend.box-title { - margin: 0 0 @indent__xs; + .legend.box-title { + margin: 0 0 @indent__xs; + } + } } - } - } - .hidden { - &:extend(.abs-no-display all); - } + .hidden { + &:extend(.abs-no-display all); + } - .checkout-review .grand.totals { - .lib-font-size(@font-size__xl); - margin-bottom: @indent__xl; + .checkout-review .grand.totals { + .lib-font-size(@font-size__xl); + margin-bottom: @indent__xl; - .mark { - font-weight: @font-weight__regular; - } + .mark { + font-weight: @font-weight__regular; + } + } } - } - [class^='multishipping-'] { - .nav-sections, - .nav-toggle { - &:extend(.abs-no-display all); - } + [class^='multishipping-'] { + .nav-sections, + .nav-toggle { + &:extend(.abs-no-display all); + } - .logo { - margin-left: 0; + .logo { + margin-left: 0; + } } - } - .multishipping-checkout-success { - .nav-sections { - display: block; + .multishipping-checkout-success { + .nav-sections { + display: block; + } } - } } // @@ -294,200 +300,200 @@ // _____________________________________________ .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) { - .multicheckout { - .data.table { - .address { - &:before { - margin-bottom: @indent__xs; + .multicheckout { + .data.table { + .address { + &:before { + margin-bottom: @indent__xs; + } + } } - } - } - - .product-item-name, - .price-including-tax, - .price-excluding-tax { - display: inline-block; - } - .block-content .box { - &:not(:last-child) { - margin-bottom: @indent__xl; - } + .product-item-name, + .price-including-tax, + .price-excluding-tax { + display: inline-block; + } - &:last-child { - margin-bottom: 0; - } - } + .block-content .box { + &:not(:last-child) { + margin-bottom: @indent__xl; + } - &.order-review { - .box-items { - .data.table { - thead { - display: block; + &:last-child { + margin-bottom: 0; + } + } - tr { - display: block; + &.order-review { + .box-items { + .data.table { + thead { + display: block; + + tr { + display: block; + } + + .col.item { + display: block; + padding: 0; + } + } + } } - .col.item { - display: block; - padding: 0; + .data.table { + &:extend(.abs-checkout-order-review all); } - } } - } - - .data.table { - &:extend(.abs-checkout-order-review all); - } - } - .actions-toolbar { - .action { - margin-bottom: @indent__m; - } + .actions-toolbar { + .action { + margin-bottom: @indent__m; + } - > .primary { - margin-bottom: @indent__m; - margin-right: 0; - } + > .primary { + margin-bottom: @indent__m; + margin-right: 0; + } + } } - } } .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__s) { - .multicheckout { - .actions-toolbar { - .column:not(.sidebar-main) & { - &:extend(.abs-reset-left-margin-desktop-s all); - } + .multicheckout { + .actions-toolbar { + .column:not(.sidebar-main) & { + &:extend(.abs-reset-left-margin-desktop-s all); + } - .secondary { - float: none; - margin-top: 11px; - text-align: right; + .secondary { + float: none; + margin-top: 11px; + text-align: right; - .action { - margin-left: @indent__s; + .action { + margin-left: @indent__s; - &.back { - display: block; - float: left; - } + &.back { + display: block; + float: left; + } + } + } } - } - } - - .item-options { - margin: @indent__base 0 0; - } - - .block-content .box { - margin-bottom: 0; - } - .block-shipping { - .box { - &:extend(.abs-add-box-sizing-desktop-s all); - float: left; - width: 25%; - } + .item-options { + margin: @indent__base 0 0; + } - .box-shipping-method { - padding-left: @indent__m; - padding-right: @indent__m; - width: 50%; + .block-content .box { + margin-bottom: 0; + } - .fieldset { - .legend { - &:extend(.abs-reset-left-margin-desktop-s all); - } + .block-shipping { + .box { + &:extend(.abs-add-box-sizing-desktop-s all); + float: left; + width: 25%; + } - .field { - &:before { - display: none; + .box-shipping-method { + padding-left: @indent__m; + padding-right: @indent__m; + width: 50%; + + .fieldset { + .legend { + &:extend(.abs-reset-left-margin-desktop-s all); + } + + .field { + &:before { + display: none; + } + } + } } - } } - } - } - .block-billing { - &:extend(.abs-add-clearfix-desktop-s all); - .box-billing-address { - &:extend(.abs-add-box-sizing-desktop-s all); - float: left; - width: 25%; - } - - .box-billing-method { - &:extend(.abs-add-box-sizing-desktop-s all); - float: left; - padding-left: @indent__m; - width: 50%; - } - } + .block-billing { + &:extend(.abs-add-clearfix-desktop-s all); + .box-billing-address { + &:extend(.abs-add-box-sizing-desktop-s all); + float: left; + width: 25%; + } - &.form.address { - .table-wrapper { - .applicable { - margin: 7px 0 0; + .box-billing-method { + &:extend(.abs-add-box-sizing-desktop-s all); + float: left; + padding-left: @indent__m; + width: 50%; + } } - } - } - &.order-review { - .box-items { - clear: left; - float: none; - padding-top: @indent__xl; - width: auto; - } - - .col.item { - width: 75%; - } - } + &.form.address { + .table-wrapper { + .applicable { + margin: 7px 0 0; + } + } + } - // Payment methods - .methods-payment { - .item-content > .fieldset { - width: auto; + &.order-review { + .box-items { + clear: left; + float: none; + padding-top: @indent__xl; + width: auto; + } - .field { - &.cvv { - display: inline-block; - width: auto; - } + .col.item { + width: 75%; + } } - } - .fieldset > .field:not(.choice) { - > .label { - float: none; - margin-bottom: 8px; - text-align: left; - width: auto; - } + // Payment methods + .methods-payment { + .item-content > .fieldset { + width: auto; + + .field { + &.cvv { + display: inline-block; + width: auto; + } + } + } + + .fieldset > .field:not(.choice) { + > .label { + float: none; + margin-bottom: 8px; + text-align: left; + width: auto; + } - &:not(.cvv) { - .control { - width: 100%; - } + &:not(.cvv) { + .control { + width: 100%; + } + } + } } - } } - } } .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { - .multishipping-checkout-success { - .nav-toggle { - display: block; - } + .multishipping-checkout-success { + .nav-toggle { + display: block; + } - .logo { - margin-left: @indent__xl; + .logo { + margin-left: @indent__xl; + } } - } } diff --git a/app/etc/di.xml b/app/etc/di.xml index 6e3dabaa0751f..76f9e8f590f1c 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -249,9 +249,15 @@ Magento\Framework\Logger\Handler\System Magento\Framework\Logger\Handler\Debug + Magento\Framework\Logger\Handler\Syslog + + + Magento + + Magento\Framework\Model\ActionValidator\RemoveAction\Proxy diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index e1e6ff79e75ce..e140305db4dcd 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -10,6 +10,7 @@ use Magento\Store\Model\Store; use Magento\CatalogInventory\Api\Data\StockItemInterface; use Magento\Store\Model\Website; +use Magento\Store\Model\WebsiteRepository; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; use Magento\Framework\Api\FilterBuilder; @@ -17,6 +18,7 @@ use Magento\Framework\Api\SortOrder; use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; +use Magento\Framework\Exception\NoSuchEntityException; /** * @magentoAppIsolation enabled @@ -136,6 +138,24 @@ public function productCreationProvider() ]; } + /** + * Load website by website code + * + * @param $websiteCode + * @return Website + */ + private function loadWebsiteByCode($websiteCode) + { + $websiteRepository = Bootstrap::getObjectManager()->get(WebsiteRepository::class); + try { + $website = $websiteRepository->get($websiteCode); + } catch (NoSuchEntityException $e) { + $this->fail("Couldn`t load website: {$websiteCode}"); + } + + return $website; + } + /** * Test removing association between product and website 1 * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php @@ -144,12 +164,7 @@ public function testUpdateWithDeleteWebsites() { $productBuilder[ProductInterface::SKU] = 'unique-simple-azaza'; /** @var Website $website */ - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(Website::class); - $website->load('second_website', 'code'); - - if (!$website->getId()) { - $this->fail("Couldn`t load website"); - } + $website = $this->loadWebsiteByCode('second_website'); $websitesData = [ 'website_ids' => [ @@ -171,13 +186,6 @@ public function testUpdateWithDeleteWebsites() public function testDeleteAllWebsiteAssociations() { $productBuilder[ProductInterface::SKU] = 'unique-simple-azaza'; - /** @var Website $website */ - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(Website::class); - $website->load('second_website', 'code'); - - if (!$website->getId()) { - $this->fail("Couldn`t load website"); - } $websitesData = [ 'website_ids' => [] @@ -198,14 +206,9 @@ public function testCreateWithMultipleWebsites() $productBuilder = $this->getSimpleProductData(); $productBuilder[ProductInterface::SKU] = 'test-test-sku'; $productBuilder[ProductInterface::TYPE_ID] = 'simple'; - /** @var Website $website */ - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(Website::class); - $website->load('test_website', 'code'); + $website = $this->loadWebsiteByCode('test_website'); - if (!$website->getId()) { - $this->fail("Couldn`t load website"); - } $websitesData = [ 'website_ids' => [ 1, @@ -218,6 +221,84 @@ public function testCreateWithMultipleWebsites() $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"], $websitesData["website_ids"] ); + $this->deleteProduct($productBuilder[ProductInterface::SKU]); + } + + /** + * Add product associated with website that is not associated with default store + * + * @magentoApiDataFixture Magento/Store/_files/second_website_with_two_stores.php + */ + public function testCreateWithNonDefaultStoreWebsite() + { + $productBuilder = $this->getSimpleProductData(); + $productBuilder[ProductInterface::SKU] = 'test-sku-second-site-123'; + $productBuilder[ProductInterface::TYPE_ID] = 'simple'; + /** @var Website $website */ + $website = $this->loadWebsiteByCode('test'); + + $websitesData = [ + 'website_ids' => [ + $website->getId(), + ] + ]; + $productBuilder[ProductInterface::EXTENSION_ATTRIBUTES_KEY] = $websitesData; + $response = $this->saveProduct($productBuilder); + $this->assertEquals( + $websitesData["website_ids"], + $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"] + ); + $this->deleteProduct($productBuilder[ProductInterface::SKU]); + } + + /** + * Update product to be associated with website that is not associated with default store + * + * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php + * @magentoApiDataFixture Magento/Store/_files/second_website_with_two_stores.php + */ + public function testUpdateWithNonDefaultStoreWebsite() + { + $productBuilder[ProductInterface::SKU] = 'unique-simple-azaza'; + /** @var Website $website */ + $website = $this->loadWebsiteByCode('test'); + + $this->assertNotContains(Store::SCOPE_DEFAULT, $website->getStoreCodes()); + + $websitesData = [ + 'website_ids' => [ + $website->getId(), + ] + ]; + $productBuilder[ProductInterface::EXTENSION_ATTRIBUTES_KEY] = $websitesData; + $response = $this->updateProduct($productBuilder); + $this->assertEquals( + $websitesData["website_ids"], + $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"] + ); + } + + /** + * Update product without specifying websites + * + * @magentoApiDataFixture Magento/Catalog/_files/product_with_two_websites.php + */ + public function testUpdateWithoutWebsiteIds() + { + $productBuilder[ProductInterface::SKU] = 'unique-simple-azaza'; + $originalProduct = $this->getProduct($productBuilder[ProductInterface::SKU]); + $newName = 'Updated Product'; + + $productBuilder[ProductInterface::NAME] = $newName; + $response = $this->updateProduct($productBuilder); + $this->assertEquals( + $newName, + $response[ProductInterface::NAME] + ); + $this->assertEquals( + $originalProduct[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"], + $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]["website_ids"] + ); } /** @@ -727,8 +808,7 @@ public function testGetList() */ public function testGetListWithFilteringByWebsite() { - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(Website::class); - $website->load('test', 'code'); + $website = $this->loadWebsiteByCode('test'); $searchCriteria = [ 'searchCriteria' => [ 'filter_groups' => [ diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json index da431fcf8a252..e49824d17df80 100644 --- a/dev/tests/functional/composer.json +++ b/dev/tests/functional/composer.json @@ -4,7 +4,7 @@ }, "require": { "php": "~7.1.3||~7.2.0", - "magento/mtf": "1.0.0-rc60", + "magento/mtf": "1.0.0-rc61", "allure-framework/allure-phpunit": "~1.2.0", "doctrine/annotations": "1.4.*", "phpunit/phpunit": "~6.5.0", diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php index e25a5c1f719d0..1ef9267e73785 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/AuthenticationPopup.php @@ -69,6 +69,7 @@ public function createAccount() */ public function loginCustomer(Customer $customer) { + sleep(10); $this->fill($customer); $this->_rootElement->find($this->login)->click(); $this->waitForElementNotVisible($this->loadingMask); diff --git a/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForBackendObserverTest.php b/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForBackendObserverTest.php new file mode 100644 index 0000000000000..c0a720229a00d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForBackendObserverTest.php @@ -0,0 +1,60 @@ +objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + } + + /** + * @magentoDataFixture Magento/Captcha/_files/failed_logins_backend.php + */ + public function testLoginAttemptsRemovedAfterSuccessfulLogin() + { + $login = 'mageadmin'; + $userFactory = $this->objectManager->get(UserFactory::class); + $captchaLogFactory = $this->objectManager->get(LogFactory::class); + $eventManager = $this->objectManager->get(ManagerInterface::class); + + /** @var User $user */ + $user = $userFactory->create(); + $user->setUserName($login); + + $eventManager->dispatch( + 'backend_auth_user_login_success', + ['user' => $user] + ); + + /** + * @var CaptchaLog $captchaLog + */ + $captchaLog = $captchaLogFactory->create(); + + self::assertEquals(0, $captchaLog->countAttemptsByUserLogin($login)); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend.php b/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend.php new file mode 100644 index 0000000000000..7130cdfca57d7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend.php @@ -0,0 +1,17 @@ +get(LogFactory::class); + +/** @var Log $captchaLog */ +$captchaLog = $logFactory->create(); +$captchaLog->logAttempt('mageadmin'); diff --git a/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend_rollback.php b/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend_rollback.php new file mode 100644 index 0000000000000..12a16027e1e5c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Captcha/_files/failed_logins_backend_rollback.php @@ -0,0 +1,17 @@ +get(LogFactory::class); + +/** @var Log $captchaLog */ +$captchaLog = $logFactory->create(); +$captchaLog->deleteUserAttempts('mageadmin'); diff --git a/dev/tests/integration/testsuite/Magento/Setup/Declaration/WhitelistDeclarationTest.php b/dev/tests/integration/testsuite/Magento/Setup/Declaration/WhitelistDeclarationTest.php new file mode 100644 index 0000000000000..6b92e687284db --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Setup/Declaration/WhitelistDeclarationTest.php @@ -0,0 +1,162 @@ +create(ResourceConnection::class); + $objectManager->removeSharedInstance(ResourceConnection::class); + $objectManager->addSharedInstance($resourceConnection, ResourceConnection::class); + $this->componentRegistrar = $objectManager->get(ComponentRegistrarInterface::class); + $this->schemaConfig = $objectManager->create(SchemaConfigInterface::class); + } + + /** + * Checks that all declared table elements also declared into whitelist declaration. + * + * @appIsolation + * @throws \Exception + */ + public function testConstraintsAndIndexesAreWhitelisted() + { + $undeclaredElements = []; + $resultMessage = "New table elements that do not exist in the whitelist declaration:\n"; + $whitelistTables = $this->getWhiteListTables(); + $declarativeSchema = $this->schemaConfig->getDeclarationConfig(); + + foreach ($declarativeSchema->getTables() as $schemaTable) { + $tableNameWithoutPrefix = $schemaTable->getNameWithoutPrefix(); + foreach ($schemaTable->getConstraints() as $constraint) { + $constraintNameWithoutPrefix = $constraint->getNameWithoutPrefix(); + if (isset($whitelistTables[$tableNameWithoutPrefix][Constraint::TYPE][$constraintNameWithoutPrefix])) { + continue; + } + + $undeclaredElements[$tableNameWithoutPrefix][Constraint::TYPE][] = $constraintNameWithoutPrefix; + } + + foreach ($schemaTable->getIndexes() as $index) { + $indexNameWithoutPrefix = $index->getNameWithoutPrefix(); + if (isset($whitelistTables[$tableNameWithoutPrefix][Index::TYPE][$indexNameWithoutPrefix])) { + continue; + } + + $undeclaredElements[$tableNameWithoutPrefix][Index::TYPE][] = $indexNameWithoutPrefix; + } + } + + $undeclaredElements = $this->filterUndeclaredElements($undeclaredElements); + + if (!empty($undeclaredElements)) { + $resultMessage .= json_encode($undeclaredElements, JSON_PRETTY_PRINT); + } + + $this->assertEmpty($undeclaredElements, $resultMessage); + } + + /** + * Excludes ignored elements from the list of undeclared table elements. + * + * @param array $undeclaredElements + * @return array + */ + private function filterUndeclaredElements(array $undeclaredElements): array + { + $files = Files::getFiles([__DIR__ . '/_files/ignore_whitelisting'], '*.json'); + $ignoredElements = []; + foreach ($files as $filePath) { + $ignoredElements = array_merge_recursive( + $ignoredElements, + json_decode(file_get_contents($filePath), true) + ); + } + + return $this->arrayRecursiveDiff($undeclaredElements, $ignoredElements); + } + + /** + * Performs a recursive comparison of two arrays. + * + * @param array $array1 + * @param array $array2 + * @return array + */ + private function arrayRecursiveDiff(array $array1, array $array2): array + { + $diffResult = []; + + foreach ($array1 as $key => $value) { + if (array_key_exists($key, $array2)) { + if (is_array($value)) { + $recursiveDiffResult = $this->arrayRecursiveDiff($value, $array2[$key]); + if (count($recursiveDiffResult)) { + $diffResult[$key] = $recursiveDiffResult; + } + } else { + if (!in_array($value, $array2)) { + $diffResult[] = $value; + } + } + } else { + $diffResult[$key] = $value; + } + } + + return $diffResult; + } + + /** + * @return array + */ + private function getWhiteListTables(): array + { + $whiteListTables = []; + + foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $path) { + $whiteListPath = $path . DIRECTORY_SEPARATOR . 'etc' . + DIRECTORY_SEPARATOR . 'db_schema_whitelist.json'; + + if (file_exists($whiteListPath)) { + $whiteListTables = array_replace_recursive( + $whiteListTables, + json_decode(file_get_contents($whiteListPath), true) + ); + } + } + + return $whiteListTables; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Setup/Declaration/_files/ignore_whitelisting/ce.json b/dev/tests/integration/testsuite/Magento/Setup/Declaration/_files/ignore_whitelisting/ce.json new file mode 100644 index 0000000000000..881481ab407bc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Setup/Declaration/_files/ignore_whitelisting/ce.json @@ -0,0 +1,7 @@ +{ + "patch_list": { + "constraint": [ + "PRIMARY" + ] + } +} diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml index c57581d7f1621..5b8a4c8f37c99 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema.xml @@ -30,7 +30,7 @@ nullable="true"/> - + @@ -53,14 +53,15 @@ - + - - + diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema_whitelist.json index 14b4887b662e2..49866f645d09d 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema_whitelist.json +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/etc/db_schema_whitelist.json @@ -23,7 +23,7 @@ "int_disabled_auto_increment": true }, "constraint": { - "unique_null_key": true + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true } }, "test_table": { @@ -46,11 +46,11 @@ "varbinary_rename": true }, "index": { - "speedup_index": true + "TEST_TABLE_TINYINT_BIGINT": true }, "constraint": { - "some_unique_key": true, - "some_foreign_key": true + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true } }, "store": { @@ -59,7 +59,7 @@ "store_owner": true }, "constraint": { - "STORE_OWNER_ID_REFERENCE": true + "STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID": true } }, "store_owner": { diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php index a48a0a21b4f9b..a69e456ec4a8b 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_modification.php @@ -7,7 +7,7 @@ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(15) unsigned DEFAULT NULL, `int_disabled_auto_increment` smallint(12) unsigned DEFAULT \'0\', - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'reference_table' => 'CREATE TABLE `reference_table` ( `tinyint_ref` tinyint(7) NOT NULL AUTO_INCREMENT, @@ -39,8 +39,9 @@ `mediumblob` mediumblob, `blob` blob, `boolean` tinyint(1) DEFAULT \'1\', - UNIQUE KEY `some_unique_key` (`smallint`,`bigint`), - KEY `speedup_index` (`tinyint`,`bigint`), - CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION + UNIQUE KEY `TEST_TABLE_SMALLINT_BIGINT` (`smallint`,`bigint`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) +REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8', ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php index dea57d5d9a803..0091b89845a73 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/column_removal.php @@ -6,7 +6,7 @@ return [ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) unsigned NOT NULL AUTO_INCREMENT, - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'reference_table' => 'CREATE TABLE `reference_table` ( `tinyint_ref` tinyint(7) NOT NULL AUTO_INCREMENT, @@ -37,8 +37,9 @@ `blob` blob, `boolean` tinyint(1) DEFAULT NULL, `varbinary_rename` varbinary(255) DEFAULT \'10101\', - UNIQUE KEY `some_unique_key` (`smallint`,`bigint`), - KEY `speedup_index` (`tinyint`,`bigint`), - CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION + UNIQUE KEY `TEST_TABLE_SMALLINT_BIGINT` (`smallint`,`bigint`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) +REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8', ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php index 26ba8848095b3..01e007edb7684 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.php @@ -7,7 +7,7 @@ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) unsigned NOT NULL AUTO_INCREMENT, `int_disabled_auto_increment` smallint(12) unsigned DEFAULT \'0\', - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'reference_table' => 'CREATE TABLE `reference_table` ( `tinyint_ref` tinyint(7) NOT NULL AUTO_INCREMENT, @@ -23,7 +23,7 @@ `bigint_not_default_not_nullable` bigint(2) unsigned NOT NULL, `smallint_ref` smallint(254) NOT NULL DEFAULT \'0\', PRIMARY KEY (`tinyint_ref`,`smallint_ref`), - UNIQUE KEY `smallint_unique` (`smallint_ref`) + UNIQUE KEY `REFERENCE_TABLE_SMALLINT_REF` (`smallint_ref`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'test_table' => 'CREATE TABLE `test_table` ( `smallint` smallint(3) DEFAULT NULL, @@ -43,16 +43,16 @@ `boolean` tinyint(1) DEFAULT NULL, `integer_main` int(12) unsigned DEFAULT NULL, `smallint_main` smallint(254) NOT NULL DEFAULT \'0\', - UNIQUE KEY `some_unique_key` (`smallint`,`float`), - UNIQUE KEY `some_unique_key_2` (`double`), - KEY `some_foreign_key_new` (`smallint_main`), - KEY `some_foreign_key_without_action` (`integer_main`), - KEY `speedup_index_renamed` (`tinyint`,`bigint`), - CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) -ON DELETE SET NULL, - CONSTRAINT `some_foreign_key_new` FOREIGN KEY (`smallint_main`) REFERENCES `reference_table` (`smallint_ref`) -ON DELETE CASCADE, - CONSTRAINT `some_foreign_key_without_action` FOREIGN KEY (`integer_main`) REFERENCES `auto_increment_test` -(`int_auto_increment_with_nullable`) ON DELETE CASCADE + UNIQUE KEY `TEST_TABLE_SMALLINT_FLOAT` (`smallint`,`float`), + UNIQUE KEY `TEST_TABLE_DOUBLE` (`double`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + KEY `TEST_TABLE_SMALLINT_MAIN_REFERENCE_TABLE_SMALLINT_REF` (`smallint_main`), + KEY `FK_FB77604C299EB8612D01E4AF8D9931F2` (`integer_main`), + CONSTRAINT `FK_FB77604C299EB8612D01E4AF8D9931F2` FOREIGN KEY (`integer_main`) +REFERENCES `auto_increment_test` (`int_auto_increment_with_nullable`) ON DELETE CASCADE, + CONSTRAINT `TEST_TABLE_SMALLINT_MAIN_REFERENCE_TABLE_SMALLINT_REF` FOREIGN KEY (`smallint_main`) +REFERENCES `reference_table` (`smallint_ref`) ON DELETE CASCADE, + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) +REFERENCES `reference_table` (`tinyint_ref`) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8', ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php index 82f945070443f..3e807c25e3519 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/installation.php @@ -7,7 +7,7 @@ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) unsigned NOT NULL AUTO_INCREMENT, `int_disabled_auto_increment` smallint(12) unsigned DEFAULT \'0\', - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'reference_table' => 'CREATE TABLE `reference_table` ( `tinyint_ref` tinyint(7) NOT NULL AUTO_INCREMENT, @@ -39,8 +39,9 @@ `mediumblob` mediumblob, `blob` blob, `boolean` tinyint(1) DEFAULT NULL, - UNIQUE KEY `some_unique_key` (`smallint`,`bigint`), - KEY `speedup_index` (`tinyint`,`bigint`), - CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION + UNIQUE KEY `TEST_TABLE_SMALLINT_BIGINT` (`smallint`,`bigint`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) +REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8', ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php index aa80af695cc99..f5b98ce8a2735 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.php @@ -10,8 +10,9 @@ 'before' => [ 'store' => 'CREATE TABLE `store` ( `store_owner_id` smallint(5) DEFAULT NULL COMMENT \'Store Owner Reference\', - KEY `STORE_OWNER_ID_REFERENCE` (`store_owner_id`), - CONSTRAINT `STORE_OWNER_ID_REFERENCE` FOREIGN KEY (`store_owner_id`) REFERENCES `store_owner` (`owner_id`) ON DELETE SET NULL + KEY `STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID` (`store_owner_id`), + CONSTRAINT `STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID` FOREIGN KEY (`store_owner_id`) +REFERENCES `store_owner` (`owner_id`) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8', 'store_owner' => 'CREATE TABLE `store_owner` ( `owner_id` smallint(5) NOT NULL AUTO_INCREMENT, diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php index 3b607574d167a..7bd0213c6590d 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.php @@ -7,6 +7,6 @@ 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) unsigned NOT NULL AUTO_INCREMENT, `int_disabled_auto_increment` smallint(12) unsigned DEFAULT \'0\', - UNIQUE KEY `unique_null_key` (`int_auto_increment_with_nullable`) + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8' ]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.php index 43680b4218f66..e642e57701149 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.php @@ -22,7 +22,7 @@ CREATE TABLE `auto_increment_test` ( `int_auto_increment_with_nullable` int(12) UNSIGNED NOT NULL AUTO_INCREMENT , `int_disabled_auto_increment` smallint(12) UNSIGNED NULL DEFAULT 0 , -CONSTRAINT `unique_null_key` UNIQUE KEY (`int_auto_increment_with_nullable`) +CONSTRAINT `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` UNIQUE KEY (`int_auto_increment_with_nullable`) ) ENGINE=innodb DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci CREATE TABLE `test_table` ( @@ -41,9 +41,9 @@ `mediumblob` mediumblob NULL , `blob` blob NULL , `boolean` BOOLEAN NULL , -CONSTRAINT `some_unique_key` UNIQUE KEY (`smallint`,`bigint`), -CONSTRAINT `some_foreign_key` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION, -INDEX `speedup_index` (`tinyint`,`bigint`) +CONSTRAINT `TEST_TABLE_SMALLINT_BIGINT` UNIQUE KEY (`smallint`,`bigint`), +CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION, +INDEX `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`) ) ENGINE=innodb DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci CREATE TABLE `patch_list` ( diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php index e912d9fb96f47..76fcf6b2fad11 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/foreign_key_interpreter_result.php @@ -31,9 +31,9 @@ ], ], 'constraint' => [ - 'some_foreign_key' => [ + 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ 'type' => 'foreign', - 'name' => 'some_foreign_key', + 'name' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php index 7aaf37ba156f5..cd42a1e8fc360 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/valid_xml_revision_1.php @@ -120,12 +120,12 @@ ], ], 'constraint' => [ - 'unique_null_key' => [ + 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE' => [ 'column' => [ 'int_auto_increment_with_nullable' => 'int_auto_increment_with_nullable', ], 'type' => 'unique', - 'name' => 'unique_null_key', + 'name' => 'AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE', ], ], 'name' => 'auto_increment_test', @@ -225,17 +225,17 @@ ], ], 'constraint' => [ - 'some_unique_key' => [ + 'TEST_TABLE_SMALLINT_BIGINT' => [ 'column' => [ 'smallint' => 'smallint', 'bigint' => 'bigint', ], 'type' => 'unique', - 'name' => 'some_unique_key', + 'name' => 'TEST_TABLE_SMALLINT_BIGINT', ], - 'some_foreign_key' => [ + 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF' => [ 'type' => 'foreign', - 'name' => 'some_foreign_key', + 'name' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', 'column' => 'tinyint', 'table' => 'test_table', 'referenceTable' => 'reference_table', @@ -244,12 +244,12 @@ ], ], 'index' => [ - 'speedup_index' => [ + 'TEST_TABLE_TINYINT_BIGINT' => [ 'column' => [ 'tinyint' => 'tinyint', 'bigint' => 'bigint', ], - 'name' => 'speedup_index', + 'name' => 'TEST_TABLE_TINYINT_BIGINT', 'indexType' => 'btree', ], ], diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/InstallSchema.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/InstallSchema.php new file mode 100644 index 0000000000000..22cfcd1fa2870 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/InstallSchema.php @@ -0,0 +1,126 @@ +startSetup(); + + //Create first table + $table = $installer->getConnection() + ->newTable($installer->getTable('reference_table')) + ->addColumn( + 'smallint_ref', + \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + 3, + ['primary' => true, 'identity' => true, 'nullable' => false], + 'Smallint' + ) + ->setComment('Reference table'); + $installer->getConnection()->createTable($table); + + $testTable = $installer->getConnection()->newTable($installer->getTable('test_table')) + ->addColumn( + 'smallint', + \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + 2, + ['nullable' => true, 'default' => 0], + 'Smallint' + ) + ->addColumn( + 'bigint', + \Magento\Framework\DB\Ddl\Table::TYPE_BIGINT, + 10, + ['nullable' => true, 'unsigned' => false, 'default' => 0], + 'Bigint' + ) + ->addColumn( + 'float', + \Magento\Framework\DB\Ddl\Table::TYPE_FLOAT, + null, + ['default' => 0], + 'Float' + ) + ->addColumn( + 'date', + \Magento\Framework\DB\Ddl\Table::TYPE_DATE, + null, + [], + 'Date' + ) + ->addColumn( + 'timestamp', + \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, + null, + ['default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE], + 'Timestamp' + ) + ->addColumn( + 'mediumtext', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 11222222, + [], + 'Mediumtext' + ) + ->addColumn( + 'varchar', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 254, + ['nullable' => true], + 'Varchar' + ) + ->addColumn( + 'boolean', + \Magento\Framework\DB\Ddl\Table::TYPE_BOOLEAN, + 1, + [], + 'Boolean' + ) + ->addIndex( + $installer->getIdxName('test_table', ['smallint', 'bigint']), + ['smallint', 'bigint'], + ['type' => \Magento\Framework\DB\Adapter\Pdo\Mysql::INDEX_TYPE_UNIQUE] + ) + ->addIndex( + $installer->getIdxName('test_table', ['bigint']), + ['bigint'] + ) + ->addForeignKey( + $installer->getFkName( + $installer->getTable('test_table'), + 'smallint', + 'reference_table', + 'smallint_ref' + ), + 'smallint', + $installer->getTable('reference_table'), + 'smallint_ref', + \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE + ) + ->setComment('Test Table'); + $installer->getConnection()->createTable($testTable); + + $installer->endSetup(); + } +} diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml new file mode 100644 index 0000000000000..7384c4ed7baab --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/base_update/db_schema.xml @@ -0,0 +1,36 @@ + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+
diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml index 242b555a14949..4d3d51b9c0237 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/before_rollback/db_schema.xml @@ -10,7 +10,7 @@ - +
diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml index a748af135c209..0adcd5c52f962 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_modifications/db_schema.xml @@ -29,7 +29,7 @@ - + @@ -52,14 +52,15 @@ - + - - + diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml index e7361dd28fc0a..4b78f436eab37 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema.xml @@ -27,7 +27,7 @@ - +
@@ -50,14 +50,15 @@ - + - - + diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema_whitelist.json index 890fea33106b7..9105a2b0b25cb 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema_whitelist.json +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/column_removals/db_schema_whitelist.json @@ -23,7 +23,7 @@ "int_disabled_auto_increment": true }, "constraint": { - "unique_null_key": true + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true } }, "test_table": { @@ -46,11 +46,11 @@ "varbinary_rename": true }, "index": { - "speedup_index": true + "TEST_TABLE_TINYINT_BIGINT": true }, "constraint": { - "some_unique_key": true, - "some_foreign_key": true + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true } } } diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml index 97f1862e14028..68f2810e8eed7 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema.xml @@ -26,7 +26,7 @@ - + @@ -35,7 +35,7 @@ nullable="true"/> - + @@ -60,21 +60,23 @@ - + - + - - - + diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema_whitelist.json index bcae522f68995..16ff756ef552a 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema_whitelist.json +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/constraint_modifications/db_schema_whitelist.json @@ -23,7 +23,7 @@ "int_disabled_auto_increment": true }, "constraint": { - "unique_null_key": true + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true } }, "test_table": { @@ -46,11 +46,11 @@ "varbinary_rename": true }, "index": { - "speedup_index": true + "TEST_TABLE_TINYINT_BIGINT": true }, "constraint": { - "some_unique_key": true, - "some_foreign_key": true + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true } } } diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml index 57403cbea3fdc..0a0131e500641 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/drop_table/db_schema.xml @@ -12,7 +12,7 @@ nullable="true"/> - + diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml index 2b8b162bf2a9e..e4a5ca05d02fe 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/foreign_key_interpreter/db_schema.xml @@ -12,7 +12,8 @@ -
diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/InstallSchema.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/InstallSchema.php index 3b73610f18270..8678218a51e05 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/InstallSchema.php +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/InstallSchema.php @@ -97,16 +97,21 @@ public function install(SchemaSetupInterface $setup, ModuleContextInterface $con 'Boolean' ) ->addIndex( - 'some_unique_key', + $installer->getIdxName($installer->getTable('test_table'), ['smallint', 'bigint']), ['smallint', 'bigint'], ['type' => \Magento\Framework\DB\Adapter\Pdo\Mysql::INDEX_TYPE_UNIQUE] ) ->addIndex( - 'speedup_index', + $installer->getIdxName($installer->getTable('test_table'), ['bigint']), ['bigint'] ) ->addForeignKey( - 'some_foreign_key', + $installer->getFkName( + $installer->getTable('test_table'), + 'smallint', + $installer->getTable('reference_table'), + 'smallint_ref' + ), 'smallint', $installer->getTable('reference_table'), 'smallint_ref', diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml index 97b375d228e0c..6b92440ca92f5 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/revisions/old_diff/db_schema.xml @@ -22,13 +22,14 @@ - + - - + diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml index 00b5d6f9bb27d..b6ff634e6ef1d 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule3/etc/db_schema.xml @@ -21,7 +21,8 @@ - diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml index 00b5d6f9bb27d..b6ff634e6ef1d 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule5/etc/db_schema.xml @@ -21,7 +21,8 @@ - diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml index 3eeb141c2e606..9263004c6e7f6 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema.xml @@ -30,7 +30,7 @@ nullable="true"/> - + @@ -53,14 +53,15 @@ - + - - + diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema_whitelist.json b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema_whitelist.json index 890fea33106b7..9105a2b0b25cb 100644 --- a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema_whitelist.json +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule6/etc/db_schema_whitelist.json @@ -23,7 +23,7 @@ "int_disabled_auto_increment": true }, "constraint": { - "unique_null_key": true + "AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE": true } }, "test_table": { @@ -46,11 +46,11 @@ "varbinary_rename": true }, "index": { - "speedup_index": true + "TEST_TABLE_TINYINT_BIGINT": true }, "constraint": { - "some_unique_key": true, - "some_foreign_key": true + "TEST_TABLE_SMALLINT_BIGINT": true, + "TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF": true } } } diff --git a/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/ReinstallInstance.php b/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/ReinstallInstance.php index 6f7949861928e..e3825db2bd1f1 100644 --- a/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/ReinstallInstance.php +++ b/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/ReinstallInstance.php @@ -33,12 +33,12 @@ public function __construct(\Magento\TestFramework\Application $application) public function startTest() { - $this->application->reinitialize(); /** @var ObjectManager $objectManager */ $objectManager = Bootstrap::getObjectManager(); $resourceConnection = $objectManager->create(ResourceConnection::class); $objectManager->removeSharedInstance(ResourceConnection::class); $objectManager->addSharedInstance($resourceConnection, ResourceConnection::class); + $this->application->reinitialize(); } /** diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/BCMultiModuleTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/BCMultiModuleTest.php index 6ea79f9628e39..f40339fd02439 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/BCMultiModuleTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/BCMultiModuleTest.php @@ -7,14 +7,12 @@ namespace Magento\Setup; use Magento\Framework\Module\DbVersionInfo; -use Magento\Framework\Module\ModuleList; use Magento\Framework\Module\ModuleResource; use Magento\Framework\Setup\Declaration\Schema\Db\DbSchemaReaderInterface; use Magento\TestFramework\Deploy\CliCommand; use Magento\TestFramework\Deploy\TableData; use Magento\TestFramework\Deploy\TestModuleManager; use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\SetupTestCase; /** @@ -77,7 +75,7 @@ public function testFirstCleanInstall() //Check if declaration is applied $indexes = $this->dbSchemaReader->readIndexes('test_table', 'default'); self::assertCount(1, $indexes); - self::assertArrayHasKey('speedup_index', $indexes); + self::assertArrayHasKey('TEST_TABLE_TINYINT_BIGINT', $indexes); //Check UpgradeSchema old format, that modify declaration $columns = $this->dbSchemaReader->readColumns('test_table', 'default'); $floatColumn = $columns['float']; @@ -199,4 +197,69 @@ public function testDSFirstRelease() $tables = $this->dbSchemaReader->readTables('default'); self::assertNotContains('custom_table', $tables); } + + /** + * @moduleName Magento_TestSetupDeclarationModule1 + * @dataProvider firstCleanInstallOneModuleDataProvider + * @param string $dbPrefix + * @param string $tableName + * @param string $indexName + * @param string $constraintName + * @param string $foreignKeyName + * @throws \Exception + */ + public function testFirstCleanInstallOneModule( + string $dbPrefix, + string $tableName, + string $indexName, + string $constraintName, + string $foreignKeyName + ) { + $this->cliCommand->install( + [ + 'Magento_TestSetupDeclarationModule1' + ], + [ + 'db-prefix' => $dbPrefix, + ] + ); + + $indexes = $this->dbSchemaReader + ->readIndexes($tableName, 'default'); + self::assertCount(1, $indexes); + self::assertArrayHasKey($indexName, $indexes); + + $constraints = $this->dbSchemaReader + ->readConstraints($tableName, 'default'); + self::assertCount(1, $constraints); + self::assertArrayHasKey($constraintName, $constraints); + + $foreignKeys = $this->dbSchemaReader + ->readReferences($tableName, 'default'); + self::assertCount(1, $foreignKeys); + self::assertArrayHasKey($foreignKeyName, $foreignKeys); + } + + /** + * @return array + */ + public function firstCleanInstallOneModuleDataProvider() + { + return [ + 'Installation without db prefix' => [ + 'dbPrefix' => '', + 'tableName' => 'test_table', + 'indexName' => 'TEST_TABLE_TINYINT_BIGINT', + 'constraintName' => 'TEST_TABLE_SMALLINT_BIGINT', + 'foreignKeyName' => 'TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF', + ], + 'Installation with db prefix' => [ + 'dbPrefix' => 'spec_', + 'tableName' => 'spec_test_table', + 'indexName' => 'SPEC_TEST_TABLE_TINYINT_BIGINT', + 'constraintName' => 'SPEC_TEST_TABLE_SMALLINT_BIGINT', + 'foreignKeyName' => 'SPEC_TEST_TABLE_TINYINT_SPEC_REFERENCE_TABLE_TINYINT_REF', + ] + ]; + } } diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index 2bdf85bc95217..34d432e566fec 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -80,7 +80,7 @@ public function testInstallation() //Second time installation should not find anything as we do not change anything self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getData(), $shardData); + self::assertEquals($this->getTrimmedData(), $shardData); } /** @@ -111,7 +111,7 @@ public function testInstallationWithColumnsModification() ); self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getData(), $shardData); + self::assertEquals($this->getTrimmedData(), $shardData); } /** @@ -157,7 +157,7 @@ public function testInstallationWithColumnsRemoval() ); self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getData(), $shardData); + self::assertEquals($this->getTrimmedData(), $shardData); } /** @@ -243,7 +243,7 @@ public function testInstallWithCodeBaseRollback() ['Magento_TestSetupDeclarationModule1'] ); $beforeRollback = $this->describeTable->describeShard('default'); - self::assertEquals($this->getData()['before'], $beforeRollback); + self::assertEquals($this->getTrimmedData()['before'], $beforeRollback); //Move db_schema.xml file and tried to install $this->moduleManager->updateRevision( 'Magento_TestSetupDeclarationModule1', diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeSchemaBuilderTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeSchemaBuilderTest.php index 07544c25c45e4..d4126d9d1e16c 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeSchemaBuilderTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeSchemaBuilderTest.php @@ -79,7 +79,7 @@ public function testSchemaBuilder() /** * @var Reference $foreignKey */ - $foreignKey = $testTable->getConstraintByName('some_foreign_key'); + $foreignKey = $testTable->getConstraintByName('TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF'); self::assertEquals('NO ACTION', $foreignKey->getOnDelete()); self::assertEquals('tinyint_ref', $foreignKey->getReferenceColumn()->getName()); } diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DiffOldSchemaTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DiffOldSchemaTest.php index 3fb117896eaa9..0521a832ae392 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DiffOldSchemaTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DiffOldSchemaTest.php @@ -96,6 +96,58 @@ public function testOldDiff() ); } + /** + * @moduleName Magento_TestSetupDeclarationModule1 + * @param string $dbPrefix + * @throws \Exception + * @dataProvider oldSchemaUpgradeDataProvider + */ + public function testOldSchemaUpgrade(string $dbPrefix) + { + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule1', + 'old_diff_before', + 'db_schema.xml', + 'etc' + ); + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule1', + 'base_update', + 'InstallSchema.php', + 'Setup' + ); + $this->cliCommad->install( + ['Magento_TestSetupDeclarationModule1'], + ['db-prefix' => $dbPrefix] + ); + //Move db_schema.xml + $this->moduleManager->updateRevision( + 'Magento_TestSetupDeclarationModule1', + 'base_update', + 'db_schema.xml', + 'etc' + ); + $declarativeSchema = $this->schemaConfig->getDeclarationConfig(); + $generatedSchema = $this->schemaConfig->getDbConfig(); + $diff = $this->schemaDiff->diff($declarativeSchema, $generatedSchema); + self::assertEmpty($diff->getAll()); + } + + /** + * @return array + */ + public function oldSchemaUpgradeDataProvider(): array + { + return [ + 'Without db prefix' => [ + 'dbPrefix' => '', + ], + 'With db prefix' => [ + 'dbPrefix' => 'spec_', + ], + ]; + } + /** * @return array */ diff --git a/lib/internal/Magento/Framework/Logger/Handler/Syslog.php b/lib/internal/Magento/Framework/Logger/Handler/Syslog.php new file mode 100644 index 0000000000000..4964cc45f85d7 --- /dev/null +++ b/lib/internal/Magento/Framework/Logger/Handler/Syslog.php @@ -0,0 +1,28 @@ +name = $name; return $this; } + + /** + * @param string $key Key is used as index + * @param string $value + * @return void + */ + public function setData(string $key, string $value) + { + $this->data[$key] = $value; + } + + /** + * @param array $data + * @return void + */ + public function addData(array $data) + { + $this->data = $data; + } + + /** + * @param TSampleInterface[] $list + * @return void + */ + public function addObjectList(array $list) + { + $this->data['objects'] = $list; + } } diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php index 4543b3b6eec12..4a61d003e32a8 100644 --- a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php +++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php @@ -8,24 +8,22 @@ use Magento\Framework\Exception\SerializationException; use Magento\Framework\Reflection\Test\Unit\Fixture\TSample; +use Magento\Framework\Reflection\TypeProcessor; use Zend\Code\Reflection\ClassReflection; -/** - * Type processor Test - */ class TypeProcessorTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Framework\Reflection\TypeProcessor + * @var TypeProcessor */ - protected $_typeProcessor; + private $typeProcessor; /** * Set up helper. */ protected function setUp() { - $this->_typeProcessor = new \Magento\Framework\Reflection\TypeProcessor(); + $this->typeProcessor = new TypeProcessor(); } /** @@ -33,11 +31,11 @@ protected function setUp() */ public function testGetTypesData() { - $this->_typeProcessor->setTypeData('typeA', ['dataA']); - $this->_typeProcessor->setTypeData('typeB', ['dataB']); + $this->typeProcessor->setTypeData('typeA', ['dataA']); + $this->typeProcessor->setTypeData('typeB', ['dataB']); $this->assertEquals( ['typeA' => ['dataA'], 'typeB' => ['dataB']], - $this->_typeProcessor->getTypesData() + $this->typeProcessor->getTypesData() ); } @@ -46,11 +44,11 @@ public function testGetTypesData() */ public function testSetTypesData() { - $this->_typeProcessor->setTypeData('typeC', ['dataC']); - $this->assertEquals(['typeC' => ['dataC']], $this->_typeProcessor->getTypesData()); + $this->typeProcessor->setTypeData('typeC', ['dataC']); + $this->assertEquals(['typeC' => ['dataC']], $this->typeProcessor->getTypesData()); $typeData = ['typeA' => ['dataA'], 'typeB' => ['dataB']]; - $this->_typeProcessor->setTypesData($typeData); - $this->assertEquals($typeData, $this->_typeProcessor->getTypesData()); + $this->typeProcessor->setTypesData($typeData); + $this->assertEquals($typeData, $this->typeProcessor->getTypesData()); } /** @@ -59,7 +57,7 @@ public function testSetTypesData() */ public function testGetTypeDataInvalidArgumentException() { - $this->_typeProcessor->getTypeData('NonExistentType'); + $this->typeProcessor->getTypeData('NonExistentType'); } /** @@ -67,8 +65,8 @@ public function testGetTypeDataInvalidArgumentException() */ public function testGetTypeData() { - $this->_typeProcessor->setTypeData('typeA', ['dataA']); - $this->assertEquals(['dataA'], $this->_typeProcessor->getTypeData('typeA')); + $this->typeProcessor->setTypeData('typeA', ['dataA']); + $this->assertEquals(['dataA'], $this->typeProcessor->getTypeData('typeA')); } /** @@ -76,85 +74,88 @@ public function testGetTypeData() */ public function testSetTypeDataArrayMerge() { - $this->_typeProcessor->setTypeData('typeA', ['dataA1']); - $this->_typeProcessor->setTypeData('typeA', ['dataA2']); - $this->_typeProcessor->setTypeData('typeA', ['dataA3']); - $this->_typeProcessor->setTypeData('typeA', [null]); - $this->assertEquals(['dataA1', 'dataA2', 'dataA3', null], $this->_typeProcessor->getTypeData('typeA')); + $this->typeProcessor->setTypeData('typeA', ['dataA1']); + $this->typeProcessor->setTypeData('typeA', ['dataA2']); + $this->typeProcessor->setTypeData('typeA', ['dataA3']); + $this->typeProcessor->setTypeData('typeA', [null]); + $this->assertEquals( + ['dataA1', 'dataA2', 'dataA3', null], + $this->typeProcessor->getTypeData('typeA') + ); } public function testNormalizeType() { - $this->assertEquals('blah', $this->_typeProcessor->normalizeType('blah')); - $this->assertEquals('string', $this->_typeProcessor->normalizeType('str')); - $this->assertEquals('int', $this->_typeProcessor->normalizeType('integer')); - $this->assertEquals('boolean', $this->_typeProcessor->normalizeType('bool')); - $this->assertEquals('anyType', $this->_typeProcessor->normalizeType('mixed')); + $this->assertEquals('blah', $this->typeProcessor->normalizeType('blah')); + $this->assertEquals('string', $this->typeProcessor->normalizeType('str')); + $this->assertEquals('int', $this->typeProcessor->normalizeType('integer')); + $this->assertEquals('boolean', $this->typeProcessor->normalizeType('bool')); + $this->assertEquals('anyType', $this->typeProcessor->normalizeType('mixed')); } public function testIsTypeSimple() { - $this->assertTrue($this->_typeProcessor->isTypeSimple('string')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('string[]')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('int')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('float')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('double')); - $this->assertTrue($this->_typeProcessor->isTypeSimple('boolean')); - $this->assertFalse($this->_typeProcessor->isTypeSimple('blah')); + $this->assertTrue($this->typeProcessor->isTypeSimple('string')); + $this->assertTrue($this->typeProcessor->isTypeSimple('string[]')); + $this->assertTrue($this->typeProcessor->isTypeSimple('int')); + $this->assertTrue($this->typeProcessor->isTypeSimple('float')); + $this->assertTrue($this->typeProcessor->isTypeSimple('double')); + $this->assertTrue($this->typeProcessor->isTypeSimple('boolean')); + $this->assertFalse($this->typeProcessor->isTypeSimple('blah')); } public function testIsTypeAny() { - $this->assertTrue($this->_typeProcessor->isTypeAny('mixed')); - $this->assertTrue($this->_typeProcessor->isTypeAny('mixed[]')); - $this->assertFalse($this->_typeProcessor->isTypeAny('int')); - $this->assertFalse($this->_typeProcessor->isTypeAny('int[]')); + $this->assertTrue($this->typeProcessor->isTypeAny('mixed')); + $this->assertTrue($this->typeProcessor->isTypeAny('mixed[]')); + $this->assertFalse($this->typeProcessor->isTypeAny('int')); + $this->assertFalse($this->typeProcessor->isTypeAny('int[]')); } public function testIsArrayType() { - $this->assertFalse($this->_typeProcessor->isArrayType('string')); - $this->assertTrue($this->_typeProcessor->isArrayType('string[]')); + $this->assertFalse($this->typeProcessor->isArrayType('string')); + $this->assertTrue($this->typeProcessor->isArrayType('string[]')); } public function testIsValidTypeDeclaration() { - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('Traversable')); // Interface - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('stdObj')); // Class - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('array')); - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('callable')); - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('self')); - $this->assertTrue($this->_typeProcessor->isValidTypeDeclaration('self')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('string')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('string[]')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('int')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('float')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('double')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('boolean')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('[]')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('mixed[]')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('stdObj[]')); - $this->assertFalse($this->_typeProcessor->isValidTypeDeclaration('Traversable[]')); + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('Traversable')); // Interface + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('stdObj')); // Class + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('array')); + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('callable')); + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('self')); + $this->assertTrue($this->typeProcessor->isValidTypeDeclaration('self')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('string')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('string[]')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('int')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('float')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('double')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('boolean')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('[]')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('mixed[]')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('stdObj[]')); + $this->assertFalse($this->typeProcessor->isValidTypeDeclaration('Traversable[]')); } public function getArrayItemType() { - $this->assertEquals('string', $this->_typeProcessor->getArrayItemType('str[]')); - $this->assertEquals('string', $this->_typeProcessor->getArrayItemType('string[]')); - $this->assertEquals('integer', $this->_typeProcessor->getArrayItemType('int[]')); - $this->assertEquals('boolean', $this->_typeProcessor->getArrayItemType('bool[]')); - $this->assertEquals('any', $this->_typeProcessor->getArrayItemType('mixed[]')); + $this->assertEquals('string', $this->typeProcessor->getArrayItemType('str[]')); + $this->assertEquals('string', $this->typeProcessor->getArrayItemType('string[]')); + $this->assertEquals('integer', $this->typeProcessor->getArrayItemType('int[]')); + $this->assertEquals('boolean', $this->typeProcessor->getArrayItemType('bool[]')); + $this->assertEquals('any', $this->typeProcessor->getArrayItemType('mixed[]')); } public function testTranslateTypeName() { $this->assertEquals( 'TestModule1V1EntityItem', - $this->_typeProcessor->translateTypeName(\Magento\TestModule1\Service\V1\Entity\Item::class) + $this->typeProcessor->translateTypeName(\Magento\TestModule1\Service\V1\Entity\Item::class) ); $this->assertEquals( 'TestModule3V1EntityParameter[]', - $this->_typeProcessor->translateTypeName('\Magento\TestModule3\Service\V1\Entity\Parameter[]') + $this->typeProcessor->translateTypeName('\Magento\TestModule3\Service\V1\Entity\Parameter[]') ); } @@ -164,47 +165,47 @@ public function testTranslateTypeName() */ public function testTranslateTypeNameInvalidArgumentException() { - $this->_typeProcessor->translateTypeName('\Magento\TestModule3\V1\Parameter[]'); + $this->typeProcessor->translateTypeName('\Magento\TestModule3\V1\Parameter[]'); } public function testTranslateArrayTypeName() { - $this->assertEquals('ArrayOfComplexType', $this->_typeProcessor->translateArrayTypeName('complexType')); + $this->assertEquals('ArrayOfComplexType', $this->typeProcessor->translateArrayTypeName('complexType')); } public function testProcessSimpleTypeIntToString() { $value = 1; $type = 'string'; - $this->assertSame('1', $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame('1', $this->typeProcessor->processSimpleAndAnyType($value, $type)); } public function testProcessSimpleTypeStringToInt() { $value = '1'; $type = 'int'; - $this->assertSame(1, $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame(1, $this->typeProcessor->processSimpleAndAnyType($value, $type)); } public function testProcessSimpleTypeMixed() { $value = 1; $type = 'mixed'; - $this->assertSame(1, $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame(1, $this->typeProcessor->processSimpleAndAnyType($value, $type)); } public function testProcessSimpleTypeIntArrayToStringArray() { $value = [1, 2, 3, 4, 5]; $type = 'string[]'; - $this->assertSame(['1', '2', '3', '4', '5'], $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame(['1', '2', '3', '4', '5'], $this->typeProcessor->processSimpleAndAnyType($value, $type)); } public function testProcessSimpleTypeStringArrayToIntArray() { $value = ['1', '2', '3', '4', '5']; $type = 'int[]'; - $this->assertSame([1, 2, 3, 4, 5], $this->_typeProcessor->processSimpleAndAnyType($value, $type)); + $this->assertSame([1, 2, 3, 4, 5], $this->typeProcessor->processSimpleAndAnyType($value, $type)); } /** @@ -212,10 +213,11 @@ public function testProcessSimpleTypeStringArrayToIntArray() */ public function testProcessSimpleTypeException($value, $type) { - $this->expectException(SerializationException::class); - $this->expectExceptionMessage('The "' - . $value . '" value\'s type is invalid. The "' . $type . '" type was expected. Verify and try again.'); - $this->_typeProcessor->processSimpleAndAnyType($value, $type); + $this->expectException( + SerializationException::class, + 'Invalid type for value: "' . $value . '". Expected Type: "' . $type . '"' + ); + $this->typeProcessor->processSimpleAndAnyType($value, $type); } public static function processSimpleTypeExceptionProvider() @@ -234,32 +236,89 @@ public function testProcessSimpleTypeInvalidType() { $value = 1; $type = 'int[]'; - $this->_typeProcessor->processSimpleAndAnyType($value, $type); + $this->typeProcessor->processSimpleAndAnyType($value, $type); } /** * @expectedException \LogicException * @expectedExceptionMessageRegExp /@param annotation is incorrect for the parameter "name" \w+/ */ - public function testGetParamType() + public function testGetParamTypeWithIncorrectAnnotation() { - $class = new ClassReflection(\Magento\Framework\Reflection\Test\Unit\DataObject::class); + $class = new ClassReflection(DataObject::class); $methodReflection = $class->getMethod('setName'); $paramsReflection = $methodReflection->getParameters(); - $this->_typeProcessor->getParamType($paramsReflection[0]); + $this->typeProcessor->getParamType($paramsReflection[0]); } - public function testGetParameterDescription() + /** + * Checks a case for different array param types. + * + * @param string $methodName + * @param string $type + * @dataProvider arrayParamTypeDataProvider + */ + public function testGetArrayParamType(string $methodName, string $type) { - $class = new ClassReflection(\Magento\Framework\Reflection\Test\Unit\DataObject::class); - $methodReflection = $class->getMethod('setName'); + $class = new ClassReflection(DataObject::class); + $methodReflection = $class->getMethod($methodName); + $params = $methodReflection->getParameters(); + $this->assertEquals($type, $this->typeProcessor->getParamType(array_pop($params))); + } + + /** + * Get list of methods with expected param types. + * + * @return array + */ + public function arrayParamTypeDataProvider() + { + return [ + ['method name' => 'addData', 'type' => 'array[]'], + ['method name' => 'addObjectList', 'type' => 'TSampleInterface[]'] + ]; + } + + /** + * Checks a case when method param has additional description. + * + * @param string $methodName + * @param array $descriptions + * @dataProvider methodParamsDataProvider + */ + public function testGetParameterDescription(string $methodName, array $descriptions) + { + $class = new ClassReflection(DataObject::class); + $methodReflection = $class->getMethod($methodName); $paramsReflection = $methodReflection->getParameters(); - $this->assertEquals('Name of the attribute', $this->_typeProcessor->getParamDescription($paramsReflection[0])); + foreach ($paramsReflection as $paramReflection) { + $description = array_shift($descriptions); + $this->assertEquals( + $description, + $this->typeProcessor->getParamDescription($paramReflection) + ); + } + } + + /** + * Gets list of method names with params and their descriptions. + * + * @return array + */ + public function methodParamsDataProvider() + { + return [ + ['method name' => 'setName', 'descriptions' => ['Name of the attribute']], + ['method name' => 'setData', 'descriptions' => ['Key is used as index', null]], + ]; } public function testGetOperationName() { - $this->assertEquals("resNameMethodName", $this->_typeProcessor->getOperationName("resName", "methodName")); + $this->assertEquals( + "resNameMethodName", + $this->typeProcessor->getOperationName("resName", "methodName") + ); } /** @@ -277,19 +336,19 @@ public function testGetReturnTypeWithInheritDocBlock() $classReflection = new ClassReflection(TSample::class); $methodReflection = $classReflection->getMethod('getPropertyName'); - self::assertEquals($expected, $this->_typeProcessor->getGetterReturnType($methodReflection)); + self::assertEquals($expected, $this->typeProcessor->getGetterReturnType($methodReflection)); } /** * Checks a case when method and parent interface don't have `@return` annotation. * * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Getter return type must be specified using @return annotation. See Magento\Framework\Reflection\Test\Unit\Fixture\TSample::getName() + * @expectedExceptionMessage Method's return type must be specified using @return annotation. See Magento\Framework\Reflection\Test\Unit\Fixture\TSample::getName() */ public function testGetReturnTypeWithoutReturnTag() { $classReflection = new ClassReflection(TSample::class); $methodReflection = $classReflection->getMethod('getName'); - $this->_typeProcessor->getGetterReturnType($methodReflection); + $this->typeProcessor->getGetterReturnType($methodReflection); } } diff --git a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php index cf2f8bf3369ec..d7206032c68c7 100644 --- a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php +++ b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php @@ -9,6 +9,7 @@ use Magento\Framework\Exception\SerializationException; use Magento\Framework\Phrase; use Zend\Code\Reflection\ClassReflection; +use Zend\Code\Reflection\DocBlock\Tag\ParamTag; use Zend\Code\Reflection\DocBlock\Tag\ReturnTag; use Zend\Code\Reflection\DocBlockReflection; use Zend\Code\Reflection\MethodReflection; @@ -522,35 +523,24 @@ public function getParamType(ParameterReflection $param) } if ($type == 'array') { // try to determine class, if it's array of objects - $docBlock = $param->getDeclaringFunction()->getDocBlock(); - $pattern = "/\@param\s+([\w\\\_]+\[\])\s+\\\${$param->getName()}[\n\r]/"; - $matches = []; - if (preg_match($pattern, $docBlock->getContents(), $matches)) { - return $matches[1]; - } - return "{$type}[]"; + $paramDocBlock = $this->getParamDocBlockTag($param); + $paramTypes = $paramDocBlock->getTypes(); + $paramType = array_shift($paramTypes); + return strpos($paramType, '[]') !== false ? $paramType : "{$paramType}[]"; } return $type; } /** - * Get parameter description + * Gets method parameter description. * * @param ParameterReflection $param * @return string|null */ public function getParamDescription(ParameterReflection $param) { - $docBlock = $param->getDeclaringFunction()->getDocBlock(); - $docBlockLines = explode("\n", $docBlock->getContents()); - $pattern = "/\@param\s+([\w\\\_\[\]\|]+)\s+(\\\${$param->getName()})\s(.*)/"; - $matches = []; - - foreach ($docBlockLines as $line) { - if (preg_match($pattern, $line, $matches)) { - return $matches[3]; - } - } + $paramDocBlock = $this->getParamDocBlockTag($param); + return $paramDocBlock->getDescription(); } /** @@ -731,7 +721,7 @@ private function getMethodReturnAnnotation(MethodReflection $methodReflection) // throw an exception if even implemented interface doesn't have return annotations if (empty($returnAnnotations)) { throw new \InvalidArgumentException( - "Getter return type must be specified using @return annotation. " + "Method's return type must be specified using @return annotation. " . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodName}()" ); } @@ -750,10 +740,24 @@ private function getReturnFromDocBlock(MethodReflection $methodReflection) $methodDocBlock = $methodReflection->getDocBlock(); if (!$methodDocBlock) { throw new \InvalidArgumentException( - "Each getter must have a doc block. " + "Each method must have a doc block. " . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()" ); } return current($methodDocBlock->getTags('return')); } + + /** + * Gets method's param doc block. + * + * @param ParameterReflection $param + * @return ParamTag + */ + private function getParamDocBlockTag(ParameterReflection $param): ParamTag + { + $docBlock = $param->getDeclaringFunction() + ->getDocBlock(); + $paramsTag = $docBlock->getTags('param'); + return $paramsTag[$param->getPosition()]; + } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php index 7f73e742e0a6c..830fcb293a8f1 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php @@ -5,7 +5,9 @@ */ namespace Magento\Framework\Setup\Declaration\Schema\Declaration; +use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\Phrase; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; use Magento\Framework\Stdlib\BooleanUtils; use Magento\Framework\Setup\Exception; use Magento\Framework\Setup\Declaration\Schema\Dto\Column; @@ -66,6 +68,11 @@ class SchemaBuilder */ private $resourceConnection; + /** + * @var TableNameResolver + */ + private $tableNameResolver; + /** * SchemaBuilder constructor. * @@ -74,6 +81,7 @@ class SchemaBuilder * @param Sharding $sharding * @param ValidationComposite $validationComposite * @param \Magento\Framework\App\ResourceConnection $resourceConnection + * @param TableNameResolver $tableNameResolver * @internal param array $tablesData */ public function __construct( @@ -81,13 +89,15 @@ public function __construct( BooleanUtils $booleanUtils, Sharding $sharding, ValidationComposite $validationComposite, - \Magento\Framework\App\ResourceConnection $resourceConnection + \Magento\Framework\App\ResourceConnection $resourceConnection, + TableNameResolver $tableNameResolver ) { $this->sharding = $sharding; $this->elementFactory = $elementFactory; $this->booleanUtils = $booleanUtils; $this->validationComposite = $validationComposite; $this->resourceConnection = $resourceConnection; + $this->tableNameResolver = $tableNameResolver; } /** @@ -275,6 +285,35 @@ private function convertColumnNamesToObjects(array $columnNames, Table $table) return $columns; } + /** + * Provides the full index name based on the prefix value. + * + * @param string $name + * @param Table $table + * @param array $columns + * @param string $type + * @return string + */ + private function getFullIndexName( + string $name, + Table $table, + array $columns, + string $type = AdapterInterface::INDEX_TYPE_INDEX + ) { + if (AdapterInterface::INDEX_TYPE_PRIMARY === $type) { + return $name; + } + + $tableName = $this->tableNameResolver->getNameOfOriginTable($table->getName()); + + return $this->resourceConnection + ->getIdxName( + $tableName, + $columns, + $type + ); + } + /** * Convert and instantiate index objects. * @@ -296,6 +335,21 @@ private function processIndexes(array $tableData, $resource, Table $table) continue; } + /** + * Temporary solution. + * @see MAGETWO-91365 + */ + $indexType = AdapterInterface::INDEX_TYPE_INDEX; + if (isset($indexData['indexType']) && $indexData['indexType'] === AdapterInterface::INDEX_TYPE_FULLTEXT) { + $indexType = $indexData['indexType']; + } + + $indexData['name'] = $this->getFullIndexName( + $indexData['name'], + $table, + $indexData['column'], + $indexType + ); $indexData = $this->processGenericData($indexData, $resource, $table); $indexData['columns'] = $this->convertColumnNamesToObjects($indexData['column'], $table); $index = $this->elementFactory->create('index', $indexData); @@ -354,9 +408,25 @@ private function processConstraints(array $tableData, $resource, Schema $schema, $constraintData['referenceColumn'], $constraintData['referenceTable'] ); + /** + * Calculation of the full name of Foreign Key based on the prefix value. + */ + $constraintData['name'] = $this->resourceConnection + ->getFkName( + $this->tableNameResolver->getNameOfOriginTable($table->getName()), + $constraintData['column']->getName(), + $constraintData['referenceTable']->getName(), + $constraintData['referenceColumn']->getName() + ); $constraint = $this->elementFactory->create($constraintData['type'], $constraintData); $constraints[$constraint->getName()] = $constraint; } else { + $constraintData['name'] = $this->getFullIndexName( + $constraintData['name'], + $table, + $constraintData['column'], + $constraintData['type'] + ); $constraintData['columns'] = $this->convertColumnNamesToObjects($constraintData['column'], $table); $constraint = $this->elementFactory->create($constraintData['type'], $constraintData); $constraints[$constraint->getName()] = $constraint; diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/Diff.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/Diff.php index cb222d8b0c3d1..0e857567689c4 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/Diff.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/Diff.php @@ -7,8 +7,10 @@ namespace Magento\Framework\Setup\Declaration\Schema\Diff; use Magento\Framework\Component\ComponentRegistrar; +use Magento\Framework\Setup\Declaration\Schema\Dto\Constraint; use Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Reference; use Magento\Framework\Setup\Declaration\Schema\Dto\ElementInterface; +use Magento\Framework\Setup\Declaration\Schema\Dto\Index; use Magento\Framework\Setup\Declaration\Schema\Dto\Table; use Magento\Framework\Setup\Declaration\Schema\Dto\TableElementInterface; use Magento\Framework\Setup\Declaration\Schema\ElementHistory; @@ -158,20 +160,41 @@ private function getWhiteListTables() * @param string $operation * @return bool */ - public function canBeRegistered(ElementInterface $object, $operation) + public function canBeRegistered(ElementInterface $object, $operation): bool { if (!isset($this->destructiveOperations[$operation])) { return true; } + $checkResult = false; $whiteList = $this->getWhiteListTables(); - $type = $object->getElementType(); if ($object instanceof TableElementInterface) { - return isset($whiteList[$object->getTable()->getNameWithoutPrefix()][$type][$object->getName()]); + $tableNameWithoutPrefix = $object->getTable()->getNameWithoutPrefix(); + $type = $object->getElementType(); + + if ($this->isElementHaveAutoGeneratedName($object)) { + $checkResult = + isset($whiteList[$tableNameWithoutPrefix][$type][$object->getNameWithoutPrefix()]); + } else { + $checkResult = isset($whiteList[$tableNameWithoutPrefix][$type][$object->getName()]); + } + } elseif ($object instanceof Table) { + $checkResult = isset($whiteList[$object->getNameWithoutPrefix()]); } - return isset($whiteList[$object->getNameWithoutPrefix()]); + return $checkResult; + } + + /** + * Check if the element has an auto-generated name. + * + * @param ElementInterface $element + * @return bool + */ + private function isElementHaveAutoGeneratedName(ElementInterface $element): bool + { + return in_array($element->getElementType(), [Index::TYPE, Constraint::TYPE], true); } /** diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/TableDiff.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/TableDiff.php index 2030b192935e7..87045df864a3e 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/TableDiff.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Diff/TableDiff.php @@ -7,10 +7,10 @@ namespace Magento\Framework\Setup\Declaration\Schema\Diff; use Magento\Framework\Setup\Declaration\Schema\Dto\Column; +use Magento\Framework\Setup\Declaration\Schema\Dto\Constraint; use Magento\Framework\Setup\Declaration\Schema\Dto\ElementInterface; use Magento\Framework\Setup\Declaration\Schema\Dto\Index; use Magento\Framework\Setup\Declaration\Schema\Dto\Table; -use Magento\Framework\Setup\Declaration\Schema\Operations\AddComplexElement; use Magento\Framework\Setup\Declaration\Schema\Operations\ModifyColumn; /** @@ -91,12 +91,14 @@ private function turnOffForeignKeys(Table $declaredTable, Table $generatedTable, if ($elementHistory->getNew() instanceof Column) { $column = $elementHistory->getNew(); $references = $generatedTable->getReferenceConstraints(); - $declaredReferences = $declaredTable->getReferenceConstraints(); + $declaredReferences = $this->getElementsListByNameWithoutPrefix( + $declaredTable->getReferenceConstraints() + ); foreach ($references as $reference) { /** In case when we have foreign key on column, that should be modified */ if ($reference->getColumn()->getName() === $column->getName() && - isset($declaredReferences[$reference->getName()]) + isset($declaredReferences[$reference->getNameWithoutPrefix()]) ) { /** * Lets disable foreign key and enable it again @@ -104,7 +106,11 @@ private function turnOffForeignKeys(Table $declaredTable, Table $generatedTable, * we will drop key, modify column, add key */ $diff = $this->diffManager->registerRemoval($diff, [$reference]); - $diff = $this->diffManager->registerCreation($diff, $reference); + $diff = $this->diffManager + ->registerCreation( + $diff, + $declaredReferences[$reference->getNameWithoutPrefix()] + ); } } } @@ -113,6 +119,22 @@ private function turnOffForeignKeys(Table $declaredTable, Table $generatedTable, return $diff; } + /** + * Switches keys of the array on the element name without prefix. + * + * @param Constraint[]|Index[] $elements + * @return array + */ + private function getElementsListByNameWithoutPrefix(array $elements) + { + $elementsList = []; + foreach ($elements as $element) { + $elementsList[$element->getNameWithoutPrefix()] = $element; + } + + return $elementsList; + } + /** * Diff between tables. * @@ -135,6 +157,19 @@ public function diff( $this->diffManager->registerTableModification($declaredTable, $generatedTable, $diff); } + return $this->calculateDiff($declaredTable, $generatedTable, $diff); + } + + /** + * Calculate the difference between tables. + * + * @param Table|ElementInterface $declaredTable + * @param Table|ElementInterface $generatedTable + * @param Diff $diff + * @return Diff + */ + private function calculateDiff(ElementInterface $declaredTable, ElementInterface $generatedTable, Diff $diff) + { $types = [self::COLUMN_DIFF_TYPE, self::CONSTRAINT_DIFF_TYPE, self::INDEX_DIFF_TYPE]; //We do inspection for each element type foreach ($types as $elementType) { @@ -146,6 +181,11 @@ public function diff( $declaredElements = $this->excludeAutoIndexes($declaredTable, $declaredElements); } + if (in_array($elementType, [self::CONSTRAINT_DIFF_TYPE, self::INDEX_DIFF_TYPE], true)) { + $generatedElements = $this->getElementsListByNameWithoutPrefix($generatedElements); + $declaredElements = $this->getElementsListByNameWithoutPrefix($declaredElements); + } + foreach ($declaredElements as $elementName => $element) { //If it is new for generated (generated from db) elements - we need to create it if (!isset($generatedElements[$elementName])) { @@ -169,6 +209,7 @@ public function diff( } $diff = $this->turnOffForeignKeys($declaredTable, $generatedTable, $diff); + return $diff; } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraint.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraint.php index a7f7fcb2e6656..9f03c1c20cf49 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraint.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraint.php @@ -34,20 +34,28 @@ class Constraint extends GenericElement implements */ private $table; + /** + * @var string + */ + private $nameWithoutPrefix; + /** * Constructor. * * @param string $name * @param string $type - * @param Table $table + * @param Table $table + * @param string $nameWithoutPrefix */ public function __construct( string $name, string $type, - Table $table + Table $table, + string $nameWithoutPrefix ) { parent::__construct($name, $type); $this->table = $table; + $this->nameWithoutPrefix = $nameWithoutPrefix; } /** @@ -67,4 +75,14 @@ public function getElementType() { return self::TYPE; } + + /** + * Retrieve the constraint name which is calculated without table prefix. + * + * @return string + */ + public function getNameWithoutPrefix() + { + return $this->nameWithoutPrefix; + } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Internal.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Internal.php index e15407a4a837d..486d43c023c7f 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Internal.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Internal.php @@ -31,16 +31,18 @@ class Internal extends Constraint implements ElementDiffAwareInterface * * @param string $name * @param string $type - * @param Table $table - * @param array $columns + * @param Table $table + * @param string $nameWithoutPrefix + * @param array $columns */ public function __construct( $name, $type, Table $table, + string $nameWithoutPrefix, array $columns ) { - parent::__construct($name, $type, $table); + parent::__construct($name, $type, $table, $nameWithoutPrefix); $this->columns = $columns; } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Reference.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Reference.php index b79e8fdd3cc2f..b5c8d16311448 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Reference.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Constraints/Reference.php @@ -46,9 +46,10 @@ class Reference extends Constraint implements ElementDiffAwareInterface * * @param string $name * @param string $type - * @param Table $table + * @param Table $table + * @param string $nameWithoutPrefix * @param Column $column - * @param Table $referenceTable + * @param Table $referenceTable * @param Column $referenceColumn * @param string $onDelete * @SuppressWarnings(Magento.TypeDuplication) @@ -57,12 +58,13 @@ public function __construct( string $name, string $type, Table $table, + string $nameWithoutPrefix, Column $column, Table $referenceTable, Column $referenceColumn, string $onDelete ) { - parent::__construct($name, $type, $table); + parent::__construct($name, $type, $table, $nameWithoutPrefix); $this->column = $column; $this->referenceTable = $referenceTable; $this->referenceColumn = $referenceColumn; diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php index 030f2a49d81df..0e1ad0768c4da 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Foreign.php @@ -5,7 +5,9 @@ */ namespace Magento\Framework\Setup\Declaration\Schema\Dto\Factories; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** * Foreign key constraint factory. @@ -27,18 +29,34 @@ class Foreign implements FactoryInterface */ private $className; + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var TableNameResolver + */ + private $tableNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager - * @param string $className + * @param ResourceConnection $resourceConnection + * @param TableNameResolver $tableNameResolver + * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, + ResourceConnection $resourceConnection, + TableNameResolver $tableNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Reference::class ) { $this->objectManager = $objectManager; + $this->resourceConnection = $resourceConnection; $this->className = $className; + $this->tableNameResolver = $tableNameResolver; } /** @@ -50,6 +68,23 @@ public function create(array $data) $data['onDelete'] = self::DEFAULT_ON_DELETE; } + $nameWithoutPrefix = $data['name']; + + if ($this->resourceConnection->getTablePrefix()) { + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($data['table']->getResource()) + ->getForeignKeyName( + $this->tableNameResolver->getNameOfOriginTable( + $data['table']->getNameWithoutPrefix() + ), + $data['column']->getName(), + $data['referenceTable']->getNameWithoutPrefix(), + $data['referenceColumn']->getName() + ); + } + + $data['nameWithoutPrefix'] = $nameWithoutPrefix; + return $this->objectManager->create($this->className, $data); } } 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 919aa05634512..dd2acd7608867 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 @@ -5,7 +5,10 @@ */ namespace Magento\Framework\Setup\Declaration\Schema\Dto\Factories; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** * Index element factory. @@ -27,18 +30,34 @@ class Index implements FactoryInterface */ private $className; + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var TableNameResolver + */ + private $tableNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager - * @param string $className + * @param ResourceConnection $resourceConnection + * @param TableNameResolver $tableNameResolver + * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, + ResourceConnection $resourceConnection, + TableNameResolver $tableNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Index::class ) { $this->objectManager = $objectManager; + $this->resourceConnection = $resourceConnection; $this->className = $className; + $this->tableNameResolver = $tableNameResolver; } /** @@ -50,6 +69,30 @@ public function create(array $data) $data['indexType'] = self::DEFAULT_INDEX_TYPE; } + $nameWithoutPrefix = $data['name']; + + if ($this->resourceConnection->getTablePrefix()) { + /** + * Temporary solution. + * @see MAGETWO-91365 + */ + $indexType = AdapterInterface::INDEX_TYPE_INDEX; + if ($data['indexType'] === AdapterInterface::INDEX_TYPE_FULLTEXT) { + $indexType = $data['indexType']; + } + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($data['table']->getResource()) + ->getIndexName( + $this->tableNameResolver->getNameOfOriginTable( + $data['table']->getNameWithoutPrefix() + ), + $data['column'], + $indexType + ); + } + + $data['nameWithoutPrefix'] = $nameWithoutPrefix; + return $this->objectManager->create($this->className, $data); } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Primary.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Primary.php index ca87ab34f007d..836e32efec057 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Primary.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Primary.php @@ -45,6 +45,7 @@ public function __construct( public function create(array $data) { $data['name'] = Internal::PRIMARY_NAME; + $data['nameWithoutPrefix'] = $data['name']; return $this->objectManager->create($this->className, $data); } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Table.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Table.php index 7c552acda5157..0a8f5b4ad23b3 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Table.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Table.php @@ -86,7 +86,7 @@ public function create(array $data) $tablePrefix = $this->resourceConnection->getTablePrefix(); $nameWithoutPrefix = $data['name']; if (!empty($tablePrefix) && strpos($nameWithoutPrefix, $tablePrefix) === 0) { - $data['nameWithoutPrefix'] = str_replace($tablePrefix, "", $data['name']); + $data['nameWithoutPrefix'] = preg_replace('/^' . $tablePrefix . '/i', '', $data['name']); } else { $data['name'] = $tablePrefix . $data['name']; $data['nameWithoutPrefix'] = $nameWithoutPrefix; diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php index 3709f035fe3a4..57e5270b0c82e 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Factories/Unique.php @@ -5,7 +5,9 @@ */ namespace Magento\Framework\Setup\Declaration\Schema\Dto\Factories; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Setup\Declaration\Schema\TableNameResolver; /** * Unique constraint DTO element factory. @@ -22,18 +24,34 @@ class Unique implements FactoryInterface */ private $className; + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var TableNameResolver + */ + private $tableNameResolver; + /** * Constructor. * * @param ObjectManagerInterface $objectManager - * @param string $className + * @param ResourceConnection $resourceConnection + * @param TableNameResolver $tableNameResolver + * @param string $className */ public function __construct( ObjectManagerInterface $objectManager, + ResourceConnection $resourceConnection, + TableNameResolver $tableNameResolver, $className = \Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Internal::class ) { $this->objectManager = $objectManager; + $this->resourceConnection = $resourceConnection; $this->className = $className; + $this->tableNameResolver = $tableNameResolver; } /** @@ -41,6 +59,22 @@ public function __construct( */ public function create(array $data) { + $nameWithoutPrefix = $data['name']; + + if ($this->resourceConnection->getTablePrefix()) { + $nameWithoutPrefix = $this->resourceConnection + ->getConnection($data['table']->getResource()) + ->getIndexName( + $this->tableNameResolver->getNameOfOriginTable( + $data['table']->getNameWithoutPrefix() + ), + $data['column'], + $data['type'] + ); + } + + $data['nameWithoutPrefix'] = $nameWithoutPrefix; + return $this->objectManager->create($this->className, $data); } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Index.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Index.php index ea8c07bf19e4c..49436adad04e8 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Index.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Dto/Index.php @@ -39,6 +39,11 @@ class Index extends GenericElement implements */ private $indexType; + /** + * @var string + */ + private $nameWithoutPrefix; + /** * Constructor. * @@ -47,18 +52,21 @@ class Index extends GenericElement implements * @param Table $table * @param array $columns * @param string $indexType + * @param string $nameWithoutPrefix */ public function __construct( string $name, string $type, Table $table, array $columns, - string $indexType + string $indexType, + string $nameWithoutPrefix ) { parent::__construct($name, $type); $this->table = $table; $this->columns = $columns; $this->indexType = $indexType; + $this->nameWithoutPrefix = $nameWithoutPrefix; } /** @@ -123,4 +131,14 @@ public function getIndexType() { return $this->indexType; } + + /** + * Retrieve the index name which is calculated without table prefix. + * + * @return string + */ + public function getNameWithoutPrefix() + { + return $this->nameWithoutPrefix; + } } diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php index 9cda6aa4a8842..9a42090ad31db 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/Operations/AddColumn.php @@ -110,6 +110,7 @@ private function getTemporaryIndexHistory(Column $column) Index::TYPE, [ 'name' => self::TEMPORARY_KEY, + 'column' => $column->getName(), 'columns' => [$column], 'table' => $column->getTable() ] diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/TableNameResolver.php b/lib/internal/Magento/Framework/Setup/Declaration/Schema/TableNameResolver.php new file mode 100644 index 0000000000000..6cca87bd19b80 --- /dev/null +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/TableNameResolver.php @@ -0,0 +1,51 @@ +getFilterPattern(), $tableName, $matches); + + return $tableIsReplica ? $matches['table_name'] : $tableName; + } + + /** + * Provides a RegEx pattern used to search cloned temporary tables used as a replica. + * + * @return string + */ + private function getFilterPattern(): string + { + if (!$this->filterPattern) { + $this->filterPattern = '#(?\S+)_replica$#i'; + } + + return $this->filterPattern; + } +} diff --git a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd index 61540ecc616b0..8c264bd95a076 100644 --- a/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd +++ b/lib/internal/Magento/Framework/Setup/Declaration/Schema/etc/constraints/constraint.xsd @@ -10,6 +10,6 @@ - + diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php index 0a2eb60fda48a..15dfcc746407e 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Db/SchemaBuilderTest.php @@ -133,7 +133,8 @@ public function dataProvider() 'type' => 'primary', 'column' => [ 'first_column' - ] + ], + 'nameWithoutPrefix' => 'PRIMARY', ] ] ], @@ -141,9 +142,10 @@ public function dataProvider() 'second_table' => [ 'FIRST_INDEX' => [ 'name' => 'FIRST_INDEX', + 'nameWithoutPrefix' => 'FIRST_INDEX', 'column' => [ 'ref_column' - ] + ], ] ] ] @@ -221,6 +223,7 @@ private function createPrimaryConstraint(Table $table, array $columns) 'PRIMARY', 'primary', $table, + 'PRIMARY', $columns ); } @@ -240,7 +243,8 @@ private function createIndex($indexName, Table $table, array $columns) 'index', $table, $columns, - 'btree' + 'btree', + $indexName ); } @@ -370,6 +374,7 @@ private function prepareSchemaMocks(array $columns, array $references, array $co 'some_foreign_key', 'foreign', $table, + 'some_foreign_key', $foreignColumn, $refTable, $refColumn, @@ -429,6 +434,7 @@ private function prepareSchemaMocks(array $columns, array $references, array $co 'type' => 'primary', 'columns' => [$firstColumn], 'table' => $table, + 'nameWithoutPrefix' => 'PRIMARY', 'column' => ['first_column'], ] ], @@ -460,6 +466,7 @@ private function prepareSchemaMocks(array $columns, array $references, array $co 'table' => $refTable, 'column' => ['ref_column'], 'columns' => [$refColumn], + 'nameWithoutPrefix' => 'FIRST_INDEX', ] ], [ diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Declaration/SchemaBuilderTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Declaration/SchemaBuilderTest.php index f596a448f1aba..a590a50edb72f 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Declaration/SchemaBuilderTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Declaration/SchemaBuilderTest.php @@ -241,14 +241,16 @@ private function createIntegerColumn($name, Table $table) * * @param Table $table * @param array $columns + * @param string $nameWithoutPrefix * @return Internal */ - private function createPrimaryConstraint(Table $table, array $columns) + private function createPrimaryConstraint(Table $table, array $columns, $nameWithoutPrefix = 'PRIMARY') { return new Internal( 'PRIMARY', 'primary', $table, + $nameWithoutPrefix, $columns ); } @@ -259,16 +261,18 @@ private function createPrimaryConstraint(Table $table, array $columns) * @param string $indexName * @param Table $table * @param array $columns + * @param string|null $nameWithoutPrefix * @return Index */ - private function createIndex($indexName, Table $table, array $columns) + private function createIndex($indexName, Table $table, array $columns, $nameWithoutPrefix = null) { return new Index( $indexName, 'index', $table, $columns, - 'btree' + 'btree', + $nameWithoutPrefix ?: $indexName ); } @@ -295,13 +299,14 @@ private function createTimestampColumn($name, Table $table) * @dataProvider tablesProvider * @param array $tablesData * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @throws \Magento\Framework\Setup\Exception */ public function testBuild(array $tablesData) { $table = $this->createTable('first_table'); $refTable = $this->createTable('second_table'); $refColumn = $this->createIntegerColumn('ref_column', $refTable); - $index = $this->createIndex('FIRST_INDEX', $table, [$refColumn]); + $index = $this->createIndex('PRE_FIRST_INDEX', $table, [$refColumn], 'FIRST_INDEX'); $refTable->addColumns([$refColumn]); $refTable->addIndexes([$index]); $firstColumn = $this->createIntegerAIColumn('first_column', $table); @@ -312,6 +317,7 @@ public function testBuild(array $tablesData) 'some_foreign_key', 'foreign', $table, + 'some_foreign_key', $foreignColumn, $refTable, $refColumn, diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Diff/DiffManagerTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Diff/DiffManagerTest.php index 8a8aecb818348..22dc6c6d18a9e 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Diff/DiffManagerTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Diff/DiffManagerTest.php @@ -107,8 +107,8 @@ public function testRegisterIndexModification() '' ); $column = new Column('third', 'int', $table, 'Previous column'); - $index = new Index('index_type', 'index', $table, [$column], 'btree'); - $generatedIndex = new Index('index_type', 'index', $table, [$column], 'hash'); + $index = new Index('index_type', 'index', $table, [$column], 'btree', 'index_type'); + $generatedIndex = new Index('index_type', 'index', $table, [$column], 'hash', 'index_type'); $diff->expects(self::exactly(2)) ->method('register') ->withConsecutive([$generatedIndex, 'drop_element', $generatedIndex], [$index, 'add_complex_element']); @@ -142,7 +142,7 @@ public function testRegisterRemovalReference() '' ); $column = new Column('third', 'int', $table, 'Previous column'); - $reference = new Reference('ref', 'foreign', $table, $column, $refTable, $column, 'CASCADE'); + $reference = new Reference('ref', 'foreign', $table, 'ref', $column, $refTable, $column, 'CASCADE'); $diff->expects(self::exactly(2)) ->method('register') ->withConsecutive( @@ -169,7 +169,7 @@ public function testRegisterCreation() '' ); $column = new Column('third', 'int', $table, 'Previous column'); - $reference = new Reference('ref', 'foreign', $table, $column, $table, $column, 'CASCADE'); + $reference = new Reference('ref', 'foreign', $table, 'ref', $column, $table, $column, 'CASCADE'); $diff->expects(self::exactly(3)) ->method('register') ->withConsecutive( diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php new file mode 100644 index 0000000000000..ee4331e7bfc5b --- /dev/null +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Dto/Factories/ForeignTest.php @@ -0,0 +1,187 @@ +objectManagerHelper = new ObjectManagerHelper($this); + $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->adapterMock = $this->getMockBuilder(AdapterInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->tableNameResolver = $this->getMockBuilder(TableNameResolver::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->foreignFactory = $this->objectManagerHelper->getObject( + Foreign::class, + [ + 'objectManager' => $this->objectManagerMock, + 'resourceConnection' => $this->resourceConnectionMock, + 'tableNameResolver' => $this->tableNameResolver, + ] + ); + } + + /** + * @param string $prefix + * @dataProvider createDataProvider + */ + public function testCreate(string $prefix) + { + $resource = 'default'; + $tableNameWithoutPrefix = 'table_name'; + $tableName = $prefix . $tableNameWithoutPrefix; + + $columnName = 'entity_id'; + $referenceTableName = 'second_table'; + $referenceColumnName = 'website_id'; + + $foreignKeyNameWithoutPrefix = 'table_name_field_name'; + $foreignKeyName = $prefix . $foreignKeyNameWithoutPrefix; + + $table = $this->objectManagerHelper->getObject( + DataObject::class, + [ + 'data' => [ + 'resource' => $resource, + 'name' => $tableName, + 'name_without_prefix' => $tableNameWithoutPrefix, + ], + ] + ); + + $columnMock = $this->objectManagerHelper->getObject( + DataObject::class, + [ + 'data' => ['name' => $columnName], + ] + ); + + $referenceTableMock = $this->objectManagerHelper->getObject( + DataObject::class, + [ + 'data' => ['name_without_prefix' => $referenceTableName], + ] + ); + + $referenceColumnMock = $this->objectManagerHelper->getObject( + DataObject::class, + [ + 'data' => ['name' => $referenceColumnName], + ] + ); + + $data = [ + 'name' => $foreignKeyName, + 'table' => $table, + 'column' => $columnMock, + 'referenceTable' => $referenceTableMock, + 'referenceColumn' => $referenceColumnMock, + ]; + + $expectedData = array_merge( + $data, + [ + 'onDelete' => Foreign::DEFAULT_ON_DELETE, + 'nameWithoutPrefix' => $foreignKeyNameWithoutPrefix, + ] + ); + + $this->resourceConnectionMock + ->method('getTablePrefix') + ->willReturn($prefix); + + $this->resourceConnectionMock + ->method('getConnection') + ->with($resource) + ->willReturn($this->adapterMock); + + $this->tableNameResolver + ->method('getNameOfOriginTable') + ->with($tableNameWithoutPrefix) + ->willReturn($tableNameWithoutPrefix); + + $this->adapterMock + ->method('getForeignKeyName') + ->with($tableNameWithoutPrefix, $columnName, $referenceTableName, $referenceColumnName) + ->willReturn($foreignKeyNameWithoutPrefix); + + $this->objectManagerMock + ->expects($this->once()) + ->method('create') + ->with(Reference::class, $expectedData); + + $this->foreignFactory->create($data); + } + + /** + * @return array + */ + public function createDataProvider(): array + { + return [ + 'Prefix is defined' => [ + 'pref_', + ], + 'Prefix is not defined' => [ + '', + ], + ]; + } +} diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Operations/AddColumnTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Operations/AddColumnTest.php index d061fc1fb6c9c..a8a8fb5b0c40c 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Operations/AddColumnTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/Operations/AddColumnTest.php @@ -179,7 +179,7 @@ public function testDoOperation() ->method('addElement') ->with('int', 'default', 'table', $definition, 'column') ->willReturn($statement); - $index = new Index('index', 'index', $column->getTable(), [$column], 'btree'); + $index = new Index('index', 'index', $column->getTable(), [$column], 'btree', 'index'); $this->elementFactoryMock->expects(self::once()) ->method('create') ->willReturn($index); diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/CheckReferenceColumnHasIndexTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/CheckReferenceColumnHasIndexTest.php index a0bf758004346..396cc2b2e5b34 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/CheckReferenceColumnHasIndexTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/CheckReferenceColumnHasIndexTest.php @@ -60,6 +60,7 @@ public function testValidate() 'ref', 'foreign', $table, + 'ref', $column, $refTable, $refColumn, diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/ValidationRulesTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/ValidationRulesTest.php index c4e88b569d9c2..ad547053f7bf2 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/ValidationRulesTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/Declaration/Schema/ValidationRules/ValidationRulesTest.php @@ -64,6 +64,7 @@ public function testValidate() 'ref', 'foreign', $table, + 'ref', $column, $refTable, $refColumn, diff --git a/lib/internal/Magento/Framework/Webapi/Rest/Response/FieldsFilter.php b/lib/internal/Magento/Framework/Webapi/Rest/Response/FieldsFilter.php index 9b50b45a9215c..87be46c111545 100644 --- a/lib/internal/Magento/Framework/Webapi/Rest/Response/FieldsFilter.php +++ b/lib/internal/Magento/Framework/Webapi/Rest/Response/FieldsFilter.php @@ -106,9 +106,9 @@ protected function parse($filterString) } switch ($filterString[$position]) { case '[': - array_push($parent, $currentElement); + $parent[] = $currentElement; // push current field in stack and initialize current - array_push($stack, $current); + $stack[] = $current; $current = []; break; diff --git a/lib/web/css/source/lib/_navigation.less b/lib/web/css/source/lib/_navigation.less index 56aa2e7ef86b9..b2ed4352a334a 100644 --- a/lib/web/css/source/lib/_navigation.less +++ b/lib/web/css/source/lib/_navigation.less @@ -355,6 +355,25 @@ overflow: visible !important; } + &.parent { + > .level-top { + padding-right: 20px; + + > .ui-menu-icon { + position: absolute; + right: 0; + + .lib-icon-font( + @icon-down, + @_icon-font-size: 12px, + @_icon-font-line-height: 20px, + @_icon-font-text-hide: true, + @_icon-font-position: after + ); + } + } + } + .submenu { .lib-css(background, @_submenu-background-color); .lib-css(border, @_submenu-border-width @_submenu-border-style @_submenu-border-color); @@ -414,6 +433,26 @@ left: auto !important; right: 100%; } + + li { + margin: 0; + &.parent { + > a { + > .ui-menu-icon { + position: absolute; + right: 3px; + + .lib-icon-font( + @icon-next, + @_icon-font-size: 12px, + @_icon-font-line-height: 20px, + @_icon-font-text-hide: true, + @_icon-font-position: after + ); + } + } + } + } } &.more { diff --git a/lib/web/mage/calendar.js b/lib/web/mage/calendar.js index 51ee9b3a8891a..ac154b333801d 100644 --- a/lib/web/mage/calendar.js +++ b/lib/web/mage/calendar.js @@ -236,12 +236,14 @@ firstDay = parseInt(this._get(inst, 'firstDay'), 10); firstDay = isNaN(firstDay) ? 0 : firstDay; - for (row; row < numMonths[0]; row++) { + for (row = 0; row < numMonths[0]; row++) { this.maxRows = 4; - for (col; col < numMonths[1]; col++) { + for (col = 0; col < numMonths[1]; col++) { selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); + calender = ''; + if (isMultiMonth) { calender += '
' + this._get(inst, 'weekHeader') + '' : ''; - for (dow; dow < 7; dow++) { // days of the week + for (dow = 0; dow < 7; dow++) { // days of the week day = (dow + firstDay) % 7; thead += '= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + @@ -289,7 +291,7 @@ this.maxRows = numRows; printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (dRow; dRow < numRows; dRow++) { // create date picker rows + for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows calender += ''; tbody = !showWeek ? '' : '' + this._get(inst, 'calculateWeek')(printDate) + ''; diff --git a/lib/web/mage/trim-input.js b/lib/web/mage/trim-input.js new file mode 100644 index 0000000000000..678192dcf61ac --- /dev/null +++ b/lib/web/mage/trim-input.js @@ -0,0 +1,60 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery' +], function ($) { + 'use strict'; + + $.widget('mage.trimInput', { + options: { + cache: {} + }, + + /** + * Widget initialization + * @private + */ + _create: function () { + this.options.cache.input = $(this.element); + this._bind(); + }, + + /** + * Event binding, will monitor change, keyup and paste events. + * @private + */ + _bind: function () { + if (this.options.cache.input.length) { + this._on(this.options.cache.input, { + 'change': this._trimInput, + 'keyup': this._trimInput, + 'paste': this._trimInput + }); + } + }, + + /** + * Trim value + * @private + */ + _trimInput: function () { + var input = this._getInputValue().trim(); + + this.options.cache.input.val(input); + }, + + /** + * Get input value + * @returns {*} + * @private + */ + _getInputValue: function () { + return this.options.cache.input.val(); + } + }); + + return $.mage.trimInput; +}); diff --git a/lib/web/modernizr/modernizr.js b/lib/web/modernizr/modernizr.js index 9b4f68aaaaaa9..0833cfb105cee 100644 --- a/lib/web/modernizr/modernizr.js +++ b/lib/web/modernizr/modernizr.js @@ -910,7 +910,7 @@ window.Modernizr = (function( window, document, undefined ) { bool = inputElem.checkValidity && inputElem.checkValidity() === false; } else { - // If the upgraded input compontent rejects the :) text, we got a winner + // If the upgraded input component rejects the :) text, we got a winner bool = inputElem.value != smile; } } diff --git a/setup/src/Magento/Setup/Fixtures/OrdersFixture.php b/setup/src/Magento/Setup/Fixtures/OrdersFixture.php index 1acad6dbc1787..9fbec3b3741b2 100644 --- a/setup/src/Magento/Setup/Fixtures/OrdersFixture.php +++ b/setup/src/Magento/Setup/Fixtures/OrdersFixture.php @@ -14,7 +14,7 @@ * Optionally generates inactive quotes for generated orders. * * Support the following format: - * + * * {bool} * * diff --git a/setup/src/Magento/Setup/Module/Dependency/Circular.php b/setup/src/Magento/Setup/Module/Dependency/Circular.php index 8f5bd8716f650..a10d2752fa410 100644 --- a/setup/src/Magento/Setup/Module/Dependency/Circular.php +++ b/setup/src/Magento/Setup/Module/Dependency/Circular.php @@ -118,7 +118,7 @@ protected function buildCircular($modules) return; } $this->circularDependencies[$path] = $modules; - array_push($modules, array_shift($modules)); + $modules[] = array_shift($modules); $this->buildCircular($modules); } @@ -133,7 +133,7 @@ protected function divideByModules($circularDependencies) $dependenciesByModule = []; foreach ($circularDependencies as $circularDependency) { $module = $circularDependency[0]; - array_push($circularDependency, $module); + $circularDependency[] = $module; $dependenciesByModule[$module][] = $circularDependency; } diff --git a/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlInterceptorScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlInterceptorScanner.php index e88ca9197096a..75c6e1144e8d2 100644 --- a/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlInterceptorScanner.php +++ b/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlInterceptorScanner.php @@ -42,9 +42,9 @@ protected function _collectEntitiesFromString($content) $attributes = $entityNode->attributes; $type = $attributes->getNamedItem('type'); if ($type !== null) { - array_push($output, $type->nodeValue); + $output[] = $type->nodeValue; } else { - array_push($output, $attributes->getNamedItem('name')->nodeValue); + $output[] = $attributes->getNamedItem('name')->nodeValue; } } return $output; @@ -80,7 +80,7 @@ protected function _filterEntities(array $output) $this->_handleControllerClassName($entityName); } if (class_exists($entityName) || interface_exists($entityName)) { - array_push($filteredEntities, $entityName . '\\Interceptor'); + $filteredEntities[] = $entityName . '\\Interceptor'; } } return $filteredEntities; diff --git a/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlScanner.php index 37388f563e75b..a606c266d3827 100644 --- a/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlScanner.php +++ b/setup/src/Magento/Setup/Module/Di/Code/Scanner/XmlScanner.php @@ -104,7 +104,7 @@ protected function _filterEntities(array $output) } if (false === $isClassExists) { if (class_exists($entityName) || interface_exists($entityName)) { - array_push($filteredEntities, $className); + $filteredEntities[] = $className; } else { $this->_log->add( \Magento\Setup\Module\Di\Compiler\Log\Log::CONFIGURATION_ERROR,