From 7aef59b58158c2c5f031a15550e590e3b499c989 Mon Sep 17 00:00:00 2001 From: magento packaging service Date: Thu, 8 Feb 2024 16:53:10 +0000 Subject: [PATCH] Magento Release 2.4.4-p7 --- app/code/Magento/AdminAnalytics/composer.json | 24 +- .../Magento/AdminNotification/composer.json | 24 +- .../AdvancedPricingImportExport/composer.json | 30 +- app/code/Magento/AdvancedSearch/composer.json | 28 +- app/code/Magento/Amqp/composer.json | 18 +- app/code/Magento/AmqpStore/composer.json | 22 +- ...minAdvancedReportingPageUrlActionGroup.xml | 2 +- app/code/Magento/Analytics/composer.json | 18 +- .../AsynchronousOperations/composer.json | 26 +- app/code/Magento/Authorization/composer.json | 16 +- app/code/Magento/AwsS3/composer.json | 14 +- .../Block/System/Store/Grid/Render/Group.php | 10 +- app/code/Magento/Backend/composer.json | 50 +- app/code/Magento/Backup/composer.json | 20 +- ...tAddProductToCartFromBundleActionGroup.xml | 4 + app/code/Magento/Bundle/composer.json | 52 +- .../view/type/bundle/option/radio.phtml | 50 +- app/code/Magento/BundleGraphQl/composer.json | 28 +- .../Magento/BundleImportExport/composer.json | 26 +- .../Magento/CacheInvalidate/composer.json | 16 +- ...ontCaptchaOnOnepageCheckoutPyamentTest.xml | 2 + app/code/Magento/Captcha/composer.json | 26 +- .../Magento/CardinalCommerce/composer.json | 20 +- .../Adminhtml/Product/NewAction.php | 25 +- .../Section/StorefrontCategoryMainSection.xml | 1 + .../AdminApplyTierPriceToProductTest.xml | 1 + ...ProductAttributeUpdateAddedToQueueTest.xml | 2 + ...ctedUserAddCategoryFromProductPageTest.xml | 1 + ...ularPriceInStockEnabledFlatCatalogTest.xml | 6 +- .../Test/Mftf/Test/EndToEndB2CAdminTest.xml | 4 + .../Adminhtml/Product/NewActionTest.php | 81 +- .../Unit/Pricing/Render/FinalPriceBoxTest.php | 33 + app/code/Magento/Catalog/composer.json | 70 +- app/code/Magento/Catalog/i18n/en_US.csv | 2 + .../view/adminhtml/web/js/category-tree.js | 5 +- .../Magento/CatalogAnalytics/composer.json | 14 +- .../Magento/CatalogCmsGraphQl/composer.json | 22 +- .../CatalogCustomerGraphQl/composer.json | 16 +- app/code/Magento/CatalogGraphQl/composer.json | 36 +- .../Model/Import/Product.php | 6 + .../Magento/CatalogImportExport/composer.json | 34 +- .../Magento/CatalogInventory/composer.json | 28 +- .../CatalogInventoryGraphQl/composer.json | 18 +- app/code/Magento/CatalogRule/composer.json | 32 +- .../CatalogRuleConfigurable/composer.json | 22 +- .../Magento/CatalogRuleGraphQl/composer.json | 14 +- app/code/Magento/CatalogSearch/composer.json | 38 +- .../Magento/CatalogUrlRewrite/composer.json | 32 +- .../CatalogUrlRewriteGraphQl/composer.json | 26 +- ...frontProductGridUIUpdatesOnDesktopTest.xml | 1 + app/code/Magento/CatalogWidget/composer.json | 32 +- .../Controller/Sidebar/UpdateItemQty.php | 16 +- .../Checkout/Model/DefaultConfigProvider.php | 12 +- .../Model/ShippingInformationManagement.php | 34 +- .../AssertMiniCartEmptyActionGroup.xml | 3 +- .../CheckoutPlaceOrderActionGroup.xml | 4 + ...ckoutAsCustomerUsingDefaultAddressTest.xml | 3 +- ...utAsCustomerUsingNonDefaultAddressTest.xml | 2 + ...ntCheckoutWithSpecialPriceProductsTest.xml | 2 + ...refrontCustomerLoginDuringCheckoutTest.xml | 3 +- ...ontVerifySecureURLRedirectCheckoutTest.xml | 4 +- .../Controller/Sidebar/UpdateItemQtyTest.php | 35 + app/code/Magento/Checkout/composer.json | 56 +- .../Magento/Checkout/etc/adminhtml/system.xml | 7 +- app/code/Magento/Checkout/etc/config.xml | 1 + app/code/Magento/Checkout/i18n/en_US.csv | 1 + ...dminDeleteAllTermConditionsActionGroup.xml | 27 + .../Mftf/Helper/CheckoutAgreementsHelpers.php | 61 + .../Mftf/Section/AdminTermGridSection.xml | 2 + .../AdminCreateActiveHtmlTermEntityTest.xml | 7 +- .../AdminCreateActiveTextTermEntityTest.xml | 4 +- .../Magento/CheckoutAgreements/composer.json | 22 +- .../CheckoutAgreementsGraphQl/composer.json | 18 +- .../Magento/Cms/Controller/Noroute/Index.php | 7 +- .../Unit/Controller/Noroute/IndexTest.php | 12 +- app/code/Magento/Cms/composer.json | 34 +- app/code/Magento/CmsGraphQl/composer.json | 24 +- app/code/Magento/CmsUrlRewrite/composer.json | 20 +- .../CmsUrlRewriteGraphQl/composer.json | 24 +- .../Magento/CompareListGraphQl/composer.json | 14 +- .../Block/System/Config/Form/Field/File.php | 4 +- .../System/Config/Form/Field/FileTest.php | 81 +- app/code/Magento/Config/composer.json | 28 +- .../ConfigurableImportExport/composer.json | 26 +- .../CreateNewAttributeActionGroup.xml | 1 + ...igurableProductAttributeNameDesignData.xml | 2 +- .../CatalogProductsSection.xml | 2 +- .../ConfigurableProductSection.xml | 2 +- ...hVisualSwatchAttributePrependMediaTest.xml | 41 +- .../Magento/ConfigurableProduct/composer.json | 50 +- .../ConfigurableProductGraphQl/composer.json | 24 +- .../ConfigurableProductSales/composer.json | 22 +- app/code/Magento/Contact/composer.json | 22 +- app/code/Magento/Cookie/composer.json | 18 +- app/code/Magento/Cron/composer.json | 18 +- app/code/Magento/Csp/composer.json | 16 +- ...kCurrencyConverterApiConfigurationTest.xml | 2 + app/code/Magento/CurrencySymbol/composer.json | 24 +- .../Api/AccountManagementInterface.php | 3 +- .../Customer/Controller/Account/Confirm.php | 78 +- .../Controller/Account/Confirmation.php | 62 +- .../Customer/Controller/Account/EditPost.php | 108 +- .../Customer/Model/AccountConfirmation.php | 75 +- .../Customer/Model/AccountManagement.php | 106 +- .../Customer/Model/EmailNotification.php | 73 +- .../Plugin/ClearSessionsAfterLogoutPlugin.php | 108 + .../Model/Plugin/CustomerNotification.php | 70 +- .../Customer/Model/Plugin/UpdateCustomer.php | 19 +- .../Customer/Model/ResourceModel/Customer.php | 132 +- .../Controller/Rest/ValidateCustomerData.php | 55 + .../Mftf/Test/EndToEndB2CLoggedInUserTest.xml | 2 + .../Unit/Controller/Account/ConfirmTest.php | 86 +- .../Model/Plugin/CustomerNotificationTest.php | 25 +- .../Rest/ValidateCustomerDataTest.php | 123 + app/code/Magento/Customer/composer.json | 56 +- .../Magento/Customer/etc/adminhtml/system.xml | 4 + app/code/Magento/Customer/etc/config.xml | 1 + app/code/Magento/Customer/etc/frontend/di.xml | 3 + .../Magento/Customer/etc/webapi_rest/di.xml | 3 + .../Magento/CustomerAnalytics/composer.json | 14 +- .../CustomerDownloadableGraphQl/composer.json | 18 +- .../Magento/CustomerGraphQl/composer.json | 30 +- .../CustomerImportExport/composer.json | 26 +- app/code/Magento/Deploy/composer.json | 22 +- app/code/Magento/Developer/composer.json | 18 +- app/code/Magento/Dhl/composer.json | 34 +- app/code/Magento/Directory/composer.json | 20 +- .../Magento/DirectoryGraphQl/composer.json | 16 +- app/code/Magento/Downloadable/composer.json | 48 +- .../Magento/DownloadableGraphQl/composer.json | 28 +- .../DownloadableImportExport/composer.json | 26 +- app/code/Magento/Eav/composer.json | 24 +- app/code/Magento/EavGraphQl/composer.json | 16 +- .../SearchAdapter/Query/Builder/Sort.php | 3 +- app/code/Magento/Elasticsearch/composer.json | 32 +- app/code/Magento/Elasticsearch6/composer.json | 24 +- app/code/Magento/Elasticsearch7/composer.json | 24 +- .../Magento/Email/Model/Template/Filter.php | 13 +- app/code/Magento/Email/composer.json | 34 +- app/code/Magento/EncryptionKey/composer.json | 18 +- .../Fedex/Model/Config/Backend/FedexUrl.php | 75 + .../Model/Config/Backend/FedexUrlTest.php | 131 + app/code/Magento/Fedex/composer.json | 30 +- .../Magento/Fedex/etc/adminhtml/system.xml | 2 + app/code/Magento/Fedex/i18n/en_US.csv | 1 + app/code/Magento/GiftMessage/composer.json | 34 +- .../Magento/GiftMessageGraphQl/composer.json | 16 +- app/code/Magento/GoogleAdwords/composer.json | 18 +- .../Magento/GoogleAnalytics/composer.json | 22 +- .../Magento/GoogleOptimizer/composer.json | 26 +- app/code/Magento/GraphQl/composer.json | 22 +- app/code/Magento/GraphQlCache/composer.json | 18 +- .../GroupedCatalogInventory/composer.json | 20 +- .../Magento/GroupedImportExport/composer.json | 24 +- app/code/Magento/GroupedProduct/composer.json | 42 +- .../GroupedProductGraphQl/composer.json | 16 +- app/code/Magento/ImportExport/composer.json | 26 +- app/code/Magento/Indexer/composer.json | 16 +- .../Magento/InstantPurchase/composer.json | 18 +- app/code/Magento/Integration/composer.json | 28 +- .../Magento/JwtFrameworkAdapter/composer.json | 14 +- app/code/Magento/JwtUserToken/composer.json | 18 +- .../Magento/LayeredNavigation/composer.json | 18 +- .../Magento/LoginAsCustomer/composer.json | 22 +- .../LoginAsCustomerAdminUi/composer.json | 29 +- .../Magento/LoginAsCustomerApi/composer.json | 10 +- .../LoginAsCustomerAssistance/composer.json | 29 +- .../LoginAsCustomerFrontendUi/composer.json | 17 +- .../LoginAsCustomerGraphQl/composer.json | 26 +- .../Magento/LoginAsCustomerLog/composer.json | 27 +- .../LoginAsCustomerPageCache/composer.json | 21 +- .../LoginAsCustomerQuote/composer.json | 23 +- .../LoginAsCustomerSales/composer.json | 23 +- app/code/Magento/Marketplace/composer.json | 16 +- .../view/adminhtml/templates/index.phtml | 6 +- app/code/Magento/MediaContent/composer.json | 14 +- .../Magento/MediaContentApi/composer.json | 12 +- .../Magento/MediaContentCatalog/composer.json | 18 +- .../Magento/MediaContentCms/composer.json | 14 +- .../MediaContentSynchronization/composer.json | 24 +- .../composer.json | 12 +- .../composer.json | 16 +- .../composer.json | 16 +- app/code/Magento/MediaGallery/composer.json | 14 +- .../Magento/MediaGalleryApi/composer.json | 10 +- .../Magento/MediaGalleryCatalog/composer.json | 14 +- .../composer.json | 24 +- .../MediaGalleryCatalogUi/composer.json | 20 +- .../Magento/MediaGalleryCmsUi/composer.json | 14 +- .../MediaGalleryIntegration/composer.json | 32 +- .../MediaGalleryMetadata/composer.json | 12 +- .../MediaGalleryMetadataApi/composer.json | 10 +- .../MediaGalleryRenditions/composer.json | 24 +- .../MediaGalleryRenditionsApi/composer.json | 10 +- .../MediaGallerySynchronization/composer.json | 16 +- .../composer.json | 12 +- .../composer.json | 16 +- app/code/Magento/MediaGalleryUi/composer.json | 32 +- .../Magento/MediaGalleryUiApi/composer.json | 16 +- app/code/Magento/MediaStorage/composer.json | 30 +- app/code/Magento/MessageQueue/composer.json | 16 +- app/code/Magento/Msrp/composer.json | 28 +- .../MsrpConfigurableProduct/composer.json | 20 +- .../Magento/MsrpGroupedProduct/composer.json | 20 +- app/code/Magento/Multishipping/composer.json | 34 +- app/code/Magento/MysqlMq/composer.json | 18 +- .../Magento/NewRelicReporting/composer.json | 26 +- ...ingDeleteNewsletterTemplateActionGroup.xml | 2 + ...nNewsletterTemplateFromGridActionGroup.xml | 2 + app/code/Magento/Newsletter/composer.json | 32 +- .../Magento/NewsletterGraphQl/composer.json | 22 +- .../Magento/OfflinePayments/composer.json | 22 +- .../Magento/OfflineShipping/composer.json | 36 +- .../Magento/PageCache/Controller/Block.php | 86 +- .../Test/Unit/Controller/Block/EsiTest.php | 20 +- .../Test/Unit/Controller/Block/RenderTest.php | 20 +- app/code/Magento/PageCache/composer.json | 20 +- .../PageCache/etc/adminhtml/system.xml | 4 + app/code/Magento/PageCache/etc/config.xml | 1 + app/code/Magento/PageCache/etc/di.xml | 1 + app/code/Magento/Payment/composer.json | 28 +- app/code/Magento/PaymentGraphQl/composer.json | 18 +- app/code/Magento/Paypal/composer.json | 50 +- ...frontPaymentsCaptchaWithPayflowProTest.xml | 2 + app/code/Magento/PaypalCaptcha/composer.json | 22 +- app/code/Magento/PaypalGraphQl/composer.json | 34 +- ...CartPersistenceUnderLongTermCookieTest.xml | 1 + app/code/Magento/Persistent/composer.json | 26 +- app/code/Magento/ProductAlert/composer.json | 32 +- app/code/Magento/ProductVideo/composer.json | 28 +- .../Quote/Model/BillingAddressManagement.php | 17 +- app/code/Magento/Quote/Model/Quote.php | 28 +- .../Quote/Model/QuoteAddressValidator.php | 109 +- .../Quote/Model/ShippingMethodManagement.php | 29 +- .../Controller/Rest/ValidateQuoteData.php | 55 + .../Quote/Test/Unit/Model/QuoteTest.php | 13 +- .../Model/ShippingMethodManagementTest.php | 214 +- .../Controller/Rest/ValidateQuoteDataTest.php | 113 + app/code/Magento/Quote/composer.json | 44 +- app/code/Magento/Quote/etc/webapi_rest/di.xml | 3 + app/code/Magento/Quote/i18n/en_US.csv | 2 + app/code/Magento/QuoteAnalytics/composer.json | 14 +- .../Magento/QuoteBundleOptions/composer.json | 12 +- .../QuoteConfigurableOptions/composer.json | 12 +- .../QuoteDownloadableLinks/composer.json | 12 +- .../Model/Resolver/RemoveItemFromCart.php | 3 +- app/code/Magento/QuoteGraphQl/composer.json | 40 +- .../RelatedProductGraphQl/composer.json | 18 +- .../Magento/ReleaseNotification/composer.json | 22 +- app/code/Magento/RemoteStorage/composer.json | 36 +- app/code/Magento/Reports/composer.json | 48 +- app/code/Magento/RequireJs/composer.json | 14 +- app/code/Magento/Review/composer.json | 34 +- .../Magento/ReviewAnalytics/composer.json | 14 +- app/code/Magento/ReviewGraphQl/composer.json | 22 +- app/code/Magento/Robots/composer.json | 18 +- app/code/Magento/Rss/composer.json | 20 +- app/code/Magento/Rule/composer.json | 22 +- .../Controller/Adminhtml/Order/AddComment.php | 9 +- .../Adminhtml/Order/Create/LoadBlock.php | 55 +- ...teToNewOrderPageNewCustomerActionGroup.xml | 23 + ...tCreateOrderWithDifferentAddressesTest.xml | 3 +- app/code/Magento/Sales/composer.json | 64 +- app/code/Magento/SalesAnalytics/composer.json | 14 +- app/code/Magento/SalesGraphQl/composer.json | 24 +- app/code/Magento/SalesInventory/composer.json | 22 +- .../Adminhtml/Promo/Quote/Generate.php | 109 +- ...StorefrontApplyDiscountCodeActionGroup.xml | 2 +- .../Adminhtml/Promo/Quote/GenerateTest.php | 228 +- app/code/Magento/SalesRule/composer.json | 58 +- .../SalesRule/etc/adminhtml/system.xml | 13 +- app/code/Magento/SalesRule/etc/config.xml | 1 + app/code/Magento/SalesRule/etc/di.xml | 9 +- app/code/Magento/SalesRule/i18n/en_US.csv | 3 + app/code/Magento/SalesSequence/composer.json | 14 +- app/code/Magento/SampleData/composer.json | 16 +- app/code/Magento/Search/composer.json | 24 +- app/code/Magento/Security/composer.json | 24 +- app/code/Magento/SendFriend/composer.json | 26 +- .../Magento/SendFriendGraphQl/composer.json | 16 +- app/code/Magento/Shipping/composer.json | 46 +- app/code/Magento/Sitemap/composer.json | 34 +- app/code/Magento/Store/Model/Group.php | 35 +- .../StorefrontSwitchStoreViewActionGroup.xml | 1 + app/code/Magento/Store/composer.json | 32 +- app/code/Magento/Store/etc/config.xml | 1 + app/code/Magento/StoreGraphQl/composer.json | 16 +- app/code/Magento/Swagger/composer.json | 14 +- app/code/Magento/SwaggerWebapi/composer.json | 16 +- .../Magento/SwaggerWebapiAsync/composer.json | 18 +- ...AssertStorefrontSwatchColorActionGroup.xml | 3 +- .../AssertSwatchColorActionGroup.xml | 3 +- .../Mftf/Section/AdminManageSwatchSection.xml | 1 + .../StorefrontFilterByImageSwatchTest.xml | 3 +- ...tSwatchProductWithFileCustomOptionTest.xml | 3 + .../Renderer/Listing/ConfigurableTest.php | 15 +- app/code/Magento/Swatches/composer.json | 38 +- .../Magento/SwatchesGraphQl/composer.json | 20 +- .../SwatchesLayeredNavigation/composer.json | 14 +- .../Test/AdminCheckCreditMemoTotalsTest.xml | 2 + app/code/Magento/Tax/composer.json | 44 +- app/code/Magento/TaxGraphQl/composer.json | 16 +- .../Magento/TaxImportExport/composer.json | 24 +- app/code/Magento/Theme/composer.json | 40 +- .../Theme/view/adminhtml/requirejs-config.js | 7 - .../Theme/view/frontend/requirejs-config.js | 3 - app/code/Magento/ThemeGraphQl/composer.json | 14 +- app/code/Magento/Translation/composer.json | 24 +- app/code/Magento/Ui/composer.json | 26 +- app/code/Magento/Ups/composer.json | 30 +- .../Test/Mftf/Data/UrlRewriteData.xml | 4 +- app/code/Magento/UrlRewrite/composer.json | 28 +- .../Magento/UrlRewriteGraphQl/composer.json | 16 +- .../Test/AdminCreateActiveUserEntityTest.xml | 2 +- app/code/Magento/User/composer.json | 28 +- app/code/Magento/Usps/Helper/Data.php | 12 +- app/code/Magento/Usps/Model/Carrier.php | 16 + .../Usps/Model/Config/Backend/UspsUrl.php | 76 + .../Setup/Patch/Data/UpdateAllowedMethods.php | 13 +- .../Usps/Test/Unit/Helper/DataTest.php | 8 + .../Usps/Test/Unit/Model/CarrierTest.php | 3 +- .../Unit/Model/Config/Backend/UspsUrlTest.php | 124 + app/code/Magento/Usps/composer.json | 30 +- .../Magento/Usps/etc/adminhtml/system.xml | 2 + app/code/Magento/Usps/etc/config.xml | 2 +- app/code/Magento/Usps/i18n/en_US.csv | 9 + app/code/Magento/Variable/composer.json | 22 +- app/code/Magento/Vault/composer.json | 29 +- app/code/Magento/VaultGraphQl/composer.json | 14 +- app/code/Magento/Version/composer.json | 14 +- app/code/Magento/Webapi/composer.json | 26 +- app/code/Magento/WebapiAsync/composer.json | 24 +- app/code/Magento/WebapiSecurity/composer.json | 16 +- app/code/Magento/Weee/composer.json | 40 +- app/code/Magento/WeeeGraphQl/composer.json | 20 +- .../Magento/Widget/Model/Widget/Instance.php | 22 +- app/code/Magento/Widget/composer.json | 32 +- app/code/Magento/Wishlist/composer.json | 48 +- .../Magento/WishlistAnalytics/composer.json | 14 +- .../Magento/WishlistGraphQl/composer.json | 22 +- .../adminhtml/Magento/backend/composer.json | 14 +- .../frontend/Magento/blank/composer.json | 14 +- .../frontend/Magento/luma/composer.json | 16 +- app/etc/di.xml | 1 + app/i18n/Magento/de_DE/composer.json | 6 +- app/i18n/Magento/en_US/composer.json | 6 +- app/i18n/Magento/es_ES/composer.json | 6 +- app/i18n/Magento/fr_FR/composer.json | 6 +- app/i18n/Magento/nl_NL/composer.json | 6 +- app/i18n/Magento/pt_BR/composer.json | 6 +- app/i18n/Magento/zh_Hans_CN/composer.json | 6 +- composer.json | 537 +- composer.lock | 77 +- .../TestCase/GraphQlAbstract.php | 4 +- .../Customer/Api/AccountManagementTest.php | 35 +- .../GraphQl/Catalog/ProductPriceTest.php | 13 +- .../GraphQl/Customer/IsEmailAvailableTest.php | 35 +- .../SubscribeEmailToNewsletterTest.php | 23 +- .../GraphQl/Quote/CartPromotionsTest.php | 6 +- .../Quote/Customer/RemoveItemFromCartTest.php | 55 +- .../Magento/TestFramework/ErrorLog/Logger.php | 11 +- .../PublisherConsumerController.php | 7 +- .../Command/ProductAttributesCleanUpTest.php | 1 + .../Indexer/Product/Flat/ProcessorTest.php | 11 +- .../Wysiwyg/Images/DeleteFilesTest.php | 2 - .../Customer/Model/AccountManagementTest.php | 32 +- .../View/Element/AbstractBlockTest.php | 5 +- .../Controller/Subscriber/NewActionTest.php | 15 +- .../Quote/Model/QuoteManagementTest.php | 8 +- .../Magento/Quote/Model/QuoteTest.php | 2 +- .../Model/ShippingMethodManagementTest.php | 9 +- .../Rule/Action/Discount/CartFixedTest.php | 9 +- .../Tax/Model/Sales/Total/Quote/TaxTest.php | 14 +- .../Magento/Tax/Model/TaxCalculationTest.php | 23 +- .../Integrity/Magento/Payment/MethodsTest.php | 11 +- .../Magento/Ups/Model/CarrierTest.php | 75 +- .../Ups/_files/ups_rates_response_option9.xml | 299 + .../constraint_modification.mariadb10427.php | 59 + .../constraint_modification.mysql829.php | 59 + .../rollback.mariadb10427.php | 27 + .../rollback.mysql829.php | 27 + .../table_removal.mariadb10427.php | 14 + .../table_removal.mysql829.php | 14 + .../table_rename.mariadb10427.php | 15 + .../table_rename.mysql829.php | 15 + .../fixture/dry_run_log.mysql829.php | 58 + .../fixture/shards.mariadb10427.php | 38 + .../fixture/shards.mysql829.php | 38 + .../disabling_tables.mariadb10427.php | 14 + .../disabling_tables.mysql829.php | 14 + .../Annotation/DataProviderFromFile.php | 6 +- .../TestFramework/TestCase/SetupTestCase.php | 38 +- .../Setup/DeclarativeInstallerTest.php | 38 +- .../testsuite/Magento/Setup/ShardingTest.php | 24 +- lib/internal/GnuFreeFont/gpl-3.0.txt | 674 + .../Magento/Framework/Amqp/Config.php | 20 +- .../Magento/Framework/Amqp/composer.json | 18 +- .../Magento/Framework/App/Http/Context.php | 28 +- .../App/Test/Unit/Http/ContextTest.php | 39 +- .../Magento/Framework/Bulk/composer.json | 18 +- .../DB/Adapter/SqlVersionProvider.php | 40 + lib/internal/Magento/Framework/DataObject.php | 3 +- .../Filesystem/Directory/PathValidator.php | 7 +- .../Framework/Filesystem/File/Write.php | 19 +- .../Framework/Filter/Input/MaliciousCode.php | 31 +- .../Framework/Filter/Input/Purifier.php | 46 + .../Filter/Input/PurifierInterface.php | 19 + .../Magento/Framework/Filter/Template.php | 127 +- .../Filter/Template/FilteringDepthMeter.php | 52 + .../Filter/Template/SignatureProvider.php | 53 + .../Test/Unit/Input/MaliciousCodeTest.php | 48 +- .../Unit/Template/SignatureProviderTest.php | 54 + .../Filter/Test/Unit/TemplateTest.php | 61 +- .../Framework/MessageQueue/composer.json | 18 +- .../Magento/Framework/RegexValidator.php | 53 + .../Framework/Search/Request/Binder.php | 2 +- .../Schema/Dto/Factories/Table.php | 98 +- .../Framework/Setup/Test/Unit/ListsTest.php | 27 +- .../Framework/Url/Test/Unit/ValidatorTest.php | 12 + .../Magento/Framework/Url/Validator.php | 12 +- .../Framework/View/Element/AbstractBlock.php | 54 +- .../Test/Unit/Element/AbstractBlockTest.php | 55 +- lib/internal/Magento/Framework/composer.json | 13 +- lib/internal/Magento/Framework/composer.lock | 3985 ++ .../fileUploader/vendor/jquery.ui.widget.js | 1508 +- lib/web/jquery/jquery-ui.js | 36624 ++++++++-------- lib/web/jquery/jquery.validate.js | 37 +- lib/web/jquery/patches/jquery-ui-sortable.js | 298 - lib/web/jquery/ui-modules/data.js | 44 +- .../jquery/ui-modules/disable-selection.js | 56 +- lib/web/jquery/ui-modules/effect.js | 1888 +- .../jquery/ui-modules/effects/effect-blind.js | 92 +- .../ui-modules/effects/effect-bounce.js | 146 +- .../jquery/ui-modules/effects/effect-clip.js | 82 +- .../jquery/ui-modules/effects/effect-drop.js | 92 +- .../ui-modules/effects/effect-explode.js | 182 +- .../jquery/ui-modules/effects/effect-fade.js | 58 +- .../jquery/ui-modules/effects/effect-fold.js | 142 +- .../ui-modules/effects/effect-highlight.js | 78 +- .../jquery/ui-modules/effects/effect-puff.js | 50 +- .../ui-modules/effects/effect-pulsate.js | 78 +- .../jquery/ui-modules/effects/effect-scale.js | 82 +- .../jquery/ui-modules/effects/effect-shake.js | 94 +- .../jquery/ui-modules/effects/effect-size.js | 350 +- .../jquery/ui-modules/effects/effect-slide.js | 104 +- .../ui-modules/effects/effect-transfer.js | 42 +- lib/web/jquery/ui-modules/focusable.js | 110 +- lib/web/jquery/ui-modules/form-reset-mixin.js | 106 +- lib/web/jquery/ui-modules/jquery-patch.js | 100 +- lib/web/jquery/ui-modules/keycode.js | 56 +- lib/web/jquery/ui-modules/labels.js | 76 +- lib/web/jquery/ui-modules/position.js | 976 +- lib/web/jquery/ui-modules/scroll-parent.js | 56 +- lib/web/jquery/ui-modules/tabbable.js | 34 +- lib/web/jquery/ui-modules/unique-id.js | 64 +- lib/web/jquery/ui-modules/version.js | 22 +- lib/web/jquery/ui-modules/widget.js | 1466 +- .../jquery/ui-modules/widgets/accordion.js | 1198 +- .../jquery/ui-modules/widgets/autocomplete.js | 1301 +- lib/web/jquery/ui-modules/widgets/button.js | 842 +- .../ui-modules/widgets/checkboxradio.js | 531 +- .../jquery/ui-modules/widgets/controlgroup.js | 558 +- .../jquery/ui-modules/widgets/datepicker.js | 4430 +- lib/web/jquery/ui-modules/widgets/dialog.js | 1860 +- .../jquery/ui-modules/widgets/draggable.js | 2480 +- .../jquery/ui-modules/widgets/droppable.js | 964 +- lib/web/jquery/ui-modules/widgets/menu.js | 1384 +- lib/web/jquery/ui-modules/widgets/mouse.js | 440 +- .../jquery/ui-modules/widgets/progressbar.js | 302 +- .../jquery/ui-modules/widgets/resizable.js | 2340 +- .../jquery/ui-modules/widgets/selectable.js | 596 +- .../jquery/ui-modules/widgets/selectmenu.js | 1340 +- lib/web/jquery/ui-modules/widgets/slider.js | 1468 +- lib/web/jquery/ui-modules/widgets/sortable.js | 3193 +- lib/web/jquery/ui-modules/widgets/spinner.js | 1116 +- lib/web/jquery/ui-modules/widgets/tabs.js | 1802 +- lib/web/jquery/ui-modules/widgets/tooltip.js | 1003 +- lib/web/moment.js | 5 +- pub/errors/default/page.phtml | 4 +- pub/errors/processor.php | 2 +- setup/pub/fonts/opensans/LICENSE-2.0.txt | 202 + 481 files changed, 50007 insertions(+), 40778 deletions(-) mode change 100644 => 100755 app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php create mode 100644 app/code/Magento/CheckoutAgreements/Test/Mftf/ActionGroup/AdminDeleteAllTermConditionsActionGroup.xml create mode 100644 app/code/Magento/CheckoutAgreements/Test/Mftf/Helper/CheckoutAgreementsHelpers.php create mode 100644 app/code/Magento/Customer/Model/Plugin/ClearSessionsAfterLogoutPlugin.php create mode 100644 app/code/Magento/Customer/Plugin/Webapi/Controller/Rest/ValidateCustomerData.php create mode 100644 app/code/Magento/Customer/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateCustomerDataTest.php create mode 100755 app/code/Magento/Fedex/Model/Config/Backend/FedexUrl.php create mode 100755 app/code/Magento/Fedex/Test/Unit/Model/Config/Backend/FedexUrlTest.php mode change 100644 => 100755 app/code/Magento/PageCache/Controller/Block.php create mode 100644 app/code/Magento/Quote/Plugin/Webapi/Controller/Rest/ValidateQuoteData.php create mode 100644 app/code/Magento/Quote/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateQuoteDataTest.php create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageNewCustomerActionGroup.xml mode change 100644 => 100755 app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php mode change 100644 => 100755 app/code/Magento/SalesRule/Test/Unit/Controller/Adminhtml/Promo/Quote/GenerateTest.php mode change 100644 => 100755 app/code/Magento/SalesRule/etc/adminhtml/system.xml mode change 100644 => 100755 app/code/Magento/SalesRule/etc/config.xml mode change 100644 => 100755 app/code/Magento/SalesRule/etc/di.xml mode change 100644 => 100755 app/code/Magento/SalesRule/i18n/en_US.csv create mode 100644 app/code/Magento/Usps/Model/Config/Backend/UspsUrl.php create mode 100644 app/code/Magento/Usps/Test/Unit/Model/Config/Backend/UspsUrlTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Ups/_files/ups_rates_response_option9.xml create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mysql829.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mysql829.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mysql829.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mysql829.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.mysql829.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mysql829.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mysql829.php create mode 100644 lib/internal/GnuFreeFont/gpl-3.0.txt create mode 100644 lib/internal/Magento/Framework/Filter/Input/Purifier.php create mode 100644 lib/internal/Magento/Framework/Filter/Input/PurifierInterface.php create mode 100644 lib/internal/Magento/Framework/Filter/Template/FilteringDepthMeter.php create mode 100644 lib/internal/Magento/Framework/Filter/Template/SignatureProvider.php create mode 100644 lib/internal/Magento/Framework/Filter/Test/Unit/Template/SignatureProviderTest.php create mode 100644 lib/internal/Magento/Framework/RegexValidator.php create mode 100644 lib/internal/Magento/Framework/composer.lock delete mode 100644 lib/web/jquery/patches/jquery-ui-sortable.js create mode 100644 setup/pub/fonts/opensans/LICENSE-2.0.txt diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json index ef3829fd149c6..1f3efd6281a58 100644 --- a/app/code/Magento/AdminAnalytics/composer.json +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-admin-analytics", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-release-notification": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-release-notification": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json index 28ca1f626a2cd..6bfb98da02245 100644 --- a/app/code/Magento/AdminNotification/composer.json +++ b/app/code/Magento/AdminNotification/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-admin-notification", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-config": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/AdvancedPricingImportExport/composer.json b/app/code/Magento/AdvancedPricingImportExport/composer.json index 59ea74cf4ddcb..f40a9ef5750c5 100644 --- a/app/code/Magento/AdvancedPricingImportExport/composer.json +++ b/app/code/Magento/AdvancedPricingImportExport/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-advanced-pricing-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-catalog-inventory": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*", - "magento/module-directory": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*", + "magento/module-directory": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/AdvancedSearch/composer.json b/app/code/Magento/AdvancedSearch/composer.json index 30205c5255cdd..52d4a2b3deb8d 100644 --- a/app/code/Magento/AdvancedSearch/composer.json +++ b/app/code/Magento/AdvancedSearch/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-advanced-search", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-search": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-search": "*", - "magento/module-store": "*", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-search": "101.1.*", + "magento/module-store": "101.1.*", "php": "~7.4.0||~8.1.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Amqp/composer.json b/app/code/Magento/Amqp/composer.json index c7d8d49fb0003..6f2b360634d3e 100644 --- a/app/code/Magento/Amqp/composer.json +++ b/app/code/Magento/Amqp/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-amqp", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { - "magento/framework": "*", - "magento/framework-amqp": "*", - "magento/framework-message-queue": "*", + "magento/framework": "103.0.*", + "magento/framework-amqp": "100.4.*", + "magento/framework-message-queue": "100.4.*", "php": "~7.4.0||~8.1.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/AmqpStore/composer.json b/app/code/Magento/AmqpStore/composer.json index 4d4685dda0b51..53d1e8d12db23 100644 --- a/app/code/Magento/AmqpStore/composer.json +++ b/app/code/Magento/AmqpStore/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-amqp-store", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { - "magento/framework": "*", - "magento/framework-amqp": "*", - "magento/module-store": "*", + "magento/framework": "103.0.*", + "magento/framework-amqp": "100.4.*", + "magento/module-store": "101.1.*", "php": "~7.4.0||~8.1.0" }, "suggest": { - "magento/module-asynchronous-operations": "*", - "magento/framework-message-queue": "*" + "magento/module-asynchronous-operations": "100.4.*", + "magento/framework-message-queue": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/Analytics/Test/Mftf/ActionGroup/AssertAdminAdvancedReportingPageUrlActionGroup.xml b/app/code/Magento/Analytics/Test/Mftf/ActionGroup/AssertAdminAdvancedReportingPageUrlActionGroup.xml index ac4fca843a36b..3f0bedd344d24 100644 --- a/app/code/Magento/Analytics/Test/Mftf/ActionGroup/AssertAdminAdvancedReportingPageUrlActionGroup.xml +++ b/app/code/Magento/Analytics/Test/Mftf/ActionGroup/AssertAdminAdvancedReportingPageUrlActionGroup.xml @@ -15,6 +15,6 @@ - + diff --git a/app/code/Magento/Analytics/composer.json b/app/code/Magento/Analytics/composer.json index 9bf08b4b068ca..2a29c61b93ae0 100644 --- a/app/code/Magento/Analytics/composer.json +++ b/app/code/Magento/Analytics/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-analytics", "description": "N/A", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-integration": "*", - "magento/module-store": "*", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4-p4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-integration": "100.4.*", + "magento/module-store": "101.1.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index b09ca94052e87..ba34d2f770ee9 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-asynchronous-operations", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { - "magento/framework": "*", - "magento/framework-message-queue": "*", - "magento/framework-bulk": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-ui": "*", + "magento/framework": "103.0.*", + "magento/framework-message-queue": "100.4.*", + "magento/framework-bulk": "101.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-ui": "101.2.*", "php": "~7.4.0||~8.1.0" }, "suggest": { - "magento/module-admin-notification": "*", + "magento/module-admin-notification": "100.4.*", "magento/module-logging": "*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json index d122e8b29b46e..b4b0fa6ab43ab 100644 --- a/app/code/Magento/Authorization/composer.json +++ b/app/code/Magento/Authorization/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-authorization", "description": "Authorization module provides access to Magento ACL functionality.", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/AwsS3/composer.json b/app/code/Magento/AwsS3/composer.json index 470580df35f59..874341cce831d 100644 --- a/app/code/Magento/AwsS3/composer.json +++ b/app/code/Magento/AwsS3/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-aws-s3", "description": "N/A", + "type": "magento2-module", + "license": [ + "proprietary" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-remote-storage": "*", + "magento/framework": "103.0.*", + "magento/module-remote-storage": "100.4.*", "league/flysystem": "^2.0", "league/flysystem-aws-s3-v3": "^2.0" }, - "type": "magento2-module", - "license": [ - "proprietary" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php index 3d7154eb20f92..34d588c2dc080 100644 --- a/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php +++ b/app/code/Magento/Backend/Block/System/Store/Grid/Render/Group.php @@ -3,8 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Backend\Block\System\Store\Grid\Render; +use Magento\Framework\DataObject; + /** * Store render group * @@ -13,9 +17,9 @@ class Group extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer { /** - * {@inheritdoc} + * @inheritDoc */ - public function render(\Magento\Framework\DataObject $row) + public function render(DataObject $row) { if (!$row->getData($this->getColumn()->getIndex())) { return null; @@ -28,6 +32,6 @@ public function render(\Magento\Framework\DataObject $row) '">' . $this->escapeHtml($row->getData($this->getColumn()->getIndex())) . '
' - . '(' . __('Code') . ': ' . $row->getGroupCode() . ')'; + . '(' . __('Code') . ': ' . $this->escapeHtml($row->getGroupCode()) . ')'; } } diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json index 65aa05fe71e56..631c6b2c4ded8 100644 --- a/app/code/Magento/Backend/composer.json +++ b/app/code/Magento/Backend/composer.json @@ -1,38 +1,39 @@ { "name": "magento/module-backend", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "102.0.4-p3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backup": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-cms": "*", - "magento/module-customer": "*", - "magento/module-developer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-quote": "*", - "magento/module-reports": "*", - "magento/module-require-js": "*", - "magento/module-sales": "*", - "magento/module-security": "*", - "magento/module-store": "*", - "magento/module-translation": "*", - "magento/module-ui": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-backup": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-cms": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-developer": "100.4.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-quote": "101.2.*", + "magento/module-reports": "100.4.*", + "magento/module-require-js": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-security": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-translation": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-user": "101.2.*" }, "suggest": { - "magento/module-theme": "*" + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php", @@ -43,3 +44,4 @@ } } } + diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json index e7437a3077aa7..137a008f10209 100644 --- a/app/code/Magento/Backup/composer.json +++ b/app/code/Magento/Backup/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-backup", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cron": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cron": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml index 7038ad90b81b9..45e26cf327dc9 100644 --- a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml +++ b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/StoreFrontAddProductToCartFromBundleActionGroup.xml @@ -17,11 +17,15 @@ + + + + diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json index 47be75a42c254..782f460495f34 100644 --- a/app/code/Magento/Bundle/composer.json +++ b/app/code/Magento/Bundle/composer.json @@ -1,39 +1,40 @@ { "name": "magento/module-bundle", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.0.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-catalog-rule": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-gift-message": "*", - "magento/module-media-storage": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-ui": "*", - "magento/module-directory": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-catalog-rule": "101.2.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-gift-message": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-directory": "100.4.*" }, "suggest": { - "magento/module-webapi": "*", - "magento/module-bundle-sample-data": "*", - "magento/module-sales-rule": "*" + "magento/module-webapi": "100.4.*", + "magento/module-bundle-sample-data": "Sample Data version: 100.4.*", + "magento/module-sales-rule": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -43,3 +44,4 @@ } } } + diff --git a/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml b/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml index 706b28049470e..5f3e219866ba6 100644 --- a/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml +++ b/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ use Magento\Bundle\ViewModel\ValidateQuantity; + +// phpcs:disable Generic.Files.LineLength.TooLong ?> getOption(); ?> @@ -20,42 +22,45 @@ $viewModel = $block->getData('validateQuantityViewModel');
- showSingle()) : ?> + showSingle()): ?> getSelectionTitlePrice($_selections[0]) ?> getTierPriceRenderer()->renderTierPrice($_selections[0]) ?> - - getRequired()) : ?> + + getRequired()): ?>
isSalable())?'':' checked="checked" ' ?> + isSalable())?'':' checked="checked" ' ?> value=""/>
- +
getRequired()) { echo 'data-validate="{\'validate-one-required-by-name\':true}"'; }?> + getRequired()) { + echo 'data-validate="{\'validate-one-required-by-name\':true}"'; + } ?> name="bundle_option[escapeHtmlAttr($_option->getId()) ?>]" data-selector="bundle_option[escapeHtmlAttr($_option->getId()) ?>]" - isSelected($_selection)) { echo ' checked="checked"'; } ?> - isSaleable()) { echo ' disabled="disabled"'; } ?> - value="escapeHtmlAttr($_selection->getSelectionId()) ?>"/> + isSelected($_selection)) { echo ' checked="checked"'; } ?> + isSaleable()) { echo ' disabled="disabled"'; } ?> + value="escapeHtmlAttr($_selection->getSelectionId()) ?>" + data-errors-message-box="#validation-message-box-radio"/>
+
- id="bundle-option-escapeHtmlAttr($_option->getId()) ?>-qty-input" - class="input-text qty" - type="number" - min="0" - data-validate="escapeHtmlAttr($viewModel->getQuantityValidators()) ?>" - name="bundle_option_qty[escapeHtmlAttr($_option->getId()) ?>]" - data-selector="bundle_option_qty[escapeHtmlAttr($_option->getId()) ?>]" - value="escapeHtmlAttr($_defaultQty) ?>"/> + id="bundle-option-escapeHtmlAttr($_option->getId()) ?>-qty-input" + class="input-text qty" + type="number" + min="0" + data-validate="escapeHtmlAttr($viewModel->getQuantityValidators()) ?>" + name="bundle_option_qty[escapeHtmlAttr($_option->getId()) ?>]" + data-selector="bundle_option_qty[escapeHtmlAttr($_option->getId()) ?>]" + value="escapeHtmlAttr($_defaultQty) ?>"/>
diff --git a/app/code/Magento/BundleGraphQl/composer.json b/app/code/Magento/BundleGraphQl/composer.json index 70a619cbf6837..62f1337085934 100644 --- a/app/code/Magento/BundleGraphQl/composer.json +++ b/app/code/Magento/BundleGraphQl/composer.json @@ -2,23 +2,24 @@ "name": "magento/module-bundle-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-catalog": "*", - "magento/module-bundle": "*", - "magento/module-graph-ql": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-quote": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-store": "*", - "magento/module-sales": "*", - "magento/module-sales-graph-ql": "*", - "magento/framework": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-catalog": "104.0.*", + "magento/module-bundle": "101.0.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-graph-ql": "100.4.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/BundleImportExport/composer.json b/app/code/Magento/BundleImportExport/composer.json index ff7d0acc7c48d..1c5cf7e70ab12 100644 --- a/app/code/Magento/BundleImportExport/composer.json +++ b/app/code/Magento/BundleImportExport/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-bundle-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-bundle": "*", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*" + "magento/framework": "103.0.*", + "magento/module-bundle": "101.0.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json index c756a5fe602e9..7985a50cb2e28 100644 --- a/app/code/Magento/CacheInvalidate/composer.json +++ b/app/code/Magento/CacheInvalidate/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-cache-invalidate", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-page-cache": "*" + "magento/framework": "103.0.*", + "magento/module-page-cache": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml index 912e637dc534e..4ab4ec7f055f9 100644 --- a/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml +++ b/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml @@ -21,6 +21,7 @@ + 20 @@ -62,6 +63,7 @@ + diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json index b276555326eb8..a90ec4cd5568f 100644 --- a/app/code/Magento/Captcha/composer.json +++ b/app/code/Magento/Captcha/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-captcha", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-authorization": "*", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-authorization": "100.4.*", "laminas/laminas-captcha": "^2.11.0", "laminas/laminas-db": "^2.13.4", "laminas/laminas-session": "^2.12.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/CardinalCommerce/composer.json b/app/code/Magento/CardinalCommerce/composer.json index 4c49c92cec1ea..097783f77e433 100644 --- a/app/code/Magento/CardinalCommerce/composer.json +++ b/app/code/Magento/CardinalCommerce/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-cardinal-commerce", "description": "Provides a possibility to enable 3-D Secure 2.0 support for payment methods.", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-payment": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php index 0b1ef98c386c4..ea14dbc1ce627 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php @@ -4,18 +4,21 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Controller\Adminhtml\Product; -use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; -use Magento\Backend\App\Action; use Magento\Catalog\Controller\Adminhtml\Product; +use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\RegexValidator; class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product implements HttpGetActionInterface { /** * @var Initialization\StockDataFilter * @deprecated 101.0.0 + * @see Initialization\StockDataFilter */ protected $stockFilter; @@ -30,23 +33,32 @@ class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product implements protected $resultForwardFactory; /** - * @param Action\Context $context + * @var RegexValidator + */ + private RegexValidator $regexValidator; + + /** + * @param Context $context * @param Builder $productBuilder * @param Initialization\StockDataFilter $stockFilter * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory * @param \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory + * @param RegexValidator|null $regexValidator */ public function __construct( \Magento\Backend\App\Action\Context $context, Product\Builder $productBuilder, Initialization\StockDataFilter $stockFilter, \Magento\Framework\View\Result\PageFactory $resultPageFactory, - \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory + \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory, + RegexValidator $regexValidator = null ) { $this->stockFilter = $stockFilter; parent::__construct($context, $productBuilder); $this->resultPageFactory = $resultPageFactory; $this->resultForwardFactory = $resultForwardFactory; + $this->regexValidator = $regexValidator + ?: ObjectManager::getInstance()->get(RegexValidator::class); } /** @@ -56,6 +68,11 @@ public function __construct( */ public function execute() { + $typeId = $this->getRequest()->getParam('type'); + if (!$this->regexValidator->validateParamRegex($typeId)) { + return $this->resultForwardFactory->create()->forward('noroute'); + } + if (!$this->getRequest()->getParam('set')) { return $this->resultForwardFactory->create()->forward('noroute'); } diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml index f3a0919f6c728..cf419c8f27c00 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml @@ -40,5 +40,6 @@ + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/AdminApplyTierPriceToProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/AdminApplyTierPriceToProductTest.xml index 8add42ec7493f..b2d36589dd251 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/AdminApplyTierPriceToProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/AdminApplyTierPriceToProductTest.xml @@ -230,6 +230,7 @@ + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductAttributeUpdateAddedToQueueTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductAttributeUpdateAddedToQueueTest.xml index c887ed5b42816..1d75f49ab6740 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductAttributeUpdateAddedToQueueTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassProductAttributeUpdateAddedToQueueTest.xml @@ -46,8 +46,10 @@ + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRestrictedUserAddCategoryFromProductPageTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRestrictedUserAddCategoryFromProductPageTest.xml index 795c2ac77acdd..fb4a4a2bfac8d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRestrictedUserAddCategoryFromProductPageTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRestrictedUserAddCategoryFromProductPageTest.xml @@ -97,6 +97,7 @@ + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockEnabledFlatCatalogTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockEnabledFlatCatalogTest.xml index 3af6de07e561d..71c82f654310a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockEnabledFlatCatalogTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockEnabledFlatCatalogTest.xml @@ -6,7 +6,7 @@ */ --> - @@ -26,6 +26,9 @@ + + + @@ -33,6 +36,7 @@ + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml index 3cb36ae2c3735..33e34018b5f4e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml @@ -21,8 +21,12 @@ + + + + diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php old mode 100644 new mode 100755 index 974c85b2b5c98..b1b649bf551c6 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php @@ -16,6 +16,9 @@ use Magento\Catalog\Controller\Adminhtml\Product\NewAction; use Magento\Catalog\Model\Product; use Magento\Catalog\Test\Unit\Controller\Adminhtml\ProductTest; +use Magento\Framework\RegexValidator; +use Magento\Framework\Validator\Regex; +use Magento\Framework\Validator\RegexFactory; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Result\PageFactory; use PHPUnit\Framework\MockObject\MockObject; @@ -42,6 +45,26 @@ class NewActionTest extends ProductTest */ protected $initializationHelper; + /** + * @var RegexValidator|MockObject + */ + private $regexValidator; + + /** + * @var RegexFactory + */ + private $regexValidatorFactoryMock; + + /** + * @var Regex|MockObject + */ + private $regexValidatorMock; + + /** + * @var ForwardFactory&MockObject|MockObject + */ + private $resultForwardFactory; + protected function setUp(): void { $this->productBuilder = $this->createPartialMock( @@ -63,37 +86,69 @@ protected function setUp(): void ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $resultPageFactory->expects($this->atLeastOnce()) - ->method('create') - ->willReturn($this->resultPage); $this->resultForward = $this->getMockBuilder(Forward::class) ->disableOriginalConstructor() ->getMock(); - $resultForwardFactory = $this->getMockBuilder(ForwardFactory::class) + $this->resultForwardFactory = $this->getMockBuilder(ForwardFactory::class) + ->disableOriginalConstructor() + ->onlyMethods(['create']) + ->getMock(); + + $this->regexValidatorFactoryMock = $this->getMockBuilder(RegexFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $resultForwardFactory->expects($this->any()) - ->method('create') - ->willReturn($this->resultForward); + $this->regexValidatorMock = $this->createMock(Regex::class); + $this->regexValidatorFactoryMock->method('create') + ->willReturn($this->regexValidatorMock); + $this->regexValidator = new regexValidator($this->regexValidatorFactoryMock); $this->action = (new ObjectManager($this))->getObject( NewAction::class, [ 'context' => $this->initContext(), 'productBuilder' => $this->productBuilder, 'resultPageFactory' => $resultPageFactory, - 'resultForwardFactory' => $resultForwardFactory, + 'resultForwardFactory' => $this->resultForwardFactory, + 'regexValidator' => $this->regexValidator, ] ); } - public function testExecute() + /** + * @return void + */ + public function testExecute(): void { - $this->action->getRequest()->expects($this->any())->method('getParam')->willReturn(true); - $this->action->getRequest()->expects($this->any())->method('getFullActionName') - ->willReturn('catalog_product_new'); - $this->action->execute(); + $value = 'catalog_product_new'; + + $this->action->getRequest()->expects($this->any())->method('getParam')->willReturn($value); + $this->regexValidatorMock->expects($this->any()) + ->method('isValid') + ->with($value) + ->willReturn(true); + + $this->assertEquals(true, $this->regexValidator->validateParamRegex($value)); + } + + /** + * @return void + */ + public function testExecuteWithError(): void + { + $value = 'simple\' and true()]|*[self%3a%3ahandle%20or%20self%3a%3alayout'; + + $this->action->getRequest()->expects($this->any()) + ->method('getParam') + ->willReturn($value); + $this->resultForwardFactory->expects($this->any()) + ->method('create') + ->willReturn($this->resultForward); + $this->resultForward->expects($this->once()) + ->method('forward') + ->with('noroute') + ->willReturn(true); + $this->assertTrue($this->action->execute()); } } diff --git a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php index f3831e50ef3d9..a97c75d32da15 100644 --- a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php @@ -15,8 +15,11 @@ use Magento\Catalog\Pricing\Render\FinalPriceBox; use Magento\Framework\App\Cache\StateInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\State; +use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\Event\Test\Unit\ManagerStub; +use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Pricing\Amount\AmountInterface; use Magento\Framework\Pricing\Price\PriceInterface; use Magento\Framework\Pricing\PriceInfoInterface; @@ -96,11 +99,27 @@ class FinalPriceBoxTest extends TestCase */ private $minimalPriceCalculator; + /** + * @var DeploymentConfig|MockObject + */ + private $deploymentConfig; + + /** + * @var ObjectManagerInterface|MockObject + */ + private $objectManagerMock; + /** * @inheritDoc + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function setUp(): void { + $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->onlyMethods(['get']) + ->getMockForAbstractClass(); + \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock); $this->product = $this->getMockBuilder(Product::class) ->addMethods(['getCanShowPrice']) ->onlyMethods(['getPriceInfo', 'isSalable', 'getId']) @@ -183,6 +202,11 @@ protected function setUp(): void ->disableOriginalConstructor() ->getMockForAbstractClass(); + $this->deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); + $this->minimalPriceCalculator = $this->getMockForAbstractClass(MinimalPriceCalculatorInterface::class); $this->object = $objectManager->getObject( FinalPriceBox::class, @@ -455,6 +479,15 @@ public function testHidePrice(): void */ public function testGetCacheKey(): void { + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->with(DeploymentConfig::class) + ->willReturn($this->deploymentConfig); + + $this->deploymentConfig->expects($this->any()) + ->method('get') + ->with(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY) + ->willReturn('448198e08af35844a42d3c93c1ef4e03'); $result = $this->object->getCacheKey(); $this->assertStringEndsWith('list-category-page', $result); } diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json index 6597e88e9d995..61499468740fb 100644 --- a/app/code/Magento/Catalog/composer.json +++ b/app/code/Magento/Catalog/composer.json @@ -1,48 +1,49 @@ { "name": "magento/module-catalog", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "104.0.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-backend": "*", - "magento/module-catalog-inventory": "*", - "magento/module-catalog-rule": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-checkout": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-indexer": "*", - "magento/module-media-storage": "*", - "magento/module-msrp": "*", - "magento/module-page-cache": "*", - "magento/module-product-alert": "*", - "magento/module-quote": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-url-rewrite": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-asynchronous-operations": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-catalog-rule": "101.2.*", + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-indexer": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-msrp": "100.4.*", + "magento/module-page-cache": "100.4.*", + "magento/module-product-alert": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-url-rewrite": "102.0.*", + "magento/module-widget": "101.2.*", + "magento/module-wishlist": "101.2.*" }, "suggest": { - "magento/module-cookie": "*", - "magento/module-sales": "*", - "magento/module-catalog-sample-data": "*" + "magento/module-cookie": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-catalog-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -52,3 +53,4 @@ } } } + diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index d5ba3b75493eb..34d31f1c9a6fa 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -816,4 +816,6 @@ Details,Details "Are you sure you want to delete this category?","Are you sure you want to delete this category?" "Attribute Set Information","Attribute Set Information" "Failed to retrieve product links for ""%1""","Failed to retrieve product links for ""%1""" +"The url has invalid characters. Please correct and try again.","The url has invalid characters. Please correct and try again." + diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js b/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js index d292bd126593c..b4d4ed12d20ba 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js @@ -5,10 +5,9 @@ define([ 'jquery', - 'mageUtils', 'jquery/ui', 'jquery/jstree/jquery.jstree' -], function ($, utils) { +], function ($) { 'use strict'; $.widget('mage.categoryTree', { @@ -87,7 +86,7 @@ define([ // jscs:disable requireCamelCaseOrUpperCaseIdentifiers result = { id: node.id, - text: utils.unescape(node.name) + ' (' + node.product_count + ')', + text: node.name + ' (' + node.product_count + ')', li_attr: { class: node.cls + (!!node.disabled ? ' disabled' : '') //eslint-disable-line no-extra-boolean-cast }, diff --git a/app/code/Magento/CatalogAnalytics/composer.json b/app/code/Magento/CatalogAnalytics/composer.json index a41a47fa4764b..2fb9f4fb021cf 100644 --- a/app/code/Magento/CatalogAnalytics/composer.json +++ b/app/code/Magento/CatalogAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-catalog-analytics", "description": "N/A", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/CatalogCmsGraphQl/composer.json b/app/code/Magento/CatalogCmsGraphQl/composer.json index cf9e76f3b2ea2..b32b4635745c3 100644 --- a/app/code/Magento/CatalogCmsGraphQl/composer.json +++ b/app/code/Magento/CatalogCmsGraphQl/composer.json @@ -2,21 +2,22 @@ "name": "magento/module-catalog-cms-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-cms-graph-ql": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-cms-graph-ql": "100.4.*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-cms": "*", - "magento/module-catalog-graph-ql": "*" + "magento/module-graph-ql": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/CatalogCustomerGraphQl/composer.json b/app/code/Magento/CatalogCustomerGraphQl/composer.json index b1743ae964966..c7062a2d03e6a 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/composer.json +++ b/app/code/Magento/CatalogCustomerGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-catalog-customer-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-catalog-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-catalog-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/CatalogGraphQl/composer.json b/app/code/Magento/CatalogGraphQl/composer.json index c289f84a359ba..bd3626743f4de 100644 --- a/app/code/Magento/CatalogGraphQl/composer.json +++ b/app/code/Magento/CatalogGraphQl/composer.json @@ -2,28 +2,29 @@ "name": "magento/module-catalog-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-eav": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-directory": "*", - "magento/module-search": "*", - "magento/module-store": "*", - "magento/module-eav-graph-ql": "*", - "magento/module-catalog-search": "*", - "magento/framework": "*", - "magento/module-graph-ql": "*", - "magento/module-advanced-search": "*" + "magento/module-eav": "102.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-directory": "100.4.*", + "magento/module-search": "101.1.*", + "magento/module-store": "101.1.*", + "magento/module-eav-graph-ql": "100.4.*", + "magento/module-catalog-search": "102.0.*", + "magento/framework": "103.0.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-advanced-search": "100.4.*" }, "suggest": { - "magento/module-graph-ql-cache": "*", - "magento/module-store-graph-ql": "*" + "magento/module-graph-ql-cache": "100.4.*", + "magento/module-store-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 25dc5360c8df2..3ad96737bf323 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -47,6 +47,7 @@ */ class Product extends AbstractEntity { + private const COL_NAME_FORMAT = '/[\x00-\x1F\x7F]/'; private const DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR = ','; public const CONFIG_KEY_PRODUCT_TYPES = 'global/importexport/import_product_types'; private const HASH_ALGORITHM = 'sha256'; @@ -1611,6 +1612,11 @@ protected function _saveProducts() $bunch[$rowNum][self::URL_KEY] = $rowData[self::URL_KEY] = $urlKey; } + if (!empty($rowData[self::COL_NAME])) { + // remove null byte character + $rowData[self::COL_NAME] = preg_replace(self::COL_NAME_FORMAT, '', $rowData[self::COL_NAME]); + } + $rowSku = $rowData[self::COL_SKU]; $rowSkuNormalized = mb_strtolower($rowSku); diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index dac8624086df0..817c7e65cb94e 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-catalog-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.4-p4", "require": { "php": "~7.4.0||~8.1.0", "ext-ctype": "*", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-authorization": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-authorization": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index 4b7fee72c4347..18c51001c091f 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-catalog-inventory", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-quote": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ }, "abandoned": "magento/inventory-composer-metapackage" } + diff --git a/app/code/Magento/CatalogInventoryGraphQl/composer.json b/app/code/Magento/CatalogInventoryGraphQl/composer.json index 38685524d5346..92f6224abc5a8 100644 --- a/app/code/Magento/CatalogInventoryGraphQl/composer.json +++ b/app/code/Magento/CatalogInventoryGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-catalog-inventory-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json index 531a12ac017ed..43a970bc52a60 100644 --- a/app/code/Magento/CatalogRule/composer.json +++ b/app/code/Magento/CatalogRule/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-catalog-rule", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-rule": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-rule": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-import-export": "*", - "magento/module-catalog-rule-sample-data": "*" + "magento/module-import-export": "101.0.*", + "magento/module-catalog-rule-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/CatalogRuleConfigurable/composer.json b/app/code/Magento/CatalogRuleConfigurable/composer.json index 68da972ae94f9..46a0b604835ad 100644 --- a/app/code/Magento/CatalogRuleConfigurable/composer.json +++ b/app/code/Magento/CatalogRuleConfigurable/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-catalog-rule-configurable", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "magento/magento-composer-installer": "*", - "magento/module-catalog": "*", - "magento/module-catalog-rule": "*", - "magento/module-configurable-product": "*" + "magento/module-catalog": "104.0.*", + "magento/module-catalog-rule": "101.2.*", + "magento/module-configurable-product": "100.4.*" }, "suggest": { - "magento/module-catalog-rule": "*" + "magento/module-catalog-rule": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/CatalogRuleGraphQl/composer.json b/app/code/Magento/CatalogRuleGraphQl/composer.json index 2c8c3ef20c96a..6bd7ef191d895 100644 --- a/app/code/Magento/CatalogRuleGraphQl/composer.json +++ b/app/code/Magento/CatalogRuleGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-catalog-rule-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-catalog-rule": "*" + "magento/module-catalog-rule": "101.2.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index 465d7daeebe18..a3a5246e1992a 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -1,32 +1,33 @@ { "name": "magento/module-catalog-search", "description": "Catalog search", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "102.0.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-indexer": "*", - "magento/module-catalog-inventory": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-search": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-indexer": "100.4.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-search": "101.1.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -36,3 +37,4 @@ } } } + diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index ce409e2186faa..490ad57b35a6f 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-catalog-url-rewrite", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-url-rewrite": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-url-rewrite": "102.0.*" }, "suggest": { - "magento/module-webapi": "*" + "magento/module-webapi": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json b/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json index 025234af6f865..d79c2ab17f611 100644 --- a/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json +++ b/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json @@ -2,23 +2,24 @@ "name": "magento/module-catalog-url-rewrite-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-url-rewrite-graph-ql": "*", - "magento/framework": "*" + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-url-rewrite-graph-ql": "100.4.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-catalog-url-rewrite": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-url-rewrite-graph-ql": "*" + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-url-rewrite-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Test/StorefrontProductGridUIUpdatesOnDesktopTest.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Test/StorefrontProductGridUIUpdatesOnDesktopTest.xml index 5590aa1cdcefa..e833c8e72f47a 100644 --- a/app/code/Magento/CatalogWidget/Test/Mftf/Test/StorefrontProductGridUIUpdatesOnDesktopTest.xml +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Test/StorefrontProductGridUIUpdatesOnDesktopTest.xml @@ -61,6 +61,7 @@ + diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json index 33c5e3b3ba3ee..bb74be273a5e5 100644 --- a/app/code/Magento/CatalogWidget/composer.json +++ b/app/code/Magento/CatalogWidget/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-catalog-widget", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-rule": "*", - "magento/module-store": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-rule": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-widget": "101.2.*", + "magento/module-wishlist": "101.2.*", + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php b/app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php index 44e40c57f6615..abaecf51b076b 100644 --- a/app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php +++ b/app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php @@ -3,19 +3,25 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Checkout\Controller\Sidebar; use Magento\Checkout\Model\Cart\RequestQuantityProcessor; use Magento\Checkout\Model\Sidebar; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\App\Response\Http; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Json\Helper\Data; use Psr\Log\LoggerInterface; -class UpdateItemQty extends Action +/** + * Class used to update item quantity. + */ +class UpdateItemQty extends Action implements HttpPostActionInterface { /** * @var Sidebar @@ -61,12 +67,18 @@ public function __construct( } /** + * Action for Quantity update + * * @return $this */ public function execute() { $itemId = (int)$this->getRequest()->getParam('item_id'); - $itemQty = $this->getRequest()->getParam('item_qty') * 1; + $itemQty = (int)$this->getRequest()->getParam('item_qty'); + + if ($itemQty <= 0) { + return $this->jsonResponse(__('Invalid Item Quantity Requested.')); + } $itemQty = $this->quantityProcessor->prepareQuantity($itemQty); try { diff --git a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php index 9e31c4d77301e..dd4080bcc39dc 100644 --- a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php +++ b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php @@ -31,6 +31,7 @@ use Magento\Quote\Model\QuoteIdMaskFactory; use Magento\Store\Model\ScopeInterface; use Magento\Ui\Component\Form\Element\Multiline; +use Magento\Framework\Escaper; /** * Default Config Provider for checkout @@ -191,6 +192,11 @@ class DefaultConfigProvider implements ConfigProviderInterface */ private $configPostProcessor; + /** + * @var Escaper + */ + private $escaper; + /** * @param CheckoutHelper $checkoutHelper * @param Session $checkoutSession @@ -222,6 +228,7 @@ class DefaultConfigProvider implements ConfigProviderInterface * @param AddressMetadataInterface $addressMetadata * @param AttributeOptionManagementInterface $attributeOptionManager * @param CustomerAddressDataProvider|null $customerAddressData + * @param Escaper|null $escaper * @codeCoverageIgnore * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -255,7 +262,8 @@ public function __construct( CaptchaConfigPostProcessorInterface $configPostProcessor, AddressMetadataInterface $addressMetadata = null, AttributeOptionManagementInterface $attributeOptionManager = null, - CustomerAddressDataProvider $customerAddressData = null + CustomerAddressDataProvider $customerAddressData = null, + Escaper $escaper = null ) { $this->checkoutHelper = $checkoutHelper; $this->checkoutSession = $checkoutSession; @@ -289,6 +297,7 @@ public function __construct( $this->customerAddressData = $customerAddressData ?: ObjectManager::getInstance()->get(CustomerAddressDataProvider::class); $this->configPostProcessor = $configPostProcessor; + $this->escaper = $escaper ?? ObjectManager::getInstance()->get(Escaper::class); } /** @@ -343,6 +352,7 @@ public function getConfig() 'shipping/shipping_policy/shipping_policy_content', ScopeInterface::SCOPE_STORE ); + $policyContent = $this->escaper->escapeHtml($policyContent); $output['shippingPolicy'] = [ 'isEnabled' => $this->scopeConfig->isSetFlag( 'shipping/shipping_policy/enable_shipping_policy', diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index f397a8ddc9cf1..f08c48c55efa1 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Checkout\Model; @@ -39,60 +40,62 @@ class ShippingInformationManagement implements ShippingInformationManagementInte /** * @var PaymentMethodManagementInterface */ - protected $paymentMethodManagement; + protected PaymentMethodManagementInterface $paymentMethodManagement; /** * @var PaymentDetailsFactory */ - protected $paymentDetailsFactory; + protected PaymentDetailsFactory $paymentDetailsFactory; /** * @var CartTotalRepositoryInterface */ - protected $cartTotalsRepository; + protected CartTotalRepositoryInterface $cartTotalsRepository; /** * @var CartRepositoryInterface */ - protected $quoteRepository; - + protected CartRepositoryInterface $quoteRepository; /** * @var Logger */ - protected $logger; + protected Logger $logger; /** * @var QuoteAddressValidator */ - protected $addressValidator; + protected QuoteAddressValidator $addressValidator; /** * @var AddressRepositoryInterface * @deprecated 100.2.0 + * @see AddressRepositoryInterface */ - protected $addressRepository; + protected AddressRepositoryInterface $addressRepository; /** * @var ScopeConfigInterface * @deprecated 100.2.0 + * @see ScopeConfigInterface */ - protected $scopeConfig; + protected ScopeConfigInterface $scopeConfig; /** * @var TotalsCollector * @deprecated 100.2.0 + * @see TotalsCollector */ - protected $totalsCollector; + protected TotalsCollector $totalsCollector; /** * @var CartExtensionFactory */ - private $cartExtensionFactory; + private CartExtensionFactory $cartExtensionFactory; /** * @var ShippingAssignmentFactory */ - protected $shippingAssignmentFactory; + protected ShippingAssignmentFactory $shippingAssignmentFactory; /** * @var ShippingFactory @@ -262,8 +265,11 @@ protected function validateQuote(Quote $quote): void * @param string $method * @return CartInterface */ - private function prepareShippingAssignment(CartInterface $quote, AddressInterface $address, $method): CartInterface - { + private function prepareShippingAssignment( + CartInterface $quote, + AddressInterface $address, + string $method + ): CartInterface { $cartExtension = $quote->getExtensionAttributes(); if ($cartExtension === null) { $cartExtension = $this->cartExtensionFactory->create(); diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertMiniCartEmptyActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertMiniCartEmptyActionGroup.xml index 649421a53040b..2119e5c43f7bb 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertMiniCartEmptyActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertMiniCartEmptyActionGroup.xml @@ -13,8 +13,9 @@ Validates that the provided Product Count appears in the Storefront Header next to the Shopping Cart icon. Clicks on the Mini Shopping Cart icon. Validates that the 'No Items' message is present and correct in the Storefront Mini Shopping Cart. + - + diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutPlaceOrderActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutPlaceOrderActionGroup.xml index 48c515a3dd197..4269e647cf7f8 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutPlaceOrderActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutPlaceOrderActionGroup.xml @@ -17,8 +17,12 @@ + + + + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml index 64f392d39edcb..f770e7f42caec 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml @@ -20,11 +20,11 @@ + 560 - @@ -40,6 +40,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml index b60b60d5d0dc5..a235da133af79 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml @@ -20,6 +20,7 @@ + 560 @@ -40,6 +41,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml index 1a85bb0bee1ee..07d1378d00529 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml @@ -18,6 +18,7 @@ + @@ -105,6 +106,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml index eb76748a81c97..ec4593cf133b0 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml @@ -19,6 +19,7 @@ + @@ -39,9 +40,9 @@ - + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml index 901c5c3598dbf..af5af1d2a0963 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml @@ -45,8 +45,10 @@ - + + + diff --git a/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php b/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php index 400f6ddfe26f4..959cebea17471 100644 --- a/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php @@ -19,6 +19,9 @@ use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; +/** + * Class used to execute test cases for update item quantity + */ class UpdateItemQtyTest extends TestCase { /** @@ -244,4 +247,36 @@ public function testExecuteWithException(): void $this->assertEquals('json represented', $this->updateItemQty->execute()); } + + /** + * @return void + */ + public function testExecuteWithInvalidItemQty(): void + { + $error = [ + 'success' => false, + 'error_message' => 'Invalid Item Quantity Requested.' + ]; + $jsonResult = json_encode($error); + $this->requestMock + ->method('getParam') + ->withConsecutive(['item_id', null], ['item_qty', null]) + ->willReturnOnConsecutiveCalls('1', '{{7+2}}'); + + $this->sidebarMock->expects($this->once()) + ->method('getResponseData') + ->with('Invalid Item Quantity Requested.') + ->willReturn($error); + + $this->jsonHelperMock->expects($this->once()) + ->method('jsonEncode') + ->with($error) + ->willReturn($jsonResult); + + $this->responseMock->expects($this->once()) + ->method('representJson') + ->willReturn($jsonResult); + + $this->assertEquals($jsonResult, $this->updateItemQty->execute()); + } } diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json index f277184d8986b..0586e5e1ed0e6 100644 --- a/app/code/Magento/Checkout/composer.json +++ b/app/code/Magento/Checkout/composer.json @@ -1,41 +1,42 @@ { "name": "magento/module-checkout", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-captcha": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-msrp": "*", - "magento/module-page-cache": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-sales-rule": "*", - "magento/module-security": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-authorization": "*" + "magento/framework": "103.0.*", + "magento/module-captcha": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-msrp": "100.4.*", + "magento/module-page-cache": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-security": "100.4.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-authorization": "100.4.*" }, "suggest": { - "magento/module-cookie": "*" + "magento/module-cookie": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -45,3 +46,4 @@ } } } + diff --git a/app/code/Magento/Checkout/etc/adminhtml/system.xml b/app/code/Magento/Checkout/etc/adminhtml/system.xml index b56566a043c3e..5bb0f37f3bc25 100644 --- a/app/code/Magento/Checkout/etc/adminhtml/system.xml +++ b/app/code/Magento/Checkout/etc/adminhtml/system.xml @@ -13,6 +13,11 @@ Magento_Checkout::checkout + + + Magento\Config\Model\Config\Source\Yesno + Enabling this setting will allow unauthenticated users to query if an e-mail address is already associated with a customer account. This can be used to enhance the checkout workflow for guests that do not realize they already have an account but comes at the cost of exposing information to unauthenticated users. + Magento\Config\Model\Config\Source\Yesno @@ -23,7 +28,7 @@ - \Magento\Checkout\Model\Adminhtml\BillingAddressDisplayOptions + Magento\Checkout\Model\Adminhtml\BillingAddressDisplayOptions diff --git a/app/code/Magento/Checkout/etc/config.xml b/app/code/Magento/Checkout/etc/config.xml index eac0bd849da35..c85d68b35f714 100644 --- a/app/code/Magento/Checkout/etc/config.xml +++ b/app/code/Magento/Checkout/etc/config.xml @@ -9,6 +9,7 @@ + 0 1 1 0 diff --git a/app/code/Magento/Checkout/i18n/en_US.csv b/app/code/Magento/Checkout/i18n/en_US.csv index ca118f21f2441..de0c4717e4170 100644 --- a/app/code/Magento/Checkout/i18n/en_US.csv +++ b/app/code/Magento/Checkout/i18n/en_US.csv @@ -186,3 +186,4 @@ Payment,Payment "Show Cross-sell Items in the Shopping Cart","Show Cross-sell Items in the Shopping Cart" "You added %1 to your shopping cart.","You added %1 to your shopping cart." "The shipping method is missing. Select the shipping method and try again.","The shipping method is missing. Select the shipping method and try again." +"Invalid Item Quantity Requested.","Invalid Item Quantity Requested." diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/ActionGroup/AdminDeleteAllTermConditionsActionGroup.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/ActionGroup/AdminDeleteAllTermConditionsActionGroup.xml new file mode 100644 index 0000000000000..fec0a686d839e --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/ActionGroup/AdminDeleteAllTermConditionsActionGroup.xml @@ -0,0 +1,27 @@ + + + + + + Deletes all rows one by one on the 'Terms and Conditions' page. + + + + + + {{AdminTermGridSection.allTermRows}} + {{AdminMainActionsSection.delete}} + {{AdminConfirmationModalSection.ok}} + You deleted the condition. + {{AdminMessagesSection.success}} + + + + + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Helper/CheckoutAgreementsHelpers.php b/app/code/Magento/CheckoutAgreements/Test/Mftf/Helper/CheckoutAgreementsHelpers.php new file mode 100644 index 0000000000000..7f0150b274f47 --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Helper/CheckoutAgreementsHelpers.php @@ -0,0 +1,61 @@ +getModule("\\" . MagentoWebDriver::class); + $webDriver = $magentoWebDriver->webDriver; + + $magentoWebDriver->waitForPageLoad(30); + $rows = $webDriver->findElements(WebDriverBy::xpath($rowsToDelete)); + while (!empty($rows)) { + $rows[0]->click(); + $magentoWebDriver->waitForPageLoad(30); + $magentoWebDriver->waitForElementVisible($deleteButton, 10); + $magentoWebDriver->click($deleteButton); + $magentoWebDriver->waitForPageLoad(30); + $magentoWebDriver->waitForElementVisible($modalAcceptButton, 10); + $magentoWebDriver->click($modalAcceptButton); + $magentoWebDriver->waitForPageLoad(60); + $magentoWebDriver->waitForText($successMessage, 10, $successMessageContainer); + $rows = $webDriver->findElements(WebDriverBy::xpath($rowsToDelete)); + } + } catch (Exception $exception) { + $this->fail($exception->getMessage()); + } + } +} diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Section/AdminTermGridSection.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Section/AdminTermGridSection.xml index 326f9dcce4320..ab198fbfb4ecc 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Section/AdminTermGridSection.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Section/AdminTermGridSection.xml @@ -14,5 +14,7 @@ + + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveHtmlTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveHtmlTermEntityTest.xml index c597d3d660dc8..4c1a258115646 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveHtmlTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveHtmlTermEntityTest.xml @@ -32,10 +32,9 @@ - - - - + + + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveTextTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveTextTermEntityTest.xml index a90c3536ec744..f0c2bac759829 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveTextTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveTextTermEntityTest.xml @@ -20,9 +20,7 @@ - - - + diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json index 753bef25e3e64..e5cc74b014ea3 100644 --- a/app/code/Magento/CheckoutAgreements/composer.json +++ b/app/code/Magento/CheckoutAgreements/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-checkout-agreements", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-checkout": "*", - "magento/module-quote": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json index de6bc855e7847..f75215e0e3e1f 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json +++ b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json @@ -2,19 +2,20 @@ "name": "magento/module-checkout-agreements-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-checkout-agreements": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-checkout-agreements": "100.4.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Cms/Controller/Noroute/Index.php b/app/code/Magento/Cms/Controller/Noroute/Index.php index b30beae73dce1..5475e7960dd26 100644 --- a/app/code/Magento/Cms/Controller/Noroute/Index.php +++ b/app/code/Magento/Cms/Controller/Noroute/Index.php @@ -6,15 +6,17 @@ */ namespace Magento\Cms\Controller\Noroute; +use Magento\Framework\Controller\Result\ForwardFactory; + /** * @SuppressWarnings(PHPMD.AllPurposeAction) */ class Index extends \Magento\Framework\App\Action\Action { /** - * @var \Magento\Framework\Controller\Result\ForwardFactory + * @var ForwardFactory */ - protected $resultForwardFactory; + protected ForwardFactory $resultForwardFactory; /** * @param \Magento\Framework\App\Action\Context $context @@ -48,6 +50,7 @@ public function execute() if ($resultPage) { $resultPage->setStatusHeader(404, '1.1', 'Not Found'); $resultPage->setHeader('Status', '404 File not found'); + $resultPage->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0', true); return $resultPage; } else { /** @var \Magento\Framework\Controller\Result\Forward $resultForward */ diff --git a/app/code/Magento/Cms/Test/Unit/Controller/Noroute/IndexTest.php b/app/code/Magento/Cms/Test/Unit/Controller/Noroute/IndexTest.php index 665b79fdf48be..6d4dcfc0711df 100644 --- a/app/code/Magento/Cms/Test/Unit/Controller/Noroute/IndexTest.php +++ b/app/code/Magento/Cms/Test/Unit/Controller/Noroute/IndexTest.php @@ -29,17 +29,17 @@ class IndexTest extends TestCase /** * @var Index */ - protected $_controller; + protected Index $_controller; /** * @var MockObject */ - protected $_cmsHelperMock; + protected MockObject $_cmsHelperMock; /** * @var MockObject */ - protected $_requestMock; + protected MockObject $_requestMock; /** * @var ForwardFactory|MockObject @@ -121,8 +121,10 @@ public function testExecuteResultPage(): void ->willReturn($this->resultPageMock); $this->resultPageMock ->method('setHeader') - ->with('Status', '404 File not found') - ->willReturn($this->resultPageMock); + ->withConsecutive( + ['Status', '404 File not found'], + ['Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0'] + )->willReturn($this->resultPageMock); $this->_cmsHelperMock->expects( $this->once() )->method( diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json index b3b2ba31db37b..4edaefe5474e3 100644 --- a/app/code/Magento/Cms/composer.json +++ b/app/code/Magento/Cms/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-cms", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "104.0.4-p2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-email": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-variable": "*", - "magento/module-widget": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-email": "101.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-variable": "100.4.*", + "magento/module-widget": "101.2.*" }, "suggest": { - "magento/module-cms-sample-data": "*" + "magento/module-cms-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/CmsGraphQl/composer.json b/app/code/Magento/CmsGraphQl/composer.json index b2550344299fa..31cdf1b9242e7 100644 --- a/app/code/Magento/CmsGraphQl/composer.json +++ b/app/code/Magento/CmsGraphQl/composer.json @@ -2,22 +2,23 @@ "name": "magento/module-cms-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-widget": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-widget": "101.2.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-graph-ql-cache": "*", - "magento/module-store-graph-ql": "*" + "magento/module-graph-ql": "100.4.*", + "magento/module-graph-ql-cache": "100.4.*", + "magento/module-store-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json index 8fb9bbfff22e2..d9e13faaab104 100644 --- a/app/code/Magento/CmsUrlRewrite/composer.json +++ b/app/code/Magento/CmsUrlRewrite/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-cms-url-rewrite", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-store": "*", - "magento/module-url-rewrite": "*" + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-store": "101.1.*", + "magento/module-url-rewrite": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/CmsUrlRewriteGraphQl/composer.json b/app/code/Magento/CmsUrlRewriteGraphQl/composer.json index 70a598d26d574..05fb964b8e51e 100644 --- a/app/code/Magento/CmsUrlRewriteGraphQl/composer.json +++ b/app/code/Magento/CmsUrlRewriteGraphQl/composer.json @@ -2,22 +2,23 @@ "name": "magento/module-cms-url-rewrite-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-store": "*", - "magento/module-url-rewrite-graph-ql": "*", - "magento/module-cms-graph-ql": "*" + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-store": "101.1.*", + "magento/module-url-rewrite-graph-ql": "100.4.*", + "magento/module-cms-graph-ql": "100.4.*" }, "suggest": { - "magento/module-cms-url-rewrite": "*", - "magento/module-catalog-graph-ql": "*" + "magento/module-cms-url-rewrite": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/CompareListGraphQl/composer.json b/app/code/Magento/CompareListGraphQl/composer.json index e8fb5d588852e..bae7c7a6e3769 100644 --- a/app/code/Magento/CompareListGraphQl/composer.json +++ b/app/code/Magento/CompareListGraphQl/composer.json @@ -2,16 +2,17 @@ "name": "magento/module-compare-list-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/Config/Block/System/Config/Form/Field/File.php b/app/code/Magento/Config/Block/System/Config/Form/Field/File.php index 6ebd85af7a5da..edc3d3e977072 100644 --- a/app/code/Magento/Config/Block/System/Config/Form/Field/File.php +++ b/app/code/Magento/Config/Block/System/Config/Form/Field/File.php @@ -9,6 +9,8 @@ * * @author Magento Core Team */ +declare(strict_types=1); + namespace Magento\Config\Block\System\Config\Form\Field; class File extends \Magento\Framework\Data\Form\Element\File @@ -35,7 +37,7 @@ protected function _getDeleteCheckbox() $html = ''; if ((string)$this->getValue()) { $label = __('Delete File'); - $html .= '
' . $this->getValue() . ' '; + $html .= '
' . $this->_escaper->escapeHtml($this->getValue()) . ' '; $html .= 'assertStringContainsString($this->testData['before_element_html'], $html); diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json index 61100e6336c27..b25efbc3d28f1 100644 --- a/app/code/Magento/Config/composer.json +++ b/app/code/Magento/Config/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-config", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cron": "*", - "magento/module-deploy": "*", - "magento/module-directory": "*", - "magento/module-email": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cron": "100.4.*", + "magento/module-deploy": "100.4.*", + "magento/module-directory": "100.4.*", + "magento/module-email": "101.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json index 98205def6a799..6280f47609dbd 100644 --- a/app/code/Magento/ConfigurableImportExport/composer.json +++ b/app/code/Magento/ConfigurableImportExport/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-configurable-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-configurable-product": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-configurable-product": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/CreateNewAttributeActionGroup.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/CreateNewAttributeActionGroup.xml index 9925aba09fb82..0f0ea705971ec 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/CreateNewAttributeActionGroup.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/CreateNewAttributeActionGroup.xml @@ -51,6 +51,7 @@ + diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductAttributeNameDesignData.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductAttributeNameDesignData.xml index 0018f5996c9bc..ec8fc99b46bb3 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductAttributeNameDesignData.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductAttributeNameDesignData.xml @@ -12,7 +12,7 @@ Shoes 60 100 - design + design123 red red123 blue diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/ConfigurableProductAttributeNameDesignSection/CatalogProductsSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/ConfigurableProductAttributeNameDesignSection/CatalogProductsSection.xml index fb71d6cbda2a8..df3fffb6f716c 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/ConfigurableProductAttributeNameDesignSection/CatalogProductsSection.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/ConfigurableProductAttributeNameDesignSection/CatalogProductsSection.xml @@ -14,7 +14,7 @@ - + diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/ConfigurableProductAttributeNameDesignSection/ConfigurableProductSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/ConfigurableProductAttributeNameDesignSection/ConfigurableProductSection.xml index 8099f30941f7d..437411d7c041a 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/ConfigurableProductAttributeNameDesignSection/ConfigurableProductSection.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/ConfigurableProductAttributeNameDesignSection/ConfigurableProductSection.xml @@ -12,7 +12,7 @@ - + diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithVisualSwatchAttributePrependMediaTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithVisualSwatchAttributePrependMediaTest.xml index c76d49a76d947..61d4eb230b9ec 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithVisualSwatchAttributePrependMediaTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithVisualSwatchAttributePrependMediaTest.xml @@ -106,7 +106,9 @@ - + + + @@ -115,14 +117,16 @@ - + - + + + @@ -130,7 +134,10 @@ - + + + + |{{Magento2.filename}}.*.jpg| @@ -157,7 +164,13 @@ - + + + + + + + |{{MagentoLogo.filename}}.*.png| @@ -196,7 +209,10 @@ - + + + + |{{Magento2.filename}}.*.jpg| @@ -223,7 +239,13 @@ - + + + + + + + |{{Magento3.filename}}.*.jpg| @@ -262,7 +284,10 @@ - + + + + |{{Magento2.filename}}.*.jpg| diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index 67b1ad2b2ed33..940a1d8581646 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -1,38 +1,39 @@ { "name": "magento/module-configurable-product", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-quote": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-msrp": "*", - "magento/module-webapi": "*", - "magento/module-sales": "*", - "magento/module-sales-rule": "*", - "magento/module-product-video": "*", - "magento/module-configurable-sample-data": "*", - "magento/module-product-links-sample-data": "*", - "magento/module-tax": "*" + "magento/module-msrp": "100.4.*", + "magento/module-webapi": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-product-video": "100.4.*", + "magento/module-configurable-sample-data": "Sample Data version: 100.4.*", + "magento/module-product-links-sample-data": "Sample Data version: 100.4.*", + "magento/module-tax": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -42,3 +43,4 @@ } } } + diff --git a/app/code/Magento/ConfigurableProductGraphQl/composer.json b/app/code/Magento/ConfigurableProductGraphQl/composer.json index b839227511d88..c6afeab187bdb 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/composer.json +++ b/app/code/Magento/ConfigurableProductGraphQl/composer.json @@ -2,21 +2,22 @@ "name": "magento/module-configurable-product-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-catalog": "*", - "magento/module-configurable-product": "*", - "magento/module-graph-ql": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-quote": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-catalog-inventory": "*", - "magento/framework": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-catalog": "104.0.*", + "magento/module-configurable-product": "100.4.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/ConfigurableProductSales/composer.json b/app/code/Magento/ConfigurableProductSales/composer.json index 55b2e78bd24d2..4256442b87ac1 100644 --- a/app/code/Magento/ConfigurableProductSales/composer.json +++ b/app/code/Magento/ConfigurableProductSales/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-configurable-product-sales", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-configurable-product": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-configurable-product": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json index 00ea8f865928d..55e8dae73c64d 100644 --- a/app/code/Magento/Contact/composer.json +++ b/app/code/Magento/Contact/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-contact", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json index 6a5752792f7fb..597019ad62110 100644 --- a/app/code/Magento/Cookie/composer.json +++ b/app/code/Magento/Cookie/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-cookie", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-backend": "*" + "magento/module-backend": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json index 0468a95b457c0..6cc88e7583af0 100644 --- a/app/code/Magento/Cron/composer.json +++ b/app/code/Magento/Cron/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-cron", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Csp/composer.json b/app/code/Magento/Csp/composer.json index 2079a30d92068..b8aea8598e46d 100644 --- a/app/code/Magento/Csp/composer.json +++ b/app/code/Magento/Csp/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-csp", "description": "CSP module enables Content Security Policies for Magento", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCheckCurrencyConverterApiConfigurationTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCheckCurrencyConverterApiConfigurationTest.xml index 91ae96e2656df..e6086c427a708 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCheckCurrencyConverterApiConfigurationTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCheckCurrencyConverterApiConfigurationTest.xml @@ -18,6 +18,8 @@ + + diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json index 4f6854cbee185..7ea6115b6457c 100644 --- a/app/code/Magento/CurrencySymbol/composer.json +++ b/app/code/Magento/CurrencySymbol/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-currency-symbol", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3-p6", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-page-cache": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-page-cache": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Customer/Api/AccountManagementInterface.php b/app/code/Magento/Customer/Api/AccountManagementInterface.php index 9c607be9f217c..165233cc6a880 100644 --- a/app/code/Magento/Customer/Api/AccountManagementInterface.php +++ b/app/code/Magento/Customer/Api/AccountManagementInterface.php @@ -8,6 +8,7 @@ namespace Magento\Customer\Api; use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\LocalizedException; /** * Interface for managing customers accounts. @@ -194,7 +195,7 @@ public function resendConfirmation($email, $websiteId, $redirectUrl = ''); * Check if given email is associated with a customer account in given website. * * @param string $customerEmail - * @param int $websiteId If not set, will use the current websiteId + * @param int|null $websiteId If not set, will use the current websiteId * @return bool * @throws \Magento\Framework\Exception\LocalizedException */ diff --git a/app/code/Magento/Customer/Controller/Account/Confirm.php b/app/code/Magento/Customer/Controller/Account/Confirm.php index 2fc6ed4d422fb..4d640e660510c 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirm.php +++ b/app/code/Magento/Customer/Controller/Account/Confirm.php @@ -1,9 +1,10 @@ session = $customerSession; $this->scopeConfig = $scopeConfig; @@ -102,13 +114,13 @@ public function __construct( $this->customerRepository = $customerRepository; $this->addressHelper = $addressHelper; $this->urlModel = $urlFactory->create(); + $this->customerLogger = $customerLogger ?? ObjectManager::getInstance()->get(CustomerLogger::class); parent::__construct($context); } /** * Retrieve cookie manager * - * @deprecated 101.0.0 * @return \Magento\Framework\Stdlib\Cookie\PhpCookieManager */ private function getCookieManager() @@ -124,7 +136,6 @@ private function getCookieManager() /** * Retrieve cookie metadata factory * - * @deprecated 101.0.0 * @return \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory */ private function getCookieMetadataFactory() @@ -152,11 +163,12 @@ public function execute() return $resultRedirect; } - $customerId = $this->getRequest()->getParam('id', false); + $customerId = $this->getCustomerId(); $key = $this->getRequest()->getParam('key', false); if (empty($customerId) || empty($key)) { $this->messageManager->addErrorMessage(__('Bad request.')); $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); + // phpcs:ignore Magento2.Legacy.ObsoleteResponse return $resultRedirect->setUrl($this->_redirect->error($url)); } @@ -164,13 +176,19 @@ public function execute() // log in and send greeting email $customerEmail = $this->customerRepository->getById($customerId)->getEmail(); $customer = $this->customerAccountManagement->activate($customerEmail, $key); + $successMessage = $this->getSuccessMessage(); $this->session->setCustomerDataAsLoggedIn($customer); + if ($this->getCookieManager()->getCookie('mage-cache-sessid')) { $metadata = $this->getCookieMetadataFactory()->createCookieMetadata(); $metadata->setPath('/'); $this->getCookieManager()->deleteCookie('mage-cache-sessid', $metadata); } - $this->messageManager->addSuccess($this->getSuccessMessage()); + + if ($successMessage) { + $this->messageManager->addSuccess($successMessage); + } + $resultRedirect->setUrl($this->getSuccessRedirect()); return $resultRedirect; } catch (StateException $e) { @@ -180,36 +198,45 @@ public function execute() } $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); + // phpcs:ignore Magento2.Legacy.ObsoleteResponse return $resultRedirect->setUrl($this->_redirect->error($url)); } + /** + * Returns customer id from request + * + * @return int + */ + private function getCustomerId(): int + { + return (int)$this->getRequest()->getParam('id', 0); + } + /** * Retrieve success message * - * @return string + * @return Phrase|null + * @throws NoSuchEntityException */ protected function getSuccessMessage() { if ($this->addressHelper->isVatValidationEnabled()) { - if ($this->addressHelper->getTaxCalculationAddressType() == Address::TYPE_SHIPPING) { - // @codingStandardsIgnoreStart - $message = __( - 'If you are a registered VAT customer, please click here to enter your shipping address for proper VAT calculation.', - $this->urlModel->getUrl('customer/address/edit') - ); - // @codingStandardsIgnoreEnd - } else { - // @codingStandardsIgnoreStart - $message = __( - 'If you are a registered VAT customer, please click here to enter your billing address for proper VAT calculation.', - $this->urlModel->getUrl('customer/address/edit') - ); - // @codingStandardsIgnoreEnd - } - } else { - $message = __('Thank you for registering with %1.', $this->storeManager->getStore()->getFrontendName()); + return __( + $this->addressHelper->getTaxCalculationAddressType() == Address::TYPE_SHIPPING + ? 'If you are a registered VAT customer, please click here to enter your ' + .'shipping address for proper VAT calculation.' + :'If you are a registered VAT customer, please click here to enter your ' + .'billing address for proper VAT calculation.', + $this->urlModel->getUrl('customer/address/edit') + ); } - return $message; + + $customerId = $this->getCustomerId(); + if ($customerId && $this->customerLogger->get($customerId)->getLastLoginAt()) { + return null; + } + + return __('Thank you for registering with %1.', $this->storeManager->getStore()->getFrontendName()); } /** @@ -229,6 +256,7 @@ protected function getSuccessRedirect() } else { $successUrl = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); } + // phpcs:ignore Magento2.Legacy.ObsoleteResponse return $this->_redirect->success($backUrl ? $backUrl : $successUrl); } } diff --git a/app/code/Magento/Customer/Controller/Account/Confirmation.php b/app/code/Magento/Customer/Controller/Account/Confirmation.php index 59def8640328c..db4f49549116d 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirmation.php +++ b/app/code/Magento/Customer/Controller/Account/Confirmation.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Customer\Controller\Account; use Magento\Customer\Api\AccountManagementInterface; @@ -13,22 +15,26 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\App\Action\Context; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Controller\Result\Redirect; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\State\InvalidTransitionException; +use Magento\Framework\View\Result\Page; use Magento\Framework\View\Result\PageFactory; use Magento\Store\Model\StoreManagerInterface; /** - * Class Confirmation. Send confirmation link to specified email + * Send confirmation link to specified email */ class Confirmation extends AbstractAccount implements HttpGetActionInterface, HttpPostActionInterface { /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ protected $storeManager; /** - * @var \Magento\Customer\Api\AccountManagementInterface + * @var AccountManagementInterface */ protected $customerAccountManagement; @@ -53,7 +59,7 @@ class Confirmation extends AbstractAccount implements HttpGetActionInterface, Ht * @param PageFactory $resultPageFactory * @param StoreManagerInterface $storeManager * @param AccountManagementInterface $customerAccountManagement - * @param Url $customerUrl + * @param Url|null $customerUrl */ public function __construct( Context $context, @@ -74,48 +80,52 @@ public function __construct( /** * Send confirmation link to specified email * - * @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page + * @return Redirect|Page + * @throws LocalizedException */ public function execute() { if ($this->session->isLoggedIn()) { - /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ - $resultRedirect = $this->resultRedirectFactory->create(); - $resultRedirect->setPath('*/*/'); - return $resultRedirect; + return $this->getRedirect('*/*/'); } - // try to confirm by email $email = $this->getRequest()->getPost('email'); - if ($email) { - /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ - $resultRedirect = $this->resultRedirectFactory->create(); + if ($email) { try { $this->customerAccountManagement->resendConfirmation( $email, $this->storeManager->getStore()->getWebsiteId() ); $this->messageManager->addSuccessMessage(__('Please check your email for confirmation key.')); + return $this->getRedirect('*/*/index', ['_secure' => true]); } catch (InvalidTransitionException $e) { $this->messageManager->addSuccessMessage(__('This email does not require confirmation.')); - } catch (\Exception $e) { - $this->messageManager->addExceptionMessage($e, __('Wrong email.')); - $resultRedirect->setPath('*/*/*', ['email' => $email, '_secure' => true]); - return $resultRedirect; + return $this->getRedirect('*/*/index', ['_secure' => true]); + } catch (NoSuchEntityException $e) { + $this->messageManager->addErrorMessage(__('Wrong email.')); } - $this->session->setUsername($email); - $resultRedirect->setPath('*/*/index', ['_secure' => true]); - return $resultRedirect; } - /** @var \Magento\Framework\View\Result\Page $resultPage */ $resultPage = $this->resultPageFactory->create(); - $resultPage->getLayout()->getBlock('accountConfirmation')->setEmail( - $this->getRequest()->getParam('email', $email) - )->setLoginUrl( - $this->customerUrl->getLoginUrl() - ); + $resultPage->getLayout()->getBlock('accountConfirmation') + ->setEmail($email) + ->setLoginUrl($this->customerUrl->getLoginUrl()); return $resultPage; } + + /** + * Returns redirect object + * + * @param string $path + * @param array $params + * @return Redirect + */ + private function getRedirect(string $path, array $params = []): Redirect + { + $resultRedirect = $this->resultRedirectFactory->create(); + $resultRedirect->setPath($path, $params); + + return $resultRedirect; + } } diff --git a/app/code/Magento/Customer/Controller/Account/EditPost.php b/app/code/Magento/Customer/Controller/Account/EditPost.php index d616c03be6bd0..408eb1666bfde 100644 --- a/app/code/Magento/Customer/Controller/Account/EditPost.php +++ b/app/code/Magento/Customer/Controller/Account/EditPost.php @@ -1,6 +1,5 @@ session = $customerSession; - $this->customerAccountManagement = $customerAccountManagement; + $this->accountManagement = $accountManagement; $this->customerRepository = $customerRepository; $this->formKeyValidator = $formKeyValidator; $this->customerExtractor = $customerExtractor; @@ -143,6 +161,9 @@ public function __construct( $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class); $this->filesystem = $filesystem ?: ObjectManager::getInstance()->get(Filesystem::class); $this->sessionCleaner = $sessionCleaner ?: ObjectManager::getInstance()->get(SessionCleanerInterface::class); + $this->accountConfirmation = $accountConfirmation ?: + ObjectManager::getInstance()->get(AccountConfirmation::class); + $this->customerUrl = $customerUrl ?: ObjectManager::getInstance()->get(Url::class); } /** @@ -164,7 +185,6 @@ private function getAuthentication() * Get email notification * * @return EmailNotificationInterface - * @deprecated 100.1.0 */ private function getEmailNotification() { @@ -180,7 +200,6 @@ private function getEmailNotification() */ public function createCsrfValidationException(RequestInterface $request): ?InvalidRequestException { - /** @var Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); $resultRedirect->setPath('*/*/edit'); @@ -203,50 +222,49 @@ public function validateForCsrf(RequestInterface $request): ?bool * * @return Redirect * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @throws SessionException */ public function execute() { - /** @var Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); $validFormKey = $this->formKeyValidator->validate($this->getRequest()); if ($validFormKey && $this->getRequest()->isPost()) { - $currentCustomerDataObject = $this->getCustomerDataObject($this->session->getCustomerId()); - $customerCandidateDataObject = $this->populateNewCustomerDataObject( - $this->_request, - $currentCustomerDataObject - ); + $customer = $this->getCustomerDataObject($this->session->getCustomerId()); + $customerCandidate = $this->populateNewCustomerDataObject($this->_request, $customer); $attributeToDelete = $this->_request->getParam('delete_attribute_value'); if ($attributeToDelete !== null) { - $this->deleteCustomerFileAttribute( - $customerCandidateDataObject, - $attributeToDelete - ); + $this->deleteCustomerFileAttribute($customerCandidate, $attributeToDelete); } try { // whether a customer enabled change email option - $isEmailChanged = $this->processChangeEmailRequest($currentCustomerDataObject); + $isEmailChanged = $this->processChangeEmailRequest($customer); // whether a customer enabled change password option - $isPasswordChanged = $this->changeCustomerPassword($currentCustomerDataObject->getEmail()); + $isPasswordChanged = $this->changeCustomerPassword($customer->getEmail()); // No need to validate customer address while editing customer profile - $this->disableAddressValidation($customerCandidateDataObject); + $this->disableAddressValidation($customerCandidate); + + $this->customerRepository->save($customerCandidate); + $updatedCustomer = $this->customerRepository->getById($customerCandidate->getId()); - $this->customerRepository->save($customerCandidateDataObject); $this->getEmailNotification()->credentialsChanged( - $customerCandidateDataObject, - $currentCustomerDataObject->getEmail(), + $updatedCustomer, + $customer->getEmail(), $isPasswordChanged ); - $this->dispatchSuccessEvent($customerCandidateDataObject); + + $this->dispatchSuccessEvent($updatedCustomer); $this->messageManager->addSuccessMessage(__('You saved the account information.')); // logout from current session if password or email changed. if ($isPasswordChanged || $isEmailChanged) { $this->session->logout(); $this->session->start(); + $this->addComplexSuccessMessage($customer, $updatedCustomer); + return $resultRedirect->setPath('customer/account/login'); } return $resultRedirect->setPath('customer/account'); @@ -276,13 +294,32 @@ public function execute() $this->session->setCustomerFormData($this->getRequest()->getPostValue()); } - /** @var Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); $resultRedirect->setPath('*/*/edit'); return $resultRedirect; } + /** + * Adds a complex success message if email confirmation is required + * + * @param CustomerInterface $outdatedCustomer + * @param CustomerInterface $updatedCustomer + * @throws LocalizedException + */ + private function addComplexSuccessMessage( + CustomerInterface $outdatedCustomer, + CustomerInterface $updatedCustomer + ): void { + if (($outdatedCustomer->getEmail() !== $updatedCustomer->getEmail()) + && $this->accountConfirmation->isCustomerEmailChangedConfirmRequired($updatedCustomer)) { + $this->messageManager->addComplexSuccessMessage( + 'confirmAccountSuccessMessage', + ['url' => $this->customerUrl->getEmailConfirmationUrl($updatedCustomer->getEmail())] + ); + } + } + /** * Account editing action completed successfully event * @@ -303,6 +340,8 @@ private function dispatchSuccessEvent(CustomerInterface $customerCandidateDataOb * @param int $customerId * * @return CustomerInterface + * @throws LocalizedException + * @throws NoSuchEntityException */ private function getCustomerDataObject($customerId) { @@ -342,7 +381,7 @@ private function populateNewCustomerDataObject( * * @param string $email * @return boolean - * @throws InvalidEmailOrPasswordException|InputException + * @throws InvalidEmailOrPasswordException|InputException|LocalizedException */ protected function changeCustomerPassword($email) { @@ -355,7 +394,7 @@ protected function changeCustomerPassword($email) throw new InputException(__('Password confirmation doesn\'t match entered password.')); } - $isPasswordChanged = $this->customerAccountManagement->changePassword($email, $currPass, $newPass); + $isPasswordChanged = $this->accountManagement->changePassword($email, $currPass, $newPass); } return $isPasswordChanged; @@ -393,8 +432,6 @@ private function processChangeEmailRequest(CustomerInterface $currentCustomerDat * Get Customer Mapper instance * * @return Mapper - * - * @deprecated 100.1.3 */ private function getCustomerMapper() { @@ -424,6 +461,7 @@ private function disableAddressValidation($customer) * @param CustomerInterface $customerCandidateDataObject * @param string $attributeToDelete * @return void + * @throws FileSystemException */ private function deleteCustomerFileAttribute( CustomerInterface $customerCandidateDataObject, diff --git a/app/code/Magento/Customer/Model/AccountConfirmation.php b/app/code/Magento/Customer/Model/AccountConfirmation.php index f29330af25874..bba18b48ffaa8 100644 --- a/app/code/Magento/Customer/Model/AccountConfirmation.php +++ b/app/code/Magento/Customer/Model/AccountConfirmation.php @@ -3,8 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Customer\Model; +use Magento\Customer\Api\Data\CustomerInterface; use Magento\Store\Model\ScopeInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Registry; @@ -15,9 +18,29 @@ class AccountConfirmation { /** - * Configuration path for email confirmation. + * Configuration path for email confirmation when creating a new customer + */ + public const XML_PATH_IS_CONFIRM = 'customer/create_account/confirm'; + + /** + * Configuration path for email confirmation when updating an existing customer's email + */ + public const XML_PATH_IS_CONFIRM_EMAIL_CHANGED = 'customer/account_information/confirm'; + + /** + * Constant for confirmed status + */ + private const ACCOUNT_CONFIRMED = 'account_confirmed'; + + /** + * Constant for confirmation required status */ - const XML_PATH_IS_CONFIRM = 'customer/create_account/confirm'; + private const ACCOUNT_CONFIRMATION_REQUIRED = 'account_confirmation_required'; + + /** + * Constant for confirmation not required status + */ + private const ACCOUNT_CONFIRMATION_NOT_REQUIRED = 'account_confirmation_not_required'; /** * @var ScopeConfigInterface @@ -64,6 +87,54 @@ public function isConfirmationRequired($websiteId, $customerId, $customerEmail): ); } + /** + * Check if accounts confirmation is required if email has been changed + * + * @param int|null $websiteId + * @param int|null $customerId + * @param string|null $customerEmail + * @return bool + */ + public function isEmailChangedConfirmationRequired($websiteId, $customerId, $customerEmail): bool + { + return !$this->canSkipConfirmation($customerId, $customerEmail) + && $this->scopeConfig->isSetFlag( + self::XML_PATH_IS_CONFIRM_EMAIL_CHANGED, + ScopeInterface::SCOPE_WEBSITES, + $websiteId + ); + } + + /** + * Returns an email confirmation status if email has been changed + * + * @param CustomerInterface $customer + * @return string + */ + private function getEmailChangedConfirmStatus(CustomerInterface $customer): string + { + $isEmailChangedConfirmationRequired = $this->isEmailChangedConfirmationRequired( + (int)$customer->getWebsiteId(), + (int)$customer->getId(), + $customer->getEmail() + ); + + return $isEmailChangedConfirmationRequired + ? $customer->getConfirmation() ? self::ACCOUNT_CONFIRMATION_REQUIRED : self::ACCOUNT_CONFIRMED + : self::ACCOUNT_CONFIRMATION_NOT_REQUIRED; + } + + /** + * Checks if email confirmation is required for the customer + * + * @param CustomerInterface $customer + * @return bool + */ + public function isCustomerEmailChangedConfirmRequired(CustomerInterface $customer):bool + { + return $this->getEmailChangedConfirmStatus($customer) === self::ACCOUNT_CONFIRMATION_REQUIRED; + } + /** * Check whether confirmation may be skipped when registering using certain email address. * diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 3b00721ac8b9a..6e0aac11d8e98 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Customer\Model; @@ -56,6 +57,7 @@ use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Psr\Log\LoggerInterface as PsrLogger; +use Magento\Customer\Model\Logger as CustomerLogger; /** * Handle various customer account actions @@ -67,6 +69,11 @@ */ class AccountManagement implements AccountManagementInterface { + /** + * System Configuration Path for Enable/Disable Login at Guest Checkout + */ + public const GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG = 'checkout/options/enable_guest_checkout_login'; + /** * Configuration paths for create account email template * @@ -219,7 +226,7 @@ class AccountManagement implements AccountManagementInterface private $customerFactory; /** - * @var \Magento\Customer\Api\Data\ValidationResultsInterfaceFactory + * @var ValidationResultsInterfaceFactory */ private $validationResultsDataFactory; @@ -229,7 +236,7 @@ class AccountManagement implements AccountManagementInterface private $eventManager; /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ private $storeManager; @@ -299,7 +306,7 @@ class AccountManagement implements AccountManagementInterface protected $dataProcessor; /** - * @var \Magento\Framework\Registry + * @var Registry */ protected $registry; @@ -319,7 +326,7 @@ class AccountManagement implements AccountManagementInterface protected $objectFactory; /** - * @var \Magento\Framework\Api\ExtensibleDataObjectConverter + * @var ExtensibleDataObjectConverter */ protected $extensibleDataObjectConverter; @@ -339,7 +346,7 @@ class AccountManagement implements AccountManagementInterface private $emailNotification; /** - * @var \Magento\Eav\Model\Validator\Attribute\Backend + * @var Backend */ private $eavValidator; @@ -388,6 +395,11 @@ class AccountManagement implements AccountManagementInterface */ private $authorization; + /** + * @var CustomerLogger + */ + private CustomerLogger $customerLogger; + /** * @param CustomerFactory $customerFactory * @param ManagerInterface $eventManager @@ -426,6 +438,7 @@ class AccountManagement implements AccountManagementInterface * @param AuthorizationInterface|null $authorization * @param AuthenticationInterface|null $authentication * @param Backend|null $eavValidator + * @param CustomerLogger|null $customerLogger * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @SuppressWarnings(PHPMD.NPathComplexity) @@ -469,7 +482,8 @@ public function __construct( SessionCleanerInterface $sessionCleaner = null, AuthorizationInterface $authorization = null, AuthenticationInterface $authentication = null, - Backend $eavValidator = null + Backend $eavValidator = null, + ?CustomerLogger $customerLogger = null ) { $this->customerFactory = $customerFactory; $this->eventManager = $eventManager; @@ -512,6 +526,7 @@ public function __construct( $this->authorization = $authorization ?? $objectManager->get(AuthorizationInterface::class); $this->authentication = $authentication ?? $objectManager->get(AuthenticationInterface::class); $this->eavValidator = $eavValidator ?? $objectManager->get(Backend::class); + $this->customerLogger = $customerLogger ?? $objectManager->get(CustomerLogger::class); } /** @@ -562,9 +577,9 @@ public function activateById($customerId, $confirmationKey) /** * Activate a customer account using a key that was sent in a confirmation email. * - * @param \Magento\Customer\Api\Data\CustomerInterface $customer + * @param CustomerInterface $customer * @param string $confirmationKey - * @return \Magento\Customer\Api\Data\CustomerInterface + * @return CustomerInterface * @throws InputException * @throws InputMismatchException * @throws InvalidTransitionException @@ -586,12 +601,17 @@ private function activateCustomer($customer, $confirmationKey) // No need to validate customer and customer address while activating customer $this->setIgnoreValidationFlag($customer); $this->customerRepository->save($customer); - $this->getEmailNotification()->newAccount( - $customer, - 'confirmed', - '', - $this->storeManager->getStore()->getId() - ); + + $customerLastLoginAt = $this->customerLogger->get((int)$customer->getId())->getLastLoginAt(); + if (!$customerLastLoginAt) { + $this->getEmailNotification()->newAccount( + $customer, + 'confirmed', + '', + $this->storeManager->getStore()->getId() + ); + } + return $customer; } @@ -615,7 +635,9 @@ public function authenticate($username, $password) } catch (InvalidEmailOrPasswordException $e) { throw new InvalidEmailOrPasswordException(__('Invalid login or password.')); } - if ($customer->getConfirmation() && $this->isConfirmationRequired($customer)) { + + if ($customer->getConfirmation() + && ($this->isConfirmationRequired($customer) || $this->isEmailChangedConfirmationRequired($customer))) { throw new EmailNotConfirmedException(__("This account isn't confirmed. Verify and try again.")); } @@ -630,6 +652,21 @@ public function authenticate($username, $password) return $customer; } + /** + * Checks if account confirmation is required if the email address has been changed + * + * @param CustomerInterface $customer + * @return bool + */ + private function isEmailChangedConfirmationRequired(CustomerInterface $customer): bool + { + return $this->accountConfirmation->isEmailChangedConfirmationRequired( + (int)$customer->getWebsiteId(), + (int)$customer->getId(), + $customer->getEmail() + ); + } + /** * @inheritdoc */ @@ -715,7 +752,7 @@ public function resetPassword($email, $resetToken, $newPassword) $this->setIgnoreValidationFlag($customer); //Validate Token and new password strength - $this->validateResetPasswordToken($customer->getId(), $resetToken); + $this->validateResetPasswordToken((int)$customer->getId(), $resetToken); $this->credentialsValidator->checkPasswordDifferentFromEmail( $email, $newPassword @@ -826,13 +863,10 @@ public function getConfirmationStatus($customerId) { // load customer by id $customer = $this->customerRepository->getById($customerId); - if ($this->isConfirmationRequired($customer)) { - if (!$customer->getConfirmation()) { - return self::ACCOUNT_CONFIRMED; - } - return self::ACCOUNT_CONFIRMATION_REQUIRED; - } - return self::ACCOUNT_CONFIRMATION_NOT_REQUIRED; + + return $this->isConfirmationRequired($customer) + ? $customer->getConfirmation() ? self::ACCOUNT_CONFIRMATION_REQUIRED : self::ACCOUNT_CONFIRMED + : self::ACCOUNT_CONFIRMATION_NOT_REQUIRED; } /** @@ -1102,9 +1136,24 @@ public function validate(CustomerInterface $customer) /** * @inheritdoc + * + * @param string $customerEmail + * @param int|null $websiteId + * @return bool + * @throws LocalizedException */ public function isEmailAvailable($customerEmail, $websiteId = null) { + $guestLoginConfig = $this->scopeConfig->getValue( + self::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + $websiteId + ); + + if (!$guestLoginConfig) { + return true; + } + try { if ($websiteId === null) { $websiteId = $this->storeManager->getStore()->getWebsiteId(); @@ -1213,6 +1262,7 @@ public function isReadonly($customerId) * @return $this * @throws LocalizedException * @deprecated 100.1.0 + * @see EmailNotification::newAccount() */ protected function sendNewAccountEmail( $customer, @@ -1256,6 +1306,7 @@ protected function sendNewAccountEmail( * @throws LocalizedException * @throws NoSuchEntityException * @deprecated 100.1.0 + * @see EmailNotification::credentialsChanged() */ protected function sendPasswordResetNotificationEmail($customer) { @@ -1269,6 +1320,7 @@ protected function sendPasswordResetNotificationEmail($customer) * @param int|string|null $defaultStoreId * @return int * @deprecated 100.1.0 + * @see StoreManagerInterface::getWebsite() * @throws LocalizedException */ protected function getWebsiteStoreId($customer, $defaultStoreId = null) @@ -1286,6 +1338,7 @@ protected function getWebsiteStoreId($customer, $defaultStoreId = null) * * @return array * @deprecated 100.1.0 + * @see EmailNotification::TEMPLATE_TYPES */ protected function getTemplateTypes() { @@ -1319,6 +1372,7 @@ protected function getTemplateTypes() * @return $this * @throws MailException * @deprecated 100.1.0 + * @see EmailNotification::sendEmailTemplate() */ protected function sendEmailTemplate( $customer, @@ -1473,6 +1527,7 @@ public function changeResetPasswordLinkToken(CustomerInterface $customer, string * @throws LocalizedException * @throws NoSuchEntityException * @deprecated 100.1.0 + * @see EmailNotification::passwordReminder() */ public function sendPasswordReminderEmail($customer) { @@ -1502,6 +1557,7 @@ public function sendPasswordReminderEmail($customer) * @throws LocalizedException * @throws NoSuchEntityException * @deprecated 100.1.0 + * @see EmailNotification::passwordResetConfirmation() */ public function sendPasswordResetConfirmationEmail($customer) { @@ -1547,6 +1603,7 @@ protected function getAddressById(CustomerInterface $customer, $addressId) * @return Data\CustomerSecure * @throws NoSuchEntityException * @deprecated 100.1.0 + * @see EmailNotification::getFullCustomerObject() */ protected function getFullCustomerObject($customer) { @@ -1555,7 +1612,7 @@ protected function getFullCustomerObject($customer) $mergedCustomerData = $this->customerRegistry->retrieveSecureData($customer->getId()); $customerData = $this->dataProcessor->buildOutputDataArray( $customer, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $mergedCustomerData->addData($customerData); $mergedCustomerData->setData('name', $this->customerViewHelper->getCustomerName($customer)); @@ -1591,7 +1648,6 @@ private function disableAddressValidation($customer) * Get email notification * * @return EmailNotificationInterface - * @deprecated 100.1.0 */ private function getEmailNotification() { diff --git a/app/code/Magento/Customer/Model/EmailNotification.php b/app/code/Magento/Customer/Model/EmailNotification.php index a4f85a9c4a0c9..a71cf79a4f51b 100644 --- a/app/code/Magento/Customer/Model/EmailNotification.php +++ b/app/code/Magento/Customer/Model/EmailNotification.php @@ -9,6 +9,8 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\MailException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Mail\Template\SenderResolverInterface; use Magento\Store\Model\App\Emulation; use Magento\Store\Model\StoreManagerInterface; @@ -30,28 +32,28 @@ class EmailNotification implements EmailNotificationInterface /**#@+ * Configuration paths for email templates and identities */ - const XML_PATH_FORGOT_EMAIL_IDENTITY = 'customer/password/forgot_email_identity'; + public const XML_PATH_FORGOT_EMAIL_IDENTITY = 'customer/password/forgot_email_identity'; - const XML_PATH_RESET_PASSWORD_TEMPLATE = 'customer/password/reset_password_template'; + public const XML_PATH_RESET_PASSWORD_TEMPLATE = 'customer/password/reset_password_template'; - const XML_PATH_CHANGE_EMAIL_TEMPLATE = 'customer/account_information/change_email_template'; + public const XML_PATH_CHANGE_EMAIL_TEMPLATE = 'customer/account_information/change_email_template'; - const XML_PATH_CHANGE_EMAIL_AND_PASSWORD_TEMPLATE = + public const XML_PATH_CHANGE_EMAIL_AND_PASSWORD_TEMPLATE = 'customer/account_information/change_email_and_password_template'; - const XML_PATH_FORGOT_EMAIL_TEMPLATE = 'customer/password/forgot_email_template'; + public const XML_PATH_FORGOT_EMAIL_TEMPLATE = 'customer/password/forgot_email_template'; - const XML_PATH_REMIND_EMAIL_TEMPLATE = 'customer/password/remind_email_template'; + public const XML_PATH_REMIND_EMAIL_TEMPLATE = 'customer/password/remind_email_template'; - const XML_PATH_REGISTER_EMAIL_IDENTITY = 'customer/create_account/email_identity'; + public const XML_PATH_REGISTER_EMAIL_IDENTITY = 'customer/create_account/email_identity'; - const XML_PATH_REGISTER_EMAIL_TEMPLATE = 'customer/create_account/email_template'; + public const XML_PATH_REGISTER_EMAIL_TEMPLATE = 'customer/create_account/email_template'; - const XML_PATH_REGISTER_NO_PASSWORD_EMAIL_TEMPLATE = 'customer/create_account/email_no_password_template'; + public const XML_PATH_REGISTER_NO_PASSWORD_EMAIL_TEMPLATE = 'customer/create_account/email_no_password_template'; - const XML_PATH_CONFIRM_EMAIL_TEMPLATE = 'customer/create_account/email_confirmation_template'; + public const XML_PATH_CONFIRM_EMAIL_TEMPLATE = 'customer/create_account/email_confirmation_template'; - const XML_PATH_CONFIRMED_EMAIL_TEMPLATE = 'customer/create_account/email_confirmed_template'; + public const XML_PATH_CONFIRMED_EMAIL_TEMPLATE = 'customer/create_account/email_confirmed_template'; /** * self::NEW_ACCOUNT_EMAIL_REGISTERED welcome email, when confirmation is disabled @@ -62,7 +64,7 @@ class EmailNotification implements EmailNotificationInterface * and password is set * self::NEW_ACCOUNT_EMAIL_CONFIRMATION email with confirmation link */ - const TEMPLATE_TYPES = [ + public const TEMPLATE_TYPES = [ self::NEW_ACCOUNT_EMAIL_REGISTERED => self::XML_PATH_REGISTER_EMAIL_TEMPLATE, self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD => self::XML_PATH_REGISTER_NO_PASSWORD_EMAIL_TEMPLATE, self::NEW_ACCOUNT_EMAIL_CONFIRMED => self::XML_PATH_CONFIRMED_EMAIL_TEMPLATE, @@ -71,7 +73,9 @@ class EmailNotification implements EmailNotificationInterface /**#@-*/ - /**#@-*/ + /** + * @var CustomerRegistry + */ private $customerRegistry; /** @@ -109,6 +113,11 @@ class EmailNotification implements EmailNotificationInterface */ private $emulation; + /** + * @var AccountConfirmation + */ + private AccountConfirmation $accountConfirmation; + /** * @param CustomerRegistry $customerRegistry * @param StoreManagerInterface $storeManager @@ -118,6 +127,7 @@ class EmailNotification implements EmailNotificationInterface * @param ScopeConfigInterface $scopeConfig * @param SenderResolverInterface|null $senderResolver * @param Emulation|null $emulation + * @param AccountConfirmation|null $accountConfirmation */ public function __construct( CustomerRegistry $customerRegistry, @@ -127,7 +137,8 @@ public function __construct( DataObjectProcessor $dataProcessor, ScopeConfigInterface $scopeConfig, SenderResolverInterface $senderResolver = null, - Emulation $emulation =null + Emulation $emulation = null, + ?AccountConfirmation $accountConfirmation = null ) { $this->customerRegistry = $customerRegistry; $this->storeManager = $storeManager; @@ -137,6 +148,8 @@ public function __construct( $this->scopeConfig = $scopeConfig; $this->senderResolver = $senderResolver ?? ObjectManager::getInstance()->get(SenderResolverInterface::class); $this->emulation = $emulation ?? ObjectManager::getInstance()->get(Emulation::class); + $this->accountConfirmation = $accountConfirmation ?? ObjectManager::getInstance() + ->get(AccountConfirmation::class); } /** @@ -146,6 +159,7 @@ public function __construct( * @param string $origCustomerEmail * @param bool $isPasswordChanged * @return void + * @throws LocalizedException */ public function credentialsChanged( CustomerInterface $savedCustomer, @@ -153,6 +167,7 @@ public function credentialsChanged( $isPasswordChanged = false ): void { if ($origCustomerEmail != $savedCustomer->getEmail()) { + $this->emailChangedConfirmation($savedCustomer); if ($isPasswordChanged) { $this->emailAndPasswordChanged($savedCustomer, $origCustomerEmail); $this->emailAndPasswordChanged($savedCustomer, $savedCustomer->getEmail()); @@ -175,6 +190,8 @@ public function credentialsChanged( * @param CustomerInterface $customer * @param string $email * @return void + * @throws MailException + * @throws NoSuchEntityException|LocalizedException */ private function emailAndPasswordChanged(CustomerInterface $customer, $email): void { @@ -201,6 +218,8 @@ private function emailAndPasswordChanged(CustomerInterface $customer, $email): v * @param CustomerInterface $customer * @param string $email * @return void + * @throws MailException + * @throws NoSuchEntityException|LocalizedException */ private function emailChanged(CustomerInterface $customer, $email): void { @@ -226,6 +245,8 @@ private function emailChanged(CustomerInterface $customer, $email): void * * @param CustomerInterface $customer * @return void + * @throws MailException + * @throws NoSuchEntityException|LocalizedException */ private function passwordReset(CustomerInterface $customer): void { @@ -255,7 +276,7 @@ private function passwordReset(CustomerInterface $customer): void * @param int|null $storeId * @param string $email * @return void - * @throws \Magento\Framework\Exception\MailException + * @throws MailException|LocalizedException */ private function sendEmailTemplate( $customer, @@ -293,6 +314,7 @@ private function sendEmailTemplate( * * @param CustomerInterface $customer * @return CustomerSecure + * @throws NoSuchEntityException */ private function getFullCustomerObject($customer): CustomerSecure { @@ -312,6 +334,7 @@ private function getFullCustomerObject($customer): CustomerSecure * @param CustomerInterface $customer * @param int|string|null $defaultStoreId * @return int + * @throws LocalizedException */ private function getWebsiteStoreId($customer, $defaultStoreId = null): int { @@ -327,6 +350,9 @@ private function getWebsiteStoreId($customer, $defaultStoreId = null): int * * @param CustomerInterface $customer * @return void + * @throws LocalizedException + * @throws MailException + * @throws NoSuchEntityException */ public function passwordReminder(CustomerInterface $customer): void { @@ -351,6 +377,9 @@ public function passwordReminder(CustomerInterface $customer): void * * @param CustomerInterface $customer * @return void + * @throws LocalizedException + * @throws MailException + * @throws NoSuchEntityException */ public function passwordResetConfirmation(CustomerInterface $customer): void { @@ -412,4 +441,18 @@ public function newAccount( $storeId ); } + + /** + * Sending an email to confirm the email address in case the email address has been changed + * + * @param CustomerInterface $customer + * @throws LocalizedException + */ + private function emailChangedConfirmation(CustomerInterface $customer): void + { + if (!$this->accountConfirmation->isCustomerEmailChangedConfirmRequired($customer)) { + return; + } + $this->newAccount($customer, self::NEW_ACCOUNT_EMAIL_CONFIRMATION, null, $customer->getStoreId()); + } } diff --git a/app/code/Magento/Customer/Model/Plugin/ClearSessionsAfterLogoutPlugin.php b/app/code/Magento/Customer/Model/Plugin/ClearSessionsAfterLogoutPlugin.php new file mode 100644 index 0000000000000..ec837d9737595 --- /dev/null +++ b/app/code/Magento/Customer/Model/Plugin/ClearSessionsAfterLogoutPlugin.php @@ -0,0 +1,108 @@ +session = $customerSession; + $this->saveHandler = $saveHandler; + $this->storage = $storage; + $this->state = $state; + $this->logger = $logger; + } + + /** + * Plugin to clear session after logout + * + * @param Session $subject + * @param Session $result + * @return Session + * @throws LocalizedException + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterLogout(Session $subject, Session $result): Session + { + $isAreaFrontEnd = $this->state->getAreaCode() === Area::AREA_FRONTEND; + $previousSessions = $this->storage->getData(self::PREVIOUS_ACTIVE_SESSIONS); + + if ($isAreaFrontEnd && !empty($previousSessions)) { + foreach ($previousSessions as $sessionId) { + try { + $this->session->start(); + $this->saveHandler->destroy($sessionId); + $this->session->writeClose(); + } catch (SessionException $e) { + $this->logger->error($e); + } + + } + $this->storage->setData(self::PREVIOUS_ACTIVE_SESSIONS, []); + } + return $result; + } +} diff --git a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php index db694ad3295ce..35642f9d0fc1d 100644 --- a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php +++ b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Customer\Model\Plugin; @@ -16,13 +17,23 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\App\State; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Session\StorageInterface; use Psr\Log\LoggerInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\App\Request\Http; /** * Refresh the Customer session if `UpdateSession` notification registered + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class CustomerNotification { + /** + * Array key for all active previous session ids. + */ + private const PREVIOUS_ACTIVE_SESSIONS = 'previous_active_sessions'; + /** * @var Session */ @@ -49,10 +60,15 @@ class CustomerNotification private $logger; /** - * @var RequestInterface|\Magento\Framework\App\Request\Http + * @var RequestInterface|Http */ private $request; + /** + * @var StorageInterface + */ + private StorageInterface $storage; + /** * Initialize dependencies. * @@ -61,7 +77,8 @@ class CustomerNotification * @param State $state * @param CustomerRepositoryInterface $customerRepository * @param LoggerInterface $logger - * @param RequestInterface|null $request + * @param RequestInterface $request + * @param StorageInterface|null $storage */ public function __construct( Session $session, @@ -69,7 +86,8 @@ public function __construct( State $state, CustomerRepositoryInterface $customerRepository, LoggerInterface $logger, - RequestInterface $request + RequestInterface $request, + StorageInterface $storage = null ) { $this->session = $session; $this->notificationStorage = $notificationStorage; @@ -77,6 +95,7 @@ public function __construct( $this->customerRepository = $customerRepository; $this->logger = $logger; $this->request = $request; + $this->storage = $storage ?? ObjectManager::getInstance()->get(StorageInterface::class); } /** @@ -84,23 +103,38 @@ public function __construct( * * @param ActionInterface $subject * @return void - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function beforeExecute(ActionInterface $subject) { - $customerId = $this->session->getCustomerId(); - - if ($this->isFrontendRequest() && $this->isPostRequest() && $this->isSessionUpdateRegisteredFor($customerId)) { - try { - $this->session->regenerateId(); - $customer = $this->customerRepository->getById($customerId); - $this->session->setCustomerData($customer); - $this->session->setCustomerGroupId($customer->getGroupId()); - $this->notificationStorage->remove(NotificationStorage::UPDATE_CUSTOMER_SESSION, $customer->getId()); - } catch (NoSuchEntityException $e) { - $this->logger->error($e); + $customerId = (int)$this->session->getCustomerId(); + + if (!$this->isFrontendRequest() + || !$this->isPostRequest() + || !$this->isSessionUpdateRegisteredFor($customerId)) { + return; + } + + try { + $oldSessionId = $this->session->getSessionId(); + $previousSessions = $this->storage->getData(self::PREVIOUS_ACTIVE_SESSIONS); + + if (empty($previousSessions)) { + $previousSessions = []; } + $previousSessions[] = $oldSessionId; + $this->storage->setData(self::PREVIOUS_ACTIVE_SESSIONS, $previousSessions); + $this->session->regenerateId(); + $customer = $this->customerRepository->getById($customerId); + $this->session->setCustomerData($customer); + $this->session->setCustomerGroupId($customer->getGroupId()); + $this->notificationStorage->remove( + NotificationStorage::UPDATE_CUSTOMER_SESSION, + $customer->getId() + ); + } catch (NoSuchEntityException $e) { + $this->logger->error($e); } } @@ -118,7 +152,7 @@ private function isPostRequest(): bool * Check if the current application area is frontend. * * @return bool - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ private function isFrontendRequest(): bool { @@ -131,8 +165,8 @@ private function isFrontendRequest(): bool * @param int $customerId * @return bool */ - private function isSessionUpdateRegisteredFor($customerId): bool + private function isSessionUpdateRegisteredFor(int $customerId): bool { - return $this->notificationStorage->isExists(NotificationStorage::UPDATE_CUSTOMER_SESSION, $customerId); + return (bool)$this->notificationStorage->isExists(NotificationStorage::UPDATE_CUSTOMER_SESSION, $customerId); } } diff --git a/app/code/Magento/Customer/Model/Plugin/UpdateCustomer.php b/app/code/Magento/Customer/Model/Plugin/UpdateCustomer.php index 7cf5000a859a7..8f9d6e6850060 100644 --- a/app/code/Magento/Customer/Model/Plugin/UpdateCustomer.php +++ b/app/code/Magento/Customer/Model/Plugin/UpdateCustomer.php @@ -11,6 +11,8 @@ use Magento\Framework\Webapi\Rest\Request as RestRequest; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\App\ObjectManager; /** * Update customer by id from request param @@ -22,12 +24,19 @@ class UpdateCustomer */ private $request; + /** + * @var UserContextInterface + */ + private $userContext; + /** * @param RestRequest $request + * @param UserContextInterface|null $userContext */ - public function __construct(RestRequest $request) + public function __construct(RestRequest $request, ?UserContextInterface $userContext = null) { $this->request = $request; + $this->userContext = $userContext ?? ObjectManager::getInstance()->get(UserContextInterface::class); } /** @@ -43,10 +52,14 @@ public function beforeSave( CustomerInterface $customer, ?string $passwordHash = null ): array { - $customerId = $this->request->getParam('customerId'); + $customerSessionId = $this->userContext->getUserType() === UserContextInterface::USER_TYPE_CUSTOMER ? + (int)$this->userContext->getUserId() : 0; + $customerId = (int)$this->request->getParam('customerId'); $bodyParams = $this->request->getBodyParams(); if (!isset($bodyParams['customer']['Id']) && $customerId) { - $customer = $this->getUpdatedCustomer($customerRepository->getById($customerId), $customer); + if ($customerId === $customerSessionId || $customerSessionId === 0) { + $customer = $this->getUpdatedCustomer($customerRepository->getById($customerId), $customer); + } } return [$customer, $passwordHash]; diff --git a/app/code/Magento/Customer/Model/ResourceModel/Customer.php b/app/code/Magento/Customer/Model/ResourceModel/Customer.php index c065f85aa6483..9ae14f68923fa 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/Customer.php +++ b/app/code/Magento/Customer/Model/ResourceModel/Customer.php @@ -7,12 +7,25 @@ namespace Magento\Customer\Model\ResourceModel; +use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Model\AccountConfirmation; use Magento\Customer\Model\Customer\NotificationStorage; +use Magento\Eav\Model\Entity\Context; +use Magento\Eav\Model\Entity\VersionControl\AbstractEntity; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\DataObject; +use Magento\Framework\DB\Select; use Magento\Framework\Exception\AlreadyExistsException; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Model\ResourceModel\Db\VersionControl\RelationComposite; +use Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot; +use Magento\Framework\Stdlib\DateTime; use Magento\Framework\Validator\Exception as ValidatorException; use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Framework\Validator\Factory; +use Magento\Store\Model\StoreManagerInterface; /** * Customer entity resource model @@ -21,27 +34,27 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 */ -class Customer extends \Magento\Eav\Model\Entity\VersionControl\AbstractEntity +class Customer extends AbstractEntity { /** - * @var \Magento\Framework\Validator\Factory + * @var Factory */ protected $_validatorFactory; /** * Core store config * - * @var \Magento\Framework\App\Config\ScopeConfigInterface + * @var ScopeConfigInterface */ protected $_scopeConfig; /** - * @var \Magento\Framework\Stdlib\DateTime + * @var DateTime */ protected $dateTime; /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ protected $storeManager; @@ -63,26 +76,26 @@ class Customer extends \Magento\Eav\Model\Entity\VersionControl\AbstractEntity /** * Customer constructor. * - * @param \Magento\Eav\Model\Entity\Context $context - * @param \Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot $entitySnapshot - * @param \Magento\Framework\Model\ResourceModel\Db\VersionControl\RelationComposite $entityRelationComposite - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param \Magento\Framework\Validator\Factory $validatorFactory - * @param \Magento\Framework\Stdlib\DateTime $dateTime - * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param Context $context + * @param Snapshot $entitySnapshot + * @param RelationComposite $entityRelationComposite + * @param ScopeConfigInterface $scopeConfig + * @param Factory $validatorFactory + * @param DateTime $dateTime + * @param StoreManagerInterface $storeManager * @param array $data - * @param AccountConfirmation $accountConfirmation + * @param AccountConfirmation|null $accountConfirmation * @param EncryptorInterface|null $encryptor * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( - \Magento\Eav\Model\Entity\Context $context, - \Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot $entitySnapshot, - \Magento\Framework\Model\ResourceModel\Db\VersionControl\RelationComposite $entityRelationComposite, - \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, - \Magento\Framework\Validator\Factory $validatorFactory, - \Magento\Framework\Stdlib\DateTime $dateTime, - \Magento\Store\Model\StoreManagerInterface $storeManager, + Context $context, + Snapshot $entitySnapshot, + RelationComposite $entityRelationComposite, + ScopeConfigInterface $scopeConfig, + Factory $validatorFactory, + DateTime $dateTime, + StoreManagerInterface $storeManager, $data = [], AccountConfirmation $accountConfirmation = null, EncryptorInterface $encryptor = null @@ -120,16 +133,16 @@ protected function _getDefaultAttributes() /** * Check customer scope, email and confirmation key before saving * - * @param \Magento\Framework\DataObject|\Magento\Customer\Api\Data\CustomerInterface $customer + * @param DataObject|CustomerInterface $customer * * @return $this * @throws AlreadyExistsException * @throws ValidatorException - * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws NoSuchEntityException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - protected function _beforeSave(\Magento\Framework\DataObject $customer) + protected function _beforeSave(DataObject $customer) { /** @var \Magento\Customer\Model\Customer $customer */ if ($customer->getStoreId() === null) { @@ -169,13 +182,7 @@ protected function _beforeSave(\Magento\Framework\DataObject $customer) } // set confirmation key logic - if (!$customer->getId() && - $this->accountConfirmation->isConfirmationRequired( - $customer->getWebsiteId(), - $customer->getId(), - $customer->getEmail() - ) - ) { + if ($this->isConfirmationRequired($customer)) { $customer->setConfirmation($customer->getRandomConfirmationKey()); } // remove customer confirmation key from database, if empty @@ -195,6 +202,51 @@ protected function _beforeSave(\Magento\Framework\DataObject $customer) return $this; } + /** + * Checks if customer email verification is required + * + * @param DataObject|CustomerInterface $customer + * @return bool + */ + private function isConfirmationRequired(DataObject $customer): bool + { + return $this->isNewCustomerConfirmationRequired($customer) + || $this->isExistingCustomerConfirmationRequired($customer); + } + + /** + * Checks if customer email verification is required for a new customer + * + * @param DataObject|CustomerInterface $customer + * @return bool + */ + private function isNewCustomerConfirmationRequired(DataObject $customer): bool + { + return !$customer->getId() + && $this->accountConfirmation->isConfirmationRequired( + $customer->getWebsiteId(), + $customer->getId(), + $customer->getEmail() + ); + } + + /** + * Checks if customer email verification is required for an existing customer + * + * @param DataObject|CustomerInterface $customer + * @return bool + */ + private function isExistingCustomerConfirmationRequired(DataObject $customer): bool + { + return $customer->getId() + && $customer->dataHasChangedFor('email') + && $this->accountConfirmation->isEmailChangedConfirmationRequired( + (int)$customer->getWebsiteId(), + (int)$customer->getId(), + $customer->getEmail() + ); + } + /** * Validate customer entity * @@ -231,10 +283,10 @@ private function getNotificationStorage() /** * Save customer addresses and set default addresses in attributes backend * - * @param \Magento\Framework\DataObject $customer + * @param DataObject $customer * @return $this */ - protected function _afterSave(\Magento\Framework\DataObject $customer) + protected function _afterSave(DataObject $customer) { $this->getNotificationStorage()->add( NotificationStorage::UPDATE_CUSTOMER_SESSION, @@ -250,9 +302,9 @@ protected function _afterSave(\Magento\Framework\DataObject $customer) /** * Retrieve select object for loading base entity row * - * @param \Magento\Framework\DataObject $object + * @param DataObject $object * @param string|int $rowId - * @return \Magento\Framework\DB\Select + * @return Select */ protected function _getLoadRowSelect($object, $rowId) { @@ -270,7 +322,7 @@ protected function _getLoadRowSelect($object, $rowId) * @param \Magento\Customer\Model\Customer $customer * @param string $email * @return $this - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function loadByEmail(\Magento\Customer\Model\Customer $customer, $email) { @@ -285,7 +337,7 @@ public function loadByEmail(\Magento\Customer\Model\Customer $customer, $email) if ($customer->getSharingConfig()->isWebsiteScope()) { if (!$customer->hasData('website_id')) { - throw new \Magento\Framework\Exception\LocalizedException( + throw new LocalizedException( __("A customer website ID wasn't specified. The ID must be specified to use the website scope.") ); } @@ -390,10 +442,10 @@ public function getWebsiteId($customerId) /** * Custom setter of increment ID if its needed * - * @param \Magento\Framework\DataObject $object + * @param DataObject $object * @return $this */ - public function setNewIncrementId(\Magento\Framework\DataObject $object) + public function setNewIncrementId(DataObject $object) { if ($this->_scopeConfig->getValue( \Magento\Customer\Model\Customer::XML_PATH_GENERATE_HUMAN_FRIENDLY_ID, @@ -419,7 +471,7 @@ public function changeResetPasswordLinkToken(\Magento\Customer\Model\Customer $c if (is_string($passwordLinkToken) && !empty($passwordLinkToken)) { $customer->setRpToken($passwordLinkToken); $customer->setRpTokenCreatedAt( - (new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT) + (new \DateTime())->format(DateTime::DATETIME_PHP_FORMAT) ); } return $this; @@ -469,7 +521,7 @@ public function updateSessionCutOff(int $customerId, int $timestamp): void /** * @inheritDoc */ - protected function _afterLoad(\Magento\Framework\DataObject $customer) + protected function _afterLoad(DataObject $customer) { if ($customer->getData('rp_token')) { $rpToken = $customer->getData('rp_token'); diff --git a/app/code/Magento/Customer/Plugin/Webapi/Controller/Rest/ValidateCustomerData.php b/app/code/Magento/Customer/Plugin/Webapi/Controller/Rest/ValidateCustomerData.php new file mode 100644 index 0000000000000..7d744cb4fe971 --- /dev/null +++ b/app/code/Magento/Customer/Plugin/Webapi/Controller/Rest/ValidateCustomerData.php @@ -0,0 +1,55 @@ +validateInputData($inputData[self::CUSTOMER_KEY]); + } + return [$inputData, $parameters]; + } + + /** + * Validates InputData + * + * @param array $inputData + * @return array + */ + private function validateInputData(array $inputData): array + { + $result = []; + $data = array_filter($inputData, function ($k) use (&$result) { + $key = is_string($k) ? strtolower(str_replace('_', "", $k)) : $k; + return !isset($result[$key]) && ($result[$key] = true); + }, ARRAY_FILTER_USE_KEY); + + return array_map(function ($value) { + return is_array($value) ? $this->validateInputData($value) : $value; + }, $data); + } +} diff --git a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml index 824c898068342..22bbfb0fde809 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml @@ -20,6 +20,7 @@ + @@ -29,6 +30,7 @@ + diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php index 19db3d8317da1..3062d9a5df2d1 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php @@ -12,6 +12,8 @@ use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Controller\Account\Confirm; use Magento\Customer\Helper\Address; +use Magento\Customer\Model\Logger as CustomerLogger; +use Magento\Customer\Model\Log; use Magento\Customer\Model\Session; use Magento\Customer\Model\Url; use Magento\Framework\App\Action\Context; @@ -123,6 +125,16 @@ class ConfirmTest extends TestCase */ protected $redirectResultMock; + /** + * @var CustomerLogger|MockObject + */ + private $customerLoggerMock; + + /** + * @var Log|MockObject + */ + private $logMock; + /** * @inheritdoc */ @@ -143,6 +155,9 @@ protected function setUp(): void ->method('create') ->willReturn($this->urlMock); + $this->customerLoggerMock = $this->createMock(CustomerLogger::class); + $this->logMock = $this->createMock(Log::class); + $this->customerAccountManagementMock = $this->getMockForAbstractClass(AccountManagementInterface::class); $this->customerDataMock = $this->getMockForAbstractClass(CustomerInterface::class); @@ -195,7 +210,8 @@ protected function setUp(): void 'customerAccountManagement' => $this->customerAccountManagementMock, 'customerRepository' => $this->customerRepositoryMock, 'addressHelper' => $this->addressHelperMock, - 'urlFactory' => $urlFactoryMock + 'urlFactory' => $urlFactoryMock, + 'customerLogger' => $this->customerLoggerMock ] ); } @@ -218,6 +234,8 @@ public function testIsLoggedIn(): void } /** + * @param $customerId + * @param $key * @return void * @dataProvider getParametersDataProvider */ @@ -271,7 +289,8 @@ public function getParametersDataProvider(): array * @param $key * @param $vatValidationEnabled * @param $addressType - * @param Phrase $successMessage + * @param $lastLoginAt + * @param $successMessage * * @return void * @dataProvider getSuccessMessageDataProvider @@ -282,7 +301,8 @@ public function testSuccessMessage( $key, $vatValidationEnabled, $addressType, - Phrase $successMessage + $lastLoginAt, + $successMessage ): void { $this->customerSessionMock->expects($this->once()) ->method('isLoggedIn') @@ -292,7 +312,7 @@ public function testSuccessMessage( ->method('getParam') ->willReturnMap( [ - ['id', false, $customerId], + ['id', 0, $customerId], ['key', false, $key] ] ); @@ -333,6 +353,14 @@ public function testSuccessMessage( ['*/*/admin', ['_secure' => true], 'http://store.web/back'] ]); + $this->logMock->expects($vatValidationEnabled ? $this->never() : $this->once()) + ->method('getLastLoginAt') + ->willReturn($lastLoginAt); + $this->customerLoggerMock->expects($vatValidationEnabled ? $this->never() : $this->once()) + ->method('get') + ->with(1) + ->willReturn($this->logMock); + $this->addressHelperMock->expects($this->once()) ->method('isVatValidationEnabled') ->willReturn($vatValidationEnabled); @@ -388,12 +416,14 @@ public function testSuccessMessage( public function getSuccessMessageDataProvider(): array { return [ - [1, 1, false, null, __('Thank you for registering with %1.', 'frontend')], + [1, 1, false, null, 'some-datetime', null], + [1, 1, false, null, null, __('Thank you for registering with %1.', 'frontend')], [ 1, 1, true, Address::TYPE_BILLING, + null, __( 'If you are a registered VAT customer, please click here' . ' to enter your billing address for proper VAT calculation.', @@ -405,12 +435,13 @@ public function getSuccessMessageDataProvider(): array 1, true, Address::TYPE_SHIPPING, + null, __( 'If you are a registered VAT customer, please click here' . ' to enter your shipping address for proper VAT calculation.', 'http://store.web/customer/address/edit' ) - ] + ], ]; } @@ -421,7 +452,8 @@ public function getSuccessMessageDataProvider(): array * @param $successUrl * @param $resultUrl * @param $isSetFlag - * @param Phrase $successMessage + * @param $successMessage + * @param $lastLoginAt * * @return void * @dataProvider getSuccessRedirectDataProvider @@ -433,7 +465,8 @@ public function testSuccessRedirect( $successUrl, $resultUrl, $isSetFlag, - Phrase $successMessage + $lastLoginAt, + $successMessage ): void { $this->customerSessionMock->expects($this->once()) ->method('isLoggedIn') @@ -443,7 +476,7 @@ public function testSuccessRedirect( ->method('getParam') ->willReturnMap( [ - ['id', false, $customerId], + ['id', 0, $customerId], ['key', false, $key], ['back_url', false, $backUrl] ] @@ -469,23 +502,28 @@ public function testSuccessRedirect( ->with($this->customerDataMock) ->willReturnSelf(); - $this->messageManagerMock - ->method('addSuccess') + $this->messageManagerMock->method('addSuccess') ->with($successMessage) ->willReturnSelf(); - $this->messageManagerMock - ->expects($this->never()) + $this->messageManagerMock->expects($this->never()) ->method('addException'); - $this->urlMock - ->method('getUrl') + $this->urlMock->method('getUrl') ->willReturnMap([ ['customer/address/edit', null, 'http://store.web/customer/address/edit'], ['*/*/admin', ['_secure' => true], 'http://store.web/back'], ['*/*/index', ['_secure' => true], $successUrl] ]); + $this->logMock->expects($this->once()) + ->method('getLastLoginAt') + ->willReturn($lastLoginAt); + $this->customerLoggerMock->expects($this->once()) + ->method('get') + ->with(1) + ->willReturn($this->logMock); + $this->storeMock->expects($this->any()) ->method('getFrontendName') ->willReturn('frontend'); @@ -500,10 +538,7 @@ public function testSuccessRedirect( $this->scopeConfigMock->expects($this->any()) ->method('isSetFlag') - ->with( - Url::XML_PATH_CUSTOMER_STARTUP_REDIRECT_TO_DASHBOARD, - ScopeInterface::SCOPE_STORE - ) + ->with(Url::XML_PATH_CUSTOMER_STARTUP_REDIRECT_TO_DASHBOARD, ScopeInterface::SCOPE_STORE) ->willReturn($isSetFlag); $cookieMetadataManager = $this->getMockBuilder(PhpCookieManager::class) @@ -535,6 +570,7 @@ public function getSuccessRedirectDataProvider(): array null, 'http://example.com/back', true, + null, __('Thank you for registering with %1.', 'frontend'), ], [ @@ -544,6 +580,7 @@ public function getSuccessRedirectDataProvider(): array 'http://example.com/success', 'http://example.com/success', true, + null, __('Thank you for registering with %1.', 'frontend'), ], [ @@ -553,7 +590,18 @@ public function getSuccessRedirectDataProvider(): array 'http://example.com/success', 'http://example.com/success', false, + null, __('Thank you for registering with %1.', 'frontend'), + ], + [ + 1, + 1, + null, + 'http://example.com/success', + 'http://example.com/success', + false, + 'some data', + null, ] ]; } diff --git a/app/code/Magento/Customer/Test/Unit/Model/Plugin/CustomerNotificationTest.php b/app/code/Magento/Customer/Test/Unit/Model/Plugin/CustomerNotificationTest.php index 35f9b0b8371c3..c7ae84b1fa0c2 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Plugin/CustomerNotificationTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Plugin/CustomerNotificationTest.php @@ -20,7 +20,13 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; +use Magento\Framework\Session\StorageInterface; +/** + * Unit test for CustomerNotification plugin + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class CustomerNotificationTest extends TestCase { private const STUB_CUSTOMER_ID = 1; @@ -65,6 +71,11 @@ class CustomerNotificationTest extends TestCase */ private $plugin; + /** + * @var StorageInterface|MockObject + */ + private $storage; + protected function setUp(): void { $this->sessionMock = $this->createMock(Session::class); @@ -87,19 +98,27 @@ protected function setUp(): void ->with(NotificationStorage::UPDATE_CUSTOMER_SESSION, self::STUB_CUSTOMER_ID) ->willReturn(true); + $this->storage = $this + ->getMockBuilder(StorageInterface::class) + ->addMethods(['getData', 'setData']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->plugin = new CustomerNotification( $this->sessionMock, $this->notificationStorageMock, $this->appStateMock, $this->customerRepositoryMock, $this->loggerMock, - $this->requestMock + $this->requestMock, + $this->storage ); } public function testBeforeExecute() { $customerGroupId = 1; + $testSessionId = [uniqid()]; $customerMock = $this->getMockForAbstractClass(CustomerInterface::class); $customerMock->method('getGroupId')->willReturn($customerGroupId); @@ -116,6 +135,10 @@ public function testBeforeExecute() $this->sessionMock->expects($this->once())->method('setCustomerData')->with($customerMock); $this->sessionMock->expects($this->once())->method('setCustomerGroupId')->with($customerGroupId); $this->sessionMock->expects($this->once())->method('regenerateId'); + $this->storage->expects($this->once())->method('getData')->willReturn($testSessionId); + $this->storage + ->expects($this->once()) + ->method('setData'); $this->plugin->beforeExecute($this->actionMock); } diff --git a/app/code/Magento/Customer/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateCustomerDataTest.php b/app/code/Magento/Customer/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateCustomerDataTest.php new file mode 100644 index 0000000000000..72d5f36e2266f --- /dev/null +++ b/app/code/Magento/Customer/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateCustomerDataTest.php @@ -0,0 +1,123 @@ +validateCustomerDataObject = ObjectManager::getInstance()->get(ValidateCustomerData::class); + $this->reflectionObject = new ReflectionClass(get_class($this->validateCustomerDataObject)); + } + + /** + * Test if the customer Info is valid + * + * @param array $customerInfo + * @param array $result + * @dataProvider dataProviderInputData + * @throws Exception + */ + public function testValidateInputData(array $customerInfo, array $result) + { + $this->assertEquals( + $result, + $this->invokeValidateInputData('validateInputData', [$customerInfo]) + ); + } + + /** + * @param string $methodName + * @param array $arguments + * @return mixed + * @throws Exception + */ + private function invokeValidateInputData(string $methodName, array $arguments = []) + { + $validateInputDataMethod = $this->reflectionObject->getMethod($methodName); + $validateInputDataMethod->setAccessible(true); + return $validateInputDataMethod->invokeArgs($this->validateCustomerDataObject, $arguments); + } + + /** + * @return array + */ + public function dataProviderInputData(): array + { + return [ + [ + ['customer' => [ + 'id' => -1, + 'Id' => 1, + 'name' => [ + 'firstName' => 'Test', + 'LastName' => 'user' + ], + 'isHavingOwnHouse' => 1, + 'address' => [ + 'street' => '1st Street', + 'Street' => '3rd Street', + 'city' => 'London' + ], + ] + ], + ['customer' => [ + 'id' => -1, + 'name' => [ + 'firstName' => 'Test', + 'LastName' => 'user' + ], + 'isHavingOwnHouse' => 1, + 'address' => [ + 'street' => '1st Street', + 'city' => 'London' + ], + ] + ], + ['customer' => [ + 'id' => -1, + '_Id' => 1, + 'name' => [ + 'firstName' => 'Test', + 'LastName' => 'user' + ], + 'isHavingOwnHouse' => 1, + 'address' => [ + 'street' => '1st Street', + 'city' => 'London' + ], + ] + ], + ] + ]; + } +} diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json index 2d76da56bff7d..ccf5ad94f8481 100644 --- a/app/code/Magento/Customer/composer.json +++ b/app/code/Magento/Customer/composer.json @@ -1,41 +1,42 @@ { "name": "magento/module-customer", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "103.0.4-p6", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-integration": "*", - "magento/module-media-storage": "*", - "magento/module-newsletter": "*", - "magento/module-page-cache": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-wishlist": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-integration": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-newsletter": "100.4.*", + "magento/module-page-cache": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-wishlist": "101.2.*" }, "suggest": { - "magento/module-cookie": "*", - "magento/module-customer-sample-data": "*", - "magento/module-webapi": "*" + "magento/module-cookie": "100.4.*", + "magento/module-customer-sample-data": "Sample Data version: 100.4.*", + "magento/module-webapi": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -45,3 +46,4 @@ } } } + diff --git a/app/code/Magento/Customer/etc/adminhtml/system.xml b/app/code/Magento/Customer/etc/adminhtml/system.xml index 569f9d09c2087..ec76e09fdf459 100644 --- a/app/code/Magento/Customer/etc/adminhtml/system.xml +++ b/app/code/Magento/Customer/etc/adminhtml/system.xml @@ -193,6 +193,10 @@ Email template chosen based on theme fallback when "Default" option is selected. Magento\Config\Model\Config\Source\Email\Template + + + Magento\Config\Model\Config\Source\Yesno + diff --git a/app/code/Magento/Customer/etc/config.xml b/app/code/Magento/Customer/etc/config.xml index 22596e0b901b2..23a7c9ebb4034 100644 --- a/app/code/Magento/Customer/etc/config.xml +++ b/app/code/Magento/Customer/etc/config.xml @@ -32,6 +32,7 @@ customer_account_information_change_email_template customer_account_information_change_email_and_password_template + 0 support diff --git a/app/code/Magento/Customer/etc/frontend/di.xml b/app/code/Magento/Customer/etc/frontend/di.xml index 31f3e11522e12..827a153e94674 100644 --- a/app/code/Magento/Customer/etc/frontend/di.xml +++ b/app/code/Magento/Customer/etc/frontend/di.xml @@ -127,4 +127,7 @@ + + + diff --git a/app/code/Magento/Customer/etc/webapi_rest/di.xml b/app/code/Magento/Customer/etc/webapi_rest/di.xml index 18627b68320ed..c5d7a28a3651d 100644 --- a/app/code/Magento/Customer/etc/webapi_rest/di.xml +++ b/app/code/Magento/Customer/etc/webapi_rest/di.xml @@ -31,6 +31,9 @@ + + + diff --git a/app/code/Magento/CustomerAnalytics/composer.json b/app/code/Magento/CustomerAnalytics/composer.json index 396c7d4ca3364..c866756b082c0 100644 --- a/app/code/Magento/CustomerAnalytics/composer.json +++ b/app/code/Magento/CustomerAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-customer-analytics", "description": "N/A", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-customer": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-customer": "103.0.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/CustomerDownloadableGraphQl/composer.json b/app/code/Magento/CustomerDownloadableGraphQl/composer.json index f33d05e18568a..80d7dc4632e6b 100644 --- a/app/code/Magento/CustomerDownloadableGraphQl/composer.json +++ b/app/code/Magento/CustomerDownloadableGraphQl/composer.json @@ -2,19 +2,20 @@ "name": "magento/module-customer-downloadable-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-downloadable-graph-ql": "*", - "magento/module-graph-ql": "*", - "magento/framework": "*" + "magento/module-downloadable-graph-ql": "100.4.*", + "magento/module-graph-ql": "100.4.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-catalog-graph-ql": "*" + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/CustomerGraphQl/composer.json b/app/code/Magento/CustomerGraphQl/composer.json index 30d94c20acc98..995c4f86bb2f4 100644 --- a/app/code/Magento/CustomerGraphQl/composer.json +++ b/app/code/Magento/CustomerGraphQl/composer.json @@ -2,24 +2,25 @@ "name": "magento/module-customer-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-authorization": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-graph-ql": "*", - "magento/module-newsletter": "*", - "magento/module-integration": "*", - "magento/module-store": "*", - "magento/framework": "*", - "magento/module-directory": "*", - "magento/module-tax": "*", - "magento/module-graph-ql-cache": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-authorization": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-newsletter": "100.4.*", + "magento/module-integration": "100.4.*", + "magento/module-store": "101.1.*", + "magento/framework": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-tax": "100.4.*", + "magento/module-graph-ql-cache": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json index 2f5c74020e602..8b82d0ea307f0 100644 --- a/app/code/Magento/CustomerImportExport/composer.json +++ b/app/code/Magento/CustomerImportExport/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-customer-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/Deploy/composer.json b/app/code/Magento/Deploy/composer.json index e965b6222e375..ebecaa1e53d74 100644 --- a/app/code/Magento/Deploy/composer.json +++ b/app/code/Magento/Deploy/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-deploy", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-config": "*", - "magento/module-require-js": "*", - "magento/module-store": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-config": "101.2.*", + "magento/module-require-js": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-user": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "cli_commands.php", @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json index 49b9d324f0d11..15140b76b7f33 100644 --- a/app/code/Magento/Developer/composer.json +++ b/app/code/Magento/Developer/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-developer", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-config": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json index 9596f789be5fc..77bd3d728563b 100644 --- a/app/code/Magento/Dhl/composer.json +++ b/app/code/Magento/Dhl/composer.json @@ -1,31 +1,32 @@ { "name": "magento/module-dhl", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-checkout": "*" + "magento/module-checkout": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -35,3 +36,4 @@ } } } + diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json index c3973b9cee0c9..b0661a6d3ba5d 100644 --- a/app/code/Magento/Directory/composer.json +++ b/app/code/Magento/Directory/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-directory", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/DirectoryGraphQl/composer.json b/app/code/Magento/DirectoryGraphQl/composer.json index 6acbef5c5534c..24c1c77c45f49 100644 --- a/app/code/Magento/DirectoryGraphQl/composer.json +++ b/app/code/Magento/DirectoryGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-directory-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-directory": "*", - "magento/module-store": "*", - "magento/module-graph-ql": "*", - "magento/framework": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-directory": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-graph-ql": "100.4.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json index a9487f8c430d3..8ad609b5b6faa 100644 --- a/app/code/Magento/Downloadable/composer.json +++ b/app/code/Magento/Downloadable/composer.json @@ -1,37 +1,38 @@ { "name": "magento/module-downloadable", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-gift-message": "*", - "magento/module-media-storage": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-gift-message": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-downloadable-sample-data": "*" + "magento/module-downloadable-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -41,3 +42,4 @@ } } } + diff --git a/app/code/Magento/DownloadableGraphQl/composer.json b/app/code/Magento/DownloadableGraphQl/composer.json index 214b857bcd6f9..0564cb1082821 100644 --- a/app/code/Magento/DownloadableGraphQl/composer.json +++ b/app/code/Magento/DownloadableGraphQl/composer.json @@ -2,24 +2,25 @@ "name": "magento/module-downloadable-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-downloadable": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-quote-graph-ql": "*", - "magento/framework": "*" + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-downloadable": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-catalog-graph-ql": "*", - "magento/module-sales-graph-ql": "*" + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-sales-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/DownloadableImportExport/composer.json b/app/code/Magento/DownloadableImportExport/composer.json index d6daea4b2ac17..4f2bf145a39e5 100644 --- a/app/code/Magento/DownloadableImportExport/composer.json +++ b/app/code/Magento/DownloadableImportExport/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-downloadable-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-downloadable": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-downloadable": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json index 60915bd4ba590..d11db21d9030d 100644 --- a/app/code/Magento/Eav/composer.json +++ b/app/code/Magento/Eav/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-eav", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "102.1.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/EavGraphQl/composer.json b/app/code/Magento/EavGraphQl/composer.json index cfb8dc7ac9e11..40033f8c3cffa 100644 --- a/app/code/Magento/EavGraphQl/composer.json +++ b/app/code/Magento/EavGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-eav-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-eav": "*" + "magento/framework": "103.0.*", + "magento/module-eav": "102.1.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Sort.php b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Sort.php index e8085787f2b44..296a71eda5c61 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Sort.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Sort.php @@ -89,7 +89,8 @@ public function getSort(RequestInterface $request) if (in_array($item['field'], $this->skippedFields)) { continue; } - $attribute = $this->attributeAdapterProvider->getByAttributeCode($item['field']); + $itemField = $item['field'] != null ? $item['field'] : ''; + $attribute = $this->attributeAdapterProvider->getByAttributeCode($itemField); $fieldName = $this->fieldNameResolver->getFieldName($attribute); if (isset($this->map[$fieldName])) { $fieldName = $this->map[$fieldName]; diff --git a/app/code/Magento/Elasticsearch/composer.json b/app/code/Magento/Elasticsearch/composer.json index 568e0b51c13db..1907ea86a6d0f 100644 --- a/app/code/Magento/Elasticsearch/composer.json +++ b/app/code/Magento/Elasticsearch/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-elasticsearch", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "101.0.4-p1", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-advanced-search": "*", - "magento/module-catalog": "*", - "magento/module-catalog-search": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-search": "*", - "magento/module-store": "*", - "magento/module-catalog-inventory": "*", - "magento/framework": "*", + "magento/module-advanced-search": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-search": "101.1.*", + "magento/module-store": "101.1.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/framework": "103.0.*", "elasticsearch/elasticsearch": "~7.16.0" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Elasticsearch6/composer.json b/app/code/Magento/Elasticsearch6/composer.json index 2cc3262e90663..e3a719122de4d 100644 --- a/app/code/Magento/Elasticsearch6/composer.json +++ b/app/code/Magento/Elasticsearch6/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-elasticsearch-6", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-advanced-search": "*", - "magento/module-catalog-search": "*", - "magento/module-search": "*", - "magento/module-elasticsearch": "*", + "magento/framework": "103.0.*", + "magento/module-advanced-search": "100.4.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-search": "101.1.*", + "magento/module-elasticsearch": "101.0.*", "elasticsearch/elasticsearch": "~7.16.0" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Elasticsearch7/composer.json b/app/code/Magento/Elasticsearch7/composer.json index 63cd34d4a11a8..9651cf5616cd7 100644 --- a/app/code/Magento/Elasticsearch7/composer.json +++ b/app/code/Magento/Elasticsearch7/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-elasticsearch-7", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-elasticsearch": "*", + "magento/framework": "103.0.*", + "magento/module-elasticsearch": "101.0.*", "elasticsearch/elasticsearch": "~7.16.0", - "magento/module-advanced-search": "*", - "magento/module-catalog-search": "*" + "magento/module-advanced-search": "100.4.*", + "magento/module-catalog-search": "102.0.*" }, "suggest": { - "magento/module-config": "*", - "magento/module-search": "*" + "magento/module-config": "101.2.*", + "magento/module-search": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Email/Model/Template/Filter.php b/app/code/Magento/Email/Model/Template/Filter.php index aab7284dd0263..4ebd6df4c9b8b 100644 --- a/app/code/Magento/Email/Model/Template/Filter.php +++ b/app/code/Magento/Email/Model/Template/Filter.php @@ -53,12 +53,12 @@ class Filter extends Template /** * The name used in the {{trans}} directive */ - const TRANS_DIRECTIVE_NAME = 'trans'; + public const TRANS_DIRECTIVE_NAME = 'trans'; /** * The regex to match interior portion of a {{trans "foo"}} translation directive */ - const TRANS_DIRECTIVE_REGEX = '/^\s*([\'"])([^\1]*?)(? '']; @@ -119,7 +121,7 @@ class Filter extends Template /** * Core store config - * Variable factory + * Factory for Variable model * * @var VariableFactory */ @@ -273,6 +275,7 @@ public function setUseAbsoluteLinks($flag) * @return $this * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @deprecated SID query parameter is not used in URLs anymore. + * @see SessionId's in URL */ public function setUseSessionInUrl($flag) { @@ -396,6 +399,7 @@ public function blockDirective($construction) { $skipParams = ['class', 'id', 'output']; $blockParameters = $this->getParameters($construction[2]); + $block = null; if (isset($blockParameters['class'])) { @@ -679,6 +683,7 @@ public function varDirective($construction) * @param string $default assumed modifier if none present * @return array * @deprecated 101.0.4 Use the new FilterApplier or Directive Processor interfaces + * @see Directive Processor Interfaces */ protected function explodeModifiers($value, $default = null) { @@ -698,6 +703,7 @@ protected function explodeModifiers($value, $default = null) * @param string $modifiers * @return string * @deprecated 101.0.4 Use the new FilterApplier or Directive Processor interfaces + * @see Directive Processor Interfaces */ protected function applyModifiers($value, $modifiers) { @@ -726,6 +732,7 @@ protected function applyModifiers($value, $modifiers) * @param string $type * @return string * @deprecated 101.0.4 Use the new FilterApplier or Directive Processor interfaces + * @see Directive Processor Interfacees */ public function modifierEscape($value, $type = 'html') { diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json index 4499b1060a011..378736afcf52e 100644 --- a/app/code/Magento/Email/composer.json +++ b/app/code/Magento/Email/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-email", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-require-js": "*", - "magento/module-media-storage": "*", - "magento/module-variable": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-require-js": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-variable": "100.4.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-theme": "*" + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/EncryptionKey/composer.json b/app/code/Magento/EncryptionKey/composer.json index c20cd852d2377..8d573ed694420 100644 --- a/app/code/Magento/EncryptionKey/composer.json +++ b/app/code/Magento/EncryptionKey/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-encryption-key", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Fedex/Model/Config/Backend/FedexUrl.php b/app/code/Magento/Fedex/Model/Config/Backend/FedexUrl.php new file mode 100755 index 0000000000000..fc88ff129d708 --- /dev/null +++ b/app/code/Magento/Fedex/Model/Config/Backend/FedexUrl.php @@ -0,0 +1,75 @@ +url = $url; + parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); + } + + /** + * @inheritdoc + * + * @throws ValidatorException + */ + public function beforeSave(): AbstractModel + { + $isValid = $this->url->isValid($this->getValue()); + if ($isValid) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $host = parse_url((string)$this->getValue(), \PHP_URL_HOST); + + if (!empty($host) && !preg_match('/(?:.+\.|^)fedex\.com$/i', $host)) { + throw new ValidatorException(__('Fedex API endpoint URL\'s must use fedex.com')); + } + } + + return parent::beforeSave(); + } +} diff --git a/app/code/Magento/Fedex/Test/Unit/Model/Config/Backend/FedexUrlTest.php b/app/code/Magento/Fedex/Test/Unit/Model/Config/Backend/FedexUrlTest.php new file mode 100755 index 0000000000000..854e72592f814 --- /dev/null +++ b/app/code/Magento/Fedex/Test/Unit/Model/Config/Backend/FedexUrlTest.php @@ -0,0 +1,131 @@ +contextMock = $this->createMock(Context::class); + $registry = $this->createMock(Registry::class); + $config = $this->createMock(ScopeConfigInterface::class); + $cacheTypeList = $this->createMock(TypeListInterface::class); + $this->url = $this->createMock(Url::class); + $resource = $this->createMock(AbstractResource::class); + $resourceCollection = $this->createMock(AbstractDb::class); + $eventManagerMock = $this->getMockForAbstractClass(ManagerInterface::class); + $eventManagerMock->expects($this->any())->method('dispatch'); + $this->contextMock->expects($this->any())->method('getEventDispatcher')->willReturn($eventManagerMock); + + $this->urlConfig = $objectManager->getObject( + FedexUrl::class, + [ + 'url' => $this->url, + 'context' => $this->contextMock, + 'registry' => $registry, + 'config' => $config, + 'cacheTypeList' => $cacheTypeList, + 'resource' => $resource, + 'resourceCollection' => $resourceCollection, + ] + ); + } + + /** + * @dataProvider validDataProvider + * @param string|null $data The valid data + * @throws ValidatorException + */ + public function testBeforeSave(string $data = null): void + { + $this->url->expects($this->any())->method('isValid')->willReturn(true); + $this->urlConfig->setValue($data); + $this->urlConfig->beforeSave(); + $this->assertTrue($this->url->isValid($data)); + } + + /** + * @dataProvider invalidDataProvider + * @param string $data The invalid data + */ + public function testBeforeSaveErrors(string $data): void + { + $this->url->expects($this->any())->method('isValid')->willReturn(true); + $this->expectException('Magento\Framework\Exception\ValidatorException'); + $this->expectExceptionMessage('Fedex API endpoint URL\'s must use fedex.com'); + $this->urlConfig->setValue($data); + $this->urlConfig->beforeSave(); + } + + /** + * Validator Data Provider + * + * @return array + */ + public function validDataProvider(): array + { + return [ + [], + [null], + [''], + ['http://fedex.com'], + ['https://foo.fedex.com'], + ['http://foo.fedex.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } + + /** + * @return \string[][] + */ + public function invalidDataProvider(): array + { + return [ + ['http://fedexfoo.com'], + ['https://foofedex.com'], + ['https://fedex.com.fake.com'], + ['https://fedex.info'], + ['http://fedex.com.foo.com/foo/bar?baz=bash&fizz=buzz'], + ['http://foofedex.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } +} diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json index 1734040c2c487..37c22989b7f8d 100644 --- a/app/code/Magento/Fedex/composer.json +++ b/app/code/Magento/Fedex/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-fedex", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3-p4", "require": { "php": "~7.4.0||~8.1.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Fedex/etc/adminhtml/system.xml b/app/code/Magento/Fedex/etc/adminhtml/system.xml index f164a8e21e0ae..a200b5bda7199 100644 --- a/app/code/Magento/Fedex/etc/adminhtml/system.xml +++ b/app/code/Magento/Fedex/etc/adminhtml/system.xml @@ -40,12 +40,14 @@ + Magento\Fedex\Model\Config\Backend\FedexUrl 0 + Magento\Fedex\Model\Config\Backend\FedexUrl 1 diff --git a/app/code/Magento/Fedex/i18n/en_US.csv b/app/code/Magento/Fedex/i18n/en_US.csv index d1509d42730bc..2911ebe793f23 100644 --- a/app/code/Magento/Fedex/i18n/en_US.csv +++ b/app/code/Magento/Fedex/i18n/en_US.csv @@ -78,3 +78,4 @@ Debug,Debug "Show Method if Not Applicable","Show Method if Not Applicable" "Sort Order","Sort Order" "Can't convert a shipping cost from ""%1-%2"" for FedEx carrier.","Can't convert a shipping cost from ""%1-%2"" for FedEx carrier." +"Fedex API endpoint URL\'s must use fedex.com","Fedex API endpoint URL\'s must use fedex.com" diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json index f205f2f4621d2..3a5ce78abc8aa 100644 --- a/app/code/Magento/GiftMessage/composer.json +++ b/app/code/Magento/GiftMessage/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-gift-message", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-eav": "*", - "magento/module-multishipping": "*" + "magento/module-eav": "102.1.*", + "magento/module-multishipping": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/GiftMessageGraphQl/composer.json b/app/code/Magento/GiftMessageGraphQl/composer.json index f9b980d26fa78..df748c8a0e223 100644 --- a/app/code/Magento/GiftMessageGraphQl/composer.json +++ b/app/code/Magento/GiftMessageGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-gift-message-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-gift-message": "*" + "magento/framework": "103.0.*", + "magento/module-gift-message": "100.4.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json index 3637b38f9ab61..973e58065d292 100644 --- a/app/code/Magento/GoogleAdwords/composer.json +++ b/app/code/Magento/GoogleAdwords/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-google-adwords", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json index bb94435c9e9fd..9f96b7fe681c2 100644 --- a/app/code/Magento/GoogleAnalytics/composer.json +++ b/app/code/Magento/GoogleAnalytics/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-google-analytics", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-cookie": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-cookie": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json index 7ef2d97679ae0..1cb05b7d4ecd0 100644 --- a/app/code/Magento/GoogleOptimizer/composer.json +++ b/app/code/Magento/GoogleOptimizer/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-google-optimizer", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-cms": "*", - "magento/module-google-analytics": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-cms": "104.0.*", + "magento/module-google-analytics": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/GraphQl/composer.json b/app/code/Magento/GraphQl/composer.json index 880e64d043443..a73fac7e9c8a9 100644 --- a/app/code/Magento/GraphQl/composer.json +++ b/app/code/Magento/GraphQl/composer.json @@ -2,22 +2,23 @@ "name": "magento/module-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-eav": "*", - "magento/framework": "*", - "magento/module-webapi": "*", - "magento/module-new-relic-reporting": "*", - "magento/module-authorization": "*", + "magento/module-eav": "102.1.*", + "magento/framework": "103.0.*", + "magento/module-webapi": "100.4.*", + "magento/module-new-relic-reporting": "100.4.*", + "magento/module-authorization": "100.4.*", "webonyx/graphql-php": "~14.11.3" }, "suggest": { - "magento/module-graph-ql-cache": "*" + "magento/module-graph-ql-cache": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/GraphQlCache/composer.json b/app/code/Magento/GraphQlCache/composer.json index 5be26cbf5990d..8aab21e9092e0 100644 --- a/app/code/Magento/GraphQlCache/composer.json +++ b/app/code/Magento/GraphQlCache/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-graph-ql-cache", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-page-cache": "*", - "magento/module-graph-ql": "*", - "magento/module-authorization": "*", - "magento/module-integration": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-page-cache": "100.4.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-authorization": "100.4.*", + "magento/module-integration": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/GroupedCatalogInventory/composer.json b/app/code/Magento/GroupedCatalogInventory/composer.json index 1a5e6054130eb..a88d53af1d1e4 100644 --- a/app/code/Magento/GroupedCatalogInventory/composer.json +++ b/app/code/Magento/GroupedCatalogInventory/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-grouped-catalog-inventory", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-grouped-product": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-grouped-product": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json index e411f55d00f4e..9c4d19c9f9e91 100644 --- a/app/code/Magento/GroupedImportExport/composer.json +++ b/app/code/Magento/GroupedImportExport/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-grouped-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-eav": "*", - "magento/module-grouped-product": "*", - "magento/module-import-export": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-eav": "102.1.*", + "magento/module-grouped-product": "100.4.*", + "magento/module-import-export": "101.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json index 105e711c75b41..7d1fbbb948a97 100644 --- a/app/code/Magento/GroupedProduct/composer.json +++ b/app/code/Magento/GroupedProduct/composer.json @@ -1,34 +1,35 @@ { "name": "magento/module-grouped-product", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-msrp": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-wishlist": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-msrp": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-wishlist": "101.2.*" }, "suggest": { - "magento/module-grouped-product-sample-data": "*" + "magento/module-grouped-product-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -38,3 +39,4 @@ } } } + diff --git a/app/code/Magento/GroupedProductGraphQl/composer.json b/app/code/Magento/GroupedProductGraphQl/composer.json index bb0f79e208dcb..2e2301b6d5c85 100644 --- a/app/code/Magento/GroupedProductGraphQl/composer.json +++ b/app/code/Magento/GroupedProductGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-grouped-product-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-grouped-product": "*", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*", - "magento/framework": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-grouped-product": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json index b85162e9bec76..1c8e1c2252413 100644 --- a/app/code/Magento/ImportExport/composer.json +++ b/app/code/Magento/ImportExport/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.0.4", "require": { "php": "~7.4.0||~8.1.0", "ext-ctype": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json index bdcd05d5a71e3..3d651e625b625 100644 --- a/app/code/Magento/Indexer/composer.json +++ b/app/code/Magento/Indexer/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-indexer", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/InstantPurchase/composer.json b/app/code/Magento/InstantPurchase/composer.json index c399f60df1dbb..b136fb8bda9c5 100644 --- a/app/code/Magento/InstantPurchase/composer.json +++ b/app/code/Magento/InstantPurchase/composer.json @@ -6,16 +6,17 @@ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-quote": "*", - "magento/module-vault": "*", - "magento/framework": "*" + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-vault": "101.2.*", + "magento/framework": "103.0.*" }, "autoload": { "files": [ @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json index d3c226066226f..77d91bc617ff3 100644 --- a/app/code/Magento/Integration/composer.json +++ b/app/code/Magento/Integration/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-integration", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-security": "*", - "magento/module-store": "*", - "magento/module-user": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-security": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-user": "101.2.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/JwtFrameworkAdapter/composer.json b/app/code/Magento/JwtFrameworkAdapter/composer.json index a375ed0b197a8..2a85dddfe417d 100644 --- a/app/code/Magento/JwtFrameworkAdapter/composer.json +++ b/app/code/Magento/JwtFrameworkAdapter/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-jwt-framework-adapter", "description": "JWT Manager implementation based on jwt-framework", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "web-token/jwt-framework": "^v2.2.7" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/JwtUserToken/composer.json b/app/code/Magento/JwtUserToken/composer.json index d632d6e4a49b0..09414a2f64373 100644 --- a/app/code/Magento/JwtUserToken/composer.json +++ b/app/code/Magento/JwtUserToken/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-jwt-user-token", "description": "Introduces JWT token support for web API authentication", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.0", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-integration": "*", - "magento/module-authorization": "*" + "magento/framework": "103.0.*", + "magento/module-integration": "100.4.*", + "magento/module-authorization": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json index d6285b4260f5f..6180ae95e6f62 100644 --- a/app/code/Magento/LayeredNavigation/composer.json +++ b/app/code/Magento/LayeredNavigation/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-layered-navigation", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-config": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomer/composer.json b/app/code/Magento/LoginAsCustomer/composer.json index 61a4e1c0dda96..4010896f0cc15 100755 --- a/app/code/Magento/LoginAsCustomer/composer.json +++ b/app/code/Magento/LoginAsCustomer/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-login-as-customer", "description": "Allow for admin to enter a customer account", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-login-as-customer-api": "*" - }, - "suggest": { - "magento/module-backend": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*" + }, + "suggest": { + "magento/module-backend": "102.0.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerAdminUi/composer.json b/app/code/Magento/LoginAsCustomerAdminUi/composer.json index 6841ee3790cb3..5aa8a946a5b92 100644 --- a/app/code/Magento/LoginAsCustomerAdminUi/composer.json +++ b/app/code/Magento/LoginAsCustomerAdminUi/composer.json @@ -1,24 +1,24 @@ { "name": "magento/module-login-as-customer-admin-ui", - "description": "", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-login-as-customer-frontend-ui": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-sales": "*", - "magento/module-store": "*" - }, - "suggest": { - "magento/module-login-as-customer": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*", + "magento/module-login-as-customer-frontend-ui": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" + }, + "suggest": { + "magento/module-login-as-customer": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -28,3 +28,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerApi/composer.json b/app/code/Magento/LoginAsCustomerApi/composer.json index e4a0952ac0369..0484d17f1a9df 100644 --- a/app/code/Magento/LoginAsCustomerApi/composer.json +++ b/app/code/Magento/LoginAsCustomerApi/composer.json @@ -1,15 +1,16 @@ { "name": "magento/module-login-as-customer-api", "description": "Allow for admin to enter a customer account", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -19,3 +20,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerAssistance/composer.json b/app/code/Magento/LoginAsCustomerAssistance/composer.json index 58e48bddc7c0f..a39ac21dd4013 100644 --- a/app/code/Magento/LoginAsCustomerAssistance/composer.json +++ b/app/code/Magento/LoginAsCustomerAssistance/composer.json @@ -1,24 +1,24 @@ { "name": "magento/module-login-as-customer-assistance", - "description": "", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-store": "*", - "magento/module-login-as-customer": "*", - "magento/module-login-as-customer-api": "*" - }, - "suggest": { - "magento/module-login-as-customer-admin-ui": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-login-as-customer": "100.4.*", + "magento/module-login-as-customer-api": "100.4.*" + }, + "suggest": { + "magento/module-login-as-customer-admin-ui": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -28,3 +28,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerFrontendUi/composer.json b/app/code/Magento/LoginAsCustomerFrontendUi/composer.json index 8a5437dc42d28..79c8fb7e9fe40 100644 --- a/app/code/Magento/LoginAsCustomerFrontendUi/composer.json +++ b/app/code/Magento/LoginAsCustomerFrontendUi/composer.json @@ -1,18 +1,18 @@ { "name": "magento/module-login-as-customer-frontend-ui", - "description": "", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-customer": "*", - "magento/module-store": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +22,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerGraphQl/composer.json b/app/code/Magento/LoginAsCustomerGraphQl/composer.json index 25a5ef8ff8b6c..51737669a36ad 100755 --- a/app/code/Magento/LoginAsCustomerGraphQl/composer.json +++ b/app/code/Magento/LoginAsCustomerGraphQl/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-login-as-customer-graph-ql", "description": "Flexible login as a customer so a merchant or merchant admin can log into an end customer's account to assist them with their account.", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-login-as-customer-assistance": "*", - "magento/module-integration": "*", - "magento/module-store": "*", - "magento/module-customer": "*" - }, - "suggest": { - "magento/module-login-as-customer": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*", + "magento/module-login-as-customer-assistance": "100.4.*", + "magento/module-integration": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-customer": "103.0.*" + }, + "suggest": { + "magento/module-login-as-customer": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerLog/composer.json b/app/code/Magento/LoginAsCustomerLog/composer.json index 404511f7315f4..cb798372a4662 100644 --- a/app/code/Magento/LoginAsCustomerLog/composer.json +++ b/app/code/Magento/LoginAsCustomerLog/composer.json @@ -1,23 +1,23 @@ { "name": "magento/module-login-as-customer-log", - "description": "", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-ui": "*", - "magento/module-user": "*" - }, - "suggest": { - "magento/module-login-as-customer": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-user": "101.2.*" + }, + "suggest": { + "magento/module-login-as-customer": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -27,3 +27,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerPageCache/composer.json b/app/code/Magento/LoginAsCustomerPageCache/composer.json index 93f74f29ef246..ab29da4834fff 100644 --- a/app/code/Magento/LoginAsCustomerPageCache/composer.json +++ b/app/code/Magento/LoginAsCustomerPageCache/composer.json @@ -1,20 +1,20 @@ { "name": "magento/module-login-as-customer-page-cache", - "description": "", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-login-as-customer-api": "*" - }, - "suggest": { - "magento/module-page-cache": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-login-as-customer-api": "100.4.*" + }, + "suggest": { + "magento/module-page-cache": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -24,3 +24,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerQuote/composer.json b/app/code/Magento/LoginAsCustomerQuote/composer.json index f852948ab757f..cd20e600e3495 100644 --- a/app/code/Magento/LoginAsCustomerQuote/composer.json +++ b/app/code/Magento/LoginAsCustomerQuote/composer.json @@ -1,21 +1,21 @@ { "name": "magento/module-login-as-customer-quote", - "description": "", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-quote": "*" - }, - "suggest": { - "magento/module-login-as-customer-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-quote": "101.2.*" + }, + "suggest": { + "magento/module-login-as-customer-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +25,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerSales/composer.json b/app/code/Magento/LoginAsCustomerSales/composer.json index ba24858b6f548..d86e972a4a115 100644 --- a/app/code/Magento/LoginAsCustomerSales/composer.json +++ b/app/code/Magento/LoginAsCustomerSales/composer.json @@ -1,21 +1,21 @@ { "name": "magento/module-login-as-customer-sales", - "description": "", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-user": "*", - "magento/module-login-as-customer-api": "*" - }, - "suggest": { - "magento/module-sales": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-user": "101.2.*", + "magento/module-login-as-customer-api": "100.4.*" + }, + "suggest": { + "magento/module-sales": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Marketplace/composer.json b/app/code/Magento/Marketplace/composer.json index f468808298344..ae1f36cbfc0f3 100644 --- a/app/code/Magento/Marketplace/composer.json +++ b/app/code/Magento/Marketplace/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-marketplace", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3-p5", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Marketplace/view/adminhtml/templates/index.phtml b/app/code/Magento/Marketplace/view/adminhtml/templates/index.phtml index ac39d72388e6c..fc58db1bed373 100644 --- a/app/code/Magento/Marketplace/view/adminhtml/templates/index.phtml +++ b/app/code/Magento/Marketplace/view/adminhtml/templates/index.phtml @@ -32,8 +32,8 @@

escapeHtml(__('Partner search')) ?>

escapeHtml(__( - 'Magento has a thriving ecosystem of technology partners to help merchants and brands deliver ' . - 'the best possible customer experiences. They are recognized as experts in eCommerce, ' . + 'Magento has a thriving ecosystem of technology partners to help merchants and brands deliver ' + . 'the best possible customer experiences. They are recognized as experts in eCommerce, ' . 'search, email marketing, payments, tax, fraud, optimization and analytics, fulfillment, ' . 'and more. Visit the Magento Partner Directory to see all of our trusted partners.' )); ?> @@ -61,7 +61,7 @@ )); ?>

+ href="https://commercemarketplace.adobe.com/"> escapeHtml(__('Visit Magento Marketplaces')) ?>
diff --git a/app/code/Magento/MediaContent/composer.json b/app/code/Magento/MediaContent/composer.json index 7eb51b02f61eb..e47e10de7e66f 100644 --- a/app/code/Magento/MediaContent/composer.json +++ b/app/code/Magento/MediaContent/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-content", "description": "Magento module provides the implementation for managing relations between content and media files used in that content", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-content-api": "*", - "magento/module-media-gallery-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-content-api": "100.4.*", + "magento/module-media-gallery-api": "101.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaContentApi/composer.json b/app/code/Magento/MediaContentApi/composer.json index 86dc6408cd6fd..b991f600f38cd 100644 --- a/app/code/Magento/MediaContentApi/composer.json +++ b/app/code/Magento/MediaContentApi/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-media-content-api", "description": "Magento module provides the API interfaces for managing relations between content and media files used in that content", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-media-gallery-api": "*", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-media-gallery-api": "101.0.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/MediaContentCatalog/composer.json b/app/code/Magento/MediaContentCatalog/composer.json index 822fd1ec73814..1e22e96975989 100644 --- a/app/code/Magento/MediaContentCatalog/composer.json +++ b/app/code/Magento/MediaContentCatalog/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-media-content-catalog", "description": "Magento module provides the implementation of MediaContent functionality for Magento_Catalog module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-media-content-api": "*", - "magento/module-catalog": "*", - "magento/module-eav": "*", - "magento/module-store": "*", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-media-content-api": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-eav": "102.1.*", + "magento/module-store": "101.1.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/MediaContentCms/composer.json b/app/code/Magento/MediaContentCms/composer.json index 6cd121d00d2a2..72b3376b3ba84 100644 --- a/app/code/Magento/MediaContentCms/composer.json +++ b/app/code/Magento/MediaContentCms/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-content-cms", "description": "Magento module provides the implementation of MediaContent functionality for Magento_Cms module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-media-content-api": "*", - "magento/module-cms": "*", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-media-content-api": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaContentSynchronization/composer.json b/app/code/Magento/MediaContentSynchronization/composer.json index a3062c163b246..9074756a2f0da 100644 --- a/app/code/Magento/MediaContentSynchronization/composer.json +++ b/app/code/Magento/MediaContentSynchronization/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-media-content-synchronization", "description": "Magento module provides implementation of the media content data synchronization.", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/framework-bulk": "*", - "magento/module-media-content-synchronization-api": "*", - "magento/module-media-content-api": "*", - "magento/module-asynchronous-operations": "*" - }, - "suggest": { - "magento/module-media-gallery-synchronization": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/framework-bulk": "101.0.*", + "magento/module-media-content-synchronization-api": "100.4.*", + "magento/module-media-content-api": "100.4.*", + "magento/module-asynchronous-operations": "100.4.*" + }, + "suggest": { + "magento/module-media-gallery-synchronization": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/MediaContentSynchronizationApi/composer.json b/app/code/Magento/MediaContentSynchronizationApi/composer.json index 953d665b79a4d..7fbac6cf63cfb 100644 --- a/app/code/Magento/MediaContentSynchronizationApi/composer.json +++ b/app/code/Magento/MediaContentSynchronizationApi/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-media-content-synchronization-api", "description": "Magento module responsible for the media content synchronization implementation API", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-content-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-content-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/MediaContentSynchronizationCatalog/composer.json b/app/code/Magento/MediaContentSynchronizationCatalog/composer.json index 7a0375e30c370..00b185eea5cfd 100644 --- a/app/code/Magento/MediaContentSynchronizationCatalog/composer.json +++ b/app/code/Magento/MediaContentSynchronizationCatalog/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-content-synchronization-catalog", "description": "Magento module provides the implementation of MediaContentSynchronization functionality for Magento_Catalog module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-content-synchronization-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-content-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-content-synchronization-api": "100.4.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-media-content-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaContentSynchronizationCms/composer.json b/app/code/Magento/MediaContentSynchronizationCms/composer.json index 9e1236bcb863d..c5f213102070a 100644 --- a/app/code/Magento/MediaContentSynchronizationCms/composer.json +++ b/app/code/Magento/MediaContentSynchronizationCms/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-content-synchronization-cms", "description": "Magento module provides the implementation of MediaContentSynchronization functionality for Magento_Cms module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-content-synchronization-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-content-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-content-synchronization-api": "100.4.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-media-content-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaGallery/composer.json b/app/code/Magento/MediaGallery/composer.json index ccea65f248c26..4b9a99ac967da 100644 --- a/app/code/Magento/MediaGallery/composer.json +++ b/app/code/Magento/MediaGallery/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-gallery", "description": "Magento module responsible for media handling", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*", - "magento/module-cms": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-cms": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryApi/composer.json b/app/code/Magento/MediaGalleryApi/composer.json index d4299f8ef5e8d..5d9da6d6e7231 100644 --- a/app/code/Magento/MediaGalleryApi/composer.json +++ b/app/code/Magento/MediaGalleryApi/composer.json @@ -1,15 +1,16 @@ { "name": "magento/module-media-gallery-api", "description": "Magento module responsible for media gallery asset attributes storage and management", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "101.0.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -19,3 +20,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryCatalog/composer.json b/app/code/Magento/MediaGalleryCatalog/composer.json index ce438f66fda19..e681c5903b381 100644 --- a/app/code/Magento/MediaGalleryCatalog/composer.json +++ b/app/code/Magento/MediaGalleryCatalog/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-gallery-catalog", "description": "Magento module responsible for catalog gallery processor delete operation handling", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*", - "magento/module-catalog": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-catalog": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryCatalogIntegration/composer.json b/app/code/Magento/MediaGalleryCatalogIntegration/composer.json index 477312fd0e4fb..d538419f75eb9 100644 --- a/app/code/Magento/MediaGalleryCatalogIntegration/composer.json +++ b/app/code/Magento/MediaGalleryCatalogIntegration/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-media-gallery-catalog-integration", "description": "Magento module responsible for extending catalog image uploader functionality", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-gallery-ui-api": "*" - }, - "suggest": { - "magento/module-catalog": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-media-gallery-ui-api": "100.4.*" + }, + "suggest": { + "magento/module-catalog": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryCatalogUi/composer.json b/app/code/Magento/MediaGalleryCatalogUi/composer.json index 296de50df5189..274c1d75d41d4 100644 --- a/app/code/Magento/MediaGalleryCatalogUi/composer.json +++ b/app/code/Magento/MediaGalleryCatalogUi/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-media-gallery-catalog-ui", "description": "Magento module that implement category grid for media gallery.", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-store": "*", - "magento/module-ui": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryCmsUi/composer.json b/app/code/Magento/MediaGalleryCmsUi/composer.json index 01e65b4212322..c0cfa93ed7ca7 100644 --- a/app/code/Magento/MediaGalleryCmsUi/composer.json +++ b/app/code/Magento/MediaGalleryCmsUi/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-gallery-cms-ui", "description": "Cms related UI elements in the magento media gallery", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-backend": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-backend": "102.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryIntegration/composer.json b/app/code/Magento/MediaGalleryIntegration/composer.json index a29b109174369..3581aa5c2ebf9 100644 --- a/app/code/Magento/MediaGalleryIntegration/composer.json +++ b/app/code/Magento/MediaGalleryIntegration/composer.json @@ -1,26 +1,24 @@ { "name": "magento/module-media-gallery-integration", "description": "Magento module responsible for integration of enhanced media gallery", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-gallery-ui-api": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-ui": "*" - }, - "require-dev": { - "magento/module-cms": "*" - }, - "suggest": { - "magento/module-catalog": "*", - "magento/module-cms": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-ui-api": "100.4.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-ui": "101.2.*" + }, + "suggest": { + "magento/module-catalog": "104.0.*", + "magento/module-cms": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -28,5 +26,9 @@ "psr-4": { "Magento\\MediaGalleryIntegration\\": "" } + }, + "require-dev": { + "magento/module-cms": "*" } } + diff --git a/app/code/Magento/MediaGalleryMetadata/composer.json b/app/code/Magento/MediaGalleryMetadata/composer.json index 88a54ffadab49..a276e10212ea6 100644 --- a/app/code/Magento/MediaGalleryMetadata/composer.json +++ b/app/code/Magento/MediaGalleryMetadata/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-media-gallery-metadata", "description": "Magento module responsible for images metadata processing", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-gallery-metadata-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-metadata-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryMetadataApi/composer.json b/app/code/Magento/MediaGalleryMetadataApi/composer.json index ea8ec2763678b..df1962f0b5def 100644 --- a/app/code/Magento/MediaGalleryMetadataApi/composer.json +++ b/app/code/Magento/MediaGalleryMetadataApi/composer.json @@ -1,15 +1,16 @@ { "name": "magento/module-media-gallery-metadata-api", "description": "Magento module responsible for media gallery metadata implementation API", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -19,3 +20,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryRenditions/composer.json b/app/code/Magento/MediaGalleryRenditions/composer.json index e18f3ae6e78c3..eb452c55b6463 100644 --- a/app/code/Magento/MediaGalleryRenditions/composer.json +++ b/app/code/Magento/MediaGalleryRenditions/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-media-gallery-renditions", "description": "Magento module that implements height and width fields for for media gallery items.", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-gallery-renditions-api": "*", - "magento/module-media-gallery-api": "*", - "magento/framework-message-queue": "*", - "magento/module-cms": "*" - }, - "suggest": { - "magento/module-media-content-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-renditions-api": "100.4.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/framework-message-queue": "100.4.*", + "magento/module-cms": "104.0.*" + }, + "suggest": { + "magento/module-media-content-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryRenditionsApi/composer.json b/app/code/Magento/MediaGalleryRenditionsApi/composer.json index 589247e91f269..8ca5cf9765d6b 100644 --- a/app/code/Magento/MediaGalleryRenditionsApi/composer.json +++ b/app/code/Magento/MediaGalleryRenditionsApi/composer.json @@ -1,15 +1,16 @@ { "name": "magento/module-media-gallery-renditions-api", "description": "Magento module that is responsible for the API implementation of Media Gallery Renditions.", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -19,3 +20,4 @@ } } } + diff --git a/app/code/Magento/MediaGallerySynchronization/composer.json b/app/code/Magento/MediaGallerySynchronization/composer.json index 0a7b05a9f4fca..349f02dd3d5a9 100644 --- a/app/code/Magento/MediaGallerySynchronization/composer.json +++ b/app/code/Magento/MediaGallerySynchronization/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-gallery-synchronization", "description": "Magento module provides implementation of the media gallery data synchronization.", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/framework-message-queue": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/framework-message-queue": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaGallerySynchronizationApi/composer.json b/app/code/Magento/MediaGallerySynchronizationApi/composer.json index e7b388d7f407d..71d90601936f6 100644 --- a/app/code/Magento/MediaGallerySynchronizationApi/composer.json +++ b/app/code/Magento/MediaGallerySynchronizationApi/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-media-gallery-synchronization-api", "description": "Magento module responsible for the media gallery synchronization implementation API", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/MediaGallerySynchronizationMetadata/composer.json b/app/code/Magento/MediaGallerySynchronizationMetadata/composer.json index 38088910e6a78..df46bf6b541ef 100644 --- a/app/code/Magento/MediaGallerySynchronizationMetadata/composer.json +++ b/app/code/Magento/MediaGallerySynchronizationMetadata/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-gallery-synchronization-metadata", "description": "Magento module responsible for images metadata synchronization", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-metadata-api": "*", - "magento/module-media-gallery-synchronization-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-metadata-api": "100.4.*", + "magento/module-media-gallery-synchronization-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryUi/composer.json b/app/code/Magento/MediaGalleryUi/composer.json index c95c16cfc8ad2..668942c4a9b83 100644 --- a/app/code/Magento/MediaGalleryUi/composer.json +++ b/app/code/Magento/MediaGalleryUi/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-media-gallery-ui", "description": "Magento module responsible for the media gallery UI implementation", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-ui": "*", - "magento/module-store": "*", - "magento/module-media-gallery-ui-api": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-metadata-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-content-api": "*", - "magento/module-cms": "*", - "magento/module-directory": "*", - "magento/module-authorization": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-ui": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-media-gallery-ui-api": "100.4.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-metadata-api": "100.4.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-media-content-api": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-directory": "100.4.*", + "magento/module-authorization": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryUiApi/composer.json b/app/code/Magento/MediaGalleryUiApi/composer.json index b1078e8e3a4f7..9ec4bcc3e70ed 100644 --- a/app/code/Magento/MediaGalleryUiApi/composer.json +++ b/app/code/Magento/MediaGalleryUiApi/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-gallery-ui-api", "description": "Magento module responsible for the media gallery UI implementation API", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*" - }, - "suggest": { - "magento/module-cms": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*" + }, + "suggest": { + "magento/module-cms": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json index 1654e1645e7ba..4e946668366fd 100644 --- a/app/code/Magento/MediaStorage/composer.json +++ b/app/code/Magento/MediaStorage/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-media-storage", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/framework-bulk": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-theme": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-authorization": "*" + "magento/framework": "103.0.*", + "magento/framework-bulk": "101.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-theme": "101.1.*", + "magento/module-asynchronous-operations": "100.4.*", + "magento/module-authorization": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/MessageQueue/composer.json b/app/code/Magento/MessageQueue/composer.json index 2038e14ad32ed..02d5b1f427401 100644 --- a/app/code/Magento/MessageQueue/composer.json +++ b/app/code/Magento/MessageQueue/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-message-queue", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { - "magento/framework": "*", - "magento/framework-message-queue": "*", + "magento/framework": "103.0.*", + "magento/framework-message-queue": "100.4.*", "magento/magento-composer-installer": "*", "php": "~7.4.0||~8.1.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json index 926b35621be3d..d37ba0d9eb8a9 100644 --- a/app/code/Magento/Msrp/composer.json +++ b/app/code/Magento/Msrp/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-msrp", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-downloadable": "*", - "magento/module-eav": "*", - "magento/module-store": "*", - "magento/module-tax": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-downloadable": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*" }, "suggest": { - "magento/module-bundle": "*", - "magento/module-msrp-sample-data": "*" + "magento/module-bundle": "101.0.*", + "magento/module-msrp-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/MsrpConfigurableProduct/composer.json b/app/code/Magento/MsrpConfigurableProduct/composer.json index 067a89c0be42a..08b8189548fa2 100644 --- a/app/code/Magento/MsrpConfigurableProduct/composer.json +++ b/app/code/Magento/MsrpConfigurableProduct/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-msrp-configurable-product", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-msrp": "*", - "magento/module-configurable-product": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-msrp": "100.4.*", + "magento/module-configurable-product": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/MsrpGroupedProduct/composer.json b/app/code/Magento/MsrpGroupedProduct/composer.json index 0ea4a60098282..0459ed15e5842 100644 --- a/app/code/Magento/MsrpGroupedProduct/composer.json +++ b/app/code/Magento/MsrpGroupedProduct/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-msrp-grouped-product", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-msrp": "*", - "magento/module-grouped-product": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-msrp": "100.4.*", + "magento/module-grouped-product": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json index e796d7fd01b11..c53ad11c3a9d1 100644 --- a/app/code/Magento/Multishipping/composer.json +++ b/app/code/Magento/Multishipping/composer.json @@ -1,28 +1,29 @@ { "name": "magento/module-multishipping", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-captcha": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-captcha": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -32,3 +33,4 @@ } } } + diff --git a/app/code/Magento/MysqlMq/composer.json b/app/code/Magento/MysqlMq/composer.json index 8b62c6daf183c..fe41e39668ed5 100644 --- a/app/code/Magento/MysqlMq/composer.json +++ b/app/code/Magento/MysqlMq/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-mysql-mq", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { - "magento/framework": "*", - "magento/framework-message-queue": "*", + "magento/framework": "103.0.*", + "magento/framework-message-queue": "100.4.*", "magento/magento-composer-installer": "*", - "magento/module-store": "*", + "magento/module-store": "101.1.*", "php": "~7.4.0||~8.1.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/NewRelicReporting/composer.json b/app/code/Magento/NewRelicReporting/composer.json index b566a7117dc48..9e18c622c14ff 100644 --- a/app/code/Magento/NewRelicReporting/composer.json +++ b/app/code/Magento/NewRelicReporting/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-new-relic-reporting", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "magento/magento-composer-installer": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-configurable-product": "*", - "magento/module-customer": "*", - "magento/module-store": "*" + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-configurable-product": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingDeleteNewsletterTemplateActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingDeleteNewsletterTemplateActionGroup.xml index fd9c372388689..9077e352f19bf 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingDeleteNewsletterTemplateActionGroup.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingDeleteNewsletterTemplateActionGroup.xml @@ -10,7 +10,9 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + + diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingOpenNewsletterTemplateFromGridActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingOpenNewsletterTemplateFromGridActionGroup.xml index 0341e68cf2b13..018d7cb17f1d0 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingOpenNewsletterTemplateFromGridActionGroup.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingOpenNewsletterTemplateFromGridActionGroup.xml @@ -9,6 +9,8 @@ + + diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json index 9c3e3627e4cea..2673fa78f59d0 100644 --- a/app/code/Magento/Newsletter/composer.json +++ b/app/code/Magento/Newsletter/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-newsletter", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cms": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-email": "*", - "magento/module-require-js": "*", - "magento/module-store": "*", - "magento/module-widget": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cms": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-email": "101.1.*", + "magento/module-require-js": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-widget": "101.2.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/NewsletterGraphQl/composer.json b/app/code/Magento/NewsletterGraphQl/composer.json index 03fa7650257fb..d22cb8259142c 100644 --- a/app/code/Magento/NewsletterGraphQl/composer.json +++ b/app/code/Magento/NewsletterGraphQl/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-newsletter-graph-ql", "description": "Provides GraphQl functionality for the newsletter subscriptions.", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, - "type": "magento2-module", + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-customer": "*", - "magento/module-newsletter": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-customer": "103.0.*", + "magento/module-newsletter": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json index cdd383aee71e5..74f2c5183fdac 100644 --- a/app/code/Magento/OfflinePayments/composer.json +++ b/app/code/Magento/OfflinePayments/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-offline-payments", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-payment": "*", - "magento/module-quote": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json index e58f678e47770..789e1099b13cf 100644 --- a/app/code/Magento/OfflineShipping/composer.json +++ b/app/code/Magento/OfflineShipping/composer.json @@ -1,31 +1,32 @@ { "name": "magento/module-offline-shipping", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-sales-rule": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-checkout": "*", - "magento/module-offline-shipping-sample-data": "*" + "magento/module-checkout": "100.4.*", + "magento/module-offline-shipping-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -35,3 +36,4 @@ } } } + diff --git a/app/code/Magento/PageCache/Controller/Block.php b/app/code/Magento/PageCache/Controller/Block.php old mode 100644 new mode 100755 index e69614496c66d..7d87ed14efd6e --- a/app/code/Magento/PageCache/Controller/Block.php +++ b/app/code/Magento/PageCache/Controller/Block.php @@ -1,20 +1,26 @@ translateInline = $translateInline; $this->jsonSerializer = $jsonSerializer - ?: \Magento\Framework\App\ObjectManager::getInstance()->get(Json::class); + ?: ObjectManager::getInstance()->get(Json::class); $this->base64jsonSerializer = $base64jsonSerializer - ?: \Magento\Framework\App\ObjectManager::getInstance()->get(Base64Json::class); + ?: ObjectManager::getInstance()->get(Base64Json::class); $this->layoutCacheKey = $layoutCacheKey - ?: \Magento\Framework\App\ObjectManager::getInstance()->get(LayoutCacheKeyInterface::class); + ?: ObjectManager::getInstance()->get(LayoutCacheKeyInterface::class); + $this->regexValidatorFactory = $regexValidatorFactory + ?: ObjectManager::getInstance()->get(RegexFactory::class); + $this->config = $scopeConfig; } /** @@ -79,10 +112,19 @@ protected function _getBlocks() } $blocks = $this->jsonSerializer->unserialize($blocks); $handles = $this->base64jsonSerializer->unserialize($handles); + $handlesSize = (int)$this->config->getValue(self::XML_HANDLES_SIZE); + $handles = ($handlesSize && count($handles) > $handlesSize) + ? array_splice($handles, 0, $handlesSize) : $handles; + + if (!$this->validateHandleParam($handles)) { + return []; + } $layout = $this->_view->getLayout(); $this->layoutCacheKey->addCacheKeys($this->layoutCacheKeyName); + // loadLayout() is using actionHandlers flag which doesn't exist in Framework\View\Layout\Builder::build + // phpcs:ignore $this->_view->loadLayout($handles, true, true, false); $data = []; @@ -95,4 +137,22 @@ protected function _getBlocks() return $data; } + + /** + * Validates handles parameter + * + * @param array $handles + * @return bool + */ + private function validateHandleParam($handles): bool + { + $validator = $this->regexValidatorFactory->create(['pattern' => self::VALIDATION_RULE_PATTERN]); + foreach ($handles as $handle) { + if ($handle && !$validator->isValid($handle)) { + return false; + } + } + + return true; + } } diff --git a/app/code/Magento/PageCache/Test/Unit/Controller/Block/EsiTest.php b/app/code/Magento/PageCache/Test/Unit/Controller/Block/EsiTest.php index c0c4eac7d5255..a003d6aa3bd1f 100644 --- a/app/code/Magento/PageCache/Test/Unit/Controller/Block/EsiTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Controller/Block/EsiTest.php @@ -18,6 +18,8 @@ use Magento\Framework\View\Element\AbstractBlock; use Magento\Framework\View\Layout; use Magento\Framework\View\Layout\LayoutCacheKeyInterface; +use Magento\Framework\Validator\Regex; +use Magento\Framework\Validator\RegexFactory; use Magento\PageCache\Controller\Block; use Magento\PageCache\Controller\Block\Esi; use Magento\PageCache\Test\Unit\Block\Controller\StubBlock; @@ -64,6 +66,11 @@ class EsiTest extends TestCase */ protected $translateInline; + /** + * Validation pattern for handles array + */ + private const VALIDATION_RULE_PATTERN = '/^[a-z0-9]+[a-z0-9_]*$/i'; + /** * Set up before test */ @@ -98,6 +105,16 @@ protected function setUp(): void $this->translateInline = $this->getMockForAbstractClass(InlineInterface::class); + $regexFactoryMock = $this->getMockBuilder(RegexFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $regexObject = new Regex(self::VALIDATION_RULE_PATTERN); + + $regexFactoryMock->expects($this->any())->method('create') + ->willReturn($regexObject); + $helperObjectManager = new ObjectManager($this); $this->action = $helperObjectManager->getObject( Esi::class, @@ -106,7 +123,8 @@ protected function setUp(): void 'translateInline' => $this->translateInline, 'jsonSerializer' => new Json(), 'base64jsonSerializer' => new Base64Json(), - 'layoutCacheKey' => $this->layoutCacheKeyMock + 'layoutCacheKey' => $this->layoutCacheKeyMock, + 'regexValidatorFactory' => $regexFactoryMock ] ); } diff --git a/app/code/Magento/PageCache/Test/Unit/Controller/Block/RenderTest.php b/app/code/Magento/PageCache/Test/Unit/Controller/Block/RenderTest.php index 89e4b06994a71..7cec177a3a0bb 100644 --- a/app/code/Magento/PageCache/Test/Unit/Controller/Block/RenderTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Controller/Block/RenderTest.php @@ -18,6 +18,8 @@ use Magento\Framework\View\Layout; use Magento\Framework\View\Layout\LayoutCacheKeyInterface; use Magento\Framework\View\Layout\ProcessorInterface; +use Magento\Framework\Validator\Regex; +use Magento\Framework\Validator\RegexFactory; use Magento\PageCache\Controller\Block; use Magento\PageCache\Controller\Block\Render; use Magento\PageCache\Test\Unit\Block\Controller\StubBlock; @@ -69,6 +71,11 @@ class RenderTest extends TestCase */ protected $layoutCacheKeyMock; + /** + * Validation pattern for handles array + */ + private const VALIDATION_RULE_PATTERN = '/^[a-z0-9]+[a-z0-9_]*$/i'; + /** * @inheritDoc */ @@ -111,6 +118,16 @@ protected function setUp(): void $this->translateInline = $this->getMockForAbstractClass(InlineInterface::class); + $regexFactoryMock = $this->getMockBuilder(RegexFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $regexObject = new Regex(self::VALIDATION_RULE_PATTERN); + + $regexFactoryMock->expects($this->any())->method('create') + ->willReturn($regexObject); + $helperObjectManager = new ObjectManager($this); $this->action = $helperObjectManager->getObject( Render::class, @@ -119,7 +136,8 @@ protected function setUp(): void 'translateInline' => $this->translateInline, 'jsonSerializer' => new Json(), 'base64jsonSerializer' => new Base64Json(), - 'layoutCacheKey' => $this->layoutCacheKeyMock + 'layoutCacheKey' => $this->layoutCacheKeyMock, + 'regexValidatorFactory' => $regexFactoryMock ] ); } diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json index 08a17cda61bbe..779adbc4f4085 100644 --- a/app/code/Magento/PageCache/composer.json +++ b/app/code/Magento/PageCache/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-page-cache", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/PageCache/etc/adminhtml/system.xml b/app/code/Magento/PageCache/etc/adminhtml/system.xml index 4ffc20958748d..73c8c913ba63c 100644 --- a/app/code/Magento/PageCache/etc/adminhtml/system.xml +++ b/app/code/Magento/PageCache/etc/adminhtml/system.xml @@ -78,6 +78,10 @@ Public content cache lifetime in seconds. If field is empty default value 86400 will be saved. Magento\PageCache\Model\System\Config\Backend\Ttl + + + Handles params size. For better performance use handles parameter size between 50 and 100. + diff --git a/app/code/Magento/PageCache/etc/config.xml b/app/code/Magento/PageCache/etc/config.xml index 8a2412030c6aa..7ec052cb065ea 100644 --- a/app/code/Magento/PageCache/etc/config.xml +++ b/app/code/Magento/PageCache/etc/config.xml @@ -24,6 +24,7 @@ varnish4.vcl 86400 + 100 1 localhost diff --git a/app/code/Magento/PageCache/etc/di.xml b/app/code/Magento/PageCache/etc/di.xml index f70a561342763..acaee4b373b0f 100644 --- a/app/code/Magento/PageCache/etc/di.xml +++ b/app/code/Magento/PageCache/etc/di.xml @@ -35,6 +35,7 @@ Magento\Framework\View\Layout\LayoutCacheKeyInterface + Magento\Framework\App\Config\ScopeConfigInterface\Proxy diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json index 8caad77d9b36b..a32139dd3caf3 100644 --- a/app/code/Magento/Payment/composer.json +++ b/app/code/Magento/Payment/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-payment", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/PaymentGraphQl/composer.json b/app/code/Magento/PaymentGraphQl/composer.json index 8332d7dee0a4a..fc1d50dceb9f2 100644 --- a/app/code/Magento/PaymentGraphQl/composer.json +++ b/app/code/Magento/PaymentGraphQl/composer.json @@ -2,19 +2,20 @@ "name": "magento/module-payment-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.0", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-payment": "*", - "magento/module-graph-ql": "*" + "magento/framework": "103.0.*", + "magento/module-payment": "100.4.*", + "magento/module-graph-ql": "100.4.*" }, "suggest": { - "magento/module-store-graph-ql": "*" + "magento/module-store-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Paypal/composer.json b/app/code/Magento/Paypal/composer.json index b157a63fefeb2..3a3be55ed01cf 100644 --- a/app/code/Magento/Paypal/composer.json +++ b/app/code/Magento/Paypal/composer.json @@ -1,39 +1,40 @@ { "name": "magento/module-paypal", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.0.4", "require": { "php": "~7.4.0||~8.1.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-instant-purchase": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-vault": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-instant-purchase": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-vault": "101.2.*" }, "suggest": { - "magento/module-checkout-agreements": "*" + "magento/module-checkout-agreements": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -43,3 +44,4 @@ } } } + diff --git a/app/code/Magento/PaypalCaptcha/Test/Mftf/Test/StorefrontPaymentsCaptchaWithPayflowProTest.xml b/app/code/Magento/PaypalCaptcha/Test/Mftf/Test/StorefrontPaymentsCaptchaWithPayflowProTest.xml index 0a84cebfe3770..50a1076b5229d 100644 --- a/app/code/Magento/PaypalCaptcha/Test/Mftf/Test/StorefrontPaymentsCaptchaWithPayflowProTest.xml +++ b/app/code/Magento/PaypalCaptcha/Test/Mftf/Test/StorefrontPaymentsCaptchaWithPayflowProTest.xml @@ -18,6 +18,8 @@ + + diff --git a/app/code/Magento/PaypalCaptcha/composer.json b/app/code/Magento/PaypalCaptcha/composer.json index 3f1f5bad59c3b..8080aa0435f7c 100644 --- a/app/code/Magento/PaypalCaptcha/composer.json +++ b/app/code/Magento/PaypalCaptcha/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-paypal-captcha", "description": "Provides CAPTCHA validation for PayPal Payflow Pro", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-captcha": "*", - "magento/module-checkout": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-captcha": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-paypal": "*" + "magento/module-paypal": "101.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/PaypalGraphQl/composer.json b/app/code/Magento/PaypalGraphQl/composer.json index ea8a43c64257d..7469a68fed93a 100644 --- a/app/code/Magento/PaypalGraphQl/composer.json +++ b/app/code/Magento/PaypalGraphQl/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-paypal-graph-ql", "description": "GraphQl support for Paypal", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-quote": "*", - "magento/module-checkout": "*", - "magento/module-paypal": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-sales": "*", - "magento/module-payment": "*", - "magento/module-store": "*", - "magento/module-vault": "*" + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*", + "magento/module-checkout": "100.4.*", + "magento/module-paypal": "101.0.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-payment": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-vault": "101.2.*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-store-graph-ql": "*" + "magento/module-graph-ql": "100.4.*", + "magento/module-store-graph-ql": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml index 159b5b6b9e79b..83814d4900818 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml @@ -152,6 +152,7 @@ + diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json index 3e4b24c38b92b..e2f11eed313e0 100644 --- a/app/code/Magento/Persistent/composer.json +++ b/app/code/Magento/Persistent/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-persistent", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p6", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-cron": "*", - "magento/module-customer": "*", - "magento/module-page-cache": "*", - "magento/module-quote": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-cron": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-page-cache": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json index 8533a0e37443e..59266f60cd0bc 100644 --- a/app/code/Magento/ProductAlert/composer.json +++ b/app/code/Magento/ProductAlert/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-product-alert", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/framework-bulk": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-store": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/framework-bulk": "101.0.*", + "magento/module-asynchronous-operations": "100.4.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/ProductVideo/composer.json b/app/code/Magento/ProductVideo/composer.json index 6d35ce9c3440a..bffbf263f27cb 100644 --- a/app/code/Magento/ProductVideo/composer.json +++ b/app/code/Magento/ProductVideo/composer.json @@ -1,28 +1,29 @@ { "name": "magento/module-product-video", "description": "Add Video to Products", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "magento/magento-composer-installer": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*" + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-customer": "*", - "magento/module-config": "*" + "magento/module-customer": "103.0.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -32,3 +33,4 @@ } } } + diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php index 6f8a44dff464c..93185227b080a 100644 --- a/app/code/Magento/Quote/Model/BillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php @@ -3,14 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Quote\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\InputException; -use Magento\Quote\Model\Quote\Address\BillingAddressPersister; -use Psr\Log\LoggerInterface as Logger; use Magento\Quote\Api\BillingAddressManagementInterface; -use Magento\Framework\App\ObjectManager; +use Magento\Quote\Api\Data\AddressInterface; +use Psr\Log\LoggerInterface as Logger; /** * Quote billing address write service object. @@ -25,14 +26,14 @@ class BillingAddressManagement implements BillingAddressManagementInterface protected $addressValidator; /** - * Logger. + * Logger object. * * @var Logger */ protected $logger; /** - * Quote repository. + * Quote repository object. * * @var \Magento\Quote\Api\CartRepositoryInterface */ @@ -72,10 +73,14 @@ public function __construct( * @inheritdoc * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false) + public function assign($cartId, AddressInterface $address, $useForShipping = false) { /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); + + // validate the address + $this->addressValidator->validateWithExistingAddress($quote, $address); + $address->setCustomerId($quote->getCustomerId()); $quote->removeAddress($quote->getBillingAddress()->getId()); $quote->setBillingAddress($address); diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index 48cd4b2eb2fad..476f2fc6534d5 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -5,6 +5,7 @@ */ namespace Magento\Quote\Model; +use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Api\Data\GroupInterface; use Magento\Directory\Model\AllowedCountries; @@ -112,7 +113,7 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C /** * Checkout login method key */ - const CHECKOUT_METHOD_LOGIN_IN = 'login_in'; + public const CHECKOUT_METHOD_LOGIN_IN = 'login_in'; /** * @var string @@ -172,15 +173,11 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C protected $_preventSaving = false; /** - * Catalog product - * * @var \Magento\Catalog\Helper\Product */ protected $_catalogProduct; /** - * Quote validator - * * @var \Magento\Quote\Model\QuoteValidator */ protected $quoteValidator; @@ -213,8 +210,6 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C protected $_customerFactory; /** - * Group repository - * * @var \Magento\Customer\Api\GroupRepositoryInterface */ protected $groupRepository; @@ -260,22 +255,16 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C protected $_objectCopyService; /** - * Address repository - * * @var \Magento\Customer\Api\AddressRepositoryInterface */ protected $addressRepository; /** - * Search criteria builder - * * @var \Magento\Framework\Api\SearchCriteriaBuilder */ protected $searchCriteriaBuilder; /** - * Filter builder - * * @var \Magento\Framework\Api\FilterBuilder */ protected $filterBuilder; @@ -874,7 +863,8 @@ public function beforeSave() * Loading quote data by customer * * @param \Magento\Customer\Model\Customer|int $customer - * @deprecated 101.0.0 + * @deprecated 101.0.0 Deprecated to handle external usages of customer methods + * @see https://jira.corp.magento.com/browse/MAGETWO-19935 * @return $this */ public function loadByCustomer($customer) @@ -1356,7 +1346,7 @@ public function setBillingAddress(\Magento\Quote\Api\Data\AddressInterface $addr { $old = $this->getAddressesCollection()->getItemById($address->getId()) ?? $this->getBillingAddress(); - if (!empty($old)) { + if ($old) { $old->addData($address->getData()); } else { $this->addAddress($address->setAddressType(Address::TYPE_BILLING)); @@ -1378,7 +1368,7 @@ public function setShippingAddress(\Magento\Quote\Api\Data\AddressInterface $add } else { $old = $this->getAddressesCollection()->getItemById($address->getId()) ?? $this->getShippingAddress(); - if (!empty($old)) { + if ($old) { $old->addData($address->getData()); } else { $this->addAddress($address->setAddressType(Address::TYPE_SHIPPING)); @@ -1427,12 +1417,14 @@ public function getItemsCollection($useCache = true) public function getAllItems() { $items = []; + /** @var \Magento\Quote\Model\Quote\Item $item */ foreach ($this->getItemsCollection() as $item) { - /** @var \Magento\Quote\Model\Quote\Item $item */ - if (!$item->isDeleted()) { + $product = $item->getProduct(); + if (!$item->isDeleted() && ($product && (int)$product->getStatus() !== ProductStatus::STATUS_DISABLED)) { $items[] = $item; } } + return $items; } diff --git a/app/code/Magento/Quote/Model/QuoteAddressValidator.php b/app/code/Magento/Quote/Model/QuoteAddressValidator.php index f0bc12f7b3a36..1306d2d6b985f 100644 --- a/app/code/Magento/Quote/Model/QuoteAddressValidator.php +++ b/app/code/Magento/Quote/Model/QuoteAddressValidator.php @@ -3,8 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Quote\Model; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\Session; +use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Api\Data\CartInterface; @@ -17,35 +24,35 @@ class QuoteAddressValidator { /** - * Address factory. - * - * @var \Magento\Customer\Api\AddressRepositoryInterface + * @var AddressRepositoryInterface */ - protected $addressRepository; + protected AddressRepositoryInterface $addressRepository; /** - * Customer repository. + * Customer repository object. * - * @var \Magento\Customer\Api\CustomerRepositoryInterface + * @var CustomerRepositoryInterface */ - protected $customerRepository; + protected CustomerRepositoryInterface $customerRepository; /** + * @var Session * @deprecated 101.1.1 This class is not a part of HTML presentation layer and should not use sessions. + * @see Session */ - protected $customerSession; + protected Session $customerSession; /** * Constructs a quote shipping address validator service object. * - * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository - * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository Customer repository. - * @param \Magento\Customer\Model\Session $customerSession + * @param AddressRepositoryInterface $addressRepository + * @param CustomerRepositoryInterface $customerRepository Customer repository. + * @param Session $customerSession */ public function __construct( - \Magento\Customer\Api\AddressRepositoryInterface $addressRepository, - \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository, - \Magento\Customer\Model\Session $customerSession + AddressRepositoryInterface $addressRepository, + CustomerRepositoryInterface $customerRepository, + Session $customerSession ) { $this->addressRepository = $addressRepository; $this->customerRepository = $customerRepository; @@ -56,10 +63,10 @@ public function __construct( * Validate address. * * @param AddressInterface $address - * @param int|null $customerId Cart belongs to + * @param int|null $customerId * @return void - * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer. - * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid. + * @throws LocalizedException The specified customer ID or address ID is not valid. + * @throws NoSuchEntityException The specified customer ID or address ID is not valid. */ private function doValidate(AddressInterface $address, ?int $customerId): void { @@ -67,7 +74,7 @@ private function doValidate(AddressInterface $address, ?int $customerId): void if ($customerId) { $customer = $this->customerRepository->getById($customerId); if (!$customer->getId()) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __('Invalid customer id %1', $customerId) ); } @@ -76,7 +83,7 @@ private function doValidate(AddressInterface $address, ?int $customerId): void if ($address->getCustomerAddressId()) { //Existing address cannot belong to a guest if (!$customerId) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __('Invalid customer address id %1', $address->getCustomerAddressId()) ); } @@ -84,7 +91,7 @@ private function doValidate(AddressInterface $address, ?int $customerId): void try { $this->addressRepository->getById($address->getCustomerAddressId()); } catch (NoSuchEntityException $e) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __('Invalid address id %1', $address->getId()) ); } @@ -94,7 +101,7 @@ private function doValidate(AddressInterface $address, ?int $customerId): void return $address->getId(); }, $this->customerRepository->getById($customerId)->getAddresses()); if (!in_array($address->getCustomerAddressId(), $applicableAddressIds)) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __('Invalid customer address id %1', $address->getCustomerAddressId()) ); } @@ -104,29 +111,75 @@ private function doValidate(AddressInterface $address, ?int $customerId): void /** * Validates the fields in a specified address data object. * - * @param \Magento\Quote\Api\Data\AddressInterface $addressData The address data object. + * @param AddressInterface $addressData The address data object. * @return bool - * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer. - * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid. + * @throws InputException The specified address belongs to another customer. + * @throws NoSuchEntityException|LocalizedException The specified customer ID or address ID is not valid. */ - public function validate(AddressInterface $addressData) + public function validate(AddressInterface $addressData): bool { $this->doValidate($addressData, $addressData->getCustomerId()); return true; } + /** + * Validate Quest Address for guest user + * + * @param AddressInterface $address + * @param CartInterface $cart + * @return void + * @throws NoSuchEntityException + */ + private function doValidateForGuestQuoteAddress(AddressInterface $address, CartInterface $cart): void + { + //validate guest cart address + if ($address->getId() !== null) { + $old = $cart->getAddressById($address->getId()); + + if ($old === false) { + throw new NoSuchEntityException( + __('Invalid quote address id %1', $address->getId()) + ); + } + } + } + /** * Validate address to be used for cart. * * @param CartInterface $cart * @param AddressInterface $address * @return void - * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer. - * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid. + * @throws InputException The specified address belongs to another customer. + * @throws NoSuchEntityException|LocalizedException The specified customer ID or address ID is not valid. */ public function validateForCart(CartInterface $cart, AddressInterface $address): void { - $this->doValidate($address, $cart->getCustomerIsGuest() ? null : $cart->getCustomer()->getId()); + if ($cart->getCustomerIsGuest()) { + $this->doValidateForGuestQuoteAddress($address, $cart); + } + $this->doValidate($address, $cart->getCustomerIsGuest() ? null : (int) $cart->getCustomer()->getId()); + } + + /** + * Validate address id to be used for cart. + * + * @param CartInterface $cart + * @param AddressInterface $address + * @return void + * @throws NoSuchEntityException The specified customer ID or address ID is not valid. + */ + public function validateWithExistingAddress(CartInterface $cart, AddressInterface $address): void + { + // check if address belongs to quote. + if ($address->getId() !== null) { + $old = $cart->getAddressesCollection()->getItemById($address->getId()); + if ($old === null) { + throw new NoSuchEntityException( + __('Invalid quote address id %1', $address->getId()) + ); + } + } } } diff --git a/app/code/Magento/Quote/Model/ShippingMethodManagement.php b/app/code/Magento/Quote/Model/ShippingMethodManagement.php index 8d851c71b6602..3f90af4f30cd3 100644 --- a/app/code/Magento/Quote/Model/ShippingMethodManagement.php +++ b/app/code/Magento/Quote/Model/ShippingMethodManagement.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Quote\Model; use Magento\Customer\Api\AddressRepositoryInterface; @@ -25,6 +27,7 @@ use Magento\Quote\Model\Quote\Address\Rate; use Magento\Quote\Model\Quote\TotalsCollector; use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; +use Magento\Customer\Model\Data\Address as CustomerAddress; /** * Shipping method read service @@ -38,7 +41,7 @@ class ShippingMethodManagement implements ShipmentEstimationInterface { /** - * Quote repository. + * Quote repository model * * @var CartRepositoryInterface */ @@ -268,6 +271,8 @@ public function estimateByExtendedAddress($cartId, AddressInterface $address) /** * @inheritDoc + * @throws InputException + * @throws NoSuchEntityException */ public function estimateByAddressId($cartId, $addressId) { @@ -278,7 +283,7 @@ public function estimateByAddressId($cartId, $addressId) if ($quote->isVirtual() || 0 == $quote->getItemsCount()) { return []; } - $address = $this->addressRepository->getById($addressId); + $address = $this->getAddress($addressId, $quote); return $this->getShippingMethods($quote, $address); } @@ -384,4 +389,24 @@ private function getDataObjectProcessor() } return $this->dataProcessor; } + + /** + * Gets the address if exists for customer + * + * @param int $addressId + * @param Quote $quote + * @return CustomerAddress + * @throws InputException The shipping address is incorrect. + */ + private function getAddress(int $addressId, Quote $quote): CustomerAddress + { + $addresses = $quote->getCustomer()->getAddresses(); + foreach ($addresses as $address) { + if ($addressId === (int)$address->getId()) { + return $address; + } + } + + throw new InputException(__('The shipping address is missing. Set the address and try again.')); + } } diff --git a/app/code/Magento/Quote/Plugin/Webapi/Controller/Rest/ValidateQuoteData.php b/app/code/Magento/Quote/Plugin/Webapi/Controller/Rest/ValidateQuoteData.php new file mode 100644 index 0000000000000..4590322b6b382 --- /dev/null +++ b/app/code/Magento/Quote/Plugin/Webapi/Controller/Rest/ValidateQuoteData.php @@ -0,0 +1,55 @@ +validateInputData($inputData[self:: QUOTE_KEY]); + } + return [$inputData, $parameters]; + } + + /** + * Validates InputData + * + * @param array $inputData + * @return array + */ + private function validateInputData(array $inputData): array + { + $result = []; + + $data = array_filter($inputData, function ($k) use (&$result) { + $key = is_string($k) ? strtolower($k) : $k; + return !isset($result[$key]) && ($result[$key] = true); + }, ARRAY_FILTER_USE_KEY); + + return array_map(function ($value) { + return is_array($value) ? $this->validateInputData($value) : $value; + }, $data); + } +} diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php index fd0a4982541e3..36f2266fbdee0 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php @@ -1034,6 +1034,9 @@ public function testAddProductItemPreparation(): void $itemMock->expects($this->any()) ->method('representProduct') ->willReturn(true); + $itemMock->expects($this->any()) + ->method('getProduct') + ->willReturn($this->productMock); $iterator = new \ArrayIterator([$itemMock]); $collectionMock->expects($this->any()) @@ -1402,20 +1405,26 @@ public function testGetItemsCollection(): void public function testGetAllItems(): void { $itemOneMock = $this->getMockBuilder(\Magento\Quote\Model\ResourceModel\Quote\Item::class) - ->addMethods(['isDeleted']) + ->addMethods(['isDeleted', 'getProduct']) ->disableOriginalConstructor() ->getMock(); $itemOneMock->expects($this->once()) ->method('isDeleted') ->willReturn(false); + $itemOneMock->expects($this->once()) + ->method('getProduct') + ->willReturn($this->productMock); $itemTwoMock = $this->getMockBuilder(\Magento\Quote\Model\ResourceModel\Quote\Item::class) - ->addMethods(['isDeleted']) + ->addMethods(['isDeleted', 'getProduct']) ->disableOriginalConstructor() ->getMock(); $itemTwoMock->expects($this->once()) ->method('isDeleted') ->willReturn(true); + $itemTwoMock->expects($this->once()) + ->method('getProduct') + ->willReturn($this->productMock); $items = [$itemOneMock, $itemTwoMock]; $itemResult = [$itemOneMock]; diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php index 784bf04ddf7d3..c1c7de3369a24 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php @@ -24,12 +24,13 @@ use Magento\Quote\Model\QuoteRepository; use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; use Magento\Quote\Model\ShippingMethodManagement; -use Magento\Store\Model\Store; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Magento\Quote\Api\Data\CartExtensionInterface; use Magento\Sales\Model\Order\ShippingAssignmentBuilder; use Magento\Quote\Api\Data\ShippingInterface; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Model\Session; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -41,16 +42,6 @@ class ShippingMethodManagementTest extends TestCase */ protected $model; - /** - * @var MockObject - */ - protected $shippingMethodMock; - - /** - * @var MockObject - */ - protected $methodDataFactoryMock; - /** * @var ShippingMethodConverter|MockObject */ @@ -96,11 +87,6 @@ class ShippingMethodManagementTest extends TestCase */ private $totalsCollector; - /** - * @var Store|MockObject - */ - private $storeMock; - /** * @var QuoteAddressResource|MockObject */ @@ -121,13 +107,20 @@ class ShippingMethodManagementTest extends TestCase */ private $shippingAssignmentBuilder; + /** + * @var Session + */ + private $customerSession; + protected function setUp(): void { $this->objectManager = new ObjectManager($this); $this->quoteRepository = $this->getMockForAbstractClass(CartRepositoryInterface::class); $this->addressRepository = $this->getMockForAbstractClass(AddressRepositoryInterface::class); + $this->customerSession = $this->createMock(Session::class); - $this->methodDataFactoryMock = $this->getMockBuilder(ShippingMethodInterfaceFactory::class) + /** @var MockObject $methodDataFactoryMock */ + $methodDataFactoryMock = $this->getMockBuilder(ShippingMethodInterfaceFactory::class) ->disableOriginalConstructor() ->onlyMethods(['create']) ->getMock(); @@ -141,7 +134,6 @@ protected function setUp(): void $this->dataProcessor = $this->createMock($className); $this->quoteAddressResource = $this->createMock(QuoteAddressResource::class); - $this->storeMock = $this->createMock(Store::class); $this->quote = $this->getMockBuilder(Quote::class) ->disableOriginalConstructor() ->setMethods([ @@ -153,7 +145,8 @@ protected function setUp(): void 'collectTotals', 'save', '__wakeup', - 'getExtensionAttributes' + 'getExtensionAttributes', + 'getCustomer' ]) ->getMock(); @@ -190,25 +183,17 @@ protected function setUp(): void ShippingMethodManagement::class, [ 'quoteRepository' => $this->quoteRepository, - 'methodDataFactory' => $this->methodDataFactoryMock, + 'methodDataFactory' => $methodDataFactoryMock, 'converter' => $this->converter, 'totalsCollector' => $this->totalsCollector, 'addressRepository' => $this->addressRepository, 'quoteAddressResource' => $this->quoteAddressResource, + 'customerSession' => $this->customerSession, ] ); - $this->objectManager->setBackwardCompatibleProperty( - $this->model, - 'addressFactory', - $this->addressFactory - ); - - $this->objectManager->setBackwardCompatibleProperty( - $this->model, - 'dataProcessor', - $this->dataProcessor - ); + $this->objectManager->setBackwardCompatibleProperty($this->model, 'addressFactory', $this->addressFactory); + $this->objectManager->setBackwardCompatibleProperty($this->model, 'dataProcessor', $this->dataProcessor); $this->extensionAttributesMock = $this->getMockBuilder(CartExtensionInterface::class) ->setMethods(['getShippingAssignments']) @@ -266,11 +251,12 @@ public function testGetMethod() ->with('one_two') ->willReturn($shippingRateMock); - $this->shippingMethodMock = $this->getMockForAbstractClass(ShippingMethodInterface::class); + /** @var MockObject $shippingMethodMock */ + $shippingMethodMock = $this->getMockForAbstractClass(ShippingMethodInterface::class); $this->converter->expects($this->once()) ->method('modelToDataObject') ->with($shippingRateMock, $currencyCode) - ->willReturn($this->shippingMethodMock); + ->willReturn($shippingMethodMock); $this->model->get($cartId); } @@ -578,32 +564,32 @@ public function testEstimateByExtendedAddress() ->method('create') ->willReturn($address); - $this->quoteRepository->expects(static::once()) + $this->quoteRepository->expects(self::once()) ->method('getActive') ->with($cartId) ->willReturn($this->quote); - $this->quote->expects(static::once()) + $this->quote->expects(self::once()) ->method('isVirtual') ->willReturn(false); - $this->quote->expects(static::once()) + $this->quote->expects(self::once()) ->method('getItemsCount') ->willReturn(1); - $this->quote->expects(static::once()) + $this->quote->expects(self::once()) ->method('getShippingAddress') ->willReturn($this->shippingAddress); - $this->dataProcessor->expects(static::any()) + $this->dataProcessor->expects(self::any()) ->method('buildOutputDataArray') ->willReturn($addressData); - $this->shippingAddress->expects(static::once()) + $this->shippingAddress->expects(self::once()) ->method('setCollectShippingRates') ->with(true) ->willReturnSelf(); - $this->totalsCollector->expects(static::once()) + $this->totalsCollector->expects(self::once()) ->method('collectAddressTotals') ->with($this->quote, $this->shippingAddress) ->willReturnSelf(); @@ -615,30 +601,34 @@ public function testEstimateByExtendedAddress() $methodObject = $this->getMockForAbstractClass(ShippingMethodInterface::class); $expectedRates = [$methodObject]; - $this->shippingAddress->expects(static::once()) + $this->shippingAddress->expects(self::once()) ->method('getGroupedAllShippingRates') ->willReturn([[$rate]]); - $this->quote->expects(static::once()) + $this->quote->expects(self::once()) ->method('getQuoteCurrencyCode') ->willReturn($currencyCode); - $this->converter->expects(static::once()) + $this->converter->expects(self::once()) ->method('modelToDataObject') ->with($rate, $currencyCode) ->willReturn($methodObject); $carriersRates = $this->model->estimateByExtendedAddress($cartId, $address); - static::assertEquals($expectedRates, $carriersRates); + self::assertEquals($expectedRates, $carriersRates); } /** + * @dataProvider getAddressDataProvider + * * @covers \Magento\Quote\Model\ShippingMethodManagement::estimateByAddressId + * @param int $cartId + * @param int $addressId + * @param int $randomAddressId + * @param bool $throwsException */ - public function testEstimateByAddressId() + public function testEstimateByAddressId($cartId, $addressId, $randomAddressId, $throwsException) { - $cartId = 1; - $addressData = [ 'region' => 'California', 'region_id' => 23, @@ -646,73 +636,109 @@ public function testEstimateByAddressId() 'postcode' => 90200, ]; $currencyCode = 'UAH'; + $customerId = 1; - /** - * @var \Magento\Customer\Api\Data\AddressInterface|MockObject $address - */ - $address = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) + $rate = $this->getMockBuilder(Rate::class) ->disableOriginalConstructor() + ->setMethods([]) ->getMock(); + $methodObject = $this->getMockForAbstractClass(ShippingMethodInterface::class); - $this->addressRepository->expects($this->any()) - ->method('getById') - ->willReturn($address); - - $this->addressFactory->expects($this->any()) - ->method('create') - ->willReturn($address); - - $this->quoteRepository->expects(static::once()) + $this->quoteRepository->expects(self::once()) ->method('getActive') ->with($cartId) ->willReturn($this->quote); - $this->quote->expects(static::once()) + $this->quote->expects(self::once()) ->method('isVirtual') ->willReturn(false); - $this->quote->expects(static::once()) + + $this->quote->expects(self::once()) ->method('getItemsCount') ->willReturn(1); - $this->quote->expects(static::once()) - ->method('getShippingAddress') - ->willReturn($this->shippingAddress); - - $this->dataProcessor->expects(static::any()) - ->method('buildOutputDataArray') - ->willReturn($addressData); - - $this->shippingAddress->expects(static::once()) - ->method('setCollectShippingRates') - ->with(true) - ->willReturnSelf(); + $this->setCustomerSession($addressId, $customerId); + if ($throwsException) { + $this->expectException('Magento\Framework\Exception\InputException'); + $this->expectExceptionMessage('The shipping address is missing. Set the address and try again.'); + $this->model->estimateByAddressId($cartId, $randomAddressId); + } else { + $this->quote->expects(self::once()) + ->method('getShippingAddress') + ->willReturn($this->shippingAddress); + + $this->dataProcessor->expects(self::any()) + ->method('buildOutputDataArray') + ->willReturn($addressData); + + $this->shippingAddress->expects(self::once()) + ->method('setCollectShippingRates') + ->with(true) + ->willReturnSelf(); + + $this->totalsCollector->expects(self::once()) + ->method('collectAddressTotals') + ->with($this->quote, $this->shippingAddress) + ->willReturnSelf(); + + $expectedRates = [$methodObject]; + $this->shippingAddress->expects(self::once()) + ->method('getGroupedAllShippingRates') + ->willReturn([[$rate]]); + + $this->quote->expects(self::once()) + ->method('getQuoteCurrencyCode') + ->willReturn($currencyCode); + + $this->converter->expects(self::once()) + ->method('modelToDataObject') + ->with($rate, $currencyCode) + ->willReturn($methodObject); + + $carriersRates = $this->model->estimateByAddressId($cartId, $addressId); + self::assertEquals($expectedRates, $carriersRates); + } + } - $this->totalsCollector->expects(static::once()) - ->method('collectAddressTotals') - ->with($this->quote, $this->shippingAddress) - ->willReturnSelf(); + /** + * @return array + */ + public function getAddressDataProvider() + { + return [ + [1, 1, 5, true], + [1, 1, 1, false], + ]; + } - $rate = $this->getMockBuilder(Rate::class) + private function setCustomerSession($addressId, $customerId) + { + /** + * @var \Magento\Customer\Model\Data\Address|MockObject $address + */ + $address = $this->getMockBuilder(\Magento\Customer\Model\Data\Address::class) + ->setMethods(['getId']) ->disableOriginalConstructor() - ->setMethods([]) ->getMock(); - $methodObject = $this->getMockForAbstractClass(ShippingMethodInterface::class); - $expectedRates = [$methodObject]; + $address->expects($this->atLeastOnce()) + ->method('getId') + ->willReturn($addressId); - $this->shippingAddress->expects(static::once()) - ->method('getGroupedAllShippingRates') - ->willReturn([[$rate]]); + $this->addressRepository->expects($this->any()) + ->method('getById') + ->willReturn($address); - $this->quote->expects(static::once()) - ->method('getQuoteCurrencyCode') - ->willReturn($currencyCode); + $this->addressFactory->expects($this->any()) + ->method('create') + ->willReturn($address); - $this->converter->expects(static::once()) - ->method('modelToDataObject') - ->with($rate, $currencyCode) - ->willReturn($methodObject); + $customerAddresses = [$address]; + $customerMock = $this->getMockForAbstractClass(CustomerInterface::class); + $customerMock->method('getAddresses')->willReturn($customerAddresses); - $carriersRates = $this->model->estimateByAddressId($cartId, $address); - static::assertEquals($expectedRates, $carriersRates); + $this->quote->method('getCustomer')->willReturn($customerMock); + $this->customerSession->method('getCustomerId')->willReturn($customerId); + $this->customerSession->expects(self::any())->method('isLoggedIn')->willReturn(true); + $this->customerSession->expects(self::any())->method('getCustomerData')->willReturn($customerMock); } } diff --git a/app/code/Magento/Quote/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateQuoteDataTest.php b/app/code/Magento/Quote/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateQuoteDataTest.php new file mode 100644 index 0000000000000..8965cc2d96c45 --- /dev/null +++ b/app/code/Magento/Quote/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateQuoteDataTest.php @@ -0,0 +1,113 @@ +validateQuoteDataObject = ObjectManager::getInstance()->get(ValidateQuoteData::class); + $this->reflectionObject = new ReflectionClass(get_class($this->validateQuoteDataObject)); + } + /** + * Test if the quote array is valid + * + * @param array $array + * @param array $result + * @dataProvider dataProviderInputData + * @throws Exception + */ + public function testValidateInputData(array $array, array $result) + { + $this->assertEquals( + $result, + $this->invokeValidateInputData('validateInputData', [$array]) + ); + } + + /** + * @param string $methodName + * @param array $arguments + * @return mixed + * @throws Exception + */ + private function invokeValidateInputData(string $methodName, array $arguments = []) + { + $validateInputDataMethod = $this->reflectionObject->getMethod($methodName); + $validateInputDataMethod->setAccessible(true); + return $validateInputDataMethod->invokeArgs($this->validateQuoteDataObject, $arguments); + } + + /** + * @return array + */ + public function dataProviderInputData(): array + { + return [ + [ + ['person' => + [ + 'id' => -1, + 'Id' => 1, + 'name' => + [ + 'firstName' => 'John', + 'LastName' => 'S' + ], + 'isHavingVehicle' => 1, + 'address' => + [ + 'street' => '4th Street', + 'Street' => '2nd Street', + 'city' => 'Atlanta' + ], + ] + ], + ['person' => + [ + 'id' => -1, + 'name' => + [ + 'firstName' => 'John', + 'LastName' => 'S' + ], + 'isHavingVehicle' => 1, + 'address' => + [ + 'street' => '4th Street', + 'city' => 'Atlanta' + ], + ] + ], + ] + ]; + } +} diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json index 922f3d36fa918..6899fd81a3cb8 100644 --- a/app/code/Magento/Quote/composer.json +++ b/app/code/Magento/Quote/composer.json @@ -1,35 +1,36 @@ { "name": "magento/module-quote", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4-p4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-payment": "*", - "magento/module-sales": "*", - "magento/module-sales-sequence": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-tax": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-payment": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-sequence": "100.4.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*" }, "suggest": { - "magento/module-webapi": "*" + "magento/module-webapi": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -39,3 +40,4 @@ } } } + diff --git a/app/code/Magento/Quote/etc/webapi_rest/di.xml b/app/code/Magento/Quote/etc/webapi_rest/di.xml index 6ed9909f04eb9..d5893f7d16d8b 100644 --- a/app/code/Magento/Quote/etc/webapi_rest/di.xml +++ b/app/code/Magento/Quote/etc/webapi_rest/di.xml @@ -19,4 +19,7 @@ + + + diff --git a/app/code/Magento/Quote/i18n/en_US.csv b/app/code/Magento/Quote/i18n/en_US.csv index c899c432c70d4..c8da332f729c8 100644 --- a/app/code/Magento/Quote/i18n/en_US.csv +++ b/app/code/Magento/Quote/i18n/en_US.csv @@ -68,3 +68,5 @@ Carts,Carts "Invalid state change requested","Invalid state change requested" "Validated Country Code","Validated Country Code" "Validated Vat Number","Validated Vat Number" +"Invalid Quote Item id %1","Invalid Quote Item id %1" +"Invalid quote address id %1","Invalid quote address id %1" diff --git a/app/code/Magento/QuoteAnalytics/composer.json b/app/code/Magento/QuoteAnalytics/composer.json index 038553b4d487e..e8803403c6bcb 100644 --- a/app/code/Magento/QuoteAnalytics/composer.json +++ b/app/code/Magento/QuoteAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-quote-analytics", "description": "N/A", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-quote": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/QuoteBundleOptions/composer.json b/app/code/Magento/QuoteBundleOptions/composer.json index 79ad425b2d359..8709dc6815c56 100644 --- a/app/code/Magento/QuoteBundleOptions/composer.json +++ b/app/code/Magento/QuoteBundleOptions/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-quote-bundle-options", "description": "Magento module provides data provider for creating buy request for bundle products", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-quote": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/QuoteConfigurableOptions/composer.json b/app/code/Magento/QuoteConfigurableOptions/composer.json index 2da064db42965..140142767f03b 100644 --- a/app/code/Magento/QuoteConfigurableOptions/composer.json +++ b/app/code/Magento/QuoteConfigurableOptions/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-quote-configurable-options", "description": "Magento module provides data provider for creating buy request for configurable products", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-quote": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/QuoteDownloadableLinks/composer.json b/app/code/Magento/QuoteDownloadableLinks/composer.json index 2b4dcc3331b8e..d1f9ce29b81f0 100644 --- a/app/code/Magento/QuoteDownloadableLinks/composer.json +++ b/app/code/Magento/QuoteDownloadableLinks/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-quote-downloadable-links", "description": "Magento module provides data provider for creating buy request for links of downloadable products", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-quote": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php index 09ef1ad581876..307087391b89d 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php @@ -86,6 +86,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $itemId = $processedArgs['input']['cart_item_id']; $storeId = (int)$context->getExtensionAttributes()->getStore()->getId(); + /** Check if the current user is allowed to perform actions with the cart */ + $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId); try { $this->cartItemRepository->deleteById($cartId, $itemId); @@ -95,7 +97,6 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__($e->getMessage()), $e); } - $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId); return [ 'cart' => [ 'model' => $cart, diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 4f885fa33a7b0..b42b078a9b3ea 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -2,30 +2,31 @@ "name": "magento/module-quote-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4-p4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-quote": "*", - "magento/module-checkout": "*", - "magento/module-catalog": "*", - "magento/module-store": "*", - "magento/module-customer": "*", - "magento/module-customer-graph-ql": "*", - "magento/module-sales": "*", - "magento/module-directory": "*", - "magento/module-graph-ql": "*", - "magento/module-gift-message": "*", - "magento/module-catalog-inventory": "*" + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*", + "magento/module-checkout": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-store": "101.1.*", + "magento/module-customer": "103.0.*", + "magento/module-customer-graph-ql": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-gift-message": "100.4.*", + "magento/module-catalog-inventory": "100.4.*" }, "suggest": { - "magento/module-graph-ql-cache": "*", - "magento/module-catalog-inventory-graph-ql": "*", - "magento/module-payment-graph-ql": "*" + "magento/module-graph-ql-cache": "100.4.*", + "magento/module-catalog-inventory-graph-ql": "100.4.*", + "magento/module-payment-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -35,3 +36,4 @@ } } } + diff --git a/app/code/Magento/RelatedProductGraphQl/composer.json b/app/code/Magento/RelatedProductGraphQl/composer.json index 25bb6dc47722d..d06f681afc5ca 100644 --- a/app/code/Magento/RelatedProductGraphQl/composer.json +++ b/app/code/Magento/RelatedProductGraphQl/composer.json @@ -2,19 +2,20 @@ "name": "magento/module-related-product-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*", - "magento/framework": "*" + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/ReleaseNotification/composer.json b/app/code/Magento/ReleaseNotification/composer.json index 039ea30e339be..a2888508dadfa 100644 --- a/app/code/Magento/ReleaseNotification/composer.json +++ b/app/code/Magento/ReleaseNotification/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-release-notification", "description": "N/A", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/module-user": "*", - "magento/module-backend": "*", - "magento/module-ui": "*", - "magento/framework": "*" - }, - "suggest": { - "magento/module-config": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/module-user": "101.2.*", + "magento/module-backend": "102.0.*", + "magento/module-ui": "101.2.*", + "magento/framework": "103.0.*" + }, + "suggest": { + "magento/module-config": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/RemoteStorage/composer.json b/app/code/Magento/RemoteStorage/composer.json index b2ebf9ae7d6c7..4cba57a3ae1b7 100644 --- a/app/code/Magento/RemoteStorage/composer.json +++ b/app/code/Magento/RemoteStorage/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-remote-storage", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-backend": "*", - "magento/module-sitemap": "*", - "magento/module-cms": "*", - "magento/module-downloadable": "*", - "magento/module-catalog": "*", - "magento/module-media-storage": "*", - "magento/module-media-gallery-metadata": "*", - "magento/module-media-gallery-synchronization": "*", - "magento/module-import-export": "*", - "magento/module-catalog-import-export": "*", - "magento/module-downloadable-import-export": "*", + "magento/module-backend": "102.0.*", + "magento/module-sitemap": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-downloadable": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-media-storage": "100.4.*", + "magento/module-media-gallery-metadata": "100.4.*", + "magento/module-media-gallery-synchronization": "100.4.*", + "magento/module-import-export": "101.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-downloadable-import-export": "100.4.*", "predis/predis": "*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json index e758e3a739f91..af4622de22eff 100644 --- a/app/code/Magento/Reports/composer.json +++ b/app/code/Magento/Reports/composer.json @@ -1,35 +1,36 @@ { "name": "magento/module-reports", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-downloadable": "*", - "magento/module-eav": "*", - "magento/module-quote": "*", - "magento/module-review": "*", - "magento/module-sales": "*", - "magento/module-sales-rule": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*", - "magento/module-directory": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-downloadable": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-quote": "101.2.*", + "magento/module-review": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-widget": "101.2.*", + "magento/module-wishlist": "101.2.*", + "magento/module-directory": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -39,3 +40,4 @@ } } } + diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json index 746b09474ec03..ebf2d0c8892c1 100644 --- a/app/code/Magento/RequireJs/composer.json +++ b/app/code/Magento/RequireJs/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-require-js", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json index b79ec24b633f3..dc6856233ada7 100644 --- a/app/code/Magento/Review/composer.json +++ b/app/code/Magento/Review/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-review", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-newsletter": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-newsletter": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-cookie": "*", - "magento/module-review-sample-data": "*" + "magento/module-cookie": "100.4.*", + "magento/module-review-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/ReviewAnalytics/composer.json b/app/code/Magento/ReviewAnalytics/composer.json index 6694a8e8400cb..f4cd79b269fba 100644 --- a/app/code/Magento/ReviewAnalytics/composer.json +++ b/app/code/Magento/ReviewAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-review-analytics", "description": "N/A", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-review": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-review": "100.4.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/ReviewGraphQl/composer.json b/app/code/Magento/ReviewGraphQl/composer.json index ac1c11df1b8dc..1989614e17064 100644 --- a/app/code/Magento/ReviewGraphQl/composer.json +++ b/app/code/Magento/ReviewGraphQl/composer.json @@ -2,21 +2,22 @@ "name": "magento/module-review-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/module-catalog": "*", - "magento/module-review": "*", - "magento/module-store": "*", - "magento/framework": "*" + "magento/module-catalog": "104.0.*", + "magento/module-review": "100.4.*", + "magento/module-store": "101.1.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-graph-ql-cache": "*" + "magento/module-graph-ql": "100.4.*", + "magento/module-graph-ql-cache": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Robots/composer.json b/app/code/Magento/Robots/composer.json index d11d4568bf7d5..4d179f60e6ef3 100644 --- a/app/code/Magento/Robots/composer.json +++ b/app/code/Magento/Robots/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-robots", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-theme": "*" + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json index 0b89505e7e618..401e256f75c7c 100644 --- a/app/code/Magento/Rss/composer.json +++ b/app/code/Magento/Rss/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-rss", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json index a1b60b7e57eeb..5723a173c161a 100644 --- a/app/code/Magento/Rule/composer.json +++ b/app/code/Magento/Rule/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-rule", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-eav": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-eav": "102.1.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php index 492d2d71df8d9..3dcd30edd4f04 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php @@ -20,12 +20,12 @@ class AddComment extends \Magento\Sales\Controller\Adminhtml\Order implements Ht * * @see _isAllowed() */ - const ADMIN_RESOURCE = 'Magento_Sales::comment'; + public const ADMIN_RESOURCE = 'Magento_Sales::comment'; /** * ACL resource needed to send comment email notification */ - const ADMIN_SALES_EMAIL_RESOURCE = 'Magento_Sales::emails'; + public const ADMIN_SALES_EMAIL_RESOURCE = 'Magento_Sales::emails'; /** * Add order comment action @@ -52,13 +52,12 @@ public function execute() $notify = false; } - $history = $order->addStatusHistoryComment($data['comment'], $data['status']); + $comment = trim(strip_tags($data['comment'])); + $history = $order->addStatusHistoryComment($comment, $data['status']); $history->setIsVisibleOnFront($visible); $history->setIsCustomerNotified($notify); $history->save(); - $comment = trim(strip_tags($data['comment'])); - $order->save(); /** @var OrderCommentSender $orderCommentSender */ $orderCommentSender = $this->_objectManager diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php index 1e13e282cae3a..643ed5445231f 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php @@ -3,16 +3,26 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Controller\Adminhtml\Order\Create; -use Magento\Framework\App\Action\HttpGetActionInterface; -use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; use Magento\Backend\Model\View\Result\ForwardFactory; -use Magento\Framework\View\Result\PageFactory; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Controller\Result\RawFactory; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\RegexValidator; +use Magento\Framework\View\Result\PageFactory; use Magento\Sales\Controller\Adminhtml\Order\Create as CreateAction; +use Magento\Store\Model\StoreManagerInterface; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class LoadBlock extends CreateAction implements HttpPostActionInterface, HttpGetActionInterface { /** @@ -21,12 +31,24 @@ class LoadBlock extends CreateAction implements HttpPostActionInterface, HttpGet protected $resultRawFactory; /** - * @param Action\Context $context - * @param \Magento\Catalog\Helper\Product $productHelper - * @param \Magento\Framework\Escaper $escaper + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var RegexValidator + */ + private RegexValidator $regexValidator; + + /** + * @param Context $context + * @param Product $productHelper + * @param Escaper $escaper * @param PageFactory $resultPageFactory * @param ForwardFactory $resultForwardFactory * @param RawFactory $resultRawFactory + * @param StoreManagerInterface|null $storeManager + * @param RegexValidator|null $regexValidator */ public function __construct( Action\Context $context, @@ -34,7 +56,9 @@ public function __construct( \Magento\Framework\Escaper $escaper, PageFactory $resultPageFactory, ForwardFactory $resultForwardFactory, - RawFactory $resultRawFactory + RawFactory $resultRawFactory, + StoreManagerInterface $storeManager = null, + RegexValidator $regexValidator = null ) { $this->resultRawFactory = $resultRawFactory; parent::__construct( @@ -44,16 +68,27 @@ public function __construct( $resultPageFactory, $resultForwardFactory ); + $this->storeManager = $storeManager ?: ObjectManager::getInstance() + ->get(StoreManagerInterface::class); + $this->regexValidator = $regexValidator + ?: ObjectManager::getInstance()->get(RegexValidator::class); } /** * Loading page block * * @return \Magento\Backend\Model\View\Result\Redirect|\Magento\Framework\Controller\Result\Raw + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + * @throws LocalizedException */ public function execute() { $request = $this->getRequest(); + if ($request->getParam('store_id') !== 'false') { + $this->storeManager->setCurrentStore($request->getParam('store_id')); + } try { $this->_initSession()->_processData(); } catch (\Magento\Framework\Exception\LocalizedException $e) { @@ -67,6 +102,12 @@ public function execute() $asJson = $request->getParam('json'); $block = $request->getParam('block'); + if ($block && !$this->regexValidator->validateParamRegex($block)) { + throw new LocalizedException( + __('The url has invalid characters. Please correct and try again.') + ); + } + /** @var \Magento\Framework\View\Result\Page $resultPage */ $resultPage = $this->resultPageFactory->create(); if ($asJson) { diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageNewCustomerActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageNewCustomerActionGroup.xml new file mode 100644 index 0000000000000..438407e2e3468 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageNewCustomerActionGroup.xml @@ -0,0 +1,23 @@ + + + + + + + + Goes to the Admin Orders grid page. Clicks on 'Create New Order'. Clicks on 'Create New Customer'. + + + + + + + + + diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrderWithDifferentAddressesTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrderWithDifferentAddressesTest.xml index bf45d3305dcfd..59c15c877bd72 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrderWithDifferentAddressesTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrderWithDifferentAddressesTest.xml @@ -15,15 +15,16 @@ + - + diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json index 710d5c07d0490..5a8c18dbed1f3 100644 --- a/app/code/Magento/Sales/composer.json +++ b/app/code/Magento/Sales/composer.json @@ -1,45 +1,46 @@ { "name": "magento/module-sales", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "103.0.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-bundle": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-gift-message": "*", - "magento/module-media-storage": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-reports": "*", - "magento/module-sales-rule": "*", - "magento/module-sales-sequence": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-bundle": "101.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-gift-message": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-reports": "100.4.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-sales-sequence": "100.4.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-widget": "101.2.*", + "magento/module-wishlist": "101.2.*" }, "suggest": { - "magento/module-sales-sample-data": "*" + "magento/module-sales-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -49,3 +50,4 @@ } } } + diff --git a/app/code/Magento/SalesAnalytics/composer.json b/app/code/Magento/SalesAnalytics/composer.json index 6be5b39e3df33..4dde5a8139405 100644 --- a/app/code/Magento/SalesAnalytics/composer.json +++ b/app/code/Magento/SalesAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-sales-analytics", "description": "N/A", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-sales": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/SalesGraphQl/composer.json b/app/code/Magento/SalesGraphQl/composer.json index dfa29321b033e..b1c04dc9d5500 100644 --- a/app/code/Magento/SalesGraphQl/composer.json +++ b/app/code/Magento/SalesGraphQl/composer.json @@ -2,21 +2,22 @@ "name": "magento/module-sales-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-tax": "*", - "magento/module-quote": "*", - "magento/module-graph-ql": "*", - "magento/module-shipping": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-tax": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-shipping": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/SalesInventory/composer.json b/app/code/Magento/SalesInventory/composer.json index e5c5e90f8dfb2..1c51c54d7acdb 100644 --- a/app/code/Magento/SalesInventory/composer.json +++ b/app/code/Magento/SalesInventory/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-sales-inventory", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php old mode 100644 new mode 100755 index 0bca04a955817..5f5e24ef425e0 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php @@ -3,20 +3,43 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote; +use Magento\Backend\App\Action\Context; +use Magento\Backend\Model\View\Result\Forward; +use Magento\Backend\Model\View\Result\ForwardFactory; use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\Response\Http\FileFactory; +use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Json\Helper\Data; +use Magento\Framework\Registry; +use Magento\Framework\Stdlib\DateTime\Filter\Date; +use Magento\SalesRule\Controller\Adminhtml\Promo\Quote; use Magento\SalesRule\Model\CouponGenerator; use Magento\Framework\MessageQueue\PublisherInterface; use Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory; +use Magento\SalesRule\Model\RegistryConstants; +use Magento\SalesRule\Model\Rule; +use Magento\Store\Model\ScopeInterface; +use Psr\Log\LoggerInterface; /** * Generate promo quote * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implements HttpPostActionInterface +class Generate extends Quote implements HttpPostActionInterface { + /** + * Coupon quantity limit config path + */ + private const XML_CONFIG_COUPON_QUANTITY_LIMIT = 'promo/auto_generated_coupon_codes/quantity_limit'; + /** * @var CouponGenerator */ @@ -32,55 +55,77 @@ class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote imple */ private $generationSpecFactory; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * @var ForwardFactory + */ + private $resultForwardFactory; + /** * Generate constructor. - * @param \Magento\Backend\App\Action\Context $context - * @param \Magento\Framework\Registry $coreRegistry - * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory - * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter + * @param Context $context + * @param Registry $coreRegistry + * @param FileFactory $fileFactory + * @param Date $dateFilter + * @param ForwardFactory $resultForwardFactory * @param CouponGenerator|null $couponGenerator * @param PublisherInterface|null $publisher * @param CouponGenerationSpecInterfaceFactory|null $generationSpecFactory + * @param ScopeConfigInterface|null $scopeConfig */ public function __construct( - \Magento\Backend\App\Action\Context $context, - \Magento\Framework\Registry $coreRegistry, - \Magento\Framework\App\Response\Http\FileFactory $fileFactory, - \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter, + Context $context, + Registry $coreRegistry, + FileFactory $fileFactory, + Date $dateFilter, + ForwardFactory $resultForwardFactory, CouponGenerator $couponGenerator = null, PublisherInterface $publisher = null, - CouponGenerationSpecInterfaceFactory $generationSpecFactory = null + CouponGenerationSpecInterfaceFactory $generationSpecFactory = null, + ScopeConfigInterface $scopeConfig = null ) { parent::__construct($context, $coreRegistry, $fileFactory, $dateFilter); + $this->resultForwardFactory = $resultForwardFactory; $this->couponGenerator = $couponGenerator ?: $this->_objectManager->get(CouponGenerator::class); - $this->messagePublisher = $publisher ?: \Magento\Framework\App\ObjectManager::getInstance() + $this->messagePublisher = $publisher ?: ObjectManager::getInstance() ->get(PublisherInterface::class); $this->generationSpecFactory = $generationSpecFactory ?: - \Magento\Framework\App\ObjectManager::getInstance()->get( + ObjectManager::getInstance()->get( CouponGenerationSpecInterfaceFactory::class ); + $this->scopeConfig = $scopeConfig ?: + ObjectManager::getInstance()->get( + ScopeConfigInterface::class + ); } /** * Generate Coupons action * * @return void + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function execute() { if (!$this->getRequest()->isAjax()) { - $this->_forward('noroute'); + $resultForward = $this->resultForwardFactory->create(); + $resultForward->forward('noroute'); + return; } $result = []; $this->_initRule(); - $rule = $this->_coreRegistry->registry(\Magento\SalesRule\Model\RegistryConstants::CURRENT_SALES_RULE); + $rule = $this->_coreRegistry->registry(RegistryConstants::CURRENT_SALES_RULE); if (!$rule->getId()) { $result['error'] = __('Rule is not defined'); - } elseif ((int) $rule->getCouponType() !== \Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO + } elseif ((int) $rule->getCouponType() !== Rule::COUPON_TYPE_AUTO && !$rule->getUseAutoGeneration()) { $result['error'] = __('The rule coupon settings changed. Please save the rule before using auto-generation.'); @@ -92,29 +137,43 @@ public function execute() $data = $inputFilter->getUnescaped(); } - $data['quantity'] = isset($data['qty']) ? $data['qty'] : null; + $data['quantity'] = $data['qty'] ?? 0; - $couponSpec = $this->generationSpecFactory->create(['data' => $data]); - - $this->messagePublisher->publish('sales_rule.codegenerator', $couponSpec); - $this->messageManager->addSuccessMessage( - __('Message is added to queue, wait to get your coupons soon') + $couponQuantityLimit = (int)$this->scopeConfig->getValue( + self::XML_CONFIG_COUPON_QUANTITY_LIMIT, + ScopeInterface::SCOPE_STORE ); + // @codingStandardsIgnoreStart + if ($data['quantity'] > 0 && ($data['quantity'] <= $couponQuantityLimit || $couponQuantityLimit === 0)) { + $couponSpec = $this->generationSpecFactory->create(['data' => $data]); + + $this->messagePublisher->publish('sales_rule.codegenerator', $couponSpec); + $this->messageManager->addSuccessMessage( + __('Message is added to queue, wait to get your coupons soon.') + ); + } else { + $this->messageManager->addErrorMessage( + __( + 'Coupon quantity should be less than or equal to the coupon quantity in the store configuration.' + ) + ); + } + // @codingStandardsIgnoreEnd $this->_view->getLayout()->initMessages(); $result['messages'] = $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml(); - } catch (\Magento\Framework\Exception\InputException $inputException) { + } catch (InputException $inputException) { $result['error'] = __('Invalid data provided'); - } catch (\Magento\Framework\Exception\LocalizedException $e) { + } catch (LocalizedException $e) { $result['error'] = $e->getMessage(); } catch (\Exception $e) { $result['error'] = __( 'Something went wrong while generating coupons. Please review the log and try again.' ); - $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e); + $this->_objectManager->get(LoggerInterface::class)->critical($e); } } $this->getResponse()->representJson( - $this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)->jsonEncode($result) + $this->_objectManager->get(Data::class)->jsonEncode($result) ); } } diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/StorefrontApplyDiscountCodeActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/StorefrontApplyDiscountCodeActionGroup.xml index 5607512c862b3..9d6630463e444 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/StorefrontApplyDiscountCodeActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/StorefrontApplyDiscountCodeActionGroup.xml @@ -15,7 +15,7 @@ - + diff --git a/app/code/Magento/SalesRule/Test/Unit/Controller/Adminhtml/Promo/Quote/GenerateTest.php b/app/code/Magento/SalesRule/Test/Unit/Controller/Adminhtml/Promo/Quote/GenerateTest.php old mode 100644 new mode 100755 index fd0b864ab9201..9e48ea65a9e62 --- a/app/code/Magento/SalesRule/Test/Unit/Controller/Adminhtml/Promo/Quote/GenerateTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Controller/Adminhtml/Promo/Quote/GenerateTest.php @@ -8,12 +8,15 @@ namespace Magento\SalesRule\Test\Unit\Controller\Adminhtml\Promo\Quote; use Magento\Backend\App\Action\Context; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; -use Magento\Framework\App\Request\Http; +use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\App\Response\Http as HttpResponse; use Magento\Framework\App\Response\Http\FileFactory; use Magento\Framework\App\ViewInterface; use Magento\Framework\Json\Helper\Data; use Magento\Framework\Message\ManagerInterface; +use Magento\Framework\MessageQueue\PublisherInterface; use Magento\Framework\Registry; use Magento\Framework\Stdlib\DateTime\Filter\Date; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; @@ -28,9 +31,37 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class GenerateTest extends TestCase { + /** @const XML_COUPON_QUANTITY_LIMIT_PATH_TEST */ + private const XML_COUPON_QUANTITY_LIMIT_PATH_TEST = 'promo/auto_generated_coupon_codes/quantity_limit'; + + /** @const XML_COUPON_QUANTITY_LIMIT_VALUE_TEST */ + private const XML_COUPON_QUANTITY_LIMIT_VALUE_TEST = 250000; + + /** @const XML_COUPON_QUANTITY_LIMIT_DISABLE_VALUE_TEST */ + private const XML_COUPON_QUANTITY_LIMIT_DISABLE_VALUE_TEST = 0; + + /** + * @var array + */ + private array $requestMockData = [ + 'qty' => 2, + 'length' => 10, + 'rule_id' => 1 + ]; + + /** + * @var array + */ + private array $requestMockDataWithInvalidCouponQuantity = [ + 'qty' => 250001, + 'length' => 10, + 'rule_id' => 1 + ]; + /** @var Generate */ protected $model; @@ -67,9 +98,17 @@ class GenerateTest extends TestCase /** @var CouponGenerator|MockObject */ private $couponGenerator; + /** @var PublisherInterface|MockObject */ + private $publisherMock; + /** @var CouponGenerationSpecInterfaceFactory|MockObject */ private $couponGenerationSpec; + /** + * @var ScopeConfigInterface|MockObject + */ + private $scopeConfigMock; + /** * Test setup */ @@ -79,11 +118,11 @@ protected function setUp(): void ->disableOriginalConstructor() ->getMock(); $this->requestMock = $this - ->getMockBuilder(Http::class) + ->getMockBuilder(HttpRequest::class) ->disableOriginalConstructor() ->getMock(); $this->responseMock = $this - ->getMockBuilder(\Magento\Framework\App\Response\Http::class) + ->getMockBuilder(HttpResponse::class) ->disableOriginalConstructor() ->getMock(); $this->messageManager = $this->getMockForAbstractClass(ManagerInterface::class); @@ -118,9 +157,13 @@ protected function setUp(): void $this->couponGenerator = $this->getMockBuilder(CouponGenerator::class) ->disableOriginalConstructor() ->getMock(); + $this->publisherMock = $this->getMockBuilder(PublisherInterface::class) + ->disableOriginalConstructor() + ->getMock(); $this->couponGenerationSpec = $this->getMockBuilder(CouponGenerationSpecInterfaceFactory::class) ->disableOriginalConstructor() ->getMock(); + $this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)->getMockForAbstractClass(); $this->objectManagerHelper = new ObjectManagerHelper($this); $this->model = $this->objectManagerHelper->getObject( @@ -131,7 +174,9 @@ protected function setUp(): void 'fileFactory' => $this->fileFactoryMock, 'dateFilter' => $this->dateMock, 'couponGenerator' => $this->couponGenerator, - 'generationSpecFactory' => $this->couponGenerationSpec + 'publisher' => $this->publisherMock, + 'generationSpecFactory' => $this->couponGenerationSpec, + 'scopeConfig' => $this->scopeConfigMock ] ); } @@ -148,11 +193,6 @@ public function testExecuteWithCouponTypeAuto() ->method('get') ->with(Data::class) ->willReturn($helperData); - $requestData = [ - 'qty' => 2, - 'length' => 10, - 'rule_id' => 1 - ]; $this->requestMock->expects($this->once()) ->method('isAjax') ->willReturn(true); @@ -169,16 +209,16 @@ public function testExecuteWithCouponTypeAuto() ->willReturn(1); $ruleMock->expects($this->once()) ->method('getCouponType') - ->willReturn(\Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO); + ->willReturn(Rule::COUPON_TYPE_AUTO); $this->requestMock->expects($this->once()) ->method('getParams') - ->willReturn($requestData); - $requestData['quantity'] = isset($requestData['qty']) ? $requestData['qty'] : null; - $this->couponGenerationSpec->expects($this->once()) + ->willReturn($this->requestMockData); + $this->requestMockData['quantity'] = $this->requestMockData['qty'] ?? 0; + $this->couponGenerationSpec->expects($this->any()) ->method('create') - ->with(['data' => $requestData]) + ->with(['data' => $this->requestMockData]) ->willReturn(['some_data', 'some_data_2']); - $this->messageManager->expects($this->once()) + $this->messageManager->expects($this->any()) ->method('addSuccessMessage'); $this->responseMock->expects($this->once()) ->method('representJson') @@ -220,11 +260,6 @@ public function testExecuteWithAutoGenerationEnabled() ->method('get') ->with(Data::class) ->willReturn($helperData); - $requestData = [ - 'qty' => 2, - 'length' => 10, - 'rule_id' => 1 - ]; $this->requestMock->expects($this->once()) ->method('isAjax') ->willReturn(true); @@ -244,13 +279,13 @@ public function testExecuteWithAutoGenerationEnabled() ->willReturn(1); $this->requestMock->expects($this->once()) ->method('getParams') - ->willReturn($requestData); - $requestData['quantity'] = isset($requestData['qty']) ? $requestData['qty'] : null; - $this->couponGenerationSpec->expects($this->once()) + ->willReturn($this->requestMockData); + $this->requestMockData['quantity'] = $this->requestMockData['qty'] ?? 0; + $this->couponGenerationSpec->expects($this->any()) ->method('create') - ->with(['data' => $requestData]) + ->with(['data' => $this->requestMockData]) ->willReturn(['some_data', 'some_data_2']); - $this->messageManager->expects($this->once()) + $this->messageManager->expects($this->any()) ->method('addSuccessMessage'); $this->responseMock->expects($this->once()) ->method('representJson') @@ -308,7 +343,7 @@ public function testExecuteWithCouponTypeNotAutoAndAutoGenerationNotEnabled() ->willReturn(1); $ruleMock->expects($this->once()) ->method('getCouponType') - ->willReturn(\Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON); + ->willReturn(Rule::COUPON_TYPE_NO_COUPON); $ruleMock->expects($this->once()) ->method('getUseAutoGeneration') ->willReturn(0); @@ -323,4 +358,145 @@ public function testExecuteWithCouponTypeNotAutoAndAutoGenerationNotEnabled() ]); $this->model->execute(); } + + /** + * @covers \Magento\SalesRule\Controller\Adminhtml\Promo\Quote::execute + */ + public function testExecuteWithInvalidCouponQuantity() + { + $helperData = $this->getMockBuilder(Data::class) + ->disableOriginalConstructor() + ->getMock(); + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->with(Data::class) + ->willReturn($helperData); + $this->requestMock->expects($this->once()) + ->method('isAjax') + ->willReturn(true); + $ruleMock = $this->getMockBuilder(Rule::class) + ->addMethods(['getCouponType']) + ->onlyMethods(['getId']) + ->disableOriginalConstructor() + ->getMock(); + $this->registryMock->expects($this->once()) + ->method('registry') + ->willReturn($ruleMock); + $ruleMock->expects($this->once()) + ->method('getId') + ->willReturn(1); + $ruleMock->expects($this->once()) + ->method('getCouponType') + ->willReturn(Rule::COUPON_TYPE_AUTO); + $this->requestMock->expects($this->once()) + ->method('getParams') + ->willReturn($this->requestMockDataWithInvalidCouponQuantity); + $this->scopeConfigMock + ->expects($this->once()) + ->method('getValue') + ->with(self::XML_COUPON_QUANTITY_LIMIT_PATH_TEST) + ->willReturn(self::XML_COUPON_QUANTITY_LIMIT_VALUE_TEST); + $this->messageManager->expects($this->once()) + ->method('addErrorMessage'); + $this->responseMock->expects($this->once()) + ->method('representJson') + ->with(); + $helperData->expects($this->once()) + ->method('jsonEncode') + ->with([ + 'messages' => __( + 'Coupon qty should be less than or equal to the coupon qty in the store configuration.' + ) + ]); + $layout = $this->getMockBuilder(Layout::class) + ->disableOriginalConstructor() + ->getMock(); + $this->view->expects($this->any()) + ->method('getLayout') + ->willReturn($layout); + $messageBlock = $this->getMockBuilder(Messages::class) + ->disableOriginalConstructor() + ->getMock(); + $layout->expects($this->once()) + ->method('initMessages'); + $layout->expects($this->once()) + ->method('getMessagesBlock') + ->willReturn($messageBlock); + $messageBlock->expects($this->once()) + ->method('getGroupedHtml') + ->willReturn(__('Coupon qty should be less than or equal to the coupon qty in the store configuration.')); + $this->model->execute(); + } + + /** + * @covers \Magento\SalesRule\Controller\Adminhtml\Promo\Quote::execute + */ + public function testExecuteWithDisableCouponQuantity() + { + $helperData = $this->getMockBuilder(Data::class) + ->disableOriginalConstructor() + ->getMock(); + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->with(Data::class) + ->willReturn($helperData); + $this->requestMock->expects($this->once()) + ->method('isAjax') + ->willReturn(true); + $ruleMock = $this->getMockBuilder(Rule::class) + ->addMethods(['getCouponType']) + ->onlyMethods(['getId']) + ->disableOriginalConstructor() + ->getMock(); + $this->registryMock->expects($this->once()) + ->method('registry') + ->willReturn($ruleMock); + $ruleMock->expects($this->once()) + ->method('getId') + ->willReturn(1); + $ruleMock->expects($this->once()) + ->method('getCouponType') + ->willReturn(Rule::COUPON_TYPE_AUTO); + $this->requestMock->expects($this->once()) + ->method('getParams') + ->willReturn($this->requestMockDataWithInvalidCouponQuantity); + $this->scopeConfigMock + ->expects($this->once()) + ->method('getValue') + ->with(self::XML_COUPON_QUANTITY_LIMIT_PATH_TEST) + ->willReturn(self::XML_COUPON_QUANTITY_LIMIT_DISABLE_VALUE_TEST); + $this->requestMockDataWithInvalidCouponQuantity['quantity'] = $this->requestMockDataWithInvalidCouponQuantity['qty'] ?? 0;//phpcs:ignore + $this->couponGenerationSpec->expects($this->any()) + ->method('create') + ->with(['data' => $this->requestMockDataWithInvalidCouponQuantity]) + ->willReturn(['some_data', 'some_data_2']); + $this->messageManager->expects($this->any()) + ->method('addSuccessMessage'); + $this->responseMock->expects($this->once()) + ->method('representJson') + ->with(); + $helperData->expects($this->once()) + ->method('jsonEncode') + ->with([ + 'messages' => __('%1 coupon(s) have been generated.', 2) + ]); + $layout = $this->getMockBuilder(Layout::class) + ->disableOriginalConstructor() + ->getMock(); + $this->view->expects($this->any()) + ->method('getLayout') + ->willReturn($layout); + $messageBlock = $this->getMockBuilder(Messages::class) + ->disableOriginalConstructor() + ->getMock(); + $layout->expects($this->once()) + ->method('initMessages'); + $layout->expects($this->once()) + ->method('getMessagesBlock') + ->willReturn($messageBlock); + $messageBlock->expects($this->once()) + ->method('getGroupedHtml') + ->willReturn(__('%1 coupon(s) have been generated.', 2)); + $this->model->execute(); + } } diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json index fef739ce979a7..f360fbbe91196 100644 --- a/app/code/Magento/SalesRule/composer.json +++ b/app/code/Magento/SalesRule/composer.json @@ -1,42 +1,43 @@ { "name": "magento/module-sales-rule", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/framework-bulk": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-rule": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-reports": "*", - "magento/module-rule": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-widget": "*", - "magento/module-captcha": "*", - "magento/module-checkout": "*", - "magento/module-authorization": "*", - "magento/module-asynchronous-operations": "*" + "magento/framework": "103.0.*", + "magento/framework-bulk": "101.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-rule": "101.2.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-reports": "100.4.*", + "magento/module-rule": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-widget": "101.2.*", + "magento/module-captcha": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-authorization": "100.4.*", + "magento/module-asynchronous-operations": "100.4.*" }, "suggest": { - "magento/module-sales-rule-sample-data": "*" + "magento/module-sales-rule-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -46,3 +47,4 @@ } } } + diff --git a/app/code/Magento/SalesRule/etc/adminhtml/system.xml b/app/code/Magento/SalesRule/etc/adminhtml/system.xml old mode 100644 new mode 100755 index 2655add5f8bbf..ca2a1b241bb26 --- a/app/code/Magento/SalesRule/etc/adminhtml/system.xml +++ b/app/code/Magento/SalesRule/etc/adminhtml/system.xml @@ -19,17 +19,22 @@ Excluding prefix, suffix and separators. validate-digits - + + + For better performance max value allowed is 250,000. Set 0 to disable it. + required-entry validate-number-range number-range-0-250000 + + Magento\SalesRule\Model\System\Config\Source\Coupon\Format - + - + - + If empty no separation. validate-digits diff --git a/app/code/Magento/SalesRule/etc/config.xml b/app/code/Magento/SalesRule/etc/config.xml old mode 100644 new mode 100755 index 10d704f50e5c0..dc809a7e730e0 --- a/app/code/Magento/SalesRule/etc/config.xml +++ b/app/code/Magento/SalesRule/etc/config.xml @@ -10,6 +10,7 @@ 12 + 250000 1 diff --git a/app/code/Magento/SalesRule/etc/di.xml b/app/code/Magento/SalesRule/etc/di.xml old mode 100644 new mode 100755 index 05bd801c3b99f..4109259551f0f --- a/app/code/Magento/SalesRule/etc/di.xml +++ b/app/code/Magento/SalesRule/etc/di.xml @@ -35,9 +35,9 @@ + type="Magento\SalesRule\Model\Rule\RuleQuoteRecollectTotalsOnDemand" /> + type="Magento\SalesRule\Model\Rule\QuoteResetAppliedRules" /> @@ -198,4 +198,9 @@ + + + Magento\Framework\App\Config\ScopeConfigInterface\Proxy + + diff --git a/app/code/Magento/SalesRule/i18n/en_US.csv b/app/code/Magento/SalesRule/i18n/en_US.csv old mode 100644 new mode 100755 index d4f93c25dc46c..bb6dcd704ec91 --- a/app/code/Magento/SalesRule/i18n/en_US.csv +++ b/app/code/Magento/SalesRule/i18n/en_US.csv @@ -165,3 +165,6 @@ Apply,Apply "Discard subsequent rules","Discard subsequent rules" "Default Rule Label for All Store Views","Default Rule Label for All Store Views" "Rule is not saved with auto generate option enabled. Please save the rule and try again.", "Rule is not saved with auto generate option enabled. Please save the rule and try again." +"Coupon quantity should be less than or equal to the coupon quantity in the store configuration.","Coupon quantity should be less than or equal to the coupon quantity in the store configuration." +"Code Quantity Limit","Code Quantity Limit" +"For better performance max value allowed is 250,000. Set 0 to disable it.","For better performance max value allowed is 250,000. Set 0 to disable it." diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json index d06655b83bfc2..739ae67c8bbd3 100644 --- a/app/code/Magento/SalesSequence/composer.json +++ b/app/code/Magento/SalesSequence/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-sales-sequence", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/SampleData/composer.json b/app/code/Magento/SampleData/composer.json index 05826fd71fc13..95a7ed6528cc2 100644 --- a/app/code/Magento/SampleData/composer.json +++ b/app/code/Magento/SampleData/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-sample-data", "description": "Sample Data fixtures", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/sample-data-media": "*" + "magento/sample-data-media": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "cli_commands.php", @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json index 4b9241f8303d7..800069d0b00ec 100644 --- a/app/code/Magento/Search/composer.json +++ b/app/code/Magento/Search/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-search", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog-search": "*", - "magento/module-reports": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-reports": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Security/composer.json b/app/code/Magento/Security/composer.json index 07fd6655f678e..5535f0f95d0b5 100644 --- a/app/code/Magento/Security/composer.json +++ b/app/code/Magento/Security/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-security", "description": "Security management module", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-config": "*", - "magento/module-backend": "*", - "magento/module-store": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-config": "101.2.*", + "magento/module-backend": "102.0.*", + "magento/module-store": "101.1.*", + "magento/module-user": "101.2.*" }, "suggest": { - "magento/module-customer": "*" + "magento/module-customer": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/SendFriend/composer.json b/app/code/Magento/SendFriend/composer.json index 47623f8f683a1..64540b0fd2212 100644 --- a/app/code/Magento/SendFriend/composer.json +++ b/app/code/Magento/SendFriend/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-send-friend", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-store": "*", - "magento/module-captcha": "*", - "magento/module-authorization": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-captcha": "100.4.*", + "magento/module-authorization": "100.4.*", + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json index e836197fd42e1..c41cfbe183601 100644 --- a/app/code/Magento/SendFriendGraphQl/composer.json +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-send-friend-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-send-friend": "*", - "magento/module-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-send-friend": "100.4.*", + "magento/module-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json index 8afbe9553094f..1ffda7952b581 100644 --- a/app/code/Magento/Shipping/composer.json +++ b/app/code/Magento/Shipping/composer.json @@ -1,37 +1,38 @@ { "name": "magento/module-shipping", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", "ext-gd": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-contact": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-ui": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-contact": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-user": "101.2.*" }, "suggest": { - "magento/module-fedex": "*", - "magento/module-ups": "*", - "magento/module-config": "*" + "magento/module-fedex": "100.4.*", + "magento/module-ups": "100.4.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -41,3 +42,4 @@ } } } + diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json index be9826186e128..5b53b329f6822 100644 --- a/app/code/Magento/Sitemap/composer.json +++ b/app/code/Magento/Sitemap/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-sitemap", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-robots": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-robots": "101.1.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/Store/Model/Group.php b/app/code/Magento/Store/Model/Group.php index 7f1e71c422251..8cc43afb874d9 100644 --- a/app/code/Magento/Store/Model/Group.php +++ b/app/code/Magento/Store/Model/Group.php @@ -9,8 +9,12 @@ */ namespace Magento\Store\Model; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface; +use Magento\Store\Model\Validation\StoreValidator; + /** - * Class Group + * Store Group model class used to retrieve and format group information * * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -21,9 +25,9 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel implements \Magento\Store\Api\Data\GroupInterface, \Magento\Framework\App\ScopeInterface { - const ENTITY = 'store_group'; + public const ENTITY = 'store_group'; - const CACHE_TAG = 'store_group'; + public const CACHE_TAG = 'store_group'; /** * @var bool @@ -101,10 +105,15 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel implements private $eventManager; /** - * @var \Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface + * @var PoisonPillPutInterface */ private $pillPut; + /** + * @var StoreValidator + */ + private $modelValidator; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -117,7 +126,8 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel implements * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data * @param \Magento\Framework\Event\ManagerInterface|null $eventManager - * @param \Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface|null $pillPut + * @param PoisonPillPutInterface|null $pillPut + * @param StoreValidator|null $modelValidator * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -132,7 +142,8 @@ public function __construct( \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], \Magento\Framework\Event\ManagerInterface $eventManager = null, - \Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface $pillPut = null + PoisonPillPutInterface $pillPut = null, + StoreValidator $modelValidator = null ) { $this->_configDataResource = $configDataResource; $this->_storeListFactory = $storeListFactory; @@ -140,7 +151,9 @@ public function __construct( $this->eventManager = $eventManager ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Framework\Event\ManagerInterface::class); $this->pillPut = $pillPut ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\MessageQueue\PoisonPill\PoisonPillPutInterface::class); + ->get(PoisonPillPutInterface::class); + $this->modelValidator = $modelValidator ?: ObjectManager::getInstance() + ->get(StoreValidator::class); parent::__construct( $context, $registry, @@ -162,6 +175,14 @@ protected function _construct() $this->_init(\Magento\Store\Model\ResourceModel\Group::class); } + /** + * @inheritdoc + */ + protected function _getValidationRulesBeforeSave() + { + return $this->modelValidator; + } + /** * Load store collection and set internal data * diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/StorefrontSwitchStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/StorefrontSwitchStoreViewActionGroup.xml index 9d8fb267910e1..e1ae5896a2746 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/StorefrontSwitchStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/StorefrontSwitchStoreViewActionGroup.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index 6dd17c590490e..2fd4b2d840806 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-store", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-media-storage": "*", - "magento/module-ui": "*", - "magento/module-customer": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*" }, "suggest": { - "magento/module-deploy": "*" + "magento/module-deploy": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/Store/etc/config.xml b/app/code/Magento/Store/etc/config.xml index 3b87f4340cd31..00a9be38123bf 100644 --- a/app/code/Magento/Store/etc/config.xml +++ b/app/code/Magento/Store/etc/config.xml @@ -135,6 +135,7 @@ pht phar svg + svgz xml xhtml diff --git a/app/code/Magento/StoreGraphQl/composer.json b/app/code/Magento/StoreGraphQl/composer.json index d5cb8d1ff4176..e29fc85137289 100644 --- a/app/code/Magento/StoreGraphQl/composer.json +++ b/app/code/Magento/StoreGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-store-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-graph-ql": "*", - "magento/module-graph-ql-cache": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-graph-ql-cache": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index 0a7b1c401886c..7a7e0ad9d9e0e 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-swagger", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/SwaggerWebapi/composer.json b/app/code/Magento/SwaggerWebapi/composer.json index dd1dc5d0011af..7b67e848f7045 100644 --- a/app/code/Magento/SwaggerWebapi/composer.json +++ b/app/code/Magento/SwaggerWebapi/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-swagger-webapi", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-swagger": "*" + "magento/framework": "103.0.*", + "magento/module-swagger": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/SwaggerWebapiAsync/composer.json b/app/code/Magento/SwaggerWebapiAsync/composer.json index e69821cc1067a..144a08cc35958 100644 --- a/app/code/Magento/SwaggerWebapiAsync/composer.json +++ b/app/code/Magento/SwaggerWebapiAsync/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-swagger-webapi-async", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-swagger": "*" + "magento/framework": "103.0.*", + "magento/module-swagger": "100.4.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AssertStorefrontSwatchColorActionGroup.xml b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AssertStorefrontSwatchColorActionGroup.xml index b48494a85ae2c..a8dce74036b59 100644 --- a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AssertStorefrontSwatchColorActionGroup.xml +++ b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AssertStorefrontSwatchColorActionGroup.xml @@ -17,7 +17,8 @@ - + {$grabStyle1} background: center center no-repeat {{expectedRgb}}; diff --git a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AssertSwatchColorActionGroup.xml b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AssertSwatchColorActionGroup.xml index f978afd7d2ca0..daf67d2f3f103 100644 --- a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AssertSwatchColorActionGroup.xml +++ b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AssertSwatchColorActionGroup.xml @@ -17,7 +17,8 @@ - + {$grabStyle1} {{expectedStyle}} diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml index dd5f6d6812436..449f917463fc8 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml @@ -27,5 +27,6 @@ + diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml index 201cd7d59104a..8ecae7e0137a1 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml @@ -42,6 +42,7 @@ + @@ -57,7 +58,7 @@ - + diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml index 0e25a14d6c170..e935aeb02be6d 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml @@ -18,6 +18,9 @@ + + + diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php index 589a0e84ee609..4cbdab21a1054 100644 --- a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php @@ -19,6 +19,8 @@ use Magento\Customer\Helper\Session\CurrentCustomer; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\Json\EncoderInterface; use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Framework\Pricing\PriceInfo\Base; @@ -106,6 +108,16 @@ protected function setUp(): void Prices::class ); + $deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); + + $deploymentConfig->expects($this->any()) + ->method('get') + ->with(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY) + ->willReturn('448198e08af35844a42d3c93c1ef4e03'); + $objectManagerHelper = new ObjectManager($this); $this->configurable = $objectManagerHelper->getObject( ConfigurableRenderer::class, @@ -123,7 +135,8 @@ protected function setUp(): void 'priceCurrency' => $this->priceCurrency, 'configurableAttributeData' => $this->configurableAttributeData, 'data' => [], - 'variationPrices' => $this->variationPricesMock + 'variationPrices' => $this->variationPricesMock, + 'deploymentConfig' => $deploymentConfig, ] ); } diff --git a/app/code/Magento/Swatches/composer.json b/app/code/Magento/Swatches/composer.json index d2f9201e8be5e..e4c58e03c3a9b 100644 --- a/app/code/Magento/Swatches/composer.json +++ b/app/code/Magento/Swatches/composer.json @@ -1,32 +1,33 @@ { "name": "magento/module-swatches", "description": "Add Swatches to Products", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-configurable-product": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-page-cache": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-configurable-product": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-page-cache": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*" }, "suggest": { - "magento/module-layered-navigation": "*", - "magento/module-swatches-sample-data": "*" + "magento/module-layered-navigation": "100.4.*", + "magento/module-swatches-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -36,3 +37,4 @@ } } } + diff --git a/app/code/Magento/SwatchesGraphQl/composer.json b/app/code/Magento/SwatchesGraphQl/composer.json index 1dc7a1528ad1b..15dd0cb85abe9 100644 --- a/app/code/Magento/SwatchesGraphQl/composer.json +++ b/app/code/Magento/SwatchesGraphQl/composer.json @@ -2,20 +2,21 @@ "name": "magento/module-swatches-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-swatches": "*", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*" + "magento/framework": "103.0.*", + "magento/module-swatches": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*" }, "suggest": { - "magento/module-configurable-product-graph-ql": "*" + "magento/module-configurable-product-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/SwatchesLayeredNavigation/composer.json b/app/code/Magento/SwatchesLayeredNavigation/composer.json index 9af558ec757e4..120287d6a37fd 100644 --- a/app/code/Magento/SwatchesLayeredNavigation/composer.json +++ b/app/code/Magento/SwatchesLayeredNavigation/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-swatches-layered-navigation", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "magento/magento-composer-installer": "*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCheckCreditMemoTotalsTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCheckCreditMemoTotalsTest.xml index 9b67208f77492..6cc1eb00dbdb1 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCheckCreditMemoTotalsTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCheckCreditMemoTotalsTest.xml @@ -20,6 +20,8 @@ + + diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json index e5628b04cc3f9..36b40b1158b75 100644 --- a/app/code/Magento/Tax/composer.json +++ b/app/code/Magento/Tax/composer.json @@ -1,35 +1,36 @@ { "name": "magento/module-tax", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p7", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-page-cache": "*", - "magento/module-quote": "*", - "magento/module-reports": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-page-cache": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-reports": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-tax-sample-data": "*" + "magento/module-tax-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -39,3 +40,4 @@ } } } + diff --git a/app/code/Magento/TaxGraphQl/composer.json b/app/code/Magento/TaxGraphQl/composer.json index 3ebd323fbfe12..71174a3f91698 100644 --- a/app/code/Magento/TaxGraphQl/composer.json +++ b/app/code/Magento/TaxGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-tax-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-tax": "*", - "magento/module-catalog-graph-ql": "*" + "magento/module-tax": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json index b83fe6dcdacf1..e1f81eb8fe508 100644 --- a/app/code/Magento/TaxImportExport/composer.json +++ b/app/code/Magento/TaxImportExport/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-tax-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-directory": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-directory": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index 80fe77d9c123f..9bf2e41db9ef4 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -1,33 +1,34 @@ { "name": "magento/module-theme", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.4-p6", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-require-js": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-widget": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-require-js": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-widget": "101.2.*" }, "suggest": { - "magento/module-theme-sample-data": "*", - "magento/module-deploy": "*", - "magento/module-directory": "*" + "magento/module-theme-sample-data": "Sample Data version: 100.4.*", + "magento/module-deploy": "100.4.*", + "magento/module-directory": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -37,3 +38,4 @@ } } } + diff --git a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js index 431e046049993..948bd2a57c30b 100644 --- a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js +++ b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js @@ -88,13 +88,6 @@ var config = { 'mage/backend/bootstrap', 'mage/adminhtml/globals' ], - config: { - mixins: { - 'jquery/jquery-ui': { - 'jquery/patches/jquery-ui-sortable': true - } - } - }, 'paths': { 'jquery/ui': 'jquery/jquery-ui' } diff --git a/app/code/Magento/Theme/view/frontend/requirejs-config.js b/app/code/Magento/Theme/view/frontend/requirejs-config.js index fb649f75d90bc..0a064cd0cd3da 100644 --- a/app/code/Magento/Theme/view/frontend/requirejs-config.js +++ b/app/code/Magento/Theme/view/frontend/requirejs-config.js @@ -40,9 +40,6 @@ var config = { mixins: { 'Magento_Theme/js/view/breadcrumbs': { 'Magento_Theme/js/view/add-home-breadcrumb': true - }, - 'jquery/ui-modules/widgets/sortable': { - 'jquery/patches/jquery-ui-sortable': true } } } diff --git a/app/code/Magento/ThemeGraphQl/composer.json b/app/code/Magento/ThemeGraphQl/composer.json index dbb9afddd7df0..723fd8cb5c497 100644 --- a/app/code/Magento/ThemeGraphQl/composer.json +++ b/app/code/Magento/ThemeGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-theme-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-store-graph-ql": "*" + "magento/module-store-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json index 91185e004418d..ced1a9630b43c 100644 --- a/app/code/Magento/Translation/composer.json +++ b/app/code/Magento/Translation/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-translation", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-developer": "*", - "magento/module-store": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-developer": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*" }, "suggest": { - "magento/module-deploy": "*" + "magento/module-deploy": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json index 8d6650101b5b2..9743d1e3ed1e8 100644 --- a/app/code/Magento/Ui/composer.json +++ b/app/code/Magento/Ui/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-ui", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-eav": "*", - "magento/module-store": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-eav": "102.1.*", + "magento/module-store": "101.1.*", + "magento/module-user": "101.2.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json index e34416ef0c05f..1febbe277e565 100644 --- a/app/code/Magento/Ups/composer.json +++ b/app/code/Magento/Ups/composer.json @@ -1,28 +1,29 @@ { "name": "magento/module-ups", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog-inventory": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -32,3 +33,4 @@ } } } + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml index 3692e82072afc..404fcb52c91e9 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml @@ -28,7 +28,7 @@ wishlist - https://marketplace.magento.com/ + https://commercemarketplace.adobe.com/ 301 Permanent (301) 1 @@ -37,7 +37,7 @@ wishlist - https://marketplace.magento.com/ + https://commercemarketplace.adobe.com/ 302 Temporary (302) 1 diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json index 84f06e17b6465..9c33e65e12fc8 100644 --- a/app/code/Magento/UrlRewrite/composer.json +++ b/app/code/Magento/UrlRewrite/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-url-rewrite", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "102.0.3-p5", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-cms": "*", - "magento/module-cms-url-rewrite": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-cms-url-rewrite": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/UrlRewriteGraphQl/composer.json b/app/code/Magento/UrlRewriteGraphQl/composer.json index 3e943ecf3e749..6fbdda7e4f0ee 100644 --- a/app/code/Magento/UrlRewriteGraphQl/composer.json +++ b/app/code/Magento/UrlRewriteGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-url-rewrite-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-url-rewrite": "*" + "magento/framework": "103.0.*", + "magento/module-url-rewrite": "102.0.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/User/Test/Mftf/Test/AdminCreateActiveUserEntityTest.xml b/app/code/Magento/User/Test/Mftf/Test/AdminCreateActiveUserEntityTest.xml index ba8d6ef433e13..f11bffa9b1ac0 100644 --- a/app/code/Magento/User/Test/Mftf/Test/AdminCreateActiveUserEntityTest.xml +++ b/app/code/Magento/User/Test/Mftf/Test/AdminCreateActiveUserEntityTest.xml @@ -28,7 +28,7 @@ - + diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json index 0008abc75e5be..af7e6af2d1995 100644 --- a/app/code/Magento/User/composer.json +++ b/app/code/Magento/User/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-user", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4-p2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-email": "*", - "magento/module-integration": "*", - "magento/module-security": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-email": "101.1.*", + "magento/module-integration": "100.4.*", + "magento/module-security": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Usps/Helper/Data.php b/app/code/Magento/Usps/Helper/Data.php index 4a03f2aa815f1..42a3266c5738a 100644 --- a/app/code/Magento/Usps/Helper/Data.php +++ b/app/code/Magento/Usps/Helper/Data.php @@ -8,12 +8,12 @@ use Magento\Framework\App\Helper\AbstractHelper; /** - * Usps data helper + * USPS Allowed shipping methods */ class Data extends AbstractHelper { /** - * Available shipping methods + * Shipping methods * * @var array */ @@ -36,6 +36,14 @@ class Data extends AbstractHelper 'usps_INT_14', // First-Class Mail International Large Envelope 'usps_INT_16', // Priority Mail International Small Flat Rate Box 'usps_INT_20', // Priority Mail International Small Flat Rate Envelope + '1058', // Ground Advantage™ + '4058', // Ground Advantage™ HAZMAT + '6058', // Ground Advantage™ Parcel locker + '2058', // Ground Advantage™ Hold for pickup + '4096', // Ground Advantage™ Cubic HAZMAT + '1096', // Ground Advantage™ Cubic + '2096', // Ground Advantage™ Cubic Hold for pickup + '6096', // Ground Advantage™ Cubic Parcel locker ]; /** diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index 5c4fc6086bed8..697cb4c82a5a4 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -809,6 +809,14 @@ public function getCode($type, $code = '') 'INT_24' => __('Priority Mail International DVD Flat Rate priced box'), 'INT_25' => __('Priority Mail International Large Video Flat Rate priced box'), 'INT_27' => __('Priority Mail Express International Padded Flat Rate Envelope'), + '1058' => __('Ground Advantage™'), + '4058' => __('Ground Advantage™ HAZMAT'), + '6058' => __('Ground Advantage™ Parcel locker'), + '2058' => __('Ground Advantage™ Hold for pickup'), + '4096' => __('Ground Advantage™ Cubic HAZMAT'), + '1096' => __('Ground Advantage™ Cubic'), + '2096' => __('Ground Advantage™ Cubic Hold for pickup'), + '6096' => __('Ground Advantage™ Cubic Parcel locker') ], 'service_to_code' => [ '0_FCLE' => 'First Class', @@ -885,6 +893,14 @@ public function getCode($type, $code = '') 'INT_24' => 'Priority', 'INT_25' => 'Priority', 'INT_27' => 'Priority Express', + '1058' => 'Ground Advantage', + '4058' => 'Ground Advantage', + '6058' => 'Ground Advantage', + '2058' => 'Ground Advantage', + '4096' => 'Ground Advantage', + '1096' => 'Ground Advantage', + '2096' => 'Ground Advantage', + '6096' => 'Ground Advantage', ], 'method_to_code' => [ 'First-Class Mail Large Envelope' => '0_FCLE', diff --git a/app/code/Magento/Usps/Model/Config/Backend/UspsUrl.php b/app/code/Magento/Usps/Model/Config/Backend/UspsUrl.php new file mode 100644 index 0000000000000..17cdcc83961bd --- /dev/null +++ b/app/code/Magento/Usps/Model/Config/Backend/UspsUrl.php @@ -0,0 +1,76 @@ +url = $url; + parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); + } + + /** + * @inheritdoc + * + * @throws ValidatorException + */ + public function beforeSave() + { + $isValid = $this->url->isValid($this->getValue()); + if ($isValid) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $host = parse_url((string)$this->getValue(), \PHP_URL_HOST); + + if (!empty($host) && !preg_match("/(?:.+\.|^)usps|shippingapis\.com$/i", $host)) { + throw new ValidatorException(__('USPS API endpoint URL\'s must use usps.com or shippingapis.com')); + } + } + + return parent::beforeSave(); + } +} diff --git a/app/code/Magento/Usps/Setup/Patch/Data/UpdateAllowedMethods.php b/app/code/Magento/Usps/Setup/Patch/Data/UpdateAllowedMethods.php index 913819a5c1ac4..7e3dd1b74e829 100644 --- a/app/code/Magento/Usps/Setup/Patch/Data/UpdateAllowedMethods.php +++ b/app/code/Magento/Usps/Setup/Patch/Data/UpdateAllowedMethods.php @@ -11,8 +11,7 @@ use Magento\Framework\Setup\Patch\PatchVersionInterface; /** - * Class UpdateAllowedMethods - * @package Magento\Usps\Setup\Patch + * Updates all methods on the configuration */ class UpdateAllowedMethods implements DataPatchInterface, PatchVersionInterface { @@ -23,6 +22,7 @@ class UpdateAllowedMethods implements DataPatchInterface, PatchVersionInterface /** * UpdateAllowedMethods constructor. + * * @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup */ public function __construct( @@ -32,7 +32,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function apply() { @@ -113,10 +113,11 @@ public function apply() $connection->update($configDataTable, ['value' => $newValue], $whereConfigId); } } + return $this; } /** - * {@inheritdoc} + * @inheritdoc */ public static function getDependencies() { @@ -124,7 +125,7 @@ public static function getDependencies() } /** - * {@inheritdoc} + * @inheritdoc */ public static function getVersion() { @@ -132,7 +133,7 @@ public static function getVersion() } /** - * {@inheritdoc} + * @inheritdoc */ public function getAliases() { diff --git a/app/code/Magento/Usps/Test/Unit/Helper/DataTest.php b/app/code/Magento/Usps/Test/Unit/Helper/DataTest.php index 2581385f1812c..a0077864ad256 100644 --- a/app/code/Magento/Usps/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Usps/Test/Unit/Helper/DataTest.php @@ -70,6 +70,14 @@ public function shippingMethodDataProvider() ['usps_INT_14'], // First-Class Mail International Large Envelope ['usps_INT_16'], // Priority Mail International Small Flat Rate Box ['usps_INT_20'], // Priority Mail International Small Flat Rate Envelope + ['1058'], // Ground Advantage™ + ['4058'], // Ground Advantage™ HAZMAT + ['6058'], // Ground Advantage™ Parcel locker + ['2058'], // Ground Advantage™ Hold for pickup + ['4096'], // Ground Advantage™ Cubic HAZMAT + ['1096'], // Ground Advantage™ Cubic + ['2096'], // Ground Advantage™ Cubic Hold for pickup + ['6096'], // Ground Advantage™ Cubic Parcel locker ]; } } diff --git a/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php index 52235aaa58076..96a8c9f557a6b 100644 --- a/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php +++ b/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php @@ -89,7 +89,8 @@ class CarrierTest extends TestCase private $config = [ 'carriers/usps/allowed_methods' => '0_FCLE,0_FCL,0_FCP,1,2,3,4,6,7,13,16,17,22,23,25,27,28,33,' . '34,35,36,37,42,43,53,55,56,57,61,INT_1,INT_2,INT_4,INT_6,INT_7,INT_8,INT_9,INT_10,INT_11,' . - 'INT_12,INT_13,INT_14,INT_15,INT_16,INT_20,INT_26', + 'INT_12,INT_13,INT_14,INT_15,INT_16,INT_20,INT_26,1058,4058,6058,2058,4096,' . + '1096,2096,6096', 'carriers/usps/showmethod' => 1, 'carriers/usps/debug' => 1, 'carriers/usps/userid' => 'test', diff --git a/app/code/Magento/Usps/Test/Unit/Model/Config/Backend/UspsUrlTest.php b/app/code/Magento/Usps/Test/Unit/Model/Config/Backend/UspsUrlTest.php new file mode 100644 index 0000000000000..da18923366c55 --- /dev/null +++ b/app/code/Magento/Usps/Test/Unit/Model/Config/Backend/UspsUrlTest.php @@ -0,0 +1,124 @@ +contextMock = $this->createMock(Context::class); + $registry = $this->createMock(Registry::class); + $config = $this->createMock(ScopeConfigInterface::class); + $cacheTypeList = $this->createMock(TypeListInterface::class); + $this->url = $this->createMock(Url::class); + $resource = $this->createMock(AbstractResource::class); + $resourceCollection = $this->createMock(AbstractDb::class); + $eventManagerMock = $this->getMockForAbstractClass(ManagerInterface::class); + + $eventManagerMock->expects($this->any())->method('dispatch'); + $this->contextMock->expects($this->any())->method('getEventDispatcher')->willReturn($eventManagerMock); + + $this->urlConfig = $objectManager->getObject( + UspsUrl::class, + [ + 'url' => $this->url, + 'context' => $this->contextMock, + 'registry' => $registry, + 'config' => $config, + 'cacheTypeList' => $cacheTypeList, + 'resource' => $resource, + 'resourceCollection' => $resourceCollection, + ] + ); + } + + /** + * @dataProvider validDataProvider + * @param string $data The valid data + * @throws ValidatorException + */ + public function testBeforeSave(string $data = ""): void + { + $this->url->expects($this->any())->method('isValid')->willReturn(true); + $this->urlConfig->setValue($data); + $this->urlConfig->beforeSave(); + $this->assertTrue($this->url->isValid($data)); + } + + /** + * @dataProvider invalidDataProvider + * @param string $data The invalid data + */ + public function testBeforeSaveErrors(string $data): void + { + $this->url->expects($this->any())->method('isValid')->willReturn(true); + $this->expectException('Magento\Framework\Exception\ValidatorException'); + $this->expectExceptionMessage('USPS API endpoint URL\'s must use usps.com or shippingapis.com'); + $this->urlConfig->setValue($data); + $this->urlConfig->beforeSave(); + } + + public function validDataProvider(): array + { + return [ + [], + [''], + ['http://usps.com'], + ['https://foo.usps.com'], + ['http://foo.usps.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } + + /** + * @return string[][] + */ + public function invalidDataProvider(): array + { + return [ + ['https://shippingapis.com.fake.com'], + ['https://shippingapis.info'], + ['http://shippingapis.com.foo.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } +} diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json index 8471b83a41246..39d3f677b3be4 100644 --- a/app/code/Magento/Usps/composer.json +++ b/app/code/Magento/Usps/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-usps", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3-p6", "require": { "php": "~7.4.0||~8.1.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Usps/etc/adminhtml/system.xml b/app/code/Magento/Usps/etc/adminhtml/system.xml index b01f7be9a19f9..00c9632b99367 100644 --- a/app/code/Magento/Usps/etc/adminhtml/system.xml +++ b/app/code/Magento/Usps/etc/adminhtml/system.xml @@ -16,9 +16,11 @@ + Magento\Usps\Model\Config\Backend\UspsUrl + Magento\Usps\Model\Config\Backend\UspsUrl diff --git a/app/code/Magento/Usps/etc/config.xml b/app/code/Magento/Usps/etc/config.xml index 852fbe9652929..bd6ad73f03130 100644 --- a/app/code/Magento/Usps/etc/config.xml +++ b/app/code/Magento/Usps/etc/config.xml @@ -11,7 +11,7 @@ 0 0 - 0_FCLE,0_FCL,0_FCP,1,2,3,4,6,7,13,16,17,22,23,25,27,28,33,34,35,36,37,42,43,53,57,61,INT_1,INT_2,INT_4,INT_6,INT_7,INT_8,INT_9,INT_10,INT_11,INT_12,INT_13,INT_14,INT_15,INT_16,INT_20 + 0_FCLE,0_FCL,0_FCP,1,2,3,4,6,7,13,16,17,22,23,25,27,28,33,34,35,36,37,42,43,53,57,61,INT_1,INT_2,INT_4,INT_6,INT_7,INT_8,INT_9,INT_10,INT_11,INT_12,INT_13,INT_14,INT_15,INT_16,INT_20,1058,4058,6058,2058,4096,1096,2096,6096 VARIABLE diff --git a/app/code/Magento/Usps/i18n/en_US.csv b/app/code/Magento/Usps/i18n/en_US.csv index ab1a11155fe04..1c14cbc2b00c3 100644 --- a/app/code/Magento/Usps/i18n/en_US.csv +++ b/app/code/Magento/Usps/i18n/en_US.csv @@ -72,6 +72,14 @@ "Priority Mail International DVD Flat Rate priced box","Priority Mail International DVD Flat Rate priced box" "Priority Mail International Large Video Flat Rate priced box","Priority Mail International Large Video Flat Rate priced box" "Priority Mail Express International Padded Flat Rate Envelope","Priority Mail Express International Padded Flat Rate Envelope" +"Ground Advantage™","Ground Advantage™" +"Ground Advantage™ HAZMAT","Ground Advantage™ HAZMAT" +"Ground Advantage™ Parcel locker","Ground Advantage™ Parcel locker" +"Ground Advantage™ Hold for pickup","Ground Advantage™ Hold for pickup" +"Ground Advantage™ Cubic HAZMAT","Ground Advantage™ Cubic HAZMAT" +"Ground Advantage™ Cubic","Ground Advantage™ Cubic" +"Ground Advantage™ Cubic Hold for pickup","Ground Advantage™ Cubic Hold for pickup" +"Ground Advantage™ Cubic Parcel locker","Ground Advantage™ Cubic Parcel locker" Letter,Letter Flat,Flat Parcel,Parcel @@ -137,3 +145,4 @@ Machinable,Machinable Debug,Debug "Show Method if Not Applicable","Show Method if Not Applicable" "Sort Order","Sort Order" +"USPS API endpoint URL\'s must use usps.com or shippingapis.com","USPS API endpoint URL\'s must use usps.com or shippingapis.com" diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json index a65fefb589422..1640e4cb0a596 100644 --- a/app/code/Magento/Variable/composer.json +++ b/app/code/Magento/Variable/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-variable", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-store": "*", - "magento/module-config": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-store": "101.1.*", + "magento/module-config": "101.2.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Vault/composer.json b/app/code/Magento/Vault/composer.json index e285571634993..8da051370b189 100644 --- a/app/code/Magento/Vault/composer.json +++ b/app/code/Magento/Vault/composer.json @@ -1,25 +1,25 @@ { "name": "magento/module-vault", - "description": "", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +29,4 @@ } } } + diff --git a/app/code/Magento/VaultGraphQl/composer.json b/app/code/Magento/VaultGraphQl/composer.json index e4a5dd65fa76d..ef87a3c52af74 100644 --- a/app/code/Magento/VaultGraphQl/composer.json +++ b/app/code/Magento/VaultGraphQl/composer.json @@ -2,16 +2,17 @@ "name": "magento/module-vault-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-vault": "*", - "magento/module-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.1", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-vault": "101.2.*", + "magento/module-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json index dc9ac096f7215..21ea754d32a2c 100644 --- a/app/code/Magento/Version/composer.json +++ b/app/code/Magento/Version/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-version", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json index 6a4823d2b1d15..712edf7bab742 100644 --- a/app/code/Magento/Webapi/composer.json +++ b/app/code/Magento/Webapi/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-webapi", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-integration": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-integration": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-user": "*", - "magento/module-customer": "*" + "magento/module-user": "101.2.*", + "magento/module-customer": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/WebapiAsync/composer.json b/app/code/Magento/WebapiAsync/composer.json index f136cf561d603..f4d86c2c6b7f5 100644 --- a/app/code/Magento/WebapiAsync/composer.json +++ b/app/code/Magento/WebapiAsync/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-webapi-async", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/framework-message-queue": "*", - "magento/module-webapi": "*", - "magento/module-asynchronous-operations": "*" + "magento/framework": "103.0.*", + "magento/framework-message-queue": "100.4.*", + "magento/module-webapi": "100.4.*", + "magento/module-asynchronous-operations": "100.4.*" }, "suggest": { - "magento/module-user": "*", - "magento/module-customer": "*" + "magento/module-user": "101.2.*", + "magento/module-customer": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/WebapiSecurity/composer.json b/app/code/Magento/WebapiSecurity/composer.json index bb4d8c10be48c..fb103bb1d2556 100644 --- a/app/code/Magento/WebapiSecurity/composer.json +++ b/app/code/Magento/WebapiSecurity/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-webapi-security", "description": "WebapiSecurity module provides option to loosen security on some webapi resources.", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-webapi": "*" + "magento/framework": "103.0.*", + "magento/module-webapi": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json index 3086929d12c0a..0d8a30f0ad50b 100644 --- a/app/code/Magento/Weee/composer.json +++ b/app/code/Magento/Weee/composer.json @@ -1,33 +1,34 @@ { "name": "magento/module-weee", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-page-cache": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-page-cache": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-bundle": "*" + "magento/module-bundle": "101.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -37,3 +38,4 @@ } } } + diff --git a/app/code/Magento/WeeeGraphQl/composer.json b/app/code/Magento/WeeeGraphQl/composer.json index 1cda2e3bc753b..67fe583b15bdc 100644 --- a/app/code/Magento/WeeeGraphQl/composer.json +++ b/app/code/Magento/WeeeGraphQl/composer.json @@ -2,20 +2,21 @@ "name": "magento/module-weee-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-weee": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-weee": "100.4.*" }, "suggest": { - "magento/module-catalog-graph-ql": "*" + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Widget/Model/Widget/Instance.php b/app/code/Magento/Widget/Model/Widget/Instance.php index 5192f06856474..2ea3225a42a13 100644 --- a/app/code/Magento/Widget/Model/Widget/Instance.php +++ b/app/code/Magento/Widget/Model/Widget/Instance.php @@ -33,28 +33,28 @@ */ class Instance extends \Magento\Framework\Model\AbstractModel { - const SPECIFIC_ENTITIES = 'specific'; + public const SPECIFIC_ENTITIES = 'specific'; - const ALL_ENTITIES = 'all'; + public const ALL_ENTITIES = 'all'; - const DEFAULT_LAYOUT_HANDLE = 'default'; + public const DEFAULT_LAYOUT_HANDLE = 'default'; - const PRODUCT_LAYOUT_HANDLE = 'catalog_product_view'; + public const PRODUCT_LAYOUT_HANDLE = 'catalog_product_view'; /** * @deprecated see self::SINGLE_PRODUCT_LAYOUT_HANDLE */ - const SINGLE_PRODUCT_LAYOUT_HANLDE = self::SINGLE_PRODUCT_LAYOUT_HANDLE; + public const SINGLE_PRODUCT_LAYOUT_HANLDE = self::SINGLE_PRODUCT_LAYOUT_HANDLE; - const SINGLE_PRODUCT_LAYOUT_HANDLE = 'catalog_product_view_id_{{ID}}'; + public const SINGLE_PRODUCT_LAYOUT_HANDLE = 'catalog_product_view_id_{{ID}}'; - const PRODUCT_TYPE_LAYOUT_HANDLE = 'catalog_product_view_type_{{TYPE}}'; + public const PRODUCT_TYPE_LAYOUT_HANDLE = 'catalog_product_view_type_{{TYPE}}'; - const ANCHOR_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_type_layered'; + public const ANCHOR_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_type_layered'; - const NOTANCHOR_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_type_default'; + public const NOTANCHOR_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_type_default'; - const SINGLE_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_id_{{ID}}'; + public const SINGLE_CATEGORY_LAYOUT_HANDLE = 'catalog_category_view_id_{{ID}}'; /** * @var array @@ -644,7 +644,7 @@ public function generateLayoutUpdateXml($container, $templatePath = '') return ''; } $parameters = $this->getWidgetParameters(); - $xml = ''; + $xml = ''; $template = ''; if (isset($parameters['template'])) { unset($parameters['template']); diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json index 5538cc70bff45..4e93c915c303e 100644 --- a/app/code/Magento/Widget/composer.json +++ b/app/code/Magento/Widget/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-widget", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4-p1", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-cms": "*", - "magento/module-email": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-variable": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-cms": "104.0.*", + "magento/module-email": "101.1.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-variable": "100.4.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-widget-sample-data": "*" + "magento/module-widget-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json index 4a9ce797c9add..347d70cd35a23 100644 --- a/app/code/Magento/Wishlist/composer.json +++ b/app/code/Magento/Wishlist/composer.json @@ -1,37 +1,38 @@ { "name": "magento/module-wishlist", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-rss": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-captcha": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-rss": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-captcha": "100.4.*" }, "suggest": { - "magento/module-configurable-product": "*", - "magento/module-downloadable": "*", - "magento/module-bundle": "*", - "magento/module-cookie": "*", - "magento/module-grouped-product": "*", - "magento/module-wishlist-sample-data": "*" + "magento/module-configurable-product": "100.4.*", + "magento/module-downloadable": "100.4.*", + "magento/module-bundle": "101.0.*", + "magento/module-cookie": "100.4.*", + "magento/module-grouped-product": "100.4.*", + "magento/module-wishlist-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -41,3 +42,4 @@ } } } + diff --git a/app/code/Magento/WishlistAnalytics/composer.json b/app/code/Magento/WishlistAnalytics/composer.json index 0a313416ce474..7df3f9556c9bc 100644 --- a/app/code/Magento/WishlistAnalytics/composer.json +++ b/app/code/Magento/WishlistAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-wishlist-analytics", "description": "N/A", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-wishlist": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-wishlist": "101.2.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json index ee08ec077c917..f7782cebba450 100755 --- a/app/code/Magento/WishlistGraphQl/composer.json +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -2,20 +2,21 @@ "name": "magento/module-wishlist-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/module-wishlist": "*", - "magento/module-store": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-quote": "*", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~7.4.0||~8.1.0", + "magento/framework": "103.0.*", + "magento/module-wishlist": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json index 450d82475e488..157617e4ea172 100644 --- a/app/design/adminhtml/Magento/backend/composer.json +++ b/app/design/adminhtml/Magento/backend/composer.json @@ -1,21 +1,23 @@ { "name": "magento/theme-adminhtml-backend", "description": "N/A", + "type": "magento2-theme", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-theme", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json index 741f700dfc1e2..e4a410e0ad8e7 100644 --- a/app/design/frontend/Magento/blank/composer.json +++ b/app/design/frontend/Magento/blank/composer.json @@ -1,21 +1,23 @@ { "name": "magento/theme-frontend-blank", "description": "N/A", + "type": "magento2-theme", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-theme", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json index 34f1ef911a84c..6ee86e9c7c9f2 100644 --- a/app/design/frontend/Magento/luma/composer.json +++ b/app/design/frontend/Magento/luma/composer.json @@ -1,22 +1,24 @@ { "name": "magento/theme-frontend-luma", "description": "N/A", + "type": "magento2-theme", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~7.4.0||~8.1.0", - "magento/framework": "*", - "magento/theme-frontend-blank": "*" + "magento/framework": "103.0.*", + "magento/theme-frontend-blank": "100.4.*" }, - "type": "magento2-theme", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/etc/di.xml b/app/etc/di.xml index bbb7770a6d78d..1cf14f3f87a56 100644 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -212,6 +212,7 @@ + diff --git a/app/i18n/Magento/de_DE/composer.json b/app/i18n/Magento/de_DE/composer.json index 5a488a3e32c2b..fd23d037ba459 100644 --- a/app/i18n/Magento/de_DE/composer.json +++ b/app/i18n/Magento/de_DE/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-de_de", "description": "German (Germany) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/en_US/composer.json b/app/i18n/Magento/en_US/composer.json index 1108c70de28a6..194854d58bbe2 100644 --- a/app/i18n/Magento/en_US/composer.json +++ b/app/i18n/Magento/en_US/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-en_us", "description": "English (United States) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/es_ES/composer.json b/app/i18n/Magento/es_ES/composer.json index 5bc3cb5730adf..0b49475587d54 100644 --- a/app/i18n/Magento/es_ES/composer.json +++ b/app/i18n/Magento/es_ES/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-es_es", "description": "Spanish (Spain) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/fr_FR/composer.json b/app/i18n/Magento/fr_FR/composer.json index 50c541308673b..ada414e6a7a32 100644 --- a/app/i18n/Magento/fr_FR/composer.json +++ b/app/i18n/Magento/fr_FR/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-fr_fr", "description": "French (France) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/nl_NL/composer.json b/app/i18n/Magento/nl_NL/composer.json index a182e179d4103..a881eed112ea0 100644 --- a/app/i18n/Magento/nl_NL/composer.json +++ b/app/i18n/Magento/nl_NL/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-nl_nl", "description": "Dutch (Netherlands) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/pt_BR/composer.json b/app/i18n/Magento/pt_BR/composer.json index 46734cc09b363..6e10bc16f6a79 100644 --- a/app/i18n/Magento/pt_BR/composer.json +++ b/app/i18n/Magento/pt_BR/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-pt_br", "description": "Portuguese (Brazil) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/zh_Hans_CN/composer.json b/app/i18n/Magento/zh_Hans_CN/composer.json index ce214ce649f56..8491eced1389f 100644 --- a/app/i18n/Magento/zh_Hans_CN/composer.json +++ b/app/i18n/Magento/zh_Hans_CN/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-zh_hans_cn", "description": "Chinese (China) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/composer.json b/composer.json index f23245a7e92bc..0a24bdf1e837b 100644 --- a/composer.json +++ b/composer.json @@ -7,14 +7,15 @@ "AFL-3.0" ], "config": { - "preferred-install": "dist", - "sort-packages": true, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true, "laminas/laminas-dependency-plugin": true, "magento/*": true - } + }, + "preferred-install": "dist", + "sort-packages": true }, + "version": "2.4.4-p7", "require": { "php": "~7.4.0||~8.1.0", "ext-bcmath": "*", @@ -40,6 +41,7 @@ "colinmollenhour/php-redis-session-abstract": "~1.4.5", "composer/composer": "^1.9 || ^2.0", "elasticsearch/elasticsearch": "~7.16.0", + "ezyang/htmlpurifier": "^4.16", "guzzlehttp/guzzle": "^7.3.0", "laminas/laminas-captcha": "^2.11", "laminas/laminas-code": "~4.5.0", @@ -70,7 +72,7 @@ "magento/composer-dependency-version-audit-plugin": "~0.1", "magento/magento-composer-installer": ">=0.3.0", "magento/zendframework1": "~1.15.0", - "monolog/monolog": "^2.3", + "monolog/monolog": "^2.7", "pelago/emogrifier": "^6.0.0", "php-amqplib/php-amqplib": "~3.1.0", "phpseclib/mcrypt_compat": "~2.0.0", @@ -85,6 +87,30 @@ "webonyx/graphql-php": "~14.11.3", "wikimedia/less.php": "^3.0.0" }, + "suggest": { + "ext-pcntl": "Need for run processes in parallel mode" + }, + "autoload": { + "exclude-from-classmap": [ + "**/dev/**", + "**/update/**", + "**/Test/**" + ], + "files": [ + "app/etc/NonComposerComponentRegistration.php" + ], + "psr-0": { + "": [ + "app/code/", + "generated/code/" + ] + }, + "psr-4": { + "Magento\\": "app/code/Magento/", + "Magento\\Framework\\": "lib/internal/Magento/Framework/", + "Magento\\Setup\\": "setup/src/Magento/Setup/" + } + }, "require-dev": { "allure-framework/allure-phpunit": "~1.5.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", @@ -100,291 +126,268 @@ "squizlabs/php_codesniffer": "~3.6.0", "symfony/finder": "^5.2" }, - "suggest": { - "ext-pcntl": "Need for run processes in parallel mode" + "conflict": { + "gene/bluefoot": "*" }, "replace": { - "magento/module-marketplace": "*", - "magento/module-admin-analytics": "*", - "magento/module-admin-notification": "*", - "magento/module-advanced-pricing-import-export": "*", - "magento/module-amqp": "*", - "magento/module-amqp-store": "*", - "magento/module-analytics": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-authorization": "*", - "magento/module-advanced-search": "*", - "magento/module-backend": "*", - "magento/module-backup": "*", - "magento/module-bundle": "*", - "magento/module-bundle-graph-ql": "*", - "magento/module-bundle-import-export": "*", - "magento/module-cache-invalidate": "*", - "magento/module-captcha": "*", - "magento/module-cardinal-commerce": "*", - "magento/module-catalog": "*", - "magento/module-catalog-customer-graph-ql": "*", - "magento/module-catalog-analytics": "*", - "magento/module-catalog-import-export": "*", - "magento/module-catalog-inventory": "*", - "magento/module-catalog-inventory-graph-ql": "*", - "magento/module-catalog-rule": "*", - "magento/module-catalog-rule-graph-ql": "*", - "magento/module-catalog-rule-configurable": "*", - "magento/module-catalog-search": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-catalog-widget": "*", - "magento/module-checkout": "*", - "magento/module-checkout-agreements": "*", - "magento/module-checkout-agreements-graph-ql": "*", - "magento/module-cms": "*", - "magento/module-cms-url-rewrite": "*", - "magento/module-compare-list-graph-ql": "*", - "magento/module-config": "*", - "magento/module-configurable-import-export": "*", - "magento/module-configurable-product": "*", - "magento/module-configurable-product-sales": "*", - "magento/module-contact": "*", - "magento/module-cookie": "*", - "magento/module-cron": "*", - "magento/module-currency-symbol": "*", - "magento/module-customer": "*", - "magento/module-customer-analytics": "*", - "magento/module-customer-downloadable-graph-ql": "*", - "magento/module-customer-import-export": "*", - "magento/module-deploy": "*", - "magento/module-developer": "*", - "magento/module-dhl": "*", - "magento/module-directory": "*", - "magento/module-directory-graph-ql": "*", - "magento/module-downloadable": "*", - "magento/module-downloadable-graph-ql": "*", - "magento/module-downloadable-import-export": "*", - "magento/module-eav": "*", - "magento/module-elasticsearch": "*", - "magento/module-elasticsearch-6": "*", - "magento/module-elasticsearch-7": "*", - "magento/module-email": "*", - "magento/module-encryption-key": "*", - "magento/module-fedex": "*", - "magento/module-gift-message": "*", - "magento/module-gift-message-graph-ql": "*", - "magento/module-google-adwords": "*", - "magento/module-google-analytics": "*", - "magento/module-google-optimizer": "*", - "magento/module-graph-ql": "*", - "magento/module-graph-ql-cache": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-catalog-cms-graph-ql": "*", - "magento/module-catalog-url-rewrite-graph-ql": "*", - "magento/module-configurable-product-graph-ql": "*", - "magento/module-customer-graph-ql": "*", - "magento/module-eav-graph-ql": "*", - "magento/module-swatches-graph-ql": "*", - "magento/module-tax-graph-ql": "*", - "magento/module-url-rewrite-graph-ql": "*", - "magento/module-cms-url-rewrite-graph-ql": "*", - "magento/module-weee-graph-ql": "*", - "magento/module-cms-graph-ql": "*", - "magento/module-grouped-import-export": "*", - "magento/module-grouped-product": "*", - "magento/module-grouped-catalog-inventory": "*", - "magento/module-grouped-product-graph-ql": "*", - "magento/module-import-export": "*", - "magento/module-indexer": "*", - "magento/module-instant-purchase": "*", - "magento/module-integration": "*", - "magento/module-layered-navigation": "*", - "magento/module-login-as-customer": "*", - "magento/module-login-as-customer-admin-ui": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-login-as-customer-assistance": "*", - "magento/module-login-as-customer-frontend-ui": "*", - "magento/module-login-as-customer-graph-ql": "*", - "magento/module-login-as-customer-log": "*", - "magento/module-login-as-customer-quote": "*", - "magento/module-login-as-customer-page-cache": "*", - "magento/module-login-as-customer-sales": "*", - "magento/module-media-content": "*", - "magento/module-media-content-api": "*", - "magento/module-media-content-catalog": "*", - "magento/module-media-content-cms": "*", - "magento/module-media-gallery": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-ui": "*", - "magento/module-media-gallery-ui-api": "*", - "magento/module-media-gallery-integration": "*", - "magento/module-media-gallery-synchronization": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-content-synchronization": "*", - "magento/module-media-content-synchronization-api": "*", - "magento/module-media-content-synchronization-catalog": "*", - "magento/module-media-content-synchronization-cms": "*", - "magento/module-media-gallery-synchronization-metadata": "*", - "magento/module-media-gallery-metadata": "*", - "magento/module-media-gallery-metadata-api": "*", - "magento/module-media-gallery-catalog-ui": "*", - "magento/module-media-gallery-cms-ui": "*", - "magento/module-media-gallery-catalog-integration": "*", - "magento/module-media-gallery-catalog": "*", - "magento/module-media-gallery-renditions": "*", - "magento/module-media-gallery-renditions-api": "*", - "magento/module-media-storage": "*", - "magento/module-message-queue": "*", - "magento/module-msrp": "*", - "magento/module-msrp-configurable-product": "*", - "magento/module-msrp-grouped-product": "*", - "magento/module-multishipping": "*", - "magento/module-mysql-mq": "*", - "magento/module-new-relic-reporting": "*", - "magento/module-newsletter": "*", - "magento/module-newsletter-graph-ql": "*", - "magento/module-offline-payments": "*", - "magento/module-offline-shipping": "*", - "magento/module-page-cache": "*", - "magento/module-payment": "*", - "magento/module-payment-graph-ql": "*", - "magento/module-paypal": "*", - "magento/module-paypal-captcha": "*", - "magento/module-paypal-graph-ql": "*", - "magento/module-persistent": "*", - "magento/module-product-alert": "*", - "magento/module-product-video": "*", - "magento/module-quote": "*", - "magento/module-quote-analytics": "*", - "magento/module-quote-bundle-options": "*", - "magento/module-quote-configurable-options": "*", - "magento/module-quote-downloadable-links": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-related-product-graph-ql": "*", - "magento/module-release-notification": "*", - "magento/module-reports": "*", - "magento/module-require-js": "*", - "magento/module-review": "*", - "magento/module-review-graph-ql": "*", - "magento/module-review-analytics": "*", - "magento/module-robots": "*", - "magento/module-rss": "*", - "magento/module-rule": "*", - "magento/module-sales": "*", - "magento/module-sales-analytics": "*", - "magento/module-sales-graph-ql": "*", - "magento/module-sales-inventory": "*", - "magento/module-sales-rule": "*", - "magento/module-sales-sequence": "*", - "magento/module-sample-data": "*", - "magento/module-search": "*", - "magento/module-security": "*", - "magento/module-send-friend": "*", - "magento/module-send-friend-graph-ql": "*", - "magento/module-shipping": "*", - "magento/module-sitemap": "*", - "magento/module-store": "*", - "magento/module-store-graph-ql": "*", - "magento/module-swagger": "*", - "magento/module-swagger-webapi": "*", - "magento/module-swagger-webapi-async": "*", - "magento/module-swatches": "*", - "magento/module-swatches-layered-navigation": "*", - "magento/module-tax": "*", - "magento/module-tax-import-export": "*", - "magento/module-theme": "*", - "magento/module-theme-graph-ql": "*", - "magento/module-translation": "*", - "magento/module-ui": "*", - "magento/module-ups": "*", - "magento/module-url-rewrite": "*", - "magento/module-user": "*", - "magento/module-usps": "*", - "magento/module-variable": "*", - "magento/module-vault": "*", - "magento/module-vault-graph-ql": "*", - "magento/module-version": "*", - "magento/module-webapi": "*", - "magento/module-webapi-async": "*", - "magento/module-webapi-security": "*", - "magento/module-weee": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*", - "magento/module-wishlist-graph-ql": "*", - "magento/module-wishlist-analytics": "*", - "magento/theme-adminhtml-backend": "*", - "magento/theme-frontend-blank": "*", - "magento/theme-frontend-luma": "*", - "magento/language-de_de": "*", - "magento/language-en_us": "*", - "magento/language-es_es": "*", - "magento/language-fr_fr": "*", - "magento/language-nl_nl": "*", - "magento/language-pt_br": "*", - "magento/language-zh_hans_cn": "*", - "magento/framework": "*", - "magento/framework-amqp": "*", - "magento/framework-bulk": "*", - "magento/framework-message-queue": "*", + "magento/module-marketplace": "100.4.3-p5", + "magento/module-admin-analytics": "100.4.4", + "magento/module-admin-notification": "100.4.3", + "magento/module-advanced-pricing-import-export": "100.4.4", + "magento/module-amqp": "100.4.2", + "magento/module-amqp-store": "100.4.2", + "magento/module-analytics": "100.4.4-p4", + "magento/module-asynchronous-operations": "100.4.4", + "magento/module-authorization": "100.4.4", + "magento/module-advanced-search": "100.4.2", + "magento/module-backend": "102.0.4-p3", + "magento/module-backup": "100.4.4", + "magento/module-bundle": "101.0.4-p7", + "magento/module-bundle-graph-ql": "100.4.4", + "magento/module-bundle-import-export": "100.4.3", + "magento/module-cache-invalidate": "100.4.2", + "magento/module-captcha": "100.4.4-p4", + "magento/module-cardinal-commerce": "100.4.2", + "magento/module-catalog": "104.0.4-p7", + "magento/module-catalog-customer-graph-ql": "100.4.4", + "magento/module-catalog-analytics": "100.4.2", + "magento/module-catalog-import-export": "101.1.4-p4", + "magento/module-catalog-inventory": "100.4.4", + "magento/module-catalog-inventory-graph-ql": "100.4.1", + "magento/module-catalog-rule": "101.2.4", + "magento/module-catalog-rule-graph-ql": "100.4.2", + "magento/module-catalog-rule-configurable": "100.4.3", + "magento/module-catalog-search": "102.0.4", + "magento/module-catalog-url-rewrite": "100.4.4", + "magento/module-catalog-widget": "100.4.4-p2", + "magento/module-checkout": "100.4.4-p7", + "magento/module-checkout-agreements": "100.4.3-p7", + "magento/module-checkout-agreements-graph-ql": "100.4.1", + "magento/module-cms": "104.0.4-p2", + "magento/module-cms-url-rewrite": "100.4.3", + "magento/module-compare-list-graph-ql": "100.4.1", + "magento/module-config": "101.2.4-p7", + "magento/module-configurable-import-export": "100.4.2", + "magento/module-configurable-product": "100.4.4-p7", + "magento/module-configurable-product-sales": "100.4.2", + "magento/module-contact": "100.4.4", + "magento/module-cookie": "100.4.4", + "magento/module-cron": "100.4.4", + "magento/module-currency-symbol": "100.4.3-p6", + "magento/module-customer": "103.0.4-p6", + "magento/module-customer-analytics": "100.4.2", + "magento/module-customer-downloadable-graph-ql": "100.4.1", + "magento/module-customer-import-export": "100.4.4", + "magento/module-deploy": "100.4.4", + "magento/module-developer": "100.4.4", + "magento/module-dhl": "100.4.3", + "magento/module-directory": "100.4.4", + "magento/module-directory-graph-ql": "100.4.2", + "magento/module-downloadable": "100.4.4", + "magento/module-downloadable-graph-ql": "100.4.4", + "magento/module-downloadable-import-export": "100.4.3", + "magento/module-eav": "102.1.4", + "magento/module-elasticsearch": "101.0.4-p1", + "magento/module-elasticsearch-6": "100.4.4", + "magento/module-elasticsearch-7": "100.4.4", + "magento/module-email": "101.1.4-p7", + "magento/module-encryption-key": "100.4.3", + "magento/module-fedex": "100.4.3-p4", + "magento/module-gift-message": "100.4.3", + "magento/module-gift-message-graph-ql": "100.4.2", + "magento/module-google-adwords": "100.4.2", + "magento/module-google-analytics": "100.4.1", + "magento/module-google-optimizer": "100.4.3", + "magento/module-graph-ql": "100.4.4", + "magento/module-graph-ql-cache": "100.4.1", + "magento/module-catalog-graph-ql": "100.4.4", + "magento/module-catalog-cms-graph-ql": "100.4.1", + "magento/module-catalog-url-rewrite-graph-ql": "100.4.3", + "magento/module-configurable-product-graph-ql": "100.4.4", + "magento/module-customer-graph-ql": "100.4.4", + "magento/module-eav-graph-ql": "100.4.2", + "magento/module-swatches-graph-ql": "100.4.3", + "magento/module-tax-graph-ql": "100.4.1", + "magento/module-url-rewrite-graph-ql": "100.4.3", + "magento/module-cms-url-rewrite-graph-ql": "100.4.2", + "magento/module-weee-graph-ql": "100.4.2", + "magento/module-cms-graph-ql": "100.4.2", + "magento/module-grouped-import-export": "100.4.2", + "magento/module-grouped-product": "100.4.4", + "magento/module-grouped-catalog-inventory": "100.4.1", + "magento/module-grouped-product-graph-ql": "100.4.4", + "magento/module-import-export": "101.0.4", + "magento/module-indexer": "100.4.4", + "magento/module-instant-purchase": "100.4.3", + "magento/module-integration": "100.4.4", + "magento/module-layered-navigation": "100.4.4", + "magento/module-login-as-customer": "100.4.4", + "magento/module-login-as-customer-admin-ui": "100.4.4", + "magento/module-login-as-customer-api": "100.4.3", + "magento/module-login-as-customer-assistance": "100.4.3", + "magento/module-login-as-customer-frontend-ui": "100.4.4", + "magento/module-login-as-customer-graph-ql": "100.4.1", + "magento/module-login-as-customer-log": "100.4.3", + "magento/module-login-as-customer-quote": "100.4.3", + "magento/module-login-as-customer-page-cache": "100.4.4", + "magento/module-login-as-customer-sales": "100.4.4", + "magento/module-media-content": "100.4.3", + "magento/module-media-content-api": "100.4.3", + "magento/module-media-content-catalog": "100.4.3", + "magento/module-media-content-cms": "100.4.3", + "magento/module-media-gallery": "100.4.3", + "magento/module-media-gallery-api": "101.0.3", + "magento/module-media-gallery-ui": "100.4.3", + "magento/module-media-gallery-ui-api": "100.4.2", + "magento/module-media-gallery-integration": "100.4.3", + "magento/module-media-gallery-synchronization": "100.4.3", + "magento/module-media-gallery-synchronization-api": "100.4.2", + "magento/module-media-content-synchronization": "100.4.3", + "magento/module-media-content-synchronization-api": "100.4.2", + "magento/module-media-content-synchronization-catalog": "100.4.2", + "magento/module-media-content-synchronization-cms": "100.4.2", + "magento/module-media-gallery-synchronization-metadata": "100.4.1", + "magento/module-media-gallery-metadata": "100.4.2", + "magento/module-media-gallery-metadata-api": "100.4.1", + "magento/module-media-gallery-catalog-ui": "100.4.2", + "magento/module-media-gallery-cms-ui": "100.4.2", + "magento/module-media-gallery-catalog-integration": "100.4.2", + "magento/module-media-gallery-catalog": "100.4.2", + "magento/module-media-gallery-renditions": "100.4.2", + "magento/module-media-gallery-renditions-api": "100.4.1", + "magento/module-media-storage": "100.4.3", + "magento/module-message-queue": "100.4.4", + "magento/module-msrp": "100.4.3", + "magento/module-msrp-configurable-product": "100.4.2", + "magento/module-msrp-grouped-product": "100.4.2", + "magento/module-multishipping": "100.4.4", + "magento/module-mysql-mq": "100.4.2", + "magento/module-new-relic-reporting": "100.4.2", + "magento/module-newsletter": "100.4.4-p7", + "magento/module-newsletter-graph-ql": "100.4.1", + "magento/module-offline-payments": "100.4.3", + "magento/module-offline-shipping": "100.4.3", + "magento/module-page-cache": "100.4.4-p7", + "magento/module-payment": "100.4.4", + "magento/module-payment-graph-ql": "100.4.0", + "magento/module-paypal": "101.0.4", + "magento/module-paypal-captcha": "100.4.2-p7", + "magento/module-paypal-graph-ql": "100.4.2", + "magento/module-persistent": "100.4.4-p6", + "magento/module-product-alert": "100.4.3", + "magento/module-product-video": "100.4.4", + "magento/module-quote": "101.2.4-p4", + "magento/module-quote-analytics": "100.4.4", + "magento/module-quote-bundle-options": "100.4.1", + "magento/module-quote-configurable-options": "100.4.1", + "magento/module-quote-downloadable-links": "100.4.1", + "magento/module-quote-graph-ql": "100.4.4-p4", + "magento/module-related-product-graph-ql": "100.4.2", + "magento/module-release-notification": "100.4.2", + "magento/module-reports": "100.4.4", + "magento/module-require-js": "100.4.1", + "magento/module-review": "100.4.4", + "magento/module-review-graph-ql": "100.4.1", + "magento/module-review-analytics": "100.4.2", + "magento/module-robots": "101.1.1", + "magento/module-rss": "100.4.3", + "magento/module-rule": "100.4.3", + "magento/module-sales": "103.0.4-p7", + "magento/module-sales-analytics": "100.4.2", + "magento/module-sales-graph-ql": "100.4.4", + "magento/module-sales-inventory": "100.4.1", + "magento/module-sales-rule": "101.2.4-p7", + "magento/module-sales-sequence": "100.4.2", + "magento/module-sample-data": "100.4.2", + "magento/module-search": "101.1.4", + "magento/module-security": "100.4.4", + "magento/module-send-friend": "100.4.3", + "magento/module-send-friend-graph-ql": "100.4.1", + "magento/module-shipping": "100.4.4", + "magento/module-sitemap": "100.4.3", + "magento/module-store": "101.1.4-p7", + "magento/module-store-graph-ql": "100.4.3", + "magento/module-swagger": "100.4.3", + "magento/module-swagger-webapi": "100.4.1", + "magento/module-swagger-webapi-async": "100.4.1", + "magento/module-swatches": "100.4.4-p4", + "magento/module-swatches-layered-navigation": "100.4.1", + "magento/module-tax": "100.4.4-p7", + "magento/module-tax-import-export": "100.4.4", + "magento/module-theme": "101.1.4-p6", + "magento/module-theme-graph-ql": "100.4.2", + "magento/module-translation": "100.4.4", + "magento/module-ui": "101.2.4", + "magento/module-ups": "100.4.4", + "magento/module-url-rewrite": "102.0.3-p5", + "magento/module-user": "101.2.4-p2", + "magento/module-usps": "100.4.3-p6", + "magento/module-variable": "100.4.2", + "magento/module-vault": "101.2.4", + "magento/module-vault-graph-ql": "100.4.1", + "magento/module-version": "100.4.1", + "magento/module-webapi": "100.4.3", + "magento/module-webapi-async": "100.4.2", + "magento/module-webapi-security": "100.4.2", + "magento/module-weee": "100.4.4", + "magento/module-widget": "101.2.4-p1", + "magento/module-wishlist": "101.2.4", + "magento/module-wishlist-graph-ql": "100.4.4", + "magento/module-wishlist-analytics": "100.4.3", + "magento/theme-adminhtml-backend": "100.4.4", + "magento/theme-frontend-blank": "100.4.4", + "magento/theme-frontend-luma": "100.4.4", + "magento/language-de_de": "100.4.0", + "magento/language-en_us": "100.4.0", + "magento/language-es_es": "100.4.0", + "magento/language-fr_fr": "100.4.0", + "magento/language-nl_nl": "100.4.0", + "magento/language-pt_br": "100.4.0", + "magento/language-zh_hans_cn": "100.4.0", + "magento/framework": "103.0.4-p7", + "magento/framework-amqp": "100.4.2-p1", + "magento/framework-bulk": "101.0.1", + "magento/framework-message-queue": "100.4.4", "trentrichardson/jquery-timepicker-addon": "1.4.3", "components/jquery": "1.11.0", "blueimp/jquery-file-upload": "5.6.14", "components/jqueryui": "1.10.4", "twbs/bootstrap": "3.1.0", "tinymce/tinymce": "3.4.7", - "magento/module-csp": "*", - "magento/module-aws-s3": "*", - "magento/module-remote-storage": "*", - "magento/module-jwt-framework-adapter": "*", - "magento/module-jwt-user-token": "*" + "magento/module-csp": "100.4.3", + "magento/module-aws-s3": "100.4.2", + "magento/module-remote-storage": "100.4.2", + "magento/module-jwt-framework-adapter": "100.4.1", + "magento/module-jwt-user-token": "100.4.0" }, - "conflict": { - "gene/bluefoot": "*" + "autoload-dev": { + "psr-4": { + "Magento\\PhpStan\\": "dev/tests/static/framework/Magento/PhpStan/", + "Magento\\Sniffs\\": "dev/tests/static/framework/Magento/Sniffs/", + "Magento\\TestFramework\\Inspection\\": "dev/tests/static/framework/Magento/TestFramework/Inspection/", + "Magento\\TestFramework\\Utility\\": "dev/tests/static/framework/Magento/TestFramework/Utility/", + "Magento\\Tools\\": "dev/tools/Magento/Tools/", + "Magento\\Tools\\Sanity\\": "dev/build/publication/sanity/Magento/Tools/Sanity/" + } }, + "prefer-stable": true, "extra": { "component_paths": { - "trentrichardson/jquery-timepicker-addon": "lib/web/jquery/jquery-ui-timepicker-addon.js", + "blueimp/jquery-file-upload": "lib/web/jquery/fileUploader", "components/jquery": [ "lib/web/jquery.js", "lib/web/jquery/jquery.min.js", "lib/web/jquery/jquery-migrate.js" ], - "blueimp/jquery-file-upload": "lib/web/jquery/fileUploader", "components/jqueryui": [ "lib/web/jquery/jquery-ui.js" ], + "tinymce/tinymce": "lib/web/tiny_mce_5", + "trentrichardson/jquery-timepicker-addon": "lib/web/jquery/jquery-ui-timepicker-addon.js", "twbs/bootstrap": [ "lib/web/jquery/jquery.tabs.js" - ], - "tinymce/tinymce": "lib/web/tiny_mce_5" - } - }, - "autoload": { - "psr-4": { - "Magento\\Framework\\": "lib/internal/Magento/Framework/", - "Magento\\Setup\\": "setup/src/Magento/Setup/", - "Magento\\": "app/code/Magento/" - }, - "psr-0": { - "": [ - "app/code/", - "generated/code/" ] - }, - "files": [ - "app/etc/NonComposerComponentRegistration.php" - ], - "exclude-from-classmap": [ - "**/dev/**", - "**/update/**", - "**/Test/**" - ] - }, - "autoload-dev": { - "psr-4": { - "Magento\\Sniffs\\": "dev/tests/static/framework/Magento/Sniffs/", - "Magento\\Tools\\": "dev/tools/Magento/Tools/", - "Magento\\Tools\\Sanity\\": "dev/build/publication/sanity/Magento/Tools/Sanity/", - "Magento\\TestFramework\\Inspection\\": "dev/tests/static/framework/Magento/TestFramework/Inspection/", - "Magento\\TestFramework\\Utility\\": "dev/tests/static/framework/Magento/TestFramework/Utility/", - "Magento\\PhpStan\\": "dev/tests/static/framework/Magento/PhpStan/" } - }, - "prefer-stable": true + } } + diff --git a/composer.lock b/composer.lock index 32b3311c0b14c..b8ae00955ba54 100644 --- a/composer.lock +++ b/composer.lock @@ -1167,7 +1167,68 @@ "support": { "source": "https://github.com/ezimuel/ringphp/tree/1.2.0" }, - "time": "2021-11-16T11:51:30+00:00" + "time": "2022-12-07T11:28:53+00:00" + }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.16.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/523407fb06eb9e5f3d59889b3978d5bfe94299c8", + "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8", + "shasum": "" + }, + "require": { + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" + }, + "type": "library", + "autoload": { + "files": [ + "library/HTMLPurifier.composer.php" + ], + "psr-0": { + "HTMLPurifier": "library/" + }, + "exclude-from-classmap": [ + "/library/HTMLPurifier/Language/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.16.0" + }, + "time": "2022-09-18T07:06:19+00:00" }, { "name": "fgrosse/phpasn1", @@ -4000,16 +4061,16 @@ }, { "name": "monolog/monolog", - "version": "2.3.5", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "fd4380d6fc37626e2f799f29d91195040137eba9" + "reference": "5579edf28aee1190a798bfa5be8bc16c563bd524" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd4380d6fc37626e2f799f29d91195040137eba9", - "reference": "fd4380d6fc37626e2f799f29d91195040137eba9", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5579edf28aee1190a798bfa5be8bc16c563bd524", + "reference": "5579edf28aee1190a798bfa5be8bc16c563bd524", "shasum": "" }, "require": { @@ -4083,7 +4144,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.3.5" + "source": "https://github.com/Seldaek/monolog/tree/2.7.0" }, "funding": [ { @@ -4095,7 +4156,7 @@ "type": "tidelift" } ], - "time": "2021-10-01T21:08:31+00:00" + "time": "2022-06-09T08:59:12+00:00" }, { "name": "mtdowling/jmespath.php", @@ -12785,5 +12846,5 @@ "lib-libxml": "*" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.1.0" } diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php index 10dc5c377450f..a1b1551245ac1 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQlAbstract.php @@ -51,6 +51,7 @@ abstract class GraphQlAbstract extends WebapiAbstract * @var PhpFormatter */ private $formatter; + private const EPSILON=2; /** * Perform GraphQL query call via GET to the system under test. @@ -224,9 +225,10 @@ protected function assertResponseFields($actualResponse, $assertionMap) $actualResponse, "Response array does not contain key '{$responseField}'" ); - self::assertEquals( + self::assertEqualsWithDelta( $expectedValue, $actualResponse[$responseField], + self::EPSILON, "Value of '{$responseField}' field in response does not match expected value: " . var_export($expectedValue, true) ); diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php index 63f6814897863..a9954d29053cd 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php @@ -8,10 +8,13 @@ use Magento\Customer\Api\Data\CustomerInterface as Customer; use Magento\Customer\Model\AccountManagement; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\InputException; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; use Magento\Newsletter\Model\Subscriber; use Magento\Security\Model\Config; +use Magento\Store\Model\ScopeInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Helper\Customer as CustomerHelper; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -23,15 +26,20 @@ */ class AccountManagementTest extends WebapiAbstract { - const SERVICE_VERSION = 'V1'; - const SERVICE_NAME = 'customerAccountManagementV1'; - const RESOURCE_PATH = '/V1/customers'; + public const SERVICE_VERSION = 'V1'; + public const SERVICE_NAME = 'customerAccountManagementV1'; + public const RESOURCE_PATH = '/V1/customers'; /** * Sample values for testing */ - const ATTRIBUTE_CODE = 'attribute_code'; - const ATTRIBUTE_VALUE = 'attribute_value'; + public const ATTRIBUTE_CODE = 'attribute_code'; + public const ATTRIBUTE_VALUE = 'attribute_value'; + + /** + * @var ObjectManager + */ + private $objectManager; /** * @var AccountManagementInterface @@ -86,6 +94,8 @@ class AccountManagementTest extends WebapiAbstract */ protected function setUp(): void { + $this->objectManager = Bootstrap::getObjectManager(); + $this->accountManagement = Bootstrap::getObjectManager()->get( \Magento\Customer\Api\AccountManagementInterface::class ); @@ -645,6 +655,8 @@ public function testIsReadonly() public function testEmailAvailable() { + $config = $this->objectManager->get(ScopeConfigInterface::class); + $customerData = $this->_createCustomer(); $serviceInfo = [ @@ -662,7 +674,18 @@ public function testEmailAvailable() 'customerEmail' => $customerData[Customer::EMAIL], 'websiteId' => $customerData[Customer::WEBSITE_ID], ]; - $this->assertFalse($this->_webApiCall($serviceInfo, $requestData)); + + $emailSetting = $config->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + $customerData[Customer::WEBSITE_ID] + ); + + if (!$emailSetting) { + $this->assertTrue($this->_webApiCall($serviceInfo, $requestData)); + } else { + $this->assertFalse($this->_webApiCall($serviceInfo, $requestData)); + } } public function testEmailAvailableInvalidEmail() diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php index eafed14b01ed3..5b1e59b39bd40 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php @@ -39,6 +39,7 @@ class ProductPriceTest extends GraphQlAbstract * @var LockCustomer */ private $lockCustomer; + private const EPSILON=2; protected function setUp(): void { @@ -1199,8 +1200,16 @@ private function assertPrices($expectedPrices, $actualPrices, $currency = 'USD') $expected['final_price']['currency'] ?? $currency, $actual['final_price']['currency'] ); - $this->assertEquals($expected['discount']['amount_off'], $actual['discount']['amount_off']); - $this->assertEquals($expected['discount']['percent_off'], $actual['discount']['percent_off']); + $this->assertEqualsWithDelta( + $expected['discount']['amount_off'], + $actual['discount']['amount_off'], + self::EPSILON + ); + $this->assertEqualsWithDelta( + $expected['discount']['percent_off'], + $actual['discount']['percent_off'], + self::EPSILON + ); } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/IsEmailAvailableTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/IsEmailAvailableTest.php index f0bd7dc1e854a..ca1bfdfa96108 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/IsEmailAvailableTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/IsEmailAvailableTest.php @@ -7,6 +7,11 @@ namespace Magento\GraphQl\Customer; +use Magento\Customer\Model\AccountManagement; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Api\StoreResolverInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; /** @@ -14,6 +19,25 @@ */ class IsEmailAvailableTest extends GraphQlAbstract { + /** + * @var ScopeConfigInterface|null + */ + private $scopeConfig; + + /** + * @var string|null + */ + private $storeId; + + public function setUp(): void + { + $objectManager = Bootstrap::getObjectManager(); + $this->scopeConfig = $objectManager->get(ScopeConfigInterface::class); + /* @var StoreResolverInterface $storeResolver */ + $storeResolver = $objectManager->get(StoreResolverInterface::class); + $this->storeId = $storeResolver->getCurrentStoreId(); + } + /** * @magentoApiDataFixture Magento/Customer/_files/customer.php */ @@ -31,7 +55,16 @@ public function testEmailNotAvailable() self::assertArrayHasKey('isEmailAvailable', $response); self::assertArrayHasKey('is_email_available', $response['isEmailAvailable']); - self::assertFalse($response['isEmailAvailable']['is_email_available']); + $emailConfig = $this->scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_STORE, + $this->storeId + ); + if (!$emailConfig) { + self::assertTrue($response['isEmailAvailable']['is_email_available']); + } else { + self::assertFalse($response['isEmailAvailable']['is_email_available']); + } } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Newsletter/Customer/SubscribeEmailToNewsletterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Newsletter/Customer/SubscribeEmailToNewsletterTest.php index ec0e49cc55153..17c18521f2a2c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Newsletter/Customer/SubscribeEmailToNewsletterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Newsletter/Customer/SubscribeEmailToNewsletterTest.php @@ -8,11 +8,14 @@ namespace Magento\GraphQl\Newsletter\Customer; use Exception; +use Magento\Customer\Model\AccountManagement; use Magento\Customer\Model\CustomerAuthUpdate; use Magento\Customer\Model\CustomerRegistry; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Exception\AuthenticationException; use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\Newsletter\Model\ResourceModel\Subscriber as SubscriberResourceModel; +use Magento\Store\Model\ScopeInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -40,6 +43,10 @@ class SubscribeEmailToNewsletterTest extends GraphQlAbstract * @var SubscriberResourceModel */ private $subscriberResource; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; /** * @inheritDoc @@ -47,6 +54,7 @@ class SubscribeEmailToNewsletterTest extends GraphQlAbstract protected function setUp(): void { $objectManager = Bootstrap::getObjectManager(); + $this->scopeConfig = $objectManager->get(ScopeConfigInterface::class); $this->customerAuthUpdate = Bootstrap::getObjectManager()->get(CustomerAuthUpdate::class); $this->customerRegistry = Bootstrap::getObjectManager()->get(CustomerRegistry::class); $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); @@ -146,10 +154,17 @@ public function testNewsletterSubscriptionWithAnotherCustomerEmail() { $query = $this->getQuery('customer2@search.example.com'); - $this->expectException(Exception::class); - $this->expectExceptionMessage('Cannot create a newsletter subscription.' . "\n"); - - $this->graphQlMutation($query, [], '', $this->getHeaderMap('customer@search.example.com')); + $guestLoginConfig = $this->scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + 1 + ); + + if ($guestLoginConfig) { + $this->expectException(Exception::class); + $this->expectExceptionMessage('Cannot create a newsletter subscription.' . "\n"); + $this->graphQlMutation($query, [], '', $this->getHeaderMap('customer@search.example.com')); + } } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/CartPromotionsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/CartPromotionsTest.php index 7df84c77bff04..e23d52a32581c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/CartPromotionsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/CartPromotionsTest.php @@ -23,6 +23,7 @@ */ class CartPromotionsTest extends GraphQlAbstract { + private const EPSILON=2; /** * Test adding single cart rule to multiple products in a cart * @@ -157,9 +158,10 @@ public function testCartPromotionsMultipleCartRules() $this->assertEquals('TestRule_Label', current($lineItemDiscount)['label']); $lineItemDiscountValue = next($lineItemDiscount)['amount']['value']; - $this->assertEquals( + $this->assertEqualsWithDelta( round($productsInCart[$itemIndex]->getSpecialPrice()*$qty*0.5)*0.1, - $lineItemDiscountValue + $lineItemDiscountValue, + self::EPSILON ); $this->assertEquals('10% off with two items_Label', end($lineItemDiscount)['label']); $actualTotalDiscountValue = $lineItemDiscount[0]['amount']['value']+$lineItemDiscount[1]['amount']['value']; diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/RemoveItemFromCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/RemoveItemFromCartTest.php index 2f64d0898c301..08c0237bf8dd5 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/RemoveItemFromCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/RemoveItemFromCartTest.php @@ -11,6 +11,7 @@ use Magento\GraphQl\Quote\GetQuoteItemIdByReservedQuoteIdAndSku; use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException; use Magento\TestFramework\TestCase\GraphQlAbstract; /** @@ -148,12 +149,56 @@ public function testRemoveItemFromAnotherCustomerCart() 'simple_product' ); - $this->expectExceptionMessage( - "The current user cannot perform operations on cart \"$anotherCustomerQuoteMaskedId\"" - ); - $query = $this->getQuery($anotherCustomerQuoteMaskedId, $anotherCustomerQuoteItemId); - $this->graphQlMutation($query, [], '', $this->getHeaderMap('customer2@search.example.com')); + + try { + $this->graphQlMutation( + $query, + [], + '', + $this->getHeaderMap('customer2@search.example.com') + ); + $this->fail('ResponseContainsErrorsException was not thrown'); + } catch (ResponseContainsErrorsException $e) { + $this->assertStringContainsString( + "The current user cannot perform operations on cart \"$anotherCustomerQuoteMaskedId\"", + $e->getMessage() + ); + $cartQuery = $this->getCartQuery($anotherCustomerQuoteMaskedId); + $cart = $this->graphQlQuery( + $cartQuery, + [], + '', + $this->getHeaderMap('customer@search.example.com') + ); + $this->assertTrue(count($cart['cart']['items']) > 0, 'The cart is empty'); + $this->assertTrue( + $cart['cart']['items'][0]['product']['sku'] === 'simple_product', + 'The cart doesn\'t contain product' + ); + } + } + + /** + * @param string $maskedQuoteId + * @return string + */ + private function getCartQuery(string $maskedQuoteId): string + { + return <<minimumErrorLevel) { $this->messages[] = [ @@ -77,6 +84,6 @@ public function addRecord( 'message' => $message, ]; } - return parent::addRecord($level, $message, $context); + return parent::addRecord($level, $message, $context, $datetime); } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php index 53ee4470eb9e3..b099abae60464 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php +++ b/dev/tests/integration/framework/Magento/TestFramework/MessageQueue/PublisherConsumerController.php @@ -12,9 +12,6 @@ use Magento\Framework\OsInfo; use Magento\TestFramework\Helper\Amqp; -/** - * Publisher Consumer Controller - */ class PublisherConsumerController { /** @@ -208,9 +205,9 @@ public function waitForAsynchronousResult(callable $condition, $params) { $i = 0; do { - sleep(1); + sleep(3); $assertion = call_user_func_array($condition, $params); - } while (!$assertion && ($i++ < 180)); + } while (!$assertion && ($i++ < 10)); if (!$assertion) { throw new PreconditionFailedException("No asynchronous messages were processed."); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Console/Command/ProductAttributesCleanUpTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Console/Command/ProductAttributesCleanUpTest.php index 9d3f11eb1247a..390ad01173882 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Console/Command/ProductAttributesCleanUpTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Console/Command/ProductAttributesCleanUpTest.php @@ -104,6 +104,7 @@ private function prepareAdditionalStore() $storeGroup = $this->objectManager->create(\Magento\Store\Model\Group::class); $storeGroup->setWebsiteId($website->getId()); $storeGroup->setName('Fixture Store Group'); + $storeGroup->setCode('fixturestoregroup'); $storeGroup->setRootCategoryId(2); $storeGroup->setDefaultStoreId($store->getId()); $storeGroup->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php index 5b9266dc11371..0e454a854d8ff 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php @@ -1,9 +1,9 @@ setData( - ['website_id' => 1, 'name' => 'New Store Group', 'root_category_id' => 2, 'group_id' => null] + [ + 'website_id' => 1, + 'name' => 'New Store Group', + 'root_category_id' => 2, + 'group_id' => null, + 'code' => 'newstoregroup' + ] ); $storeGroup->save(); $this->assertTrue($this->processor->getIndexer()->isInvalid()); diff --git a/dev/tests/integration/testsuite/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFilesTest.php b/dev/tests/integration/testsuite/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFilesTest.php index 3a0820c9fc829..2614169ad818b 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFilesTest.php +++ b/dev/tests/integration/testsuite/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFilesTest.php @@ -161,8 +161,6 @@ public function executeDataProvider(): array ['name with[ bracket.jpg'], ['magento_small_image.jpg'], ['_.jpg'], - [' - .jpg'], - ['-.jpg'], ]; } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php index de4a592f46c9e..b7c2dea1b5e02 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Api\AccountManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; use Magento\Customer\Api\Data\AddressInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\State\ExpiredException; @@ -16,6 +17,7 @@ use Magento\Framework\Session\SessionManagerInterface; use Magento\Framework\Stdlib\DateTime; use Magento\Framework\Url as UrlBuilder; +use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; @@ -331,7 +333,7 @@ public function testValidateResetPasswordLinkTokenExpired() public function testValidateResetPasswordLinkTokenInvalid() { $resetToken = 'lsdj579slkj5987slkj595lkj'; - $invalidToken = 0; + $invalidToken = '0'; $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s'); try { $this->accountManagement->validateResetPasswordLinkToken(1, $invalidToken); @@ -481,7 +483,7 @@ public function testResetPasswordTokenExpired() public function testResetPasswordTokenInvalid() { $resetToken = 'lsdj579slkj5987slkj595lkj'; - $invalidToken = 0; + $invalidToken = '0'; $password = 'new_Password123'; $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s'); @@ -604,7 +606,18 @@ public function testResendConfirmationNotNeeded() */ public function testIsEmailAvailable() { - $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com', 1)); + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $guestLoginConfig = $scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + 1 + ); + + if (!$guestLoginConfig) { + $this->assertTrue($this->accountManagement->isEmailAvailable('customer@example.com', 1)); + } else { + $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com', 1)); + } } /** @@ -612,7 +625,18 @@ public function testIsEmailAvailable() */ public function testIsEmailAvailableNoWebsiteSpecified() { - $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com')); + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $guestLoginConfig = $scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + 1 + ); + + if (!$guestLoginConfig) { + $this->assertTrue($this->accountManagement->isEmailAvailable('customer@example.com')); + } else { + $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com')); + } } /** diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Element/AbstractBlockTest.php b/dev/tests/integration/testsuite/Magento/Framework/View/Element/AbstractBlockTest.php index f584b8f7cfcd3..d886a9189502b 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/View/Element/AbstractBlockTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/View/Element/AbstractBlockTest.php @@ -26,6 +26,9 @@ class AbstractBlockTest extends \PHPUnit\Framework\TestCase */ protected $_layout = null; + /** + * @var array + */ protected static $_mocks = []; /** @@ -573,7 +576,7 @@ public function testGetCacheKey() $this->assertNotEquals($name, $key); $block->setCacheKey('key'); - $this->assertEquals(AbstractBlock::CACHE_KEY_PREFIX . 'key', $block->getCacheKey()); + $this->assertEquals(AbstractBlock::CUSTOM_CACHE_KEY_PREFIX . 'key', $block->getCacheKey()); } /** diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/Subscriber/NewActionTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/Subscriber/NewActionTest.php index fc1aad57e57e7..00445aa6978b4 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/Subscriber/NewActionTest.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/Subscriber/NewActionTest.php @@ -8,11 +8,14 @@ namespace Magento\Newsletter\Controller\Subscriber; use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\AccountManagement; use Magento\Customer\Model\Session; use Magento\Customer\Model\Url; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Request\Http as HttpRequest; use Magento\Newsletter\Model\ResourceModel\Subscriber as SubscriberResource; use Magento\Newsletter\Model\ResourceModel\Subscriber\CollectionFactory; +use Magento\Store\Model\ScopeInterface; use Magento\TestFramework\TestCase\AbstractController; use Laminas\Stdlib\Parameters; @@ -205,8 +208,18 @@ public function testWithEmailAssignedToAnotherCustomer(): void $this->session->loginById(1); $this->prepareRequest('customer2@search.example.com'); $this->dispatch('newsletter/subscriber/new'); + $scopeConfig = $this->_objectManager->get(ScopeConfigInterface::class); + $guestLoginConfig = $scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + 1 + ); - $this->performAsserts('This email address is already assigned to another user.'); + if ($guestLoginConfig) { + $this->performAsserts('This email address is already assigned to another user.'); + } else { + $this->performAsserts('This email address is already subscribed.'); + } } /** diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php index 9ebf3e98da69f..a6b7a42bc5a61 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteManagementTest.php @@ -34,6 +34,7 @@ * * @see \Magento\Quote\Model\QuoteManagement * @magentoDbIsolation enabled + * @magentoAppIsolation enabled * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class QuoteManagementTest extends TestCase @@ -196,7 +197,6 @@ public function testSubmitWithDeletedItem(): void $this->cartManagement->placeOrder($quote->getId()); } - /** * Tries to create order with product that has child items and one of them * was deleted when item data check is disabled on quote load. @@ -237,7 +237,11 @@ public function testSubmitWithItemOutOfStockWithDisabledInventoryCheck(): void { $this->makeProductOutOfStock('simple'); $quote = $this->getQuoteByReservedOrderId->execute('test01'); - $this->expectExceptionObject(new LocalizedException(__('The shipping method is missing. Select the shipping method and try again.'))); + $this->expectExceptionObject( + new LocalizedException( + __('The shipping method is missing. Select the shipping method and try again.') + ) + ); $this->cartManagement->placeOrder($quote->getId()); } diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php index 7bda40c440628..00a8307c126a7 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php @@ -32,7 +32,7 @@ * Tests for quote model. * * @see \Magento\Quote\Model\Quote - * + * @magentoAppIsolation enabled * @magentoDbIsolation enabled * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php index e938945f2c411..3479201179d7d 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php @@ -32,6 +32,7 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Quote\Model\GetQuoteByReservedOrderId; use PHPUnit\Framework\TestCase; +use Magento\Customer\Model\Session; /** * Test for shipping methods management @@ -319,10 +320,16 @@ public function testEstimateByAddressWithInclExclTaxAndVATGroup() $this->changeCustomerAddress($customer->getDefaultShipping()); $quote = $this->objectManager->get(GetQuoteByReservedOrderId::class)->execute('test01'); + $addressRepository = $this->objectManager->get(AddressRepositoryInterface::class); + $address = $addressRepository->getById(1); + $address->setIsDefaultShipping(true); + $customer->setAddresses([$address]); + $customerSession = $this->objectManager->get(Session::class); + $customerSession->loginById($customer->getId()); /** @var ShippingMethodManagementInterface $shippingEstimation */ $shippingEstimation = $this->objectManager->get(ShippingMethodManagementInterface::class); - $result = $shippingEstimation->estimateByAddressId($quote->getId(), $customer->getDefaultShipping()); + $result = $shippingEstimation->estimateByAddressId($quote->getId(), (int)$customer->getDefaultShipping()); $this->assertEquals(6.05, $result[0]->getPriceInclTax()); $this->assertEquals(5.0, $result[0]->getPriceExclTax()); diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Action/Discount/CartFixedTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Action/Discount/CartFixedTest.php index 2dbba66604869..30f7c60d5f497 100644 --- a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Action/Discount/CartFixedTest.php +++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Rule/Action/Discount/CartFixedTest.php @@ -47,6 +47,11 @@ */ class CartFixedTest extends TestCase { + /** + * @var float + */ + private const EPSILON = 0.0000000001; + /** * @var GuestCartManagementInterface */ @@ -521,11 +526,11 @@ public function testDiscountsWhenByPercentRuleAppliedFirstAndCartFixedRuleSecond $item = array_shift($items); $this->assertEquals('simple1', $item->getSku()); $this->assertEquals(5.99, $item->getPrice()); - $this->assertEquals($expectedDiscounts[$item->getSku()], $item->getDiscountAmount()); + $this->assertEqualsWithDelta($expectedDiscounts[$item->getSku()], $item->getDiscountAmount(), self::EPSILON); $item = array_shift($items); $this->assertEquals('simple2', $item->getSku()); $this->assertEquals(15.99, $item->getPrice()); - $this->assertEquals($expectedDiscounts[$item->getSku()], $item->getDiscountAmount()); + $this->assertEqualsWithDelta($expectedDiscounts[$item->getSku()], $item->getDiscountAmount(), self::EPSILON); } public function discountByPercentDataProvider() diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php index a119b6259b5f6..f3b43d9f2cca2 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php @@ -23,6 +23,11 @@ */ class TaxTest extends \Magento\TestFramework\Indexer\TestCase { + /** + * @var float + */ + private const EPSILON = 0.0000000001; + /** * Utility object for setting up tax rates, tax classes and tax rules * @@ -176,7 +181,7 @@ public function testFullDiscountWithDeltaRoundingFix() protected function verifyItem($item, $expectedItemData) { foreach ($expectedItemData as $key => $value) { - $this->assertEquals($value, $item->getData($key), 'item ' . $key . ' is incorrect'); + $this->assertEqualsWithDelta($value, $item->getData($key), self::EPSILON, 'item ' . $key . ' is incorrect'); } return $this; @@ -247,7 +252,12 @@ protected function verifyQuoteAddress($quoteAddress, $expectedAddressData) if ($key == 'applied_taxes') { $this->verifyAppliedTaxes($quoteAddress->getAppliedTaxes(), $value); } else { - $this->assertEquals($value, $quoteAddress->getData($key), 'Quote address ' . $key . ' is incorrect'); + $this->assertEqualsWithDelta( + $value, + $quoteAddress->getData($key), + self::EPSILON, + 'Quote address ' . $key . ' is incorrect' + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php index 604a444883a26..fde67cc7c2094 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php @@ -16,15 +16,16 @@ class TaxCalculationTest extends \PHPUnit\Framework\TestCase { /** - * Object Manager - * + * @var float + */ + private const EPSILON = 0.0000000001; + + /** * @var \Magento\Framework\ObjectManagerInterface */ private $objectManager; /** - * Tax calculation service - * * @var \Magento\Tax\Api\TaxCalculationInterface */ private $taxCalculationService; @@ -108,7 +109,7 @@ public function testCalculateTaxUnitBased($quoteDetailsData, $expected) ); $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails, 1); - $this->assertEquals($expected, $this->convertObjectToArray($taxDetails)); + $this->assertEqualsWithDelta($expected, $this->convertObjectToArray($taxDetails), self::EPSILON); } /** @@ -1286,7 +1287,7 @@ public function testCalculateTaxRowBased($quoteDetailsData, $expectedTaxDetails) $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails); - $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails)); + $this->assertEqualsWithDelta($expectedTaxDetails, $this->convertObjectToArray($taxDetails), self::EPSILON); } /** @@ -2387,7 +2388,11 @@ public function testMultiRulesRowBased($quoteDetailsData, $expectedTaxDetails) $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails); - $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails)); + $this->assertEqualsWithDelta( + $expectedTaxDetails, + $this->convertObjectToArray($taxDetails), + self::EPSILON + ); } /** @@ -2424,7 +2429,7 @@ public function testMultiRulesTotalBased($quoteDetailsData, $expectedTaxDetails) $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails); - $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails)); + $this->assertEqualsWithDelta($expectedTaxDetails, $this->convertObjectToArray($taxDetails), self::EPSILON); } /** @@ -2471,7 +2476,7 @@ public function testMultiRulesUnitBased($quoteDetailsData, $expectedTaxDetails) $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails); - $this->assertEquals($expectedTaxDetails, $this->convertObjectToArray($taxDetails)); + $this->assertEqualsWithDelta($expectedTaxDetails, $this->convertObjectToArray($taxDetails), self::EPSILON); } /** diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/Magento/Payment/MethodsTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/Magento/Payment/MethodsTest.php index eb5c66cc9c777..773b90b8ba2e5 100644 --- a/dev/tests/integration/testsuite/Magento/Test/Integrity/Magento/Payment/MethodsTest.php +++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/Magento/Payment/MethodsTest.php @@ -26,7 +26,16 @@ class MethodsTest extends \PHPUnit\Framework\TestCase */ public function testPaymentMethod($code, $methodClass) { - if (in_array($code, ['free', 'substitution', 'vault', 'payflowpro_cc_vault', 'fake_vault'])) { + $skipBlockTemplates = [ + 'free', + 'substitution', + 'vault', + 'payflowpro_cc_vault', + 'fake_vault', + 'braintree_cc_vault', + 'braintree_paypal_vault' + ]; + if (in_array($code, $skipBlockTemplates)) { return; } Bootstrap::getObjectManager()->configure($this->getTestConfiguration()); diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php index 0cedcca254f80..5758d523876b7 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php @@ -14,13 +14,13 @@ use Magento\Framework\HTTP\AsyncClient\Response; use Magento\Framework\HTTP\AsyncClientInterface; use Magento\Quote\Model\Quote\Address\RateRequest; +use Magento\Quote\Model\Quote\Address\RateRequestFactory; use Magento\Quote\Model\Quote\Address\RateResult\Error; +use Magento\Shipping\Model\Shipment\Request; use Magento\TestFramework\Helper\Bootstrap; -use Magento\Quote\Model\Quote\Address\RateRequestFactory; use Magento\TestFramework\HTTP\AsyncClientInterfaceMock; -use PHPUnit\Framework\TestCase; use PHPUnit\Framework\MockObject\MockObject; -use Magento\Shipping\Model\Shipment\Request; +use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; /** @@ -113,29 +113,54 @@ public function testGetShipConfirmUrlLive() } /** - * Collect free rates. + * Collect rates for UPS Ground method. * * @magentoConfigFixture current_store carriers/ups/active 1 - * @magentoConfigFixture current_store carriers/ups/type UPS - * @magentoConfigFixture current_store carriers/ups/allowed_methods 1DA,GND - * @magentoConfigFixture current_store carriers/ups/free_method GND + * @magentoConfigFixture current_store carriers/ups/type UPS_XML + * @magentoConfigFixture current_store carriers/ups/allowed_methods 03 + * @magentoConfigFixture current_store carriers/ups/free_method 03 + * @magentoConfigFixture default_store carriers/ups/shipper_number 12345 + * @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the United States + * @magentoConfigFixture default_store carriers/ups/username user + * @magentoConfigFixture default_store carriers/ups/password pass + * @magentoConfigFixture default_store carriers/ups/access_license_number acn + * @magentoConfigFixture default_store carriers/ups/debug 1 + * @magentoConfigFixture default_store currency/options/allow USD,EUR + * @magentoConfigFixture default_store currency/options/base USD */ public function testCollectFreeRates() { - $rateRequest = Bootstrap::getObjectManager()->get(RateRequestFactory::class)->create(); - $rateRequest->setDestCountryId('US'); - $rateRequest->setDestRegionId('CA'); - $rateRequest->setDestPostcode('90001'); - $rateRequest->setPackageQty(1); - $rateRequest->setPackageWeight(1); - $rateRequest->setFreeMethodWeight(0); - $rateRequest->setLimitCarrier($this->carrier::CODE); - $rateRequest->setFreeShipping(true); - $rateResult = $this->carrier->collectRates($rateRequest); - $result = $rateResult->asArray(); - $methods = $result[$this->carrier::CODE]['methods']; - $this->assertEquals(0, $methods['GND']['price']); - $this->assertNotEquals(0, $methods['1DA']['price']); + $request = Bootstrap::getObjectManager()->create( + RateRequest::class, + [ + 'data' => [ + 'dest_country' => 'US', + 'dest_postal' => '90001', + 'package_weight' => '1', + 'package_qty' => '1', + 'free_method_weight' => '5', + 'product' => '11', + 'action' => 'Rate', + 'unit_measure' => 'KGS', + 'free_shipping' => '1', + 'base_currency' => new DataObject(['code' => 'USD']) + ] + ] + ); + //phpcs:disable Magento2.Functions.DiscouragedFunction + $this->httpClient->nextResponses( + [ + new Response( + 200, + [], + file_get_contents(__DIR__ . "/../_files/ups_rates_response_option9.xml") + ) + ] + ); + + $rates = $this->carrier->collectRates($request)->getAllRates(); + $this->assertEquals('19.19', $rates[0]->getPrice()); + $this->assertEquals('03', $rates[0]->getMethod()); } /** @@ -181,7 +206,7 @@ public function testCollectRates(int $negotiable, int $tax, int $responseId, str new Response( 200, [], - file_get_contents(__DIR__ ."/../_files/ups_rates_response_option$responseId.xml") + file_get_contents(__DIR__ . "/../_files/ups_rates_response_option$responseId.xml") ) ] ); @@ -245,9 +270,9 @@ public function collectRatesDataProvider() public function testRequestToShipment(): void { //phpcs:disable Magento2.Functions.DiscouragedFunction - $expectedShipmentRequest = file_get_contents(__DIR__ .'/../_files/ShipmentConfirmRequest.xml'); - $shipmentResponse = file_get_contents(__DIR__ .'/../_files/ShipmentConfirmResponse.xml'); - $acceptResponse = file_get_contents(__DIR__ .'/../_files/ShipmentAcceptResponse.xml'); + $expectedShipmentRequest = file_get_contents(__DIR__ . '/../_files/ShipmentConfirmRequest.xml'); + $shipmentResponse = file_get_contents(__DIR__ . '/../_files/ShipmentConfirmResponse.xml'); + $acceptResponse = file_get_contents(__DIR__ . '/../_files/ShipmentAcceptResponse.xml'); //phpcs:enable Magento2.Functions.DiscouragedFunction $this->httpClient->nextResponses( [ diff --git a/dev/tests/integration/testsuite/Magento/Ups/_files/ups_rates_response_option9.xml b/dev/tests/integration/testsuite/Magento/Ups/_files/ups_rates_response_option9.xml new file mode 100644 index 0000000000000..2e5c4bc0ddbfd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ups/_files/ups_rates_response_option9.xml @@ -0,0 +1,299 @@ + + + + + + Rating and Service + 1.0 + + 1 + Success + + + + 12 + + Your invoice may vary from the displayed reference rates + + + LBS + + 20.0 + + + USD + 43.19 + + + USD + 0.00 + + + USD + 43.19 + + 3 + + + + USD + 43.19 + + + USD + 0.00 + + + USD + 43.19 + + 20.0 + + + LBS + + 20.0 + + + + + + 14 + + Your invoice may vary from the displayed reference rates + + + LBS + + 20.0 + + + USD + 122.34 + + + USD + 0.00 + + + USD + 122.34 + + 1 + 8:00 A.M. + + + USD + 122.34 + + + USD + 0.00 + + + USD + 122.34 + + 20.0 + + + LBS + + 20.0 + + + + + + 03 + + Your invoice may vary from the displayed reference rates + + + LBS + + 20.0 + + + USD + 19.19 + + + USD + 0.00 + + + USD + 19.19 + + + + + + USD + 19.19 + + + USD + 0.00 + + + USD + 19.19 + + 20.0 + + + LBS + + 20.0 + + + + + + 13 + + Your invoice may vary from the displayed reference rates + + + LBS + + 20.0 + + + USD + 82.24 + + + USD + 0.00 + + + USD + 82.24 + + 1 + + + + USD + 82.24 + + + USD + 0.00 + + + USD + 82.24 + + 20.0 + + + LBS + + 20.0 + + + + + + 01 + + Your invoice may vary from the displayed reference rates + + + LBS + + 20.0 + + + USD + 88.14 + + + USD + 0.00 + + + USD + 88.14 + + 1 + 10:30 A.M. + + + USD + 88.14 + + + USD + 0.00 + + + USD + 88.14 + + 20.0 + + + LBS + + 20.0 + + + + + + 02 + + Your invoice may vary from the displayed reference rates + + + LBS + + 20.0 + + + USD + 57.11 + + + USD + 0.00 + + + USD + 57.11 + + 2 + + + + USD + 57.11 + + + USD + 0.00 + + + USD + 57.11 + + 20.0 + + + LBS + + 20.0 + + + + diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10427.php new file mode 100644 index 0000000000000..f00c9a1eb08c4 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10427.php @@ -0,0 +1,59 @@ + 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'reference_table' => 'CREATE TABLE `reference_table` ( + `tinyint_ref` tinyint(4) NOT NULL AUTO_INCREMENT, + `tinyint_without_padding` tinyint(4) NOT NULL DEFAULT 0, + `bigint_without_padding` bigint(20) NOT NULL DEFAULT 0, + `smallint_without_padding` smallint(6) NOT NULL DEFAULT 0, + `integer_without_padding` int(11) NOT NULL DEFAULT 0, + `smallint_with_big_padding` smallint(6) NOT NULL DEFAULT 0, + `smallint_without_default` smallint(6) DEFAULT NULL, + `int_without_unsigned` int(11) DEFAULT NULL, + `int_unsigned` int(10) unsigned DEFAULT NULL, + `bigint_default_nullable` bigint(20) unsigned DEFAULT 1, + `bigint_not_default_not_nullable` bigint(20) unsigned NOT NULL, + `smallint_ref` smallint(6) NOT NULL DEFAULT 0, + PRIMARY KEY (`tinyint_ref`,`smallint_ref`), + UNIQUE KEY `REFERENCE_TABLE_SMALLINT_REF` (`smallint_ref`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'test_table' => 'CREATE TABLE `test_table` ( + `smallint` smallint(6) DEFAULT NULL, + `tinyint` tinyint(4) DEFAULT NULL, + `bigint` bigint(20) DEFAULT 0, + `float` float(12,10) DEFAULT 0.0000000000, + `double` double(245,10) DEFAULT 11111111.1111110000, + `decimal` decimal(15,4) DEFAULT 0.0000, + `date` date DEFAULT NULL, + `timestamp` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `datetime` datetime DEFAULT \'0000-00-00 00:00:00\', + `longtext` longtext DEFAULT NULL, + `mediumtext` mediumtext DEFAULT NULL, + `varchar` varchar(254) DEFAULT NULL, + `char` char(255) DEFAULT NULL, + `mediumblob` mediumblob DEFAULT NULL, + `blob` blob DEFAULT NULL, + `boolean` tinyint(1) DEFAULT NULL, + `integer_main` int(10) unsigned DEFAULT NULL, + `smallint_main` smallint(6) NOT NULL DEFAULT 0, + 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 COLLATE=utf8_general_ci', +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mysql829.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mysql829.php new file mode 100644 index 0000000000000..65a70da8d660c --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mysql829.php @@ -0,0 +1,59 @@ + 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint unsigned DEFAULT \'0\', + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3', + 'reference_table' => 'CREATE TABLE `reference_table` ( + `tinyint_ref` tinyint NOT NULL AUTO_INCREMENT, + `tinyint_without_padding` tinyint NOT NULL DEFAULT \'0\', + `bigint_without_padding` bigint NOT NULL DEFAULT \'0\', + `smallint_without_padding` smallint NOT NULL DEFAULT \'0\', + `integer_without_padding` int NOT NULL DEFAULT \'0\', + `smallint_with_big_padding` smallint NOT NULL DEFAULT \'0\', + `smallint_without_default` smallint DEFAULT NULL, + `int_without_unsigned` int DEFAULT NULL, + `int_unsigned` int unsigned DEFAULT NULL, + `bigint_default_nullable` bigint unsigned DEFAULT \'1\', + `bigint_not_default_not_nullable` bigint unsigned NOT NULL, + `smallint_ref` smallint NOT NULL DEFAULT \'0\', + PRIMARY KEY (`tinyint_ref`,`smallint_ref`), + UNIQUE KEY `REFERENCE_TABLE_SMALLINT_REF` (`smallint_ref`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3', + 'test_table' => 'CREATE TABLE `test_table` ( + `smallint` smallint DEFAULT NULL, + `tinyint` tinyint DEFAULT NULL, + `bigint` bigint DEFAULT \'0\', + `float` float(12,10) DEFAULT \'0.0000000000\', + `double` double(245,10) DEFAULT \'11111111.1111110000\', + `decimal` decimal(15,4) DEFAULT \'0.0000\', + `date` date DEFAULT NULL, + `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `datetime` datetime DEFAULT \'0000-00-00 00:00:00\', + `longtext` longtext, + `mediumtext` mediumtext, + `varchar` varchar(254) DEFAULT NULL, + `char` char(255) DEFAULT NULL, + `mediumblob` mediumblob, + `blob` blob, + `boolean` tinyint(1) DEFAULT NULL, + `integer_main` int unsigned DEFAULT NULL, + `smallint_main` smallint NOT NULL DEFAULT \'0\', + 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=utf8mb3', +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10427.php new file mode 100644 index 0000000000000..45cb5f6938b41 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10427.php @@ -0,0 +1,27 @@ + [ + 'store' => 'CREATE TABLE `store` ( + `store_owner_id` smallint(6) DEFAULT NULL COMMENT \'Store Owner Reference\', + 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 COLLATE=utf8_general_ci', + 'store_owner' => 'CREATE TABLE `store_owner` ( + `owner_id` smallint(6) NOT NULL AUTO_INCREMENT, + `store_owner_name` varchar(255) DEFAULT NULL COMMENT \'Store Owner Name\', + PRIMARY KEY (`owner_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT=\'Store owner information\'' + ], + 'after' => [ + 'store' => 'CREATE TABLE `store` ( + `store_owner` varchar(255) DEFAULT NULL COMMENT \'Store Owner Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' + ] +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mysql829.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mysql829.php new file mode 100644 index 0000000000000..57b70edd9e3f2 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mysql829.php @@ -0,0 +1,27 @@ + [ + 'store' => 'CREATE TABLE `store` ( + `store_owner_id` smallint DEFAULT NULL COMMENT \'Store Owner Reference\', + 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=utf8mb3', + 'store_owner' => 'CREATE TABLE `store_owner` ( + `owner_id` smallint NOT NULL AUTO_INCREMENT, + `store_owner_name` varchar(255) DEFAULT NULL COMMENT \'Store Owner Name\', + PRIMARY KEY (`owner_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT=\'Store owner information\'' + ], + 'after' => [ + 'store' => 'CREATE TABLE `store` ( + `store_owner` varchar(255) DEFAULT NULL COMMENT \'Store Owner Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3' + ] +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10427.php new file mode 100644 index 0000000000000..bc469f23f6e2b --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10427.php @@ -0,0 +1,14 @@ + 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mysql829.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mysql829.php new file mode 100644 index 0000000000000..9ca6fcbc22751 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mysql829.php @@ -0,0 +1,14 @@ + 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint unsigned DEFAULT \'0\', + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10427.php new file mode 100644 index 0000000000000..3c62923cf256f --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10427.php @@ -0,0 +1,15 @@ + 'CREATE TABLE `some_table` ( + `some_column` varchar(255) DEFAULT NULL COMMENT \'Some Column Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'after' => 'CREATE TABLE `some_table_renamed` ( + `some_column` varchar(255) DEFAULT NULL COMMENT \'Some Column Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mysql829.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mysql829.php new file mode 100644 index 0000000000000..cb8f53d499a50 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mysql829.php @@ -0,0 +1,15 @@ + 'CREATE TABLE `some_table` ( + `some_column` varchar(255) DEFAULT NULL COMMENT \'Some Column Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3', + 'after' => 'CREATE TABLE `some_table_renamed` ( + `some_column` varchar(255) DEFAULT NULL COMMENT \'Some Column Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3', +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.mysql829.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.mysql829.php new file mode 100644 index 0000000000000..4d49221074315 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.mysql829.php @@ -0,0 +1,58 @@ + 'CREATE TABLE `test_table_one` ( + `smallint` smallint(6) NOT NULL AUTO_INCREMENT, + `varchar` varchar(254) DEFAULT NULL, + PRIMARY KEY (`smallint`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'test_table_two' => 'CREATE TABLE `test_table_two` ( + `smallint` smallint(6) NOT NULL AUTO_INCREMENT, + `varchar` varchar(254) DEFAULT NULL, + PRIMARY KEY (`smallint`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'reference_table' => 'CREATE TABLE `reference_table` ( + `tinyint_ref` tinyint(4) NOT NULL AUTO_INCREMENT, + `tinyint_without_padding` tinyint(4) NOT NULL DEFAULT 0, + `bigint_without_padding` bigint(20) NOT NULL DEFAULT 0, + `smallint_without_padding` smallint(6) NOT NULL DEFAULT 0, + `integer_without_padding` int(11) NOT NULL DEFAULT 0, + `smallint_with_big_padding` smallint(6) NOT NULL DEFAULT 0, + `smallint_without_default` smallint(6) DEFAULT NULL, + `int_without_unsigned` int(11) DEFAULT NULL, + `int_unsigned` int(10) unsigned DEFAULT NULL, + `bigint_default_nullable` bigint(20) unsigned DEFAULT 1, + `bigint_not_default_not_nullable` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`tinyint_ref`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mysql829.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mysql829.php new file mode 100644 index 0000000000000..2507abeef2994 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mysql829.php @@ -0,0 +1,38 @@ + 'CREATE TABLE `test_table_one` ( + `smallint` smallint NOT NULL AUTO_INCREMENT, + `varchar` varchar(254) DEFAULT NULL, + PRIMARY KEY (`smallint`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3', + 'test_table_two' => 'CREATE TABLE `test_table_two` ( + `smallint` smallint NOT NULL AUTO_INCREMENT, + `varchar` varchar(254) DEFAULT NULL, + PRIMARY KEY (`smallint`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3', + 'reference_table' => 'CREATE TABLE `reference_table` ( + `tinyint_ref` tinyint NOT NULL AUTO_INCREMENT, + `tinyint_without_padding` tinyint NOT NULL DEFAULT \'0\', + `bigint_without_padding` bigint NOT NULL DEFAULT \'0\', + `smallint_without_padding` smallint NOT NULL DEFAULT \'0\', + `integer_without_padding` int NOT NULL DEFAULT \'0\', + `smallint_with_big_padding` smallint NOT NULL DEFAULT \'0\', + `smallint_without_default` smallint DEFAULT NULL, + `int_without_unsigned` int DEFAULT NULL, + `int_unsigned` int unsigned DEFAULT NULL, + `bigint_default_nullable` bigint unsigned DEFAULT \'1\', + `bigint_not_default_not_nullable` bigint unsigned NOT NULL, + PRIMARY KEY (`tinyint_ref`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3', + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint unsigned DEFAULT \'0\', + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10427.php new file mode 100644 index 0000000000000..bc469f23f6e2b --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10427.php @@ -0,0 +1,14 @@ + 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mysql829.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mysql829.php new file mode 100644 index 0000000000000..9ca6fcbc22751 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mysql829.php @@ -0,0 +1,14 @@ + 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint unsigned DEFAULT \'0\', + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3' +]; diff --git a/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/DataProviderFromFile.php b/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/DataProviderFromFile.php index b7c45b628b44b..c43c4f483531a 100644 --- a/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/DataProviderFromFile.php +++ b/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/DataProviderFromFile.php @@ -20,14 +20,16 @@ class DataProviderFromFile /** * @var string */ - const FALLBACK_VALUE = 'default'; + public const FALLBACK_VALUE = 'default'; /** * @var array */ - const POSSIBLE_SUFFIXES = [ + public const POSSIBLE_SUFFIXES = [ SqlVersionProvider::MYSQL_8_0_VERSION => 'mysql8', SqlVersionProvider::MARIA_DB_10_VERSION => 'mariadb10', + SqlVersionProvider::MYSQL_8_0_29_VERSION => 'mysql829', + SqlVersionProvider::MARIA_DB_10_4_27_VERSION => 'mariadb10427' ]; /** diff --git a/dev/tests/setup-integration/framework/Magento/TestFramework/TestCase/SetupTestCase.php b/dev/tests/setup-integration/framework/Magento/TestFramework/TestCase/SetupTestCase.php index 95f7e5b463160..6db21ba5b591b 100644 --- a/dev/tests/setup-integration/framework/Magento/TestFramework/TestCase/SetupTestCase.php +++ b/dev/tests/setup-integration/framework/Magento/TestFramework/TestCase/SetupTestCase.php @@ -7,10 +7,12 @@ namespace Magento\TestFramework\TestCase; +use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\ConnectionException; use Magento\Framework\DB\Adapter\SqlVersionProvider; use Magento\TestFramework\Annotation\DataProviderFromFile; use Magento\TestFramework\Helper\Bootstrap; +use Zend_Db_Statement_Exception; /** * Instance of Setup test case. Used in order to tweak dataProviders functionality. @@ -32,17 +34,25 @@ class SetupTestCase extends \PHPUnit\Framework\TestCase implements MutableDataIn */ private $sqlVersionProvider; + /** + * @var ResourceConnection + */ + private ResourceConnection $resourceConnection; + /** * @inheritDoc */ public function __construct( $name = null, array $data = [], - $dataName = '' + $dataName = '', + ResourceConnection $resourceConnection = null ) { parent::__construct($name, $data, $dataName); - $this->sqlVersionProvider = Bootstrap::getObjectManager()->get(SqlVersionProvider::class); + $objectManager = Bootstrap::getObjectManager(); + $this->sqlVersionProvider = $objectManager->get(SqlVersionProvider::class); + $this->resourceConnection = $resourceConnection ?? $objectManager->get(ResourceConnection::class); } /** @@ -97,7 +107,13 @@ private function getDbKey(): string $this->dbKey = DataProviderFromFile::FALLBACK_VALUE; foreach (DataProviderFromFile::POSSIBLE_SUFFIXES as $possibleVersion => $suffix) { - if (strpos($this->getDatabaseVersion(), (string)$possibleVersion) !== false) { + if ($this->sqlVersionProvider->isMysqlGte8029()) { + $this->dbKey = DataProviderFromFile::POSSIBLE_SUFFIXES[SqlVersionProvider::MYSQL_8_0_29_VERSION]; + break; + } elseif ($this->sqlVersionProvider->isMariaDBGte10427()) { + $this->dbKey = DataProviderFromFile::POSSIBLE_SUFFIXES[SqlVersionProvider::MARIA_DB_10_4_27_VERSION]; + break; + } elseif (strpos($this->getDatabaseVersion(), (string)$possibleVersion) !== false) { $this->dbKey = $suffix; break; } @@ -105,4 +121,20 @@ private function getDbKey(): string return $this->dbKey; } + + /** + * Checks if the DB connection Aurora RDS + * + * @param string $resource + * @return bool + */ + public function isUsingAuroraDb(string $resource = ResourceConnection::DEFAULT_CONNECTION): bool + { + try { + $this->resourceConnection->getConnection($resource)->query('SELECT AURORA_VERSION();'); + return true; + } catch (Zend_Db_Statement_Exception $e) { + return false; + } + } } diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php index e88d47a02c0d8..3a5e03fbff642 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/DeclarativeInstallerTest.php @@ -216,7 +216,7 @@ public function testInstallationWithConstraintsModification() ); self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getTrimmedData(), $shardData); + $this->assertTableCreationStatements($this->getTrimmedData(), $shardData); } /** @@ -246,7 +246,7 @@ public function testInstallationWithDroppingTables() ); self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getData(), $shardData); + $this->assertTableCreationStatements($this->getData(), $shardData); } /** @@ -305,6 +305,10 @@ public function testInstallWithCodeBaseRollback() $this->cliCommand->install( ['Magento_TestSetupDeclarationModule1'] ); + + if ($this->isUsingAuroraDb()) { + $this->markTestSkipped('Test skipped in AWS Aurora'); + } $beforeRollback = $this->describeTable->describeShard('default'); self::assertEquals($this->getTrimmedData()['before'], $beforeRollback); //Move db_schema.xml file and tried to install @@ -344,7 +348,9 @@ public function testTableRename() $this->resourceConnection->getTableName('some_table'), $dataToMigrate ); - self::assertEquals($this->getData()['before'], $before['some_table']); + $this->isUsingAuroraDb() ? + $this->assertStringContainsString($before['some_table'], $this->getTrimmedData()['before']) : + $this->assertEquals($this->getData()['before'], $before['some_table']); //Move db_schema.xml file and tried to install $this->moduleManager->updateRevision( 'Magento_TestSetupDeclarationModule1', @@ -355,7 +361,9 @@ public function testTableRename() $this->cliCommand->upgrade(); $after = $this->describeTable->describeShard('default'); - self::assertEquals($this->getData()['after'], $after['some_table_renamed']); + $this->isUsingAuroraDb() ? + $this->assertStringContainsString($after['some_table_renamed'], $this->getTrimmedData()['after']) : + $this->assertEquals($this->getData()['after'], $after['some_table_renamed']); $select = $adapter->select() ->from($this->resourceConnection->getTableName('some_table_renamed')); self::assertEquals([$dataToMigrate], $adapter->fetchAll($select)); @@ -459,6 +467,26 @@ public function testInstallationWithDisablingTables() ); self::assertNull($diff->getAll()); $shardData = $this->describeTable->describeShard(Sharding::DEFAULT_CONNECTION); - self::assertEquals($this->getData(), $shardData); + $this->assertTableCreationStatements($this->getData(), $shardData); + } + + /** + * Assert table creation statements + * + * @param array $expectedData + * @param array $actualData + */ + private function assertTableCreationStatements(array $expectedData, array $actualData): void + { + if (!$this->isUsingAuroraDb()) { + $this->assertEquals($expectedData, $actualData); + } else { + ksort($expectedData); + ksort($actualData); + $this->assertSameSize($expectedData, $actualData); + foreach ($expectedData as $key => $value) { + $this->assertStringContainsString($actualData[$key], $value); + } + } } } diff --git a/dev/tests/setup-integration/testsuite/Magento/Setup/ShardingTest.php b/dev/tests/setup-integration/testsuite/Magento/Setup/ShardingTest.php index ed219fb89a56f..3ee7d3a266359 100644 --- a/dev/tests/setup-integration/testsuite/Magento/Setup/ShardingTest.php +++ b/dev/tests/setup-integration/testsuite/Magento/Setup/ShardingTest.php @@ -78,7 +78,7 @@ public function testInstall() self::assertCount(2, $default); self::assertCount(1, $shard1); self::assertCount(1, $shard2); - self::assertEquals($this->getData(), array_replace($default, $shard1, $shard2)); + $this->assertTableCreationStatements($this->getData(), array_replace($default, $shard1, $shard2)); } /** @@ -99,6 +99,26 @@ public function testUpgrade() self::assertCount(2, $default); self::assertCount(1, $shard1); self::assertCount(1, $shard2); - self::assertEquals($this->getData(), array_replace($default, $shard1, $shard2)); + $this->assertTableCreationStatements($this->getData(), array_replace($default, $shard1, $shard2)); + } + + /** + * Assert table creation statements + * + * @param array $expectedData + * @param array $actualData + */ + private function assertTableCreationStatements(array $expectedData, array $actualData): void + { + if (!$this->isUsingAuroraDb()) { + $this->assertEquals($expectedData, $actualData); + } else { + ksort($expectedData); + ksort($actualData); + $this->assertSameSize($expectedData, $actualData); + foreach ($expectedData as $key => $value) { + $this->assertStringContainsString($actualData[$key], $value); + } + } } } diff --git a/lib/internal/GnuFreeFont/gpl-3.0.txt b/lib/internal/GnuFreeFont/gpl-3.0.txt new file mode 100644 index 0000000000000..f288702d2fa16 --- /dev/null +++ b/lib/internal/GnuFreeFont/gpl-3.0.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/lib/internal/Magento/Framework/Amqp/Config.php b/lib/internal/Magento/Framework/Amqp/Config.php index 44e033f4a7b80..3769ed51f73e9 100644 --- a/lib/internal/Magento/Framework/Amqp/Config.php +++ b/lib/internal/Magento/Framework/Amqp/Config.php @@ -23,20 +23,20 @@ class Config /** * Queue config key */ - const QUEUE_CONFIG = 'queue'; + public const QUEUE_CONFIG = 'queue'; /** * Amqp config key */ - const AMQP_CONFIG = 'amqp'; + public const AMQP_CONFIG = 'amqp'; - const HOST = 'host'; - const PORT = 'port'; - const USERNAME = 'user'; - const PASSWORD = 'password'; - const VIRTUALHOST = 'virtualhost'; - const SSL = 'ssl'; - const SSL_OPTIONS = 'ssl_options'; + public const HOST = 'host'; + public const PORT = 'port'; + public const USERNAME = 'user'; + public const PASSWORD = 'password'; + public const VIRTUALHOST = 'virtualhost'; + public const SSL = 'ssl'; + public const SSL_OPTIONS = 'ssl_options'; /** * Deployment configuration @@ -140,7 +140,7 @@ public function getValue($key) */ private function createConnection(): AbstractConnection { - $sslEnabled = trim($this->getValue(self::SSL)) === 'true'; + $sslEnabled = $this->getValue(self::SSL) && trim($this->getValue(self::SSL)) === 'true'; $options = new FactoryOptions(); $options->setHost($this->getValue(self::HOST)); $options->setPort($this->getValue(self::PORT)); diff --git a/lib/internal/Magento/Framework/Amqp/composer.json b/lib/internal/Magento/Framework/Amqp/composer.json index 5727ccb3eaa83..722127a704235 100644 --- a/lib/internal/Magento/Framework/Amqp/composer.json +++ b/lib/internal/Magento/Framework/Amqp/composer.json @@ -1,25 +1,27 @@ { "name": "magento/framework-amqp", "description": "N/A", - "config": { - "sort-packages": true - }, "type": "magento2-library", "license": [ "OSL-3.0", "AFL-3.0" ], + "config": { + "sort-packages": true + }, + "version": "100.4.2-p1", "require": { - "magento/framework": "*", + "magento/framework": "103.0.*", "php": "~7.4.0||~8.1.0", "php-amqplib/php-amqplib": "~3.1.0" }, "autoload": { - "psr-4": { - "Magento\\Framework\\Amqp\\": "" - }, "files": [ "registration.php" - ] + ], + "psr-4": { + "Magento\\Framework\\Amqp\\": "" + } } } + diff --git a/lib/internal/Magento/Framework/App/Http/Context.php b/lib/internal/Magento/Framework/App/Http/Context.php index 79a15110234cd..13e0b4f7a68d2 100644 --- a/lib/internal/Magento/Framework/App/Http/Context.php +++ b/lib/internal/Magento/Framework/App/Http/Context.php @@ -5,7 +5,9 @@ */ namespace Magento\Framework\App\Http; +use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\Serialize\Serializer\Json; /** @@ -16,7 +18,7 @@ class Context /** * Currency cache context */ - const CONTEXT_CURRENCY = 'current_currency'; + public const CONTEXT_CURRENCY = 'current_currency'; /** * Data storage @@ -35,6 +37,11 @@ class Context */ private $serializer; + /** + * @var DeploymentConfig + */ + private DeploymentConfig $deploymentConfig; + /** * @param array $data * @param array $default @@ -112,8 +119,11 @@ public function getVaryString() { $data = $this->getData(); if (!empty($data)) { + $salt = (string)$this->getDeploymentConfig()->get( + ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY + ); ksort($data); - return sha1($this->serializer->serialize($data)); + return hash('sha256', $this->serializer->serialize($data) . '|' . $salt); } return null; } @@ -130,4 +140,18 @@ public function toArray() 'default' => $this->default ]; } + + /** + * Get DeploymentConfig + * + * @return DeploymentConfig + */ + private function getDeploymentConfig() : DeploymentConfig + { + if (!isset($this->deploymentConfig)) { + $this->deploymentConfig = ObjectManager::getInstance() + ->get(DeploymentConfig::class); + } + return $this->deploymentConfig; + } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php index a1ab0f3d3f5f7..17aeb74988323 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php @@ -7,7 +7,10 @@ namespace Magento\Framework\App\Test\Unit\Http; +use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\Http\Context; +use Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit\Framework\MockObject\MockObject; @@ -25,6 +28,16 @@ class ContextTest extends TestCase */ protected $object; + /** + * @var DeploymentConfig|MockObject + */ + private $deploymentConfig; + + /** + * @var ObjectManagerInterface|MockObject + */ + private $objectManagerMock; + /** * @var Json|MockObject */ @@ -32,6 +45,12 @@ class ContextTest extends TestCase protected function setUp(): void { + $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->onlyMethods(['create']) + ->getMockForAbstractClass(); + \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock); + $this->objectManager = new ObjectManager($this); $this->serializerMock = $this->getMockBuilder(Json::class) ->setMethods(['serialize']) @@ -50,6 +69,10 @@ function ($value) { 'serializer' => $this->serializerMock ] ); + $this->deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); } public function testGetValue() @@ -81,6 +104,16 @@ public function testGetData() public function testGetVaryString() { + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->with(DeploymentConfig::class) + ->willReturn($this->deploymentConfig); + + $this->deploymentConfig->expects($this->any()) + ->method('get') + ->with(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY) + ->willReturn('448198e08af35844a42d3c93c1ef4e03'); + $this->object->setValue('key2', 'value2', 'default2'); $this->object->setValue('key1', 'value1', 'default1'); $data = [ @@ -88,7 +121,11 @@ public function testGetVaryString() 'key1' => 'value1' ]; ksort($data); - $this->assertEquals(sha1(json_encode($data)), $this->object->getVaryString()); + + $salt = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + $cacheKey = hash('sha256', $this->serializerMock->serialize($data) . '|' . $salt); + + $this->assertEquals($cacheKey, $this->object->getVaryString()); } public function testToArray() diff --git a/lib/internal/Magento/Framework/Bulk/composer.json b/lib/internal/Magento/Framework/Bulk/composer.json index 7733ce9fea4c6..0e601aac8ade9 100644 --- a/lib/internal/Magento/Framework/Bulk/composer.json +++ b/lib/internal/Magento/Framework/Bulk/composer.json @@ -1,24 +1,26 @@ { "name": "magento/framework-bulk", "description": "N/A", - "config": { - "sort-packages": true - }, "type": "magento2-library", "license": [ "OSL-3.0", "AFL-3.0" ], + "config": { + "sort-packages": true + }, + "version": "101.0.1", "require": { - "magento/framework": "*", + "magento/framework": "103.0.*", "php": "~7.4.0||~8.1.0" }, "autoload": { - "psr-4": { - "Magento\\Framework\\Bulk\\": "" - }, "files": [ "registration.php" - ] + ], + "psr-4": { + "Magento\\Framework\\Bulk\\": "" + } } } + diff --git a/lib/internal/Magento/Framework/DB/Adapter/SqlVersionProvider.php b/lib/internal/Magento/Framework/DB/Adapter/SqlVersionProvider.php index def51db16454d..a83a6d17ed52f 100644 --- a/lib/internal/Magento/Framework/DB/Adapter/SqlVersionProvider.php +++ b/lib/internal/Magento/Framework/DB/Adapter/SqlVersionProvider.php @@ -25,6 +25,12 @@ class SqlVersionProvider public const MARIA_DB_10_VERSION = '10.'; + public const MYSQL_8_0_29_VERSION = '8.0.29'; + + public const MARIA_DB_10_4_VERSION = '10.4.'; + + public const MARIA_DB_10_4_27_VERSION = '10.4.27'; + /**#@-*/ /** @@ -116,4 +122,38 @@ private function fetchSqlVersion(string $resource): string return $versionOutput[self::VERSION_VAR_NAME]; } + + /** + * Check if MariaDB version is greater than equal to 10.4.27 + * + * @return bool + * @throws ConnectionException + */ + public function isMariaDBGte10427(): bool + { + $sqlVersion = $this->getSqlVersion(); + $isMariaDB104 = str_contains($sqlVersion, SqlVersionProvider::MARIA_DB_10_4_VERSION); + $sqlExactVersion = $this->fetchSqlVersion(ResourceConnection::DEFAULT_CONNECTION); + if ($isMariaDB104 && version_compare($sqlExactVersion, '10.4.27', '>=')) { + return true; + } + return false; + } + + /** + * Check if MySQL version is greater than equal to 8.0.29 + * + * @return bool + * @throws ConnectionException + */ + public function isMysqlGte8029() + { + $sqlVersion = $this->getSqlVersion(); + $isMariaDB = str_contains($sqlVersion, SqlVersionProvider::MARIA_DB_10_VERSION); + $sqlExactVersion = $this->fetchSqlVersion(ResourceConnection::DEFAULT_CONNECTION); + if (!$isMariaDB && version_compare($sqlExactVersion, '8.0.29', '>=')) { + return true; + } + return false; + } } diff --git a/lib/internal/Magento/Framework/DataObject.php b/lib/internal/Magento/Framework/DataObject.php index d74b477d41fa8..99ccaacdad3d7 100644 --- a/lib/internal/Magento/Framework/DataObject.php +++ b/lib/internal/Magento/Framework/DataObject.php @@ -120,6 +120,7 @@ public function unsetData($key = null) * @param string $key * @param string|int $index * @return mixed + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function getData($key = '', $index = null) { @@ -128,7 +129,7 @@ public function getData($key = '', $index = null) } /* process a/b/c key as ['a']['b']['c'] */ - if (strpos($key, '/') !== false) { + if ($key !== null && strpos($key, '/') !== false) { $data = $this->getDataByPath($key); } else { $data = $this->_getData($key); diff --git a/lib/internal/Magento/Framework/Filesystem/Directory/PathValidator.php b/lib/internal/Magento/Framework/Filesystem/Directory/PathValidator.php index 9ecbfa6c9d2a3..5a088258eae37 100644 --- a/lib/internal/Magento/Framework/Filesystem/Directory/PathValidator.php +++ b/lib/internal/Magento/Framework/Filesystem/Directory/PathValidator.php @@ -54,8 +54,11 @@ public function validate( $actualPath = $this->driver->getRealPathSafety($path); } - if (mb_strpos($actualPath, $realDirectoryPath) !== 0 - && rtrim($path, DIRECTORY_SEPARATOR) !== $realDirectoryPath + if (preg_match('/(?:^-|\s-)/', $path) + || ( + mb_strpos($actualPath, $realDirectoryPath) !== 0 + && rtrim($path, DIRECTORY_SEPARATOR) !== $realDirectoryPath + ) ) { throw new ValidatorException( new Phrase( diff --git a/lib/internal/Magento/Framework/Filesystem/File/Write.php b/lib/internal/Magento/Framework/Filesystem/File/Write.php index 913421aa91ad2..14b00408999e0 100644 --- a/lib/internal/Magento/Framework/Filesystem/File/Write.php +++ b/lib/internal/Magento/Framework/Filesystem/File/Write.php @@ -8,6 +8,7 @@ use Magento\Framework\Filesystem\DriverInterface; use Magento\Framework\Exception\FileSystemException; +use Magento\Framework\Phrase; class Write extends Read implements WriteInterface { @@ -28,17 +29,21 @@ public function __construct($path, DriverInterface $driver, $mode) * Assert file existence for proper mode * * @return void - * @throws \Magento\Framework\Exception\FileSystemException + * @throws FileSystemException */ protected function assertValid() { $fileExists = $this->driver->isExists($this->path); - if (!$fileExists && preg_match('/r/', $this->mode)) { + if (preg_match('/(?:^-|\s-)/', basename($this->path))) { + throw new FileSystemException( + new Phrase('The filename "%1" contains invalid characters', [basename($this->path)]) + ); + } elseif (!$fileExists && preg_match('/r/', $this->mode)) { throw new FileSystemException( - new \Magento\Framework\Phrase('The "%1" file doesn\'t exist.', [$this->path]) + new Phrase('The "%1" file doesn\'t exist.', [$this->path]) ); } elseif ($fileExists && preg_match('/x/', $this->mode)) { - throw new FileSystemException(new \Magento\Framework\Phrase('The file "%1" already exists', [$this->path])); + throw new FileSystemException(new Phrase('The file "%1" already exists', [$this->path])); } } @@ -55,7 +60,7 @@ public function write($data) return $this->driver->fileWrite($this->resource, $data); } catch (FileSystemException $e) { throw new FileSystemException( - new \Magento\Framework\Phrase('Cannot write to the "%1" file. %2', [$this->path, $e->getMessage()]) + new Phrase('Cannot write to the "%1" file. %2', [$this->path, $e->getMessage()]) ); } } @@ -75,7 +80,7 @@ public function writeCsv(array $data, $delimiter = ',', $enclosure = '"') return $this->driver->filePutCsv($this->resource, $data, $delimiter, $enclosure); } catch (FileSystemException $e) { throw new FileSystemException( - new \Magento\Framework\Phrase('Cannot write to the "%1" file. %2', [$this->path, $e->getMessage()]) + new Phrase('Cannot write to the "%1" file. %2', [$this->path, $e->getMessage()]) ); } } @@ -92,7 +97,7 @@ public function flush() return $this->driver->fileFlush($this->resource); } catch (FileSystemException $e) { throw new FileSystemException( - new \Magento\Framework\Phrase('Cannot flush the "%1" file. %2', [$this->path, $e->getMessage()]) + new Phrase('Cannot flush the "%1" file. %2', [$this->path, $e->getMessage()]) ); } } diff --git a/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php b/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php index 7048d85be3c70..3e16f3269d4b4 100644 --- a/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php +++ b/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php @@ -1,21 +1,35 @@ purifier = $purifier ?? ObjectManager::getInstance()->get(PurifierInterface::class); + } + /** * Regular expressions for cutting malicious code * * @var string[] */ - protected $_expressions = [ + protected array $_expressions = [ //comments, must be first '/(\/\*.*\*\/)/Us', //tabs @@ -41,15 +55,16 @@ class MaliciousCode implements \Zend_Filter_Interface * Filter value * * @param string|array $value - * @return string|array Filtered value + * @return string|array */ public function filter($value) { $replaced = 0; do { - $value = preg_replace($this->_expressions, '', $value, -1, $replaced); + $value = preg_replace($this->_expressions, '', $value ?? '', -1, $replaced); } while ($replaced !== 0); - return $value; + + return $this->purifier->purify($value); } /** @@ -58,7 +73,7 @@ public function filter($value) * @param string $expression * @return $this */ - public function addExpression($expression) + public function addExpression(string $expression) :self { if (!in_array($expression, $this->_expressions)) { $this->_expressions[] = $expression; @@ -72,7 +87,7 @@ public function addExpression($expression) * @param array $expressions * @return $this */ - public function setExpressions(array $expressions) + public function setExpressions(array $expressions) :self { $this->_expressions = $expressions; return $this; diff --git a/lib/internal/Magento/Framework/Filter/Input/Purifier.php b/lib/internal/Magento/Framework/Filter/Input/Purifier.php new file mode 100644 index 0000000000000..1603f70b8f7eb --- /dev/null +++ b/lib/internal/Magento/Framework/Filter/Input/Purifier.php @@ -0,0 +1,46 @@ +set(self::CACHE_DEFINITION, null); + + $this->purifier = $purifier ?? ObjectManager::getInstance()->create(HTMLPurifier::class, ['config' => $config]); + } + + /** + * Purify Html Content from malicious code + * + * @param string|array $content + * @return mixed + */ + public function purify($content) :mixed + { + return is_array($content) ? $this->purifier->purifyArray($content) : $this->purifier->purify($content); + } +} diff --git a/lib/internal/Magento/Framework/Filter/Input/PurifierInterface.php b/lib/internal/Magento/Framework/Filter/Input/PurifierInterface.php new file mode 100644 index 0000000000000..25e590fd3a9e9 --- /dev/null +++ b/lib/internal/Magento/Framework/Filter/Input/PurifierInterface.php @@ -0,0 +1,19 @@ +string = $string; $this->setVariables($variables); @@ -118,6 +135,12 @@ public function __construct( $this->variableResolver = $variableResolver ?? ObjectManager::getInstance() ->get(VariableResolverInterface::class); + $this->signatureProvider = $signatureProvider ?? ObjectManager::getInstance() + ->get(SignatureProvider::class); + + $this->filteringDepthMeter = $filteringDepthMeter ?? ObjectManager::getInstance() + ->get(FilteringDepthMeter::class); + if (empty($directiveProcessors)) { $this->directiveProcessors = [ 'depend' => ObjectManager::getInstance()->get(DependDirective::class), @@ -180,6 +203,60 @@ public function filter($value) )->render()); } + $this->filteringDepthMeter->descend(); + + // Processing of template directives. + $templateDirectivesResults = $this->processDirectives($value); + + foreach ($templateDirectivesResults as $result) { + $value = str_replace($result['directive'], $result['output'], $value); + } + + // Processing of deferred directives received from child templates + // or nested directives. + $deferredDirectivesResults = $this->processDirectives($value, true); + + foreach ($deferredDirectivesResults as $result) { + $value = str_replace($result['directive'], $result['output'], $value); + } + + if ($this->filteringDepthMeter->showMark() > 1) { + // Signing own deferred directives (if any). + $signature = $this->signatureProvider->get(); + + foreach ($templateDirectivesResults as $result) { + if ($result['directive'] === $result['output']) { + $value = str_replace( + $result['output'], + $signature . $result['output'] . $signature, + $value + ); + } + } + } + + $value = $this->afterFilter($value); + + $this->filteringDepthMeter->ascend(); + + return $value; + } + + /** + * Processes template directives and returns an array that contains results produced by each directive. + * + * @param string $value + * @param bool $isSigned + * + * @return array + * + * @throws InvalidArgumentException + * @throws LocalizedException + */ + private function processDirectives($value, $isSigned = false): array + { + $results = []; + foreach ($this->directiveProcessors as $directiveProcessor) { if (!$directiveProcessor instanceof DirectiveProcessorInterface) { throw new InvalidArgumentException( @@ -187,15 +264,57 @@ public function filter($value) ); } - if (preg_match_all($directiveProcessor->getRegularExpression(), $value, $constructions, PREG_SET_ORDER)) { + $pattern = $directiveProcessor->getRegularExpression(); + + if ($isSigned) { + $pattern = $this->embedSignatureIntoPattern($pattern); + } + + if (preg_match_all($pattern, $value, $constructions, PREG_SET_ORDER)) { foreach ($constructions as $construction) { $replacedValue = $directiveProcessor->process($construction, $this, $this->templateVars); - $value = str_replace($construction[0], $replacedValue, $value); + + $results[] = [ + 'directive' => $construction[0], + 'output' => $replacedValue + ]; } } } - return $this->afterFilter($value); + return $results; + } + + /** + * Modifies given regular expression pattern to be able to recognize signed directives. + * + * @param string $pattern + * + * @return string + * + * @throws LocalizedException + */ + private function embedSignatureIntoPattern(string $pattern): string + { + $signature = $this->signatureProvider->get(); + + $closingDelimiters = [ + '(' => ')', + '{' => '}', + '[' => ']', + '<' => '>' + ]; + + $closingDelimiter = $openingDelimiter = substr(trim($pattern), 0, 1); + + if (array_key_exists($openingDelimiter, $closingDelimiters)) { + $closingDelimiter = $closingDelimiters[$openingDelimiter]; + } + + $pattern = substr_replace($pattern, $signature, strpos($pattern, $openingDelimiter) + 1, 0); + $pattern = substr_replace($pattern, $signature, strrpos($pattern, $closingDelimiter), 0); + + return $pattern; } /** diff --git a/lib/internal/Magento/Framework/Filter/Template/FilteringDepthMeter.php b/lib/internal/Magento/Framework/Filter/Template/FilteringDepthMeter.php new file mode 100644 index 0000000000000..57257325be797 --- /dev/null +++ b/lib/internal/Magento/Framework/Filter/Template/FilteringDepthMeter.php @@ -0,0 +1,52 @@ +depth++; + } + + /** + * Decreases filtering depth. + * + * @return void + */ + public function ascend() + { + $this->depth--; + } + + /** + * Shows current filtering depth. + * + * @return int + */ + public function showMark(): int + { + return $this->depth; + } +} diff --git a/lib/internal/Magento/Framework/Filter/Template/SignatureProvider.php b/lib/internal/Magento/Framework/Filter/Template/SignatureProvider.php new file mode 100644 index 0000000000000..3e476f3e5d79e --- /dev/null +++ b/lib/internal/Magento/Framework/Filter/Template/SignatureProvider.php @@ -0,0 +1,53 @@ +random = $random; + } + + /** + * Generates a random string which will be used as a signature during runtime. + * + * @return string + * + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function get(): string + { + if ($this->signature === null) { + $this->signature = $this->random->getRandomString(32); + } + + return $this->signature; + } +} diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php index 779a5256fedc1..a1b773c65352a 100644 --- a/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php +++ b/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php @@ -8,16 +8,37 @@ namespace Magento\Framework\Filter\Test\Unit\Input; use Magento\Framework\Filter\Input\MaliciousCode; +use Magento\Framework\Filter\Input\PurifierInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; class MaliciousCodeTest extends TestCase { - /** @var MaliciousCode */ - protected $filter; + /** + * @var MockObject|PurifierInterface $purifier + */ + private MockObject $purifier; + + /** + * @var MaliciousCode $filter + */ + private MaliciousCode $filter; protected function setUp(): void { - $this->filter = new MaliciousCode(); + $this->purifier = $this->getMockBuilder(PurifierInterface::class) + ->disableOriginalConstructor() + ->onlyMethods(['purify']) + ->getMockForAbstractClass(); + + $objectManager = new ObjectManager($this); + + $this->filter = $objectManager->getObject( + MaliciousCode::class, + ['purifier' => $this->purifier] + ); + parent::setUp(); } @@ -28,11 +49,11 @@ protected function setUp(): void */ public function testFilter($input, $expectedOutput) { - $this->assertEquals( - $expectedOutput, - $this->filter->filter($input), - 'Malicious code is not filtered out correctly.' - ); + $this->purifier->expects(self::atLeastOnce()) + ->method('purify') + ->willReturn($expectedOutput); + + self::assertEquals($expectedOutput, $this->filter->filter($input)); } /** @@ -125,6 +146,7 @@ public function filterDataProvider() '', '', ], + 'Null Value' => [null, ''], ]; } @@ -134,6 +156,11 @@ public function filterDataProvider() public function testAddExpression() { $customExpression = '/<\/?(customMalicious).*>/Uis'; + + $this->purifier->expects(self::atLeastOnce()) + ->method('purify') + ->willReturn('Custom malicious tag is removed customMalicious'); + $this->filter->addExpression($customExpression); $this->assertEquals( /** Tabs should be filtered out along with custom malicious code */ @@ -151,6 +178,11 @@ public function testAddExpression() public function testSetExpression() { $customExpression = '/<\/?(customMalicious).*>/Uis'; + + $this->purifier->expects(self::atLeastOnce()) + ->method('purify') + ->willReturn("Custom \tmalicious tag\t\t is removed customMalicious"); + $this->filter->setExpressions([$customExpression]); $this->assertEquals( /** Tabs should not be filtered out along with custom malicious code */ diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/Template/SignatureProviderTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/Template/SignatureProviderTest.php new file mode 100644 index 0000000000000..3703c1e2d1731 --- /dev/null +++ b/lib/internal/Magento/Framework/Filter/Test/Unit/Template/SignatureProviderTest.php @@ -0,0 +1,54 @@ +random = $this->createPartialMock( + Random::class, + ['getRandomString'] + ); + + $this->signatureProvider = new SignatureProvider( + $this->random + ); + } + + public function testGet() + { + $expectedResult = 'Z0FFbeCU2R8bsVGJuTdkXyiiZBzsaceV'; + + $this->random->expects($this->once()) + ->method('getRandomString') + ->with(32) + ->willReturn($expectedResult); + + $this->assertEquals($expectedResult, $this->signatureProvider->get()); + + $this->random->expects($this->never()) + ->method('getRandomString'); + + $this->assertEquals($expectedResult, $this->signatureProvider->get()); + } +} diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php index 973f7ac1d268f..bb459f147023b 100644 --- a/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php +++ b/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php @@ -9,8 +9,11 @@ use Magento\Framework\DataObject; use Magento\Framework\Filter\Template; +use Magento\Framework\Filter\Template\SignatureProvider; +use Magento\Framework\Filter\Template\FilteringDepthMeter; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Store\Model\Store; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; /** @@ -28,11 +31,43 @@ class TemplateTest extends TestCase */ private $store; + /** + * @var SignatureProvider|MockObject + */ + protected $signatureProvider; + + /** + * @var FilteringDepthMeter|MockObject + */ + protected $filteringDepthMeter; + protected function setUp(): void { $objectManager = new ObjectManager($this); - $this->templateFilter = $objectManager->getObject(Template::class); + $this->store = $objectManager->getObject(Store::class); + + $this->signatureProvider = $this->createPartialMock( + SignatureProvider::class, + ['get'] + ); + + $this->signatureProvider->expects($this->any()) + ->method('get') + ->willReturn('Z0FFbeCU2R8bsVGJuTdkXyiiZBzsaceV'); + + $this->filteringDepthMeter = $this->createPartialMock( + FilteringDepthMeter::class, + ['showMark'] + ); + + $this->templateFilter = $objectManager->getObject( + Template::class, + [ + 'signatureProvider' => $this->signatureProvider, + 'filteringDepthMeter' => $this->filteringDepthMeter + ] + ); } /** @@ -44,6 +79,10 @@ public function testAfterFilter() $value = 'test string'; $expectedResult = 'TEST STRING'; + $this->filteringDepthMeter->expects($this->any()) + ->method('showMark') + ->willReturn(1); + // Build arbitrary object to pass into the addAfterFilterCallback method $callbackObject = $this->getMockBuilder('stdObject') ->setMethods(['afterFilterCallbackMethod']) @@ -72,6 +111,10 @@ public function testAfterFilterCallbackReset() $value = 'test string'; $expectedResult = 'TEST STRING'; + $this->filteringDepthMeter->expects($this->any()) + ->method('showMark') + ->willReturn(1); + // Build arbitrary object to pass into the addAfterFilterCallback method $callbackObject = $this->getMockBuilder('stdObject') ->setMethods(['afterFilterCallbackMethod']) @@ -127,7 +170,7 @@ public function getTemplateAndExpectedResults($type)
    {{for in order.all_visible_items}}
  • - name: , lastname: , age: + name: , lastname: , age:
  • {{/for}}
@@ -137,14 +180,14 @@ public function getTemplateAndExpectedResults($type) $template = <<